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/extcon.h>
15 #include <linux/of_irq.h>
16 #include <linux/of_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/power_supply.h>
19 #include <linux/workqueue.h>
20 #include <linux/gpio.h>
21 #include <linux/i2c.h>
23 #define BQ24190_MANUFACTURER "Texas Instruments"
25 #define BQ24190_REG_ISC 0x00 /* Input Source Control */
26 #define BQ24190_REG_ISC_EN_HIZ_MASK BIT(7)
27 #define BQ24190_REG_ISC_EN_HIZ_SHIFT 7
28 #define BQ24190_REG_ISC_VINDPM_MASK (BIT(6) | BIT(5) | BIT(4) | \
30 #define BQ24190_REG_ISC_VINDPM_SHIFT 3
31 #define BQ24190_REG_ISC_IINLIM_MASK (BIT(2) | BIT(1) | BIT(0))
32 #define BQ24190_REG_ISC_IINLIM_SHIFT 0
34 #define BQ24190_REG_POC 0x01 /* Power-On Configuration */
35 #define BQ24190_REG_POC_RESET_MASK BIT(7)
36 #define BQ24190_REG_POC_RESET_SHIFT 7
37 #define BQ24190_REG_POC_WDT_RESET_MASK BIT(6)
38 #define BQ24190_REG_POC_WDT_RESET_SHIFT 6
39 #define BQ24190_REG_POC_CHG_CONFIG_MASK (BIT(5) | BIT(4))
40 #define BQ24190_REG_POC_CHG_CONFIG_SHIFT 4
41 #define BQ24190_REG_POC_CHG_CONFIG_DISABLE 0x0
42 #define BQ24190_REG_POC_CHG_CONFIG_CHARGE 0x1
43 #define BQ24190_REG_POC_CHG_CONFIG_OTG 0x2
44 #define BQ24190_REG_POC_SYS_MIN_MASK (BIT(3) | BIT(2) | BIT(1))
45 #define BQ24190_REG_POC_SYS_MIN_SHIFT 1
46 #define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0)
47 #define BQ24190_REG_POC_BOOST_LIM_SHIFT 0
49 #define BQ24190_REG_CCC 0x02 /* Charge Current Control */
50 #define BQ24190_REG_CCC_ICHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
51 BIT(4) | BIT(3) | BIT(2))
52 #define BQ24190_REG_CCC_ICHG_SHIFT 2
53 #define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0)
54 #define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0
56 #define BQ24190_REG_PCTCC 0x03 /* Pre-charge/Termination Current Cntl */
57 #define BQ24190_REG_PCTCC_IPRECHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
59 #define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4
60 #define BQ24190_REG_PCTCC_ITERM_MASK (BIT(3) | BIT(2) | BIT(1) | \
62 #define BQ24190_REG_PCTCC_ITERM_SHIFT 0
64 #define BQ24190_REG_CVC 0x04 /* Charge Voltage Control */
65 #define BQ24190_REG_CVC_VREG_MASK (BIT(7) | BIT(6) | BIT(5) | \
66 BIT(4) | BIT(3) | BIT(2))
67 #define BQ24190_REG_CVC_VREG_SHIFT 2
68 #define BQ24190_REG_CVC_BATLOWV_MASK BIT(1)
69 #define BQ24190_REG_CVC_BATLOWV_SHIFT 1
70 #define BQ24190_REG_CVC_VRECHG_MASK BIT(0)
71 #define BQ24190_REG_CVC_VRECHG_SHIFT 0
73 #define BQ24190_REG_CTTC 0x05 /* Charge Term/Timer Control */
74 #define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7)
75 #define BQ24190_REG_CTTC_EN_TERM_SHIFT 7
76 #define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6)
77 #define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6
78 #define BQ24190_REG_CTTC_WATCHDOG_MASK (BIT(5) | BIT(4))
79 #define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4
80 #define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3)
81 #define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3
82 #define BQ24190_REG_CTTC_CHG_TIMER_MASK (BIT(2) | BIT(1))
83 #define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1
84 #define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0)
85 #define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0
87 #define BQ24190_REG_ICTRC 0x06 /* IR Comp/Thermal Regulation Control */
88 #define BQ24190_REG_ICTRC_BAT_COMP_MASK (BIT(7) | BIT(6) | BIT(5))
89 #define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5
90 #define BQ24190_REG_ICTRC_VCLAMP_MASK (BIT(4) | BIT(3) | BIT(2))
91 #define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2
92 #define BQ24190_REG_ICTRC_TREG_MASK (BIT(1) | BIT(0))
93 #define BQ24190_REG_ICTRC_TREG_SHIFT 0
95 #define BQ24190_REG_MOC 0x07 /* Misc. Operation Control */
96 #define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7)
97 #define BQ24190_REG_MOC_DPDM_EN_SHIFT 7
98 #define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6)
99 #define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6
100 #define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5)
101 #define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5
102 #define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4)
103 #define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4
104 #define BQ24190_REG_MOC_INT_MASK_MASK (BIT(1) | BIT(0))
105 #define BQ24190_REG_MOC_INT_MASK_SHIFT 0
107 #define BQ24190_REG_SS 0x08 /* System Status */
108 #define BQ24190_REG_SS_VBUS_STAT_MASK (BIT(7) | BIT(6))
109 #define BQ24190_REG_SS_VBUS_STAT_SHIFT 6
110 #define BQ24190_REG_SS_CHRG_STAT_MASK (BIT(5) | BIT(4))
111 #define BQ24190_REG_SS_CHRG_STAT_SHIFT 4
112 #define BQ24190_REG_SS_DPM_STAT_MASK BIT(3)
113 #define BQ24190_REG_SS_DPM_STAT_SHIFT 3
114 #define BQ24190_REG_SS_PG_STAT_MASK BIT(2)
115 #define BQ24190_REG_SS_PG_STAT_SHIFT 2
116 #define BQ24190_REG_SS_THERM_STAT_MASK BIT(1)
117 #define BQ24190_REG_SS_THERM_STAT_SHIFT 1
118 #define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0)
119 #define BQ24190_REG_SS_VSYS_STAT_SHIFT 0
121 #define BQ24190_REG_F 0x09 /* Fault */
122 #define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7)
123 #define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7
124 #define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6)
125 #define BQ24190_REG_F_BOOST_FAULT_SHIFT 6
126 #define BQ24190_REG_F_CHRG_FAULT_MASK (BIT(5) | BIT(4))
127 #define BQ24190_REG_F_CHRG_FAULT_SHIFT 4
128 #define BQ24190_REG_F_BAT_FAULT_MASK BIT(3)
129 #define BQ24190_REG_F_BAT_FAULT_SHIFT 3
130 #define BQ24190_REG_F_NTC_FAULT_MASK (BIT(2) | BIT(1) | BIT(0))
131 #define BQ24190_REG_F_NTC_FAULT_SHIFT 0
133 #define BQ24190_REG_VPRS 0x0A /* Vendor/Part/Revision Status */
134 #define BQ24190_REG_VPRS_PN_MASK (BIT(5) | BIT(4) | BIT(3))
135 #define BQ24190_REG_VPRS_PN_SHIFT 3
136 #define BQ24190_REG_VPRS_PN_24190 0x4
137 #define BQ24190_REG_VPRS_PN_24192 0x5 /* Also 24193 */
138 #define BQ24190_REG_VPRS_PN_24192I 0x3
139 #define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2)
140 #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2
141 #define BQ24190_REG_VPRS_DEV_REG_MASK (BIT(1) | BIT(0))
142 #define BQ24190_REG_VPRS_DEV_REG_SHIFT 0
145 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
146 * so the first read after a fault returns the latched value and subsequent
147 * reads return the current value. In order to return the fault status
148 * to the user, have the interrupt handler save the reg's value and retrieve
149 * it in the appropriate health/status routine.
151 struct bq24190_dev_info {
152 struct i2c_client *client;
154 struct power_supply *charger;
155 struct power_supply *battery;
156 struct extcon_dev *extcon;
157 struct notifier_block extcon_nb;
158 struct delayed_work extcon_work;
159 char model_name[I2C_NAME_SIZE];
162 struct mutex f_reg_lock;
169 * The tables below provide a 2-way mapping for the value that goes in
170 * the register field and the real-world value that it represents.
171 * The index of the array is the value that goes in the register; the
172 * number at that index in the array is the real-world value that it
176 /* REG00[2:0] (IINLIM) in uAh */
177 static const int bq24190_isc_iinlim_values[] = {
178 100000, 150000, 500000, 900000, 1200000, 1500000, 2000000, 3000000
181 /* REG02[7:2] (ICHG) in uAh */
182 static const int bq24190_ccc_ichg_values[] = {
183 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
184 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
185 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
186 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
187 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
188 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
189 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
190 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
193 /* REG04[7:2] (VREG) in uV */
194 static const int bq24190_cvc_vreg_values[] = {
195 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
196 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
197 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
198 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
199 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
200 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
201 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
205 /* REG06[1:0] (TREG) in tenths of degrees Celsius */
206 static const int bq24190_ictrc_treg_values[] = {
211 * Return the index in 'tbl' of greatest value that is less than or equal to
212 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
213 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
216 static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
220 for (i = 1; i < tbl_size; i++)
227 /* Basic driver I/O routines */
229 static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
233 ret = i2c_smbus_read_byte_data(bdi->client, reg);
241 static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
243 return i2c_smbus_write_byte_data(bdi->client, reg, data);
246 static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
247 u8 mask, u8 shift, u8 *data)
252 ret = bq24190_read(bdi, reg, &v);
263 static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
264 u8 mask, u8 shift, u8 data)
269 ret = bq24190_read(bdi, reg, &v);
274 v |= ((data << shift) & mask);
276 return bq24190_write(bdi, reg, v);
279 static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
280 u8 reg, u8 mask, u8 shift,
281 const int tbl[], int tbl_size,
287 ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
291 v = (v >= tbl_size) ? (tbl_size - 1) : v;
297 static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
298 u8 reg, u8 mask, u8 shift,
299 const int tbl[], int tbl_size,
304 idx = bq24190_find_idx(tbl, tbl_size, val);
306 return bq24190_write_mask(bdi, reg, mask, shift, idx);
311 * There are a numerous options that are configurable on the bq24190
312 * that go well beyond what the power_supply properties provide access to.
313 * Provide sysfs access to them so they can be examined and possibly modified
314 * on the fly. They will be provided for the charger power_supply object only
315 * and will be prefixed by 'f_' to make them easier to recognize.
318 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
320 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
321 .reg = BQ24190_REG_##r, \
322 .mask = BQ24190_REG_##r##_##f##_MASK, \
323 .shift = BQ24190_REG_##r##_##f##_SHIFT, \
326 #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
327 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
330 #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
331 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
333 static ssize_t bq24190_sysfs_show(struct device *dev,
334 struct device_attribute *attr, char *buf);
335 static ssize_t bq24190_sysfs_store(struct device *dev,
336 struct device_attribute *attr, const char *buf, size_t count);
338 struct bq24190_sysfs_field_info {
339 struct device_attribute attr;
345 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
348 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
349 /* sysfs name reg field in reg */
350 BQ24190_SYSFS_FIELD_RW(en_hiz, ISC, EN_HIZ),
351 BQ24190_SYSFS_FIELD_RW(vindpm, ISC, VINDPM),
352 BQ24190_SYSFS_FIELD_RW(iinlim, ISC, IINLIM),
353 BQ24190_SYSFS_FIELD_RW(chg_config, POC, CHG_CONFIG),
354 BQ24190_SYSFS_FIELD_RW(sys_min, POC, SYS_MIN),
355 BQ24190_SYSFS_FIELD_RW(boost_lim, POC, BOOST_LIM),
356 BQ24190_SYSFS_FIELD_RW(ichg, CCC, ICHG),
357 BQ24190_SYSFS_FIELD_RW(force_20_pct, CCC, FORCE_20PCT),
358 BQ24190_SYSFS_FIELD_RW(iprechg, PCTCC, IPRECHG),
359 BQ24190_SYSFS_FIELD_RW(iterm, PCTCC, ITERM),
360 BQ24190_SYSFS_FIELD_RW(vreg, CVC, VREG),
361 BQ24190_SYSFS_FIELD_RW(batlowv, CVC, BATLOWV),
362 BQ24190_SYSFS_FIELD_RW(vrechg, CVC, VRECHG),
363 BQ24190_SYSFS_FIELD_RW(en_term, CTTC, EN_TERM),
364 BQ24190_SYSFS_FIELD_RW(term_stat, CTTC, TERM_STAT),
365 BQ24190_SYSFS_FIELD_RO(watchdog, CTTC, WATCHDOG),
366 BQ24190_SYSFS_FIELD_RW(en_timer, CTTC, EN_TIMER),
367 BQ24190_SYSFS_FIELD_RW(chg_timer, CTTC, CHG_TIMER),
368 BQ24190_SYSFS_FIELD_RW(jeta_iset, CTTC, JEITA_ISET),
369 BQ24190_SYSFS_FIELD_RW(bat_comp, ICTRC, BAT_COMP),
370 BQ24190_SYSFS_FIELD_RW(vclamp, ICTRC, VCLAMP),
371 BQ24190_SYSFS_FIELD_RW(treg, ICTRC, TREG),
372 BQ24190_SYSFS_FIELD_RW(dpdm_en, MOC, DPDM_EN),
373 BQ24190_SYSFS_FIELD_RW(tmr2x_en, MOC, TMR2X_EN),
374 BQ24190_SYSFS_FIELD_RW(batfet_disable, MOC, BATFET_DISABLE),
375 BQ24190_SYSFS_FIELD_RW(jeita_vset, MOC, JEITA_VSET),
376 BQ24190_SYSFS_FIELD_RO(int_mask, MOC, INT_MASK),
377 BQ24190_SYSFS_FIELD_RO(vbus_stat, SS, VBUS_STAT),
378 BQ24190_SYSFS_FIELD_RO(chrg_stat, SS, CHRG_STAT),
379 BQ24190_SYSFS_FIELD_RO(dpm_stat, SS, DPM_STAT),
380 BQ24190_SYSFS_FIELD_RO(pg_stat, SS, PG_STAT),
381 BQ24190_SYSFS_FIELD_RO(therm_stat, SS, THERM_STAT),
382 BQ24190_SYSFS_FIELD_RO(vsys_stat, SS, VSYS_STAT),
383 BQ24190_SYSFS_FIELD_RO(watchdog_fault, F, WATCHDOG_FAULT),
384 BQ24190_SYSFS_FIELD_RO(boost_fault, F, BOOST_FAULT),
385 BQ24190_SYSFS_FIELD_RO(chrg_fault, F, CHRG_FAULT),
386 BQ24190_SYSFS_FIELD_RO(bat_fault, F, BAT_FAULT),
387 BQ24190_SYSFS_FIELD_RO(ntc_fault, F, NTC_FAULT),
388 BQ24190_SYSFS_FIELD_RO(pn, VPRS, PN),
389 BQ24190_SYSFS_FIELD_RO(ts_profile, VPRS, TS_PROFILE),
390 BQ24190_SYSFS_FIELD_RO(dev_reg, VPRS, DEV_REG),
393 static struct attribute *
394 bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
396 static const struct attribute_group bq24190_sysfs_attr_group = {
397 .attrs = bq24190_sysfs_attrs,
400 static void bq24190_sysfs_init_attrs(void)
402 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
404 for (i = 0; i < limit; i++)
405 bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
407 bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
410 static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
413 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
415 for (i = 0; i < limit; i++)
416 if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
422 return &bq24190_sysfs_field_tbl[i];
425 static ssize_t bq24190_sysfs_show(struct device *dev,
426 struct device_attribute *attr, char *buf)
428 struct power_supply *psy = dev_get_drvdata(dev);
429 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
430 struct bq24190_sysfs_field_info *info;
435 info = bq24190_sysfs_field_lookup(attr->attr.name);
439 ret = pm_runtime_get_sync(bdi->dev);
443 ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
447 count = scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
449 pm_runtime_mark_last_busy(bdi->dev);
450 pm_runtime_put_autosuspend(bdi->dev);
455 static ssize_t bq24190_sysfs_store(struct device *dev,
456 struct device_attribute *attr, const char *buf, size_t count)
458 struct power_supply *psy = dev_get_drvdata(dev);
459 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
460 struct bq24190_sysfs_field_info *info;
464 info = bq24190_sysfs_field_lookup(attr->attr.name);
468 ret = kstrtou8(buf, 0, &v);
472 ret = pm_runtime_get_sync(bdi->dev);
476 ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
480 pm_runtime_mark_last_busy(bdi->dev);
481 pm_runtime_put_autosuspend(bdi->dev);
486 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
488 bq24190_sysfs_init_attrs();
490 return sysfs_create_group(&bdi->charger->dev.kobj,
491 &bq24190_sysfs_attr_group);
494 static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi)
496 sysfs_remove_group(&bdi->charger->dev.kobj, &bq24190_sysfs_attr_group);
499 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
504 static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {}
508 * According to the "Host Mode and default Mode" section of the
509 * manual, a write to any register causes the bq24190 to switch
510 * from default mode to host mode. It will switch back to default
511 * mode after a WDT timeout unless the WDT is turned off as well.
512 * So, by simply turning off the WDT, we accomplish both with the
515 static int bq24190_set_mode_host(struct bq24190_dev_info *bdi)
520 ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
524 bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
525 BQ24190_REG_CTTC_WATCHDOG_SHIFT);
526 v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
528 return bq24190_write(bdi, BQ24190_REG_CTTC, v);
531 static int bq24190_register_reset(struct bq24190_dev_info *bdi)
533 int ret, limit = 100;
536 /* Reset the registers */
537 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
538 BQ24190_REG_POC_RESET_MASK,
539 BQ24190_REG_POC_RESET_SHIFT,
544 /* Reset bit will be cleared by hardware so poll until it is */
546 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
547 BQ24190_REG_POC_RESET_MASK,
548 BQ24190_REG_POC_RESET_SHIFT,
556 usleep_range(100, 200);
562 /* Charger power supply property routines */
564 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
565 union power_supply_propval *val)
570 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
571 BQ24190_REG_POC_CHG_CONFIG_MASK,
572 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
577 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
579 type = POWER_SUPPLY_CHARGE_TYPE_NONE;
581 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
582 BQ24190_REG_CCC_FORCE_20PCT_MASK,
583 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
588 type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
589 POWER_SUPPLY_CHARGE_TYPE_FAST;
597 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
598 const union power_supply_propval *val)
600 u8 chg_config, force_20pct, en_term;
604 * According to the "Termination when REG02[0] = 1" section of
605 * the bq24190 manual, the trickle charge could be less than the
606 * termination current so it recommends turning off the termination
609 * Note: AFAICT from the datasheet, the user will have to manually
610 * turn off the charging when in 20% mode. If its not turned off,
611 * there could be battery damage. So, use this mode at your own risk.
613 switch (val->intval) {
614 case POWER_SUPPLY_CHARGE_TYPE_NONE:
617 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
622 case POWER_SUPPLY_CHARGE_TYPE_FAST:
631 if (chg_config) { /* Enabling the charger */
632 ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
633 BQ24190_REG_CCC_FORCE_20PCT_MASK,
634 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
639 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
640 BQ24190_REG_CTTC_EN_TERM_MASK,
641 BQ24190_REG_CTTC_EN_TERM_SHIFT,
647 return bq24190_write_mask(bdi, BQ24190_REG_POC,
648 BQ24190_REG_POC_CHG_CONFIG_MASK,
649 BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
652 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
653 union power_supply_propval *val)
658 mutex_lock(&bdi->f_reg_lock);
660 mutex_unlock(&bdi->f_reg_lock);
662 if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
664 * This could be over-current or over-voltage but there's
665 * no way to tell which. Return 'OVERVOLTAGE' since there
666 * isn't an 'OVERCURRENT' value defined that we can return
667 * even if it was over-current.
669 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
671 v &= BQ24190_REG_F_CHRG_FAULT_MASK;
672 v >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
675 case 0x0: /* Normal */
676 health = POWER_SUPPLY_HEALTH_GOOD;
678 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
680 * This could be over-voltage or under-voltage
681 * and there's no way to tell which. Instead
682 * of looking foolish and returning 'OVERVOLTAGE'
683 * when its really under-voltage, just return
686 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
688 case 0x2: /* Thermal Shutdown */
689 health = POWER_SUPPLY_HEALTH_OVERHEAT;
691 case 0x3: /* Charge Safety Timer Expiration */
692 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
695 health = POWER_SUPPLY_HEALTH_UNKNOWN;
699 val->intval = health;
704 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
705 union power_supply_propval *val)
710 ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
711 BQ24190_REG_SS_PG_STAT_MASK,
712 BQ24190_REG_SS_PG_STAT_SHIFT, &v);
720 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
721 union power_supply_propval *val)
726 ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
727 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
728 bq24190_ccc_ichg_values,
729 ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
733 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
734 BQ24190_REG_CCC_FORCE_20PCT_MASK,
735 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
739 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
747 static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
748 union power_supply_propval *val)
750 int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
752 val->intval = bq24190_ccc_ichg_values[idx];
756 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
757 const union power_supply_propval *val)
760 int ret, curr = val->intval;
762 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
763 BQ24190_REG_CCC_FORCE_20PCT_MASK,
764 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
768 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
772 return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
773 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
774 bq24190_ccc_ichg_values,
775 ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
778 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
779 union power_supply_propval *val)
783 ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
784 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
785 bq24190_cvc_vreg_values,
786 ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
790 val->intval = voltage;
794 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
795 union power_supply_propval *val)
797 int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
799 val->intval = bq24190_cvc_vreg_values[idx];
803 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
804 const union power_supply_propval *val)
806 return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
807 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
808 bq24190_cvc_vreg_values,
809 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
812 static int bq24190_charger_get_property(struct power_supply *psy,
813 enum power_supply_property psp, union power_supply_propval *val)
815 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
818 dev_dbg(bdi->dev, "prop: %d\n", psp);
820 ret = pm_runtime_get_sync(bdi->dev);
825 case POWER_SUPPLY_PROP_CHARGE_TYPE:
826 ret = bq24190_charger_get_charge_type(bdi, val);
828 case POWER_SUPPLY_PROP_HEALTH:
829 ret = bq24190_charger_get_health(bdi, val);
831 case POWER_SUPPLY_PROP_ONLINE:
832 ret = bq24190_charger_get_online(bdi, val);
834 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
835 ret = bq24190_charger_get_current(bdi, val);
837 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
838 ret = bq24190_charger_get_current_max(bdi, val);
840 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
841 ret = bq24190_charger_get_voltage(bdi, val);
843 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
844 ret = bq24190_charger_get_voltage_max(bdi, val);
846 case POWER_SUPPLY_PROP_SCOPE:
847 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
850 case POWER_SUPPLY_PROP_MODEL_NAME:
851 val->strval = bdi->model_name;
854 case POWER_SUPPLY_PROP_MANUFACTURER:
855 val->strval = BQ24190_MANUFACTURER;
862 pm_runtime_mark_last_busy(bdi->dev);
863 pm_runtime_put_autosuspend(bdi->dev);
868 static int bq24190_charger_set_property(struct power_supply *psy,
869 enum power_supply_property psp,
870 const union power_supply_propval *val)
872 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
875 dev_dbg(bdi->dev, "prop: %d\n", psp);
877 ret = pm_runtime_get_sync(bdi->dev);
882 case POWER_SUPPLY_PROP_CHARGE_TYPE:
883 ret = bq24190_charger_set_charge_type(bdi, val);
885 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
886 ret = bq24190_charger_set_current(bdi, val);
888 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
889 ret = bq24190_charger_set_voltage(bdi, val);
895 pm_runtime_mark_last_busy(bdi->dev);
896 pm_runtime_put_autosuspend(bdi->dev);
901 static int bq24190_charger_property_is_writeable(struct power_supply *psy,
902 enum power_supply_property psp)
907 case POWER_SUPPLY_PROP_CHARGE_TYPE:
908 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
909 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
919 static enum power_supply_property bq24190_charger_properties[] = {
920 POWER_SUPPLY_PROP_CHARGE_TYPE,
921 POWER_SUPPLY_PROP_HEALTH,
922 POWER_SUPPLY_PROP_ONLINE,
923 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
924 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
925 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
926 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
927 POWER_SUPPLY_PROP_SCOPE,
928 POWER_SUPPLY_PROP_MODEL_NAME,
929 POWER_SUPPLY_PROP_MANUFACTURER,
932 static char *bq24190_charger_supplied_to[] = {
936 static const struct power_supply_desc bq24190_charger_desc = {
937 .name = "bq24190-charger",
938 .type = POWER_SUPPLY_TYPE_USB,
939 .properties = bq24190_charger_properties,
940 .num_properties = ARRAY_SIZE(bq24190_charger_properties),
941 .get_property = bq24190_charger_get_property,
942 .set_property = bq24190_charger_set_property,
943 .property_is_writeable = bq24190_charger_property_is_writeable,
946 /* Battery power supply property routines */
948 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
949 union power_supply_propval *val)
951 u8 ss_reg, chrg_fault;
954 mutex_lock(&bdi->f_reg_lock);
955 chrg_fault = bdi->f_reg;
956 mutex_unlock(&bdi->f_reg_lock);
958 chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
959 chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
961 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
966 * The battery must be discharging when any of these are true:
967 * - there is no good power source;
968 * - there is a charge fault.
969 * Could also be discharging when in "supplement mode" but
970 * there is no way to tell when its in that mode.
972 if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
973 status = POWER_SUPPLY_STATUS_DISCHARGING;
975 ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
976 ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
979 case 0x0: /* Not Charging */
980 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
982 case 0x1: /* Pre-charge */
983 case 0x2: /* Fast Charging */
984 status = POWER_SUPPLY_STATUS_CHARGING;
986 case 0x3: /* Charge Termination Done */
987 status = POWER_SUPPLY_STATUS_FULL;
995 val->intval = status;
1000 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1001 union power_supply_propval *val)
1006 mutex_lock(&bdi->f_reg_lock);
1008 mutex_unlock(&bdi->f_reg_lock);
1010 if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1011 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1013 v &= BQ24190_REG_F_NTC_FAULT_MASK;
1014 v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1017 case 0x0: /* Normal */
1018 health = POWER_SUPPLY_HEALTH_GOOD;
1020 case 0x1: /* TS1 Cold */
1021 case 0x3: /* TS2 Cold */
1022 case 0x5: /* Both Cold */
1023 health = POWER_SUPPLY_HEALTH_COLD;
1025 case 0x2: /* TS1 Hot */
1026 case 0x4: /* TS2 Hot */
1027 case 0x6: /* Both Hot */
1028 health = POWER_SUPPLY_HEALTH_OVERHEAT;
1031 health = POWER_SUPPLY_HEALTH_UNKNOWN;
1035 val->intval = health;
1039 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1040 union power_supply_propval *val)
1045 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1046 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1047 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1051 val->intval = !batfet_disable;
1055 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1056 const union power_supply_propval *val)
1058 return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1059 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1060 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1063 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1064 union power_supply_propval *val)
1068 ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1069 BQ24190_REG_ICTRC_TREG_MASK,
1070 BQ24190_REG_ICTRC_TREG_SHIFT,
1071 bq24190_ictrc_treg_values,
1072 ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1080 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1081 const union power_supply_propval *val)
1083 return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1084 BQ24190_REG_ICTRC_TREG_MASK,
1085 BQ24190_REG_ICTRC_TREG_SHIFT,
1086 bq24190_ictrc_treg_values,
1087 ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1090 static int bq24190_battery_get_property(struct power_supply *psy,
1091 enum power_supply_property psp, union power_supply_propval *val)
1093 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1096 dev_dbg(bdi->dev, "prop: %d\n", psp);
1098 ret = pm_runtime_get_sync(bdi->dev);
1103 case POWER_SUPPLY_PROP_STATUS:
1104 ret = bq24190_battery_get_status(bdi, val);
1106 case POWER_SUPPLY_PROP_HEALTH:
1107 ret = bq24190_battery_get_health(bdi, val);
1109 case POWER_SUPPLY_PROP_ONLINE:
1110 ret = bq24190_battery_get_online(bdi, val);
1112 case POWER_SUPPLY_PROP_TECHNOLOGY:
1113 /* Could be Li-on or Li-polymer but no way to tell which */
1114 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1117 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1118 ret = bq24190_battery_get_temp_alert_max(bdi, val);
1120 case POWER_SUPPLY_PROP_SCOPE:
1121 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1128 pm_runtime_mark_last_busy(bdi->dev);
1129 pm_runtime_put_autosuspend(bdi->dev);
1134 static int bq24190_battery_set_property(struct power_supply *psy,
1135 enum power_supply_property psp,
1136 const union power_supply_propval *val)
1138 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1141 dev_dbg(bdi->dev, "prop: %d\n", psp);
1143 ret = pm_runtime_get_sync(bdi->dev);
1148 case POWER_SUPPLY_PROP_ONLINE:
1149 ret = bq24190_battery_set_online(bdi, val);
1151 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1152 ret = bq24190_battery_set_temp_alert_max(bdi, val);
1158 pm_runtime_mark_last_busy(bdi->dev);
1159 pm_runtime_put_autosuspend(bdi->dev);
1164 static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1165 enum power_supply_property psp)
1170 case POWER_SUPPLY_PROP_ONLINE:
1171 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1181 static enum power_supply_property bq24190_battery_properties[] = {
1182 POWER_SUPPLY_PROP_STATUS,
1183 POWER_SUPPLY_PROP_HEALTH,
1184 POWER_SUPPLY_PROP_ONLINE,
1185 POWER_SUPPLY_PROP_TECHNOLOGY,
1186 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1187 POWER_SUPPLY_PROP_SCOPE,
1190 static const struct power_supply_desc bq24190_battery_desc = {
1191 .name = "bq24190-battery",
1192 .type = POWER_SUPPLY_TYPE_BATTERY,
1193 .properties = bq24190_battery_properties,
1194 .num_properties = ARRAY_SIZE(bq24190_battery_properties),
1195 .get_property = bq24190_battery_get_property,
1196 .set_property = bq24190_battery_set_property,
1197 .property_is_writeable = bq24190_battery_property_is_writeable,
1200 static void bq24190_check_status(struct bq24190_dev_info *bdi)
1202 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1203 const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1204 | BQ24190_REG_F_NTC_FAULT_MASK;
1205 bool alert_charger = false, alert_battery = false;
1206 u8 ss_reg = 0, f_reg = 0;
1209 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1211 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1217 ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1219 dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1222 } while (f_reg && ++i < 2);
1224 /* ignore over/under voltage fault after disconnect */
1225 if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1226 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1229 if (f_reg != bdi->f_reg) {
1231 "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1232 !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1233 !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1234 !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1235 !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1237 mutex_lock(&bdi->f_reg_lock);
1238 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1239 alert_battery = true;
1240 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1241 alert_charger = true;
1243 mutex_unlock(&bdi->f_reg_lock);
1246 if (ss_reg != bdi->ss_reg) {
1248 * The device is in host mode so when PG_STAT goes from 1->0
1249 * (i.e., power removed) HIZ needs to be disabled.
1251 if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1252 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1253 ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1254 BQ24190_REG_ISC_EN_HIZ_MASK,
1255 BQ24190_REG_ISC_EN_HIZ_SHIFT,
1258 dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1262 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1263 alert_battery = true;
1264 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1265 alert_charger = true;
1266 bdi->ss_reg = ss_reg;
1270 power_supply_changed(bdi->charger);
1272 power_supply_changed(bdi->battery);
1274 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1277 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1279 struct bq24190_dev_info *bdi = data;
1282 bdi->irq_event = true;
1283 error = pm_runtime_get_sync(bdi->dev);
1285 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1286 pm_runtime_put_noidle(bdi->dev);
1289 bq24190_check_status(bdi);
1290 pm_runtime_mark_last_busy(bdi->dev);
1291 pm_runtime_put_autosuspend(bdi->dev);
1292 bdi->irq_event = false;
1297 static void bq24190_extcon_work(struct work_struct *work)
1299 struct bq24190_dev_info *bdi =
1300 container_of(work, struct bq24190_dev_info, extcon_work.work);
1301 int error, iinlim = 0;
1304 error = pm_runtime_get_sync(bdi->dev);
1306 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1307 pm_runtime_put_noidle(bdi->dev);
1311 if (extcon_get_state(bdi->extcon, EXTCON_CHG_USB_SDP) == 1)
1313 else if (extcon_get_state(bdi->extcon, EXTCON_CHG_USB_CDP) == 1 ||
1314 extcon_get_state(bdi->extcon, EXTCON_CHG_USB_ACA) == 1)
1316 else if (extcon_get_state(bdi->extcon, EXTCON_CHG_USB_DCP) == 1)
1320 error = bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1321 BQ24190_REG_ISC_IINLIM_MASK,
1322 BQ24190_REG_ISC_IINLIM_SHIFT,
1323 bq24190_isc_iinlim_values,
1324 ARRAY_SIZE(bq24190_isc_iinlim_values),
1327 dev_err(bdi->dev, "Can't set IINLIM: %d\n", error);
1330 /* if no charger found and in USB host mode, set OTG 5V boost, else normal */
1331 if (!iinlim && extcon_get_state(bdi->extcon, EXTCON_USB_HOST) == 1)
1332 v = BQ24190_REG_POC_CHG_CONFIG_OTG;
1334 v = BQ24190_REG_POC_CHG_CONFIG_CHARGE;
1336 error = bq24190_write_mask(bdi, BQ24190_REG_POC,
1337 BQ24190_REG_POC_CHG_CONFIG_MASK,
1338 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
1341 dev_err(bdi->dev, "Can't set CHG_CONFIG: %d\n", error);
1343 pm_runtime_mark_last_busy(bdi->dev);
1344 pm_runtime_put_autosuspend(bdi->dev);
1347 static int bq24190_extcon_event(struct notifier_block *nb, unsigned long event,
1350 struct bq24190_dev_info *bdi =
1351 container_of(nb, struct bq24190_dev_info, extcon_nb);
1354 * The Power-Good detection may take up to 220ms, sometimes
1355 * the external charger detection is quicker, and the bq24190 will
1356 * reset to iinlim based on its own charger detection (which is not
1357 * hooked up when using external charger detection) resulting in
1358 * a too low default 500mA iinlim. Delay applying the extcon value
1359 * for 300ms to avoid this.
1361 queue_delayed_work(system_wq, &bdi->extcon_work, msecs_to_jiffies(300));
1366 static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1371 /* First check that the device really is what its supposed to be */
1372 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1373 BQ24190_REG_VPRS_PN_MASK,
1374 BQ24190_REG_VPRS_PN_SHIFT,
1379 if (v != BQ24190_REG_VPRS_PN_24190 &&
1380 v != BQ24190_REG_VPRS_PN_24192I) {
1381 dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1385 ret = bq24190_register_reset(bdi);
1389 ret = bq24190_set_mode_host(bdi);
1393 return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1396 static int bq24190_probe(struct i2c_client *client,
1397 const struct i2c_device_id *id)
1399 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1400 struct device *dev = &client->dev;
1401 struct power_supply_config charger_cfg = {}, battery_cfg = {};
1402 struct bq24190_dev_info *bdi;
1406 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1407 dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1411 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1413 dev_err(dev, "Can't alloc bdi struct\n");
1417 bdi->client = client;
1419 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1420 mutex_init(&bdi->f_reg_lock);
1422 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1424 i2c_set_clientdata(client, bdi);
1427 dev_err(dev, "Can't get irq info\n");
1432 * Devicetree platforms should get extcon via phandle (not yet supported).
1433 * On ACPI platforms, extcon clients may invoke us with:
1434 * struct property_entry pe[] =
1435 * { PROPERTY_ENTRY_STRING("extcon-name", client_name), ... };
1436 * struct i2c_board_info bi =
1437 * { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
1438 * struct i2c_adapter ad = { ... };
1439 * i2c_add_adapter(&ad);
1440 * i2c_new_device(&ad, &bi);
1442 if (device_property_read_string(dev, "extcon-name", &name) == 0) {
1443 bdi->extcon = extcon_get_extcon_dev(name);
1445 return -EPROBE_DEFER;
1447 dev_info(bdi->dev, "using extcon device %s\n", name);
1450 pm_runtime_enable(dev);
1451 pm_runtime_use_autosuspend(dev);
1452 pm_runtime_set_autosuspend_delay(dev, 600);
1453 ret = pm_runtime_get_sync(dev);
1455 dev_err(dev, "pm_runtime_get failed: %i\n", ret);
1459 ret = bq24190_hw_init(bdi);
1461 dev_err(dev, "Hardware init failed\n");
1465 charger_cfg.drv_data = bdi;
1466 charger_cfg.supplied_to = bq24190_charger_supplied_to;
1467 charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1468 bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1470 if (IS_ERR(bdi->charger)) {
1471 dev_err(dev, "Can't register charger\n");
1472 ret = PTR_ERR(bdi->charger);
1476 battery_cfg.drv_data = bdi;
1477 bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1479 if (IS_ERR(bdi->battery)) {
1480 dev_err(dev, "Can't register battery\n");
1481 ret = PTR_ERR(bdi->battery);
1485 ret = bq24190_sysfs_create_group(bdi);
1487 dev_err(dev, "Can't create sysfs entries\n");
1491 bdi->initialized = true;
1493 ret = devm_request_threaded_irq(dev, client->irq, NULL,
1494 bq24190_irq_handler_thread,
1495 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1496 "bq24190-charger", bdi);
1498 dev_err(dev, "Can't set up irq handler\n");
1503 INIT_DELAYED_WORK(&bdi->extcon_work, bq24190_extcon_work);
1504 bdi->extcon_nb.notifier_call = bq24190_extcon_event;
1505 ret = devm_extcon_register_notifier(dev, bdi->extcon, -1,
1508 dev_err(dev, "Can't register extcon\n");
1512 /* Sync initial cable state */
1513 queue_delayed_work(system_wq, &bdi->extcon_work, 0);
1516 enable_irq_wake(client->irq);
1518 pm_runtime_mark_last_busy(dev);
1519 pm_runtime_put_autosuspend(dev);
1524 bq24190_sysfs_remove_group(bdi);
1527 power_supply_unregister(bdi->battery);
1530 power_supply_unregister(bdi->charger);
1533 pm_runtime_put_sync(dev);
1534 pm_runtime_dont_use_autosuspend(dev);
1535 pm_runtime_disable(dev);
1539 static int bq24190_remove(struct i2c_client *client)
1541 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1544 error = pm_runtime_get_sync(bdi->dev);
1546 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1547 pm_runtime_put_noidle(bdi->dev);
1550 bq24190_register_reset(bdi);
1551 bq24190_sysfs_remove_group(bdi);
1552 power_supply_unregister(bdi->battery);
1553 power_supply_unregister(bdi->charger);
1555 pm_runtime_put_sync(bdi->dev);
1556 pm_runtime_dont_use_autosuspend(bdi->dev);
1557 pm_runtime_disable(bdi->dev);
1562 static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
1564 struct i2c_client *client = to_i2c_client(dev);
1565 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1567 if (!bdi->initialized)
1570 dev_dbg(bdi->dev, "%s\n", __func__);
1575 static __maybe_unused int bq24190_runtime_resume(struct device *dev)
1577 struct i2c_client *client = to_i2c_client(dev);
1578 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1580 if (!bdi->initialized)
1583 if (!bdi->irq_event) {
1584 dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
1585 bq24190_check_status(bdi);
1591 static __maybe_unused int bq24190_pm_suspend(struct device *dev)
1593 struct i2c_client *client = to_i2c_client(dev);
1594 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1597 error = pm_runtime_get_sync(bdi->dev);
1599 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1600 pm_runtime_put_noidle(bdi->dev);
1603 bq24190_register_reset(bdi);
1606 pm_runtime_mark_last_busy(bdi->dev);
1607 pm_runtime_put_autosuspend(bdi->dev);
1613 static __maybe_unused int bq24190_pm_resume(struct device *dev)
1615 struct i2c_client *client = to_i2c_client(dev);
1616 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1620 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1622 error = pm_runtime_get_sync(bdi->dev);
1624 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1625 pm_runtime_put_noidle(bdi->dev);
1628 bq24190_register_reset(bdi);
1629 bq24190_set_mode_host(bdi);
1630 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1633 pm_runtime_mark_last_busy(bdi->dev);
1634 pm_runtime_put_autosuspend(bdi->dev);
1637 /* Things may have changed while suspended so alert upper layer */
1638 power_supply_changed(bdi->charger);
1639 power_supply_changed(bdi->battery);
1644 static const struct dev_pm_ops bq24190_pm_ops = {
1645 SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
1647 SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
1650 static const struct i2c_device_id bq24190_i2c_ids[] = {
1655 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1658 static const struct of_device_id bq24190_of_match[] = {
1659 { .compatible = "ti,bq24190", },
1662 MODULE_DEVICE_TABLE(of, bq24190_of_match);
1664 static const struct of_device_id bq24190_of_match[] = {
1669 static struct i2c_driver bq24190_driver = {
1670 .probe = bq24190_probe,
1671 .remove = bq24190_remove,
1672 .id_table = bq24190_i2c_ids,
1674 .name = "bq24190-charger",
1675 .pm = &bq24190_pm_ops,
1676 .of_match_table = of_match_ptr(bq24190_of_match),
1679 module_i2c_driver(bq24190_driver);
1681 MODULE_LICENSE("GPL");
1682 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1683 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");