2 * Driver for the TI bq24190 battery charger.
4 * Author: Mark A. Greer <mgreer@animalcreek.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/module.h>
12 #include <linux/interrupt.h>
13 #include <linux/delay.h>
14 #include <linux/of_irq.h>
15 #include <linux/of_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/power_supply.h>
18 #include <linux/gpio.h>
19 #include <linux/i2c.h>
21 #include <linux/power/bq24190_charger.h>
24 #define BQ24190_MANUFACTURER "Texas Instruments"
26 #define BQ24190_REG_ISC 0x00 /* Input Source Control */
27 #define BQ24190_REG_ISC_EN_HIZ_MASK BIT(7)
28 #define BQ24190_REG_ISC_EN_HIZ_SHIFT 7
29 #define BQ24190_REG_ISC_VINDPM_MASK (BIT(6) | BIT(5) | BIT(4) | \
31 #define BQ24190_REG_ISC_VINDPM_SHIFT 3
32 #define BQ24190_REG_ISC_IINLIM_MASK (BIT(2) | BIT(1) | BIT(0))
33 #define BQ24190_REG_ISC_IINLIM_SHIFT 0
35 #define BQ24190_REG_POC 0x01 /* Power-On Configuration */
36 #define BQ24190_REG_POC_RESET_MASK BIT(7)
37 #define BQ24190_REG_POC_RESET_SHIFT 7
38 #define BQ24190_REG_POC_WDT_RESET_MASK BIT(6)
39 #define BQ24190_REG_POC_WDT_RESET_SHIFT 6
40 #define BQ24190_REG_POC_CHG_CONFIG_MASK (BIT(5) | BIT(4))
41 #define BQ24190_REG_POC_CHG_CONFIG_SHIFT 4
42 #define BQ24190_REG_POC_SYS_MIN_MASK (BIT(3) | BIT(2) | BIT(1))
43 #define BQ24190_REG_POC_SYS_MIN_SHIFT 1
44 #define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0)
45 #define BQ24190_REG_POC_BOOST_LIM_SHIFT 0
47 #define BQ24190_REG_CCC 0x02 /* Charge Current Control */
48 #define BQ24190_REG_CCC_ICHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
49 BIT(4) | BIT(3) | BIT(2))
50 #define BQ24190_REG_CCC_ICHG_SHIFT 2
51 #define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0)
52 #define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0
54 #define BQ24190_REG_PCTCC 0x03 /* Pre-charge/Termination Current Cntl */
55 #define BQ24190_REG_PCTCC_IPRECHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
57 #define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4
58 #define BQ24190_REG_PCTCC_ITERM_MASK (BIT(3) | BIT(2) | BIT(1) | \
60 #define BQ24190_REG_PCTCC_ITERM_SHIFT 0
62 #define BQ24190_REG_CVC 0x04 /* Charge Voltage Control */
63 #define BQ24190_REG_CVC_VREG_MASK (BIT(7) | BIT(6) | BIT(5) | \
64 BIT(4) | BIT(3) | BIT(2))
65 #define BQ24190_REG_CVC_VREG_SHIFT 2
66 #define BQ24190_REG_CVC_BATLOWV_MASK BIT(1)
67 #define BQ24190_REG_CVC_BATLOWV_SHIFT 1
68 #define BQ24190_REG_CVC_VRECHG_MASK BIT(0)
69 #define BQ24190_REG_CVC_VRECHG_SHIFT 0
71 #define BQ24190_REG_CTTC 0x05 /* Charge Term/Timer Control */
72 #define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7)
73 #define BQ24190_REG_CTTC_EN_TERM_SHIFT 7
74 #define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6)
75 #define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6
76 #define BQ24190_REG_CTTC_WATCHDOG_MASK (BIT(5) | BIT(4))
77 #define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4
78 #define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3)
79 #define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3
80 #define BQ24190_REG_CTTC_CHG_TIMER_MASK (BIT(2) | BIT(1))
81 #define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1
82 #define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0)
83 #define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0
85 #define BQ24190_REG_ICTRC 0x06 /* IR Comp/Thermal Regulation Control */
86 #define BQ24190_REG_ICTRC_BAT_COMP_MASK (BIT(7) | BIT(6) | BIT(5))
87 #define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5
88 #define BQ24190_REG_ICTRC_VCLAMP_MASK (BIT(4) | BIT(3) | BIT(2))
89 #define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2
90 #define BQ24190_REG_ICTRC_TREG_MASK (BIT(1) | BIT(0))
91 #define BQ24190_REG_ICTRC_TREG_SHIFT 0
93 #define BQ24190_REG_MOC 0x07 /* Misc. Operation Control */
94 #define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7)
95 #define BQ24190_REG_MOC_DPDM_EN_SHIFT 7
96 #define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6)
97 #define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6
98 #define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5)
99 #define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5
100 #define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4)
101 #define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4
102 #define BQ24190_REG_MOC_INT_MASK_MASK (BIT(1) | BIT(0))
103 #define BQ24190_REG_MOC_INT_MASK_SHIFT 0
105 #define BQ24190_REG_SS 0x08 /* System Status */
106 #define BQ24190_REG_SS_VBUS_STAT_MASK (BIT(7) | BIT(6))
107 #define BQ24190_REG_SS_VBUS_STAT_SHIFT 6
108 #define BQ24190_REG_SS_CHRG_STAT_MASK (BIT(5) | BIT(4))
109 #define BQ24190_REG_SS_CHRG_STAT_SHIFT 4
110 #define BQ24190_REG_SS_DPM_STAT_MASK BIT(3)
111 #define BQ24190_REG_SS_DPM_STAT_SHIFT 3
112 #define BQ24190_REG_SS_PG_STAT_MASK BIT(2)
113 #define BQ24190_REG_SS_PG_STAT_SHIFT 2
114 #define BQ24190_REG_SS_THERM_STAT_MASK BIT(1)
115 #define BQ24190_REG_SS_THERM_STAT_SHIFT 1
116 #define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0)
117 #define BQ24190_REG_SS_VSYS_STAT_SHIFT 0
119 #define BQ24190_REG_F 0x09 /* Fault */
120 #define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7)
121 #define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7
122 #define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6)
123 #define BQ24190_REG_F_BOOST_FAULT_SHIFT 6
124 #define BQ24190_REG_F_CHRG_FAULT_MASK (BIT(5) | BIT(4))
125 #define BQ24190_REG_F_CHRG_FAULT_SHIFT 4
126 #define BQ24190_REG_F_BAT_FAULT_MASK BIT(3)
127 #define BQ24190_REG_F_BAT_FAULT_SHIFT 3
128 #define BQ24190_REG_F_NTC_FAULT_MASK (BIT(2) | BIT(1) | BIT(0))
129 #define BQ24190_REG_F_NTC_FAULT_SHIFT 0
131 #define BQ24190_REG_VPRS 0x0A /* Vendor/Part/Revision Status */
132 #define BQ24190_REG_VPRS_PN_MASK (BIT(5) | BIT(4) | BIT(3))
133 #define BQ24190_REG_VPRS_PN_SHIFT 3
134 #define BQ24190_REG_VPRS_PN_24190 0x4
135 #define BQ24190_REG_VPRS_PN_24192 0x5 /* Also 24193 */
136 #define BQ24190_REG_VPRS_PN_24192I 0x3
137 #define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2)
138 #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2
139 #define BQ24190_REG_VPRS_DEV_REG_MASK (BIT(1) | BIT(0))
140 #define BQ24190_REG_VPRS_DEV_REG_SHIFT 0
143 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
144 * so the first read after a fault returns the latched value and subsequent
145 * reads return the current value. In order to return the fault status
146 * to the user, have the interrupt handler save the reg's value and retrieve
147 * it in the appropriate health/status routine.
149 struct bq24190_dev_info
{
150 struct i2c_client
*client
;
152 struct power_supply
*charger
;
153 struct power_supply
*battery
;
154 char model_name
[I2C_NAME_SIZE
];
155 kernel_ulong_t model
;
156 unsigned int gpio_int
;
158 struct mutex f_reg_lock
;
165 * The tables below provide a 2-way mapping for the value that goes in
166 * the register field and the real-world value that it represents.
167 * The index of the array is the value that goes in the register; the
168 * number at that index in the array is the real-world value that it
171 /* REG02[7:2] (ICHG) in uAh */
172 static const int bq24190_ccc_ichg_values
[] = {
173 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
174 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
175 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
176 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
177 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
178 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
179 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
180 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
183 /* REG04[7:2] (VREG) in uV */
184 static const int bq24190_cvc_vreg_values
[] = {
185 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
186 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
187 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
188 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
189 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
190 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
191 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
195 /* REG06[1:0] (TREG) in tenths of degrees Celcius */
196 static const int bq24190_ictrc_treg_values
[] = {
201 * Return the index in 'tbl' of greatest value that is less than or equal to
202 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
203 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
206 static u8
bq24190_find_idx(const int tbl
[], int tbl_size
, int v
)
210 for (i
= 1; i
< tbl_size
; i
++)
217 /* Basic driver I/O routines */
219 static int bq24190_read(struct bq24190_dev_info
*bdi
, u8 reg
, u8
*data
)
223 ret
= i2c_smbus_read_byte_data(bdi
->client
, reg
);
231 static int bq24190_write(struct bq24190_dev_info
*bdi
, u8 reg
, u8 data
)
233 return i2c_smbus_write_byte_data(bdi
->client
, reg
, data
);
236 static int bq24190_read_mask(struct bq24190_dev_info
*bdi
, u8 reg
,
237 u8 mask
, u8 shift
, u8
*data
)
242 ret
= bq24190_read(bdi
, reg
, &v
);
253 static int bq24190_write_mask(struct bq24190_dev_info
*bdi
, u8 reg
,
254 u8 mask
, u8 shift
, u8 data
)
259 ret
= bq24190_read(bdi
, reg
, &v
);
264 v
|= ((data
<< shift
) & mask
);
266 return bq24190_write(bdi
, reg
, v
);
269 static int bq24190_get_field_val(struct bq24190_dev_info
*bdi
,
270 u8 reg
, u8 mask
, u8 shift
,
271 const int tbl
[], int tbl_size
,
277 ret
= bq24190_read_mask(bdi
, reg
, mask
, shift
, &v
);
281 v
= (v
>= tbl_size
) ? (tbl_size
- 1) : v
;
287 static int bq24190_set_field_val(struct bq24190_dev_info
*bdi
,
288 u8 reg
, u8 mask
, u8 shift
,
289 const int tbl
[], int tbl_size
,
294 idx
= bq24190_find_idx(tbl
, tbl_size
, val
);
296 return bq24190_write_mask(bdi
, reg
, mask
, shift
, idx
);
301 * There are a numerous options that are configurable on the bq24190
302 * that go well beyond what the power_supply properties provide access to.
303 * Provide sysfs access to them so they can be examined and possibly modified
304 * on the fly. They will be provided for the charger power_supply object only
305 * and will be prefixed by 'f_' to make them easier to recognize.
308 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
310 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
311 .reg = BQ24190_REG_##r, \
312 .mask = BQ24190_REG_##r##_##f##_MASK, \
313 .shift = BQ24190_REG_##r##_##f##_SHIFT, \
316 #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
317 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
320 #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
321 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
323 static ssize_t
bq24190_sysfs_show(struct device
*dev
,
324 struct device_attribute
*attr
, char *buf
);
325 static ssize_t
bq24190_sysfs_store(struct device
*dev
,
326 struct device_attribute
*attr
, const char *buf
, size_t count
);
328 struct bq24190_sysfs_field_info
{
329 struct device_attribute attr
;
335 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
338 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl
[] = {
339 /* sysfs name reg field in reg */
340 BQ24190_SYSFS_FIELD_RW(en_hiz
, ISC
, EN_HIZ
),
341 BQ24190_SYSFS_FIELD_RW(vindpm
, ISC
, VINDPM
),
342 BQ24190_SYSFS_FIELD_RW(iinlim
, ISC
, IINLIM
),
343 BQ24190_SYSFS_FIELD_RW(chg_config
, POC
, CHG_CONFIG
),
344 BQ24190_SYSFS_FIELD_RW(sys_min
, POC
, SYS_MIN
),
345 BQ24190_SYSFS_FIELD_RW(boost_lim
, POC
, BOOST_LIM
),
346 BQ24190_SYSFS_FIELD_RW(ichg
, CCC
, ICHG
),
347 BQ24190_SYSFS_FIELD_RW(force_20_pct
, CCC
, FORCE_20PCT
),
348 BQ24190_SYSFS_FIELD_RW(iprechg
, PCTCC
, IPRECHG
),
349 BQ24190_SYSFS_FIELD_RW(iterm
, PCTCC
, ITERM
),
350 BQ24190_SYSFS_FIELD_RW(vreg
, CVC
, VREG
),
351 BQ24190_SYSFS_FIELD_RW(batlowv
, CVC
, BATLOWV
),
352 BQ24190_SYSFS_FIELD_RW(vrechg
, CVC
, VRECHG
),
353 BQ24190_SYSFS_FIELD_RW(en_term
, CTTC
, EN_TERM
),
354 BQ24190_SYSFS_FIELD_RW(term_stat
, CTTC
, TERM_STAT
),
355 BQ24190_SYSFS_FIELD_RO(watchdog
, CTTC
, WATCHDOG
),
356 BQ24190_SYSFS_FIELD_RW(en_timer
, CTTC
, EN_TIMER
),
357 BQ24190_SYSFS_FIELD_RW(chg_timer
, CTTC
, CHG_TIMER
),
358 BQ24190_SYSFS_FIELD_RW(jeta_iset
, CTTC
, JEITA_ISET
),
359 BQ24190_SYSFS_FIELD_RW(bat_comp
, ICTRC
, BAT_COMP
),
360 BQ24190_SYSFS_FIELD_RW(vclamp
, ICTRC
, VCLAMP
),
361 BQ24190_SYSFS_FIELD_RW(treg
, ICTRC
, TREG
),
362 BQ24190_SYSFS_FIELD_RW(dpdm_en
, MOC
, DPDM_EN
),
363 BQ24190_SYSFS_FIELD_RW(tmr2x_en
, MOC
, TMR2X_EN
),
364 BQ24190_SYSFS_FIELD_RW(batfet_disable
, MOC
, BATFET_DISABLE
),
365 BQ24190_SYSFS_FIELD_RW(jeita_vset
, MOC
, JEITA_VSET
),
366 BQ24190_SYSFS_FIELD_RO(int_mask
, MOC
, INT_MASK
),
367 BQ24190_SYSFS_FIELD_RO(vbus_stat
, SS
, VBUS_STAT
),
368 BQ24190_SYSFS_FIELD_RO(chrg_stat
, SS
, CHRG_STAT
),
369 BQ24190_SYSFS_FIELD_RO(dpm_stat
, SS
, DPM_STAT
),
370 BQ24190_SYSFS_FIELD_RO(pg_stat
, SS
, PG_STAT
),
371 BQ24190_SYSFS_FIELD_RO(therm_stat
, SS
, THERM_STAT
),
372 BQ24190_SYSFS_FIELD_RO(vsys_stat
, SS
, VSYS_STAT
),
373 BQ24190_SYSFS_FIELD_RO(watchdog_fault
, F
, WATCHDOG_FAULT
),
374 BQ24190_SYSFS_FIELD_RO(boost_fault
, F
, BOOST_FAULT
),
375 BQ24190_SYSFS_FIELD_RO(chrg_fault
, F
, CHRG_FAULT
),
376 BQ24190_SYSFS_FIELD_RO(bat_fault
, F
, BAT_FAULT
),
377 BQ24190_SYSFS_FIELD_RO(ntc_fault
, F
, NTC_FAULT
),
378 BQ24190_SYSFS_FIELD_RO(pn
, VPRS
, PN
),
379 BQ24190_SYSFS_FIELD_RO(ts_profile
, VPRS
, TS_PROFILE
),
380 BQ24190_SYSFS_FIELD_RO(dev_reg
, VPRS
, DEV_REG
),
383 static struct attribute
*
384 bq24190_sysfs_attrs
[ARRAY_SIZE(bq24190_sysfs_field_tbl
) + 1];
386 static const struct attribute_group bq24190_sysfs_attr_group
= {
387 .attrs
= bq24190_sysfs_attrs
,
390 static void bq24190_sysfs_init_attrs(void)
392 int i
, limit
= ARRAY_SIZE(bq24190_sysfs_field_tbl
);
394 for (i
= 0; i
< limit
; i
++)
395 bq24190_sysfs_attrs
[i
] = &bq24190_sysfs_field_tbl
[i
].attr
.attr
;
397 bq24190_sysfs_attrs
[limit
] = NULL
; /* Has additional entry for this */
400 static struct bq24190_sysfs_field_info
*bq24190_sysfs_field_lookup(
403 int i
, limit
= ARRAY_SIZE(bq24190_sysfs_field_tbl
);
405 for (i
= 0; i
< limit
; i
++)
406 if (!strcmp(name
, bq24190_sysfs_field_tbl
[i
].attr
.attr
.name
))
412 return &bq24190_sysfs_field_tbl
[i
];
415 static ssize_t
bq24190_sysfs_show(struct device
*dev
,
416 struct device_attribute
*attr
, char *buf
)
418 struct power_supply
*psy
= dev_get_drvdata(dev
);
419 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
420 struct bq24190_sysfs_field_info
*info
;
424 info
= bq24190_sysfs_field_lookup(attr
->attr
.name
);
428 ret
= bq24190_read_mask(bdi
, info
->reg
, info
->mask
, info
->shift
, &v
);
432 return scnprintf(buf
, PAGE_SIZE
, "%hhx\n", v
);
435 static ssize_t
bq24190_sysfs_store(struct device
*dev
,
436 struct device_attribute
*attr
, const char *buf
, size_t count
)
438 struct power_supply
*psy
= dev_get_drvdata(dev
);
439 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
440 struct bq24190_sysfs_field_info
*info
;
444 info
= bq24190_sysfs_field_lookup(attr
->attr
.name
);
448 ret
= kstrtou8(buf
, 0, &v
);
452 ret
= bq24190_write_mask(bdi
, info
->reg
, info
->mask
, info
->shift
, v
);
459 static int bq24190_sysfs_create_group(struct bq24190_dev_info
*bdi
)
461 bq24190_sysfs_init_attrs();
463 return sysfs_create_group(&bdi
->charger
->dev
.kobj
,
464 &bq24190_sysfs_attr_group
);
467 static void bq24190_sysfs_remove_group(struct bq24190_dev_info
*bdi
)
469 sysfs_remove_group(&bdi
->charger
->dev
.kobj
, &bq24190_sysfs_attr_group
);
472 static int bq24190_sysfs_create_group(struct bq24190_dev_info
*bdi
)
477 static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info
*bdi
) {}
481 * According to the "Host Mode and default Mode" section of the
482 * manual, a write to any register causes the bq24190 to switch
483 * from default mode to host mode. It will switch back to default
484 * mode after a WDT timeout unless the WDT is turned off as well.
485 * So, by simply turning off the WDT, we accomplish both with the
488 static int bq24190_set_mode_host(struct bq24190_dev_info
*bdi
)
493 ret
= bq24190_read(bdi
, BQ24190_REG_CTTC
, &v
);
497 bdi
->watchdog
= ((v
& BQ24190_REG_CTTC_WATCHDOG_MASK
) >>
498 BQ24190_REG_CTTC_WATCHDOG_SHIFT
);
499 v
&= ~BQ24190_REG_CTTC_WATCHDOG_MASK
;
501 return bq24190_write(bdi
, BQ24190_REG_CTTC
, v
);
504 static int bq24190_register_reset(struct bq24190_dev_info
*bdi
)
506 int ret
, limit
= 100;
509 /* Reset the registers */
510 ret
= bq24190_write_mask(bdi
, BQ24190_REG_POC
,
511 BQ24190_REG_POC_RESET_MASK
,
512 BQ24190_REG_POC_RESET_SHIFT
,
517 /* Reset bit will be cleared by hardware so poll until it is */
519 ret
= bq24190_read_mask(bdi
, BQ24190_REG_POC
,
520 BQ24190_REG_POC_RESET_MASK
,
521 BQ24190_REG_POC_RESET_SHIFT
,
538 /* Charger power supply property routines */
540 static int bq24190_charger_get_charge_type(struct bq24190_dev_info
*bdi
,
541 union power_supply_propval
*val
)
546 ret
= bq24190_read_mask(bdi
, BQ24190_REG_POC
,
547 BQ24190_REG_POC_CHG_CONFIG_MASK
,
548 BQ24190_REG_POC_CHG_CONFIG_SHIFT
,
553 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
555 type
= POWER_SUPPLY_CHARGE_TYPE_NONE
;
557 ret
= bq24190_read_mask(bdi
, BQ24190_REG_CCC
,
558 BQ24190_REG_CCC_FORCE_20PCT_MASK
,
559 BQ24190_REG_CCC_FORCE_20PCT_SHIFT
,
564 type
= (v
) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE
:
565 POWER_SUPPLY_CHARGE_TYPE_FAST
;
573 static int bq24190_charger_set_charge_type(struct bq24190_dev_info
*bdi
,
574 const union power_supply_propval
*val
)
576 u8 chg_config
, force_20pct
, en_term
;
580 * According to the "Termination when REG02[0] = 1" section of
581 * the bq24190 manual, the trickle charge could be less than the
582 * termination current so it recommends turning off the termination
585 * Note: AFAICT from the datasheet, the user will have to manually
586 * turn off the charging when in 20% mode. If its not turned off,
587 * there could be battery damage. So, use this mode at your own risk.
589 switch (val
->intval
) {
590 case POWER_SUPPLY_CHARGE_TYPE_NONE
:
593 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE
:
598 case POWER_SUPPLY_CHARGE_TYPE_FAST
:
607 if (chg_config
) { /* Enabling the charger */
608 ret
= bq24190_write_mask(bdi
, BQ24190_REG_CCC
,
609 BQ24190_REG_CCC_FORCE_20PCT_MASK
,
610 BQ24190_REG_CCC_FORCE_20PCT_SHIFT
,
615 ret
= bq24190_write_mask(bdi
, BQ24190_REG_CTTC
,
616 BQ24190_REG_CTTC_EN_TERM_MASK
,
617 BQ24190_REG_CTTC_EN_TERM_SHIFT
,
623 return bq24190_write_mask(bdi
, BQ24190_REG_POC
,
624 BQ24190_REG_POC_CHG_CONFIG_MASK
,
625 BQ24190_REG_POC_CHG_CONFIG_SHIFT
, chg_config
);
628 static int bq24190_charger_get_health(struct bq24190_dev_info
*bdi
,
629 union power_supply_propval
*val
)
634 mutex_lock(&bdi
->f_reg_lock
);
636 mutex_unlock(&bdi
->f_reg_lock
);
638 if (v
& BQ24190_REG_F_BOOST_FAULT_MASK
) {
640 * This could be over-current or over-voltage but there's
641 * no way to tell which. Return 'OVERVOLTAGE' since there
642 * isn't an 'OVERCURRENT' value defined that we can return
643 * even if it was over-current.
645 health
= POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
647 v
&= BQ24190_REG_F_CHRG_FAULT_MASK
;
648 v
>>= BQ24190_REG_F_CHRG_FAULT_SHIFT
;
651 case 0x0: /* Normal */
652 health
= POWER_SUPPLY_HEALTH_GOOD
;
654 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
656 * This could be over-voltage or under-voltage
657 * and there's no way to tell which. Instead
658 * of looking foolish and returning 'OVERVOLTAGE'
659 * when its really under-voltage, just return
662 health
= POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
;
664 case 0x2: /* Thermal Shutdown */
665 health
= POWER_SUPPLY_HEALTH_OVERHEAT
;
667 case 0x3: /* Charge Safety Timer Expiration */
668 health
= POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE
;
671 health
= POWER_SUPPLY_HEALTH_UNKNOWN
;
675 val
->intval
= health
;
680 static int bq24190_charger_get_online(struct bq24190_dev_info
*bdi
,
681 union power_supply_propval
*val
)
686 ret
= bq24190_read_mask(bdi
, BQ24190_REG_SS
,
687 BQ24190_REG_SS_PG_STAT_MASK
,
688 BQ24190_REG_SS_PG_STAT_SHIFT
, &v
);
696 static int bq24190_charger_get_current(struct bq24190_dev_info
*bdi
,
697 union power_supply_propval
*val
)
702 ret
= bq24190_get_field_val(bdi
, BQ24190_REG_CCC
,
703 BQ24190_REG_CCC_ICHG_MASK
, BQ24190_REG_CCC_ICHG_SHIFT
,
704 bq24190_ccc_ichg_values
,
705 ARRAY_SIZE(bq24190_ccc_ichg_values
), &curr
);
709 ret
= bq24190_read_mask(bdi
, BQ24190_REG_CCC
,
710 BQ24190_REG_CCC_FORCE_20PCT_MASK
,
711 BQ24190_REG_CCC_FORCE_20PCT_SHIFT
, &v
);
715 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
723 static int bq24190_charger_get_current_max(struct bq24190_dev_info
*bdi
,
724 union power_supply_propval
*val
)
726 int idx
= ARRAY_SIZE(bq24190_ccc_ichg_values
) - 1;
728 val
->intval
= bq24190_ccc_ichg_values
[idx
];
732 static int bq24190_charger_set_current(struct bq24190_dev_info
*bdi
,
733 const union power_supply_propval
*val
)
736 int ret
, curr
= val
->intval
;
738 ret
= bq24190_read_mask(bdi
, BQ24190_REG_CCC
,
739 BQ24190_REG_CCC_FORCE_20PCT_MASK
,
740 BQ24190_REG_CCC_FORCE_20PCT_SHIFT
, &v
);
744 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
748 return bq24190_set_field_val(bdi
, BQ24190_REG_CCC
,
749 BQ24190_REG_CCC_ICHG_MASK
, BQ24190_REG_CCC_ICHG_SHIFT
,
750 bq24190_ccc_ichg_values
,
751 ARRAY_SIZE(bq24190_ccc_ichg_values
), curr
);
754 static int bq24190_charger_get_voltage(struct bq24190_dev_info
*bdi
,
755 union power_supply_propval
*val
)
759 ret
= bq24190_get_field_val(bdi
, BQ24190_REG_CVC
,
760 BQ24190_REG_CVC_VREG_MASK
, BQ24190_REG_CVC_VREG_SHIFT
,
761 bq24190_cvc_vreg_values
,
762 ARRAY_SIZE(bq24190_cvc_vreg_values
), &voltage
);
766 val
->intval
= voltage
;
770 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info
*bdi
,
771 union power_supply_propval
*val
)
773 int idx
= ARRAY_SIZE(bq24190_cvc_vreg_values
) - 1;
775 val
->intval
= bq24190_cvc_vreg_values
[idx
];
779 static int bq24190_charger_set_voltage(struct bq24190_dev_info
*bdi
,
780 const union power_supply_propval
*val
)
782 return bq24190_set_field_val(bdi
, BQ24190_REG_CVC
,
783 BQ24190_REG_CVC_VREG_MASK
, BQ24190_REG_CVC_VREG_SHIFT
,
784 bq24190_cvc_vreg_values
,
785 ARRAY_SIZE(bq24190_cvc_vreg_values
), val
->intval
);
788 static int bq24190_charger_get_property(struct power_supply
*psy
,
789 enum power_supply_property psp
, union power_supply_propval
*val
)
791 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
794 dev_dbg(bdi
->dev
, "prop: %d\n", psp
);
796 pm_runtime_get_sync(bdi
->dev
);
799 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
800 ret
= bq24190_charger_get_charge_type(bdi
, val
);
802 case POWER_SUPPLY_PROP_HEALTH
:
803 ret
= bq24190_charger_get_health(bdi
, val
);
805 case POWER_SUPPLY_PROP_ONLINE
:
806 ret
= bq24190_charger_get_online(bdi
, val
);
808 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
809 ret
= bq24190_charger_get_current(bdi
, val
);
811 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
812 ret
= bq24190_charger_get_current_max(bdi
, val
);
814 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
815 ret
= bq24190_charger_get_voltage(bdi
, val
);
817 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
:
818 ret
= bq24190_charger_get_voltage_max(bdi
, val
);
820 case POWER_SUPPLY_PROP_SCOPE
:
821 val
->intval
= POWER_SUPPLY_SCOPE_SYSTEM
;
824 case POWER_SUPPLY_PROP_MODEL_NAME
:
825 val
->strval
= bdi
->model_name
;
828 case POWER_SUPPLY_PROP_MANUFACTURER
:
829 val
->strval
= BQ24190_MANUFACTURER
;
836 pm_runtime_put_sync(bdi
->dev
);
840 static int bq24190_charger_set_property(struct power_supply
*psy
,
841 enum power_supply_property psp
,
842 const union power_supply_propval
*val
)
844 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
847 dev_dbg(bdi
->dev
, "prop: %d\n", psp
);
849 pm_runtime_get_sync(bdi
->dev
);
852 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
853 ret
= bq24190_charger_set_charge_type(bdi
, val
);
855 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
856 ret
= bq24190_charger_set_current(bdi
, val
);
858 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
859 ret
= bq24190_charger_set_voltage(bdi
, val
);
865 pm_runtime_put_sync(bdi
->dev
);
869 static int bq24190_charger_property_is_writeable(struct power_supply
*psy
,
870 enum power_supply_property psp
)
875 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
876 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
877 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
887 static enum power_supply_property bq24190_charger_properties
[] = {
888 POWER_SUPPLY_PROP_CHARGE_TYPE
,
889 POWER_SUPPLY_PROP_HEALTH
,
890 POWER_SUPPLY_PROP_ONLINE
,
891 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
,
892 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
,
893 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
,
894 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
,
895 POWER_SUPPLY_PROP_SCOPE
,
896 POWER_SUPPLY_PROP_MODEL_NAME
,
897 POWER_SUPPLY_PROP_MANUFACTURER
,
900 static char *bq24190_charger_supplied_to
[] = {
904 static const struct power_supply_desc bq24190_charger_desc
= {
905 .name
= "bq24190-charger",
906 .type
= POWER_SUPPLY_TYPE_USB
,
907 .properties
= bq24190_charger_properties
,
908 .num_properties
= ARRAY_SIZE(bq24190_charger_properties
),
909 .get_property
= bq24190_charger_get_property
,
910 .set_property
= bq24190_charger_set_property
,
911 .property_is_writeable
= bq24190_charger_property_is_writeable
,
914 /* Battery power supply property routines */
916 static int bq24190_battery_get_status(struct bq24190_dev_info
*bdi
,
917 union power_supply_propval
*val
)
919 u8 ss_reg
, chrg_fault
;
922 mutex_lock(&bdi
->f_reg_lock
);
923 chrg_fault
= bdi
->f_reg
;
924 mutex_unlock(&bdi
->f_reg_lock
);
926 chrg_fault
&= BQ24190_REG_F_CHRG_FAULT_MASK
;
927 chrg_fault
>>= BQ24190_REG_F_CHRG_FAULT_SHIFT
;
929 ret
= bq24190_read(bdi
, BQ24190_REG_SS
, &ss_reg
);
934 * The battery must be discharging when any of these are true:
935 * - there is no good power source;
936 * - there is a charge fault.
937 * Could also be discharging when in "supplement mode" but
938 * there is no way to tell when its in that mode.
940 if (!(ss_reg
& BQ24190_REG_SS_PG_STAT_MASK
) || chrg_fault
) {
941 status
= POWER_SUPPLY_STATUS_DISCHARGING
;
943 ss_reg
&= BQ24190_REG_SS_CHRG_STAT_MASK
;
944 ss_reg
>>= BQ24190_REG_SS_CHRG_STAT_SHIFT
;
947 case 0x0: /* Not Charging */
948 status
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
950 case 0x1: /* Pre-charge */
951 case 0x2: /* Fast Charging */
952 status
= POWER_SUPPLY_STATUS_CHARGING
;
954 case 0x3: /* Charge Termination Done */
955 status
= POWER_SUPPLY_STATUS_FULL
;
963 val
->intval
= status
;
968 static int bq24190_battery_get_health(struct bq24190_dev_info
*bdi
,
969 union power_supply_propval
*val
)
974 mutex_lock(&bdi
->f_reg_lock
);
976 mutex_unlock(&bdi
->f_reg_lock
);
978 if (v
& BQ24190_REG_F_BAT_FAULT_MASK
) {
979 health
= POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
981 v
&= BQ24190_REG_F_NTC_FAULT_MASK
;
982 v
>>= BQ24190_REG_F_NTC_FAULT_SHIFT
;
985 case 0x0: /* Normal */
986 health
= POWER_SUPPLY_HEALTH_GOOD
;
988 case 0x1: /* TS1 Cold */
989 case 0x3: /* TS2 Cold */
990 case 0x5: /* Both Cold */
991 health
= POWER_SUPPLY_HEALTH_COLD
;
993 case 0x2: /* TS1 Hot */
994 case 0x4: /* TS2 Hot */
995 case 0x6: /* Both Hot */
996 health
= POWER_SUPPLY_HEALTH_OVERHEAT
;
999 health
= POWER_SUPPLY_HEALTH_UNKNOWN
;
1003 val
->intval
= health
;
1007 static int bq24190_battery_get_online(struct bq24190_dev_info
*bdi
,
1008 union power_supply_propval
*val
)
1013 ret
= bq24190_read_mask(bdi
, BQ24190_REG_MOC
,
1014 BQ24190_REG_MOC_BATFET_DISABLE_MASK
,
1015 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT
, &batfet_disable
);
1019 val
->intval
= !batfet_disable
;
1023 static int bq24190_battery_set_online(struct bq24190_dev_info
*bdi
,
1024 const union power_supply_propval
*val
)
1026 return bq24190_write_mask(bdi
, BQ24190_REG_MOC
,
1027 BQ24190_REG_MOC_BATFET_DISABLE_MASK
,
1028 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT
, !val
->intval
);
1031 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info
*bdi
,
1032 union power_supply_propval
*val
)
1036 ret
= bq24190_get_field_val(bdi
, BQ24190_REG_ICTRC
,
1037 BQ24190_REG_ICTRC_TREG_MASK
,
1038 BQ24190_REG_ICTRC_TREG_SHIFT
,
1039 bq24190_ictrc_treg_values
,
1040 ARRAY_SIZE(bq24190_ictrc_treg_values
), &temp
);
1048 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info
*bdi
,
1049 const union power_supply_propval
*val
)
1051 return bq24190_set_field_val(bdi
, BQ24190_REG_ICTRC
,
1052 BQ24190_REG_ICTRC_TREG_MASK
,
1053 BQ24190_REG_ICTRC_TREG_SHIFT
,
1054 bq24190_ictrc_treg_values
,
1055 ARRAY_SIZE(bq24190_ictrc_treg_values
), val
->intval
);
1058 static int bq24190_battery_get_property(struct power_supply
*psy
,
1059 enum power_supply_property psp
, union power_supply_propval
*val
)
1061 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
1064 dev_dbg(bdi
->dev
, "prop: %d\n", psp
);
1066 pm_runtime_get_sync(bdi
->dev
);
1069 case POWER_SUPPLY_PROP_STATUS
:
1070 ret
= bq24190_battery_get_status(bdi
, val
);
1072 case POWER_SUPPLY_PROP_HEALTH
:
1073 ret
= bq24190_battery_get_health(bdi
, val
);
1075 case POWER_SUPPLY_PROP_ONLINE
:
1076 ret
= bq24190_battery_get_online(bdi
, val
);
1078 case POWER_SUPPLY_PROP_TECHNOLOGY
:
1079 /* Could be Li-on or Li-polymer but no way to tell which */
1080 val
->intval
= POWER_SUPPLY_TECHNOLOGY_UNKNOWN
;
1083 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX
:
1084 ret
= bq24190_battery_get_temp_alert_max(bdi
, val
);
1086 case POWER_SUPPLY_PROP_SCOPE
:
1087 val
->intval
= POWER_SUPPLY_SCOPE_SYSTEM
;
1094 pm_runtime_put_sync(bdi
->dev
);
1098 static int bq24190_battery_set_property(struct power_supply
*psy
,
1099 enum power_supply_property psp
,
1100 const union power_supply_propval
*val
)
1102 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
1105 dev_dbg(bdi
->dev
, "prop: %d\n", psp
);
1107 pm_runtime_put_sync(bdi
->dev
);
1110 case POWER_SUPPLY_PROP_ONLINE
:
1111 ret
= bq24190_battery_set_online(bdi
, val
);
1113 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX
:
1114 ret
= bq24190_battery_set_temp_alert_max(bdi
, val
);
1120 pm_runtime_put_sync(bdi
->dev
);
1124 static int bq24190_battery_property_is_writeable(struct power_supply
*psy
,
1125 enum power_supply_property psp
)
1130 case POWER_SUPPLY_PROP_ONLINE
:
1131 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX
:
1141 static enum power_supply_property bq24190_battery_properties
[] = {
1142 POWER_SUPPLY_PROP_STATUS
,
1143 POWER_SUPPLY_PROP_HEALTH
,
1144 POWER_SUPPLY_PROP_ONLINE
,
1145 POWER_SUPPLY_PROP_TECHNOLOGY
,
1146 POWER_SUPPLY_PROP_TEMP_ALERT_MAX
,
1147 POWER_SUPPLY_PROP_SCOPE
,
1150 static const struct power_supply_desc bq24190_battery_desc
= {
1151 .name
= "bq24190-battery",
1152 .type
= POWER_SUPPLY_TYPE_BATTERY
,
1153 .properties
= bq24190_battery_properties
,
1154 .num_properties
= ARRAY_SIZE(bq24190_battery_properties
),
1155 .get_property
= bq24190_battery_get_property
,
1156 .set_property
= bq24190_battery_set_property
,
1157 .property_is_writeable
= bq24190_battery_property_is_writeable
,
1160 static irqreturn_t
bq24190_irq_handler_thread(int irq
, void *data
)
1162 struct bq24190_dev_info
*bdi
= data
;
1163 const u8 battery_mask_ss
= BQ24190_REG_SS_CHRG_STAT_MASK
;
1164 const u8 battery_mask_f
= BQ24190_REG_F_BAT_FAULT_MASK
1165 | BQ24190_REG_F_NTC_FAULT_MASK
;
1166 bool alert_charger
= false, alert_battery
= false;
1167 u8 ss_reg
= 0, f_reg
= 0;
1170 pm_runtime_get_sync(bdi
->dev
);
1172 ret
= bq24190_read(bdi
, BQ24190_REG_SS
, &ss_reg
);
1174 dev_err(bdi
->dev
, "Can't read SS reg: %d\n", ret
);
1180 ret
= bq24190_read(bdi
, BQ24190_REG_F
, &f_reg
);
1182 dev_err(bdi
->dev
, "Can't read F reg: %d\n", ret
);
1185 } while (f_reg
&& ++i
< 2);
1187 if (f_reg
!= bdi
->f_reg
) {
1189 "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1190 !!(f_reg
& BQ24190_REG_F_BOOST_FAULT_MASK
),
1191 !!(f_reg
& BQ24190_REG_F_CHRG_FAULT_MASK
),
1192 !!(f_reg
& BQ24190_REG_F_BAT_FAULT_MASK
),
1193 !!(f_reg
& BQ24190_REG_F_NTC_FAULT_MASK
));
1195 mutex_lock(&bdi
->f_reg_lock
);
1196 if ((bdi
->f_reg
& battery_mask_f
) != (f_reg
& battery_mask_f
))
1197 alert_battery
= true;
1198 if ((bdi
->f_reg
& ~battery_mask_f
) != (f_reg
& ~battery_mask_f
))
1199 alert_charger
= true;
1201 mutex_unlock(&bdi
->f_reg_lock
);
1204 if (ss_reg
!= bdi
->ss_reg
) {
1206 * The device is in host mode so when PG_STAT goes from 1->0
1207 * (i.e., power removed) HIZ needs to be disabled.
1209 if ((bdi
->ss_reg
& BQ24190_REG_SS_PG_STAT_MASK
) &&
1210 !(ss_reg
& BQ24190_REG_SS_PG_STAT_MASK
)) {
1211 ret
= bq24190_write_mask(bdi
, BQ24190_REG_ISC
,
1212 BQ24190_REG_ISC_EN_HIZ_MASK
,
1213 BQ24190_REG_ISC_EN_HIZ_SHIFT
,
1216 dev_err(bdi
->dev
, "Can't access ISC reg: %d\n",
1220 if ((bdi
->ss_reg
& battery_mask_ss
) != (ss_reg
& battery_mask_ss
))
1221 alert_battery
= true;
1222 if ((bdi
->ss_reg
& ~battery_mask_ss
) != (ss_reg
& ~battery_mask_ss
))
1223 alert_charger
= true;
1224 bdi
->ss_reg
= ss_reg
;
1228 power_supply_changed(bdi
->charger
);
1230 power_supply_changed(bdi
->battery
);
1233 pm_runtime_put_sync(bdi
->dev
);
1235 dev_dbg(bdi
->dev
, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg
, f_reg
);
1240 static int bq24190_hw_init(struct bq24190_dev_info
*bdi
)
1245 pm_runtime_get_sync(bdi
->dev
);
1247 /* First check that the device really is what its supposed to be */
1248 ret
= bq24190_read_mask(bdi
, BQ24190_REG_VPRS
,
1249 BQ24190_REG_VPRS_PN_MASK
,
1250 BQ24190_REG_VPRS_PN_SHIFT
,
1255 if (v
!= bdi
->model
) {
1260 ret
= bq24190_register_reset(bdi
);
1264 ret
= bq24190_set_mode_host(bdi
);
1268 ret
= bq24190_read(bdi
, BQ24190_REG_SS
, &bdi
->ss_reg
);
1270 pm_runtime_put_sync(bdi
->dev
);
1275 static int bq24190_setup_dt(struct bq24190_dev_info
*bdi
)
1277 bdi
->irq
= irq_of_parse_and_map(bdi
->dev
->of_node
, 0);
1284 static int bq24190_setup_dt(struct bq24190_dev_info
*bdi
)
1290 static int bq24190_setup_pdata(struct bq24190_dev_info
*bdi
,
1291 struct bq24190_platform_data
*pdata
)
1295 if (!gpio_is_valid(pdata
->gpio_int
))
1298 ret
= gpio_request(pdata
->gpio_int
, dev_name(bdi
->dev
));
1302 ret
= gpio_direction_input(pdata
->gpio_int
);
1306 bdi
->irq
= gpio_to_irq(pdata
->gpio_int
);
1310 bdi
->gpio_int
= pdata
->gpio_int
;
1314 gpio_free(pdata
->gpio_int
);
1318 static int bq24190_probe(struct i2c_client
*client
,
1319 const struct i2c_device_id
*id
)
1321 struct i2c_adapter
*adapter
= to_i2c_adapter(client
->dev
.parent
);
1322 struct device
*dev
= &client
->dev
;
1323 struct bq24190_platform_data
*pdata
= client
->dev
.platform_data
;
1324 struct power_supply_config charger_cfg
= {}, battery_cfg
= {};
1325 struct bq24190_dev_info
*bdi
;
1328 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_BYTE_DATA
)) {
1329 dev_err(dev
, "No support for SMBUS_BYTE_DATA\n");
1333 bdi
= devm_kzalloc(dev
, sizeof(*bdi
), GFP_KERNEL
);
1335 dev_err(dev
, "Can't alloc bdi struct\n");
1339 bdi
->client
= client
;
1341 bdi
->model
= id
->driver_data
;
1342 strncpy(bdi
->model_name
, id
->name
, I2C_NAME_SIZE
);
1343 mutex_init(&bdi
->f_reg_lock
);
1345 bdi
->ss_reg
= BQ24190_REG_SS_VBUS_STAT_MASK
; /* impossible state */
1347 i2c_set_clientdata(client
, bdi
);
1350 ret
= bq24190_setup_dt(bdi
);
1352 ret
= bq24190_setup_pdata(bdi
, pdata
);
1355 dev_err(dev
, "Can't get irq info\n");
1359 pm_runtime_enable(dev
);
1360 pm_runtime_resume(dev
);
1362 ret
= bq24190_hw_init(bdi
);
1364 dev_err(dev
, "Hardware init failed\n");
1368 charger_cfg
.drv_data
= bdi
;
1369 charger_cfg
.supplied_to
= bq24190_charger_supplied_to
;
1370 charger_cfg
.num_supplicants
= ARRAY_SIZE(bq24190_charger_supplied_to
),
1371 bdi
->charger
= power_supply_register(dev
, &bq24190_charger_desc
,
1373 if (IS_ERR(bdi
->charger
)) {
1374 dev_err(dev
, "Can't register charger\n");
1375 ret
= PTR_ERR(bdi
->charger
);
1379 battery_cfg
.drv_data
= bdi
;
1380 bdi
->battery
= power_supply_register(dev
, &bq24190_battery_desc
,
1382 if (IS_ERR(bdi
->battery
)) {
1383 dev_err(dev
, "Can't register battery\n");
1384 ret
= PTR_ERR(bdi
->battery
);
1388 ret
= bq24190_sysfs_create_group(bdi
);
1390 dev_err(dev
, "Can't create sysfs entries\n");
1394 ret
= devm_request_threaded_irq(dev
, bdi
->irq
, NULL
,
1395 bq24190_irq_handler_thread
,
1396 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
1397 "bq24190-charger", bdi
);
1399 dev_err(dev
, "Can't set up irq handler\n");
1406 bq24190_sysfs_remove_group(bdi
);
1408 power_supply_unregister(bdi
->battery
);
1410 power_supply_unregister(bdi
->charger
);
1412 pm_runtime_disable(dev
);
1414 gpio_free(bdi
->gpio_int
);
1419 static int bq24190_remove(struct i2c_client
*client
)
1421 struct bq24190_dev_info
*bdi
= i2c_get_clientdata(client
);
1423 pm_runtime_get_sync(bdi
->dev
);
1424 bq24190_register_reset(bdi
);
1425 pm_runtime_put_sync(bdi
->dev
);
1427 bq24190_sysfs_remove_group(bdi
);
1428 power_supply_unregister(bdi
->battery
);
1429 power_supply_unregister(bdi
->charger
);
1430 pm_runtime_disable(bdi
->dev
);
1433 gpio_free(bdi
->gpio_int
);
1438 #ifdef CONFIG_PM_SLEEP
1439 static int bq24190_pm_suspend(struct device
*dev
)
1441 struct i2c_client
*client
= to_i2c_client(dev
);
1442 struct bq24190_dev_info
*bdi
= i2c_get_clientdata(client
);
1444 pm_runtime_get_sync(bdi
->dev
);
1445 bq24190_register_reset(bdi
);
1446 pm_runtime_put_sync(bdi
->dev
);
1451 static int bq24190_pm_resume(struct device
*dev
)
1453 struct i2c_client
*client
= to_i2c_client(dev
);
1454 struct bq24190_dev_info
*bdi
= i2c_get_clientdata(client
);
1457 bdi
->ss_reg
= BQ24190_REG_SS_VBUS_STAT_MASK
; /* impossible state */
1459 pm_runtime_get_sync(bdi
->dev
);
1460 bq24190_register_reset(bdi
);
1461 bq24190_set_mode_host(bdi
);
1462 bq24190_read(bdi
, BQ24190_REG_SS
, &bdi
->ss_reg
);
1463 pm_runtime_put_sync(bdi
->dev
);
1465 /* Things may have changed while suspended so alert upper layer */
1466 power_supply_changed(bdi
->charger
);
1467 power_supply_changed(bdi
->battery
);
1473 static SIMPLE_DEV_PM_OPS(bq24190_pm_ops
, bq24190_pm_suspend
, bq24190_pm_resume
);
1476 * Only support the bq24190 right now. The bq24192, bq24192i, and bq24193
1477 * are similar but not identical so the driver needs to be extended to
1480 static const struct i2c_device_id bq24190_i2c_ids
[] = {
1481 { "bq24190", BQ24190_REG_VPRS_PN_24190
},
1484 MODULE_DEVICE_TABLE(i2c
, bq24190_i2c_ids
);
1487 static const struct of_device_id bq24190_of_match
[] = {
1488 { .compatible
= "ti,bq24190", },
1491 MODULE_DEVICE_TABLE(of
, bq24190_of_match
);
1493 static const struct of_device_id bq24190_of_match
[] = {
1498 static struct i2c_driver bq24190_driver
= {
1499 .probe
= bq24190_probe
,
1500 .remove
= bq24190_remove
,
1501 .id_table
= bq24190_i2c_ids
,
1503 .name
= "bq24190-charger",
1504 .pm
= &bq24190_pm_ops
,
1505 .of_match_table
= of_match_ptr(bq24190_of_match
),
1508 module_i2c_driver(bq24190_driver
);
1510 MODULE_LICENSE("GPL");
1511 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1512 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");