xref: /linux/drivers/power/supply/bq24190_charger.c (revision e5c86679d5e864947a52fb31e45a425dea3e7fa9)
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/of_irq.h>
15 #include <linux/of_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/power_supply.h>
18 #include <linux/gpio.h>
19 #include <linux/i2c.h>
20 
21 #include <linux/power/bq24190_charger.h>
22 
23 
24 #define	BQ24190_MANUFACTURER	"Texas Instruments"
25 
26 #define BQ24190_REG_ISC		0x00 /* Input Source Control */
27 #define BQ24190_REG_ISC_EN_HIZ_MASK		BIT(7)
28 #define BQ24190_REG_ISC_EN_HIZ_SHIFT		7
29 #define BQ24190_REG_ISC_VINDPM_MASK		(BIT(6) | BIT(5) | BIT(4) | \
30 						 BIT(3))
31 #define BQ24190_REG_ISC_VINDPM_SHIFT		3
32 #define BQ24190_REG_ISC_IINLIM_MASK		(BIT(2) | BIT(1) | BIT(0))
33 #define BQ24190_REG_ISC_IINLIM_SHIFT		0
34 
35 #define BQ24190_REG_POC		0x01 /* Power-On Configuration */
36 #define BQ24190_REG_POC_RESET_MASK		BIT(7)
37 #define BQ24190_REG_POC_RESET_SHIFT		7
38 #define BQ24190_REG_POC_WDT_RESET_MASK		BIT(6)
39 #define BQ24190_REG_POC_WDT_RESET_SHIFT		6
40 #define BQ24190_REG_POC_CHG_CONFIG_MASK		(BIT(5) | BIT(4))
41 #define BQ24190_REG_POC_CHG_CONFIG_SHIFT	4
42 #define BQ24190_REG_POC_SYS_MIN_MASK		(BIT(3) | BIT(2) | BIT(1))
43 #define BQ24190_REG_POC_SYS_MIN_SHIFT		1
44 #define BQ24190_REG_POC_BOOST_LIM_MASK		BIT(0)
45 #define BQ24190_REG_POC_BOOST_LIM_SHIFT		0
46 
47 #define BQ24190_REG_CCC		0x02 /* Charge Current Control */
48 #define BQ24190_REG_CCC_ICHG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
49 						 BIT(4) | BIT(3) | BIT(2))
50 #define BQ24190_REG_CCC_ICHG_SHIFT		2
51 #define BQ24190_REG_CCC_FORCE_20PCT_MASK	BIT(0)
52 #define BQ24190_REG_CCC_FORCE_20PCT_SHIFT	0
53 
54 #define BQ24190_REG_PCTCC	0x03 /* Pre-charge/Termination Current Cntl */
55 #define BQ24190_REG_PCTCC_IPRECHG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
56 						 BIT(4))
57 #define BQ24190_REG_PCTCC_IPRECHG_SHIFT		4
58 #define BQ24190_REG_PCTCC_ITERM_MASK		(BIT(3) | BIT(2) | BIT(1) | \
59 						 BIT(0))
60 #define BQ24190_REG_PCTCC_ITERM_SHIFT		0
61 
62 #define BQ24190_REG_CVC		0x04 /* Charge Voltage Control */
63 #define BQ24190_REG_CVC_VREG_MASK		(BIT(7) | BIT(6) | BIT(5) | \
64 						 BIT(4) | BIT(3) | BIT(2))
65 #define BQ24190_REG_CVC_VREG_SHIFT		2
66 #define BQ24190_REG_CVC_BATLOWV_MASK		BIT(1)
67 #define BQ24190_REG_CVC_BATLOWV_SHIFT		1
68 #define BQ24190_REG_CVC_VRECHG_MASK		BIT(0)
69 #define BQ24190_REG_CVC_VRECHG_SHIFT		0
70 
71 #define BQ24190_REG_CTTC	0x05 /* Charge Term/Timer Control */
72 #define BQ24190_REG_CTTC_EN_TERM_MASK		BIT(7)
73 #define BQ24190_REG_CTTC_EN_TERM_SHIFT		7
74 #define BQ24190_REG_CTTC_TERM_STAT_MASK		BIT(6)
75 #define BQ24190_REG_CTTC_TERM_STAT_SHIFT	6
76 #define BQ24190_REG_CTTC_WATCHDOG_MASK		(BIT(5) | BIT(4))
77 #define BQ24190_REG_CTTC_WATCHDOG_SHIFT		4
78 #define BQ24190_REG_CTTC_EN_TIMER_MASK		BIT(3)
79 #define BQ24190_REG_CTTC_EN_TIMER_SHIFT		3
80 #define BQ24190_REG_CTTC_CHG_TIMER_MASK		(BIT(2) | BIT(1))
81 #define BQ24190_REG_CTTC_CHG_TIMER_SHIFT	1
82 #define BQ24190_REG_CTTC_JEITA_ISET_MASK	BIT(0)
83 #define BQ24190_REG_CTTC_JEITA_ISET_SHIFT	0
84 
85 #define BQ24190_REG_ICTRC	0x06 /* IR Comp/Thermal Regulation Control */
86 #define BQ24190_REG_ICTRC_BAT_COMP_MASK		(BIT(7) | BIT(6) | BIT(5))
87 #define BQ24190_REG_ICTRC_BAT_COMP_SHIFT	5
88 #define BQ24190_REG_ICTRC_VCLAMP_MASK		(BIT(4) | BIT(3) | BIT(2))
89 #define BQ24190_REG_ICTRC_VCLAMP_SHIFT		2
90 #define BQ24190_REG_ICTRC_TREG_MASK		(BIT(1) | BIT(0))
91 #define BQ24190_REG_ICTRC_TREG_SHIFT		0
92 
93 #define BQ24190_REG_MOC		0x07 /* Misc. Operation Control */
94 #define BQ24190_REG_MOC_DPDM_EN_MASK		BIT(7)
95 #define BQ24190_REG_MOC_DPDM_EN_SHIFT		7
96 #define BQ24190_REG_MOC_TMR2X_EN_MASK		BIT(6)
97 #define BQ24190_REG_MOC_TMR2X_EN_SHIFT		6
98 #define BQ24190_REG_MOC_BATFET_DISABLE_MASK	BIT(5)
99 #define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT	5
100 #define BQ24190_REG_MOC_JEITA_VSET_MASK		BIT(4)
101 #define BQ24190_REG_MOC_JEITA_VSET_SHIFT	4
102 #define BQ24190_REG_MOC_INT_MASK_MASK		(BIT(1) | BIT(0))
103 #define BQ24190_REG_MOC_INT_MASK_SHIFT		0
104 
105 #define BQ24190_REG_SS		0x08 /* System Status */
106 #define BQ24190_REG_SS_VBUS_STAT_MASK		(BIT(7) | BIT(6))
107 #define BQ24190_REG_SS_VBUS_STAT_SHIFT		6
108 #define BQ24190_REG_SS_CHRG_STAT_MASK		(BIT(5) | BIT(4))
109 #define BQ24190_REG_SS_CHRG_STAT_SHIFT		4
110 #define BQ24190_REG_SS_DPM_STAT_MASK		BIT(3)
111 #define BQ24190_REG_SS_DPM_STAT_SHIFT		3
112 #define BQ24190_REG_SS_PG_STAT_MASK		BIT(2)
113 #define BQ24190_REG_SS_PG_STAT_SHIFT		2
114 #define BQ24190_REG_SS_THERM_STAT_MASK		BIT(1)
115 #define BQ24190_REG_SS_THERM_STAT_SHIFT		1
116 #define BQ24190_REG_SS_VSYS_STAT_MASK		BIT(0)
117 #define BQ24190_REG_SS_VSYS_STAT_SHIFT		0
118 
119 #define BQ24190_REG_F		0x09 /* Fault */
120 #define BQ24190_REG_F_WATCHDOG_FAULT_MASK	BIT(7)
121 #define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT	7
122 #define BQ24190_REG_F_BOOST_FAULT_MASK		BIT(6)
123 #define BQ24190_REG_F_BOOST_FAULT_SHIFT		6
124 #define BQ24190_REG_F_CHRG_FAULT_MASK		(BIT(5) | BIT(4))
125 #define BQ24190_REG_F_CHRG_FAULT_SHIFT		4
126 #define BQ24190_REG_F_BAT_FAULT_MASK		BIT(3)
127 #define BQ24190_REG_F_BAT_FAULT_SHIFT		3
128 #define BQ24190_REG_F_NTC_FAULT_MASK		(BIT(2) | BIT(1) | BIT(0))
129 #define BQ24190_REG_F_NTC_FAULT_SHIFT		0
130 
131 #define BQ24190_REG_VPRS	0x0A /* Vendor/Part/Revision Status */
132 #define BQ24190_REG_VPRS_PN_MASK		(BIT(5) | BIT(4) | BIT(3))
133 #define BQ24190_REG_VPRS_PN_SHIFT		3
134 #define BQ24190_REG_VPRS_PN_24190			0x4
135 #define BQ24190_REG_VPRS_PN_24192			0x5 /* Also 24193 */
136 #define BQ24190_REG_VPRS_PN_24192I			0x3
137 #define BQ24190_REG_VPRS_TS_PROFILE_MASK	BIT(2)
138 #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT	2
139 #define BQ24190_REG_VPRS_DEV_REG_MASK		(BIT(1) | BIT(0))
140 #define BQ24190_REG_VPRS_DEV_REG_SHIFT		0
141 
142 /*
143  * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
144  * so the first read after a fault returns the latched value and subsequent
145  * reads return the current value.  In order to return the fault status
146  * to the user, have the interrupt handler save the reg's value and retrieve
147  * it in the appropriate health/status routine.
148  */
149 struct bq24190_dev_info {
150 	struct i2c_client		*client;
151 	struct device			*dev;
152 	struct power_supply		*charger;
153 	struct power_supply		*battery;
154 	char				model_name[I2C_NAME_SIZE];
155 	kernel_ulong_t			model;
156 	unsigned int			gpio_int;
157 	unsigned int			irq;
158 	struct mutex			f_reg_lock;
159 	u8				f_reg;
160 	u8				ss_reg;
161 	u8				watchdog;
162 };
163 
164 /*
165  * The tables below provide a 2-way mapping for the value that goes in
166  * the register field and the real-world value that it represents.
167  * The index of the array is the value that goes in the register; the
168  * number at that index in the array is the real-world value that it
169  * represents.
170  */
171 /* REG02[7:2] (ICHG) in uAh */
172 static const int bq24190_ccc_ichg_values[] = {
173 	 512000,  576000,  640000,  704000,  768000,  832000,  896000,  960000,
174 	1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
175 	1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
176 	2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
177 	2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
178 	3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
179 	3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
180 	4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
181 };
182 
183 /* REG04[7:2] (VREG) in uV */
184 static const int bq24190_cvc_vreg_values[] = {
185 	3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
186 	3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
187 	3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
188 	3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
189 	4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
190 	4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
191 	4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
192 	4400000
193 };
194 
195 /* REG06[1:0] (TREG) in tenths of degrees Celsius */
196 static const int bq24190_ictrc_treg_values[] = {
197 	600, 800, 1000, 1200
198 };
199 
200 /*
201  * Return the index in 'tbl' of greatest value that is less than or equal to
202  * 'val'.  The index range returned is 0 to 'tbl_size' - 1.  Assumes that
203  * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
204  * is less than 2^8.
205  */
206 static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
207 {
208 	int i;
209 
210 	for (i = 1; i < tbl_size; i++)
211 		if (v < tbl[i])
212 			break;
213 
214 	return i - 1;
215 }
216 
217 /* Basic driver I/O routines */
218 
219 static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
220 {
221 	int ret;
222 
223 	ret = i2c_smbus_read_byte_data(bdi->client, reg);
224 	if (ret < 0)
225 		return ret;
226 
227 	*data = ret;
228 	return 0;
229 }
230 
231 static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
232 {
233 	return i2c_smbus_write_byte_data(bdi->client, reg, data);
234 }
235 
236 static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
237 		u8 mask, u8 shift, u8 *data)
238 {
239 	u8 v;
240 	int ret;
241 
242 	ret = bq24190_read(bdi, reg, &v);
243 	if (ret < 0)
244 		return ret;
245 
246 	v &= mask;
247 	v >>= shift;
248 	*data = v;
249 
250 	return 0;
251 }
252 
253 static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
254 		u8 mask, u8 shift, u8 data)
255 {
256 	u8 v;
257 	int ret;
258 
259 	ret = bq24190_read(bdi, reg, &v);
260 	if (ret < 0)
261 		return ret;
262 
263 	v &= ~mask;
264 	v |= ((data << shift) & mask);
265 
266 	return bq24190_write(bdi, reg, v);
267 }
268 
269 static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
270 		u8 reg, u8 mask, u8 shift,
271 		const int tbl[], int tbl_size,
272 		int *val)
273 {
274 	u8 v;
275 	int ret;
276 
277 	ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
278 	if (ret < 0)
279 		return ret;
280 
281 	v = (v >= tbl_size) ? (tbl_size - 1) : v;
282 	*val = tbl[v];
283 
284 	return 0;
285 }
286 
287 static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
288 		u8 reg, u8 mask, u8 shift,
289 		const int tbl[], int tbl_size,
290 		int val)
291 {
292 	u8 idx;
293 
294 	idx = bq24190_find_idx(tbl, tbl_size, val);
295 
296 	return bq24190_write_mask(bdi, reg, mask, shift, idx);
297 }
298 
299 #ifdef CONFIG_SYSFS
300 /*
301  * There are a numerous options that are configurable on the bq24190
302  * that go well beyond what the power_supply properties provide access to.
303  * Provide sysfs access to them so they can be examined and possibly modified
304  * on the fly.  They will be provided for the charger power_supply object only
305  * and will be prefixed by 'f_' to make them easier to recognize.
306  */
307 
308 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store)			\
309 {									\
310 	.attr	= __ATTR(f_##_name, m, bq24190_sysfs_show, store),	\
311 	.reg	= BQ24190_REG_##r,					\
312 	.mask	= BQ24190_REG_##r##_##f##_MASK,				\
313 	.shift	= BQ24190_REG_##r##_##f##_SHIFT,			\
314 }
315 
316 #define BQ24190_SYSFS_FIELD_RW(_name, r, f)				\
317 		BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO,	\
318 				bq24190_sysfs_store)
319 
320 #define BQ24190_SYSFS_FIELD_RO(_name, r, f)				\
321 		BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
322 
323 static ssize_t bq24190_sysfs_show(struct device *dev,
324 		struct device_attribute *attr, char *buf);
325 static ssize_t bq24190_sysfs_store(struct device *dev,
326 		struct device_attribute *attr, const char *buf, size_t count);
327 
328 struct bq24190_sysfs_field_info {
329 	struct device_attribute	attr;
330 	u8	reg;
331 	u8	mask;
332 	u8	shift;
333 };
334 
335 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
336 #undef SS
337 
338 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
339 			/*	sysfs name	reg	field in reg */
340 	BQ24190_SYSFS_FIELD_RW(en_hiz,		ISC,	EN_HIZ),
341 	BQ24190_SYSFS_FIELD_RW(vindpm,		ISC,	VINDPM),
342 	BQ24190_SYSFS_FIELD_RW(iinlim,		ISC,	IINLIM),
343 	BQ24190_SYSFS_FIELD_RW(chg_config,	POC,	CHG_CONFIG),
344 	BQ24190_SYSFS_FIELD_RW(sys_min,		POC,	SYS_MIN),
345 	BQ24190_SYSFS_FIELD_RW(boost_lim,	POC,	BOOST_LIM),
346 	BQ24190_SYSFS_FIELD_RW(ichg,		CCC,	ICHG),
347 	BQ24190_SYSFS_FIELD_RW(force_20_pct,	CCC,	FORCE_20PCT),
348 	BQ24190_SYSFS_FIELD_RW(iprechg,		PCTCC,	IPRECHG),
349 	BQ24190_SYSFS_FIELD_RW(iterm,		PCTCC,	ITERM),
350 	BQ24190_SYSFS_FIELD_RW(vreg,		CVC,	VREG),
351 	BQ24190_SYSFS_FIELD_RW(batlowv,		CVC,	BATLOWV),
352 	BQ24190_SYSFS_FIELD_RW(vrechg,		CVC,	VRECHG),
353 	BQ24190_SYSFS_FIELD_RW(en_term,		CTTC,	EN_TERM),
354 	BQ24190_SYSFS_FIELD_RW(term_stat,	CTTC,	TERM_STAT),
355 	BQ24190_SYSFS_FIELD_RO(watchdog,	CTTC,	WATCHDOG),
356 	BQ24190_SYSFS_FIELD_RW(en_timer,	CTTC,	EN_TIMER),
357 	BQ24190_SYSFS_FIELD_RW(chg_timer,	CTTC,	CHG_TIMER),
358 	BQ24190_SYSFS_FIELD_RW(jeta_iset,	CTTC,	JEITA_ISET),
359 	BQ24190_SYSFS_FIELD_RW(bat_comp,	ICTRC,	BAT_COMP),
360 	BQ24190_SYSFS_FIELD_RW(vclamp,		ICTRC,	VCLAMP),
361 	BQ24190_SYSFS_FIELD_RW(treg,		ICTRC,	TREG),
362 	BQ24190_SYSFS_FIELD_RW(dpdm_en,		MOC,	DPDM_EN),
363 	BQ24190_SYSFS_FIELD_RW(tmr2x_en,	MOC,	TMR2X_EN),
364 	BQ24190_SYSFS_FIELD_RW(batfet_disable,	MOC,	BATFET_DISABLE),
365 	BQ24190_SYSFS_FIELD_RW(jeita_vset,	MOC,	JEITA_VSET),
366 	BQ24190_SYSFS_FIELD_RO(int_mask,	MOC,	INT_MASK),
367 	BQ24190_SYSFS_FIELD_RO(vbus_stat,	SS,	VBUS_STAT),
368 	BQ24190_SYSFS_FIELD_RO(chrg_stat,	SS,	CHRG_STAT),
369 	BQ24190_SYSFS_FIELD_RO(dpm_stat,	SS,	DPM_STAT),
370 	BQ24190_SYSFS_FIELD_RO(pg_stat,		SS,	PG_STAT),
371 	BQ24190_SYSFS_FIELD_RO(therm_stat,	SS,	THERM_STAT),
372 	BQ24190_SYSFS_FIELD_RO(vsys_stat,	SS,	VSYS_STAT),
373 	BQ24190_SYSFS_FIELD_RO(watchdog_fault,	F,	WATCHDOG_FAULT),
374 	BQ24190_SYSFS_FIELD_RO(boost_fault,	F,	BOOST_FAULT),
375 	BQ24190_SYSFS_FIELD_RO(chrg_fault,	F,	CHRG_FAULT),
376 	BQ24190_SYSFS_FIELD_RO(bat_fault,	F,	BAT_FAULT),
377 	BQ24190_SYSFS_FIELD_RO(ntc_fault,	F,	NTC_FAULT),
378 	BQ24190_SYSFS_FIELD_RO(pn,		VPRS,	PN),
379 	BQ24190_SYSFS_FIELD_RO(ts_profile,	VPRS,	TS_PROFILE),
380 	BQ24190_SYSFS_FIELD_RO(dev_reg,		VPRS,	DEV_REG),
381 };
382 
383 static struct attribute *
384 	bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
385 
386 static const struct attribute_group bq24190_sysfs_attr_group = {
387 	.attrs = bq24190_sysfs_attrs,
388 };
389 
390 static void bq24190_sysfs_init_attrs(void)
391 {
392 	int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
393 
394 	for (i = 0; i < limit; i++)
395 		bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
396 
397 	bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
398 }
399 
400 static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
401 		const char *name)
402 {
403 	int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
404 
405 	for (i = 0; i < limit; i++)
406 		if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
407 			break;
408 
409 	if (i >= limit)
410 		return NULL;
411 
412 	return &bq24190_sysfs_field_tbl[i];
413 }
414 
415 static ssize_t bq24190_sysfs_show(struct device *dev,
416 		struct device_attribute *attr, char *buf)
417 {
418 	struct power_supply *psy = dev_get_drvdata(dev);
419 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
420 	struct bq24190_sysfs_field_info *info;
421 	int ret;
422 	u8 v;
423 
424 	info = bq24190_sysfs_field_lookup(attr->attr.name);
425 	if (!info)
426 		return -EINVAL;
427 
428 	ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
429 	if (ret)
430 		return ret;
431 
432 	return scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
433 }
434 
435 static ssize_t bq24190_sysfs_store(struct device *dev,
436 		struct device_attribute *attr, const char *buf, size_t count)
437 {
438 	struct power_supply *psy = dev_get_drvdata(dev);
439 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
440 	struct bq24190_sysfs_field_info *info;
441 	int ret;
442 	u8 v;
443 
444 	info = bq24190_sysfs_field_lookup(attr->attr.name);
445 	if (!info)
446 		return -EINVAL;
447 
448 	ret = kstrtou8(buf, 0, &v);
449 	if (ret < 0)
450 		return ret;
451 
452 	ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
453 	if (ret)
454 		return ret;
455 
456 	return count;
457 }
458 
459 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
460 {
461 	bq24190_sysfs_init_attrs();
462 
463 	return sysfs_create_group(&bdi->charger->dev.kobj,
464 			&bq24190_sysfs_attr_group);
465 }
466 
467 static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi)
468 {
469 	sysfs_remove_group(&bdi->charger->dev.kobj, &bq24190_sysfs_attr_group);
470 }
471 #else
472 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
473 {
474 	return 0;
475 }
476 
477 static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {}
478 #endif
479 
480 /*
481  * According to the "Host Mode and default Mode" section of the
482  * manual, a write to any register causes the bq24190 to switch
483  * from default mode to host mode.  It will switch back to default
484  * mode after a WDT timeout unless the WDT is turned off as well.
485  * So, by simply turning off the WDT, we accomplish both with the
486  * same write.
487  */
488 static int bq24190_set_mode_host(struct bq24190_dev_info *bdi)
489 {
490 	int ret;
491 	u8 v;
492 
493 	ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
494 	if (ret < 0)
495 		return ret;
496 
497 	bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
498 					BQ24190_REG_CTTC_WATCHDOG_SHIFT);
499 	v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
500 
501 	return bq24190_write(bdi, BQ24190_REG_CTTC, v);
502 }
503 
504 static int bq24190_register_reset(struct bq24190_dev_info *bdi)
505 {
506 	int ret, limit = 100;
507 	u8 v;
508 
509 	/* Reset the registers */
510 	ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
511 			BQ24190_REG_POC_RESET_MASK,
512 			BQ24190_REG_POC_RESET_SHIFT,
513 			0x1);
514 	if (ret < 0)
515 		return ret;
516 
517 	/* Reset bit will be cleared by hardware so poll until it is */
518 	do {
519 		ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
520 				BQ24190_REG_POC_RESET_MASK,
521 				BQ24190_REG_POC_RESET_SHIFT,
522 				&v);
523 		if (ret < 0)
524 			return ret;
525 
526 		if (!v)
527 			break;
528 
529 		udelay(10);
530 	} while (--limit);
531 
532 	if (!limit)
533 		return -EIO;
534 
535 	return 0;
536 }
537 
538 /* Charger power supply property routines */
539 
540 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
541 		union power_supply_propval *val)
542 {
543 	u8 v;
544 	int type, ret;
545 
546 	ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
547 			BQ24190_REG_POC_CHG_CONFIG_MASK,
548 			BQ24190_REG_POC_CHG_CONFIG_SHIFT,
549 			&v);
550 	if (ret < 0)
551 		return ret;
552 
553 	/* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
554 	if (!v) {
555 		type = POWER_SUPPLY_CHARGE_TYPE_NONE;
556 	} else {
557 		ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
558 				BQ24190_REG_CCC_FORCE_20PCT_MASK,
559 				BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
560 				&v);
561 		if (ret < 0)
562 			return ret;
563 
564 		type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
565 			     POWER_SUPPLY_CHARGE_TYPE_FAST;
566 	}
567 
568 	val->intval = type;
569 
570 	return 0;
571 }
572 
573 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
574 		const union power_supply_propval *val)
575 {
576 	u8 chg_config, force_20pct, en_term;
577 	int ret;
578 
579 	/*
580 	 * According to the "Termination when REG02[0] = 1" section of
581 	 * the bq24190 manual, the trickle charge could be less than the
582 	 * termination current so it recommends turning off the termination
583 	 * function.
584 	 *
585 	 * Note: AFAICT from the datasheet, the user will have to manually
586 	 * turn off the charging when in 20% mode.  If its not turned off,
587 	 * there could be battery damage.  So, use this mode at your own risk.
588 	 */
589 	switch (val->intval) {
590 	case POWER_SUPPLY_CHARGE_TYPE_NONE:
591 		chg_config = 0x0;
592 		break;
593 	case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
594 		chg_config = 0x1;
595 		force_20pct = 0x1;
596 		en_term = 0x0;
597 		break;
598 	case POWER_SUPPLY_CHARGE_TYPE_FAST:
599 		chg_config = 0x1;
600 		force_20pct = 0x0;
601 		en_term = 0x1;
602 		break;
603 	default:
604 		return -EINVAL;
605 	}
606 
607 	if (chg_config) { /* Enabling the charger */
608 		ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
609 				BQ24190_REG_CCC_FORCE_20PCT_MASK,
610 				BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
611 				force_20pct);
612 		if (ret < 0)
613 			return ret;
614 
615 		ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
616 				BQ24190_REG_CTTC_EN_TERM_MASK,
617 				BQ24190_REG_CTTC_EN_TERM_SHIFT,
618 				en_term);
619 		if (ret < 0)
620 			return ret;
621 	}
622 
623 	return bq24190_write_mask(bdi, BQ24190_REG_POC,
624 			BQ24190_REG_POC_CHG_CONFIG_MASK,
625 			BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
626 }
627 
628 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
629 		union power_supply_propval *val)
630 {
631 	u8 v;
632 	int health;
633 
634 	mutex_lock(&bdi->f_reg_lock);
635 	v = bdi->f_reg;
636 	mutex_unlock(&bdi->f_reg_lock);
637 
638 	if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
639 		/*
640 		 * This could be over-current or over-voltage but there's
641 		 * no way to tell which.  Return 'OVERVOLTAGE' since there
642 		 * isn't an 'OVERCURRENT' value defined that we can return
643 		 * even if it was over-current.
644 		 */
645 		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
646 	} else {
647 		v &= BQ24190_REG_F_CHRG_FAULT_MASK;
648 		v >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
649 
650 		switch (v) {
651 		case 0x0: /* Normal */
652 			health = POWER_SUPPLY_HEALTH_GOOD;
653 			break;
654 		case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
655 			/*
656 			 * This could be over-voltage or under-voltage
657 			 * and there's no way to tell which.  Instead
658 			 * of looking foolish and returning 'OVERVOLTAGE'
659 			 * when its really under-voltage, just return
660 			 * 'UNSPEC_FAILURE'.
661 			 */
662 			health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
663 			break;
664 		case 0x2: /* Thermal Shutdown */
665 			health = POWER_SUPPLY_HEALTH_OVERHEAT;
666 			break;
667 		case 0x3: /* Charge Safety Timer Expiration */
668 			health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
669 			break;
670 		default:
671 			health = POWER_SUPPLY_HEALTH_UNKNOWN;
672 		}
673 	}
674 
675 	val->intval = health;
676 
677 	return 0;
678 }
679 
680 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
681 		union power_supply_propval *val)
682 {
683 	u8 v;
684 	int ret;
685 
686 	ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
687 			BQ24190_REG_SS_PG_STAT_MASK,
688 			BQ24190_REG_SS_PG_STAT_SHIFT, &v);
689 	if (ret < 0)
690 		return ret;
691 
692 	val->intval = v;
693 	return 0;
694 }
695 
696 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
697 		union power_supply_propval *val)
698 {
699 	u8 v;
700 	int curr, ret;
701 
702 	ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
703 			BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
704 			bq24190_ccc_ichg_values,
705 			ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
706 	if (ret < 0)
707 		return ret;
708 
709 	ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
710 			BQ24190_REG_CCC_FORCE_20PCT_MASK,
711 			BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
712 	if (ret < 0)
713 		return ret;
714 
715 	/* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
716 	if (v)
717 		curr /= 5;
718 
719 	val->intval = curr;
720 	return 0;
721 }
722 
723 static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
724 		union power_supply_propval *val)
725 {
726 	int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
727 
728 	val->intval = bq24190_ccc_ichg_values[idx];
729 	return 0;
730 }
731 
732 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
733 		const union power_supply_propval *val)
734 {
735 	u8 v;
736 	int ret, curr = val->intval;
737 
738 	ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
739 			BQ24190_REG_CCC_FORCE_20PCT_MASK,
740 			BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
741 	if (ret < 0)
742 		return ret;
743 
744 	/* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
745 	if (v)
746 		curr *= 5;
747 
748 	return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
749 			BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
750 			bq24190_ccc_ichg_values,
751 			ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
752 }
753 
754 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
755 		union power_supply_propval *val)
756 {
757 	int voltage, ret;
758 
759 	ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
760 			BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
761 			bq24190_cvc_vreg_values,
762 			ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
763 	if (ret < 0)
764 		return ret;
765 
766 	val->intval = voltage;
767 	return 0;
768 }
769 
770 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
771 		union power_supply_propval *val)
772 {
773 	int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
774 
775 	val->intval = bq24190_cvc_vreg_values[idx];
776 	return 0;
777 }
778 
779 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
780 		const union power_supply_propval *val)
781 {
782 	return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
783 			BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
784 			bq24190_cvc_vreg_values,
785 			ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
786 }
787 
788 static int bq24190_charger_get_property(struct power_supply *psy,
789 		enum power_supply_property psp, union power_supply_propval *val)
790 {
791 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
792 	int ret;
793 
794 	dev_dbg(bdi->dev, "prop: %d\n", psp);
795 
796 	pm_runtime_get_sync(bdi->dev);
797 
798 	switch (psp) {
799 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
800 		ret = bq24190_charger_get_charge_type(bdi, val);
801 		break;
802 	case POWER_SUPPLY_PROP_HEALTH:
803 		ret = bq24190_charger_get_health(bdi, val);
804 		break;
805 	case POWER_SUPPLY_PROP_ONLINE:
806 		ret = bq24190_charger_get_online(bdi, val);
807 		break;
808 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
809 		ret = bq24190_charger_get_current(bdi, val);
810 		break;
811 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
812 		ret = bq24190_charger_get_current_max(bdi, val);
813 		break;
814 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
815 		ret = bq24190_charger_get_voltage(bdi, val);
816 		break;
817 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
818 		ret = bq24190_charger_get_voltage_max(bdi, val);
819 		break;
820 	case POWER_SUPPLY_PROP_SCOPE:
821 		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
822 		ret = 0;
823 		break;
824 	case POWER_SUPPLY_PROP_MODEL_NAME:
825 		val->strval = bdi->model_name;
826 		ret = 0;
827 		break;
828 	case POWER_SUPPLY_PROP_MANUFACTURER:
829 		val->strval = BQ24190_MANUFACTURER;
830 		ret = 0;
831 		break;
832 	default:
833 		ret = -ENODATA;
834 	}
835 
836 	pm_runtime_put_sync(bdi->dev);
837 	return ret;
838 }
839 
840 static int bq24190_charger_set_property(struct power_supply *psy,
841 		enum power_supply_property psp,
842 		const union power_supply_propval *val)
843 {
844 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
845 	int ret;
846 
847 	dev_dbg(bdi->dev, "prop: %d\n", psp);
848 
849 	pm_runtime_get_sync(bdi->dev);
850 
851 	switch (psp) {
852 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
853 		ret = bq24190_charger_set_charge_type(bdi, val);
854 		break;
855 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
856 		ret = bq24190_charger_set_current(bdi, val);
857 		break;
858 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
859 		ret = bq24190_charger_set_voltage(bdi, val);
860 		break;
861 	default:
862 		ret = -EINVAL;
863 	}
864 
865 	pm_runtime_put_sync(bdi->dev);
866 	return ret;
867 }
868 
869 static int bq24190_charger_property_is_writeable(struct power_supply *psy,
870 		enum power_supply_property psp)
871 {
872 	int ret;
873 
874 	switch (psp) {
875 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
876 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
877 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
878 		ret = 1;
879 		break;
880 	default:
881 		ret = 0;
882 	}
883 
884 	return ret;
885 }
886 
887 static enum power_supply_property bq24190_charger_properties[] = {
888 	POWER_SUPPLY_PROP_CHARGE_TYPE,
889 	POWER_SUPPLY_PROP_HEALTH,
890 	POWER_SUPPLY_PROP_ONLINE,
891 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
892 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
893 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
894 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
895 	POWER_SUPPLY_PROP_SCOPE,
896 	POWER_SUPPLY_PROP_MODEL_NAME,
897 	POWER_SUPPLY_PROP_MANUFACTURER,
898 };
899 
900 static char *bq24190_charger_supplied_to[] = {
901 	"main-battery",
902 };
903 
904 static const struct power_supply_desc bq24190_charger_desc = {
905 	.name			= "bq24190-charger",
906 	.type			= POWER_SUPPLY_TYPE_USB,
907 	.properties		= bq24190_charger_properties,
908 	.num_properties		= ARRAY_SIZE(bq24190_charger_properties),
909 	.get_property		= bq24190_charger_get_property,
910 	.set_property		= bq24190_charger_set_property,
911 	.property_is_writeable	= bq24190_charger_property_is_writeable,
912 };
913 
914 /* Battery power supply property routines */
915 
916 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
917 		union power_supply_propval *val)
918 {
919 	u8 ss_reg, chrg_fault;
920 	int status, ret;
921 
922 	mutex_lock(&bdi->f_reg_lock);
923 	chrg_fault = bdi->f_reg;
924 	mutex_unlock(&bdi->f_reg_lock);
925 
926 	chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
927 	chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
928 
929 	ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
930 	if (ret < 0)
931 		return ret;
932 
933 	/*
934 	 * The battery must be discharging when any of these are true:
935 	 * - there is no good power source;
936 	 * - there is a charge fault.
937 	 * Could also be discharging when in "supplement mode" but
938 	 * there is no way to tell when its in that mode.
939 	 */
940 	if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
941 		status = POWER_SUPPLY_STATUS_DISCHARGING;
942 	} else {
943 		ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
944 		ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
945 
946 		switch (ss_reg) {
947 		case 0x0: /* Not Charging */
948 			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
949 			break;
950 		case 0x1: /* Pre-charge */
951 		case 0x2: /* Fast Charging */
952 			status = POWER_SUPPLY_STATUS_CHARGING;
953 			break;
954 		case 0x3: /* Charge Termination Done */
955 			status = POWER_SUPPLY_STATUS_FULL;
956 			break;
957 		default:
958 			ret = -EIO;
959 		}
960 	}
961 
962 	if (!ret)
963 		val->intval = status;
964 
965 	return ret;
966 }
967 
968 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
969 		union power_supply_propval *val)
970 {
971 	u8 v;
972 	int health;
973 
974 	mutex_lock(&bdi->f_reg_lock);
975 	v = bdi->f_reg;
976 	mutex_unlock(&bdi->f_reg_lock);
977 
978 	if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
979 		health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
980 	} else {
981 		v &= BQ24190_REG_F_NTC_FAULT_MASK;
982 		v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
983 
984 		switch (v) {
985 		case 0x0: /* Normal */
986 			health = POWER_SUPPLY_HEALTH_GOOD;
987 			break;
988 		case 0x1: /* TS1 Cold */
989 		case 0x3: /* TS2 Cold */
990 		case 0x5: /* Both Cold */
991 			health = POWER_SUPPLY_HEALTH_COLD;
992 			break;
993 		case 0x2: /* TS1 Hot */
994 		case 0x4: /* TS2 Hot */
995 		case 0x6: /* Both Hot */
996 			health = POWER_SUPPLY_HEALTH_OVERHEAT;
997 			break;
998 		default:
999 			health = POWER_SUPPLY_HEALTH_UNKNOWN;
1000 		}
1001 	}
1002 
1003 	val->intval = health;
1004 	return 0;
1005 }
1006 
1007 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1008 		union power_supply_propval *val)
1009 {
1010 	u8 batfet_disable;
1011 	int ret;
1012 
1013 	ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1014 			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1015 			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1016 	if (ret < 0)
1017 		return ret;
1018 
1019 	val->intval = !batfet_disable;
1020 	return 0;
1021 }
1022 
1023 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1024 		const union power_supply_propval *val)
1025 {
1026 	return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1027 			BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1028 			BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1029 }
1030 
1031 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1032 		union power_supply_propval *val)
1033 {
1034 	int temp, ret;
1035 
1036 	ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1037 			BQ24190_REG_ICTRC_TREG_MASK,
1038 			BQ24190_REG_ICTRC_TREG_SHIFT,
1039 			bq24190_ictrc_treg_values,
1040 			ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1041 	if (ret < 0)
1042 		return ret;
1043 
1044 	val->intval = temp;
1045 	return 0;
1046 }
1047 
1048 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1049 		const union power_supply_propval *val)
1050 {
1051 	return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1052 			BQ24190_REG_ICTRC_TREG_MASK,
1053 			BQ24190_REG_ICTRC_TREG_SHIFT,
1054 			bq24190_ictrc_treg_values,
1055 			ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1056 }
1057 
1058 static int bq24190_battery_get_property(struct power_supply *psy,
1059 		enum power_supply_property psp, union power_supply_propval *val)
1060 {
1061 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1062 	int ret;
1063 
1064 	dev_dbg(bdi->dev, "prop: %d\n", psp);
1065 
1066 	pm_runtime_get_sync(bdi->dev);
1067 
1068 	switch (psp) {
1069 	case POWER_SUPPLY_PROP_STATUS:
1070 		ret = bq24190_battery_get_status(bdi, val);
1071 		break;
1072 	case POWER_SUPPLY_PROP_HEALTH:
1073 		ret = bq24190_battery_get_health(bdi, val);
1074 		break;
1075 	case POWER_SUPPLY_PROP_ONLINE:
1076 		ret = bq24190_battery_get_online(bdi, val);
1077 		break;
1078 	case POWER_SUPPLY_PROP_TECHNOLOGY:
1079 		/* Could be Li-on or Li-polymer but no way to tell which */
1080 		val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1081 		ret = 0;
1082 		break;
1083 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1084 		ret = bq24190_battery_get_temp_alert_max(bdi, val);
1085 		break;
1086 	case POWER_SUPPLY_PROP_SCOPE:
1087 		val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1088 		ret = 0;
1089 		break;
1090 	default:
1091 		ret = -ENODATA;
1092 	}
1093 
1094 	pm_runtime_put_sync(bdi->dev);
1095 	return ret;
1096 }
1097 
1098 static int bq24190_battery_set_property(struct power_supply *psy,
1099 		enum power_supply_property psp,
1100 		const union power_supply_propval *val)
1101 {
1102 	struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1103 	int ret;
1104 
1105 	dev_dbg(bdi->dev, "prop: %d\n", psp);
1106 
1107 	pm_runtime_get_sync(bdi->dev);
1108 
1109 	switch (psp) {
1110 	case POWER_SUPPLY_PROP_ONLINE:
1111 		ret = bq24190_battery_set_online(bdi, val);
1112 		break;
1113 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1114 		ret = bq24190_battery_set_temp_alert_max(bdi, val);
1115 		break;
1116 	default:
1117 		ret = -EINVAL;
1118 	}
1119 
1120 	pm_runtime_put_sync(bdi->dev);
1121 	return ret;
1122 }
1123 
1124 static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1125 		enum power_supply_property psp)
1126 {
1127 	int ret;
1128 
1129 	switch (psp) {
1130 	case POWER_SUPPLY_PROP_ONLINE:
1131 	case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1132 		ret = 1;
1133 		break;
1134 	default:
1135 		ret = 0;
1136 	}
1137 
1138 	return ret;
1139 }
1140 
1141 static enum power_supply_property bq24190_battery_properties[] = {
1142 	POWER_SUPPLY_PROP_STATUS,
1143 	POWER_SUPPLY_PROP_HEALTH,
1144 	POWER_SUPPLY_PROP_ONLINE,
1145 	POWER_SUPPLY_PROP_TECHNOLOGY,
1146 	POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1147 	POWER_SUPPLY_PROP_SCOPE,
1148 };
1149 
1150 static const struct power_supply_desc bq24190_battery_desc = {
1151 	.name			= "bq24190-battery",
1152 	.type			= POWER_SUPPLY_TYPE_BATTERY,
1153 	.properties		= bq24190_battery_properties,
1154 	.num_properties		= ARRAY_SIZE(bq24190_battery_properties),
1155 	.get_property		= bq24190_battery_get_property,
1156 	.set_property		= bq24190_battery_set_property,
1157 	.property_is_writeable	= bq24190_battery_property_is_writeable,
1158 };
1159 
1160 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1161 {
1162 	struct bq24190_dev_info *bdi = data;
1163 	const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1164 	const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1165 				| BQ24190_REG_F_NTC_FAULT_MASK;
1166 	bool alert_charger = false, alert_battery = false;
1167 	u8 ss_reg = 0, f_reg = 0;
1168 	int i, ret;
1169 
1170 	pm_runtime_get_sync(bdi->dev);
1171 
1172 	ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1173 	if (ret < 0) {
1174 		dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1175 		goto out;
1176 	}
1177 
1178 	i = 0;
1179 	do {
1180 		ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1181 		if (ret < 0) {
1182 			dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1183 			goto out;
1184 		}
1185 	} while (f_reg && ++i < 2);
1186 
1187 	if (f_reg != bdi->f_reg) {
1188 		dev_info(bdi->dev,
1189 			"Fault: boost %d, charge %d, battery %d, ntc %d\n",
1190 			!!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1191 			!!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1192 			!!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1193 			!!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1194 
1195 		mutex_lock(&bdi->f_reg_lock);
1196 		if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1197 			alert_battery = true;
1198 		if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1199 			alert_charger = true;
1200 		bdi->f_reg = f_reg;
1201 		mutex_unlock(&bdi->f_reg_lock);
1202 	}
1203 
1204 	if (ss_reg != bdi->ss_reg) {
1205 		/*
1206 		 * The device is in host mode so when PG_STAT goes from 1->0
1207 		 * (i.e., power removed) HIZ needs to be disabled.
1208 		 */
1209 		if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1210 				!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1211 			ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1212 					BQ24190_REG_ISC_EN_HIZ_MASK,
1213 					BQ24190_REG_ISC_EN_HIZ_SHIFT,
1214 					0);
1215 			if (ret < 0)
1216 				dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1217 					ret);
1218 		}
1219 
1220 		if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1221 			alert_battery = true;
1222 		if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1223 			alert_charger = true;
1224 		bdi->ss_reg = ss_reg;
1225 	}
1226 
1227 	if (alert_charger)
1228 		power_supply_changed(bdi->charger);
1229 	if (alert_battery)
1230 		power_supply_changed(bdi->battery);
1231 
1232 out:
1233 	pm_runtime_put_sync(bdi->dev);
1234 
1235 	dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1236 
1237 	return IRQ_HANDLED;
1238 }
1239 
1240 static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1241 {
1242 	u8 v;
1243 	int ret;
1244 
1245 	pm_runtime_get_sync(bdi->dev);
1246 
1247 	/* First check that the device really is what its supposed to be */
1248 	ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1249 			BQ24190_REG_VPRS_PN_MASK,
1250 			BQ24190_REG_VPRS_PN_SHIFT,
1251 			&v);
1252 	if (ret < 0)
1253 		goto out;
1254 
1255 	if (v != bdi->model) {
1256 		ret = -ENODEV;
1257 		goto out;
1258 	}
1259 
1260 	ret = bq24190_register_reset(bdi);
1261 	if (ret < 0)
1262 		goto out;
1263 
1264 	ret = bq24190_set_mode_host(bdi);
1265 	if (ret < 0)
1266 		goto out;
1267 
1268 	ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1269 out:
1270 	pm_runtime_put_sync(bdi->dev);
1271 	return ret;
1272 }
1273 
1274 #ifdef CONFIG_OF
1275 static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1276 {
1277 	bdi->irq = irq_of_parse_and_map(bdi->dev->of_node, 0);
1278 	if (bdi->irq <= 0)
1279 		return -1;
1280 
1281 	return 0;
1282 }
1283 #else
1284 static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1285 {
1286 	return -1;
1287 }
1288 #endif
1289 
1290 static int bq24190_setup_pdata(struct bq24190_dev_info *bdi,
1291 		struct bq24190_platform_data *pdata)
1292 {
1293 	int ret;
1294 
1295 	if (!gpio_is_valid(pdata->gpio_int))
1296 		return -1;
1297 
1298 	ret = gpio_request(pdata->gpio_int, dev_name(bdi->dev));
1299 	if (ret < 0)
1300 		return -1;
1301 
1302 	ret = gpio_direction_input(pdata->gpio_int);
1303 	if (ret < 0)
1304 		goto out;
1305 
1306 	bdi->irq = gpio_to_irq(pdata->gpio_int);
1307 	if (!bdi->irq)
1308 		goto out;
1309 
1310 	bdi->gpio_int = pdata->gpio_int;
1311 	return 0;
1312 
1313 out:
1314 	gpio_free(pdata->gpio_int);
1315 	return -1;
1316 }
1317 
1318 static int bq24190_probe(struct i2c_client *client,
1319 		const struct i2c_device_id *id)
1320 {
1321 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1322 	struct device *dev = &client->dev;
1323 	struct bq24190_platform_data *pdata = client->dev.platform_data;
1324 	struct power_supply_config charger_cfg = {}, battery_cfg = {};
1325 	struct bq24190_dev_info *bdi;
1326 	int ret;
1327 
1328 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1329 		dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1330 		return -ENODEV;
1331 	}
1332 
1333 	bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1334 	if (!bdi) {
1335 		dev_err(dev, "Can't alloc bdi struct\n");
1336 		return -ENOMEM;
1337 	}
1338 
1339 	bdi->client = client;
1340 	bdi->dev = dev;
1341 	bdi->model = id->driver_data;
1342 	strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1343 	mutex_init(&bdi->f_reg_lock);
1344 	bdi->f_reg = 0;
1345 	bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1346 
1347 	i2c_set_clientdata(client, bdi);
1348 
1349 	if (dev->of_node)
1350 		ret = bq24190_setup_dt(bdi);
1351 	else
1352 		ret = bq24190_setup_pdata(bdi, pdata);
1353 
1354 	if (ret) {
1355 		dev_err(dev, "Can't get irq info\n");
1356 		return -EINVAL;
1357 	}
1358 
1359 	pm_runtime_enable(dev);
1360 	pm_runtime_resume(dev);
1361 
1362 	ret = bq24190_hw_init(bdi);
1363 	if (ret < 0) {
1364 		dev_err(dev, "Hardware init failed\n");
1365 		goto out1;
1366 	}
1367 
1368 	charger_cfg.drv_data = bdi;
1369 	charger_cfg.supplied_to = bq24190_charger_supplied_to;
1370 	charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1371 	bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1372 						&charger_cfg);
1373 	if (IS_ERR(bdi->charger)) {
1374 		dev_err(dev, "Can't register charger\n");
1375 		ret = PTR_ERR(bdi->charger);
1376 		goto out1;
1377 	}
1378 
1379 	battery_cfg.drv_data = bdi;
1380 	bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1381 						&battery_cfg);
1382 	if (IS_ERR(bdi->battery)) {
1383 		dev_err(dev, "Can't register battery\n");
1384 		ret = PTR_ERR(bdi->battery);
1385 		goto out2;
1386 	}
1387 
1388 	ret = bq24190_sysfs_create_group(bdi);
1389 	if (ret) {
1390 		dev_err(dev, "Can't create sysfs entries\n");
1391 		goto out3;
1392 	}
1393 
1394 	ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
1395 			bq24190_irq_handler_thread,
1396 			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1397 			"bq24190-charger", bdi);
1398 	if (ret < 0) {
1399 		dev_err(dev, "Can't set up irq handler\n");
1400 		goto out4;
1401 	}
1402 
1403 	return 0;
1404 
1405 out4:
1406 	bq24190_sysfs_remove_group(bdi);
1407 
1408 out3:
1409 	power_supply_unregister(bdi->battery);
1410 
1411 out2:
1412 	power_supply_unregister(bdi->charger);
1413 
1414 out1:
1415 	pm_runtime_disable(dev);
1416 	if (bdi->gpio_int)
1417 		gpio_free(bdi->gpio_int);
1418 	return ret;
1419 }
1420 
1421 static int bq24190_remove(struct i2c_client *client)
1422 {
1423 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1424 
1425 	pm_runtime_get_sync(bdi->dev);
1426 	bq24190_register_reset(bdi);
1427 	pm_runtime_put_sync(bdi->dev);
1428 
1429 	bq24190_sysfs_remove_group(bdi);
1430 	power_supply_unregister(bdi->battery);
1431 	power_supply_unregister(bdi->charger);
1432 	pm_runtime_disable(bdi->dev);
1433 
1434 	if (bdi->gpio_int)
1435 		gpio_free(bdi->gpio_int);
1436 
1437 	return 0;
1438 }
1439 
1440 #ifdef CONFIG_PM_SLEEP
1441 static int bq24190_pm_suspend(struct device *dev)
1442 {
1443 	struct i2c_client *client = to_i2c_client(dev);
1444 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1445 
1446 	pm_runtime_get_sync(bdi->dev);
1447 	bq24190_register_reset(bdi);
1448 	pm_runtime_put_sync(bdi->dev);
1449 
1450 	return 0;
1451 }
1452 
1453 static int bq24190_pm_resume(struct device *dev)
1454 {
1455 	struct i2c_client *client = to_i2c_client(dev);
1456 	struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1457 
1458 	bdi->f_reg = 0;
1459 	bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1460 
1461 	pm_runtime_get_sync(bdi->dev);
1462 	bq24190_register_reset(bdi);
1463 	bq24190_set_mode_host(bdi);
1464 	bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1465 	pm_runtime_put_sync(bdi->dev);
1466 
1467 	/* Things may have changed while suspended so alert upper layer */
1468 	power_supply_changed(bdi->charger);
1469 	power_supply_changed(bdi->battery);
1470 
1471 	return 0;
1472 }
1473 #endif
1474 
1475 static SIMPLE_DEV_PM_OPS(bq24190_pm_ops, bq24190_pm_suspend, bq24190_pm_resume);
1476 
1477 /*
1478  * Only support the bq24190 right now.  The bq24192, bq24192i, and bq24193
1479  * are similar but not identical so the driver needs to be extended to
1480  * support them.
1481  */
1482 static const struct i2c_device_id bq24190_i2c_ids[] = {
1483 	{ "bq24190", BQ24190_REG_VPRS_PN_24190 },
1484 	{ },
1485 };
1486 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1487 
1488 #ifdef CONFIG_OF
1489 static const struct of_device_id bq24190_of_match[] = {
1490 	{ .compatible = "ti,bq24190", },
1491 	{ },
1492 };
1493 MODULE_DEVICE_TABLE(of, bq24190_of_match);
1494 #else
1495 static const struct of_device_id bq24190_of_match[] = {
1496 	{ },
1497 };
1498 #endif
1499 
1500 static struct i2c_driver bq24190_driver = {
1501 	.probe		= bq24190_probe,
1502 	.remove		= bq24190_remove,
1503 	.id_table	= bq24190_i2c_ids,
1504 	.driver = {
1505 		.name		= "bq24190-charger",
1506 		.pm		= &bq24190_pm_ops,
1507 		.of_match_table	= of_match_ptr(bq24190_of_match),
1508 	},
1509 };
1510 module_i2c_driver(bq24190_driver);
1511 
1512 MODULE_LICENSE("GPL");
1513 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1514 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");
1515