1 /*
2  * Driver for the TI bq24190 battery charger.
3  *
4  * Author: Mark A. Greer <mgreer@animalcreek.com>
5  *
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.
9  */
10 
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>
22 
23 #define	BQ24190_MANUFACTURER	"Texas Instruments"
24 
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
33 
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
48 
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
55 
56 #define BQ24190_REG_PCTCC	0x03 /* Pre-charge/Termination Current Cntl */
57 #define BQ24190_REG_PCTCC_IPRECHG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
58 						 BIT(4))
59 #define BQ24190_REG_PCTCC_IPRECHG_SHIFT		4
60 #define BQ24190_REG_PCTCC_ITERM_MASK		(BIT(3) | BIT(2) | BIT(1) | \
61 						 BIT(0))
62 #define BQ24190_REG_PCTCC_ITERM_SHIFT		0
63 
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
72 
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
86 
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
94 
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
106 
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
120 
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
132 
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
143 
144 /*
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.
150  */
151 struct bq24190_dev_info {
152 	struct i2c_client		*client;
153 	struct device			*dev;
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];
160 	bool				initialized;
161 	bool				irq_event;
162 	struct mutex			f_reg_lock;
163 	u8				f_reg;
164 	u8				ss_reg;
165 	u8				watchdog;
166 };
167 
168 /*
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
173  * represents.
174  */
175 
176 /* REG00[2:0] (IINLIM) in uAh */
177 static const int bq24190_isc_iinlim_values[] = {
178 	 100000,  150000,  500000,  900000, 1200000, 1500000, 2000000, 3000000
179 };
180 
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
191 };
192 
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,
202 	4400000
203 };
204 
205 /* REG06[1:0] (TREG) in tenths of degrees Celsius */
206 static const int bq24190_ictrc_treg_values[] = {
207 	600, 800, 1000, 1200
208 };
209 
210 /*
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'
214  * is less than 2^8.
215  */
216 static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
217 {
218 	int i;
219 
220 	for (i = 1; i < tbl_size; i++)
221 		if (v < tbl[i])
222 			break;
223 
224 	return i - 1;
225 }
226 
227 /* Basic driver I/O routines */
228 
229 static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
230 {
231 	int ret;
232 
233 	ret = i2c_smbus_read_byte_data(bdi->client, reg);
234 	if (ret < 0)
235 		return ret;
236 
237 	*data = ret;
238 	return 0;
239 }
240 
241 static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
242 {
243 	return i2c_smbus_write_byte_data(bdi->client, reg, data);
244 }
245 
246 static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
247 		u8 mask, u8 shift, u8 *data)
248 {
249 	u8 v;
250 	int ret;
251 
252 	ret = bq24190_read(bdi, reg, &v);
253 	if (ret < 0)
254 		return ret;
255 
256 	v &= mask;
257 	v >>= shift;
258 	*data = v;
259 
260 	return 0;
261 }
262 
263 static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
264 		u8 mask, u8 shift, u8 data)
265 {
266 	u8 v;
267 	int ret;
268 
269 	ret = bq24190_read(bdi, reg, &v);
270 	if (ret < 0)
271 		return ret;
272 
273 	v &= ~mask;
274 	v |= ((data << shift) & mask);
275 
276 	return bq24190_write(bdi, reg, v);
277 }
278 
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,
282 		int *val)
283 {
284 	u8 v;
285 	int ret;
286 
287 	ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
288 	if (ret < 0)
289 		return ret;
290 
291 	v = (v >= tbl_size) ? (tbl_size - 1) : v;
292 	*val = tbl[v];
293 
294 	return 0;
295 }
296 
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,
300 		int val)
301 {
302 	u8 idx;
303 
304 	idx = bq24190_find_idx(tbl, tbl_size, val);
305 
306 	return bq24190_write_mask(bdi, reg, mask, shift, idx);
307 }
308 
309 #ifdef CONFIG_SYSFS
310 /*
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.
316  */
317 
318 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store)			\
319 {									\
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,			\
324 }
325 
326 #define BQ24190_SYSFS_FIELD_RW(_name, r, f)				\
327 		BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO,	\
328 				bq24190_sysfs_store)
329 
330 #define BQ24190_SYSFS_FIELD_RO(_name, r, f)				\
331 		BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
332 
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);
337 
338 struct bq24190_sysfs_field_info {
339 	struct device_attribute	attr;
340 	u8	reg;
341 	u8	mask;
342 	u8	shift;
343 };
344 
345 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
346 #undef SS
347 
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),
391 };
392 
393 static struct attribute *
394 	bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
395 
396 static const struct attribute_group bq24190_sysfs_attr_group = {
397 	.attrs = bq24190_sysfs_attrs,
398 };
399 
400 static void bq24190_sysfs_init_attrs(void)
401 {
402 	int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
403 
404 	for (i = 0; i < limit; i++)
405 		bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
406 
407 	bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
408 }
409 
410 static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
411 		const char *name)
412 {
413 	int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
414 
415 	for (i = 0; i < limit; i++)
416 		if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
417 			break;
418 
419 	if (i >= limit)
420 		return NULL;
421 
422 	return &bq24190_sysfs_field_tbl[i];
423 }
424 
425 static ssize_t bq24190_sysfs_show(struct device *dev,
426 		struct device_attribute *attr, char *buf)
427 {
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;
431 	ssize_t count;
432 	int ret;
433 	u8 v;
434 
435 	info = bq24190_sysfs_field_lookup(attr->attr.name);
436 	if (!info)
437 		return -EINVAL;
438 
439 	ret = pm_runtime_get_sync(bdi->dev);
440 	if (ret < 0)
441 		return ret;
442 
443 	ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
444 	if (ret)
445 		count = ret;
446 	else
447 		count = scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
448 
449 	pm_runtime_mark_last_busy(bdi->dev);
450 	pm_runtime_put_autosuspend(bdi->dev);
451 
452 	return count;
453 }
454 
455 static ssize_t bq24190_sysfs_store(struct device *dev,
456 		struct device_attribute *attr, const char *buf, size_t count)
457 {
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;
461 	int ret;
462 	u8 v;
463 
464 	info = bq24190_sysfs_field_lookup(attr->attr.name);
465 	if (!info)
466 		return -EINVAL;
467 
468 	ret = kstrtou8(buf, 0, &v);
469 	if (ret < 0)
470 		return ret;
471 
472 	ret = pm_runtime_get_sync(bdi->dev);
473 	if (ret < 0)
474 		return ret;
475 
476 	ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
477 	if (ret)
478 		count = ret;
479 
480 	pm_runtime_mark_last_busy(bdi->dev);
481 	pm_runtime_put_autosuspend(bdi->dev);
482 
483 	return count;
484 }
485 
486 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
487 {
488 	bq24190_sysfs_init_attrs();
489 
490 	return sysfs_create_group(&bdi->charger->dev.kobj,
491 			&bq24190_sysfs_attr_group);
492 }
493 
494 static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi)
495 {
496 	sysfs_remove_group(&bdi->charger->dev.kobj, &bq24190_sysfs_attr_group);
497 }
498 #else
499 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
500 {
501 	return 0;
502 }
503 
504 static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {}
505 #endif
506 
507 /*
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
513  * same write.
514  */
515 static int bq24190_set_mode_host(struct bq24190_dev_info *bdi)
516 {
517 	int ret;
518 	u8 v;
519 
520 	ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
521 	if (ret < 0)
522 		return ret;
523 
524 	bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
525 					BQ24190_REG_CTTC_WATCHDOG_SHIFT);
526 	v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
527 
528 	return bq24190_write(bdi, BQ24190_REG_CTTC, v);
529 }
530 
531 static int bq24190_register_reset(struct bq24190_dev_info *bdi)
532 {
533 	int ret, limit = 100;
534 	u8 v;
535 
536 	if (device_property_read_bool(bdi->dev, "disable-reset"))
537 		return 0;
538 
539 	/* Reset the registers */
540 	ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
541 			BQ24190_REG_POC_RESET_MASK,
542 			BQ24190_REG_POC_RESET_SHIFT,
543 			0x1);
544 	if (ret < 0)
545 		return ret;
546 
547 	/* Reset bit will be cleared by hardware so poll until it is */
548 	do {
549 		ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
550 				BQ24190_REG_POC_RESET_MASK,
551 				BQ24190_REG_POC_RESET_SHIFT,
552 				&v);
553 		if (ret < 0)
554 			return ret;
555 
556 		if (v == 0)
557 			return 0;
558 
559 		usleep_range(100, 200);
560 	} while (--limit);
561 
562 	return -EIO;
563 }
564 
565 /* Charger power supply property routines */
566 
567 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
568 		union power_supply_propval *val)
569 {
570 	u8 v;
571 	int type, ret;
572 
573 	ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
574 			BQ24190_REG_POC_CHG_CONFIG_MASK,
575 			BQ24190_REG_POC_CHG_CONFIG_SHIFT,
576 			&v);
577 	if (ret < 0)
578 		return ret;
579 
580 	/* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
581 	if (!v) {
582 		type = POWER_SUPPLY_CHARGE_TYPE_NONE;
583 	} else {
584 		ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
585 				BQ24190_REG_CCC_FORCE_20PCT_MASK,
586 				BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
587 				&v);
588 		if (ret < 0)
589 			return ret;
590 
591 		type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
592 			     POWER_SUPPLY_CHARGE_TYPE_FAST;
593 	}
594 
595 	val->intval = type;
596 
597 	return 0;
598 }
599 
600 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
601 		const union power_supply_propval *val)
602 {
603 	u8 chg_config, force_20pct, en_term;
604 	int ret;
605 
606 	/*
607 	 * According to the "Termination when REG02[0] = 1" section of
608 	 * the bq24190 manual, the trickle charge could be less than the
609 	 * termination current so it recommends turning off the termination
610 	 * function.
611 	 *
612 	 * Note: AFAICT from the datasheet, the user will have to manually
613 	 * turn off the charging when in 20% mode.  If its not turned off,
614 	 * there could be battery damage.  So, use this mode at your own risk.
615 	 */
616 	switch (val->intval) {
617 	case POWER_SUPPLY_CHARGE_TYPE_NONE:
618 		chg_config = 0x0;
619 		break;
620 	case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
621 		chg_config = 0x1;
622 		force_20pct = 0x1;
623 		en_term = 0x0;
624 		break;
625 	case POWER_SUPPLY_CHARGE_TYPE_FAST:
626 		chg_config = 0x1;
627 		force_20pct = 0x0;
628 		en_term = 0x1;
629 		break;
630 	default:
631 		return -EINVAL;
632 	}
633 
634 	if (chg_config) { /* Enabling the charger */
635 		ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
636 				BQ24190_REG_CCC_FORCE_20PCT_MASK,
637 				BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
638 				force_20pct);
639 		if (ret < 0)
640 			return ret;
641 
642 		ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
643 				BQ24190_REG_CTTC_EN_TERM_MASK,
644 				BQ24190_REG_CTTC_EN_TERM_SHIFT,
645 				en_term);
646 		if (ret < 0)
647 			return ret;
648 	}
649 
650 	return bq24190_write_mask(bdi, BQ24190_REG_POC,
651 			BQ24190_REG_POC_CHG_CONFIG_MASK,
652 			BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
653 }
654 
655 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
656 		union power_supply_propval *val)
657 {
658 	u8 v;
659 	int health;
660 
661 	mutex_lock(&bdi->f_reg_lock);
662 	v = bdi->f_reg;
663 	mutex_unlock(&bdi->f_reg_lock);
664 
665 	if (v & BQ24190_REG_F_NTC_FAULT_MASK) {
666 		switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
667 		case 0x1: /* TS1  Cold */
668 		case 0x3: /* TS2  Cold */
669 		case 0x5: /* Both Cold */
670 			health = POWER_SUPPLY_HEALTH_COLD;
671 			break;
672 		case 0x2: /* TS1  Hot */
673 		case 0x4: /* TS2  Hot */
674 		case 0x6: /* Both Hot */
675 			health = POWER_SUPPLY_HEALTH_OVERHEAT;
676 			break;
677 		default:
678 			health = POWER_SUPPLY_HEALTH_UNKNOWN;
679 		}
680 	} else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
681 		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
682 	} else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
683 		switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
684 		case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
685 			/*
686 			 * This could be over-voltage or under-voltage
687 			 * and there's no way to tell which.  Instead
688 			 * of looking foolish and returning 'OVERVOLTAGE'
689 			 * when its really under-voltage, just return
690 			 * 'UNSPEC_FAILURE'.
691 			 */
692 			health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
693 			break;
694 		case 0x2: /* Thermal Shutdown */
695 			health = POWER_SUPPLY_HEALTH_OVERHEAT;
696 			break;
697 		case 0x3: /* Charge Safety Timer Expiration */
698 			health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
699 			break;
700 		default:  /* prevent compiler warning */
701 			health = -1;
702 		}
703 	} else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
704 		/*
705 		 * This could be over-current or over-voltage but there's
706 		 * no way to tell which.  Return 'OVERVOLTAGE' since there
707 		 * isn't an 'OVERCURRENT' value defined that we can return
708 		 * even if it was over-current.
709 		 */
710 		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
711 	} else {
712 		health = POWER_SUPPLY_HEALTH_GOOD;
713 	}
714 
715 	val->intval = health;
716 
717 	return 0;
718 }
719 
720 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
721 		union power_supply_propval *val)
722 {
723 	u8 pg_stat, batfet_disable;
724 	int ret;
725 
726 	ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
727 			BQ24190_REG_SS_PG_STAT_MASK,
728 			BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
729 	if (ret < 0)
730 		return ret;
731 
732 	ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
733 			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
734 			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
735 	if (ret < 0)
736 		return ret;
737 
738 	val->intval = pg_stat && !batfet_disable;
739 
740 	return 0;
741 }
742 
743 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
744 				      const union power_supply_propval *val);
745 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
746 				      union power_supply_propval *val);
747 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
748 					      union power_supply_propval *val);
749 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
750 					      const union power_supply_propval *val);
751 
752 static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
753 				      const union power_supply_propval *val)
754 {
755 	return bq24190_battery_set_online(bdi, val);
756 }
757 
758 static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
759 				      union power_supply_propval *val)
760 {
761 	return bq24190_battery_get_status(bdi, val);
762 }
763 
764 static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
765 					      union power_supply_propval *val)
766 {
767 	return bq24190_battery_get_temp_alert_max(bdi, val);
768 }
769 
770 static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
771 					      const union power_supply_propval *val)
772 {
773 	return bq24190_battery_set_temp_alert_max(bdi, val);
774 }
775 
776 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
777 		union power_supply_propval *val)
778 {
779 	u8 v;
780 	int curr, ret;
781 
782 	ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
783 			BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
784 			bq24190_ccc_ichg_values,
785 			ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
786 	if (ret < 0)
787 		return ret;
788 
789 	ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
790 			BQ24190_REG_CCC_FORCE_20PCT_MASK,
791 			BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
792 	if (ret < 0)
793 		return ret;
794 
795 	/* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
796 	if (v)
797 		curr /= 5;
798 
799 	val->intval = curr;
800 	return 0;
801 }
802 
803 static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
804 		union power_supply_propval *val)
805 {
806 	int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
807 
808 	val->intval = bq24190_ccc_ichg_values[idx];
809 	return 0;
810 }
811 
812 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
813 		const union power_supply_propval *val)
814 {
815 	u8 v;
816 	int ret, curr = val->intval;
817 
818 	ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
819 			BQ24190_REG_CCC_FORCE_20PCT_MASK,
820 			BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
821 	if (ret < 0)
822 		return ret;
823 
824 	/* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
825 	if (v)
826 		curr *= 5;
827 
828 	return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
829 			BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
830 			bq24190_ccc_ichg_values,
831 			ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
832 }
833 
834 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
835 		union power_supply_propval *val)
836 {
837 	int voltage, ret;
838 
839 	ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
840 			BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
841 			bq24190_cvc_vreg_values,
842 			ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
843 	if (ret < 0)
844 		return ret;
845 
846 	val->intval = voltage;
847 	return 0;
848 }
849 
850 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
851 		union power_supply_propval *val)
852 {
853 	int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
854 
855 	val->intval = bq24190_cvc_vreg_values[idx];
856 	return 0;
857 }
858 
859 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
860 		const union power_supply_propval *val)
861 {
862 	return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
863 			BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
864 			bq24190_cvc_vreg_values,
865 			ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
866 }
867 
868 static int bq24190_charger_get_property(struct power_supply *psy,
869 		enum power_supply_property psp, union power_supply_propval *val)
870 {
871 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
872 	int ret;
873 
874 	dev_dbg(bdi->dev, "prop: %d\n", psp);
875 
876 	ret = pm_runtime_get_sync(bdi->dev);
877 	if (ret < 0)
878 		return ret;
879 
880 	switch (psp) {
881 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
882 		ret = bq24190_charger_get_charge_type(bdi, val);
883 		break;
884 	case POWER_SUPPLY_PROP_HEALTH:
885 		ret = bq24190_charger_get_health(bdi, val);
886 		break;
887 	case POWER_SUPPLY_PROP_ONLINE:
888 		ret = bq24190_charger_get_online(bdi, val);
889 		break;
890 	case POWER_SUPPLY_PROP_STATUS:
891 		ret = bq24190_charger_get_status(bdi, val);
892 		break;
893 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
894 		ret =  bq24190_charger_get_temp_alert_max(bdi, val);
895 		break;
896 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
897 		ret = bq24190_charger_get_current(bdi, val);
898 		break;
899 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
900 		ret = bq24190_charger_get_current_max(bdi, val);
901 		break;
902 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
903 		ret = bq24190_charger_get_voltage(bdi, val);
904 		break;
905 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
906 		ret = bq24190_charger_get_voltage_max(bdi, val);
907 		break;
908 	case POWER_SUPPLY_PROP_SCOPE:
909 		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
910 		ret = 0;
911 		break;
912 	case POWER_SUPPLY_PROP_MODEL_NAME:
913 		val->strval = bdi->model_name;
914 		ret = 0;
915 		break;
916 	case POWER_SUPPLY_PROP_MANUFACTURER:
917 		val->strval = BQ24190_MANUFACTURER;
918 		ret = 0;
919 		break;
920 	default:
921 		ret = -ENODATA;
922 	}
923 
924 	pm_runtime_mark_last_busy(bdi->dev);
925 	pm_runtime_put_autosuspend(bdi->dev);
926 
927 	return ret;
928 }
929 
930 static int bq24190_charger_set_property(struct power_supply *psy,
931 		enum power_supply_property psp,
932 		const union power_supply_propval *val)
933 {
934 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
935 	int ret;
936 
937 	dev_dbg(bdi->dev, "prop: %d\n", psp);
938 
939 	ret = pm_runtime_get_sync(bdi->dev);
940 	if (ret < 0)
941 		return ret;
942 
943 	switch (psp) {
944 	case POWER_SUPPLY_PROP_ONLINE:
945 		ret = bq24190_charger_set_online(bdi, val);
946 		break;
947 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
948 		ret = bq24190_charger_set_temp_alert_max(bdi, val);
949 		break;
950 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
951 		ret = bq24190_charger_set_charge_type(bdi, val);
952 		break;
953 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
954 		ret = bq24190_charger_set_current(bdi, val);
955 		break;
956 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
957 		ret = bq24190_charger_set_voltage(bdi, val);
958 		break;
959 	default:
960 		ret = -EINVAL;
961 	}
962 
963 	pm_runtime_mark_last_busy(bdi->dev);
964 	pm_runtime_put_autosuspend(bdi->dev);
965 
966 	return ret;
967 }
968 
969 static int bq24190_charger_property_is_writeable(struct power_supply *psy,
970 		enum power_supply_property psp)
971 {
972 	int ret;
973 
974 	switch (psp) {
975 	case POWER_SUPPLY_PROP_ONLINE:
976 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
977 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
978 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
979 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
980 		ret = 1;
981 		break;
982 	default:
983 		ret = 0;
984 	}
985 
986 	return ret;
987 }
988 
989 static enum power_supply_property bq24190_charger_properties[] = {
990 	POWER_SUPPLY_PROP_CHARGE_TYPE,
991 	POWER_SUPPLY_PROP_HEALTH,
992 	POWER_SUPPLY_PROP_ONLINE,
993 	POWER_SUPPLY_PROP_STATUS,
994 	POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
995 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
996 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
997 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
998 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
999 	POWER_SUPPLY_PROP_SCOPE,
1000 	POWER_SUPPLY_PROP_MODEL_NAME,
1001 	POWER_SUPPLY_PROP_MANUFACTURER,
1002 };
1003 
1004 static char *bq24190_charger_supplied_to[] = {
1005 	"main-battery",
1006 };
1007 
1008 static const struct power_supply_desc bq24190_charger_desc = {
1009 	.name			= "bq24190-charger",
1010 	.type			= POWER_SUPPLY_TYPE_USB,
1011 	.properties		= bq24190_charger_properties,
1012 	.num_properties		= ARRAY_SIZE(bq24190_charger_properties),
1013 	.get_property		= bq24190_charger_get_property,
1014 	.set_property		= bq24190_charger_set_property,
1015 	.property_is_writeable	= bq24190_charger_property_is_writeable,
1016 };
1017 
1018 /* Battery power supply property routines */
1019 
1020 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1021 		union power_supply_propval *val)
1022 {
1023 	u8 ss_reg, chrg_fault;
1024 	int status, ret;
1025 
1026 	mutex_lock(&bdi->f_reg_lock);
1027 	chrg_fault = bdi->f_reg;
1028 	mutex_unlock(&bdi->f_reg_lock);
1029 
1030 	chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
1031 	chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
1032 
1033 	ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1034 	if (ret < 0)
1035 		return ret;
1036 
1037 	/*
1038 	 * The battery must be discharging when any of these are true:
1039 	 * - there is no good power source;
1040 	 * - there is a charge fault.
1041 	 * Could also be discharging when in "supplement mode" but
1042 	 * there is no way to tell when its in that mode.
1043 	 */
1044 	if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
1045 		status = POWER_SUPPLY_STATUS_DISCHARGING;
1046 	} else {
1047 		ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
1048 		ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
1049 
1050 		switch (ss_reg) {
1051 		case 0x0: /* Not Charging */
1052 			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1053 			break;
1054 		case 0x1: /* Pre-charge */
1055 		case 0x2: /* Fast Charging */
1056 			status = POWER_SUPPLY_STATUS_CHARGING;
1057 			break;
1058 		case 0x3: /* Charge Termination Done */
1059 			status = POWER_SUPPLY_STATUS_FULL;
1060 			break;
1061 		default:
1062 			ret = -EIO;
1063 		}
1064 	}
1065 
1066 	if (!ret)
1067 		val->intval = status;
1068 
1069 	return ret;
1070 }
1071 
1072 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1073 		union power_supply_propval *val)
1074 {
1075 	u8 v;
1076 	int health;
1077 
1078 	mutex_lock(&bdi->f_reg_lock);
1079 	v = bdi->f_reg;
1080 	mutex_unlock(&bdi->f_reg_lock);
1081 
1082 	if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1083 		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1084 	} else {
1085 		v &= BQ24190_REG_F_NTC_FAULT_MASK;
1086 		v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1087 
1088 		switch (v) {
1089 		case 0x0: /* Normal */
1090 			health = POWER_SUPPLY_HEALTH_GOOD;
1091 			break;
1092 		case 0x1: /* TS1 Cold */
1093 		case 0x3: /* TS2 Cold */
1094 		case 0x5: /* Both Cold */
1095 			health = POWER_SUPPLY_HEALTH_COLD;
1096 			break;
1097 		case 0x2: /* TS1 Hot */
1098 		case 0x4: /* TS2 Hot */
1099 		case 0x6: /* Both Hot */
1100 			health = POWER_SUPPLY_HEALTH_OVERHEAT;
1101 			break;
1102 		default:
1103 			health = POWER_SUPPLY_HEALTH_UNKNOWN;
1104 		}
1105 	}
1106 
1107 	val->intval = health;
1108 	return 0;
1109 }
1110 
1111 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1112 		union power_supply_propval *val)
1113 {
1114 	u8 batfet_disable;
1115 	int ret;
1116 
1117 	ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1118 			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1119 			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1120 	if (ret < 0)
1121 		return ret;
1122 
1123 	val->intval = !batfet_disable;
1124 	return 0;
1125 }
1126 
1127 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1128 		const union power_supply_propval *val)
1129 {
1130 	return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1131 			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1132 			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1133 }
1134 
1135 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1136 		union power_supply_propval *val)
1137 {
1138 	int temp, ret;
1139 
1140 	ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1141 			BQ24190_REG_ICTRC_TREG_MASK,
1142 			BQ24190_REG_ICTRC_TREG_SHIFT,
1143 			bq24190_ictrc_treg_values,
1144 			ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1145 	if (ret < 0)
1146 		return ret;
1147 
1148 	val->intval = temp;
1149 	return 0;
1150 }
1151 
1152 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1153 		const union power_supply_propval *val)
1154 {
1155 	return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1156 			BQ24190_REG_ICTRC_TREG_MASK,
1157 			BQ24190_REG_ICTRC_TREG_SHIFT,
1158 			bq24190_ictrc_treg_values,
1159 			ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1160 }
1161 
1162 static int bq24190_battery_get_property(struct power_supply *psy,
1163 		enum power_supply_property psp, union power_supply_propval *val)
1164 {
1165 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1166 	int ret;
1167 
1168 	dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1169 	dev_dbg(bdi->dev, "prop: %d\n", psp);
1170 
1171 	ret = pm_runtime_get_sync(bdi->dev);
1172 	if (ret < 0)
1173 		return ret;
1174 
1175 	switch (psp) {
1176 	case POWER_SUPPLY_PROP_STATUS:
1177 		ret = bq24190_battery_get_status(bdi, val);
1178 		break;
1179 	case POWER_SUPPLY_PROP_HEALTH:
1180 		ret = bq24190_battery_get_health(bdi, val);
1181 		break;
1182 	case POWER_SUPPLY_PROP_ONLINE:
1183 		ret = bq24190_battery_get_online(bdi, val);
1184 		break;
1185 	case POWER_SUPPLY_PROP_TECHNOLOGY:
1186 		/* Could be Li-on or Li-polymer but no way to tell which */
1187 		val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1188 		ret = 0;
1189 		break;
1190 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1191 		ret = bq24190_battery_get_temp_alert_max(bdi, val);
1192 		break;
1193 	case POWER_SUPPLY_PROP_SCOPE:
1194 		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1195 		ret = 0;
1196 		break;
1197 	default:
1198 		ret = -ENODATA;
1199 	}
1200 
1201 	pm_runtime_mark_last_busy(bdi->dev);
1202 	pm_runtime_put_autosuspend(bdi->dev);
1203 
1204 	return ret;
1205 }
1206 
1207 static int bq24190_battery_set_property(struct power_supply *psy,
1208 		enum power_supply_property psp,
1209 		const union power_supply_propval *val)
1210 {
1211 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1212 	int ret;
1213 
1214 	dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1215 	dev_dbg(bdi->dev, "prop: %d\n", psp);
1216 
1217 	ret = pm_runtime_get_sync(bdi->dev);
1218 	if (ret < 0)
1219 		return ret;
1220 
1221 	switch (psp) {
1222 	case POWER_SUPPLY_PROP_ONLINE:
1223 		ret = bq24190_battery_set_online(bdi, val);
1224 		break;
1225 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1226 		ret = bq24190_battery_set_temp_alert_max(bdi, val);
1227 		break;
1228 	default:
1229 		ret = -EINVAL;
1230 	}
1231 
1232 	pm_runtime_mark_last_busy(bdi->dev);
1233 	pm_runtime_put_autosuspend(bdi->dev);
1234 
1235 	return ret;
1236 }
1237 
1238 static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1239 		enum power_supply_property psp)
1240 {
1241 	int ret;
1242 
1243 	switch (psp) {
1244 	case POWER_SUPPLY_PROP_ONLINE:
1245 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1246 		ret = 1;
1247 		break;
1248 	default:
1249 		ret = 0;
1250 	}
1251 
1252 	return ret;
1253 }
1254 
1255 static enum power_supply_property bq24190_battery_properties[] = {
1256 	POWER_SUPPLY_PROP_STATUS,
1257 	POWER_SUPPLY_PROP_HEALTH,
1258 	POWER_SUPPLY_PROP_ONLINE,
1259 	POWER_SUPPLY_PROP_TECHNOLOGY,
1260 	POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1261 	POWER_SUPPLY_PROP_SCOPE,
1262 };
1263 
1264 static const struct power_supply_desc bq24190_battery_desc = {
1265 	.name			= "bq24190-battery",
1266 	.type			= POWER_SUPPLY_TYPE_BATTERY,
1267 	.properties		= bq24190_battery_properties,
1268 	.num_properties		= ARRAY_SIZE(bq24190_battery_properties),
1269 	.get_property		= bq24190_battery_get_property,
1270 	.set_property		= bq24190_battery_set_property,
1271 	.property_is_writeable	= bq24190_battery_property_is_writeable,
1272 };
1273 
1274 static void bq24190_check_status(struct bq24190_dev_info *bdi)
1275 {
1276 	const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1277 	const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1278 				| BQ24190_REG_F_NTC_FAULT_MASK;
1279 	bool alert_charger = false, alert_battery = false;
1280 	u8 ss_reg = 0, f_reg = 0;
1281 	int i, ret;
1282 
1283 	ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1284 	if (ret < 0) {
1285 		dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1286 		return;
1287 	}
1288 
1289 	i = 0;
1290 	do {
1291 		ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1292 		if (ret < 0) {
1293 			dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1294 			return;
1295 		}
1296 	} while (f_reg && ++i < 2);
1297 
1298 	/* ignore over/under voltage fault after disconnect */
1299 	if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1300 	    !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1301 		f_reg = 0;
1302 
1303 	if (f_reg != bdi->f_reg) {
1304 		dev_warn(bdi->dev,
1305 			"Fault: boost %d, charge %d, battery %d, ntc %d\n",
1306 			!!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1307 			!!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1308 			!!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1309 			!!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1310 
1311 		mutex_lock(&bdi->f_reg_lock);
1312 		if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1313 			alert_battery = true;
1314 		if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1315 			alert_charger = true;
1316 		bdi->f_reg = f_reg;
1317 		mutex_unlock(&bdi->f_reg_lock);
1318 	}
1319 
1320 	if (ss_reg != bdi->ss_reg) {
1321 		/*
1322 		 * The device is in host mode so when PG_STAT goes from 1->0
1323 		 * (i.e., power removed) HIZ needs to be disabled.
1324 		 */
1325 		if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1326 				!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1327 			ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1328 					BQ24190_REG_ISC_EN_HIZ_MASK,
1329 					BQ24190_REG_ISC_EN_HIZ_SHIFT,
1330 					0);
1331 			if (ret < 0)
1332 				dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1333 					ret);
1334 		}
1335 
1336 		if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1337 			alert_battery = true;
1338 		if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1339 			alert_charger = true;
1340 		bdi->ss_reg = ss_reg;
1341 	}
1342 
1343 	if (alert_charger || alert_battery)
1344 		power_supply_changed(bdi->charger);
1345 	if (alert_battery && bdi->battery)
1346 		power_supply_changed(bdi->battery);
1347 
1348 	dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1349 }
1350 
1351 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1352 {
1353 	struct bq24190_dev_info *bdi = data;
1354 	int error;
1355 
1356 	bdi->irq_event = true;
1357 	error = pm_runtime_get_sync(bdi->dev);
1358 	if (error < 0) {
1359 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1360 		pm_runtime_put_noidle(bdi->dev);
1361 		return IRQ_NONE;
1362 	}
1363 	bq24190_check_status(bdi);
1364 	pm_runtime_mark_last_busy(bdi->dev);
1365 	pm_runtime_put_autosuspend(bdi->dev);
1366 	bdi->irq_event = false;
1367 
1368 	return IRQ_HANDLED;
1369 }
1370 
1371 static void bq24190_extcon_work(struct work_struct *work)
1372 {
1373 	struct bq24190_dev_info *bdi =
1374 		container_of(work, struct bq24190_dev_info, extcon_work.work);
1375 	int error, iinlim = 0;
1376 	u8 v;
1377 
1378 	error = pm_runtime_get_sync(bdi->dev);
1379 	if (error < 0) {
1380 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1381 		pm_runtime_put_noidle(bdi->dev);
1382 		return;
1383 	}
1384 
1385 	if      (extcon_get_state(bdi->extcon, EXTCON_CHG_USB_SDP) == 1)
1386 		iinlim =  500000;
1387 	else if (extcon_get_state(bdi->extcon, EXTCON_CHG_USB_CDP) == 1 ||
1388 		 extcon_get_state(bdi->extcon, EXTCON_CHG_USB_ACA) == 1)
1389 		iinlim = 1500000;
1390 	else if (extcon_get_state(bdi->extcon, EXTCON_CHG_USB_DCP) == 1)
1391 		iinlim = 2000000;
1392 
1393 	if (iinlim) {
1394 		error = bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1395 					      BQ24190_REG_ISC_IINLIM_MASK,
1396 					      BQ24190_REG_ISC_IINLIM_SHIFT,
1397 					      bq24190_isc_iinlim_values,
1398 					      ARRAY_SIZE(bq24190_isc_iinlim_values),
1399 					      iinlim);
1400 		if (error < 0)
1401 			dev_err(bdi->dev, "Can't set IINLIM: %d\n", error);
1402 	}
1403 
1404 	/* if no charger found and in USB host mode, set OTG 5V boost, else normal */
1405 	if (!iinlim && extcon_get_state(bdi->extcon, EXTCON_USB_HOST) == 1)
1406 		v = BQ24190_REG_POC_CHG_CONFIG_OTG;
1407 	else
1408 		v = BQ24190_REG_POC_CHG_CONFIG_CHARGE;
1409 
1410 	error = bq24190_write_mask(bdi, BQ24190_REG_POC,
1411 				   BQ24190_REG_POC_CHG_CONFIG_MASK,
1412 				   BQ24190_REG_POC_CHG_CONFIG_SHIFT,
1413 				   v);
1414 	if (error < 0)
1415 		dev_err(bdi->dev, "Can't set CHG_CONFIG: %d\n", error);
1416 
1417 	pm_runtime_mark_last_busy(bdi->dev);
1418 	pm_runtime_put_autosuspend(bdi->dev);
1419 }
1420 
1421 static int bq24190_extcon_event(struct notifier_block *nb, unsigned long event,
1422 				void *param)
1423 {
1424 	struct bq24190_dev_info *bdi =
1425 		container_of(nb, struct bq24190_dev_info, extcon_nb);
1426 
1427 	/*
1428 	 * The Power-Good detection may take up to 220ms, sometimes
1429 	 * the external charger detection is quicker, and the bq24190 will
1430 	 * reset to iinlim based on its own charger detection (which is not
1431 	 * hooked up when using external charger detection) resulting in
1432 	 * a too low default 500mA iinlim. Delay applying the extcon value
1433 	 * for 300ms to avoid this.
1434 	 */
1435 	queue_delayed_work(system_wq, &bdi->extcon_work, msecs_to_jiffies(300));
1436 
1437 	return NOTIFY_OK;
1438 }
1439 
1440 static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1441 {
1442 	u8 v;
1443 	int ret;
1444 
1445 	/* First check that the device really is what its supposed to be */
1446 	ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1447 			BQ24190_REG_VPRS_PN_MASK,
1448 			BQ24190_REG_VPRS_PN_SHIFT,
1449 			&v);
1450 	if (ret < 0)
1451 		return ret;
1452 
1453 	if (v != BQ24190_REG_VPRS_PN_24190 &&
1454 	    v != BQ24190_REG_VPRS_PN_24192I) {
1455 		dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1456 		return -ENODEV;
1457 	}
1458 
1459 	ret = bq24190_register_reset(bdi);
1460 	if (ret < 0)
1461 		return ret;
1462 
1463 	ret = bq24190_set_mode_host(bdi);
1464 	if (ret < 0)
1465 		return ret;
1466 
1467 	return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1468 }
1469 
1470 static int bq24190_probe(struct i2c_client *client,
1471 		const struct i2c_device_id *id)
1472 {
1473 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1474 	struct device *dev = &client->dev;
1475 	struct power_supply_config charger_cfg = {}, battery_cfg = {};
1476 	struct bq24190_dev_info *bdi;
1477 	const char *name;
1478 	int ret;
1479 
1480 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1481 		dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1482 		return -ENODEV;
1483 	}
1484 
1485 	bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1486 	if (!bdi) {
1487 		dev_err(dev, "Can't alloc bdi struct\n");
1488 		return -ENOMEM;
1489 	}
1490 
1491 	bdi->client = client;
1492 	bdi->dev = dev;
1493 	strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1494 	mutex_init(&bdi->f_reg_lock);
1495 	bdi->f_reg = 0;
1496 	bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1497 
1498 	i2c_set_clientdata(client, bdi);
1499 
1500 	if (!client->irq) {
1501 		dev_err(dev, "Can't get irq info\n");
1502 		return -EINVAL;
1503 	}
1504 
1505 	/*
1506 	 * Devicetree platforms should get extcon via phandle (not yet supported).
1507 	 * On ACPI platforms, extcon clients may invoke us with:
1508 	 * struct property_entry pe[] =
1509 	 *   { PROPERTY_ENTRY_STRING("extcon-name", client_name), ... };
1510 	 * struct i2c_board_info bi =
1511 	 *   { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
1512 	 * struct i2c_adapter ad = { ... };
1513 	 * i2c_add_adapter(&ad);
1514 	 * i2c_new_device(&ad, &bi);
1515 	 */
1516 	if (device_property_read_string(dev, "extcon-name", &name) == 0) {
1517 		bdi->extcon = extcon_get_extcon_dev(name);
1518 		if (!bdi->extcon)
1519 			return -EPROBE_DEFER;
1520 
1521 		dev_info(bdi->dev, "using extcon device %s\n", name);
1522 	}
1523 
1524 	pm_runtime_enable(dev);
1525 	pm_runtime_use_autosuspend(dev);
1526 	pm_runtime_set_autosuspend_delay(dev, 600);
1527 	ret = pm_runtime_get_sync(dev);
1528 	if (ret < 0) {
1529 		dev_err(dev, "pm_runtime_get failed: %i\n", ret);
1530 		goto out_pmrt;
1531 	}
1532 
1533 	ret = bq24190_hw_init(bdi);
1534 	if (ret < 0) {
1535 		dev_err(dev, "Hardware init failed\n");
1536 		goto out_pmrt;
1537 	}
1538 
1539 	charger_cfg.drv_data = bdi;
1540 	charger_cfg.supplied_to = bq24190_charger_supplied_to;
1541 	charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1542 	bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1543 						&charger_cfg);
1544 	if (IS_ERR(bdi->charger)) {
1545 		dev_err(dev, "Can't register charger\n");
1546 		ret = PTR_ERR(bdi->charger);
1547 		goto out_pmrt;
1548 	}
1549 
1550 	/* the battery class is deprecated and will be removed. */
1551 	/* in the interim, this property hides it.              */
1552 	if (!device_property_read_bool(dev, "omit-battery-class")) {
1553 		battery_cfg.drv_data = bdi;
1554 		bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1555 						     &battery_cfg);
1556 		if (IS_ERR(bdi->battery)) {
1557 			dev_err(dev, "Can't register battery\n");
1558 			ret = PTR_ERR(bdi->battery);
1559 			goto out_charger;
1560 		}
1561 	}
1562 
1563 	ret = bq24190_sysfs_create_group(bdi);
1564 	if (ret) {
1565 		dev_err(dev, "Can't create sysfs entries\n");
1566 		goto out_charger;
1567 	}
1568 
1569 	bdi->initialized = true;
1570 
1571 	ret = devm_request_threaded_irq(dev, client->irq, NULL,
1572 			bq24190_irq_handler_thread,
1573 			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1574 			"bq24190-charger", bdi);
1575 	if (ret < 0) {
1576 		dev_err(dev, "Can't set up irq handler\n");
1577 		goto out_sysfs;
1578 	}
1579 
1580 	if (bdi->extcon) {
1581 		INIT_DELAYED_WORK(&bdi->extcon_work, bq24190_extcon_work);
1582 		bdi->extcon_nb.notifier_call = bq24190_extcon_event;
1583 		ret = devm_extcon_register_notifier_all(dev, bdi->extcon,
1584 							&bdi->extcon_nb);
1585 		if (ret) {
1586 			dev_err(dev, "Can't register extcon\n");
1587 			goto out_sysfs;
1588 		}
1589 
1590 		/* Sync initial cable state */
1591 		queue_delayed_work(system_wq, &bdi->extcon_work, 0);
1592 	}
1593 
1594 	enable_irq_wake(client->irq);
1595 
1596 	pm_runtime_mark_last_busy(dev);
1597 	pm_runtime_put_autosuspend(dev);
1598 
1599 	return 0;
1600 
1601 out_sysfs:
1602 	bq24190_sysfs_remove_group(bdi);
1603 
1604 out_charger:
1605 	if (!IS_ERR_OR_NULL(bdi->battery))
1606 		power_supply_unregister(bdi->battery);
1607 	power_supply_unregister(bdi->charger);
1608 
1609 out_pmrt:
1610 	pm_runtime_put_sync(dev);
1611 	pm_runtime_dont_use_autosuspend(dev);
1612 	pm_runtime_disable(dev);
1613 	return ret;
1614 }
1615 
1616 static int bq24190_remove(struct i2c_client *client)
1617 {
1618 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1619 	int error;
1620 
1621 	error = pm_runtime_get_sync(bdi->dev);
1622 	if (error < 0) {
1623 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1624 		pm_runtime_put_noidle(bdi->dev);
1625 	}
1626 
1627 	bq24190_register_reset(bdi);
1628 	bq24190_sysfs_remove_group(bdi);
1629 	if (bdi->battery)
1630 		power_supply_unregister(bdi->battery);
1631 	power_supply_unregister(bdi->charger);
1632 	if (error >= 0)
1633 		pm_runtime_put_sync(bdi->dev);
1634 	pm_runtime_dont_use_autosuspend(bdi->dev);
1635 	pm_runtime_disable(bdi->dev);
1636 
1637 	return 0;
1638 }
1639 
1640 static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
1641 {
1642 	struct i2c_client *client = to_i2c_client(dev);
1643 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1644 
1645 	if (!bdi->initialized)
1646 		return 0;
1647 
1648 	dev_dbg(bdi->dev, "%s\n", __func__);
1649 
1650 	return 0;
1651 }
1652 
1653 static __maybe_unused int bq24190_runtime_resume(struct device *dev)
1654 {
1655 	struct i2c_client *client = to_i2c_client(dev);
1656 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1657 
1658 	if (!bdi->initialized)
1659 		return 0;
1660 
1661 	if (!bdi->irq_event) {
1662 		dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
1663 		bq24190_check_status(bdi);
1664 	}
1665 
1666 	return 0;
1667 }
1668 
1669 static __maybe_unused int bq24190_pm_suspend(struct device *dev)
1670 {
1671 	struct i2c_client *client = to_i2c_client(dev);
1672 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1673 	int error;
1674 
1675 	error = pm_runtime_get_sync(bdi->dev);
1676 	if (error < 0) {
1677 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1678 		pm_runtime_put_noidle(bdi->dev);
1679 	}
1680 
1681 	bq24190_register_reset(bdi);
1682 
1683 	if (error >= 0) {
1684 		pm_runtime_mark_last_busy(bdi->dev);
1685 		pm_runtime_put_autosuspend(bdi->dev);
1686 	}
1687 
1688 	return 0;
1689 }
1690 
1691 static __maybe_unused int bq24190_pm_resume(struct device *dev)
1692 {
1693 	struct i2c_client *client = to_i2c_client(dev);
1694 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1695 	int error;
1696 
1697 	bdi->f_reg = 0;
1698 	bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1699 
1700 	error = pm_runtime_get_sync(bdi->dev);
1701 	if (error < 0) {
1702 		dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1703 		pm_runtime_put_noidle(bdi->dev);
1704 	}
1705 
1706 	bq24190_register_reset(bdi);
1707 	bq24190_set_mode_host(bdi);
1708 	bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1709 
1710 	if (error >= 0) {
1711 		pm_runtime_mark_last_busy(bdi->dev);
1712 		pm_runtime_put_autosuspend(bdi->dev);
1713 	}
1714 
1715 	/* Things may have changed while suspended so alert upper layer */
1716 	power_supply_changed(bdi->charger);
1717 	if (bdi->battery)
1718 		power_supply_changed(bdi->battery);
1719 
1720 	return 0;
1721 }
1722 
1723 static const struct dev_pm_ops bq24190_pm_ops = {
1724 	SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
1725 			   NULL)
1726 	SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
1727 };
1728 
1729 static const struct i2c_device_id bq24190_i2c_ids[] = {
1730 	{ "bq24190" },
1731 	{ "bq24192i" },
1732 	{ },
1733 };
1734 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1735 
1736 #ifdef CONFIG_OF
1737 static const struct of_device_id bq24190_of_match[] = {
1738 	{ .compatible = "ti,bq24190", },
1739 	{ },
1740 };
1741 MODULE_DEVICE_TABLE(of, bq24190_of_match);
1742 #else
1743 static const struct of_device_id bq24190_of_match[] = {
1744 	{ },
1745 };
1746 #endif
1747 
1748 static struct i2c_driver bq24190_driver = {
1749 	.probe		= bq24190_probe,
1750 	.remove		= bq24190_remove,
1751 	.id_table	= bq24190_i2c_ids,
1752 	.driver = {
1753 		.name		= "bq24190-charger",
1754 		.pm		= &bq24190_pm_ops,
1755 		.of_match_table	= of_match_ptr(bq24190_of_match),
1756 	},
1757 };
1758 module_i2c_driver(bq24190_driver);
1759 
1760 MODULE_LICENSE("GPL");
1761 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1762 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");
1763