xref: /openbmc/linux/drivers/power/supply/ltc2941-battery-gauge.c (revision 10c1d542c7e871865bca381842fd04a92d2b95ec)
1 /*
2  * I2C client/driver for the Linear Technology LTC2941, LTC2942, LTC2943
3  * and LTC2944 Battery Gas Gauge IC
4  *
5  * Copyright (C) 2014 Topic Embedded Systems
6  *
7  * Author: Auryn Verwegen
8  * Author: Mike Looijmans
9  */
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/of_device.h>
13 #include <linux/types.h>
14 #include <linux/errno.h>
15 #include <linux/swab.h>
16 #include <linux/i2c.h>
17 #include <linux/delay.h>
18 #include <linux/power_supply.h>
19 #include <linux/slab.h>
20 
21 #define I16_MSB(x)			((x >> 8) & 0xFF)
22 #define I16_LSB(x)			(x & 0xFF)
23 
24 #define LTC294X_WORK_DELAY		10	/* Update delay in seconds */
25 
26 #define LTC294X_MAX_VALUE		0xFFFF
27 #define LTC294X_MID_SUPPLY		0x7FFF
28 
29 #define LTC2941_MAX_PRESCALER_EXP	7
30 #define LTC2943_MAX_PRESCALER_EXP	6
31 
32 enum ltc294x_reg {
33 	LTC294X_REG_STATUS		= 0x00,
34 	LTC294X_REG_CONTROL		= 0x01,
35 	LTC294X_REG_ACC_CHARGE_MSB	= 0x02,
36 	LTC294X_REG_ACC_CHARGE_LSB	= 0x03,
37 	LTC294X_REG_VOLTAGE_MSB		= 0x08,
38 	LTC294X_REG_VOLTAGE_LSB		= 0x09,
39 	LTC2942_REG_TEMPERATURE_MSB	= 0x0C,
40 	LTC2942_REG_TEMPERATURE_LSB	= 0x0D,
41 	LTC2943_REG_CURRENT_MSB		= 0x0E,
42 	LTC2943_REG_CURRENT_LSB		= 0x0F,
43 	LTC2943_REG_TEMPERATURE_MSB	= 0x14,
44 	LTC2943_REG_TEMPERATURE_LSB	= 0x15,
45 };
46 
47 enum ltc294x_id {
48 	LTC2941_ID,
49 	LTC2942_ID,
50 	LTC2943_ID,
51 	LTC2944_ID,
52 };
53 
54 #define LTC2941_REG_STATUS_CHIP_ID	BIT(7)
55 
56 #define LTC2942_REG_CONTROL_MODE_SCAN	(BIT(7) | BIT(6))
57 #define LTC2943_REG_CONTROL_MODE_SCAN	BIT(7)
58 #define LTC294X_REG_CONTROL_PRESCALER_MASK	(BIT(5) | BIT(4) | BIT(3))
59 #define LTC294X_REG_CONTROL_SHUTDOWN_MASK	(BIT(0))
60 #define LTC294X_REG_CONTROL_PRESCALER_SET(x) \
61 	((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK)
62 #define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED	0
63 #define LTC294X_REG_CONTROL_ADC_DISABLE(x)	((x) & ~(BIT(7) | BIT(6)))
64 
65 struct ltc294x_info {
66 	struct i2c_client *client;	/* I2C Client pointer */
67 	struct power_supply *supply;	/* Supply pointer */
68 	struct power_supply_desc supply_desc;	/* Supply description */
69 	struct delayed_work work;	/* Work scheduler */
70 	enum ltc294x_id id;		/* Chip type */
71 	int charge;	/* Last charge register content */
72 	int r_sense;	/* mOhm */
73 	int Qlsb;	/* nAh */
74 };
75 
76 static inline int convert_bin_to_uAh(
77 	const struct ltc294x_info *info, int Q)
78 {
79 	return ((Q * (info->Qlsb / 10))) / 100;
80 }
81 
82 static inline int convert_uAh_to_bin(
83 	const struct ltc294x_info *info, int uAh)
84 {
85 	int Q;
86 
87 	Q = (uAh * 100) / (info->Qlsb/10);
88 	return (Q < LTC294X_MAX_VALUE) ? Q : LTC294X_MAX_VALUE;
89 }
90 
91 static int ltc294x_read_regs(struct i2c_client *client,
92 	enum ltc294x_reg reg, u8 *buf, int num_regs)
93 {
94 	int ret;
95 	struct i2c_msg msgs[2] = { };
96 	u8 reg_start = reg;
97 
98 	msgs[0].addr	= client->addr;
99 	msgs[0].len	= 1;
100 	msgs[0].buf	= &reg_start;
101 
102 	msgs[1].addr	= client->addr;
103 	msgs[1].len	= num_regs;
104 	msgs[1].buf	= buf;
105 	msgs[1].flags	= I2C_M_RD;
106 
107 	ret = i2c_transfer(client->adapter, &msgs[0], 2);
108 	if (ret < 0) {
109 		dev_err(&client->dev, "ltc2941 read_reg failed!\n");
110 		return ret;
111 	}
112 
113 	dev_dbg(&client->dev, "%s (%#x, %d) -> %#x\n",
114 		__func__, reg, num_regs, *buf);
115 
116 	return 0;
117 }
118 
119 static int ltc294x_write_regs(struct i2c_client *client,
120 	enum ltc294x_reg reg, const u8 *buf, int num_regs)
121 {
122 	int ret;
123 	u8 reg_start = reg;
124 
125 	ret = i2c_smbus_write_i2c_block_data(client, reg_start, num_regs, buf);
126 	if (ret < 0) {
127 		dev_err(&client->dev, "ltc2941 write_reg failed!\n");
128 		return ret;
129 	}
130 
131 	dev_dbg(&client->dev, "%s (%#x, %d) -> %#x\n",
132 		__func__, reg, num_regs, *buf);
133 
134 	return 0;
135 }
136 
137 static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
138 {
139 	int ret;
140 	u8 value;
141 	u8 control;
142 
143 	/* Read status and control registers */
144 	ret = ltc294x_read_regs(info->client, LTC294X_REG_CONTROL, &value, 1);
145 	if (ret < 0) {
146 		dev_err(&info->client->dev,
147 			"Could not read registers from device\n");
148 		goto error_exit;
149 	}
150 
151 	control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
152 				LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
153 	/* Put device into "monitor" mode */
154 	switch (info->id) {
155 	case LTC2942_ID:	/* 2942 measures every 2 sec */
156 		control |= LTC2942_REG_CONTROL_MODE_SCAN;
157 		break;
158 	case LTC2943_ID:
159 	case LTC2944_ID:	/* 2943 and 2944 measure every 10 sec */
160 		control |= LTC2943_REG_CONTROL_MODE_SCAN;
161 		break;
162 	default:
163 		break;
164 	}
165 
166 	if (value != control) {
167 		ret = ltc294x_write_regs(info->client,
168 			LTC294X_REG_CONTROL, &control, 1);
169 		if (ret < 0) {
170 			dev_err(&info->client->dev,
171 				"Could not write register\n");
172 			goto error_exit;
173 		}
174 	}
175 
176 	return 0;
177 
178 error_exit:
179 	return ret;
180 }
181 
182 static int ltc294x_read_charge_register(const struct ltc294x_info *info)
183 {
184 	int ret;
185 	u8 datar[2];
186 
187 	ret = ltc294x_read_regs(info->client,
188 		LTC294X_REG_ACC_CHARGE_MSB, &datar[0], 2);
189 	if (ret < 0)
190 		return ret;
191 	return (datar[0] << 8) + datar[1];
192 }
193 
194 static int ltc294x_get_charge_now(const struct ltc294x_info *info, int *val)
195 {
196 	int value = ltc294x_read_charge_register(info);
197 
198 	if (value < 0)
199 		return value;
200 	/* When r_sense < 0, this counts up when the battery discharges */
201 	if (info->Qlsb < 0)
202 		value -= 0xFFFF;
203 	*val = convert_bin_to_uAh(info, value);
204 	return 0;
205 }
206 
207 static int ltc294x_set_charge_now(const struct ltc294x_info *info, int val)
208 {
209 	int ret;
210 	u8 dataw[2];
211 	u8 ctrl_reg;
212 	s32 value;
213 
214 	value = convert_uAh_to_bin(info, val);
215 	/* Direction depends on how sense+/- were connected */
216 	if (info->Qlsb < 0)
217 		value += 0xFFFF;
218 	if ((value < 0) || (value > 0xFFFF)) /* input validation */
219 		return -EINVAL;
220 
221 	/* Read control register */
222 	ret = ltc294x_read_regs(info->client,
223 		LTC294X_REG_CONTROL, &ctrl_reg, 1);
224 	if (ret < 0)
225 		return ret;
226 	/* Disable analog section */
227 	ctrl_reg |= LTC294X_REG_CONTROL_SHUTDOWN_MASK;
228 	ret = ltc294x_write_regs(info->client,
229 		LTC294X_REG_CONTROL, &ctrl_reg, 1);
230 	if (ret < 0)
231 		return ret;
232 	/* Set new charge value */
233 	dataw[0] = I16_MSB(value);
234 	dataw[1] = I16_LSB(value);
235 	ret = ltc294x_write_regs(info->client,
236 		LTC294X_REG_ACC_CHARGE_MSB, &dataw[0], 2);
237 	if (ret < 0)
238 		goto error_exit;
239 	/* Enable analog section */
240 error_exit:
241 	ctrl_reg &= ~LTC294X_REG_CONTROL_SHUTDOWN_MASK;
242 	ret = ltc294x_write_regs(info->client,
243 		LTC294X_REG_CONTROL, &ctrl_reg, 1);
244 
245 	return ret < 0 ? ret : 0;
246 }
247 
248 static int ltc294x_get_charge_counter(
249 	const struct ltc294x_info *info, int *val)
250 {
251 	int value = ltc294x_read_charge_register(info);
252 
253 	if (value < 0)
254 		return value;
255 	value -= LTC294X_MID_SUPPLY;
256 	*val = convert_bin_to_uAh(info, value);
257 	return 0;
258 }
259 
260 static int ltc294x_get_voltage(const struct ltc294x_info *info, int *val)
261 {
262 	int ret;
263 	u8 datar[2];
264 	u32 value;
265 
266 	ret = ltc294x_read_regs(info->client,
267 		LTC294X_REG_VOLTAGE_MSB, &datar[0], 2);
268 	value = (datar[0] << 8) | datar[1];
269 	switch (info->id) {
270 	case LTC2943_ID:
271 		value *= 23600 * 2;
272 		value /= 0xFFFF;
273 		value *= 1000 / 2;
274 		break;
275 	case LTC2944_ID:
276 		value *= 70800 / 5*4;
277 		value /= 0xFFFF;
278 		value *= 1000 * 5/4;
279 		break;
280 	default:
281 		value *= 6000 * 10;
282 		value /= 0xFFFF;
283 		value *= 1000 / 10;
284 		break;
285 	}
286 	*val = value;
287 	return ret;
288 }
289 
290 static int ltc294x_get_current(const struct ltc294x_info *info, int *val)
291 {
292 	int ret;
293 	u8 datar[2];
294 	s32 value;
295 
296 	ret = ltc294x_read_regs(info->client,
297 		LTC2943_REG_CURRENT_MSB, &datar[0], 2);
298 	value = (datar[0] << 8) | datar[1];
299 	value -= 0x7FFF;
300 	if (info->id == LTC2944_ID)
301 		value *= 64000;
302 	else
303 		value *= 60000;
304 	/* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
305 	 * the formula below keeps everything in s32 range while preserving
306 	 * enough digits */
307 	*val = 1000 * (value / (info->r_sense * 0x7FFF)); /* in uA */
308 	return ret;
309 }
310 
311 static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val)
312 {
313 	enum ltc294x_reg reg;
314 	int ret;
315 	u8 datar[2];
316 	u32 value;
317 
318 	if (info->id == LTC2942_ID) {
319 		reg = LTC2942_REG_TEMPERATURE_MSB;
320 		value = 60000;	/* Full-scale is 600 Kelvin */
321 	} else {
322 		reg = LTC2943_REG_TEMPERATURE_MSB;
323 		value = 51000;	/* Full-scale is 510 Kelvin */
324 	}
325 	ret = ltc294x_read_regs(info->client, reg, &datar[0], 2);
326 	value *= (datar[0] << 8) | datar[1];
327 	/* Convert to centidegrees  */
328 	*val = value / 0xFFFF - 27215;
329 	return ret;
330 }
331 
332 static int ltc294x_get_property(struct power_supply *psy,
333 				enum power_supply_property prop,
334 				union power_supply_propval *val)
335 {
336 	struct ltc294x_info *info = power_supply_get_drvdata(psy);
337 
338 	switch (prop) {
339 	case POWER_SUPPLY_PROP_CHARGE_NOW:
340 		return ltc294x_get_charge_now(info, &val->intval);
341 	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
342 		return ltc294x_get_charge_counter(info, &val->intval);
343 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
344 		return ltc294x_get_voltage(info, &val->intval);
345 	case POWER_SUPPLY_PROP_CURRENT_NOW:
346 		return ltc294x_get_current(info, &val->intval);
347 	case POWER_SUPPLY_PROP_TEMP:
348 		return ltc294x_get_temperature(info, &val->intval);
349 	default:
350 		return -EINVAL;
351 	}
352 }
353 
354 static int ltc294x_set_property(struct power_supply *psy,
355 	enum power_supply_property psp,
356 	const union power_supply_propval *val)
357 {
358 	struct ltc294x_info *info = power_supply_get_drvdata(psy);
359 
360 	switch (psp) {
361 	case POWER_SUPPLY_PROP_CHARGE_NOW:
362 		return ltc294x_set_charge_now(info, val->intval);
363 	default:
364 		return -EPERM;
365 	}
366 }
367 
368 static int ltc294x_property_is_writeable(
369 	struct power_supply *psy, enum power_supply_property psp)
370 {
371 	switch (psp) {
372 	case POWER_SUPPLY_PROP_CHARGE_NOW:
373 		return 1;
374 	default:
375 		return 0;
376 	}
377 }
378 
379 static void ltc294x_update(struct ltc294x_info *info)
380 {
381 	int charge = ltc294x_read_charge_register(info);
382 
383 	if (charge != info->charge) {
384 		info->charge = charge;
385 		power_supply_changed(info->supply);
386 	}
387 }
388 
389 static void ltc294x_work(struct work_struct *work)
390 {
391 	struct ltc294x_info *info;
392 
393 	info = container_of(work, struct ltc294x_info, work.work);
394 	ltc294x_update(info);
395 	schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ);
396 }
397 
398 static enum power_supply_property ltc294x_properties[] = {
399 	POWER_SUPPLY_PROP_CHARGE_COUNTER,
400 	POWER_SUPPLY_PROP_CHARGE_NOW,
401 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
402 	POWER_SUPPLY_PROP_TEMP,
403 	POWER_SUPPLY_PROP_CURRENT_NOW,
404 };
405 
406 static int ltc294x_i2c_remove(struct i2c_client *client)
407 {
408 	struct ltc294x_info *info = i2c_get_clientdata(client);
409 
410 	cancel_delayed_work(&info->work);
411 	power_supply_unregister(info->supply);
412 	return 0;
413 }
414 
415 static int ltc294x_i2c_probe(struct i2c_client *client,
416 	const struct i2c_device_id *id)
417 {
418 	struct power_supply_config psy_cfg = {};
419 	struct ltc294x_info *info;
420 	struct device_node *np;
421 	int ret;
422 	u32 prescaler_exp;
423 	s32 r_sense;
424 	u8 status;
425 
426 	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
427 	if (info == NULL)
428 		return -ENOMEM;
429 
430 	i2c_set_clientdata(client, info);
431 
432 	np = of_node_get(client->dev.of_node);
433 
434 	info->id = (enum ltc294x_id)of_device_get_match_data(&client->dev);
435 	info->supply_desc.name = np->name;
436 
437 	/* r_sense can be negative, when sense+ is connected to the battery
438 	 * instead of the sense-. This results in reversed measurements. */
439 	ret = of_property_read_u32(np, "lltc,resistor-sense", &r_sense);
440 	if (ret < 0) {
441 		dev_err(&client->dev,
442 			"Could not find lltc,resistor-sense in devicetree\n");
443 		return ret;
444 	}
445 	info->r_sense = r_sense;
446 
447 	ret = of_property_read_u32(np, "lltc,prescaler-exponent",
448 		&prescaler_exp);
449 	if (ret < 0) {
450 		dev_warn(&client->dev,
451 			"lltc,prescaler-exponent not in devicetree\n");
452 		prescaler_exp = LTC2941_MAX_PRESCALER_EXP;
453 	}
454 
455 	if (info->id == LTC2943_ID) {
456 		if (prescaler_exp > LTC2943_MAX_PRESCALER_EXP)
457 			prescaler_exp = LTC2943_MAX_PRESCALER_EXP;
458 		info->Qlsb = ((340 * 50000) / r_sense) /
459 				(4096 / (1 << (2*prescaler_exp)));
460 	} else {
461 		if (prescaler_exp > LTC2941_MAX_PRESCALER_EXP)
462 			prescaler_exp = LTC2941_MAX_PRESCALER_EXP;
463 		info->Qlsb = ((85 * 50000) / r_sense) /
464 				(128 / (1 << prescaler_exp));
465 	}
466 
467 	/* Read status register to check for LTC2942 */
468 	if (info->id == LTC2941_ID || info->id == LTC2942_ID) {
469 		ret = ltc294x_read_regs(client, LTC294X_REG_STATUS, &status, 1);
470 		if (ret < 0) {
471 			dev_err(&client->dev,
472 				"Could not read status register\n");
473 			return ret;
474 		}
475 		if (status & LTC2941_REG_STATUS_CHIP_ID)
476 			info->id = LTC2941_ID;
477 		else
478 			info->id = LTC2942_ID;
479 	}
480 
481 	info->client = client;
482 	info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
483 	info->supply_desc.properties = ltc294x_properties;
484 	switch (info->id) {
485 	case LTC2944_ID:
486 	case LTC2943_ID:
487 		info->supply_desc.num_properties =
488 			ARRAY_SIZE(ltc294x_properties);
489 		break;
490 	case LTC2942_ID:
491 		info->supply_desc.num_properties =
492 			ARRAY_SIZE(ltc294x_properties) - 1;
493 		break;
494 	case LTC2941_ID:
495 	default:
496 		info->supply_desc.num_properties =
497 			ARRAY_SIZE(ltc294x_properties) - 3;
498 		break;
499 	}
500 	info->supply_desc.get_property = ltc294x_get_property;
501 	info->supply_desc.set_property = ltc294x_set_property;
502 	info->supply_desc.property_is_writeable = ltc294x_property_is_writeable;
503 	info->supply_desc.external_power_changed	= NULL;
504 
505 	psy_cfg.drv_data = info;
506 
507 	INIT_DELAYED_WORK(&info->work, ltc294x_work);
508 
509 	ret = ltc294x_reset(info, prescaler_exp);
510 	if (ret < 0) {
511 		dev_err(&client->dev, "Communication with chip failed\n");
512 		return ret;
513 	}
514 
515 	info->supply = power_supply_register(&client->dev, &info->supply_desc,
516 					     &psy_cfg);
517 	if (IS_ERR(info->supply)) {
518 		dev_err(&client->dev, "failed to register ltc2941\n");
519 		return PTR_ERR(info->supply);
520 	} else {
521 		schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ);
522 	}
523 
524 	return 0;
525 }
526 
527 static void ltc294x_i2c_shutdown(struct i2c_client *client)
528 {
529 	struct ltc294x_info *info = i2c_get_clientdata(client);
530 	int ret;
531 	u8 value;
532 	u8 control;
533 
534 	/* The LTC2941 does not need any special handling */
535 	if (info->id == LTC2941_ID)
536 		return;
537 
538 	/* Read control register */
539 	ret = ltc294x_read_regs(info->client, LTC294X_REG_CONTROL, &value, 1);
540 	if (ret < 0)
541 		return;
542 
543 	/* Disable continuous ADC conversion as this drains the battery */
544 	control = LTC294X_REG_CONTROL_ADC_DISABLE(value);
545 	if (control != value)
546 		ltc294x_write_regs(info->client, LTC294X_REG_CONTROL,
547 			&control, 1);
548 }
549 
550 #ifdef CONFIG_PM_SLEEP
551 
552 static int ltc294x_suspend(struct device *dev)
553 {
554 	struct i2c_client *client = to_i2c_client(dev);
555 	struct ltc294x_info *info = i2c_get_clientdata(client);
556 
557 	cancel_delayed_work(&info->work);
558 	return 0;
559 }
560 
561 static int ltc294x_resume(struct device *dev)
562 {
563 	struct i2c_client *client = to_i2c_client(dev);
564 	struct ltc294x_info *info = i2c_get_clientdata(client);
565 
566 	schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ);
567 	return 0;
568 }
569 
570 static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume);
571 #define LTC294X_PM_OPS (&ltc294x_pm_ops)
572 
573 #else
574 #define LTC294X_PM_OPS NULL
575 #endif /* CONFIG_PM_SLEEP */
576 
577 
578 static const struct i2c_device_id ltc294x_i2c_id[] = {
579 	{ "ltc2941", LTC2941_ID, },
580 	{ "ltc2942", LTC2942_ID, },
581 	{ "ltc2943", LTC2943_ID, },
582 	{ "ltc2944", LTC2944_ID, },
583 	{ },
584 };
585 MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
586 
587 static const struct of_device_id ltc294x_i2c_of_match[] = {
588 	{
589 		.compatible = "lltc,ltc2941",
590 		.data = (void *)LTC2941_ID,
591 	},
592 	{
593 		.compatible = "lltc,ltc2942",
594 		.data = (void *)LTC2942_ID,
595 	},
596 	{
597 		.compatible = "lltc,ltc2943",
598 		.data = (void *)LTC2943_ID,
599 	},
600 	{
601 		.compatible = "lltc,ltc2944",
602 		.data = (void *)LTC2944_ID,
603 	},
604 	{ },
605 };
606 MODULE_DEVICE_TABLE(of, ltc294x_i2c_of_match);
607 
608 static struct i2c_driver ltc294x_driver = {
609 	.driver = {
610 		.name	= "LTC2941",
611 		.of_match_table = ltc294x_i2c_of_match,
612 		.pm	= LTC294X_PM_OPS,
613 	},
614 	.probe		= ltc294x_i2c_probe,
615 	.remove		= ltc294x_i2c_remove,
616 	.shutdown	= ltc294x_i2c_shutdown,
617 	.id_table	= ltc294x_i2c_id,
618 };
619 module_i2c_driver(ltc294x_driver);
620 
621 MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
622 MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
623 MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943/LTC2944 Battery Gas Gauge IC driver");
624 MODULE_LICENSE("GPL");
625