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