1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Driver for Analog Devices (Linear Technology) LTC4162-L charger IC.
4 * Copyright (C) 2020, Topic Embedded Products
7 #include <linux/module.h>
8 #include <linux/delay.h>
10 #include <linux/pm_runtime.h>
11 #include <linux/power_supply.h>
12 #include <linux/i2c.h>
13 #include <linux/regmap.h>
15 /* Registers (names based on what datasheet uses) */
16 #define LTC4162L_EN_LIMIT_ALERTS_REG 0x0D
17 #define LTC4162L_EN_CHARGER_STATE_ALERTS_REG 0x0E
18 #define LTC4162L_EN_CHARGE_STATUS_ALERTS_REG 0x0F
19 #define LTC4162L_CONFIG_BITS_REG 0x14
20 #define LTC4162L_IIN_LIMIT_TARGET 0x15
21 #define LTC4162L_ARM_SHIP_MODE 0x19
22 #define LTC4162L_CHARGE_CURRENT_SETTING 0X1A
23 #define LTC4162L_VCHARGE_SETTING 0X1B
24 #define LTC4162L_C_OVER_X_THRESHOLD 0x1C
25 #define LTC4162L_MAX_CV_TIME 0X1D
26 #define LTC4162L_MAX_CHARGE_TIME 0X1E
27 #define LTC4162L_CHARGER_CONFIG_BITS 0x29
28 #define LTC4162L_CHARGER_STATE 0x34
29 #define LTC4162L_CHARGE_STATUS 0x35
30 #define LTC4162L_LIMIT_ALERTS_REG 0x36
31 #define LTC4162L_CHARGER_STATE_ALERTS_REG 0x37
32 #define LTC4162L_CHARGE_STATUS_ALERTS_REG 0x38
33 #define LTC4162L_SYSTEM_STATUS_REG 0x39
34 #define LTC4162L_VBAT 0x3A
35 #define LTC4162L_VIN 0x3B
36 #define LTC4162L_VOUT 0x3C
37 #define LTC4162L_IBAT 0x3D
38 #define LTC4162L_IIN 0x3E
39 #define LTC4162L_DIE_TEMPERATURE 0x3F
40 #define LTC4162L_THERMISTOR_VOLTAGE 0x40
41 #define LTC4162L_BSR 0x41
42 #define LTC4162L_JEITA_REGION 0x42
43 #define LTC4162L_CHEM_CELLS_REG 0x43
44 #define LTC4162L_ICHARGE_DAC 0x44
45 #define LTC4162L_VCHARGE_DAC 0x45
46 #define LTC4162L_IIN_LIMIT_DAC 0x46
47 #define LTC4162L_VBAT_FILT 0x47
48 #define LTC4162L_INPUT_UNDERVOLTAGE_DAC 0x4B
50 /* Enumeration as in datasheet. Individual bits are mutually exclusive. */
52 battery_detection
= 2048,
53 charger_suspended
= 256,
54 precharge
= 128, /* trickle on low bat voltage */
55 cc_cv_charge
= 64, /* normal charge */
58 c_over_x_term
= 8, /* battery is full */
59 max_charge_time_fault
= 4,
60 bat_missing_fault
= 2,
64 /* Individual bits are mutually exclusive. Only active in charging states.*/
65 enum ltc4162l_charge_status
{
67 thermal_reg_active
= 16,
75 /* Magic number to write to ARM_SHIP_MODE register */
76 #define LTC4162L_ARM_SHIP_MODE_MAGIC 21325
78 struct ltc4162l_info
{
79 struct i2c_client
*client
;
80 struct regmap
*regmap
;
81 struct power_supply
*charger
;
82 u32 rsnsb
; /* Series resistor that sets charge current, microOhm */
83 u32 rsnsi
; /* Series resistor to measure input current, microOhm */
84 u8 cell_count
; /* Number of connected cells, 0 while unknown */
87 static u8
ltc4162l_get_cell_count(struct ltc4162l_info
*info
)
92 /* Once read successfully */
94 return info
->cell_count
;
96 ret
= regmap_read(info
->regmap
, LTC4162L_CHEM_CELLS_REG
, &val
);
100 /* Lower 4 bits is the cell count, or 0 if the chip doesn't know yet */
105 /* Once determined, keep the value */
106 info
->cell_count
= val
;
111 /* Convert enum value to POWER_SUPPLY_STATUS value */
112 static int ltc4162l_state_decode(enum ltc4162l_state value
)
117 return POWER_SUPPLY_STATUS_CHARGING
;
119 return POWER_SUPPLY_STATUS_FULL
;
120 case bat_missing_fault
:
121 case bat_short_fault
:
122 return POWER_SUPPLY_STATUS_UNKNOWN
;
124 return POWER_SUPPLY_STATUS_NOT_CHARGING
;
128 static int ltc4162l_get_status(struct ltc4162l_info
*info
,
129 union power_supply_propval
*val
)
134 ret
= regmap_read(info
->regmap
, LTC4162L_CHARGER_STATE
, ®val
);
136 dev_err(&info
->client
->dev
, "Failed to read CHARGER_STATE\n");
140 val
->intval
= ltc4162l_state_decode(regval
);
145 static int ltc4162l_charge_status_decode(enum ltc4162l_charge_status value
)
148 return POWER_SUPPLY_CHARGE_TYPE_NONE
;
150 /* constant voltage/current and input_current limit are "fast" modes */
151 if (value
<= iin_limit_active
)
152 return POWER_SUPPLY_CHARGE_TYPE_FAST
;
154 /* Anything that's not fast we'll return as trickle */
155 return POWER_SUPPLY_CHARGE_TYPE_TRICKLE
;
158 static int ltc4162l_get_charge_type(struct ltc4162l_info
*info
,
159 union power_supply_propval
*val
)
164 ret
= regmap_read(info
->regmap
, LTC4162L_CHARGE_STATUS
, ®val
);
168 val
->intval
= ltc4162l_charge_status_decode(regval
);
173 static int ltc4162l_state_to_health(enum ltc4162l_state value
)
177 return POWER_SUPPLY_HEALTH_OVERHEAT
;
179 return POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE
;
180 case max_charge_time_fault
:
181 return POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE
;
182 case bat_missing_fault
:
183 return POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
;
184 case bat_short_fault
:
185 return POWER_SUPPLY_HEALTH_DEAD
;
187 return POWER_SUPPLY_HEALTH_GOOD
;
191 static int ltc4162l_get_health(struct ltc4162l_info
*info
,
192 union power_supply_propval
*val
)
197 ret
= regmap_read(info
->regmap
, LTC4162L_CHARGER_STATE
, ®val
);
201 val
->intval
= ltc4162l_state_to_health(regval
);
206 static int ltc4162l_get_online(struct ltc4162l_info
*info
,
207 union power_supply_propval
*val
)
212 ret
= regmap_read(info
->regmap
, LTC4162L_SYSTEM_STATUS_REG
, ®val
);
216 /* BIT(2) indicates if input voltage is sufficient to charge */
217 val
->intval
= !!(regval
& BIT(2));
222 static int ltc4162l_get_vbat(struct ltc4162l_info
*info
,
224 union power_supply_propval
*val
)
229 ret
= regmap_read(info
->regmap
, reg
, ®val
);
233 /* cell_count × 192.4μV/LSB */
235 regval
*= ltc4162l_get_cell_count(info
);
237 val
->intval
= regval
;
242 static int ltc4162l_get_ibat(struct ltc4162l_info
*info
,
243 union power_supply_propval
*val
)
248 ret
= regmap_read(info
->regmap
, LTC4162L_IBAT
, ®val
);
252 /* Signed 16-bit number, 1.466μV / RSNSB amperes/LSB. */
253 ret
= (s16
)(regval
& 0xFFFF);
254 val
->intval
= 100 * mult_frac(ret
, 14660, (int)info
->rsnsb
);
260 static int ltc4162l_get_input_voltage(struct ltc4162l_info
*info
,
261 union power_supply_propval
*val
)
266 ret
= regmap_read(info
->regmap
, LTC4162L_VIN
, ®val
);
271 val
->intval
= regval
* 1694;
276 static int ltc4162l_get_input_current(struct ltc4162l_info
*info
,
277 union power_supply_propval
*val
)
282 ret
= regmap_read(info
->regmap
, LTC4162L_IIN
, ®val
);
286 /* Signed 16-bit number, 1.466μV / RSNSI amperes/LSB. */
287 ret
= (s16
)(regval
& 0xFFFF);
297 static int ltc4162l_get_icharge(struct ltc4162l_info
*info
,
299 union power_supply_propval
*val
)
304 ret
= regmap_read(info
->regmap
, reg
, ®val
);
308 regval
&= BIT(6) - 1; /* Only the lower 5 bits */
310 /* The charge current servo level: (icharge_dac + 1) × 1mV/RSNSB */
312 val
->intval
= 10000u * mult_frac(regval
, 100000u, info
->rsnsb
);
317 static int ltc4162l_set_icharge(struct ltc4162l_info
*info
,
321 value
= mult_frac(value
, info
->rsnsb
, 100000u);
324 /* Round to lowest possible */
331 return regmap_write(info
->regmap
, reg
, value
);
335 static int ltc4162l_get_vcharge(struct ltc4162l_info
*info
,
337 union power_supply_propval
*val
)
343 ret
= regmap_read(info
->regmap
, reg
, ®val
);
347 regval
&= BIT(6) - 1; /* Only the lower 5 bits */
350 * charge voltage setting can be computed from
351 * cell_count × (vcharge_setting × 12.5mV + 3.8125V)
352 * where vcharge_setting ranges from 0 to 31 (4.2V max).
354 voltage
= 3812500 + (regval
* 12500);
355 voltage
*= ltc4162l_get_cell_count(info
);
356 val
->intval
= voltage
;
361 static int ltc4162l_set_vcharge(struct ltc4162l_info
*info
,
365 u8 cell_count
= ltc4162l_get_cell_count(info
);
368 return -EBUSY
; /* Not available yet, try again later */
381 return regmap_write(info
->regmap
, reg
, value
);
384 static int ltc4162l_get_iin_limit_dac(struct ltc4162l_info
*info
,
385 union power_supply_propval
*val
)
390 ret
= regmap_read(info
->regmap
, LTC4162L_IIN_LIMIT_DAC
, ®val
);
394 regval
&= BIT(6) - 1; /* Only 6 bits */
396 /* (iin_limit_dac + 1) × 500μV / RSNSI */
399 regval
/= info
->rsnsi
;
400 val
->intval
= 100u * regval
;
405 static int ltc4162l_set_iin_limit(struct ltc4162l_info
*info
,
410 regval
= mult_frac(value
, info
->rsnsi
, 50000u);
417 return regmap_write(info
->regmap
, LTC4162L_IIN_LIMIT_TARGET
, regval
);
420 static int ltc4162l_get_die_temp(struct ltc4162l_info
*info
,
421 union power_supply_propval
*val
)
426 ret
= regmap_read(info
->regmap
, LTC4162L_DIE_TEMPERATURE
, ®val
);
430 /* die_temp × 0.0215°C/LSB - 264.4°C */
431 ret
= (s16
)(regval
& 0xFFFF);
433 ret
/= 100; /* Centidegrees scale */
440 static int ltc4162l_get_term_current(struct ltc4162l_info
*info
,
441 union power_supply_propval
*val
)
446 ret
= regmap_read(info
->regmap
, LTC4162L_CHARGER_CONFIG_BITS
, ®val
);
450 /* Check if C_OVER_X_THRESHOLD is enabled */
451 if (!(regval
& BIT(2))) {
456 ret
= regmap_read(info
->regmap
, LTC4162L_C_OVER_X_THRESHOLD
, ®val
);
460 /* 1.466μV / RSNSB amperes/LSB */
462 regval
/= info
->rsnsb
;
463 val
->intval
= 100 * regval
;
468 static int ltc4162l_set_term_current(struct ltc4162l_info
*info
,
475 /* Disable en_c_over_x_term when set to zero */
476 return regmap_update_bits(info
->regmap
,
477 LTC4162L_CHARGER_CONFIG_BITS
,
481 regval
= mult_frac(value
, info
->rsnsb
, 14660u);
484 ret
= regmap_write(info
->regmap
, LTC4162L_C_OVER_X_THRESHOLD
, regval
);
488 /* Set en_c_over_x_term after changing the threshold value */
489 return regmap_update_bits(info
->regmap
, LTC4162L_CHARGER_CONFIG_BITS
,
493 /* Custom properties */
494 static const char * const ltc4162l_charge_status_name
[] = {
495 "ilim_reg_active", /* 32 */
496 "thermal_reg_active",
501 "charger_off" /* 0 */
504 static ssize_t
charge_status_show(struct device
*dev
,
505 struct device_attribute
*attr
, char *buf
)
507 struct power_supply
*psy
= to_power_supply(dev
);
508 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
509 const char *result
= ltc4162l_charge_status_name
[
510 ARRAY_SIZE(ltc4162l_charge_status_name
) - 1];
516 ret
= regmap_read(info
->regmap
, LTC4162L_CHARGE_STATUS
, ®val
);
520 /* Only one bit is set according to datasheet, let's be safe here */
521 for (mask
= 32, index
= 0; mask
!= 0; mask
>>= 1, ++index
) {
523 result
= ltc4162l_charge_status_name
[index
];
528 return sysfs_emit(buf
, "%s\n", result
);
530 static DEVICE_ATTR_RO(charge_status
);
532 static ssize_t
vbat_show(struct device
*dev
,
533 struct device_attribute
*attr
, char *buf
)
535 struct power_supply
*psy
= to_power_supply(dev
);
536 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
537 union power_supply_propval val
;
540 ret
= ltc4162l_get_vbat(info
, LTC4162L_VBAT
, &val
);
544 return sysfs_emit(buf
, "%d\n", val
.intval
);
546 static DEVICE_ATTR_RO(vbat
);
548 static ssize_t
vbat_avg_show(struct device
*dev
,
549 struct device_attribute
*attr
, char *buf
)
551 struct power_supply
*psy
= to_power_supply(dev
);
552 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
553 union power_supply_propval val
;
556 ret
= ltc4162l_get_vbat(info
, LTC4162L_VBAT_FILT
, &val
);
560 return sysfs_emit(buf
, "%d\n", val
.intval
);
562 static DEVICE_ATTR_RO(vbat_avg
);
564 static ssize_t
ibat_show(struct device
*dev
,
565 struct device_attribute
*attr
, char *buf
)
567 struct power_supply
*psy
= to_power_supply(dev
);
568 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
569 union power_supply_propval val
;
572 ret
= ltc4162l_get_ibat(info
, &val
);
576 return sysfs_emit(buf
, "%d\n", val
.intval
);
578 static DEVICE_ATTR_RO(ibat
);
580 static ssize_t
force_telemetry_show(struct device
*dev
,
581 struct device_attribute
*attr
, char *buf
)
583 struct power_supply
*psy
= to_power_supply(dev
);
584 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
588 ret
= regmap_read(info
->regmap
, LTC4162L_CONFIG_BITS_REG
, ®val
);
592 return sysfs_emit(buf
, "%u\n", regval
& BIT(2) ? 1 : 0);
595 static ssize_t
force_telemetry_store(struct device
*dev
,
596 struct device_attribute
*attr
,
600 struct power_supply
*psy
= to_power_supply(dev
);
601 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
605 ret
= kstrtouint(buf
, 0, &value
);
609 ret
= regmap_update_bits(info
->regmap
, LTC4162L_CONFIG_BITS_REG
,
610 BIT(2), value
? BIT(2) : 0);
617 static DEVICE_ATTR_RW(force_telemetry
);
619 static ssize_t
arm_ship_mode_show(struct device
*dev
,
620 struct device_attribute
*attr
, char *buf
)
622 struct power_supply
*psy
= to_power_supply(dev
);
623 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
627 ret
= regmap_read(info
->regmap
, LTC4162L_ARM_SHIP_MODE
, ®val
);
631 return sysfs_emit(buf
, "%u\n",
632 regval
== LTC4162L_ARM_SHIP_MODE_MAGIC
? 1 : 0);
635 static ssize_t
arm_ship_mode_store(struct device
*dev
,
636 struct device_attribute
*attr
,
640 struct power_supply
*psy
= to_power_supply(dev
);
641 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
645 ret
= kstrtouint(buf
, 0, &value
);
649 ret
= regmap_write(info
->regmap
, LTC4162L_ARM_SHIP_MODE
,
650 value
? LTC4162L_ARM_SHIP_MODE_MAGIC
: 0);
657 static DEVICE_ATTR_RW(arm_ship_mode
);
659 static struct attribute
*ltc4162l_sysfs_entries
[] = {
660 &dev_attr_charge_status
.attr
,
663 &dev_attr_vbat_avg
.attr
,
664 &dev_attr_force_telemetry
.attr
,
665 &dev_attr_arm_ship_mode
.attr
,
669 static const struct attribute_group ltc4162l_attr_group
= {
670 .name
= NULL
, /* put in device directory */
671 .attrs
= ltc4162l_sysfs_entries
,
674 static const struct attribute_group
*ltc4162l_attr_groups
[] = {
675 <c4162l_attr_group
,
679 static int ltc4162l_get_property(struct power_supply
*psy
,
680 enum power_supply_property psp
,
681 union power_supply_propval
*val
)
683 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
686 case POWER_SUPPLY_PROP_STATUS
:
687 return ltc4162l_get_status(info
, val
);
688 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
689 return ltc4162l_get_charge_type(info
, val
);
690 case POWER_SUPPLY_PROP_HEALTH
:
691 return ltc4162l_get_health(info
, val
);
692 case POWER_SUPPLY_PROP_ONLINE
:
693 return ltc4162l_get_online(info
, val
);
694 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
695 return ltc4162l_get_input_voltage(info
, val
);
696 case POWER_SUPPLY_PROP_CURRENT_NOW
:
697 return ltc4162l_get_input_current(info
, val
);
698 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
699 return ltc4162l_get_icharge(info
,
700 LTC4162L_ICHARGE_DAC
, val
);
701 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
702 return ltc4162l_get_icharge(info
,
703 LTC4162L_CHARGE_CURRENT_SETTING
, val
);
704 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
705 return ltc4162l_get_vcharge(info
,
706 LTC4162L_VCHARGE_DAC
, val
);
707 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
:
708 return ltc4162l_get_vcharge(info
,
709 LTC4162L_VCHARGE_SETTING
, val
);
710 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
711 return ltc4162l_get_iin_limit_dac(info
, val
);
712 case POWER_SUPPLY_PROP_TEMP
:
713 return ltc4162l_get_die_temp(info
, val
);
714 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
:
715 return ltc4162l_get_term_current(info
, val
);
721 static int ltc4162l_set_property(struct power_supply
*psy
,
722 enum power_supply_property psp
,
723 const union power_supply_propval
*val
)
725 struct ltc4162l_info
*info
= power_supply_get_drvdata(psy
);
728 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
729 return ltc4162l_set_icharge(info
,
730 LTC4162L_CHARGE_CURRENT_SETTING
, val
->intval
);
731 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
:
732 return ltc4162l_set_vcharge(info
,
733 LTC4162L_VCHARGE_SETTING
, val
->intval
);
734 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
735 return ltc4162l_set_iin_limit(info
, val
->intval
);
736 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
:
737 return ltc4162l_set_term_current(info
, val
->intval
);
743 static int ltc4162l_property_is_writeable(struct power_supply
*psy
,
744 enum power_supply_property psp
)
747 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
748 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
:
749 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
750 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
:
757 /* Charger power supply property routines */
758 static enum power_supply_property ltc4162l_properties
[] = {
759 POWER_SUPPLY_PROP_STATUS
,
760 POWER_SUPPLY_PROP_CHARGE_TYPE
,
761 POWER_SUPPLY_PROP_HEALTH
,
762 POWER_SUPPLY_PROP_ONLINE
,
763 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
764 POWER_SUPPLY_PROP_CURRENT_NOW
,
765 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
,
766 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
,
767 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
,
768 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
,
769 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
,
770 POWER_SUPPLY_PROP_TEMP
,
771 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
,
774 static const struct power_supply_desc ltc4162l_desc
= {
776 .type
= POWER_SUPPLY_TYPE_MAINS
,
777 .properties
= ltc4162l_properties
,
778 .num_properties
= ARRAY_SIZE(ltc4162l_properties
),
779 .get_property
= ltc4162l_get_property
,
780 .set_property
= ltc4162l_set_property
,
781 .property_is_writeable
= ltc4162l_property_is_writeable
,
784 static bool ltc4162l_is_writeable_reg(struct device
*dev
, unsigned int reg
)
786 /* all registers up to this one are writeable */
787 if (reg
<= LTC4162L_CHARGER_CONFIG_BITS
)
790 /* The ALERTS registers can be written to clear alerts */
791 if (reg
>= LTC4162L_LIMIT_ALERTS_REG
&&
792 reg
<= LTC4162L_CHARGE_STATUS_ALERTS_REG
)
798 static bool ltc4162l_is_volatile_reg(struct device
*dev
, unsigned int reg
)
800 /* all registers after this one are read-only status registers */
801 return reg
> LTC4162L_CHARGER_CONFIG_BITS
;
804 static const struct regmap_config ltc4162l_regmap_config
= {
807 .val_format_endian
= REGMAP_ENDIAN_LITTLE
,
808 .writeable_reg
= ltc4162l_is_writeable_reg
,
809 .volatile_reg
= ltc4162l_is_volatile_reg
,
810 .max_register
= LTC4162L_INPUT_UNDERVOLTAGE_DAC
,
811 .cache_type
= REGCACHE_RBTREE
,
814 static void ltc4162l_clear_interrupts(struct ltc4162l_info
*info
)
816 /* Acknowledge interrupt to chip by clearing all events */
817 regmap_write(info
->regmap
, LTC4162L_LIMIT_ALERTS_REG
, 0);
818 regmap_write(info
->regmap
, LTC4162L_CHARGER_STATE_ALERTS_REG
, 0);
819 regmap_write(info
->regmap
, LTC4162L_CHARGE_STATUS_ALERTS_REG
, 0);
822 static int ltc4162l_probe(struct i2c_client
*client
)
824 struct i2c_adapter
*adapter
= client
->adapter
;
825 struct device
*dev
= &client
->dev
;
826 struct ltc4162l_info
*info
;
827 struct power_supply_config ltc4162l_config
= {};
831 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_WORD_DATA
)) {
832 dev_err(dev
, "No support for SMBUS_WORD_DATA\n");
835 info
= devm_kzalloc(dev
, sizeof(*info
), GFP_KERNEL
);
839 info
->client
= client
;
840 i2c_set_clientdata(client
, info
);
842 info
->regmap
= devm_regmap_init_i2c(client
, <c4162l_regmap_config
);
843 if (IS_ERR(info
->regmap
)) {
844 dev_err(dev
, "Failed to initialize register map\n");
845 return PTR_ERR(info
->regmap
);
848 ret
= device_property_read_u32(dev
, "lltc,rsnsb-micro-ohms",
851 dev_err(dev
, "Missing lltc,rsnsb-micro-ohms property\n");
857 ret
= device_property_read_u32(dev
, "lltc,rsnsi-micro-ohms",
860 dev_err(dev
, "Missing lltc,rsnsi-micro-ohms property\n");
866 if (!device_property_read_u32(dev
, "lltc,cell-count", &value
))
867 info
->cell_count
= value
;
869 ltc4162l_config
.of_node
= dev
->of_node
;
870 ltc4162l_config
.drv_data
= info
;
871 ltc4162l_config
.attr_grp
= ltc4162l_attr_groups
;
873 info
->charger
= devm_power_supply_register(dev
, <c4162l_desc
,
875 if (IS_ERR(info
->charger
)) {
876 dev_err(dev
, "Failed to register charger\n");
877 return PTR_ERR(info
->charger
);
880 /* Disable the threshold alerts, we're not using them */
881 regmap_write(info
->regmap
, LTC4162L_EN_LIMIT_ALERTS_REG
, 0);
883 /* Enable interrupts on all status changes */
884 regmap_write(info
->regmap
, LTC4162L_EN_CHARGER_STATE_ALERTS_REG
,
886 regmap_write(info
->regmap
, LTC4162L_EN_CHARGE_STATUS_ALERTS_REG
, 0x1f);
888 ltc4162l_clear_interrupts(info
);
893 static void ltc4162l_alert(struct i2c_client
*client
,
894 enum i2c_alert_protocol type
, unsigned int flag
)
896 struct ltc4162l_info
*info
= i2c_get_clientdata(client
);
898 if (type
!= I2C_PROTOCOL_SMBUS_ALERT
)
901 ltc4162l_clear_interrupts(info
);
902 power_supply_changed(info
->charger
);
905 static const struct i2c_device_id ltc4162l_i2c_id_table
[] = {
909 MODULE_DEVICE_TABLE(i2c
, ltc4162l_i2c_id_table
);
911 static const struct of_device_id ltc4162l_of_match
[] __maybe_unused
= {
912 { .compatible
= "lltc,ltc4162-l", },
915 MODULE_DEVICE_TABLE(of
, ltc4162l_of_match
);
917 static struct i2c_driver ltc4162l_driver
= {
918 .probe
= ltc4162l_probe
,
919 .alert
= ltc4162l_alert
,
920 .id_table
= ltc4162l_i2c_id_table
,
922 .name
= "ltc4162-l-charger",
923 .of_match_table
= of_match_ptr(ltc4162l_of_match
),
926 module_i2c_driver(ltc4162l_driver
);
928 MODULE_LICENSE("GPL");
929 MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
930 MODULE_DESCRIPTION("LTC4162-L charger driver");