1 // SPDX-License-Identifier: GPL-2.0-only
3 * I2C client/driver for the Linear Technology LTC2941, LTC2942, LTC2943
4 * and LTC2944 Battery Gas Gauge IC
6 * Copyright (C) 2014 Topic Embedded Systems
8 * Author: Auryn Verwegen
9 * Author: Mike Looijmans
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/of_device.h>
14 #include <linux/types.h>
15 #include <linux/errno.h>
16 #include <linux/swab.h>
17 #include <linux/i2c.h>
18 #include <linux/delay.h>
19 #include <linux/power_supply.h>
20 #include <linux/slab.h>
22 #define I16_MSB(x) ((x >> 8) & 0xFF)
23 #define I16_LSB(x) (x & 0xFF)
25 #define LTC294X_WORK_DELAY 10 /* Update delay in seconds */
27 #define LTC294X_MAX_VALUE 0xFFFF
28 #define LTC294X_MID_SUPPLY 0x7FFF
30 #define LTC2941_MAX_PRESCALER_EXP 7
31 #define LTC2943_MAX_PRESCALER_EXP 6
34 LTC294X_REG_STATUS
= 0x00,
35 LTC294X_REG_CONTROL
= 0x01,
36 LTC294X_REG_ACC_CHARGE_MSB
= 0x02,
37 LTC294X_REG_ACC_CHARGE_LSB
= 0x03,
38 LTC294X_REG_CHARGE_THR_HIGH_MSB
= 0x04,
39 LTC294X_REG_CHARGE_THR_HIGH_LSB
= 0x05,
40 LTC294X_REG_CHARGE_THR_LOW_MSB
= 0x06,
41 LTC294X_REG_CHARGE_THR_LOW_LSB
= 0x07,
42 LTC294X_REG_VOLTAGE_MSB
= 0x08,
43 LTC294X_REG_VOLTAGE_LSB
= 0x09,
44 LTC2942_REG_TEMPERATURE_MSB
= 0x0C,
45 LTC2942_REG_TEMPERATURE_LSB
= 0x0D,
46 LTC2943_REG_CURRENT_MSB
= 0x0E,
47 LTC2943_REG_CURRENT_LSB
= 0x0F,
48 LTC2943_REG_TEMPERATURE_MSB
= 0x14,
49 LTC2943_REG_TEMPERATURE_LSB
= 0x15,
59 #define LTC2941_REG_STATUS_CHIP_ID BIT(7)
61 #define LTC2942_REG_CONTROL_MODE_SCAN (BIT(7) | BIT(6))
62 #define LTC2943_REG_CONTROL_MODE_SCAN BIT(7)
63 #define LTC294X_REG_CONTROL_PRESCALER_MASK (BIT(5) | BIT(4) | BIT(3))
64 #define LTC294X_REG_CONTROL_SHUTDOWN_MASK (BIT(0))
65 #define LTC294X_REG_CONTROL_PRESCALER_SET(x) \
66 ((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK)
67 #define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED 0
68 #define LTC294X_REG_CONTROL_ADC_DISABLE(x) ((x) & ~(BIT(7) | BIT(6)))
71 struct i2c_client
*client
; /* I2C Client pointer */
72 struct power_supply
*supply
; /* Supply pointer */
73 struct power_supply_desc supply_desc
; /* Supply description */
74 struct delayed_work work
; /* Work scheduler */
75 enum ltc294x_id id
; /* Chip type */
76 int charge
; /* Last charge register content */
77 int r_sense
; /* mOhm */
81 static inline int convert_bin_to_uAh(
82 const struct ltc294x_info
*info
, int Q
)
84 return ((Q
* (info
->Qlsb
/ 10))) / 100;
87 static inline int convert_uAh_to_bin(
88 const struct ltc294x_info
*info
, int uAh
)
92 Q
= (uAh
* 100) / (info
->Qlsb
/10);
93 return (Q
< LTC294X_MAX_VALUE
) ? Q
: LTC294X_MAX_VALUE
;
96 static int ltc294x_read_regs(struct i2c_client
*client
,
97 enum ltc294x_reg reg
, u8
*buf
, int num_regs
)
100 struct i2c_msg msgs
[2] = { };
103 msgs
[0].addr
= client
->addr
;
105 msgs
[0].buf
= ®_start
;
107 msgs
[1].addr
= client
->addr
;
108 msgs
[1].len
= num_regs
;
110 msgs
[1].flags
= I2C_M_RD
;
112 ret
= i2c_transfer(client
->adapter
, &msgs
[0], 2);
114 dev_err(&client
->dev
, "ltc2941 read_reg failed!\n");
118 dev_dbg(&client
->dev
, "%s (%#x, %d) -> %#x\n",
119 __func__
, reg
, num_regs
, *buf
);
124 static int ltc294x_write_regs(struct i2c_client
*client
,
125 enum ltc294x_reg reg
, const u8
*buf
, int num_regs
)
130 ret
= i2c_smbus_write_i2c_block_data(client
, reg_start
, num_regs
, buf
);
132 dev_err(&client
->dev
, "ltc2941 write_reg failed!\n");
136 dev_dbg(&client
->dev
, "%s (%#x, %d) -> %#x\n",
137 __func__
, reg
, num_regs
, *buf
);
142 static int ltc294x_reset(const struct ltc294x_info
*info
, int prescaler_exp
)
148 /* Read status and control registers */
149 ret
= ltc294x_read_regs(info
->client
, LTC294X_REG_CONTROL
, &value
, 1);
151 dev_err(&info
->client
->dev
,
152 "Could not read registers from device\n");
156 control
= LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp
) |
157 LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED
;
158 /* Put device into "monitor" mode */
160 case LTC2942_ID
: /* 2942 measures every 2 sec */
161 control
|= LTC2942_REG_CONTROL_MODE_SCAN
;
164 case LTC2944_ID
: /* 2943 and 2944 measure every 10 sec */
165 control
|= LTC2943_REG_CONTROL_MODE_SCAN
;
171 if (value
!= control
) {
172 ret
= ltc294x_write_regs(info
->client
,
173 LTC294X_REG_CONTROL
, &control
, 1);
175 dev_err(&info
->client
->dev
,
176 "Could not write register\n");
187 static int ltc294x_read_charge_register(const struct ltc294x_info
*info
,
188 enum ltc294x_reg reg
)
193 ret
= ltc294x_read_regs(info
->client
, reg
, &datar
[0], 2);
196 return (datar
[0] << 8) + datar
[1];
199 static int ltc294x_get_charge(const struct ltc294x_info
*info
,
200 enum ltc294x_reg reg
, int *val
)
202 int value
= ltc294x_read_charge_register(info
, reg
);
206 /* When r_sense < 0, this counts up when the battery discharges */
209 *val
= convert_bin_to_uAh(info
, value
);
213 static int ltc294x_set_charge_now(const struct ltc294x_info
*info
, int val
)
220 value
= convert_uAh_to_bin(info
, val
);
221 /* Direction depends on how sense+/- were connected */
224 if ((value
< 0) || (value
> 0xFFFF)) /* input validation */
227 /* Read control register */
228 ret
= ltc294x_read_regs(info
->client
,
229 LTC294X_REG_CONTROL
, &ctrl_reg
, 1);
232 /* Disable analog section */
233 ctrl_reg
|= LTC294X_REG_CONTROL_SHUTDOWN_MASK
;
234 ret
= ltc294x_write_regs(info
->client
,
235 LTC294X_REG_CONTROL
, &ctrl_reg
, 1);
238 /* Set new charge value */
239 dataw
[0] = I16_MSB(value
);
240 dataw
[1] = I16_LSB(value
);
241 ret
= ltc294x_write_regs(info
->client
,
242 LTC294X_REG_ACC_CHARGE_MSB
, &dataw
[0], 2);
245 /* Enable analog section */
247 ctrl_reg
&= ~LTC294X_REG_CONTROL_SHUTDOWN_MASK
;
248 ret
= ltc294x_write_regs(info
->client
,
249 LTC294X_REG_CONTROL
, &ctrl_reg
, 1);
251 return ret
< 0 ? ret
: 0;
254 static int ltc294x_set_charge_thr(const struct ltc294x_info
*info
,
255 enum ltc294x_reg reg
, int val
)
260 value
= convert_uAh_to_bin(info
, val
);
261 /* Direction depends on how sense+/- were connected */
264 if ((value
< 0) || (value
> 0xFFFF)) /* input validation */
267 /* Set new charge value */
268 dataw
[0] = I16_MSB(value
);
269 dataw
[1] = I16_LSB(value
);
270 return ltc294x_write_regs(info
->client
, reg
, &dataw
[0], 2);
273 static int ltc294x_get_charge_counter(
274 const struct ltc294x_info
*info
, int *val
)
276 int value
= ltc294x_read_charge_register(info
, LTC294X_REG_ACC_CHARGE_MSB
);
280 value
-= LTC294X_MID_SUPPLY
;
281 *val
= convert_bin_to_uAh(info
, value
);
285 static int ltc294x_get_voltage(const struct ltc294x_info
*info
, int *val
)
291 ret
= ltc294x_read_regs(info
->client
,
292 LTC294X_REG_VOLTAGE_MSB
, &datar
[0], 2);
293 value
= (datar
[0] << 8) | datar
[1];
301 value
*= 70800 / 5*4;
315 static int ltc294x_get_current(const struct ltc294x_info
*info
, int *val
)
321 ret
= ltc294x_read_regs(info
->client
,
322 LTC2943_REG_CURRENT_MSB
, &datar
[0], 2);
323 value
= (datar
[0] << 8) | datar
[1];
325 if (info
->id
== LTC2944_ID
)
329 /* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
330 * the formula below keeps everything in s32 range while preserving
332 *val
= 1000 * (value
/ (info
->r_sense
* 0x7FFF)); /* in uA */
336 static int ltc294x_get_temperature(const struct ltc294x_info
*info
, int *val
)
338 enum ltc294x_reg reg
;
343 if (info
->id
== LTC2942_ID
) {
344 reg
= LTC2942_REG_TEMPERATURE_MSB
;
345 value
= 6000; /* Full-scale is 600 Kelvin */
347 reg
= LTC2943_REG_TEMPERATURE_MSB
;
348 value
= 5100; /* Full-scale is 510 Kelvin */
350 ret
= ltc294x_read_regs(info
->client
, reg
, &datar
[0], 2);
351 value
*= (datar
[0] << 8) | datar
[1];
352 /* Convert to tenths of degree Celsius */
353 *val
= value
/ 0xFFFF - 2722;
357 static int ltc294x_get_property(struct power_supply
*psy
,
358 enum power_supply_property prop
,
359 union power_supply_propval
*val
)
361 struct ltc294x_info
*info
= power_supply_get_drvdata(psy
);
364 case POWER_SUPPLY_PROP_CHARGE_FULL
:
365 return ltc294x_get_charge(info
, LTC294X_REG_CHARGE_THR_HIGH_MSB
,
367 case POWER_SUPPLY_PROP_CHARGE_EMPTY
:
368 return ltc294x_get_charge(info
, LTC294X_REG_CHARGE_THR_LOW_MSB
,
370 case POWER_SUPPLY_PROP_CHARGE_NOW
:
371 return ltc294x_get_charge(info
, LTC294X_REG_ACC_CHARGE_MSB
,
373 case POWER_SUPPLY_PROP_CHARGE_COUNTER
:
374 return ltc294x_get_charge_counter(info
, &val
->intval
);
375 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
376 return ltc294x_get_voltage(info
, &val
->intval
);
377 case POWER_SUPPLY_PROP_CURRENT_NOW
:
378 return ltc294x_get_current(info
, &val
->intval
);
379 case POWER_SUPPLY_PROP_TEMP
:
380 return ltc294x_get_temperature(info
, &val
->intval
);
386 static int ltc294x_set_property(struct power_supply
*psy
,
387 enum power_supply_property psp
,
388 const union power_supply_propval
*val
)
390 struct ltc294x_info
*info
= power_supply_get_drvdata(psy
);
393 case POWER_SUPPLY_PROP_CHARGE_FULL
:
394 return ltc294x_set_charge_thr(info
,
395 LTC294X_REG_CHARGE_THR_HIGH_MSB
, val
->intval
);
396 case POWER_SUPPLY_PROP_CHARGE_EMPTY
:
397 return ltc294x_set_charge_thr(info
,
398 LTC294X_REG_CHARGE_THR_LOW_MSB
, val
->intval
);
399 case POWER_SUPPLY_PROP_CHARGE_NOW
:
400 return ltc294x_set_charge_now(info
, val
->intval
);
406 static int ltc294x_property_is_writeable(
407 struct power_supply
*psy
, enum power_supply_property psp
)
410 case POWER_SUPPLY_PROP_CHARGE_FULL
:
411 case POWER_SUPPLY_PROP_CHARGE_EMPTY
:
412 case POWER_SUPPLY_PROP_CHARGE_NOW
:
419 static void ltc294x_update(struct ltc294x_info
*info
)
421 int charge
= ltc294x_read_charge_register(info
, LTC294X_REG_ACC_CHARGE_MSB
);
423 if (charge
!= info
->charge
) {
424 info
->charge
= charge
;
425 power_supply_changed(info
->supply
);
429 static void ltc294x_work(struct work_struct
*work
)
431 struct ltc294x_info
*info
;
433 info
= container_of(work
, struct ltc294x_info
, work
.work
);
434 ltc294x_update(info
);
435 schedule_delayed_work(&info
->work
, LTC294X_WORK_DELAY
* HZ
);
438 static enum power_supply_property ltc294x_properties
[] = {
439 POWER_SUPPLY_PROP_CHARGE_COUNTER
,
440 POWER_SUPPLY_PROP_CHARGE_FULL
,
441 POWER_SUPPLY_PROP_CHARGE_EMPTY
,
442 POWER_SUPPLY_PROP_CHARGE_NOW
,
443 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
444 POWER_SUPPLY_PROP_TEMP
,
445 POWER_SUPPLY_PROP_CURRENT_NOW
,
448 static int ltc294x_i2c_remove(struct i2c_client
*client
)
450 struct ltc294x_info
*info
= i2c_get_clientdata(client
);
452 cancel_delayed_work_sync(&info
->work
);
453 power_supply_unregister(info
->supply
);
457 static int ltc294x_i2c_probe(struct i2c_client
*client
,
458 const struct i2c_device_id
*id
)
460 struct power_supply_config psy_cfg
= {};
461 struct ltc294x_info
*info
;
462 struct device_node
*np
;
468 info
= devm_kzalloc(&client
->dev
, sizeof(*info
), GFP_KERNEL
);
472 i2c_set_clientdata(client
, info
);
474 np
= of_node_get(client
->dev
.of_node
);
476 info
->id
= (enum ltc294x_id
)of_device_get_match_data(&client
->dev
);
477 info
->supply_desc
.name
= np
->name
;
479 /* r_sense can be negative, when sense+ is connected to the battery
480 * instead of the sense-. This results in reversed measurements. */
481 ret
= of_property_read_u32(np
, "lltc,resistor-sense", &r_sense
);
483 dev_err(&client
->dev
,
484 "Could not find lltc,resistor-sense in devicetree\n");
487 info
->r_sense
= r_sense
;
489 ret
= of_property_read_u32(np
, "lltc,prescaler-exponent",
492 dev_warn(&client
->dev
,
493 "lltc,prescaler-exponent not in devicetree\n");
494 prescaler_exp
= LTC2941_MAX_PRESCALER_EXP
;
497 if (info
->id
== LTC2943_ID
) {
498 if (prescaler_exp
> LTC2943_MAX_PRESCALER_EXP
)
499 prescaler_exp
= LTC2943_MAX_PRESCALER_EXP
;
500 info
->Qlsb
= ((340 * 50000) / r_sense
) /
501 (4096 / (1 << (2*prescaler_exp
)));
503 if (prescaler_exp
> LTC2941_MAX_PRESCALER_EXP
)
504 prescaler_exp
= LTC2941_MAX_PRESCALER_EXP
;
505 info
->Qlsb
= ((85 * 50000) / r_sense
) /
506 (128 / (1 << prescaler_exp
));
509 /* Read status register to check for LTC2942 */
510 if (info
->id
== LTC2941_ID
|| info
->id
== LTC2942_ID
) {
511 ret
= ltc294x_read_regs(client
, LTC294X_REG_STATUS
, &status
, 1);
513 dev_err(&client
->dev
,
514 "Could not read status register\n");
517 if (status
& LTC2941_REG_STATUS_CHIP_ID
)
518 info
->id
= LTC2941_ID
;
520 info
->id
= LTC2942_ID
;
523 info
->client
= client
;
524 info
->supply_desc
.type
= POWER_SUPPLY_TYPE_BATTERY
;
525 info
->supply_desc
.properties
= ltc294x_properties
;
529 info
->supply_desc
.num_properties
=
530 ARRAY_SIZE(ltc294x_properties
);
533 info
->supply_desc
.num_properties
=
534 ARRAY_SIZE(ltc294x_properties
) - 1;
538 info
->supply_desc
.num_properties
=
539 ARRAY_SIZE(ltc294x_properties
) - 3;
542 info
->supply_desc
.get_property
= ltc294x_get_property
;
543 info
->supply_desc
.set_property
= ltc294x_set_property
;
544 info
->supply_desc
.property_is_writeable
= ltc294x_property_is_writeable
;
545 info
->supply_desc
.external_power_changed
= NULL
;
547 psy_cfg
.drv_data
= info
;
549 INIT_DELAYED_WORK(&info
->work
, ltc294x_work
);
551 ret
= ltc294x_reset(info
, prescaler_exp
);
553 dev_err(&client
->dev
, "Communication with chip failed\n");
557 info
->supply
= power_supply_register(&client
->dev
, &info
->supply_desc
,
559 if (IS_ERR(info
->supply
)) {
560 dev_err(&client
->dev
, "failed to register ltc2941\n");
561 return PTR_ERR(info
->supply
);
563 schedule_delayed_work(&info
->work
, LTC294X_WORK_DELAY
* HZ
);
569 static void ltc294x_i2c_shutdown(struct i2c_client
*client
)
571 struct ltc294x_info
*info
= i2c_get_clientdata(client
);
576 /* The LTC2941 does not need any special handling */
577 if (info
->id
== LTC2941_ID
)
580 /* Read control register */
581 ret
= ltc294x_read_regs(info
->client
, LTC294X_REG_CONTROL
, &value
, 1);
585 /* Disable continuous ADC conversion as this drains the battery */
586 control
= LTC294X_REG_CONTROL_ADC_DISABLE(value
);
587 if (control
!= value
)
588 ltc294x_write_regs(info
->client
, LTC294X_REG_CONTROL
,
592 #ifdef CONFIG_PM_SLEEP
594 static int ltc294x_suspend(struct device
*dev
)
596 struct i2c_client
*client
= to_i2c_client(dev
);
597 struct ltc294x_info
*info
= i2c_get_clientdata(client
);
599 cancel_delayed_work(&info
->work
);
603 static int ltc294x_resume(struct device
*dev
)
605 struct i2c_client
*client
= to_i2c_client(dev
);
606 struct ltc294x_info
*info
= i2c_get_clientdata(client
);
608 schedule_delayed_work(&info
->work
, LTC294X_WORK_DELAY
* HZ
);
612 static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops
, ltc294x_suspend
, ltc294x_resume
);
613 #define LTC294X_PM_OPS (<c294x_pm_ops)
616 #define LTC294X_PM_OPS NULL
617 #endif /* CONFIG_PM_SLEEP */
620 static const struct i2c_device_id ltc294x_i2c_id
[] = {
621 { "ltc2941", LTC2941_ID
, },
622 { "ltc2942", LTC2942_ID
, },
623 { "ltc2943", LTC2943_ID
, },
624 { "ltc2944", LTC2944_ID
, },
627 MODULE_DEVICE_TABLE(i2c
, ltc294x_i2c_id
);
629 static const struct of_device_id ltc294x_i2c_of_match
[] = {
631 .compatible
= "lltc,ltc2941",
632 .data
= (void *)LTC2941_ID
,
635 .compatible
= "lltc,ltc2942",
636 .data
= (void *)LTC2942_ID
,
639 .compatible
= "lltc,ltc2943",
640 .data
= (void *)LTC2943_ID
,
643 .compatible
= "lltc,ltc2944",
644 .data
= (void *)LTC2944_ID
,
648 MODULE_DEVICE_TABLE(of
, ltc294x_i2c_of_match
);
650 static struct i2c_driver ltc294x_driver
= {
653 .of_match_table
= ltc294x_i2c_of_match
,
654 .pm
= LTC294X_PM_OPS
,
656 .probe
= ltc294x_i2c_probe
,
657 .remove
= ltc294x_i2c_remove
,
658 .shutdown
= ltc294x_i2c_shutdown
,
659 .id_table
= ltc294x_i2c_id
,
661 module_i2c_driver(ltc294x_driver
);
663 MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
664 MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
665 MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943/LTC2944 Battery Gas Gauge IC driver");
666 MODULE_LICENSE("GPL");