treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / power / supply / bq24190_charger.c
blob453d6332d43a750619c3988141035ff276082380
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Driver for the TI bq24190 battery charger.
5 * Author: Mark A. Greer <mgreer@animalcreek.com>
6 */
8 #include <linux/module.h>
9 #include <linux/interrupt.h>
10 #include <linux/delay.h>
11 #include <linux/of_irq.h>
12 #include <linux/of_device.h>
13 #include <linux/pm_runtime.h>
14 #include <linux/power_supply.h>
15 #include <linux/power/bq24190_charger.h>
16 #include <linux/regulator/driver.h>
17 #include <linux/regulator/machine.h>
18 #include <linux/workqueue.h>
19 #include <linux/gpio.h>
20 #include <linux/i2c.h>
21 #include <linux/extcon-provider.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) | \
29 BIT(3))
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_SYS_MIN_MIN 3000
47 #define BQ24190_REG_POC_SYS_MIN_MAX 3700
48 #define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0)
49 #define BQ24190_REG_POC_BOOST_LIM_SHIFT 0
51 #define BQ24190_REG_CCC 0x02 /* Charge Current Control */
52 #define BQ24190_REG_CCC_ICHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
53 BIT(4) | BIT(3) | BIT(2))
54 #define BQ24190_REG_CCC_ICHG_SHIFT 2
55 #define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0)
56 #define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0
58 #define BQ24190_REG_PCTCC 0x03 /* Pre-charge/Termination Current Cntl */
59 #define BQ24190_REG_PCTCC_IPRECHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
60 BIT(4))
61 #define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4
62 #define BQ24190_REG_PCTCC_IPRECHG_MIN 128
63 #define BQ24190_REG_PCTCC_IPRECHG_MAX 2048
64 #define BQ24190_REG_PCTCC_ITERM_MASK (BIT(3) | BIT(2) | BIT(1) | \
65 BIT(0))
66 #define BQ24190_REG_PCTCC_ITERM_SHIFT 0
67 #define BQ24190_REG_PCTCC_ITERM_MIN 128
68 #define BQ24190_REG_PCTCC_ITERM_MAX 2048
70 #define BQ24190_REG_CVC 0x04 /* Charge Voltage Control */
71 #define BQ24190_REG_CVC_VREG_MASK (BIT(7) | BIT(6) | BIT(5) | \
72 BIT(4) | BIT(3) | BIT(2))
73 #define BQ24190_REG_CVC_VREG_SHIFT 2
74 #define BQ24190_REG_CVC_BATLOWV_MASK BIT(1)
75 #define BQ24190_REG_CVC_BATLOWV_SHIFT 1
76 #define BQ24190_REG_CVC_VRECHG_MASK BIT(0)
77 #define BQ24190_REG_CVC_VRECHG_SHIFT 0
79 #define BQ24190_REG_CTTC 0x05 /* Charge Term/Timer Control */
80 #define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7)
81 #define BQ24190_REG_CTTC_EN_TERM_SHIFT 7
82 #define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6)
83 #define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6
84 #define BQ24190_REG_CTTC_WATCHDOG_MASK (BIT(5) | BIT(4))
85 #define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4
86 #define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3)
87 #define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3
88 #define BQ24190_REG_CTTC_CHG_TIMER_MASK (BIT(2) | BIT(1))
89 #define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1
90 #define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0)
91 #define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0
93 #define BQ24190_REG_ICTRC 0x06 /* IR Comp/Thermal Regulation Control */
94 #define BQ24190_REG_ICTRC_BAT_COMP_MASK (BIT(7) | BIT(6) | BIT(5))
95 #define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5
96 #define BQ24190_REG_ICTRC_VCLAMP_MASK (BIT(4) | BIT(3) | BIT(2))
97 #define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2
98 #define BQ24190_REG_ICTRC_TREG_MASK (BIT(1) | BIT(0))
99 #define BQ24190_REG_ICTRC_TREG_SHIFT 0
101 #define BQ24190_REG_MOC 0x07 /* Misc. Operation Control */
102 #define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7)
103 #define BQ24190_REG_MOC_DPDM_EN_SHIFT 7
104 #define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6)
105 #define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6
106 #define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5)
107 #define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5
108 #define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4)
109 #define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4
110 #define BQ24190_REG_MOC_INT_MASK_MASK (BIT(1) | BIT(0))
111 #define BQ24190_REG_MOC_INT_MASK_SHIFT 0
113 #define BQ24190_REG_SS 0x08 /* System Status */
114 #define BQ24190_REG_SS_VBUS_STAT_MASK (BIT(7) | BIT(6))
115 #define BQ24190_REG_SS_VBUS_STAT_SHIFT 6
116 #define BQ24190_REG_SS_CHRG_STAT_MASK (BIT(5) | BIT(4))
117 #define BQ24190_REG_SS_CHRG_STAT_SHIFT 4
118 #define BQ24190_REG_SS_DPM_STAT_MASK BIT(3)
119 #define BQ24190_REG_SS_DPM_STAT_SHIFT 3
120 #define BQ24190_REG_SS_PG_STAT_MASK BIT(2)
121 #define BQ24190_REG_SS_PG_STAT_SHIFT 2
122 #define BQ24190_REG_SS_THERM_STAT_MASK BIT(1)
123 #define BQ24190_REG_SS_THERM_STAT_SHIFT 1
124 #define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0)
125 #define BQ24190_REG_SS_VSYS_STAT_SHIFT 0
127 #define BQ24190_REG_F 0x09 /* Fault */
128 #define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7)
129 #define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7
130 #define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6)
131 #define BQ24190_REG_F_BOOST_FAULT_SHIFT 6
132 #define BQ24190_REG_F_CHRG_FAULT_MASK (BIT(5) | BIT(4))
133 #define BQ24190_REG_F_CHRG_FAULT_SHIFT 4
134 #define BQ24190_REG_F_BAT_FAULT_MASK BIT(3)
135 #define BQ24190_REG_F_BAT_FAULT_SHIFT 3
136 #define BQ24190_REG_F_NTC_FAULT_MASK (BIT(2) | BIT(1) | BIT(0))
137 #define BQ24190_REG_F_NTC_FAULT_SHIFT 0
139 #define BQ24190_REG_VPRS 0x0A /* Vendor/Part/Revision Status */
140 #define BQ24190_REG_VPRS_PN_MASK (BIT(5) | BIT(4) | BIT(3))
141 #define BQ24190_REG_VPRS_PN_SHIFT 3
142 #define BQ24190_REG_VPRS_PN_24190 0x4
143 #define BQ24190_REG_VPRS_PN_24192 0x5 /* Also 24193, 24196 */
144 #define BQ24190_REG_VPRS_PN_24192I 0x3
145 #define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2)
146 #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2
147 #define BQ24190_REG_VPRS_DEV_REG_MASK (BIT(1) | BIT(0))
148 #define BQ24190_REG_VPRS_DEV_REG_SHIFT 0
151 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
152 * so the first read after a fault returns the latched value and subsequent
153 * reads return the current value. In order to return the fault status
154 * to the user, have the interrupt handler save the reg's value and retrieve
155 * it in the appropriate health/status routine.
157 struct bq24190_dev_info {
158 struct i2c_client *client;
159 struct device *dev;
160 struct extcon_dev *edev;
161 struct power_supply *charger;
162 struct power_supply *battery;
163 struct delayed_work input_current_limit_work;
164 char model_name[I2C_NAME_SIZE];
165 bool initialized;
166 bool irq_event;
167 u16 sys_min;
168 u16 iprechg;
169 u16 iterm;
170 struct mutex f_reg_lock;
171 u8 f_reg;
172 u8 ss_reg;
173 u8 watchdog;
176 static const unsigned int bq24190_usb_extcon_cable[] = {
177 EXTCON_USB,
178 EXTCON_NONE,
182 * The tables below provide a 2-way mapping for the value that goes in
183 * the register field and the real-world value that it represents.
184 * The index of the array is the value that goes in the register; the
185 * number at that index in the array is the real-world value that it
186 * represents.
189 /* REG00[2:0] (IINLIM) in uAh */
190 static const int bq24190_isc_iinlim_values[] = {
191 100000, 150000, 500000, 900000, 1200000, 1500000, 2000000, 3000000
194 /* REG02[7:2] (ICHG) in uAh */
195 static const int bq24190_ccc_ichg_values[] = {
196 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
197 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
198 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
199 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
200 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
201 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
202 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
203 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
206 /* REG04[7:2] (VREG) in uV */
207 static const int bq24190_cvc_vreg_values[] = {
208 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
209 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
210 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
211 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
212 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
213 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
214 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
215 4400000
218 /* REG06[1:0] (TREG) in tenths of degrees Celsius */
219 static const int bq24190_ictrc_treg_values[] = {
220 600, 800, 1000, 1200
224 * Return the index in 'tbl' of greatest value that is less than or equal to
225 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
226 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
227 * is less than 2^8.
229 static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
231 int i;
233 for (i = 1; i < tbl_size; i++)
234 if (v < tbl[i])
235 break;
237 return i - 1;
240 /* Basic driver I/O routines */
242 static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
244 int ret;
246 ret = i2c_smbus_read_byte_data(bdi->client, reg);
247 if (ret < 0)
248 return ret;
250 *data = ret;
251 return 0;
254 static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
256 return i2c_smbus_write_byte_data(bdi->client, reg, data);
259 static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
260 u8 mask, u8 shift, u8 *data)
262 u8 v;
263 int ret;
265 ret = bq24190_read(bdi, reg, &v);
266 if (ret < 0)
267 return ret;
269 v &= mask;
270 v >>= shift;
271 *data = v;
273 return 0;
276 static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
277 u8 mask, u8 shift, u8 data)
279 u8 v;
280 int ret;
282 ret = bq24190_read(bdi, reg, &v);
283 if (ret < 0)
284 return ret;
286 v &= ~mask;
287 v |= ((data << shift) & mask);
289 return bq24190_write(bdi, reg, v);
292 static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
293 u8 reg, u8 mask, u8 shift,
294 const int tbl[], int tbl_size,
295 int *val)
297 u8 v;
298 int ret;
300 ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
301 if (ret < 0)
302 return ret;
304 v = (v >= tbl_size) ? (tbl_size - 1) : v;
305 *val = tbl[v];
307 return 0;
310 static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
311 u8 reg, u8 mask, u8 shift,
312 const int tbl[], int tbl_size,
313 int val)
315 u8 idx;
317 idx = bq24190_find_idx(tbl, tbl_size, val);
319 return bq24190_write_mask(bdi, reg, mask, shift, idx);
322 #ifdef CONFIG_SYSFS
324 * There are a numerous options that are configurable on the bq24190
325 * that go well beyond what the power_supply properties provide access to.
326 * Provide sysfs access to them so they can be examined and possibly modified
327 * on the fly. They will be provided for the charger power_supply object only
328 * and will be prefixed by 'f_' to make them easier to recognize.
331 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
333 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
334 .reg = BQ24190_REG_##r, \
335 .mask = BQ24190_REG_##r##_##f##_MASK, \
336 .shift = BQ24190_REG_##r##_##f##_SHIFT, \
339 #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
340 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
341 bq24190_sysfs_store)
343 #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
344 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
346 static ssize_t bq24190_sysfs_show(struct device *dev,
347 struct device_attribute *attr, char *buf);
348 static ssize_t bq24190_sysfs_store(struct device *dev,
349 struct device_attribute *attr, const char *buf, size_t count);
351 struct bq24190_sysfs_field_info {
352 struct device_attribute attr;
353 u8 reg;
354 u8 mask;
355 u8 shift;
358 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
359 #undef SS
361 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
362 /* sysfs name reg field in reg */
363 BQ24190_SYSFS_FIELD_RW(en_hiz, ISC, EN_HIZ),
364 BQ24190_SYSFS_FIELD_RW(vindpm, ISC, VINDPM),
365 BQ24190_SYSFS_FIELD_RW(iinlim, ISC, IINLIM),
366 BQ24190_SYSFS_FIELD_RW(chg_config, POC, CHG_CONFIG),
367 BQ24190_SYSFS_FIELD_RW(sys_min, POC, SYS_MIN),
368 BQ24190_SYSFS_FIELD_RW(boost_lim, POC, BOOST_LIM),
369 BQ24190_SYSFS_FIELD_RW(ichg, CCC, ICHG),
370 BQ24190_SYSFS_FIELD_RW(force_20_pct, CCC, FORCE_20PCT),
371 BQ24190_SYSFS_FIELD_RW(iprechg, PCTCC, IPRECHG),
372 BQ24190_SYSFS_FIELD_RW(iterm, PCTCC, ITERM),
373 BQ24190_SYSFS_FIELD_RW(vreg, CVC, VREG),
374 BQ24190_SYSFS_FIELD_RW(batlowv, CVC, BATLOWV),
375 BQ24190_SYSFS_FIELD_RW(vrechg, CVC, VRECHG),
376 BQ24190_SYSFS_FIELD_RW(en_term, CTTC, EN_TERM),
377 BQ24190_SYSFS_FIELD_RW(term_stat, CTTC, TERM_STAT),
378 BQ24190_SYSFS_FIELD_RO(watchdog, CTTC, WATCHDOG),
379 BQ24190_SYSFS_FIELD_RW(en_timer, CTTC, EN_TIMER),
380 BQ24190_SYSFS_FIELD_RW(chg_timer, CTTC, CHG_TIMER),
381 BQ24190_SYSFS_FIELD_RW(jeta_iset, CTTC, JEITA_ISET),
382 BQ24190_SYSFS_FIELD_RW(bat_comp, ICTRC, BAT_COMP),
383 BQ24190_SYSFS_FIELD_RW(vclamp, ICTRC, VCLAMP),
384 BQ24190_SYSFS_FIELD_RW(treg, ICTRC, TREG),
385 BQ24190_SYSFS_FIELD_RW(dpdm_en, MOC, DPDM_EN),
386 BQ24190_SYSFS_FIELD_RW(tmr2x_en, MOC, TMR2X_EN),
387 BQ24190_SYSFS_FIELD_RW(batfet_disable, MOC, BATFET_DISABLE),
388 BQ24190_SYSFS_FIELD_RW(jeita_vset, MOC, JEITA_VSET),
389 BQ24190_SYSFS_FIELD_RO(int_mask, MOC, INT_MASK),
390 BQ24190_SYSFS_FIELD_RO(vbus_stat, SS, VBUS_STAT),
391 BQ24190_SYSFS_FIELD_RO(chrg_stat, SS, CHRG_STAT),
392 BQ24190_SYSFS_FIELD_RO(dpm_stat, SS, DPM_STAT),
393 BQ24190_SYSFS_FIELD_RO(pg_stat, SS, PG_STAT),
394 BQ24190_SYSFS_FIELD_RO(therm_stat, SS, THERM_STAT),
395 BQ24190_SYSFS_FIELD_RO(vsys_stat, SS, VSYS_STAT),
396 BQ24190_SYSFS_FIELD_RO(watchdog_fault, F, WATCHDOG_FAULT),
397 BQ24190_SYSFS_FIELD_RO(boost_fault, F, BOOST_FAULT),
398 BQ24190_SYSFS_FIELD_RO(chrg_fault, F, CHRG_FAULT),
399 BQ24190_SYSFS_FIELD_RO(bat_fault, F, BAT_FAULT),
400 BQ24190_SYSFS_FIELD_RO(ntc_fault, F, NTC_FAULT),
401 BQ24190_SYSFS_FIELD_RO(pn, VPRS, PN),
402 BQ24190_SYSFS_FIELD_RO(ts_profile, VPRS, TS_PROFILE),
403 BQ24190_SYSFS_FIELD_RO(dev_reg, VPRS, DEV_REG),
406 static struct attribute *
407 bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
409 ATTRIBUTE_GROUPS(bq24190_sysfs);
411 static void bq24190_sysfs_init_attrs(void)
413 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
415 for (i = 0; i < limit; i++)
416 bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
418 bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
421 static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
422 const char *name)
424 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
426 for (i = 0; i < limit; i++)
427 if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
428 break;
430 if (i >= limit)
431 return NULL;
433 return &bq24190_sysfs_field_tbl[i];
436 static ssize_t bq24190_sysfs_show(struct device *dev,
437 struct device_attribute *attr, char *buf)
439 struct power_supply *psy = dev_get_drvdata(dev);
440 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
441 struct bq24190_sysfs_field_info *info;
442 ssize_t count;
443 int ret;
444 u8 v;
446 info = bq24190_sysfs_field_lookup(attr->attr.name);
447 if (!info)
448 return -EINVAL;
450 ret = pm_runtime_get_sync(bdi->dev);
451 if (ret < 0)
452 return ret;
454 ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
455 if (ret)
456 count = ret;
457 else
458 count = scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
460 pm_runtime_mark_last_busy(bdi->dev);
461 pm_runtime_put_autosuspend(bdi->dev);
463 return count;
466 static ssize_t bq24190_sysfs_store(struct device *dev,
467 struct device_attribute *attr, const char *buf, size_t count)
469 struct power_supply *psy = dev_get_drvdata(dev);
470 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
471 struct bq24190_sysfs_field_info *info;
472 int ret;
473 u8 v;
475 info = bq24190_sysfs_field_lookup(attr->attr.name);
476 if (!info)
477 return -EINVAL;
479 ret = kstrtou8(buf, 0, &v);
480 if (ret < 0)
481 return ret;
483 ret = pm_runtime_get_sync(bdi->dev);
484 if (ret < 0)
485 return ret;
487 ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
488 if (ret)
489 count = ret;
491 pm_runtime_mark_last_busy(bdi->dev);
492 pm_runtime_put_autosuspend(bdi->dev);
494 return count;
496 #endif
498 #ifdef CONFIG_REGULATOR
499 static int bq24190_set_charge_mode(struct regulator_dev *dev, u8 val)
501 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
502 int ret;
504 ret = pm_runtime_get_sync(bdi->dev);
505 if (ret < 0) {
506 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
507 pm_runtime_put_noidle(bdi->dev);
508 return ret;
511 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
512 BQ24190_REG_POC_CHG_CONFIG_MASK,
513 BQ24190_REG_POC_CHG_CONFIG_SHIFT, val);
515 pm_runtime_mark_last_busy(bdi->dev);
516 pm_runtime_put_autosuspend(bdi->dev);
518 return ret;
521 static int bq24190_vbus_enable(struct regulator_dev *dev)
523 return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_OTG);
526 static int bq24190_vbus_disable(struct regulator_dev *dev)
528 return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_CHARGE);
531 static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
533 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
534 int ret;
535 u8 val;
537 ret = pm_runtime_get_sync(bdi->dev);
538 if (ret < 0) {
539 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
540 pm_runtime_put_noidle(bdi->dev);
541 return ret;
544 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
545 BQ24190_REG_POC_CHG_CONFIG_MASK,
546 BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
548 pm_runtime_mark_last_busy(bdi->dev);
549 pm_runtime_put_autosuspend(bdi->dev);
551 return ret ? ret : val == BQ24190_REG_POC_CHG_CONFIG_OTG;
554 static const struct regulator_ops bq24190_vbus_ops = {
555 .enable = bq24190_vbus_enable,
556 .disable = bq24190_vbus_disable,
557 .is_enabled = bq24190_vbus_is_enabled,
560 static const struct regulator_desc bq24190_vbus_desc = {
561 .name = "usb_otg_vbus",
562 .of_match = "usb-otg-vbus",
563 .type = REGULATOR_VOLTAGE,
564 .owner = THIS_MODULE,
565 .ops = &bq24190_vbus_ops,
566 .fixed_uV = 5000000,
567 .n_voltages = 1,
570 static const struct regulator_init_data bq24190_vbus_init_data = {
571 .constraints = {
572 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
576 static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
578 struct bq24190_platform_data *pdata = bdi->dev->platform_data;
579 struct regulator_config cfg = { };
580 struct regulator_dev *reg;
581 int ret = 0;
583 cfg.dev = bdi->dev;
584 if (pdata && pdata->regulator_init_data)
585 cfg.init_data = pdata->regulator_init_data;
586 else
587 cfg.init_data = &bq24190_vbus_init_data;
588 cfg.driver_data = bdi;
589 reg = devm_regulator_register(bdi->dev, &bq24190_vbus_desc, &cfg);
590 if (IS_ERR(reg)) {
591 ret = PTR_ERR(reg);
592 dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
595 return ret;
597 #else
598 static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
600 return 0;
602 #endif
604 static int bq24190_set_config(struct bq24190_dev_info *bdi)
606 int ret;
607 u8 v;
609 ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
610 if (ret < 0)
611 return ret;
613 bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
614 BQ24190_REG_CTTC_WATCHDOG_SHIFT);
617 * According to the "Host Mode and default Mode" section of the
618 * manual, a write to any register causes the bq24190 to switch
619 * from default mode to host mode. It will switch back to default
620 * mode after a WDT timeout unless the WDT is turned off as well.
621 * So, by simply turning off the WDT, we accomplish both with the
622 * same write.
624 v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
626 ret = bq24190_write(bdi, BQ24190_REG_CTTC, v);
627 if (ret < 0)
628 return ret;
630 if (bdi->sys_min) {
631 v = bdi->sys_min / 100 - 30; // manual section 9.5.1.2, table 9
632 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
633 BQ24190_REG_POC_SYS_MIN_MASK,
634 BQ24190_REG_POC_SYS_MIN_SHIFT,
636 if (ret < 0)
637 return ret;
640 if (bdi->iprechg) {
641 v = bdi->iprechg / 128 - 1; // manual section 9.5.1.4, table 11
642 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
643 BQ24190_REG_PCTCC_IPRECHG_MASK,
644 BQ24190_REG_PCTCC_IPRECHG_SHIFT,
646 if (ret < 0)
647 return ret;
650 if (bdi->iterm) {
651 v = bdi->iterm / 128 - 1; // manual section 9.5.1.4, table 11
652 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
653 BQ24190_REG_PCTCC_ITERM_MASK,
654 BQ24190_REG_PCTCC_ITERM_SHIFT,
656 if (ret < 0)
657 return ret;
660 return 0;
663 static int bq24190_register_reset(struct bq24190_dev_info *bdi)
665 int ret, limit = 100;
666 u8 v;
669 * This prop. can be passed on device instantiation from platform code:
670 * struct property_entry pe[] =
671 * { PROPERTY_ENTRY_BOOL("disable-reset"), ... };
672 * struct i2c_board_info bi =
673 * { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
674 * struct i2c_adapter ad = { ... };
675 * i2c_add_adapter(&ad);
676 * i2c_new_device(&ad, &bi);
678 if (device_property_read_bool(bdi->dev, "disable-reset"))
679 return 0;
681 /* Reset the registers */
682 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
683 BQ24190_REG_POC_RESET_MASK,
684 BQ24190_REG_POC_RESET_SHIFT,
685 0x1);
686 if (ret < 0)
687 return ret;
689 /* Reset bit will be cleared by hardware so poll until it is */
690 do {
691 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
692 BQ24190_REG_POC_RESET_MASK,
693 BQ24190_REG_POC_RESET_SHIFT,
694 &v);
695 if (ret < 0)
696 return ret;
698 if (v == 0)
699 return 0;
701 usleep_range(100, 200);
702 } while (--limit);
704 return -EIO;
707 /* Charger power supply property routines */
709 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
710 union power_supply_propval *val)
712 u8 v;
713 int type, ret;
715 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
716 BQ24190_REG_POC_CHG_CONFIG_MASK,
717 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
718 &v);
719 if (ret < 0)
720 return ret;
722 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
723 if (!v) {
724 type = POWER_SUPPLY_CHARGE_TYPE_NONE;
725 } else {
726 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
727 BQ24190_REG_CCC_FORCE_20PCT_MASK,
728 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
729 &v);
730 if (ret < 0)
731 return ret;
733 type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
734 POWER_SUPPLY_CHARGE_TYPE_FAST;
737 val->intval = type;
739 return 0;
742 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
743 const union power_supply_propval *val)
745 u8 chg_config, force_20pct, en_term;
746 int ret;
749 * According to the "Termination when REG02[0] = 1" section of
750 * the bq24190 manual, the trickle charge could be less than the
751 * termination current so it recommends turning off the termination
752 * function.
754 * Note: AFAICT from the datasheet, the user will have to manually
755 * turn off the charging when in 20% mode. If its not turned off,
756 * there could be battery damage. So, use this mode at your own risk.
758 switch (val->intval) {
759 case POWER_SUPPLY_CHARGE_TYPE_NONE:
760 chg_config = 0x0;
761 break;
762 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
763 chg_config = 0x1;
764 force_20pct = 0x1;
765 en_term = 0x0;
766 break;
767 case POWER_SUPPLY_CHARGE_TYPE_FAST:
768 chg_config = 0x1;
769 force_20pct = 0x0;
770 en_term = 0x1;
771 break;
772 default:
773 return -EINVAL;
776 if (chg_config) { /* Enabling the charger */
777 ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
778 BQ24190_REG_CCC_FORCE_20PCT_MASK,
779 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
780 force_20pct);
781 if (ret < 0)
782 return ret;
784 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
785 BQ24190_REG_CTTC_EN_TERM_MASK,
786 BQ24190_REG_CTTC_EN_TERM_SHIFT,
787 en_term);
788 if (ret < 0)
789 return ret;
792 return bq24190_write_mask(bdi, BQ24190_REG_POC,
793 BQ24190_REG_POC_CHG_CONFIG_MASK,
794 BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
797 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
798 union power_supply_propval *val)
800 u8 v;
801 int health;
803 mutex_lock(&bdi->f_reg_lock);
804 v = bdi->f_reg;
805 mutex_unlock(&bdi->f_reg_lock);
807 if (v & BQ24190_REG_F_NTC_FAULT_MASK) {
808 switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
809 case 0x1: /* TS1 Cold */
810 case 0x3: /* TS2 Cold */
811 case 0x5: /* Both Cold */
812 health = POWER_SUPPLY_HEALTH_COLD;
813 break;
814 case 0x2: /* TS1 Hot */
815 case 0x4: /* TS2 Hot */
816 case 0x6: /* Both Hot */
817 health = POWER_SUPPLY_HEALTH_OVERHEAT;
818 break;
819 default:
820 health = POWER_SUPPLY_HEALTH_UNKNOWN;
822 } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
823 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
824 } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
825 switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
826 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
828 * This could be over-voltage or under-voltage
829 * and there's no way to tell which. Instead
830 * of looking foolish and returning 'OVERVOLTAGE'
831 * when its really under-voltage, just return
832 * 'UNSPEC_FAILURE'.
834 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
835 break;
836 case 0x2: /* Thermal Shutdown */
837 health = POWER_SUPPLY_HEALTH_OVERHEAT;
838 break;
839 case 0x3: /* Charge Safety Timer Expiration */
840 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
841 break;
842 default: /* prevent compiler warning */
843 health = -1;
845 } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
847 * This could be over-current or over-voltage but there's
848 * no way to tell which. Return 'OVERVOLTAGE' since there
849 * isn't an 'OVERCURRENT' value defined that we can return
850 * even if it was over-current.
852 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
853 } else {
854 health = POWER_SUPPLY_HEALTH_GOOD;
857 val->intval = health;
859 return 0;
862 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
863 union power_supply_propval *val)
865 u8 pg_stat, batfet_disable;
866 int ret;
868 ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
869 BQ24190_REG_SS_PG_STAT_MASK,
870 BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
871 if (ret < 0)
872 return ret;
874 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
875 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
876 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
877 if (ret < 0)
878 return ret;
880 val->intval = pg_stat && !batfet_disable;
882 return 0;
885 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
886 const union power_supply_propval *val);
887 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
888 union power_supply_propval *val);
889 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
890 union power_supply_propval *val);
891 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
892 const union power_supply_propval *val);
894 static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
895 const union power_supply_propval *val)
897 return bq24190_battery_set_online(bdi, val);
900 static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
901 union power_supply_propval *val)
903 return bq24190_battery_get_status(bdi, val);
906 static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
907 union power_supply_propval *val)
909 return bq24190_battery_get_temp_alert_max(bdi, val);
912 static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
913 const union power_supply_propval *val)
915 return bq24190_battery_set_temp_alert_max(bdi, val);
918 static int bq24190_charger_get_precharge(struct bq24190_dev_info *bdi,
919 union power_supply_propval *val)
921 u8 v;
922 int ret;
924 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
925 BQ24190_REG_PCTCC_IPRECHG_MASK,
926 BQ24190_REG_PCTCC_IPRECHG_SHIFT, &v);
927 if (ret < 0)
928 return ret;
930 val->intval = ++v * 128 * 1000;
931 return 0;
934 static int bq24190_charger_get_charge_term(struct bq24190_dev_info *bdi,
935 union power_supply_propval *val)
937 u8 v;
938 int ret;
940 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
941 BQ24190_REG_PCTCC_ITERM_MASK,
942 BQ24190_REG_PCTCC_ITERM_SHIFT, &v);
943 if (ret < 0)
944 return ret;
946 val->intval = ++v * 128 * 1000;
947 return 0;
950 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
951 union power_supply_propval *val)
953 u8 v;
954 int curr, ret;
956 ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
957 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
958 bq24190_ccc_ichg_values,
959 ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
960 if (ret < 0)
961 return ret;
963 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
964 BQ24190_REG_CCC_FORCE_20PCT_MASK,
965 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
966 if (ret < 0)
967 return ret;
969 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
970 if (v)
971 curr /= 5;
973 val->intval = curr;
974 return 0;
977 static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
978 union power_supply_propval *val)
980 int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
982 val->intval = bq24190_ccc_ichg_values[idx];
983 return 0;
986 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
987 const union power_supply_propval *val)
989 u8 v;
990 int ret, curr = val->intval;
992 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
993 BQ24190_REG_CCC_FORCE_20PCT_MASK,
994 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
995 if (ret < 0)
996 return ret;
998 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
999 if (v)
1000 curr *= 5;
1002 return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
1003 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1004 bq24190_ccc_ichg_values,
1005 ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
1008 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
1009 union power_supply_propval *val)
1011 int voltage, ret;
1013 ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
1014 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1015 bq24190_cvc_vreg_values,
1016 ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
1017 if (ret < 0)
1018 return ret;
1020 val->intval = voltage;
1021 return 0;
1024 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
1025 union power_supply_propval *val)
1027 int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
1029 val->intval = bq24190_cvc_vreg_values[idx];
1030 return 0;
1033 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
1034 const union power_supply_propval *val)
1036 return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
1037 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1038 bq24190_cvc_vreg_values,
1039 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
1042 static int bq24190_charger_get_iinlimit(struct bq24190_dev_info *bdi,
1043 union power_supply_propval *val)
1045 int iinlimit, ret;
1047 ret = bq24190_get_field_val(bdi, BQ24190_REG_ISC,
1048 BQ24190_REG_ISC_IINLIM_MASK,
1049 BQ24190_REG_ISC_IINLIM_SHIFT,
1050 bq24190_isc_iinlim_values,
1051 ARRAY_SIZE(bq24190_isc_iinlim_values), &iinlimit);
1052 if (ret < 0)
1053 return ret;
1055 val->intval = iinlimit;
1056 return 0;
1059 static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi,
1060 const union power_supply_propval *val)
1062 return bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1063 BQ24190_REG_ISC_IINLIM_MASK,
1064 BQ24190_REG_ISC_IINLIM_SHIFT,
1065 bq24190_isc_iinlim_values,
1066 ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval);
1069 static int bq24190_charger_get_property(struct power_supply *psy,
1070 enum power_supply_property psp, union power_supply_propval *val)
1072 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1073 int ret;
1075 dev_dbg(bdi->dev, "prop: %d\n", psp);
1077 ret = pm_runtime_get_sync(bdi->dev);
1078 if (ret < 0)
1079 return ret;
1081 switch (psp) {
1082 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1083 ret = bq24190_charger_get_charge_type(bdi, val);
1084 break;
1085 case POWER_SUPPLY_PROP_HEALTH:
1086 ret = bq24190_charger_get_health(bdi, val);
1087 break;
1088 case POWER_SUPPLY_PROP_ONLINE:
1089 ret = bq24190_charger_get_online(bdi, val);
1090 break;
1091 case POWER_SUPPLY_PROP_STATUS:
1092 ret = bq24190_charger_get_status(bdi, val);
1093 break;
1094 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1095 ret = bq24190_charger_get_temp_alert_max(bdi, val);
1096 break;
1097 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
1098 ret = bq24190_charger_get_precharge(bdi, val);
1099 break;
1100 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
1101 ret = bq24190_charger_get_charge_term(bdi, val);
1102 break;
1103 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1104 ret = bq24190_charger_get_current(bdi, val);
1105 break;
1106 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
1107 ret = bq24190_charger_get_current_max(bdi, val);
1108 break;
1109 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1110 ret = bq24190_charger_get_voltage(bdi, val);
1111 break;
1112 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
1113 ret = bq24190_charger_get_voltage_max(bdi, val);
1114 break;
1115 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1116 ret = bq24190_charger_get_iinlimit(bdi, val);
1117 break;
1118 case POWER_SUPPLY_PROP_SCOPE:
1119 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1120 ret = 0;
1121 break;
1122 case POWER_SUPPLY_PROP_MODEL_NAME:
1123 val->strval = bdi->model_name;
1124 ret = 0;
1125 break;
1126 case POWER_SUPPLY_PROP_MANUFACTURER:
1127 val->strval = BQ24190_MANUFACTURER;
1128 ret = 0;
1129 break;
1130 default:
1131 ret = -ENODATA;
1134 pm_runtime_mark_last_busy(bdi->dev);
1135 pm_runtime_put_autosuspend(bdi->dev);
1137 return ret;
1140 static int bq24190_charger_set_property(struct power_supply *psy,
1141 enum power_supply_property psp,
1142 const union power_supply_propval *val)
1144 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1145 int ret;
1147 dev_dbg(bdi->dev, "prop: %d\n", psp);
1149 ret = pm_runtime_get_sync(bdi->dev);
1150 if (ret < 0)
1151 return ret;
1153 switch (psp) {
1154 case POWER_SUPPLY_PROP_ONLINE:
1155 ret = bq24190_charger_set_online(bdi, val);
1156 break;
1157 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1158 ret = bq24190_charger_set_temp_alert_max(bdi, val);
1159 break;
1160 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1161 ret = bq24190_charger_set_charge_type(bdi, val);
1162 break;
1163 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1164 ret = bq24190_charger_set_current(bdi, val);
1165 break;
1166 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1167 ret = bq24190_charger_set_voltage(bdi, val);
1168 break;
1169 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1170 ret = bq24190_charger_set_iinlimit(bdi, val);
1171 break;
1172 default:
1173 ret = -EINVAL;
1176 pm_runtime_mark_last_busy(bdi->dev);
1177 pm_runtime_put_autosuspend(bdi->dev);
1179 return ret;
1182 static int bq24190_charger_property_is_writeable(struct power_supply *psy,
1183 enum power_supply_property psp)
1185 switch (psp) {
1186 case POWER_SUPPLY_PROP_ONLINE:
1187 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1188 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1189 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1190 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1191 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1192 return 1;
1193 default:
1194 return 0;
1198 static void bq24190_input_current_limit_work(struct work_struct *work)
1200 struct bq24190_dev_info *bdi =
1201 container_of(work, struct bq24190_dev_info,
1202 input_current_limit_work.work);
1204 power_supply_set_input_current_limit_from_supplier(bdi->charger);
1207 /* Sync the input-current-limit with our parent supply (if we have one) */
1208 static void bq24190_charger_external_power_changed(struct power_supply *psy)
1210 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1213 * The Power-Good detection may take up to 220ms, sometimes
1214 * the external charger detection is quicker, and the bq24190 will
1215 * reset to iinlim based on its own charger detection (which is not
1216 * hooked up when using external charger detection) resulting in a
1217 * too low default 500mA iinlim. Delay setting the input-current-limit
1218 * for 300ms to avoid this.
1220 queue_delayed_work(system_wq, &bdi->input_current_limit_work,
1221 msecs_to_jiffies(300));
1224 static enum power_supply_property bq24190_charger_properties[] = {
1225 POWER_SUPPLY_PROP_CHARGE_TYPE,
1226 POWER_SUPPLY_PROP_HEALTH,
1227 POWER_SUPPLY_PROP_ONLINE,
1228 POWER_SUPPLY_PROP_STATUS,
1229 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1230 POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
1231 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
1232 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
1233 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
1234 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
1235 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
1236 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1237 POWER_SUPPLY_PROP_SCOPE,
1238 POWER_SUPPLY_PROP_MODEL_NAME,
1239 POWER_SUPPLY_PROP_MANUFACTURER,
1242 static char *bq24190_charger_supplied_to[] = {
1243 "main-battery",
1246 static const struct power_supply_desc bq24190_charger_desc = {
1247 .name = "bq24190-charger",
1248 .type = POWER_SUPPLY_TYPE_USB,
1249 .properties = bq24190_charger_properties,
1250 .num_properties = ARRAY_SIZE(bq24190_charger_properties),
1251 .get_property = bq24190_charger_get_property,
1252 .set_property = bq24190_charger_set_property,
1253 .property_is_writeable = bq24190_charger_property_is_writeable,
1254 .external_power_changed = bq24190_charger_external_power_changed,
1257 /* Battery power supply property routines */
1259 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1260 union power_supply_propval *val)
1262 u8 ss_reg, chrg_fault;
1263 int status, ret;
1265 mutex_lock(&bdi->f_reg_lock);
1266 chrg_fault = bdi->f_reg;
1267 mutex_unlock(&bdi->f_reg_lock);
1269 chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
1270 chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
1272 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1273 if (ret < 0)
1274 return ret;
1277 * The battery must be discharging when any of these are true:
1278 * - there is no good power source;
1279 * - there is a charge fault.
1280 * Could also be discharging when in "supplement mode" but
1281 * there is no way to tell when its in that mode.
1283 if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
1284 status = POWER_SUPPLY_STATUS_DISCHARGING;
1285 } else {
1286 ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
1287 ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
1289 switch (ss_reg) {
1290 case 0x0: /* Not Charging */
1291 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1292 break;
1293 case 0x1: /* Pre-charge */
1294 case 0x2: /* Fast Charging */
1295 status = POWER_SUPPLY_STATUS_CHARGING;
1296 break;
1297 case 0x3: /* Charge Termination Done */
1298 status = POWER_SUPPLY_STATUS_FULL;
1299 break;
1300 default:
1301 ret = -EIO;
1305 if (!ret)
1306 val->intval = status;
1308 return ret;
1311 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1312 union power_supply_propval *val)
1314 u8 v;
1315 int health;
1317 mutex_lock(&bdi->f_reg_lock);
1318 v = bdi->f_reg;
1319 mutex_unlock(&bdi->f_reg_lock);
1321 if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1322 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1323 } else {
1324 v &= BQ24190_REG_F_NTC_FAULT_MASK;
1325 v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1327 switch (v) {
1328 case 0x0: /* Normal */
1329 health = POWER_SUPPLY_HEALTH_GOOD;
1330 break;
1331 case 0x1: /* TS1 Cold */
1332 case 0x3: /* TS2 Cold */
1333 case 0x5: /* Both Cold */
1334 health = POWER_SUPPLY_HEALTH_COLD;
1335 break;
1336 case 0x2: /* TS1 Hot */
1337 case 0x4: /* TS2 Hot */
1338 case 0x6: /* Both Hot */
1339 health = POWER_SUPPLY_HEALTH_OVERHEAT;
1340 break;
1341 default:
1342 health = POWER_SUPPLY_HEALTH_UNKNOWN;
1346 val->intval = health;
1347 return 0;
1350 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1351 union power_supply_propval *val)
1353 u8 batfet_disable;
1354 int ret;
1356 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1357 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1358 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1359 if (ret < 0)
1360 return ret;
1362 val->intval = !batfet_disable;
1363 return 0;
1366 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1367 const union power_supply_propval *val)
1369 return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1370 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1371 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1374 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1375 union power_supply_propval *val)
1377 int temp, ret;
1379 ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1380 BQ24190_REG_ICTRC_TREG_MASK,
1381 BQ24190_REG_ICTRC_TREG_SHIFT,
1382 bq24190_ictrc_treg_values,
1383 ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1384 if (ret < 0)
1385 return ret;
1387 val->intval = temp;
1388 return 0;
1391 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1392 const union power_supply_propval *val)
1394 return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1395 BQ24190_REG_ICTRC_TREG_MASK,
1396 BQ24190_REG_ICTRC_TREG_SHIFT,
1397 bq24190_ictrc_treg_values,
1398 ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1401 static int bq24190_battery_get_property(struct power_supply *psy,
1402 enum power_supply_property psp, union power_supply_propval *val)
1404 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1405 int ret;
1407 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1408 dev_dbg(bdi->dev, "prop: %d\n", psp);
1410 ret = pm_runtime_get_sync(bdi->dev);
1411 if (ret < 0)
1412 return ret;
1414 switch (psp) {
1415 case POWER_SUPPLY_PROP_STATUS:
1416 ret = bq24190_battery_get_status(bdi, val);
1417 break;
1418 case POWER_SUPPLY_PROP_HEALTH:
1419 ret = bq24190_battery_get_health(bdi, val);
1420 break;
1421 case POWER_SUPPLY_PROP_ONLINE:
1422 ret = bq24190_battery_get_online(bdi, val);
1423 break;
1424 case POWER_SUPPLY_PROP_TECHNOLOGY:
1425 /* Could be Li-on or Li-polymer but no way to tell which */
1426 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1427 ret = 0;
1428 break;
1429 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1430 ret = bq24190_battery_get_temp_alert_max(bdi, val);
1431 break;
1432 case POWER_SUPPLY_PROP_SCOPE:
1433 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1434 ret = 0;
1435 break;
1436 default:
1437 ret = -ENODATA;
1440 pm_runtime_mark_last_busy(bdi->dev);
1441 pm_runtime_put_autosuspend(bdi->dev);
1443 return ret;
1446 static int bq24190_battery_set_property(struct power_supply *psy,
1447 enum power_supply_property psp,
1448 const union power_supply_propval *val)
1450 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1451 int ret;
1453 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1454 dev_dbg(bdi->dev, "prop: %d\n", psp);
1456 ret = pm_runtime_get_sync(bdi->dev);
1457 if (ret < 0)
1458 return ret;
1460 switch (psp) {
1461 case POWER_SUPPLY_PROP_ONLINE:
1462 ret = bq24190_battery_set_online(bdi, val);
1463 break;
1464 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1465 ret = bq24190_battery_set_temp_alert_max(bdi, val);
1466 break;
1467 default:
1468 ret = -EINVAL;
1471 pm_runtime_mark_last_busy(bdi->dev);
1472 pm_runtime_put_autosuspend(bdi->dev);
1474 return ret;
1477 static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1478 enum power_supply_property psp)
1480 int ret;
1482 switch (psp) {
1483 case POWER_SUPPLY_PROP_ONLINE:
1484 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1485 ret = 1;
1486 break;
1487 default:
1488 ret = 0;
1491 return ret;
1494 static enum power_supply_property bq24190_battery_properties[] = {
1495 POWER_SUPPLY_PROP_STATUS,
1496 POWER_SUPPLY_PROP_HEALTH,
1497 POWER_SUPPLY_PROP_ONLINE,
1498 POWER_SUPPLY_PROP_TECHNOLOGY,
1499 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1500 POWER_SUPPLY_PROP_SCOPE,
1503 static const struct power_supply_desc bq24190_battery_desc = {
1504 .name = "bq24190-battery",
1505 .type = POWER_SUPPLY_TYPE_BATTERY,
1506 .properties = bq24190_battery_properties,
1507 .num_properties = ARRAY_SIZE(bq24190_battery_properties),
1508 .get_property = bq24190_battery_get_property,
1509 .set_property = bq24190_battery_set_property,
1510 .property_is_writeable = bq24190_battery_property_is_writeable,
1513 static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
1515 bool otg_enabled;
1516 int ret;
1518 otg_enabled = !!(ss_reg & BQ24190_REG_SS_VBUS_STAT_MASK);
1519 ret = extcon_set_state_sync(bdi->edev, EXTCON_USB, otg_enabled);
1520 if (ret < 0)
1521 dev_err(bdi->dev, "Can't set extcon state to %d: %d\n",
1522 otg_enabled, ret);
1524 return ret;
1527 static void bq24190_check_status(struct bq24190_dev_info *bdi)
1529 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1530 const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1531 | BQ24190_REG_F_NTC_FAULT_MASK;
1532 bool alert_charger = false, alert_battery = false;
1533 u8 ss_reg = 0, f_reg = 0;
1534 int i, ret;
1536 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1537 if (ret < 0) {
1538 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1539 return;
1542 i = 0;
1543 do {
1544 ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1545 if (ret < 0) {
1546 dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1547 return;
1549 } while (f_reg && ++i < 2);
1551 /* ignore over/under voltage fault after disconnect */
1552 if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1553 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1554 f_reg = 0;
1556 if (f_reg != bdi->f_reg) {
1557 dev_warn(bdi->dev,
1558 "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1559 !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1560 !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1561 !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1562 !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1564 mutex_lock(&bdi->f_reg_lock);
1565 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1566 alert_battery = true;
1567 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1568 alert_charger = true;
1569 bdi->f_reg = f_reg;
1570 mutex_unlock(&bdi->f_reg_lock);
1573 if (ss_reg != bdi->ss_reg) {
1575 * The device is in host mode so when PG_STAT goes from 1->0
1576 * (i.e., power removed) HIZ needs to be disabled.
1578 if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1579 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1580 ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1581 BQ24190_REG_ISC_EN_HIZ_MASK,
1582 BQ24190_REG_ISC_EN_HIZ_SHIFT,
1584 if (ret < 0)
1585 dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1586 ret);
1589 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1590 alert_battery = true;
1591 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1592 alert_charger = true;
1593 bdi->ss_reg = ss_reg;
1596 if (alert_charger || alert_battery) {
1597 power_supply_changed(bdi->charger);
1598 bq24190_configure_usb_otg(bdi, ss_reg);
1600 if (alert_battery && bdi->battery)
1601 power_supply_changed(bdi->battery);
1603 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1606 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1608 struct bq24190_dev_info *bdi = data;
1609 int error;
1611 bdi->irq_event = true;
1612 error = pm_runtime_get_sync(bdi->dev);
1613 if (error < 0) {
1614 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1615 pm_runtime_put_noidle(bdi->dev);
1616 return IRQ_NONE;
1618 bq24190_check_status(bdi);
1619 pm_runtime_mark_last_busy(bdi->dev);
1620 pm_runtime_put_autosuspend(bdi->dev);
1621 bdi->irq_event = false;
1623 return IRQ_HANDLED;
1626 static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1628 u8 v;
1629 int ret;
1631 /* First check that the device really is what its supposed to be */
1632 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1633 BQ24190_REG_VPRS_PN_MASK,
1634 BQ24190_REG_VPRS_PN_SHIFT,
1635 &v);
1636 if (ret < 0)
1637 return ret;
1639 switch (v) {
1640 case BQ24190_REG_VPRS_PN_24190:
1641 case BQ24190_REG_VPRS_PN_24192:
1642 case BQ24190_REG_VPRS_PN_24192I:
1643 break;
1644 default:
1645 dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1646 return -ENODEV;
1649 ret = bq24190_register_reset(bdi);
1650 if (ret < 0)
1651 return ret;
1653 ret = bq24190_set_config(bdi);
1654 if (ret < 0)
1655 return ret;
1657 return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1660 static int bq24190_get_config(struct bq24190_dev_info *bdi)
1662 const char * const s = "ti,system-minimum-microvolt";
1663 struct power_supply_battery_info info = {};
1664 int v;
1666 if (device_property_read_u32(bdi->dev, s, &v) == 0) {
1667 v /= 1000;
1668 if (v >= BQ24190_REG_POC_SYS_MIN_MIN
1669 && v <= BQ24190_REG_POC_SYS_MIN_MAX)
1670 bdi->sys_min = v;
1671 else
1672 dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v);
1675 if (bdi->dev->of_node &&
1676 !power_supply_get_battery_info(bdi->charger, &info)) {
1677 v = info.precharge_current_ua / 1000;
1678 if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
1679 && v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
1680 bdi->iprechg = v;
1681 else
1682 dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
1685 v = info.charge_term_current_ua / 1000;
1686 if (v >= BQ24190_REG_PCTCC_ITERM_MIN
1687 && v <= BQ24190_REG_PCTCC_ITERM_MAX)
1688 bdi->iterm = v;
1689 else
1690 dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n",
1694 return 0;
1697 static int bq24190_probe(struct i2c_client *client,
1698 const struct i2c_device_id *id)
1700 struct i2c_adapter *adapter = client->adapter;
1701 struct device *dev = &client->dev;
1702 struct power_supply_config charger_cfg = {}, battery_cfg = {};
1703 struct bq24190_dev_info *bdi;
1704 int ret;
1706 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1707 dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1708 return -ENODEV;
1711 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1712 if (!bdi) {
1713 dev_err(dev, "Can't alloc bdi struct\n");
1714 return -ENOMEM;
1717 bdi->client = client;
1718 bdi->dev = dev;
1719 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1720 mutex_init(&bdi->f_reg_lock);
1721 bdi->f_reg = 0;
1722 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1723 INIT_DELAYED_WORK(&bdi->input_current_limit_work,
1724 bq24190_input_current_limit_work);
1726 i2c_set_clientdata(client, bdi);
1728 if (client->irq <= 0) {
1729 dev_err(dev, "Can't get irq info\n");
1730 return -EINVAL;
1733 bdi->edev = devm_extcon_dev_allocate(dev, bq24190_usb_extcon_cable);
1734 if (IS_ERR(bdi->edev))
1735 return PTR_ERR(bdi->edev);
1737 ret = devm_extcon_dev_register(dev, bdi->edev);
1738 if (ret < 0)
1739 return ret;
1741 pm_runtime_enable(dev);
1742 pm_runtime_use_autosuspend(dev);
1743 pm_runtime_set_autosuspend_delay(dev, 600);
1744 ret = pm_runtime_get_sync(dev);
1745 if (ret < 0) {
1746 dev_err(dev, "pm_runtime_get failed: %i\n", ret);
1747 goto out_pmrt;
1750 #ifdef CONFIG_SYSFS
1751 bq24190_sysfs_init_attrs();
1752 charger_cfg.attr_grp = bq24190_sysfs_groups;
1753 #endif
1755 charger_cfg.drv_data = bdi;
1756 charger_cfg.of_node = dev->of_node;
1757 charger_cfg.supplied_to = bq24190_charger_supplied_to;
1758 charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1759 bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1760 &charger_cfg);
1761 if (IS_ERR(bdi->charger)) {
1762 dev_err(dev, "Can't register charger\n");
1763 ret = PTR_ERR(bdi->charger);
1764 goto out_pmrt;
1767 /* the battery class is deprecated and will be removed. */
1768 /* in the interim, this property hides it. */
1769 if (!device_property_read_bool(dev, "omit-battery-class")) {
1770 battery_cfg.drv_data = bdi;
1771 bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1772 &battery_cfg);
1773 if (IS_ERR(bdi->battery)) {
1774 dev_err(dev, "Can't register battery\n");
1775 ret = PTR_ERR(bdi->battery);
1776 goto out_charger;
1780 ret = bq24190_get_config(bdi);
1781 if (ret < 0) {
1782 dev_err(dev, "Can't get devicetree config\n");
1783 goto out_charger;
1786 ret = bq24190_hw_init(bdi);
1787 if (ret < 0) {
1788 dev_err(dev, "Hardware init failed\n");
1789 goto out_charger;
1792 ret = bq24190_configure_usb_otg(bdi, bdi->ss_reg);
1793 if (ret < 0)
1794 goto out_charger;
1796 bdi->initialized = true;
1798 ret = devm_request_threaded_irq(dev, client->irq, NULL,
1799 bq24190_irq_handler_thread,
1800 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1801 "bq24190-charger", bdi);
1802 if (ret < 0) {
1803 dev_err(dev, "Can't set up irq handler\n");
1804 goto out_charger;
1807 ret = bq24190_register_vbus_regulator(bdi);
1808 if (ret < 0)
1809 goto out_charger;
1811 enable_irq_wake(client->irq);
1813 pm_runtime_mark_last_busy(dev);
1814 pm_runtime_put_autosuspend(dev);
1816 return 0;
1818 out_charger:
1819 if (!IS_ERR_OR_NULL(bdi->battery))
1820 power_supply_unregister(bdi->battery);
1821 power_supply_unregister(bdi->charger);
1823 out_pmrt:
1824 pm_runtime_put_sync(dev);
1825 pm_runtime_dont_use_autosuspend(dev);
1826 pm_runtime_disable(dev);
1827 return ret;
1830 static int bq24190_remove(struct i2c_client *client)
1832 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1833 int error;
1835 error = pm_runtime_get_sync(bdi->dev);
1836 if (error < 0) {
1837 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1838 pm_runtime_put_noidle(bdi->dev);
1841 bq24190_register_reset(bdi);
1842 if (bdi->battery)
1843 power_supply_unregister(bdi->battery);
1844 power_supply_unregister(bdi->charger);
1845 if (error >= 0)
1846 pm_runtime_put_sync(bdi->dev);
1847 pm_runtime_dont_use_autosuspend(bdi->dev);
1848 pm_runtime_disable(bdi->dev);
1850 return 0;
1853 static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
1855 struct i2c_client *client = to_i2c_client(dev);
1856 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1858 if (!bdi->initialized)
1859 return 0;
1861 dev_dbg(bdi->dev, "%s\n", __func__);
1863 return 0;
1866 static __maybe_unused int bq24190_runtime_resume(struct device *dev)
1868 struct i2c_client *client = to_i2c_client(dev);
1869 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1871 if (!bdi->initialized)
1872 return 0;
1874 if (!bdi->irq_event) {
1875 dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
1876 bq24190_check_status(bdi);
1879 return 0;
1882 static __maybe_unused int bq24190_pm_suspend(struct device *dev)
1884 struct i2c_client *client = to_i2c_client(dev);
1885 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1886 int error;
1888 error = pm_runtime_get_sync(bdi->dev);
1889 if (error < 0) {
1890 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1891 pm_runtime_put_noidle(bdi->dev);
1894 bq24190_register_reset(bdi);
1896 if (error >= 0) {
1897 pm_runtime_mark_last_busy(bdi->dev);
1898 pm_runtime_put_autosuspend(bdi->dev);
1901 return 0;
1904 static __maybe_unused int bq24190_pm_resume(struct device *dev)
1906 struct i2c_client *client = to_i2c_client(dev);
1907 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1908 int error;
1910 bdi->f_reg = 0;
1911 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1913 error = pm_runtime_get_sync(bdi->dev);
1914 if (error < 0) {
1915 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1916 pm_runtime_put_noidle(bdi->dev);
1919 bq24190_register_reset(bdi);
1920 bq24190_set_config(bdi);
1921 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1923 if (error >= 0) {
1924 pm_runtime_mark_last_busy(bdi->dev);
1925 pm_runtime_put_autosuspend(bdi->dev);
1928 /* Things may have changed while suspended so alert upper layer */
1929 power_supply_changed(bdi->charger);
1930 if (bdi->battery)
1931 power_supply_changed(bdi->battery);
1933 return 0;
1936 static const struct dev_pm_ops bq24190_pm_ops = {
1937 SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
1938 NULL)
1939 SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
1942 static const struct i2c_device_id bq24190_i2c_ids[] = {
1943 { "bq24190" },
1944 { "bq24192" },
1945 { "bq24192i" },
1946 { "bq24196" },
1947 { },
1949 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1951 #ifdef CONFIG_OF
1952 static const struct of_device_id bq24190_of_match[] = {
1953 { .compatible = "ti,bq24190", },
1954 { .compatible = "ti,bq24192", },
1955 { .compatible = "ti,bq24192i", },
1956 { .compatible = "ti,bq24196", },
1957 { },
1959 MODULE_DEVICE_TABLE(of, bq24190_of_match);
1960 #else
1961 static const struct of_device_id bq24190_of_match[] = {
1962 { },
1964 #endif
1966 static struct i2c_driver bq24190_driver = {
1967 .probe = bq24190_probe,
1968 .remove = bq24190_remove,
1969 .id_table = bq24190_i2c_ids,
1970 .driver = {
1971 .name = "bq24190-charger",
1972 .pm = &bq24190_pm_ops,
1973 .of_match_table = of_match_ptr(bq24190_of_match),
1976 module_i2c_driver(bq24190_driver);
1978 MODULE_LICENSE("GPL");
1979 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1980 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");