2 * I2C client/driver for the Linear Technology LTC2941 and LTC2943
5 * Copyright (C) 2014 Topic Embedded Systems
7 * Author: Auryn Verwegen
8 * Author: Mike Looijmans
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/errno.h>
14 #include <linux/swab.h>
15 #include <linux/i2c.h>
16 #include <linux/delay.h>
17 #include <linux/idr.h>
18 #include <linux/power_supply.h>
19 #include <linux/slab.h>
21 #define I16_MSB(x) ((x >> 8) & 0xFF)
22 #define I16_LSB(x) (x & 0xFF)
24 #define LTC294X_WORK_DELAY 10 /* Update delay in seconds */
26 #define LTC294X_MAX_VALUE 0xFFFF
27 #define LTC294X_MID_SUPPLY 0x7FFF
29 #define LTC2941_MAX_PRESCALER_EXP 7
30 #define LTC2943_MAX_PRESCALER_EXP 6
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_THRESH_HIGH_MSB
= 0x04,
38 LTC294X_REG_THRESH_HIGH_LSB
= 0x05,
39 LTC294X_REG_THRESH_LOW_MSB
= 0x06,
40 LTC294X_REG_THRESH_LOW_LSB
= 0x07,
41 LTC294X_REG_VOLTAGE_MSB
= 0x08,
42 LTC294X_REG_VOLTAGE_LSB
= 0x09,
43 LTC294X_REG_CURRENT_MSB
= 0x0E,
44 LTC294X_REG_CURRENT_LSB
= 0x0F,
45 LTC294X_REG_TEMPERATURE_MSB
= 0x14,
46 LTC294X_REG_TEMPERATURE_LSB
= 0x15,
49 #define LTC2943_REG_CONTROL_MODE_MASK (BIT(7) | BIT(6))
50 #define LTC2943_REG_CONTROL_MODE_SCAN BIT(7)
51 #define LTC294X_REG_CONTROL_PRESCALER_MASK (BIT(5) | BIT(4) | BIT(3))
52 #define LTC294X_REG_CONTROL_SHUTDOWN_MASK (BIT(0))
53 #define LTC294X_REG_CONTROL_PRESCALER_SET(x) \
54 ((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK)
55 #define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED 0
57 #define LTC2941_NUM_REGS 0x08
58 #define LTC2943_NUM_REGS 0x18
61 struct i2c_client
*client
; /* I2C Client pointer */
62 struct power_supply supply
; /* Supply pointer */
63 struct delayed_work work
; /* Work scheduler */
64 int num_regs
; /* Number of registers (chip type) */
65 int id
; /* Identifier of ltc294x chip */
66 int charge
; /* Last charge register content */
67 int r_sense
; /* mOhm */
71 static DEFINE_IDR(ltc294x_id
);
72 static DEFINE_MUTEX(ltc294x_lock
);
74 static inline int convert_bin_to_uAh(
75 const struct ltc294x_info
*info
, int Q
)
77 return ((Q
* (info
->Qlsb
/ 10))) / 100;
80 static inline int convert_uAh_to_bin(
81 const struct ltc294x_info
*info
, int uAh
)
85 Q
= (uAh
* 100) / (info
->Qlsb
/10);
86 return (Q
< LTC294X_MAX_VALUE
) ? Q
: LTC294X_MAX_VALUE
;
89 static int ltc294x_read_regs(struct i2c_client
*client
,
90 enum ltc294x_reg reg
, u8
*buf
, int num_regs
)
93 struct i2c_msg msgs
[2] = { };
96 msgs
[0].addr
= client
->addr
;
98 msgs
[0].buf
= ®_start
;
100 msgs
[1].addr
= client
->addr
;
101 msgs
[1].len
= num_regs
;
103 msgs
[1].flags
= I2C_M_RD
;
105 ret
= i2c_transfer(client
->adapter
, &msgs
[0], 2);
107 dev_err(&client
->dev
, "ltc2941 read_reg failed!\n");
111 dev_dbg(&client
->dev
, "%s (%#x, %d) -> %#x\n",
112 __func__
, reg
, num_regs
, *buf
);
117 static int ltc294x_write_regs(struct i2c_client
*client
,
118 enum ltc294x_reg reg
, const u8
*buf
, int num_regs
)
123 ret
= i2c_smbus_write_i2c_block_data(client
, reg_start
, num_regs
, buf
);
125 dev_err(&client
->dev
, "ltc2941 write_reg failed!\n");
129 dev_dbg(&client
->dev
, "%s (%#x, %d) -> %#x\n",
130 __func__
, reg
, num_regs
, *buf
);
135 static int ltc294x_reset(const struct ltc294x_info
*info
, int prescaler_exp
)
141 /* Read status and control registers */
142 ret
= ltc294x_read_regs(info
->client
, LTC294X_REG_CONTROL
, &value
, 1);
144 dev_err(&info
->client
->dev
,
145 "Could not read registers from device\n");
149 control
= LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp
) |
150 LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED
;
151 /* Put the 2943 into "monitor" mode, so it measures every 10 sec */
152 if (info
->num_regs
== LTC2943_NUM_REGS
)
153 control
|= LTC2943_REG_CONTROL_MODE_SCAN
;
155 if (value
!= control
) {
156 ret
= ltc294x_write_regs(info
->client
,
157 LTC294X_REG_CONTROL
, &control
, 1);
159 dev_err(&info
->client
->dev
,
160 "Could not write register\n");
171 static int ltc294x_read_charge_register(const struct ltc294x_info
*info
)
176 ret
= ltc294x_read_regs(info
->client
,
177 LTC294X_REG_ACC_CHARGE_MSB
, &datar
[0], 2);
180 return (datar
[0] << 8) + datar
[1];
183 static int ltc294x_get_charge_now(const struct ltc294x_info
*info
, int *val
)
185 int value
= ltc294x_read_charge_register(info
);
189 /* When r_sense < 0, this counts up when the battery discharges */
192 *val
= convert_bin_to_uAh(info
, value
);
196 static int ltc294x_set_charge_now(const struct ltc294x_info
*info
, int val
)
203 value
= convert_uAh_to_bin(info
, val
);
204 /* Direction depends on how sense+/- were connected */
207 if ((value
< 0) || (value
> 0xFFFF)) /* input validation */
210 /* Read control register */
211 ret
= ltc294x_read_regs(info
->client
,
212 LTC294X_REG_CONTROL
, &ctrl_reg
, 1);
215 /* Disable analog section */
216 ctrl_reg
|= LTC294X_REG_CONTROL_SHUTDOWN_MASK
;
217 ret
= ltc294x_write_regs(info
->client
,
218 LTC294X_REG_CONTROL
, &ctrl_reg
, 1);
221 /* Set new charge value */
222 dataw
[0] = I16_MSB(value
);
223 dataw
[1] = I16_LSB(value
);
224 ret
= ltc294x_write_regs(info
->client
,
225 LTC294X_REG_ACC_CHARGE_MSB
, &dataw
[0], 2);
228 /* Enable analog section */
230 ctrl_reg
&= ~LTC294X_REG_CONTROL_SHUTDOWN_MASK
;
231 ret
= ltc294x_write_regs(info
->client
,
232 LTC294X_REG_CONTROL
, &ctrl_reg
, 1);
234 return ret
< 0 ? ret
: 0;
237 static int ltc294x_get_charge_counter(
238 const struct ltc294x_info
*info
, int *val
)
240 int value
= ltc294x_read_charge_register(info
);
244 value
-= LTC294X_MID_SUPPLY
;
245 *val
= convert_bin_to_uAh(info
, value
);
249 static int ltc294x_get_voltage(const struct ltc294x_info
*info
, int *val
)
255 ret
= ltc294x_read_regs(info
->client
,
256 LTC294X_REG_VOLTAGE_MSB
, &datar
[0], 2);
257 value
= (datar
[0] << 8) | datar
[1];
258 *val
= ((value
* 23600) / 0xFFFF) * 1000; /* in uV */
262 static int ltc294x_get_current(const struct ltc294x_info
*info
, int *val
)
268 ret
= ltc294x_read_regs(info
->client
,
269 LTC294X_REG_CURRENT_MSB
, &datar
[0], 2);
270 value
= (datar
[0] << 8) | datar
[1];
272 /* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
273 * the formula below keeps everything in s32 range while preserving
275 *val
= 1000 * ((60000 * value
) / (info
->r_sense
* 0x7FFF)); /* in uA */
279 static int ltc294x_get_temperature(const struct ltc294x_info
*info
, int *val
)
285 ret
= ltc294x_read_regs(info
->client
,
286 LTC294X_REG_TEMPERATURE_MSB
, &datar
[0], 2);
287 value
= (datar
[0] << 8) | datar
[1];
288 /* Full-scale is 510 Kelvin, convert to centidegrees */
289 *val
= (((51000 * value
) / 0xFFFF) - 27215);
293 static int ltc294x_get_property(struct power_supply
*psy
,
294 enum power_supply_property prop
,
295 union power_supply_propval
*val
)
297 struct ltc294x_info
*info
=
298 container_of(psy
, struct ltc294x_info
, supply
);
301 case POWER_SUPPLY_PROP_CHARGE_NOW
:
302 return ltc294x_get_charge_now(info
, &val
->intval
);
303 case POWER_SUPPLY_PROP_CHARGE_COUNTER
:
304 return ltc294x_get_charge_counter(info
, &val
->intval
);
305 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
306 return ltc294x_get_voltage(info
, &val
->intval
);
307 case POWER_SUPPLY_PROP_CURRENT_NOW
:
308 return ltc294x_get_current(info
, &val
->intval
);
309 case POWER_SUPPLY_PROP_TEMP
:
310 return ltc294x_get_temperature(info
, &val
->intval
);
316 static int ltc294x_set_property(struct power_supply
*psy
,
317 enum power_supply_property psp
,
318 const union power_supply_propval
*val
)
320 struct ltc294x_info
*info
=
321 container_of(psy
, struct ltc294x_info
, supply
);
324 case POWER_SUPPLY_PROP_CHARGE_NOW
:
325 return ltc294x_set_charge_now(info
, val
->intval
);
331 static int ltc294x_property_is_writeable(
332 struct power_supply
*psy
, enum power_supply_property psp
)
335 case POWER_SUPPLY_PROP_CHARGE_NOW
:
342 static void ltc294x_update(struct ltc294x_info
*info
)
344 int charge
= ltc294x_read_charge_register(info
);
346 if (charge
!= info
->charge
) {
347 info
->charge
= charge
;
348 power_supply_changed(&info
->supply
);
352 static void ltc294x_work(struct work_struct
*work
)
354 struct ltc294x_info
*info
;
356 info
= container_of(work
, struct ltc294x_info
, work
.work
);
357 ltc294x_update(info
);
358 schedule_delayed_work(&info
->work
, LTC294X_WORK_DELAY
* HZ
);
361 static enum power_supply_property ltc294x_properties
[] = {
362 POWER_SUPPLY_PROP_CHARGE_COUNTER
,
363 POWER_SUPPLY_PROP_CHARGE_NOW
,
364 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
365 POWER_SUPPLY_PROP_CURRENT_NOW
,
366 POWER_SUPPLY_PROP_TEMP
,
369 static int ltc294x_i2c_remove(struct i2c_client
*client
)
371 struct ltc294x_info
*info
= i2c_get_clientdata(client
);
373 cancel_delayed_work(&info
->work
);
374 power_supply_unregister(&info
->supply
);
375 kfree(info
->supply
.name
);
376 mutex_lock(<c294x_lock
);
377 idr_remove(<c294x_id
, info
->id
);
378 mutex_unlock(<c294x_lock
);
382 static int ltc294x_i2c_probe(struct i2c_client
*client
,
383 const struct i2c_device_id
*id
)
385 struct ltc294x_info
*info
;
390 struct device_node
*np
;
392 mutex_lock(<c294x_lock
);
393 ret
= idr_alloc(<c294x_id
, client
, 0, 0, GFP_KERNEL
);
394 mutex_unlock(<c294x_lock
);
400 info
= devm_kzalloc(&client
->dev
, sizeof(*info
), GFP_KERNEL
);
406 i2c_set_clientdata(client
, info
);
408 info
->num_regs
= id
->driver_data
;
409 info
->supply
.name
= kasprintf(GFP_KERNEL
, "%s-%d", client
->name
, num
);
410 if (!info
->supply
.name
) {
415 np
= of_node_get(client
->dev
.of_node
);
417 /* r_sense can be negative, when sense+ is connected to the battery
418 * instead of the sense-. This results in reversed measurements. */
419 ret
= of_property_read_u32(np
, "lltc,resistor-sense", &r_sense
);
421 dev_err(&client
->dev
,
422 "Could not find lltc,resistor-sense in devicetree\n");
425 info
->r_sense
= r_sense
;
427 ret
= of_property_read_u32(np
, "lltc,prescaler-exponent",
430 dev_warn(&client
->dev
,
431 "lltc,prescaler-exponent not in devicetree\n");
432 prescaler_exp
= LTC2941_MAX_PRESCALER_EXP
;
435 if (info
->num_regs
== LTC2943_NUM_REGS
) {
436 if (prescaler_exp
> LTC2943_MAX_PRESCALER_EXP
)
437 prescaler_exp
= LTC2943_MAX_PRESCALER_EXP
;
438 info
->Qlsb
= ((340 * 50000) / r_sense
) /
439 (4096 / (1 << (2*prescaler_exp
)));
441 if (prescaler_exp
> LTC2941_MAX_PRESCALER_EXP
)
442 prescaler_exp
= LTC2941_MAX_PRESCALER_EXP
;
443 info
->Qlsb
= ((58 * 50000) / r_sense
) /
444 (128 / (1 << prescaler_exp
));
447 info
->client
= client
;
449 info
->supply
.type
= POWER_SUPPLY_TYPE_BATTERY
;
450 info
->supply
.properties
= ltc294x_properties
;
451 if (info
->num_regs
>= LTC294X_REG_TEMPERATURE_LSB
)
452 info
->supply
.num_properties
=
453 ARRAY_SIZE(ltc294x_properties
);
454 else if (info
->num_regs
>= LTC294X_REG_CURRENT_LSB
)
455 info
->supply
.num_properties
=
456 ARRAY_SIZE(ltc294x_properties
) - 1;
457 else if (info
->num_regs
>= LTC294X_REG_VOLTAGE_LSB
)
458 info
->supply
.num_properties
=
459 ARRAY_SIZE(ltc294x_properties
) - 2;
461 info
->supply
.num_properties
=
462 ARRAY_SIZE(ltc294x_properties
) - 3;
463 info
->supply
.get_property
= ltc294x_get_property
;
464 info
->supply
.set_property
= ltc294x_set_property
;
465 info
->supply
.property_is_writeable
= ltc294x_property_is_writeable
;
466 info
->supply
.external_power_changed
= NULL
;
468 INIT_DELAYED_WORK(&info
->work
, ltc294x_work
);
470 ret
= ltc294x_reset(info
, prescaler_exp
);
472 dev_err(&client
->dev
, "Communication with chip failed\n");
476 ret
= power_supply_register(&client
->dev
, &info
->supply
);
478 dev_err(&client
->dev
, "failed to register ltc2941\n");
481 schedule_delayed_work(&info
->work
, LTC294X_WORK_DELAY
* HZ
);
487 kfree(info
->supply
.name
);
491 mutex_lock(<c294x_lock
);
492 idr_remove(<c294x_id
, num
);
493 mutex_unlock(<c294x_lock
);
498 #ifdef CONFIG_PM_SLEEP
500 static int ltc294x_suspend(struct device
*dev
)
502 struct i2c_client
*client
= to_i2c_client(dev
);
503 struct ltc294x_info
*info
= i2c_get_clientdata(client
);
505 cancel_delayed_work(&info
->work
);
509 static int ltc294x_resume(struct device
*dev
)
511 struct i2c_client
*client
= to_i2c_client(dev
);
512 struct ltc294x_info
*info
= i2c_get_clientdata(client
);
514 schedule_delayed_work(&info
->work
, LTC294X_WORK_DELAY
* HZ
);
518 static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops
, ltc294x_suspend
, ltc294x_resume
);
519 #define LTC294X_PM_OPS (<c294x_pm_ops)
522 #define LTC294X_PM_OPS NULL
523 #endif /* CONFIG_PM_SLEEP */
526 static const struct i2c_device_id ltc294x_i2c_id
[] = {
527 {"ltc2941", LTC2941_NUM_REGS
},
528 {"ltc2943", LTC2943_NUM_REGS
},
531 MODULE_DEVICE_TABLE(i2c
, ltc294x_i2c_id
);
533 static struct i2c_driver ltc294x_driver
= {
536 .pm
= LTC294X_PM_OPS
,
538 .probe
= ltc294x_i2c_probe
,
539 .remove
= ltc294x_i2c_remove
,
540 .id_table
= ltc294x_i2c_id
,
542 module_i2c_driver(ltc294x_driver
);
544 MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
545 MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
546 MODULE_DESCRIPTION("LTC2941/LTC2943 Battery Gas Gauge IC driver");
547 MODULE_LICENSE("GPL");