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. Each routine has its own
148 * flag indicating whether it should use the value stored by the last run
149 * of the interrupt handler or do an actual reg read. That way each routine
150 * can report back whatever fault may have occured.
152 struct bq24190_dev_info
{
153 struct i2c_client
*client
;
155 struct power_supply
*charger
;
156 struct power_supply
*battery
;
157 char model_name
[I2C_NAME_SIZE
];
158 kernel_ulong_t model
;
159 unsigned int gpio_int
;
161 struct mutex f_reg_lock
;
163 bool charger_health_valid
;
164 bool battery_health_valid
;
165 bool battery_status_valid
;
172 * The tables below provide a 2-way mapping for the value that goes in
173 * the register field and the real-world value that it represents.
174 * The index of the array is the value that goes in the register; the
175 * number at that index in the array is the real-world value that it
178 /* REG02[7:2] (ICHG) in uAh */
179 static const int bq24190_ccc_ichg_values
[] = {
180 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
181 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
182 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
183 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
184 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
185 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
186 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
187 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
190 /* REG04[7:2] (VREG) in uV */
191 static const int bq24190_cvc_vreg_values
[] = {
192 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
193 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
194 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
195 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
196 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
197 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
198 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
202 /* REG06[1:0] (TREG) in tenths of degrees Celcius */
203 static const int bq24190_ictrc_treg_values
[] = {
208 * Return the index in 'tbl' of greatest value that is less than or equal to
209 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
210 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
213 static u8
bq24190_find_idx(const int tbl
[], int tbl_size
, int v
)
217 for (i
= 1; i
< tbl_size
; i
++)
224 /* Basic driver I/O routines */
226 static int bq24190_read(struct bq24190_dev_info
*bdi
, u8 reg
, u8
*data
)
230 ret
= i2c_smbus_read_byte_data(bdi
->client
, reg
);
238 static int bq24190_write(struct bq24190_dev_info
*bdi
, u8 reg
, u8 data
)
240 return i2c_smbus_write_byte_data(bdi
->client
, reg
, data
);
243 static int bq24190_read_mask(struct bq24190_dev_info
*bdi
, u8 reg
,
244 u8 mask
, u8 shift
, u8
*data
)
249 ret
= bq24190_read(bdi
, reg
, &v
);
260 static int bq24190_write_mask(struct bq24190_dev_info
*bdi
, u8 reg
,
261 u8 mask
, u8 shift
, u8 data
)
266 ret
= bq24190_read(bdi
, reg
, &v
);
271 v
|= ((data
<< shift
) & mask
);
273 return bq24190_write(bdi
, reg
, v
);
276 static int bq24190_get_field_val(struct bq24190_dev_info
*bdi
,
277 u8 reg
, u8 mask
, u8 shift
,
278 const int tbl
[], int tbl_size
,
284 ret
= bq24190_read_mask(bdi
, reg
, mask
, shift
, &v
);
288 v
= (v
>= tbl_size
) ? (tbl_size
- 1) : v
;
294 static int bq24190_set_field_val(struct bq24190_dev_info
*bdi
,
295 u8 reg
, u8 mask
, u8 shift
,
296 const int tbl
[], int tbl_size
,
301 idx
= bq24190_find_idx(tbl
, tbl_size
, val
);
303 return bq24190_write_mask(bdi
, reg
, mask
, shift
, idx
);
308 * There are a numerous options that are configurable on the bq24190
309 * that go well beyond what the power_supply properties provide access to.
310 * Provide sysfs access to them so they can be examined and possibly modified
311 * on the fly. They will be provided for the charger power_supply object only
312 * and will be prefixed by 'f_' to make them easier to recognize.
315 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
317 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
318 .reg = BQ24190_REG_##r, \
319 .mask = BQ24190_REG_##r##_##f##_MASK, \
320 .shift = BQ24190_REG_##r##_##f##_SHIFT, \
323 #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
324 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
327 #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
328 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
330 static ssize_t
bq24190_sysfs_show(struct device
*dev
,
331 struct device_attribute
*attr
, char *buf
);
332 static ssize_t
bq24190_sysfs_store(struct device
*dev
,
333 struct device_attribute
*attr
, const char *buf
, size_t count
);
335 struct bq24190_sysfs_field_info
{
336 struct device_attribute attr
;
342 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
345 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl
[] = {
346 /* sysfs name reg field in reg */
347 BQ24190_SYSFS_FIELD_RW(en_hiz
, ISC
, EN_HIZ
),
348 BQ24190_SYSFS_FIELD_RW(vindpm
, ISC
, VINDPM
),
349 BQ24190_SYSFS_FIELD_RW(iinlim
, ISC
, IINLIM
),
350 BQ24190_SYSFS_FIELD_RW(chg_config
, POC
, CHG_CONFIG
),
351 BQ24190_SYSFS_FIELD_RW(sys_min
, POC
, SYS_MIN
),
352 BQ24190_SYSFS_FIELD_RW(boost_lim
, POC
, BOOST_LIM
),
353 BQ24190_SYSFS_FIELD_RW(ichg
, CCC
, ICHG
),
354 BQ24190_SYSFS_FIELD_RW(force_20_pct
, CCC
, FORCE_20PCT
),
355 BQ24190_SYSFS_FIELD_RW(iprechg
, PCTCC
, IPRECHG
),
356 BQ24190_SYSFS_FIELD_RW(iterm
, PCTCC
, ITERM
),
357 BQ24190_SYSFS_FIELD_RW(vreg
, CVC
, VREG
),
358 BQ24190_SYSFS_FIELD_RW(batlowv
, CVC
, BATLOWV
),
359 BQ24190_SYSFS_FIELD_RW(vrechg
, CVC
, VRECHG
),
360 BQ24190_SYSFS_FIELD_RW(en_term
, CTTC
, EN_TERM
),
361 BQ24190_SYSFS_FIELD_RW(term_stat
, CTTC
, TERM_STAT
),
362 BQ24190_SYSFS_FIELD_RO(watchdog
, CTTC
, WATCHDOG
),
363 BQ24190_SYSFS_FIELD_RW(en_timer
, CTTC
, EN_TIMER
),
364 BQ24190_SYSFS_FIELD_RW(chg_timer
, CTTC
, CHG_TIMER
),
365 BQ24190_SYSFS_FIELD_RW(jeta_iset
, CTTC
, JEITA_ISET
),
366 BQ24190_SYSFS_FIELD_RW(bat_comp
, ICTRC
, BAT_COMP
),
367 BQ24190_SYSFS_FIELD_RW(vclamp
, ICTRC
, VCLAMP
),
368 BQ24190_SYSFS_FIELD_RW(treg
, ICTRC
, TREG
),
369 BQ24190_SYSFS_FIELD_RW(dpdm_en
, MOC
, DPDM_EN
),
370 BQ24190_SYSFS_FIELD_RW(tmr2x_en
, MOC
, TMR2X_EN
),
371 BQ24190_SYSFS_FIELD_RW(batfet_disable
, MOC
, BATFET_DISABLE
),
372 BQ24190_SYSFS_FIELD_RW(jeita_vset
, MOC
, JEITA_VSET
),
373 BQ24190_SYSFS_FIELD_RO(int_mask
, MOC
, INT_MASK
),
374 BQ24190_SYSFS_FIELD_RO(vbus_stat
, SS
, VBUS_STAT
),
375 BQ24190_SYSFS_FIELD_RO(chrg_stat
, SS
, CHRG_STAT
),
376 BQ24190_SYSFS_FIELD_RO(dpm_stat
, SS
, DPM_STAT
),
377 BQ24190_SYSFS_FIELD_RO(pg_stat
, SS
, PG_STAT
),
378 BQ24190_SYSFS_FIELD_RO(therm_stat
, SS
, THERM_STAT
),
379 BQ24190_SYSFS_FIELD_RO(vsys_stat
, SS
, VSYS_STAT
),
380 BQ24190_SYSFS_FIELD_RO(watchdog_fault
, F
, WATCHDOG_FAULT
),
381 BQ24190_SYSFS_FIELD_RO(boost_fault
, F
, BOOST_FAULT
),
382 BQ24190_SYSFS_FIELD_RO(chrg_fault
, F
, CHRG_FAULT
),
383 BQ24190_SYSFS_FIELD_RO(bat_fault
, F
, BAT_FAULT
),
384 BQ24190_SYSFS_FIELD_RO(ntc_fault
, F
, NTC_FAULT
),
385 BQ24190_SYSFS_FIELD_RO(pn
, VPRS
, PN
),
386 BQ24190_SYSFS_FIELD_RO(ts_profile
, VPRS
, TS_PROFILE
),
387 BQ24190_SYSFS_FIELD_RO(dev_reg
, VPRS
, DEV_REG
),
390 static struct attribute
*
391 bq24190_sysfs_attrs
[ARRAY_SIZE(bq24190_sysfs_field_tbl
) + 1];
393 static const struct attribute_group bq24190_sysfs_attr_group
= {
394 .attrs
= bq24190_sysfs_attrs
,
397 static void bq24190_sysfs_init_attrs(void)
399 int i
, limit
= ARRAY_SIZE(bq24190_sysfs_field_tbl
);
401 for (i
= 0; i
< limit
; i
++)
402 bq24190_sysfs_attrs
[i
] = &bq24190_sysfs_field_tbl
[i
].attr
.attr
;
404 bq24190_sysfs_attrs
[limit
] = NULL
; /* Has additional entry for this */
407 static struct bq24190_sysfs_field_info
*bq24190_sysfs_field_lookup(
410 int i
, limit
= ARRAY_SIZE(bq24190_sysfs_field_tbl
);
412 for (i
= 0; i
< limit
; i
++)
413 if (!strcmp(name
, bq24190_sysfs_field_tbl
[i
].attr
.attr
.name
))
419 return &bq24190_sysfs_field_tbl
[i
];
422 static ssize_t
bq24190_sysfs_show(struct device
*dev
,
423 struct device_attribute
*attr
, char *buf
)
425 struct power_supply
*psy
= dev_get_drvdata(dev
);
426 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
427 struct bq24190_sysfs_field_info
*info
;
431 info
= bq24190_sysfs_field_lookup(attr
->attr
.name
);
435 ret
= bq24190_read_mask(bdi
, info
->reg
, info
->mask
, info
->shift
, &v
);
439 return scnprintf(buf
, PAGE_SIZE
, "%hhx\n", v
);
442 static ssize_t
bq24190_sysfs_store(struct device
*dev
,
443 struct device_attribute
*attr
, const char *buf
, size_t count
)
445 struct power_supply
*psy
= dev_get_drvdata(dev
);
446 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
447 struct bq24190_sysfs_field_info
*info
;
451 info
= bq24190_sysfs_field_lookup(attr
->attr
.name
);
455 ret
= kstrtou8(buf
, 0, &v
);
459 ret
= bq24190_write_mask(bdi
, info
->reg
, info
->mask
, info
->shift
, v
);
466 static int bq24190_sysfs_create_group(struct bq24190_dev_info
*bdi
)
468 bq24190_sysfs_init_attrs();
470 return sysfs_create_group(&bdi
->charger
->dev
.kobj
,
471 &bq24190_sysfs_attr_group
);
474 static void bq24190_sysfs_remove_group(struct bq24190_dev_info
*bdi
)
476 sysfs_remove_group(&bdi
->charger
->dev
.kobj
, &bq24190_sysfs_attr_group
);
479 static int bq24190_sysfs_create_group(struct bq24190_dev_info
*bdi
)
484 static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info
*bdi
) {}
488 * According to the "Host Mode and default Mode" section of the
489 * manual, a write to any register causes the bq24190 to switch
490 * from default mode to host mode. It will switch back to default
491 * mode after a WDT timeout unless the WDT is turned off as well.
492 * So, by simply turning off the WDT, we accomplish both with the
495 static int bq24190_set_mode_host(struct bq24190_dev_info
*bdi
)
500 ret
= bq24190_read(bdi
, BQ24190_REG_CTTC
, &v
);
504 bdi
->watchdog
= ((v
& BQ24190_REG_CTTC_WATCHDOG_MASK
) >>
505 BQ24190_REG_CTTC_WATCHDOG_SHIFT
);
506 v
&= ~BQ24190_REG_CTTC_WATCHDOG_MASK
;
508 return bq24190_write(bdi
, BQ24190_REG_CTTC
, v
);
511 static int bq24190_register_reset(struct bq24190_dev_info
*bdi
)
513 int ret
, limit
= 100;
516 /* Reset the registers */
517 ret
= bq24190_write_mask(bdi
, BQ24190_REG_POC
,
518 BQ24190_REG_POC_RESET_MASK
,
519 BQ24190_REG_POC_RESET_SHIFT
,
524 /* Reset bit will be cleared by hardware so poll until it is */
526 ret
= bq24190_read_mask(bdi
, BQ24190_REG_POC
,
527 BQ24190_REG_POC_RESET_MASK
,
528 BQ24190_REG_POC_RESET_SHIFT
,
545 /* Charger power supply property routines */
547 static int bq24190_charger_get_charge_type(struct bq24190_dev_info
*bdi
,
548 union power_supply_propval
*val
)
553 ret
= bq24190_read_mask(bdi
, BQ24190_REG_POC
,
554 BQ24190_REG_POC_CHG_CONFIG_MASK
,
555 BQ24190_REG_POC_CHG_CONFIG_SHIFT
,
560 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
562 type
= POWER_SUPPLY_CHARGE_TYPE_NONE
;
564 ret
= bq24190_read_mask(bdi
, BQ24190_REG_CCC
,
565 BQ24190_REG_CCC_FORCE_20PCT_MASK
,
566 BQ24190_REG_CCC_FORCE_20PCT_SHIFT
,
571 type
= (v
) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE
:
572 POWER_SUPPLY_CHARGE_TYPE_FAST
;
580 static int bq24190_charger_set_charge_type(struct bq24190_dev_info
*bdi
,
581 const union power_supply_propval
*val
)
583 u8 chg_config
, force_20pct
, en_term
;
587 * According to the "Termination when REG02[0] = 1" section of
588 * the bq24190 manual, the trickle charge could be less than the
589 * termination current so it recommends turning off the termination
592 * Note: AFAICT from the datasheet, the user will have to manually
593 * turn off the charging when in 20% mode. If its not turned off,
594 * there could be battery damage. So, use this mode at your own risk.
596 switch (val
->intval
) {
597 case POWER_SUPPLY_CHARGE_TYPE_NONE
:
600 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE
:
605 case POWER_SUPPLY_CHARGE_TYPE_FAST
:
614 if (chg_config
) { /* Enabling the charger */
615 ret
= bq24190_write_mask(bdi
, BQ24190_REG_CCC
,
616 BQ24190_REG_CCC_FORCE_20PCT_MASK
,
617 BQ24190_REG_CCC_FORCE_20PCT_SHIFT
,
622 ret
= bq24190_write_mask(bdi
, BQ24190_REG_CTTC
,
623 BQ24190_REG_CTTC_EN_TERM_MASK
,
624 BQ24190_REG_CTTC_EN_TERM_SHIFT
,
630 return bq24190_write_mask(bdi
, BQ24190_REG_POC
,
631 BQ24190_REG_POC_CHG_CONFIG_MASK
,
632 BQ24190_REG_POC_CHG_CONFIG_SHIFT
, chg_config
);
635 static int bq24190_charger_get_health(struct bq24190_dev_info
*bdi
,
636 union power_supply_propval
*val
)
641 mutex_lock(&bdi
->f_reg_lock
);
643 if (bdi
->charger_health_valid
) {
645 bdi
->charger_health_valid
= false;
646 mutex_unlock(&bdi
->f_reg_lock
);
648 mutex_unlock(&bdi
->f_reg_lock
);
650 ret
= bq24190_read(bdi
, BQ24190_REG_F
, &v
);
655 if (v
& BQ24190_REG_F_BOOST_FAULT_MASK
) {
657 * This could be over-current or over-voltage but there's
658 * no way to tell which. Return 'OVERVOLTAGE' since there
659 * isn't an 'OVERCURRENT' value defined that we can return
660 * even if it was over-current.
662 health
= POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
664 v
&= BQ24190_REG_F_CHRG_FAULT_MASK
;
665 v
>>= BQ24190_REG_F_CHRG_FAULT_SHIFT
;
668 case 0x0: /* Normal */
669 health
= POWER_SUPPLY_HEALTH_GOOD
;
671 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
673 * This could be over-voltage or under-voltage
674 * and there's no way to tell which. Instead
675 * of looking foolish and returning 'OVERVOLTAGE'
676 * when its really under-voltage, just return
679 health
= POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
;
681 case 0x2: /* Thermal Shutdown */
682 health
= POWER_SUPPLY_HEALTH_OVERHEAT
;
684 case 0x3: /* Charge Safety Timer Expiration */
685 health
= POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE
;
688 health
= POWER_SUPPLY_HEALTH_UNKNOWN
;
692 val
->intval
= health
;
697 static int bq24190_charger_get_online(struct bq24190_dev_info
*bdi
,
698 union power_supply_propval
*val
)
703 ret
= bq24190_read_mask(bdi
, BQ24190_REG_SS
,
704 BQ24190_REG_SS_PG_STAT_MASK
,
705 BQ24190_REG_SS_PG_STAT_SHIFT
, &v
);
713 static int bq24190_charger_get_current(struct bq24190_dev_info
*bdi
,
714 union power_supply_propval
*val
)
719 ret
= bq24190_get_field_val(bdi
, BQ24190_REG_CCC
,
720 BQ24190_REG_CCC_ICHG_MASK
, BQ24190_REG_CCC_ICHG_SHIFT
,
721 bq24190_ccc_ichg_values
,
722 ARRAY_SIZE(bq24190_ccc_ichg_values
), &curr
);
726 ret
= bq24190_read_mask(bdi
, BQ24190_REG_CCC
,
727 BQ24190_REG_CCC_FORCE_20PCT_MASK
,
728 BQ24190_REG_CCC_FORCE_20PCT_SHIFT
, &v
);
732 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
740 static int bq24190_charger_get_current_max(struct bq24190_dev_info
*bdi
,
741 union power_supply_propval
*val
)
743 int idx
= ARRAY_SIZE(bq24190_ccc_ichg_values
) - 1;
745 val
->intval
= bq24190_ccc_ichg_values
[idx
];
749 static int bq24190_charger_set_current(struct bq24190_dev_info
*bdi
,
750 const union power_supply_propval
*val
)
753 int ret
, curr
= val
->intval
;
755 ret
= bq24190_read_mask(bdi
, BQ24190_REG_CCC
,
756 BQ24190_REG_CCC_FORCE_20PCT_MASK
,
757 BQ24190_REG_CCC_FORCE_20PCT_SHIFT
, &v
);
761 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
765 return bq24190_set_field_val(bdi
, BQ24190_REG_CCC
,
766 BQ24190_REG_CCC_ICHG_MASK
, BQ24190_REG_CCC_ICHG_SHIFT
,
767 bq24190_ccc_ichg_values
,
768 ARRAY_SIZE(bq24190_ccc_ichg_values
), curr
);
771 static int bq24190_charger_get_voltage(struct bq24190_dev_info
*bdi
,
772 union power_supply_propval
*val
)
776 ret
= bq24190_get_field_val(bdi
, BQ24190_REG_CVC
,
777 BQ24190_REG_CVC_VREG_MASK
, BQ24190_REG_CVC_VREG_SHIFT
,
778 bq24190_cvc_vreg_values
,
779 ARRAY_SIZE(bq24190_cvc_vreg_values
), &voltage
);
783 val
->intval
= voltage
;
787 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info
*bdi
,
788 union power_supply_propval
*val
)
790 int idx
= ARRAY_SIZE(bq24190_cvc_vreg_values
) - 1;
792 val
->intval
= bq24190_cvc_vreg_values
[idx
];
796 static int bq24190_charger_set_voltage(struct bq24190_dev_info
*bdi
,
797 const union power_supply_propval
*val
)
799 return bq24190_set_field_val(bdi
, BQ24190_REG_CVC
,
800 BQ24190_REG_CVC_VREG_MASK
, BQ24190_REG_CVC_VREG_SHIFT
,
801 bq24190_cvc_vreg_values
,
802 ARRAY_SIZE(bq24190_cvc_vreg_values
), val
->intval
);
805 static int bq24190_charger_get_property(struct power_supply
*psy
,
806 enum power_supply_property psp
, union power_supply_propval
*val
)
808 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
811 dev_dbg(bdi
->dev
, "prop: %d\n", psp
);
813 pm_runtime_get_sync(bdi
->dev
);
816 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
817 ret
= bq24190_charger_get_charge_type(bdi
, val
);
819 case POWER_SUPPLY_PROP_HEALTH
:
820 ret
= bq24190_charger_get_health(bdi
, val
);
822 case POWER_SUPPLY_PROP_ONLINE
:
823 ret
= bq24190_charger_get_online(bdi
, val
);
825 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
826 ret
= bq24190_charger_get_current(bdi
, val
);
828 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
829 ret
= bq24190_charger_get_current_max(bdi
, val
);
831 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
832 ret
= bq24190_charger_get_voltage(bdi
, val
);
834 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
:
835 ret
= bq24190_charger_get_voltage_max(bdi
, val
);
837 case POWER_SUPPLY_PROP_SCOPE
:
838 val
->intval
= POWER_SUPPLY_SCOPE_SYSTEM
;
841 case POWER_SUPPLY_PROP_MODEL_NAME
:
842 val
->strval
= bdi
->model_name
;
845 case POWER_SUPPLY_PROP_MANUFACTURER
:
846 val
->strval
= BQ24190_MANUFACTURER
;
853 pm_runtime_put_sync(bdi
->dev
);
857 static int bq24190_charger_set_property(struct power_supply
*psy
,
858 enum power_supply_property psp
,
859 const union power_supply_propval
*val
)
861 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
864 dev_dbg(bdi
->dev
, "prop: %d\n", psp
);
866 pm_runtime_get_sync(bdi
->dev
);
869 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
870 ret
= bq24190_charger_set_charge_type(bdi
, val
);
872 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
873 ret
= bq24190_charger_set_current(bdi
, val
);
875 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
876 ret
= bq24190_charger_set_voltage(bdi
, val
);
882 pm_runtime_put_sync(bdi
->dev
);
886 static int bq24190_charger_property_is_writeable(struct power_supply
*psy
,
887 enum power_supply_property psp
)
892 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
893 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
894 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
:
904 static enum power_supply_property bq24190_charger_properties
[] = {
905 POWER_SUPPLY_PROP_TYPE
,
906 POWER_SUPPLY_PROP_HEALTH
,
907 POWER_SUPPLY_PROP_ONLINE
,
908 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
,
909 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
,
910 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE
,
911 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX
,
912 POWER_SUPPLY_PROP_SCOPE
,
913 POWER_SUPPLY_PROP_MODEL_NAME
,
914 POWER_SUPPLY_PROP_MANUFACTURER
,
917 static char *bq24190_charger_supplied_to
[] = {
921 static const struct power_supply_desc bq24190_charger_desc
= {
922 .name
= "bq24190-charger",
923 .type
= POWER_SUPPLY_TYPE_USB
,
924 .properties
= bq24190_charger_properties
,
925 .num_properties
= ARRAY_SIZE(bq24190_charger_properties
),
926 .get_property
= bq24190_charger_get_property
,
927 .set_property
= bq24190_charger_set_property
,
928 .property_is_writeable
= bq24190_charger_property_is_writeable
,
931 /* Battery power supply property routines */
933 static int bq24190_battery_get_status(struct bq24190_dev_info
*bdi
,
934 union power_supply_propval
*val
)
936 u8 ss_reg
, chrg_fault
;
939 mutex_lock(&bdi
->f_reg_lock
);
941 if (bdi
->battery_status_valid
) {
942 chrg_fault
= bdi
->f_reg
;
943 bdi
->battery_status_valid
= false;
944 mutex_unlock(&bdi
->f_reg_lock
);
946 mutex_unlock(&bdi
->f_reg_lock
);
948 ret
= bq24190_read(bdi
, BQ24190_REG_F
, &chrg_fault
);
953 chrg_fault
&= BQ24190_REG_F_CHRG_FAULT_MASK
;
954 chrg_fault
>>= BQ24190_REG_F_CHRG_FAULT_SHIFT
;
956 ret
= bq24190_read(bdi
, BQ24190_REG_SS
, &ss_reg
);
961 * The battery must be discharging when any of these are true:
962 * - there is no good power source;
963 * - there is a charge fault.
964 * Could also be discharging when in "supplement mode" but
965 * there is no way to tell when its in that mode.
967 if (!(ss_reg
& BQ24190_REG_SS_PG_STAT_MASK
) || chrg_fault
) {
968 status
= POWER_SUPPLY_STATUS_DISCHARGING
;
970 ss_reg
&= BQ24190_REG_SS_CHRG_STAT_MASK
;
971 ss_reg
>>= BQ24190_REG_SS_CHRG_STAT_SHIFT
;
974 case 0x0: /* Not Charging */
975 status
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
977 case 0x1: /* Pre-charge */
978 case 0x2: /* Fast Charging */
979 status
= POWER_SUPPLY_STATUS_CHARGING
;
981 case 0x3: /* Charge Termination Done */
982 status
= POWER_SUPPLY_STATUS_FULL
;
990 val
->intval
= status
;
995 static int bq24190_battery_get_health(struct bq24190_dev_info
*bdi
,
996 union power_supply_propval
*val
)
1001 mutex_lock(&bdi
->f_reg_lock
);
1003 if (bdi
->battery_health_valid
) {
1005 bdi
->battery_health_valid
= false;
1006 mutex_unlock(&bdi
->f_reg_lock
);
1008 mutex_unlock(&bdi
->f_reg_lock
);
1010 ret
= bq24190_read(bdi
, BQ24190_REG_F
, &v
);
1015 if (v
& BQ24190_REG_F_BAT_FAULT_MASK
) {
1016 health
= POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
1018 v
&= BQ24190_REG_F_NTC_FAULT_MASK
;
1019 v
>>= BQ24190_REG_F_NTC_FAULT_SHIFT
;
1022 case 0x0: /* Normal */
1023 health
= POWER_SUPPLY_HEALTH_GOOD
;
1025 case 0x1: /* TS1 Cold */
1026 case 0x3: /* TS2 Cold */
1027 case 0x5: /* Both Cold */
1028 health
= POWER_SUPPLY_HEALTH_COLD
;
1030 case 0x2: /* TS1 Hot */
1031 case 0x4: /* TS2 Hot */
1032 case 0x6: /* Both Hot */
1033 health
= POWER_SUPPLY_HEALTH_OVERHEAT
;
1036 health
= POWER_SUPPLY_HEALTH_UNKNOWN
;
1040 val
->intval
= health
;
1044 static int bq24190_battery_get_online(struct bq24190_dev_info
*bdi
,
1045 union power_supply_propval
*val
)
1050 ret
= bq24190_read_mask(bdi
, BQ24190_REG_MOC
,
1051 BQ24190_REG_MOC_BATFET_DISABLE_MASK
,
1052 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT
, &batfet_disable
);
1056 val
->intval
= !batfet_disable
;
1060 static int bq24190_battery_set_online(struct bq24190_dev_info
*bdi
,
1061 const union power_supply_propval
*val
)
1063 return bq24190_write_mask(bdi
, BQ24190_REG_MOC
,
1064 BQ24190_REG_MOC_BATFET_DISABLE_MASK
,
1065 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT
, !val
->intval
);
1068 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info
*bdi
,
1069 union power_supply_propval
*val
)
1073 ret
= bq24190_get_field_val(bdi
, BQ24190_REG_ICTRC
,
1074 BQ24190_REG_ICTRC_TREG_MASK
,
1075 BQ24190_REG_ICTRC_TREG_SHIFT
,
1076 bq24190_ictrc_treg_values
,
1077 ARRAY_SIZE(bq24190_ictrc_treg_values
), &temp
);
1085 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info
*bdi
,
1086 const union power_supply_propval
*val
)
1088 return bq24190_set_field_val(bdi
, BQ24190_REG_ICTRC
,
1089 BQ24190_REG_ICTRC_TREG_MASK
,
1090 BQ24190_REG_ICTRC_TREG_SHIFT
,
1091 bq24190_ictrc_treg_values
,
1092 ARRAY_SIZE(bq24190_ictrc_treg_values
), val
->intval
);
1095 static int bq24190_battery_get_property(struct power_supply
*psy
,
1096 enum power_supply_property psp
, union power_supply_propval
*val
)
1098 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
1101 dev_dbg(bdi
->dev
, "prop: %d\n", psp
);
1103 pm_runtime_get_sync(bdi
->dev
);
1106 case POWER_SUPPLY_PROP_STATUS
:
1107 ret
= bq24190_battery_get_status(bdi
, val
);
1109 case POWER_SUPPLY_PROP_HEALTH
:
1110 ret
= bq24190_battery_get_health(bdi
, val
);
1112 case POWER_SUPPLY_PROP_ONLINE
:
1113 ret
= bq24190_battery_get_online(bdi
, val
);
1115 case POWER_SUPPLY_PROP_TECHNOLOGY
:
1116 /* Could be Li-on or Li-polymer but no way to tell which */
1117 val
->intval
= POWER_SUPPLY_TECHNOLOGY_UNKNOWN
;
1120 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX
:
1121 ret
= bq24190_battery_get_temp_alert_max(bdi
, val
);
1123 case POWER_SUPPLY_PROP_SCOPE
:
1124 val
->intval
= POWER_SUPPLY_SCOPE_SYSTEM
;
1131 pm_runtime_put_sync(bdi
->dev
);
1135 static int bq24190_battery_set_property(struct power_supply
*psy
,
1136 enum power_supply_property psp
,
1137 const union power_supply_propval
*val
)
1139 struct bq24190_dev_info
*bdi
= power_supply_get_drvdata(psy
);
1142 dev_dbg(bdi
->dev
, "prop: %d\n", psp
);
1144 pm_runtime_put_sync(bdi
->dev
);
1147 case POWER_SUPPLY_PROP_ONLINE
:
1148 ret
= bq24190_battery_set_online(bdi
, val
);
1150 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX
:
1151 ret
= bq24190_battery_set_temp_alert_max(bdi
, val
);
1157 pm_runtime_put_sync(bdi
->dev
);
1161 static int bq24190_battery_property_is_writeable(struct power_supply
*psy
,
1162 enum power_supply_property psp
)
1167 case POWER_SUPPLY_PROP_ONLINE
:
1168 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX
:
1178 static enum power_supply_property bq24190_battery_properties
[] = {
1179 POWER_SUPPLY_PROP_STATUS
,
1180 POWER_SUPPLY_PROP_HEALTH
,
1181 POWER_SUPPLY_PROP_ONLINE
,
1182 POWER_SUPPLY_PROP_TECHNOLOGY
,
1183 POWER_SUPPLY_PROP_TEMP_ALERT_MAX
,
1184 POWER_SUPPLY_PROP_SCOPE
,
1187 static const struct power_supply_desc bq24190_battery_desc
= {
1188 .name
= "bq24190-battery",
1189 .type
= POWER_SUPPLY_TYPE_BATTERY
,
1190 .properties
= bq24190_battery_properties
,
1191 .num_properties
= ARRAY_SIZE(bq24190_battery_properties
),
1192 .get_property
= bq24190_battery_get_property
,
1193 .set_property
= bq24190_battery_set_property
,
1194 .property_is_writeable
= bq24190_battery_property_is_writeable
,
1197 static irqreturn_t
bq24190_irq_handler_thread(int irq
, void *data
)
1199 struct bq24190_dev_info
*bdi
= data
;
1200 bool alert_userspace
= false;
1201 u8 ss_reg
= 0, f_reg
= 0;
1204 pm_runtime_get_sync(bdi
->dev
);
1206 ret
= bq24190_read(bdi
, BQ24190_REG_SS
, &ss_reg
);
1208 dev_err(bdi
->dev
, "Can't read SS reg: %d\n", ret
);
1212 if (ss_reg
!= bdi
->ss_reg
) {
1214 * The device is in host mode so when PG_STAT goes from 1->0
1215 * (i.e., power removed) HIZ needs to be disabled.
1217 if ((bdi
->ss_reg
& BQ24190_REG_SS_PG_STAT_MASK
) &&
1218 !(ss_reg
& BQ24190_REG_SS_PG_STAT_MASK
)) {
1219 ret
= bq24190_write_mask(bdi
, BQ24190_REG_ISC
,
1220 BQ24190_REG_ISC_EN_HIZ_MASK
,
1221 BQ24190_REG_ISC_EN_HIZ_SHIFT
,
1224 dev_err(bdi
->dev
, "Can't access ISC reg: %d\n",
1228 bdi
->ss_reg
= ss_reg
;
1229 alert_userspace
= true;
1232 mutex_lock(&bdi
->f_reg_lock
);
1234 ret
= bq24190_read(bdi
, BQ24190_REG_F
, &f_reg
);
1236 mutex_unlock(&bdi
->f_reg_lock
);
1237 dev_err(bdi
->dev
, "Can't read F reg: %d\n", ret
);
1241 if (f_reg
!= bdi
->f_reg
) {
1243 bdi
->charger_health_valid
= true;
1244 bdi
->battery_health_valid
= true;
1245 bdi
->battery_status_valid
= true;
1247 alert_userspace
= true;
1250 mutex_unlock(&bdi
->f_reg_lock
);
1253 * Sometimes bq24190 gives a steady trickle of interrupts even
1254 * though the watchdog timer is turned off and neither the STATUS
1255 * nor FAULT registers have changed. Weed out these sprurious
1256 * interrupts so userspace isn't alerted for no reason.
1257 * In addition, the chip always generates an interrupt after
1258 * register reset so we should ignore that one (the very first
1259 * interrupt received).
1261 if (alert_userspace
&& !bdi
->first_time
) {
1262 power_supply_changed(bdi
->charger
);
1263 power_supply_changed(bdi
->battery
);
1264 bdi
->first_time
= false;
1268 pm_runtime_put_sync(bdi
->dev
);
1270 dev_dbg(bdi
->dev
, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg
, f_reg
);
1275 static int bq24190_hw_init(struct bq24190_dev_info
*bdi
)
1280 pm_runtime_get_sync(bdi
->dev
);
1282 /* First check that the device really is what its supposed to be */
1283 ret
= bq24190_read_mask(bdi
, BQ24190_REG_VPRS
,
1284 BQ24190_REG_VPRS_PN_MASK
,
1285 BQ24190_REG_VPRS_PN_SHIFT
,
1290 if (v
!= bdi
->model
) {
1295 ret
= bq24190_register_reset(bdi
);
1299 ret
= bq24190_set_mode_host(bdi
);
1301 pm_runtime_put_sync(bdi
->dev
);
1306 static int bq24190_setup_dt(struct bq24190_dev_info
*bdi
)
1308 bdi
->irq
= irq_of_parse_and_map(bdi
->dev
->of_node
, 0);
1315 static int bq24190_setup_dt(struct bq24190_dev_info
*bdi
)
1321 static int bq24190_setup_pdata(struct bq24190_dev_info
*bdi
,
1322 struct bq24190_platform_data
*pdata
)
1326 if (!gpio_is_valid(pdata
->gpio_int
))
1329 ret
= gpio_request(pdata
->gpio_int
, dev_name(bdi
->dev
));
1333 ret
= gpio_direction_input(pdata
->gpio_int
);
1337 bdi
->irq
= gpio_to_irq(pdata
->gpio_int
);
1341 bdi
->gpio_int
= pdata
->gpio_int
;
1345 gpio_free(pdata
->gpio_int
);
1349 static int bq24190_probe(struct i2c_client
*client
,
1350 const struct i2c_device_id
*id
)
1352 struct i2c_adapter
*adapter
= to_i2c_adapter(client
->dev
.parent
);
1353 struct device
*dev
= &client
->dev
;
1354 struct bq24190_platform_data
*pdata
= client
->dev
.platform_data
;
1355 struct power_supply_config charger_cfg
= {}, battery_cfg
= {};
1356 struct bq24190_dev_info
*bdi
;
1359 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_BYTE_DATA
)) {
1360 dev_err(dev
, "No support for SMBUS_BYTE_DATA\n");
1364 bdi
= devm_kzalloc(dev
, sizeof(*bdi
), GFP_KERNEL
);
1366 dev_err(dev
, "Can't alloc bdi struct\n");
1370 bdi
->client
= client
;
1372 bdi
->model
= id
->driver_data
;
1373 strncpy(bdi
->model_name
, id
->name
, I2C_NAME_SIZE
);
1374 mutex_init(&bdi
->f_reg_lock
);
1375 bdi
->first_time
= true;
1376 bdi
->charger_health_valid
= false;
1377 bdi
->battery_health_valid
= false;
1378 bdi
->battery_status_valid
= false;
1380 i2c_set_clientdata(client
, bdi
);
1383 ret
= bq24190_setup_dt(bdi
);
1385 ret
= bq24190_setup_pdata(bdi
, pdata
);
1388 dev_err(dev
, "Can't get irq info\n");
1392 ret
= devm_request_threaded_irq(dev
, bdi
->irq
, NULL
,
1393 bq24190_irq_handler_thread
,
1394 IRQF_TRIGGER_RISING
| IRQF_ONESHOT
,
1395 "bq24190-charger", bdi
);
1397 dev_err(dev
, "Can't set up irq handler\n");
1401 pm_runtime_enable(dev
);
1402 pm_runtime_resume(dev
);
1404 ret
= bq24190_hw_init(bdi
);
1406 dev_err(dev
, "Hardware init failed\n");
1410 charger_cfg
.drv_data
= bdi
;
1411 charger_cfg
.supplied_to
= bq24190_charger_supplied_to
;
1412 charger_cfg
.num_supplicants
= ARRAY_SIZE(bq24190_charger_supplied_to
),
1413 bdi
->charger
= power_supply_register(dev
, &bq24190_charger_desc
,
1415 if (IS_ERR(bdi
->charger
)) {
1416 dev_err(dev
, "Can't register charger\n");
1417 ret
= PTR_ERR(bdi
->charger
);
1421 battery_cfg
.drv_data
= bdi
;
1422 bdi
->battery
= power_supply_register(dev
, &bq24190_battery_desc
,
1424 if (IS_ERR(bdi
->battery
)) {
1425 dev_err(dev
, "Can't register battery\n");
1426 ret
= PTR_ERR(bdi
->battery
);
1430 ret
= bq24190_sysfs_create_group(bdi
);
1432 dev_err(dev
, "Can't create sysfs entries\n");
1439 power_supply_unregister(bdi
->battery
);
1441 power_supply_unregister(bdi
->charger
);
1443 pm_runtime_disable(dev
);
1446 gpio_free(bdi
->gpio_int
);
1451 static int bq24190_remove(struct i2c_client
*client
)
1453 struct bq24190_dev_info
*bdi
= i2c_get_clientdata(client
);
1455 pm_runtime_get_sync(bdi
->dev
);
1456 bq24190_register_reset(bdi
);
1457 pm_runtime_put_sync(bdi
->dev
);
1459 bq24190_sysfs_remove_group(bdi
);
1460 power_supply_unregister(bdi
->battery
);
1461 power_supply_unregister(bdi
->charger
);
1462 pm_runtime_disable(bdi
->dev
);
1465 gpio_free(bdi
->gpio_int
);
1470 #ifdef CONFIG_PM_SLEEP
1471 static int bq24190_pm_suspend(struct device
*dev
)
1473 struct i2c_client
*client
= to_i2c_client(dev
);
1474 struct bq24190_dev_info
*bdi
= i2c_get_clientdata(client
);
1476 pm_runtime_get_sync(bdi
->dev
);
1477 bq24190_register_reset(bdi
);
1478 pm_runtime_put_sync(bdi
->dev
);
1483 static int bq24190_pm_resume(struct device
*dev
)
1485 struct i2c_client
*client
= to_i2c_client(dev
);
1486 struct bq24190_dev_info
*bdi
= i2c_get_clientdata(client
);
1488 bdi
->charger_health_valid
= false;
1489 bdi
->battery_health_valid
= false;
1490 bdi
->battery_status_valid
= false;
1492 pm_runtime_get_sync(bdi
->dev
);
1493 bq24190_register_reset(bdi
);
1494 pm_runtime_put_sync(bdi
->dev
);
1496 /* Things may have changed while suspended so alert upper layer */
1497 power_supply_changed(bdi
->charger
);
1498 power_supply_changed(bdi
->battery
);
1504 static SIMPLE_DEV_PM_OPS(bq24190_pm_ops
, bq24190_pm_suspend
, bq24190_pm_resume
);
1507 * Only support the bq24190 right now. The bq24192, bq24192i, and bq24193
1508 * are similar but not identical so the driver needs to be extended to
1511 static const struct i2c_device_id bq24190_i2c_ids
[] = {
1512 { "bq24190", BQ24190_REG_VPRS_PN_24190
},
1517 static const struct of_device_id bq24190_of_match
[] = {
1518 { .compatible
= "ti,bq24190", },
1521 MODULE_DEVICE_TABLE(of
, bq24190_of_match
);
1523 static const struct of_device_id bq24190_of_match
[] = {
1528 static struct i2c_driver bq24190_driver
= {
1529 .probe
= bq24190_probe
,
1530 .remove
= bq24190_remove
,
1531 .id_table
= bq24190_i2c_ids
,
1533 .name
= "bq24190-charger",
1534 .owner
= THIS_MODULE
,
1535 .pm
= &bq24190_pm_ops
,
1536 .of_match_table
= of_match_ptr(bq24190_of_match
),
1539 module_i2c_driver(bq24190_driver
);
1541 MODULE_LICENSE("GPL");
1542 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1543 MODULE_ALIAS("i2c:bq24190-charger");
1544 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");