xref: /openbmc/linux/drivers/power/supply/bq25980_charger.c (revision 5069185fc18e810715a91d80fcd075e03add600c)
1*5069185fSDan Murphy // SPDX-License-Identifier: GPL-2.0
2*5069185fSDan Murphy // BQ25980 Battery Charger Driver
3*5069185fSDan Murphy // Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
4*5069185fSDan Murphy 
5*5069185fSDan Murphy #include <linux/err.h>
6*5069185fSDan Murphy #include <linux/i2c.h>
7*5069185fSDan Murphy #include <linux/init.h>
8*5069185fSDan Murphy #include <linux/interrupt.h>
9*5069185fSDan Murphy #include <linux/kernel.h>
10*5069185fSDan Murphy #include <linux/module.h>
11*5069185fSDan Murphy #include <linux/gpio/consumer.h>
12*5069185fSDan Murphy #include <linux/power_supply.h>
13*5069185fSDan Murphy #include <linux/regmap.h>
14*5069185fSDan Murphy #include <linux/types.h>
15*5069185fSDan Murphy #include <linux/delay.h>
16*5069185fSDan Murphy #include <linux/device.h>
17*5069185fSDan Murphy #include <linux/moduleparam.h>
18*5069185fSDan Murphy #include <linux/slab.h>
19*5069185fSDan Murphy 
20*5069185fSDan Murphy #include "bq25980_charger.h"
21*5069185fSDan Murphy 
22*5069185fSDan Murphy struct bq25980_state {
23*5069185fSDan Murphy 	bool dischg;
24*5069185fSDan Murphy 	bool ovp;
25*5069185fSDan Murphy 	bool ocp;
26*5069185fSDan Murphy 	bool wdt;
27*5069185fSDan Murphy 	bool tflt;
28*5069185fSDan Murphy 	bool online;
29*5069185fSDan Murphy 	bool ce;
30*5069185fSDan Murphy 	bool hiz;
31*5069185fSDan Murphy 	bool bypass;
32*5069185fSDan Murphy 
33*5069185fSDan Murphy 	u32 vbat_adc;
34*5069185fSDan Murphy 	u32 vsys_adc;
35*5069185fSDan Murphy 	u32 ibat_adc;
36*5069185fSDan Murphy };
37*5069185fSDan Murphy 
38*5069185fSDan Murphy enum bq25980_id {
39*5069185fSDan Murphy 	BQ25980,
40*5069185fSDan Murphy 	BQ25975,
41*5069185fSDan Murphy 	BQ25960,
42*5069185fSDan Murphy };
43*5069185fSDan Murphy 
44*5069185fSDan Murphy struct bq25980_chip_info {
45*5069185fSDan Murphy 
46*5069185fSDan Murphy 	int model_id;
47*5069185fSDan Murphy 
48*5069185fSDan Murphy 	const struct regmap_config *regmap_config;
49*5069185fSDan Murphy 
50*5069185fSDan Murphy 	int busocp_def;
51*5069185fSDan Murphy 	int busocp_sc_max;
52*5069185fSDan Murphy 	int busocp_byp_max;
53*5069185fSDan Murphy 	int busocp_sc_min;
54*5069185fSDan Murphy 	int busocp_byp_min;
55*5069185fSDan Murphy 
56*5069185fSDan Murphy 	int busovp_sc_def;
57*5069185fSDan Murphy 	int busovp_byp_def;
58*5069185fSDan Murphy 	int busovp_sc_step;
59*5069185fSDan Murphy 
60*5069185fSDan Murphy 	int busovp_sc_offset;
61*5069185fSDan Murphy 	int busovp_byp_step;
62*5069185fSDan Murphy 	int busovp_byp_offset;
63*5069185fSDan Murphy 	int busovp_sc_min;
64*5069185fSDan Murphy 	int busovp_sc_max;
65*5069185fSDan Murphy 	int busovp_byp_min;
66*5069185fSDan Murphy 	int busovp_byp_max;
67*5069185fSDan Murphy 
68*5069185fSDan Murphy 	int batovp_def;
69*5069185fSDan Murphy 	int batovp_max;
70*5069185fSDan Murphy 	int batovp_min;
71*5069185fSDan Murphy 	int batovp_step;
72*5069185fSDan Murphy 	int batovp_offset;
73*5069185fSDan Murphy 
74*5069185fSDan Murphy 	int batocp_def;
75*5069185fSDan Murphy 	int batocp_max;
76*5069185fSDan Murphy };
77*5069185fSDan Murphy 
78*5069185fSDan Murphy struct bq25980_init_data {
79*5069185fSDan Murphy 	u32 ichg;
80*5069185fSDan Murphy 	u32 bypass_ilim;
81*5069185fSDan Murphy 	u32 sc_ilim;
82*5069185fSDan Murphy 	u32 vreg;
83*5069185fSDan Murphy 	u32 iterm;
84*5069185fSDan Murphy 	u32 iprechg;
85*5069185fSDan Murphy 	u32 bypass_vlim;
86*5069185fSDan Murphy 	u32 sc_vlim;
87*5069185fSDan Murphy 	u32 ichg_max;
88*5069185fSDan Murphy 	u32 vreg_max;
89*5069185fSDan Murphy };
90*5069185fSDan Murphy 
91*5069185fSDan Murphy struct bq25980_device {
92*5069185fSDan Murphy 	struct i2c_client *client;
93*5069185fSDan Murphy 	struct device *dev;
94*5069185fSDan Murphy 	struct power_supply *charger;
95*5069185fSDan Murphy 	struct power_supply *battery;
96*5069185fSDan Murphy 	struct mutex lock;
97*5069185fSDan Murphy 	struct regmap *regmap;
98*5069185fSDan Murphy 
99*5069185fSDan Murphy 	char model_name[I2C_NAME_SIZE];
100*5069185fSDan Murphy 
101*5069185fSDan Murphy 	struct bq25980_init_data init_data;
102*5069185fSDan Murphy 	const struct bq25980_chip_info *chip_info;
103*5069185fSDan Murphy 	struct bq25980_state state;
104*5069185fSDan Murphy 	int watchdog_timer;
105*5069185fSDan Murphy };
106*5069185fSDan Murphy 
107*5069185fSDan Murphy static struct reg_default bq25980_reg_defs[] = {
108*5069185fSDan Murphy 	{BQ25980_BATOVP, 0x5A},
109*5069185fSDan Murphy 	{BQ25980_BATOVP_ALM, 0x46},
110*5069185fSDan Murphy 	{BQ25980_BATOCP, 0x51},
111*5069185fSDan Murphy 	{BQ25980_BATOCP_ALM, 0x50},
112*5069185fSDan Murphy 	{BQ25980_BATUCP_ALM, 0x28},
113*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_1, 0x0},
114*5069185fSDan Murphy 	{BQ25980_BUSOVP, 0x26},
115*5069185fSDan Murphy 	{BQ25980_BUSOVP_ALM, 0x22},
116*5069185fSDan Murphy 	{BQ25980_BUSOCP, 0xD},
117*5069185fSDan Murphy 	{BQ25980_BUSOCP_ALM, 0xC},
118*5069185fSDan Murphy 	{BQ25980_TEMP_CONTROL, 0x30},
119*5069185fSDan Murphy 	{BQ25980_TDIE_ALM, 0xC8},
120*5069185fSDan Murphy 	{BQ25980_TSBUS_FLT, 0x15},
121*5069185fSDan Murphy 	{BQ25980_TSBAT_FLG, 0x15},
122*5069185fSDan Murphy 	{BQ25980_VAC_CONTROL, 0x0},
123*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_2, 0x0},
124*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_3, 0x20},
125*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_4, 0x1D},
126*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_5, 0x18},
127*5069185fSDan Murphy 	{BQ25980_STAT1, 0x0},
128*5069185fSDan Murphy 	{BQ25980_STAT2, 0x0},
129*5069185fSDan Murphy 	{BQ25980_STAT3, 0x0},
130*5069185fSDan Murphy 	{BQ25980_STAT4, 0x0},
131*5069185fSDan Murphy 	{BQ25980_STAT5, 0x0},
132*5069185fSDan Murphy 	{BQ25980_FLAG1, 0x0},
133*5069185fSDan Murphy 	{BQ25980_FLAG2, 0x0},
134*5069185fSDan Murphy 	{BQ25980_FLAG3, 0x0},
135*5069185fSDan Murphy 	{BQ25980_FLAG4, 0x0},
136*5069185fSDan Murphy 	{BQ25980_FLAG5, 0x0},
137*5069185fSDan Murphy 	{BQ25980_MASK1, 0x0},
138*5069185fSDan Murphy 	{BQ25980_MASK2, 0x0},
139*5069185fSDan Murphy 	{BQ25980_MASK3, 0x0},
140*5069185fSDan Murphy 	{BQ25980_MASK4, 0x0},
141*5069185fSDan Murphy 	{BQ25980_MASK5, 0x0},
142*5069185fSDan Murphy 	{BQ25980_DEVICE_INFO, 0x8},
143*5069185fSDan Murphy 	{BQ25980_ADC_CONTROL1, 0x0},
144*5069185fSDan Murphy 	{BQ25980_ADC_CONTROL2, 0x0},
145*5069185fSDan Murphy 	{BQ25980_IBUS_ADC_LSB, 0x0},
146*5069185fSDan Murphy 	{BQ25980_IBUS_ADC_MSB, 0x0},
147*5069185fSDan Murphy 	{BQ25980_VBUS_ADC_LSB, 0x0},
148*5069185fSDan Murphy 	{BQ25980_VBUS_ADC_MSB, 0x0},
149*5069185fSDan Murphy 	{BQ25980_VAC1_ADC_LSB, 0x0},
150*5069185fSDan Murphy 	{BQ25980_VAC2_ADC_LSB, 0x0},
151*5069185fSDan Murphy 	{BQ25980_VOUT_ADC_LSB, 0x0},
152*5069185fSDan Murphy 	{BQ25980_VBAT_ADC_LSB, 0x0},
153*5069185fSDan Murphy 	{BQ25980_IBAT_ADC_MSB, 0x0},
154*5069185fSDan Murphy 	{BQ25980_IBAT_ADC_LSB, 0x0},
155*5069185fSDan Murphy 	{BQ25980_TSBUS_ADC_LSB, 0x0},
156*5069185fSDan Murphy 	{BQ25980_TSBAT_ADC_LSB, 0x0},
157*5069185fSDan Murphy 	{BQ25980_TDIE_ADC_LSB, 0x0},
158*5069185fSDan Murphy 	{BQ25980_DEGLITCH_TIME, 0x0},
159*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_6, 0x0},
160*5069185fSDan Murphy };
161*5069185fSDan Murphy 
162*5069185fSDan Murphy static struct reg_default bq25975_reg_defs[] = {
163*5069185fSDan Murphy 	{BQ25980_BATOVP, 0x5A},
164*5069185fSDan Murphy 	{BQ25980_BATOVP_ALM, 0x46},
165*5069185fSDan Murphy 	{BQ25980_BATOCP, 0x51},
166*5069185fSDan Murphy 	{BQ25980_BATOCP_ALM, 0x50},
167*5069185fSDan Murphy 	{BQ25980_BATUCP_ALM, 0x28},
168*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_1, 0x0},
169*5069185fSDan Murphy 	{BQ25980_BUSOVP, 0x26},
170*5069185fSDan Murphy 	{BQ25980_BUSOVP_ALM, 0x22},
171*5069185fSDan Murphy 	{BQ25980_BUSOCP, 0xD},
172*5069185fSDan Murphy 	{BQ25980_BUSOCP_ALM, 0xC},
173*5069185fSDan Murphy 	{BQ25980_TEMP_CONTROL, 0x30},
174*5069185fSDan Murphy 	{BQ25980_TDIE_ALM, 0xC8},
175*5069185fSDan Murphy 	{BQ25980_TSBUS_FLT, 0x15},
176*5069185fSDan Murphy 	{BQ25980_TSBAT_FLG, 0x15},
177*5069185fSDan Murphy 	{BQ25980_VAC_CONTROL, 0x0},
178*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_2, 0x0},
179*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_3, 0x20},
180*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_4, 0x1D},
181*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_5, 0x18},
182*5069185fSDan Murphy 	{BQ25980_STAT1, 0x0},
183*5069185fSDan Murphy 	{BQ25980_STAT2, 0x0},
184*5069185fSDan Murphy 	{BQ25980_STAT3, 0x0},
185*5069185fSDan Murphy 	{BQ25980_STAT4, 0x0},
186*5069185fSDan Murphy 	{BQ25980_STAT5, 0x0},
187*5069185fSDan Murphy 	{BQ25980_FLAG1, 0x0},
188*5069185fSDan Murphy 	{BQ25980_FLAG2, 0x0},
189*5069185fSDan Murphy 	{BQ25980_FLAG3, 0x0},
190*5069185fSDan Murphy 	{BQ25980_FLAG4, 0x0},
191*5069185fSDan Murphy 	{BQ25980_FLAG5, 0x0},
192*5069185fSDan Murphy 	{BQ25980_MASK1, 0x0},
193*5069185fSDan Murphy 	{BQ25980_MASK2, 0x0},
194*5069185fSDan Murphy 	{BQ25980_MASK3, 0x0},
195*5069185fSDan Murphy 	{BQ25980_MASK4, 0x0},
196*5069185fSDan Murphy 	{BQ25980_MASK5, 0x0},
197*5069185fSDan Murphy 	{BQ25980_DEVICE_INFO, 0x8},
198*5069185fSDan Murphy 	{BQ25980_ADC_CONTROL1, 0x0},
199*5069185fSDan Murphy 	{BQ25980_ADC_CONTROL2, 0x0},
200*5069185fSDan Murphy 	{BQ25980_IBUS_ADC_LSB, 0x0},
201*5069185fSDan Murphy 	{BQ25980_IBUS_ADC_MSB, 0x0},
202*5069185fSDan Murphy 	{BQ25980_VBUS_ADC_LSB, 0x0},
203*5069185fSDan Murphy 	{BQ25980_VBUS_ADC_MSB, 0x0},
204*5069185fSDan Murphy 	{BQ25980_VAC1_ADC_LSB, 0x0},
205*5069185fSDan Murphy 	{BQ25980_VAC2_ADC_LSB, 0x0},
206*5069185fSDan Murphy 	{BQ25980_VOUT_ADC_LSB, 0x0},
207*5069185fSDan Murphy 	{BQ25980_VBAT_ADC_LSB, 0x0},
208*5069185fSDan Murphy 	{BQ25980_IBAT_ADC_MSB, 0x0},
209*5069185fSDan Murphy 	{BQ25980_IBAT_ADC_LSB, 0x0},
210*5069185fSDan Murphy 	{BQ25980_TSBUS_ADC_LSB, 0x0},
211*5069185fSDan Murphy 	{BQ25980_TSBAT_ADC_LSB, 0x0},
212*5069185fSDan Murphy 	{BQ25980_TDIE_ADC_LSB, 0x0},
213*5069185fSDan Murphy 	{BQ25980_DEGLITCH_TIME, 0x0},
214*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_6, 0x0},
215*5069185fSDan Murphy };
216*5069185fSDan Murphy 
217*5069185fSDan Murphy static struct reg_default bq25960_reg_defs[] = {
218*5069185fSDan Murphy 	{BQ25980_BATOVP, 0x5A},
219*5069185fSDan Murphy 	{BQ25980_BATOVP_ALM, 0x46},
220*5069185fSDan Murphy 	{BQ25980_BATOCP, 0x51},
221*5069185fSDan Murphy 	{BQ25980_BATOCP_ALM, 0x50},
222*5069185fSDan Murphy 	{BQ25980_BATUCP_ALM, 0x28},
223*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_1, 0x0},
224*5069185fSDan Murphy 	{BQ25980_BUSOVP, 0x26},
225*5069185fSDan Murphy 	{BQ25980_BUSOVP_ALM, 0x22},
226*5069185fSDan Murphy 	{BQ25980_BUSOCP, 0xD},
227*5069185fSDan Murphy 	{BQ25980_BUSOCP_ALM, 0xC},
228*5069185fSDan Murphy 	{BQ25980_TEMP_CONTROL, 0x30},
229*5069185fSDan Murphy 	{BQ25980_TDIE_ALM, 0xC8},
230*5069185fSDan Murphy 	{BQ25980_TSBUS_FLT, 0x15},
231*5069185fSDan Murphy 	{BQ25980_TSBAT_FLG, 0x15},
232*5069185fSDan Murphy 	{BQ25980_VAC_CONTROL, 0x0},
233*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_2, 0x0},
234*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_3, 0x20},
235*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_4, 0x1D},
236*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_5, 0x18},
237*5069185fSDan Murphy 	{BQ25980_STAT1, 0x0},
238*5069185fSDan Murphy 	{BQ25980_STAT2, 0x0},
239*5069185fSDan Murphy 	{BQ25980_STAT3, 0x0},
240*5069185fSDan Murphy 	{BQ25980_STAT4, 0x0},
241*5069185fSDan Murphy 	{BQ25980_STAT5, 0x0},
242*5069185fSDan Murphy 	{BQ25980_FLAG1, 0x0},
243*5069185fSDan Murphy 	{BQ25980_FLAG2, 0x0},
244*5069185fSDan Murphy 	{BQ25980_FLAG3, 0x0},
245*5069185fSDan Murphy 	{BQ25980_FLAG4, 0x0},
246*5069185fSDan Murphy 	{BQ25980_FLAG5, 0x0},
247*5069185fSDan Murphy 	{BQ25980_MASK1, 0x0},
248*5069185fSDan Murphy 	{BQ25980_MASK2, 0x0},
249*5069185fSDan Murphy 	{BQ25980_MASK3, 0x0},
250*5069185fSDan Murphy 	{BQ25980_MASK4, 0x0},
251*5069185fSDan Murphy 	{BQ25980_MASK5, 0x0},
252*5069185fSDan Murphy 	{BQ25980_DEVICE_INFO, 0x8},
253*5069185fSDan Murphy 	{BQ25980_ADC_CONTROL1, 0x0},
254*5069185fSDan Murphy 	{BQ25980_ADC_CONTROL2, 0x0},
255*5069185fSDan Murphy 	{BQ25980_IBUS_ADC_LSB, 0x0},
256*5069185fSDan Murphy 	{BQ25980_IBUS_ADC_MSB, 0x0},
257*5069185fSDan Murphy 	{BQ25980_VBUS_ADC_LSB, 0x0},
258*5069185fSDan Murphy 	{BQ25980_VBUS_ADC_MSB, 0x0},
259*5069185fSDan Murphy 	{BQ25980_VAC1_ADC_LSB, 0x0},
260*5069185fSDan Murphy 	{BQ25980_VAC2_ADC_LSB, 0x0},
261*5069185fSDan Murphy 	{BQ25980_VOUT_ADC_LSB, 0x0},
262*5069185fSDan Murphy 	{BQ25980_VBAT_ADC_LSB, 0x0},
263*5069185fSDan Murphy 	{BQ25980_IBAT_ADC_MSB, 0x0},
264*5069185fSDan Murphy 	{BQ25980_IBAT_ADC_LSB, 0x0},
265*5069185fSDan Murphy 	{BQ25980_TSBUS_ADC_LSB, 0x0},
266*5069185fSDan Murphy 	{BQ25980_TSBAT_ADC_LSB, 0x0},
267*5069185fSDan Murphy 	{BQ25980_TDIE_ADC_LSB, 0x0},
268*5069185fSDan Murphy 	{BQ25980_DEGLITCH_TIME, 0x0},
269*5069185fSDan Murphy 	{BQ25980_CHRGR_CTRL_6, 0x0},
270*5069185fSDan Murphy };
271*5069185fSDan Murphy 
272*5069185fSDan Murphy static int bq25980_watchdog_time[BQ25980_NUM_WD_VAL] = {5000, 10000, 50000,
273*5069185fSDan Murphy 							300000};
274*5069185fSDan Murphy 
275*5069185fSDan Murphy static int bq25980_get_input_curr_lim(struct bq25980_device *bq)
276*5069185fSDan Murphy {
277*5069185fSDan Murphy 	unsigned int busocp_reg_code;
278*5069185fSDan Murphy 	int ret;
279*5069185fSDan Murphy 
280*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_BUSOCP, &busocp_reg_code);
281*5069185fSDan Murphy 	if (ret)
282*5069185fSDan Murphy 		return ret;
283*5069185fSDan Murphy 
284*5069185fSDan Murphy 	return (busocp_reg_code * BQ25980_BUSOCP_STEP_uA) + BQ25980_BUSOCP_OFFSET_uA;
285*5069185fSDan Murphy }
286*5069185fSDan Murphy 
287*5069185fSDan Murphy static int bq25980_set_hiz(struct bq25980_device *bq, int setting)
288*5069185fSDan Murphy {
289*5069185fSDan Murphy 	return regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2,
290*5069185fSDan Murphy 			BQ25980_EN_HIZ, setting);
291*5069185fSDan Murphy }
292*5069185fSDan Murphy 
293*5069185fSDan Murphy static int bq25980_set_input_curr_lim(struct bq25980_device *bq, int busocp)
294*5069185fSDan Murphy {
295*5069185fSDan Murphy 	unsigned int busocp_reg_code;
296*5069185fSDan Murphy 	int ret;
297*5069185fSDan Murphy 
298*5069185fSDan Murphy 	if (!busocp)
299*5069185fSDan Murphy 		return bq25980_set_hiz(bq, BQ25980_ENABLE_HIZ);
300*5069185fSDan Murphy 
301*5069185fSDan Murphy 	bq25980_set_hiz(bq, BQ25980_DISABLE_HIZ);
302*5069185fSDan Murphy 
303*5069185fSDan Murphy 	if (busocp < BQ25980_BUSOCP_MIN_uA)
304*5069185fSDan Murphy 		busocp = BQ25980_BUSOCP_MIN_uA;
305*5069185fSDan Murphy 
306*5069185fSDan Murphy 	if (bq->state.bypass)
307*5069185fSDan Murphy 		busocp = min(busocp, bq->chip_info->busocp_sc_max);
308*5069185fSDan Murphy 	else
309*5069185fSDan Murphy 		busocp = min(busocp, bq->chip_info->busocp_byp_max);
310*5069185fSDan Murphy 
311*5069185fSDan Murphy 	busocp_reg_code = (busocp - BQ25980_BUSOCP_OFFSET_uA)
312*5069185fSDan Murphy 						/ BQ25980_BUSOCP_STEP_uA;
313*5069185fSDan Murphy 
314*5069185fSDan Murphy 	ret = regmap_write(bq->regmap, BQ25980_BUSOCP, busocp_reg_code);
315*5069185fSDan Murphy 	if (ret)
316*5069185fSDan Murphy 		return ret;
317*5069185fSDan Murphy 
318*5069185fSDan Murphy 	return regmap_write(bq->regmap, BQ25980_BUSOCP_ALM, busocp_reg_code);
319*5069185fSDan Murphy }
320*5069185fSDan Murphy 
321*5069185fSDan Murphy static int bq25980_get_input_volt_lim(struct bq25980_device *bq)
322*5069185fSDan Murphy {
323*5069185fSDan Murphy 	unsigned int busovp_reg_code;
324*5069185fSDan Murphy 	unsigned int busovp_offset;
325*5069185fSDan Murphy 	unsigned int busovp_step;
326*5069185fSDan Murphy 	int ret;
327*5069185fSDan Murphy 
328*5069185fSDan Murphy 	if (bq->state.bypass) {
329*5069185fSDan Murphy 		busovp_step = bq->chip_info->busovp_byp_step;
330*5069185fSDan Murphy 		busovp_offset = bq->chip_info->busovp_byp_offset;
331*5069185fSDan Murphy 	} else {
332*5069185fSDan Murphy 		busovp_step = bq->chip_info->busovp_sc_step;
333*5069185fSDan Murphy 		busovp_offset = bq->chip_info->busovp_sc_offset;
334*5069185fSDan Murphy 	}
335*5069185fSDan Murphy 
336*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_BUSOVP, &busovp_reg_code);
337*5069185fSDan Murphy 	if (ret)
338*5069185fSDan Murphy 		return ret;
339*5069185fSDan Murphy 
340*5069185fSDan Murphy 	return (busovp_reg_code * busovp_step) + busovp_offset;
341*5069185fSDan Murphy }
342*5069185fSDan Murphy 
343*5069185fSDan Murphy static int bq25980_set_input_volt_lim(struct bq25980_device *bq, int busovp)
344*5069185fSDan Murphy {
345*5069185fSDan Murphy 	unsigned int busovp_reg_code;
346*5069185fSDan Murphy 	unsigned int busovp_step;
347*5069185fSDan Murphy 	unsigned int busovp_offset;
348*5069185fSDan Murphy 	int ret;
349*5069185fSDan Murphy 
350*5069185fSDan Murphy 	if (bq->state.bypass) {
351*5069185fSDan Murphy 		busovp_step = bq->chip_info->busovp_byp_step;
352*5069185fSDan Murphy 		busovp_offset = bq->chip_info->busovp_byp_offset;
353*5069185fSDan Murphy 		if (busovp > bq->chip_info->busovp_byp_max)
354*5069185fSDan Murphy 			busovp = bq->chip_info->busovp_byp_max;
355*5069185fSDan Murphy 		else if (busovp < bq->chip_info->busovp_byp_min)
356*5069185fSDan Murphy 			busovp = bq->chip_info->busovp_byp_min;
357*5069185fSDan Murphy 	} else {
358*5069185fSDan Murphy 		busovp_step = bq->chip_info->busovp_sc_step;
359*5069185fSDan Murphy 		busovp_offset = bq->chip_info->busovp_sc_offset;
360*5069185fSDan Murphy 		if (busovp > bq->chip_info->busovp_sc_max)
361*5069185fSDan Murphy 			busovp = bq->chip_info->busovp_sc_max;
362*5069185fSDan Murphy 		else if (busovp < bq->chip_info->busovp_sc_min)
363*5069185fSDan Murphy 			busovp = bq->chip_info->busovp_sc_min;
364*5069185fSDan Murphy 	}
365*5069185fSDan Murphy 
366*5069185fSDan Murphy 	busovp_reg_code = (busovp - busovp_offset) / busovp_step;
367*5069185fSDan Murphy 
368*5069185fSDan Murphy 	ret = regmap_write(bq->regmap, BQ25980_BUSOVP, busovp_reg_code);
369*5069185fSDan Murphy 	if (ret)
370*5069185fSDan Murphy 		return ret;
371*5069185fSDan Murphy 
372*5069185fSDan Murphy 	return regmap_write(bq->regmap, BQ25980_BUSOVP_ALM, busovp_reg_code);
373*5069185fSDan Murphy }
374*5069185fSDan Murphy 
375*5069185fSDan Murphy static int bq25980_get_const_charge_curr(struct bq25980_device *bq)
376*5069185fSDan Murphy {
377*5069185fSDan Murphy 	unsigned int batocp_reg_code;
378*5069185fSDan Murphy 	int ret;
379*5069185fSDan Murphy 
380*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_BATOCP, &batocp_reg_code);
381*5069185fSDan Murphy 	if (ret)
382*5069185fSDan Murphy 		return ret;
383*5069185fSDan Murphy 
384*5069185fSDan Murphy 	return (batocp_reg_code & BQ25980_BATOCP_MASK) *
385*5069185fSDan Murphy 						BQ25980_BATOCP_STEP_uA;
386*5069185fSDan Murphy }
387*5069185fSDan Murphy 
388*5069185fSDan Murphy static int bq25980_set_const_charge_curr(struct bq25980_device *bq, int batocp)
389*5069185fSDan Murphy {
390*5069185fSDan Murphy 	unsigned int batocp_reg_code;
391*5069185fSDan Murphy 	int ret;
392*5069185fSDan Murphy 
393*5069185fSDan Murphy 	batocp = max(batocp, BQ25980_BATOCP_MIN_uA);
394*5069185fSDan Murphy 	batocp = min(batocp, bq->chip_info->batocp_max);
395*5069185fSDan Murphy 
396*5069185fSDan Murphy 	batocp_reg_code = batocp / BQ25980_BATOCP_STEP_uA;
397*5069185fSDan Murphy 
398*5069185fSDan Murphy 	ret = regmap_update_bits(bq->regmap, BQ25980_BATOCP,
399*5069185fSDan Murphy 				BQ25980_BATOCP_MASK, batocp_reg_code);
400*5069185fSDan Murphy 	if (ret)
401*5069185fSDan Murphy 		return ret;
402*5069185fSDan Murphy 
403*5069185fSDan Murphy 	return regmap_update_bits(bq->regmap, BQ25980_BATOCP_ALM,
404*5069185fSDan Murphy 				BQ25980_BATOCP_MASK, batocp_reg_code);
405*5069185fSDan Murphy }
406*5069185fSDan Murphy 
407*5069185fSDan Murphy static int bq25980_get_const_charge_volt(struct bq25980_device *bq)
408*5069185fSDan Murphy {
409*5069185fSDan Murphy 	unsigned int batovp_reg_code;
410*5069185fSDan Murphy 	int ret;
411*5069185fSDan Murphy 
412*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_BATOVP, &batovp_reg_code);
413*5069185fSDan Murphy 	if (ret)
414*5069185fSDan Murphy 		return ret;
415*5069185fSDan Murphy 
416*5069185fSDan Murphy 	return ((batovp_reg_code * bq->chip_info->batovp_step) +
417*5069185fSDan Murphy 			bq->chip_info->batovp_offset);
418*5069185fSDan Murphy }
419*5069185fSDan Murphy 
420*5069185fSDan Murphy static int bq25980_set_const_charge_volt(struct bq25980_device *bq, int batovp)
421*5069185fSDan Murphy {
422*5069185fSDan Murphy 	unsigned int batovp_reg_code;
423*5069185fSDan Murphy 	int ret;
424*5069185fSDan Murphy 
425*5069185fSDan Murphy 	if (batovp < bq->chip_info->batovp_min)
426*5069185fSDan Murphy 		batovp = bq->chip_info->batovp_min;
427*5069185fSDan Murphy 
428*5069185fSDan Murphy 	if (batovp > bq->chip_info->batovp_max)
429*5069185fSDan Murphy 		batovp = bq->chip_info->batovp_max;
430*5069185fSDan Murphy 
431*5069185fSDan Murphy 	batovp_reg_code = (batovp - bq->chip_info->batovp_offset) /
432*5069185fSDan Murphy 						bq->chip_info->batovp_step;
433*5069185fSDan Murphy 
434*5069185fSDan Murphy 	ret = regmap_write(bq->regmap, BQ25980_BATOVP, batovp_reg_code);
435*5069185fSDan Murphy 	if (ret)
436*5069185fSDan Murphy 		return ret;
437*5069185fSDan Murphy 
438*5069185fSDan Murphy 	return regmap_write(bq->regmap, BQ25980_BATOVP_ALM, batovp_reg_code);
439*5069185fSDan Murphy }
440*5069185fSDan Murphy 
441*5069185fSDan Murphy static int bq25980_set_bypass(struct bq25980_device *bq, bool en_bypass)
442*5069185fSDan Murphy {
443*5069185fSDan Murphy 	int ret;
444*5069185fSDan Murphy 
445*5069185fSDan Murphy 	if (en_bypass)
446*5069185fSDan Murphy 		ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2,
447*5069185fSDan Murphy 					BQ25980_EN_BYPASS, BQ25980_EN_BYPASS);
448*5069185fSDan Murphy 	else
449*5069185fSDan Murphy 		ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2,
450*5069185fSDan Murphy 					BQ25980_EN_BYPASS, en_bypass);
451*5069185fSDan Murphy 	if (ret)
452*5069185fSDan Murphy 		return ret;
453*5069185fSDan Murphy 
454*5069185fSDan Murphy 	bq->state.bypass = en_bypass;
455*5069185fSDan Murphy 
456*5069185fSDan Murphy 	return bq->state.bypass;
457*5069185fSDan Murphy }
458*5069185fSDan Murphy 
459*5069185fSDan Murphy static int bq25980_set_chg_en(struct bq25980_device *bq, bool en_chg)
460*5069185fSDan Murphy {
461*5069185fSDan Murphy 	int ret;
462*5069185fSDan Murphy 
463*5069185fSDan Murphy 	if (en_chg)
464*5069185fSDan Murphy 		ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2,
465*5069185fSDan Murphy 					BQ25980_CHG_EN, BQ25980_CHG_EN);
466*5069185fSDan Murphy 	else
467*5069185fSDan Murphy 		ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2,
468*5069185fSDan Murphy 					BQ25980_CHG_EN, en_chg);
469*5069185fSDan Murphy 	if (ret)
470*5069185fSDan Murphy 		return ret;
471*5069185fSDan Murphy 
472*5069185fSDan Murphy 	bq->state.ce = en_chg;
473*5069185fSDan Murphy 
474*5069185fSDan Murphy 	return 0;
475*5069185fSDan Murphy }
476*5069185fSDan Murphy 
477*5069185fSDan Murphy static int bq25980_get_adc_ibus(struct bq25980_device *bq)
478*5069185fSDan Murphy {
479*5069185fSDan Murphy 	int ibus_adc_lsb, ibus_adc_msb;
480*5069185fSDan Murphy 	u16 ibus_adc;
481*5069185fSDan Murphy 	int ret;
482*5069185fSDan Murphy 
483*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_IBUS_ADC_MSB, &ibus_adc_msb);
484*5069185fSDan Murphy 	if (ret)
485*5069185fSDan Murphy 		return ret;
486*5069185fSDan Murphy 
487*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_IBUS_ADC_LSB, &ibus_adc_lsb);
488*5069185fSDan Murphy 	if (ret)
489*5069185fSDan Murphy 		return ret;
490*5069185fSDan Murphy 
491*5069185fSDan Murphy 	ibus_adc = (ibus_adc_msb << 8) | ibus_adc_lsb;
492*5069185fSDan Murphy 
493*5069185fSDan Murphy 	if (ibus_adc_msb & BQ25980_ADC_POLARITY_BIT)
494*5069185fSDan Murphy 		return ((ibus_adc ^ 0xffff) + 1) * BQ25980_ADC_CURR_STEP_uA;
495*5069185fSDan Murphy 
496*5069185fSDan Murphy 	return ibus_adc * BQ25980_ADC_CURR_STEP_uA;
497*5069185fSDan Murphy }
498*5069185fSDan Murphy 
499*5069185fSDan Murphy static int bq25980_get_adc_vbus(struct bq25980_device *bq)
500*5069185fSDan Murphy {
501*5069185fSDan Murphy 	int vbus_adc_lsb, vbus_adc_msb;
502*5069185fSDan Murphy 	u16 vbus_adc;
503*5069185fSDan Murphy 	int ret;
504*5069185fSDan Murphy 
505*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_VBUS_ADC_MSB, &vbus_adc_msb);
506*5069185fSDan Murphy 	if (ret)
507*5069185fSDan Murphy 		return ret;
508*5069185fSDan Murphy 
509*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_VBUS_ADC_LSB, &vbus_adc_lsb);
510*5069185fSDan Murphy 	if (ret)
511*5069185fSDan Murphy 		return ret;
512*5069185fSDan Murphy 
513*5069185fSDan Murphy 	vbus_adc = (vbus_adc_msb << 8) | vbus_adc_lsb;
514*5069185fSDan Murphy 
515*5069185fSDan Murphy 	return vbus_adc * BQ25980_ADC_VOLT_STEP_uV;
516*5069185fSDan Murphy }
517*5069185fSDan Murphy 
518*5069185fSDan Murphy static int bq25980_get_ibat_adc(struct bq25980_device *bq)
519*5069185fSDan Murphy {
520*5069185fSDan Murphy 	int ret;
521*5069185fSDan Murphy 	int ibat_adc_lsb, ibat_adc_msb;
522*5069185fSDan Murphy 	int ibat_adc;
523*5069185fSDan Murphy 
524*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_IBAT_ADC_MSB, &ibat_adc_msb);
525*5069185fSDan Murphy 	if (ret)
526*5069185fSDan Murphy 		return ret;
527*5069185fSDan Murphy 
528*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_IBAT_ADC_LSB, &ibat_adc_lsb);
529*5069185fSDan Murphy 	if (ret)
530*5069185fSDan Murphy 		return ret;
531*5069185fSDan Murphy 
532*5069185fSDan Murphy 	ibat_adc = (ibat_adc_msb << 8) | ibat_adc_lsb;
533*5069185fSDan Murphy 
534*5069185fSDan Murphy 	if (ibat_adc_msb & BQ25980_ADC_POLARITY_BIT)
535*5069185fSDan Murphy 		return ((ibat_adc ^ 0xffff) + 1) * BQ25980_ADC_CURR_STEP_uA;
536*5069185fSDan Murphy 
537*5069185fSDan Murphy 	return ibat_adc * BQ25980_ADC_CURR_STEP_uA;
538*5069185fSDan Murphy }
539*5069185fSDan Murphy 
540*5069185fSDan Murphy static int bq25980_get_adc_vbat(struct bq25980_device *bq)
541*5069185fSDan Murphy {
542*5069185fSDan Murphy 	int vsys_adc_lsb, vsys_adc_msb;
543*5069185fSDan Murphy 	u16 vsys_adc;
544*5069185fSDan Murphy 	int ret;
545*5069185fSDan Murphy 
546*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_VBAT_ADC_MSB, &vsys_adc_msb);
547*5069185fSDan Murphy 	if (ret)
548*5069185fSDan Murphy 		return ret;
549*5069185fSDan Murphy 
550*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_VBAT_ADC_LSB, &vsys_adc_lsb);
551*5069185fSDan Murphy 	if (ret)
552*5069185fSDan Murphy 		return ret;
553*5069185fSDan Murphy 
554*5069185fSDan Murphy 	vsys_adc = (vsys_adc_msb << 8) | vsys_adc_lsb;
555*5069185fSDan Murphy 
556*5069185fSDan Murphy 	return vsys_adc * BQ25980_ADC_VOLT_STEP_uV;
557*5069185fSDan Murphy }
558*5069185fSDan Murphy 
559*5069185fSDan Murphy static int bq25980_get_state(struct bq25980_device *bq,
560*5069185fSDan Murphy 				struct bq25980_state *state)
561*5069185fSDan Murphy {
562*5069185fSDan Murphy 	unsigned int chg_ctrl_2;
563*5069185fSDan Murphy 	unsigned int stat1;
564*5069185fSDan Murphy 	unsigned int stat2;
565*5069185fSDan Murphy 	unsigned int stat3;
566*5069185fSDan Murphy 	unsigned int stat4;
567*5069185fSDan Murphy 	unsigned int ibat_adc_msb;
568*5069185fSDan Murphy 	int ret;
569*5069185fSDan Murphy 
570*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_STAT1, &stat1);
571*5069185fSDan Murphy 	if (ret)
572*5069185fSDan Murphy 		return ret;
573*5069185fSDan Murphy 
574*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_STAT2, &stat2);
575*5069185fSDan Murphy 	if (ret)
576*5069185fSDan Murphy 		return ret;
577*5069185fSDan Murphy 
578*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_STAT3, &stat3);
579*5069185fSDan Murphy 	if (ret)
580*5069185fSDan Murphy 		return ret;
581*5069185fSDan Murphy 
582*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_STAT4, &stat4);
583*5069185fSDan Murphy 	if (ret)
584*5069185fSDan Murphy 		return ret;
585*5069185fSDan Murphy 
586*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_CHRGR_CTRL_2, &chg_ctrl_2);
587*5069185fSDan Murphy 	if (ret)
588*5069185fSDan Murphy 		return ret;
589*5069185fSDan Murphy 
590*5069185fSDan Murphy 	ret = regmap_read(bq->regmap, BQ25980_IBAT_ADC_MSB, &ibat_adc_msb);
591*5069185fSDan Murphy 	if (ret)
592*5069185fSDan Murphy 		return ret;
593*5069185fSDan Murphy 
594*5069185fSDan Murphy 	state->dischg = ibat_adc_msb & BQ25980_ADC_POLARITY_BIT;
595*5069185fSDan Murphy 	state->ovp = (stat1 & BQ25980_STAT1_OVP_MASK) |
596*5069185fSDan Murphy 		(stat3 & BQ25980_STAT3_OVP_MASK);
597*5069185fSDan Murphy 	state->ocp = (stat1 & BQ25980_STAT1_OCP_MASK) |
598*5069185fSDan Murphy 		(stat2 & BQ25980_STAT2_OCP_MASK);
599*5069185fSDan Murphy 	state->tflt = stat4 & BQ25980_STAT4_TFLT_MASK;
600*5069185fSDan Murphy 	state->wdt = stat4 & BQ25980_WD_STAT;
601*5069185fSDan Murphy 	state->online = stat3 & BQ25980_PRESENT_MASK;
602*5069185fSDan Murphy 	state->ce = chg_ctrl_2 & BQ25980_CHG_EN;
603*5069185fSDan Murphy 	state->hiz = chg_ctrl_2 & BQ25980_EN_HIZ;
604*5069185fSDan Murphy 	state->bypass = chg_ctrl_2 & BQ25980_EN_BYPASS;
605*5069185fSDan Murphy 
606*5069185fSDan Murphy 	return 0;
607*5069185fSDan Murphy }
608*5069185fSDan Murphy 
609*5069185fSDan Murphy static int bq25980_set_battery_property(struct power_supply *psy,
610*5069185fSDan Murphy 				enum power_supply_property psp,
611*5069185fSDan Murphy 				const union power_supply_propval *val)
612*5069185fSDan Murphy {
613*5069185fSDan Murphy 	struct bq25980_device *bq = power_supply_get_drvdata(psy);
614*5069185fSDan Murphy 	int ret = 0;
615*5069185fSDan Murphy 
616*5069185fSDan Murphy 	if (ret)
617*5069185fSDan Murphy 		return ret;
618*5069185fSDan Murphy 
619*5069185fSDan Murphy 	switch (psp) {
620*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
621*5069185fSDan Murphy 		ret = bq25980_set_const_charge_curr(bq, val->intval);
622*5069185fSDan Murphy 		if (ret)
623*5069185fSDan Murphy 			return ret;
624*5069185fSDan Murphy 		break;
625*5069185fSDan Murphy 
626*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
627*5069185fSDan Murphy 		ret = bq25980_set_const_charge_volt(bq, val->intval);
628*5069185fSDan Murphy 		if (ret)
629*5069185fSDan Murphy 			return ret;
630*5069185fSDan Murphy 		break;
631*5069185fSDan Murphy 
632*5069185fSDan Murphy 	default:
633*5069185fSDan Murphy 		return -EINVAL;
634*5069185fSDan Murphy 	}
635*5069185fSDan Murphy 
636*5069185fSDan Murphy 	return ret;
637*5069185fSDan Murphy }
638*5069185fSDan Murphy 
639*5069185fSDan Murphy static int bq25980_get_battery_property(struct power_supply *psy,
640*5069185fSDan Murphy 				enum power_supply_property psp,
641*5069185fSDan Murphy 				union power_supply_propval *val)
642*5069185fSDan Murphy {
643*5069185fSDan Murphy 	struct bq25980_device *bq = power_supply_get_drvdata(psy);
644*5069185fSDan Murphy 	int ret = 0;
645*5069185fSDan Murphy 
646*5069185fSDan Murphy 	switch (psp) {
647*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
648*5069185fSDan Murphy 		val->intval = bq->init_data.ichg_max;
649*5069185fSDan Murphy 		break;
650*5069185fSDan Murphy 
651*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
652*5069185fSDan Murphy 		val->intval = bq->init_data.vreg_max;
653*5069185fSDan Murphy 		break;
654*5069185fSDan Murphy 
655*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CURRENT_NOW:
656*5069185fSDan Murphy 		ret = bq25980_get_ibat_adc(bq);
657*5069185fSDan Murphy 		val->intval = ret;
658*5069185fSDan Murphy 		break;
659*5069185fSDan Murphy 
660*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
661*5069185fSDan Murphy 		ret = bq25980_get_adc_vbat(bq);
662*5069185fSDan Murphy 		if (ret < 0)
663*5069185fSDan Murphy 			return ret;
664*5069185fSDan Murphy 
665*5069185fSDan Murphy 		val->intval = ret;
666*5069185fSDan Murphy 		break;
667*5069185fSDan Murphy 
668*5069185fSDan Murphy 	default:
669*5069185fSDan Murphy 		return -EINVAL;
670*5069185fSDan Murphy 	}
671*5069185fSDan Murphy 
672*5069185fSDan Murphy 	return ret;
673*5069185fSDan Murphy }
674*5069185fSDan Murphy 
675*5069185fSDan Murphy static int bq25980_set_charger_property(struct power_supply *psy,
676*5069185fSDan Murphy 		enum power_supply_property prop,
677*5069185fSDan Murphy 		const union power_supply_propval *val)
678*5069185fSDan Murphy {
679*5069185fSDan Murphy 	struct bq25980_device *bq = power_supply_get_drvdata(psy);
680*5069185fSDan Murphy 	int ret = -EINVAL;
681*5069185fSDan Murphy 
682*5069185fSDan Murphy 	switch (prop) {
683*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
684*5069185fSDan Murphy 		ret = bq25980_set_input_curr_lim(bq, val->intval);
685*5069185fSDan Murphy 		if (ret)
686*5069185fSDan Murphy 			return ret;
687*5069185fSDan Murphy 		break;
688*5069185fSDan Murphy 
689*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
690*5069185fSDan Murphy 		ret = bq25980_set_input_volt_lim(bq, val->intval);
691*5069185fSDan Murphy 		if (ret)
692*5069185fSDan Murphy 			return ret;
693*5069185fSDan Murphy 		break;
694*5069185fSDan Murphy 
695*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
696*5069185fSDan Murphy 		ret = bq25980_set_bypass(bq, val->intval);
697*5069185fSDan Murphy 		if (ret)
698*5069185fSDan Murphy 			return ret;
699*5069185fSDan Murphy 		break;
700*5069185fSDan Murphy 
701*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_STATUS:
702*5069185fSDan Murphy 		ret = bq25980_set_chg_en(bq, val->intval);
703*5069185fSDan Murphy 		if (ret)
704*5069185fSDan Murphy 			return ret;
705*5069185fSDan Murphy 		break;
706*5069185fSDan Murphy 
707*5069185fSDan Murphy 	default:
708*5069185fSDan Murphy 		return -EINVAL;
709*5069185fSDan Murphy 	}
710*5069185fSDan Murphy 
711*5069185fSDan Murphy 	return ret;
712*5069185fSDan Murphy }
713*5069185fSDan Murphy 
714*5069185fSDan Murphy static int bq25980_get_charger_property(struct power_supply *psy,
715*5069185fSDan Murphy 				enum power_supply_property psp,
716*5069185fSDan Murphy 				union power_supply_propval *val)
717*5069185fSDan Murphy {
718*5069185fSDan Murphy 	struct bq25980_device *bq = power_supply_get_drvdata(psy);
719*5069185fSDan Murphy 	struct bq25980_state state;
720*5069185fSDan Murphy 	int ret = 0;
721*5069185fSDan Murphy 
722*5069185fSDan Murphy 	mutex_lock(&bq->lock);
723*5069185fSDan Murphy 	ret = bq25980_get_state(bq, &state);
724*5069185fSDan Murphy 	mutex_unlock(&bq->lock);
725*5069185fSDan Murphy 	if (ret)
726*5069185fSDan Murphy 		return ret;
727*5069185fSDan Murphy 
728*5069185fSDan Murphy 	switch (psp) {
729*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_MANUFACTURER:
730*5069185fSDan Murphy 		val->strval = BQ25980_MANUFACTURER;
731*5069185fSDan Murphy 		break;
732*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_MODEL_NAME:
733*5069185fSDan Murphy 		val->strval = bq->model_name;
734*5069185fSDan Murphy 		break;
735*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_ONLINE:
736*5069185fSDan Murphy 		val->intval = state.online;
737*5069185fSDan Murphy 		break;
738*5069185fSDan Murphy 
739*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
740*5069185fSDan Murphy 		ret = bq25980_get_input_volt_lim(bq);
741*5069185fSDan Murphy 		if (ret < 0)
742*5069185fSDan Murphy 			return ret;
743*5069185fSDan Murphy 		val->intval = ret;
744*5069185fSDan Murphy 		break;
745*5069185fSDan Murphy 
746*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
747*5069185fSDan Murphy 		ret = bq25980_get_input_curr_lim(bq);
748*5069185fSDan Murphy 		if (ret < 0)
749*5069185fSDan Murphy 			return ret;
750*5069185fSDan Murphy 
751*5069185fSDan Murphy 		val->intval = ret;
752*5069185fSDan Murphy 		break;
753*5069185fSDan Murphy 
754*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_HEALTH:
755*5069185fSDan Murphy 		val->intval = POWER_SUPPLY_HEALTH_GOOD;
756*5069185fSDan Murphy 
757*5069185fSDan Murphy 		if (state.tflt)
758*5069185fSDan Murphy 			val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
759*5069185fSDan Murphy 		else if (state.ovp)
760*5069185fSDan Murphy 			val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
761*5069185fSDan Murphy 		else if (state.ocp)
762*5069185fSDan Murphy 			val->intval = POWER_SUPPLY_HEALTH_OVERCURRENT;
763*5069185fSDan Murphy 		else if (state.wdt)
764*5069185fSDan Murphy 			val->intval =
765*5069185fSDan Murphy 				POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE;
766*5069185fSDan Murphy 		break;
767*5069185fSDan Murphy 
768*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_STATUS:
769*5069185fSDan Murphy 		val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
770*5069185fSDan Murphy 
771*5069185fSDan Murphy 		if ((state.ce) && (!state.hiz))
772*5069185fSDan Murphy 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
773*5069185fSDan Murphy 		else if (state.dischg)
774*5069185fSDan Murphy 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
775*5069185fSDan Murphy 		else if (!state.ce)
776*5069185fSDan Murphy 			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
777*5069185fSDan Murphy 		break;
778*5069185fSDan Murphy 
779*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
780*5069185fSDan Murphy 		val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
781*5069185fSDan Murphy 
782*5069185fSDan Murphy 		if (!state.ce)
783*5069185fSDan Murphy 			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
784*5069185fSDan Murphy 		else if (state.bypass)
785*5069185fSDan Murphy 			val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
786*5069185fSDan Murphy 		else if (!state.bypass)
787*5069185fSDan Murphy 			val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
788*5069185fSDan Murphy 		break;
789*5069185fSDan Murphy 
790*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CURRENT_NOW:
791*5069185fSDan Murphy 		ret = bq25980_get_adc_ibus(bq);
792*5069185fSDan Murphy 		if (ret < 0)
793*5069185fSDan Murphy 			return ret;
794*5069185fSDan Murphy 
795*5069185fSDan Murphy 		val->intval = ret;
796*5069185fSDan Murphy 		break;
797*5069185fSDan Murphy 
798*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
799*5069185fSDan Murphy 		ret = bq25980_get_adc_vbus(bq);
800*5069185fSDan Murphy 		if (ret < 0)
801*5069185fSDan Murphy 			return ret;
802*5069185fSDan Murphy 
803*5069185fSDan Murphy 		val->intval = ret;
804*5069185fSDan Murphy 		break;
805*5069185fSDan Murphy 
806*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
807*5069185fSDan Murphy 		ret = bq25980_get_const_charge_curr(bq);
808*5069185fSDan Murphy 		if (ret < 0)
809*5069185fSDan Murphy 			return ret;
810*5069185fSDan Murphy 
811*5069185fSDan Murphy 		val->intval = ret;
812*5069185fSDan Murphy 		break;
813*5069185fSDan Murphy 
814*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
815*5069185fSDan Murphy 		ret = bq25980_get_const_charge_volt(bq);
816*5069185fSDan Murphy 		if (ret < 0)
817*5069185fSDan Murphy 			return ret;
818*5069185fSDan Murphy 
819*5069185fSDan Murphy 		val->intval = ret;
820*5069185fSDan Murphy 		break;
821*5069185fSDan Murphy 
822*5069185fSDan Murphy 	default:
823*5069185fSDan Murphy 		return -EINVAL;
824*5069185fSDan Murphy 	}
825*5069185fSDan Murphy 
826*5069185fSDan Murphy 	return ret;
827*5069185fSDan Murphy }
828*5069185fSDan Murphy 
829*5069185fSDan Murphy static bool bq25980_state_changed(struct bq25980_device *bq,
830*5069185fSDan Murphy 				  struct bq25980_state *new_state)
831*5069185fSDan Murphy {
832*5069185fSDan Murphy 	struct bq25980_state old_state;
833*5069185fSDan Murphy 
834*5069185fSDan Murphy 	mutex_lock(&bq->lock);
835*5069185fSDan Murphy 	old_state = bq->state;
836*5069185fSDan Murphy 	mutex_unlock(&bq->lock);
837*5069185fSDan Murphy 
838*5069185fSDan Murphy 	return (old_state.dischg != new_state->dischg ||
839*5069185fSDan Murphy 		old_state.ovp != new_state->ovp ||
840*5069185fSDan Murphy 		old_state.ocp != new_state->ocp ||
841*5069185fSDan Murphy 		old_state.online != new_state->online ||
842*5069185fSDan Murphy 		old_state.wdt != new_state->wdt ||
843*5069185fSDan Murphy 		old_state.tflt != new_state->tflt ||
844*5069185fSDan Murphy 		old_state.ce != new_state->ce ||
845*5069185fSDan Murphy 		old_state.hiz != new_state->hiz ||
846*5069185fSDan Murphy 		old_state.bypass != new_state->bypass);
847*5069185fSDan Murphy }
848*5069185fSDan Murphy 
849*5069185fSDan Murphy static irqreturn_t bq25980_irq_handler_thread(int irq, void *private)
850*5069185fSDan Murphy {
851*5069185fSDan Murphy 	struct bq25980_device *bq = private;
852*5069185fSDan Murphy 	struct bq25980_state state;
853*5069185fSDan Murphy 	int ret;
854*5069185fSDan Murphy 
855*5069185fSDan Murphy 	ret = bq25980_get_state(bq, &state);
856*5069185fSDan Murphy 	if (ret < 0)
857*5069185fSDan Murphy 		goto irq_out;
858*5069185fSDan Murphy 
859*5069185fSDan Murphy 	if (!bq25980_state_changed(bq, &state))
860*5069185fSDan Murphy 		goto irq_out;
861*5069185fSDan Murphy 
862*5069185fSDan Murphy 	mutex_lock(&bq->lock);
863*5069185fSDan Murphy 	bq->state = state;
864*5069185fSDan Murphy 	mutex_unlock(&bq->lock);
865*5069185fSDan Murphy 
866*5069185fSDan Murphy 	power_supply_changed(bq->charger);
867*5069185fSDan Murphy 
868*5069185fSDan Murphy irq_out:
869*5069185fSDan Murphy 	return IRQ_HANDLED;
870*5069185fSDan Murphy }
871*5069185fSDan Murphy 
872*5069185fSDan Murphy static enum power_supply_property bq25980_power_supply_props[] = {
873*5069185fSDan Murphy 	POWER_SUPPLY_PROP_MANUFACTURER,
874*5069185fSDan Murphy 	POWER_SUPPLY_PROP_MODEL_NAME,
875*5069185fSDan Murphy 	POWER_SUPPLY_PROP_STATUS,
876*5069185fSDan Murphy 	POWER_SUPPLY_PROP_ONLINE,
877*5069185fSDan Murphy 	POWER_SUPPLY_PROP_HEALTH,
878*5069185fSDan Murphy 	POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT,
879*5069185fSDan Murphy 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
880*5069185fSDan Murphy 	POWER_SUPPLY_PROP_CHARGE_TYPE,
881*5069185fSDan Murphy 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
882*5069185fSDan Murphy 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
883*5069185fSDan Murphy 	POWER_SUPPLY_PROP_CURRENT_NOW,
884*5069185fSDan Murphy 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
885*5069185fSDan Murphy };
886*5069185fSDan Murphy 
887*5069185fSDan Murphy static enum power_supply_property bq25980_battery_props[] = {
888*5069185fSDan Murphy 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
889*5069185fSDan Murphy 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
890*5069185fSDan Murphy 	POWER_SUPPLY_PROP_CURRENT_NOW,
891*5069185fSDan Murphy 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
892*5069185fSDan Murphy };
893*5069185fSDan Murphy 
894*5069185fSDan Murphy static char *bq25980_charger_supplied_to[] = {
895*5069185fSDan Murphy 	"main-battery",
896*5069185fSDan Murphy };
897*5069185fSDan Murphy 
898*5069185fSDan Murphy static int bq25980_property_is_writeable(struct power_supply *psy,
899*5069185fSDan Murphy 					 enum power_supply_property prop)
900*5069185fSDan Murphy {
901*5069185fSDan Murphy 	switch (prop) {
902*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
903*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
904*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
905*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
906*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_STATUS:
907*5069185fSDan Murphy 	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
908*5069185fSDan Murphy 		return true;
909*5069185fSDan Murphy 	default:
910*5069185fSDan Murphy 		return false;
911*5069185fSDan Murphy 	}
912*5069185fSDan Murphy }
913*5069185fSDan Murphy 
914*5069185fSDan Murphy static const struct power_supply_desc bq25980_power_supply_desc = {
915*5069185fSDan Murphy 	.name = "bq25980-charger",
916*5069185fSDan Murphy 	.type = POWER_SUPPLY_TYPE_MAINS,
917*5069185fSDan Murphy 	.properties = bq25980_power_supply_props,
918*5069185fSDan Murphy 	.num_properties = ARRAY_SIZE(bq25980_power_supply_props),
919*5069185fSDan Murphy 	.get_property = bq25980_get_charger_property,
920*5069185fSDan Murphy 	.set_property = bq25980_set_charger_property,
921*5069185fSDan Murphy 	.property_is_writeable = bq25980_property_is_writeable,
922*5069185fSDan Murphy };
923*5069185fSDan Murphy 
924*5069185fSDan Murphy static struct power_supply_desc bq25980_battery_desc = {
925*5069185fSDan Murphy 	.name			= "bq25980-battery",
926*5069185fSDan Murphy 	.type			= POWER_SUPPLY_TYPE_BATTERY,
927*5069185fSDan Murphy 	.get_property		= bq25980_get_battery_property,
928*5069185fSDan Murphy 	.set_property		= bq25980_set_battery_property,
929*5069185fSDan Murphy 	.properties		= bq25980_battery_props,
930*5069185fSDan Murphy 	.num_properties		= ARRAY_SIZE(bq25980_battery_props),
931*5069185fSDan Murphy 	.property_is_writeable	= bq25980_property_is_writeable,
932*5069185fSDan Murphy };
933*5069185fSDan Murphy 
934*5069185fSDan Murphy 
935*5069185fSDan Murphy static bool bq25980_is_volatile_reg(struct device *dev, unsigned int reg)
936*5069185fSDan Murphy {
937*5069185fSDan Murphy 	switch (reg) {
938*5069185fSDan Murphy 	case BQ25980_CHRGR_CTRL_2:
939*5069185fSDan Murphy 	case BQ25980_STAT1...BQ25980_FLAG5:
940*5069185fSDan Murphy 	case BQ25980_ADC_CONTROL1...BQ25980_TDIE_ADC_LSB:
941*5069185fSDan Murphy 		return true;
942*5069185fSDan Murphy 	default:
943*5069185fSDan Murphy 		return false;
944*5069185fSDan Murphy 	}
945*5069185fSDan Murphy }
946*5069185fSDan Murphy 
947*5069185fSDan Murphy static const struct regmap_config bq25980_regmap_config = {
948*5069185fSDan Murphy 	.reg_bits = 8,
949*5069185fSDan Murphy 	.val_bits = 8,
950*5069185fSDan Murphy 
951*5069185fSDan Murphy 	.max_register = BQ25980_CHRGR_CTRL_6,
952*5069185fSDan Murphy 	.reg_defaults	= bq25980_reg_defs,
953*5069185fSDan Murphy 	.num_reg_defaults = ARRAY_SIZE(bq25980_reg_defs),
954*5069185fSDan Murphy 	.cache_type = REGCACHE_RBTREE,
955*5069185fSDan Murphy 	.volatile_reg = bq25980_is_volatile_reg,
956*5069185fSDan Murphy };
957*5069185fSDan Murphy 
958*5069185fSDan Murphy static const struct regmap_config bq25975_regmap_config = {
959*5069185fSDan Murphy 	.reg_bits = 8,
960*5069185fSDan Murphy 	.val_bits = 8,
961*5069185fSDan Murphy 
962*5069185fSDan Murphy 	.max_register = BQ25980_CHRGR_CTRL_6,
963*5069185fSDan Murphy 	.reg_defaults	= bq25975_reg_defs,
964*5069185fSDan Murphy 	.num_reg_defaults = ARRAY_SIZE(bq25975_reg_defs),
965*5069185fSDan Murphy 	.cache_type = REGCACHE_RBTREE,
966*5069185fSDan Murphy 	.volatile_reg = bq25980_is_volatile_reg,
967*5069185fSDan Murphy };
968*5069185fSDan Murphy 
969*5069185fSDan Murphy static const struct regmap_config bq25960_regmap_config = {
970*5069185fSDan Murphy 	.reg_bits = 8,
971*5069185fSDan Murphy 	.val_bits = 8,
972*5069185fSDan Murphy 
973*5069185fSDan Murphy 	.max_register = BQ25980_CHRGR_CTRL_6,
974*5069185fSDan Murphy 	.reg_defaults	= bq25960_reg_defs,
975*5069185fSDan Murphy 	.num_reg_defaults = ARRAY_SIZE(bq25960_reg_defs),
976*5069185fSDan Murphy 	.cache_type = REGCACHE_RBTREE,
977*5069185fSDan Murphy 	.volatile_reg = bq25980_is_volatile_reg,
978*5069185fSDan Murphy };
979*5069185fSDan Murphy 
980*5069185fSDan Murphy static const struct bq25980_chip_info bq25980_chip_info_tbl[] = {
981*5069185fSDan Murphy 	[BQ25980] = {
982*5069185fSDan Murphy 		.model_id = BQ25980,
983*5069185fSDan Murphy 		.regmap_config = &bq25980_regmap_config,
984*5069185fSDan Murphy 
985*5069185fSDan Murphy 		.busocp_def = BQ25980_BUSOCP_DFLT_uA,
986*5069185fSDan Murphy 		.busocp_sc_min = BQ25960_BUSOCP_SC_MAX_uA,
987*5069185fSDan Murphy 		.busocp_sc_max = BQ25980_BUSOCP_SC_MAX_uA,
988*5069185fSDan Murphy 		.busocp_byp_max = BQ25980_BUSOCP_BYP_MAX_uA,
989*5069185fSDan Murphy 		.busocp_byp_min = BQ25980_BUSOCP_MIN_uA,
990*5069185fSDan Murphy 
991*5069185fSDan Murphy 		.busovp_sc_def = BQ25980_BUSOVP_DFLT_uV,
992*5069185fSDan Murphy 		.busovp_byp_def = BQ25980_BUSOVP_BYPASS_DFLT_uV,
993*5069185fSDan Murphy 		.busovp_sc_step = BQ25980_BUSOVP_SC_STEP_uV,
994*5069185fSDan Murphy 		.busovp_sc_offset = BQ25980_BUSOVP_SC_OFFSET_uV,
995*5069185fSDan Murphy 		.busovp_byp_step = BQ25980_BUSOVP_BYP_STEP_uV,
996*5069185fSDan Murphy 		.busovp_byp_offset = BQ25980_BUSOVP_BYP_OFFSET_uV,
997*5069185fSDan Murphy 		.busovp_sc_min = BQ25980_BUSOVP_SC_MIN_uV,
998*5069185fSDan Murphy 		.busovp_sc_max = BQ25980_BUSOVP_SC_MAX_uV,
999*5069185fSDan Murphy 		.busovp_byp_min = BQ25980_BUSOVP_BYP_MIN_uV,
1000*5069185fSDan Murphy 		.busovp_byp_max = BQ25980_BUSOVP_BYP_MAX_uV,
1001*5069185fSDan Murphy 
1002*5069185fSDan Murphy 		.batovp_def = BQ25980_BATOVP_DFLT_uV,
1003*5069185fSDan Murphy 		.batovp_max = BQ25980_BATOVP_MAX_uV,
1004*5069185fSDan Murphy 		.batovp_min = BQ25980_BATOVP_MIN_uV,
1005*5069185fSDan Murphy 		.batovp_step = BQ25980_BATOVP_STEP_uV,
1006*5069185fSDan Murphy 		.batovp_offset = BQ25980_BATOVP_OFFSET_uV,
1007*5069185fSDan Murphy 
1008*5069185fSDan Murphy 		.batocp_def = BQ25980_BATOCP_DFLT_uA,
1009*5069185fSDan Murphy 		.batocp_max = BQ25980_BATOCP_MAX_uA,
1010*5069185fSDan Murphy 	},
1011*5069185fSDan Murphy 
1012*5069185fSDan Murphy 	[BQ25975] = {
1013*5069185fSDan Murphy 		.model_id = BQ25975,
1014*5069185fSDan Murphy 		.regmap_config = &bq25975_regmap_config,
1015*5069185fSDan Murphy 
1016*5069185fSDan Murphy 		.busocp_def = BQ25975_BUSOCP_DFLT_uA,
1017*5069185fSDan Murphy 		.busocp_sc_min = BQ25975_BUSOCP_SC_MAX_uA,
1018*5069185fSDan Murphy 		.busocp_sc_max = BQ25975_BUSOCP_SC_MAX_uA,
1019*5069185fSDan Murphy 		.busocp_byp_min = BQ25980_BUSOCP_MIN_uA,
1020*5069185fSDan Murphy 		.busocp_byp_max = BQ25975_BUSOCP_BYP_MAX_uA,
1021*5069185fSDan Murphy 
1022*5069185fSDan Murphy 		.busovp_sc_def = BQ25975_BUSOVP_DFLT_uV,
1023*5069185fSDan Murphy 		.busovp_byp_def = BQ25975_BUSOVP_BYPASS_DFLT_uV,
1024*5069185fSDan Murphy 		.busovp_sc_step = BQ25975_BUSOVP_SC_STEP_uV,
1025*5069185fSDan Murphy 		.busovp_sc_offset = BQ25975_BUSOVP_SC_OFFSET_uV,
1026*5069185fSDan Murphy 		.busovp_byp_step = BQ25975_BUSOVP_BYP_STEP_uV,
1027*5069185fSDan Murphy 		.busovp_byp_offset = BQ25975_BUSOVP_BYP_OFFSET_uV,
1028*5069185fSDan Murphy 		.busovp_sc_min = BQ25975_BUSOVP_SC_MIN_uV,
1029*5069185fSDan Murphy 		.busovp_sc_max = BQ25975_BUSOVP_SC_MAX_uV,
1030*5069185fSDan Murphy 		.busovp_byp_min = BQ25975_BUSOVP_BYP_MIN_uV,
1031*5069185fSDan Murphy 		.busovp_byp_max = BQ25975_BUSOVP_BYP_MAX_uV,
1032*5069185fSDan Murphy 
1033*5069185fSDan Murphy 		.batovp_def = BQ25975_BATOVP_DFLT_uV,
1034*5069185fSDan Murphy 		.batovp_max = BQ25975_BATOVP_MAX_uV,
1035*5069185fSDan Murphy 		.batovp_min = BQ25975_BATOVP_MIN_uV,
1036*5069185fSDan Murphy 		.batovp_step = BQ25975_BATOVP_STEP_uV,
1037*5069185fSDan Murphy 		.batovp_offset = BQ25975_BATOVP_OFFSET_uV,
1038*5069185fSDan Murphy 
1039*5069185fSDan Murphy 		.batocp_def = BQ25980_BATOCP_DFLT_uA,
1040*5069185fSDan Murphy 		.batocp_max = BQ25980_BATOCP_MAX_uA,
1041*5069185fSDan Murphy 	},
1042*5069185fSDan Murphy 
1043*5069185fSDan Murphy 	[BQ25960] = {
1044*5069185fSDan Murphy 		.model_id = BQ25960,
1045*5069185fSDan Murphy 		.regmap_config = &bq25960_regmap_config,
1046*5069185fSDan Murphy 
1047*5069185fSDan Murphy 		.busocp_def = BQ25960_BUSOCP_DFLT_uA,
1048*5069185fSDan Murphy 		.busocp_sc_min = BQ25960_BUSOCP_SC_MAX_uA,
1049*5069185fSDan Murphy 		.busocp_sc_max = BQ25960_BUSOCP_SC_MAX_uA,
1050*5069185fSDan Murphy 		.busocp_byp_min = BQ25960_BUSOCP_SC_MAX_uA,
1051*5069185fSDan Murphy 		.busocp_byp_max = BQ25960_BUSOCP_BYP_MAX_uA,
1052*5069185fSDan Murphy 
1053*5069185fSDan Murphy 		.busovp_sc_def = BQ25975_BUSOVP_DFLT_uV,
1054*5069185fSDan Murphy 		.busovp_byp_def = BQ25975_BUSOVP_BYPASS_DFLT_uV,
1055*5069185fSDan Murphy 		.busovp_sc_step = BQ25960_BUSOVP_SC_STEP_uV,
1056*5069185fSDan Murphy 		.busovp_sc_offset = BQ25960_BUSOVP_SC_OFFSET_uV,
1057*5069185fSDan Murphy 		.busovp_byp_step = BQ25960_BUSOVP_BYP_STEP_uV,
1058*5069185fSDan Murphy 		.busovp_byp_offset = BQ25960_BUSOVP_BYP_OFFSET_uV,
1059*5069185fSDan Murphy 		.busovp_sc_min = BQ25960_BUSOVP_SC_MIN_uV,
1060*5069185fSDan Murphy 		.busovp_sc_max = BQ25960_BUSOVP_SC_MAX_uV,
1061*5069185fSDan Murphy 		.busovp_byp_min = BQ25960_BUSOVP_BYP_MIN_uV,
1062*5069185fSDan Murphy 		.busovp_byp_max = BQ25960_BUSOVP_BYP_MAX_uV,
1063*5069185fSDan Murphy 
1064*5069185fSDan Murphy 		.batovp_def = BQ25960_BATOVP_DFLT_uV,
1065*5069185fSDan Murphy 		.batovp_max = BQ25960_BATOVP_MAX_uV,
1066*5069185fSDan Murphy 		.batovp_min = BQ25960_BATOVP_MIN_uV,
1067*5069185fSDan Murphy 		.batovp_step = BQ25960_BATOVP_STEP_uV,
1068*5069185fSDan Murphy 		.batovp_offset = BQ25960_BATOVP_OFFSET_uV,
1069*5069185fSDan Murphy 
1070*5069185fSDan Murphy 		.batocp_def = BQ25960_BATOCP_DFLT_uA,
1071*5069185fSDan Murphy 		.batocp_max = BQ25960_BATOCP_MAX_uA,
1072*5069185fSDan Murphy 	},
1073*5069185fSDan Murphy };
1074*5069185fSDan Murphy 
1075*5069185fSDan Murphy static int bq25980_power_supply_init(struct bq25980_device *bq,
1076*5069185fSDan Murphy 							struct device *dev)
1077*5069185fSDan Murphy {
1078*5069185fSDan Murphy 	struct power_supply_config psy_cfg = { .drv_data = bq,
1079*5069185fSDan Murphy 						.of_node = dev->of_node, };
1080*5069185fSDan Murphy 
1081*5069185fSDan Murphy 	psy_cfg.supplied_to = bq25980_charger_supplied_to;
1082*5069185fSDan Murphy 	psy_cfg.num_supplicants = ARRAY_SIZE(bq25980_charger_supplied_to);
1083*5069185fSDan Murphy 
1084*5069185fSDan Murphy 	bq->charger = devm_power_supply_register(bq->dev,
1085*5069185fSDan Murphy 						 &bq25980_power_supply_desc,
1086*5069185fSDan Murphy 						 &psy_cfg);
1087*5069185fSDan Murphy 	if (IS_ERR(bq->charger))
1088*5069185fSDan Murphy 		return -EINVAL;
1089*5069185fSDan Murphy 
1090*5069185fSDan Murphy 	bq->battery = devm_power_supply_register(bq->dev,
1091*5069185fSDan Murphy 						      &bq25980_battery_desc,
1092*5069185fSDan Murphy 						      &psy_cfg);
1093*5069185fSDan Murphy 	if (IS_ERR(bq->battery))
1094*5069185fSDan Murphy 		return -EINVAL;
1095*5069185fSDan Murphy 
1096*5069185fSDan Murphy 	return 0;
1097*5069185fSDan Murphy }
1098*5069185fSDan Murphy 
1099*5069185fSDan Murphy static int bq25980_hw_init(struct bq25980_device *bq)
1100*5069185fSDan Murphy {
1101*5069185fSDan Murphy 	struct power_supply_battery_info bat_info = { };
1102*5069185fSDan Murphy 	int wd_reg_val;
1103*5069185fSDan Murphy 	int ret = 0;
1104*5069185fSDan Murphy 	int curr_val;
1105*5069185fSDan Murphy 	int volt_val;
1106*5069185fSDan Murphy 	int i;
1107*5069185fSDan Murphy 
1108*5069185fSDan Murphy 	if (!bq->watchdog_timer) {
1109*5069185fSDan Murphy 		ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_3,
1110*5069185fSDan Murphy 					 BQ25980_WATCHDOG_DIS,
1111*5069185fSDan Murphy 					 BQ25980_WATCHDOG_DIS);
1112*5069185fSDan Murphy 	} else {
1113*5069185fSDan Murphy 		for (i = 0; i < BQ25980_NUM_WD_VAL; i++) {
1114*5069185fSDan Murphy 			if (bq->watchdog_timer > bq25980_watchdog_time[i] &&
1115*5069185fSDan Murphy 			    bq->watchdog_timer < bq25980_watchdog_time[i + 1]) {
1116*5069185fSDan Murphy 				wd_reg_val = i;
1117*5069185fSDan Murphy 				break;
1118*5069185fSDan Murphy 			}
1119*5069185fSDan Murphy 		}
1120*5069185fSDan Murphy 
1121*5069185fSDan Murphy 		ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_3,
1122*5069185fSDan Murphy 					BQ25980_WATCHDOG_MASK, wd_reg_val);
1123*5069185fSDan Murphy 	}
1124*5069185fSDan Murphy 	if (ret)
1125*5069185fSDan Murphy 		return ret;
1126*5069185fSDan Murphy 
1127*5069185fSDan Murphy 	ret = power_supply_get_battery_info(bq->charger, &bat_info);
1128*5069185fSDan Murphy 	if (ret) {
1129*5069185fSDan Murphy 		dev_warn(bq->dev, "battery info missing\n");
1130*5069185fSDan Murphy 		return -EINVAL;
1131*5069185fSDan Murphy 	}
1132*5069185fSDan Murphy 
1133*5069185fSDan Murphy 	bq->init_data.ichg_max = bat_info.constant_charge_current_max_ua;
1134*5069185fSDan Murphy 	bq->init_data.vreg_max = bat_info.constant_charge_voltage_max_uv;
1135*5069185fSDan Murphy 
1136*5069185fSDan Murphy 	if (bq->state.bypass) {
1137*5069185fSDan Murphy 		ret = regmap_update_bits(bq->regmap, BQ25980_CHRGR_CTRL_2,
1138*5069185fSDan Murphy 					BQ25980_EN_BYPASS, BQ25980_EN_BYPASS);
1139*5069185fSDan Murphy 		if (ret)
1140*5069185fSDan Murphy 			return ret;
1141*5069185fSDan Murphy 
1142*5069185fSDan Murphy 		curr_val = bq->init_data.bypass_ilim;
1143*5069185fSDan Murphy 		volt_val = bq->init_data.bypass_vlim;
1144*5069185fSDan Murphy 	} else {
1145*5069185fSDan Murphy 		curr_val = bq->init_data.sc_ilim;
1146*5069185fSDan Murphy 		volt_val = bq->init_data.sc_vlim;
1147*5069185fSDan Murphy 	}
1148*5069185fSDan Murphy 
1149*5069185fSDan Murphy 	ret = bq25980_set_input_curr_lim(bq, curr_val);
1150*5069185fSDan Murphy 	if (ret)
1151*5069185fSDan Murphy 		return ret;
1152*5069185fSDan Murphy 
1153*5069185fSDan Murphy 	ret = bq25980_set_input_volt_lim(bq, volt_val);
1154*5069185fSDan Murphy 	if (ret)
1155*5069185fSDan Murphy 		return ret;
1156*5069185fSDan Murphy 
1157*5069185fSDan Murphy 	return regmap_update_bits(bq->regmap, BQ25980_ADC_CONTROL1,
1158*5069185fSDan Murphy 				 BQ25980_ADC_EN, BQ25980_ADC_EN);
1159*5069185fSDan Murphy }
1160*5069185fSDan Murphy 
1161*5069185fSDan Murphy static int bq25980_parse_dt(struct bq25980_device *bq)
1162*5069185fSDan Murphy {
1163*5069185fSDan Murphy 	int ret;
1164*5069185fSDan Murphy 
1165*5069185fSDan Murphy 	ret = device_property_read_u32(bq->dev, "ti,watchdog-timeout-ms",
1166*5069185fSDan Murphy 				       &bq->watchdog_timer);
1167*5069185fSDan Murphy 	if (ret)
1168*5069185fSDan Murphy 		bq->watchdog_timer = BQ25980_WATCHDOG_MIN;
1169*5069185fSDan Murphy 
1170*5069185fSDan Murphy 	if (bq->watchdog_timer > BQ25980_WATCHDOG_MAX ||
1171*5069185fSDan Murphy 	    bq->watchdog_timer < BQ25980_WATCHDOG_MIN)
1172*5069185fSDan Murphy 		return -EINVAL;
1173*5069185fSDan Murphy 
1174*5069185fSDan Murphy 	ret = device_property_read_u32(bq->dev,
1175*5069185fSDan Murphy 				       "ti,sc-ovp-limit-microvolt",
1176*5069185fSDan Murphy 				       &bq->init_data.sc_vlim);
1177*5069185fSDan Murphy 	if (ret)
1178*5069185fSDan Murphy 		bq->init_data.sc_vlim = bq->chip_info->busovp_sc_def;
1179*5069185fSDan Murphy 
1180*5069185fSDan Murphy 	if (bq->init_data.sc_vlim > bq->chip_info->busovp_sc_max ||
1181*5069185fSDan Murphy 	    bq->init_data.sc_vlim < bq->chip_info->busovp_sc_min) {
1182*5069185fSDan Murphy 		dev_err(bq->dev, "SC ovp limit is out of range\n");
1183*5069185fSDan Murphy 		return -EINVAL;
1184*5069185fSDan Murphy 	}
1185*5069185fSDan Murphy 
1186*5069185fSDan Murphy 	ret = device_property_read_u32(bq->dev,
1187*5069185fSDan Murphy 				       "ti,sc-ocp-limit-microamp",
1188*5069185fSDan Murphy 				       &bq->init_data.sc_ilim);
1189*5069185fSDan Murphy 	if (ret)
1190*5069185fSDan Murphy 		bq->init_data.sc_ilim = bq->chip_info->busocp_def;
1191*5069185fSDan Murphy 
1192*5069185fSDan Murphy 	if (bq->init_data.sc_ilim > bq->chip_info->busocp_sc_max ||
1193*5069185fSDan Murphy 	    bq->init_data.sc_ilim < bq->chip_info->busocp_sc_min) {
1194*5069185fSDan Murphy 		dev_err(bq->dev, "SC ocp limit is out of range\n");
1195*5069185fSDan Murphy 		return -EINVAL;
1196*5069185fSDan Murphy 	}
1197*5069185fSDan Murphy 
1198*5069185fSDan Murphy 	ret = device_property_read_u32(bq->dev,
1199*5069185fSDan Murphy 				       "ti,bypass-ovp-limit-microvolt",
1200*5069185fSDan Murphy 				       &bq->init_data.bypass_vlim);
1201*5069185fSDan Murphy 	if (ret)
1202*5069185fSDan Murphy 		bq->init_data.bypass_vlim = bq->chip_info->busovp_byp_def;
1203*5069185fSDan Murphy 
1204*5069185fSDan Murphy 	if (bq->init_data.bypass_vlim > bq->chip_info->busovp_byp_max ||
1205*5069185fSDan Murphy 	    bq->init_data.bypass_vlim < bq->chip_info->busovp_byp_min) {
1206*5069185fSDan Murphy 		dev_err(bq->dev, "Bypass ovp limit is out of range\n");
1207*5069185fSDan Murphy 		return -EINVAL;
1208*5069185fSDan Murphy 	}
1209*5069185fSDan Murphy 
1210*5069185fSDan Murphy 	ret = device_property_read_u32(bq->dev,
1211*5069185fSDan Murphy 				       "ti,bypass-ocp-limit-microamp",
1212*5069185fSDan Murphy 				       &bq->init_data.bypass_ilim);
1213*5069185fSDan Murphy 	if (ret)
1214*5069185fSDan Murphy 		bq->init_data.bypass_ilim = bq->chip_info->busocp_def;
1215*5069185fSDan Murphy 
1216*5069185fSDan Murphy 	if (bq->init_data.bypass_ilim > bq->chip_info->busocp_byp_max ||
1217*5069185fSDan Murphy 	    bq->init_data.bypass_ilim < bq->chip_info->busocp_byp_min) {
1218*5069185fSDan Murphy 		dev_err(bq->dev, "Bypass ocp limit is out of range\n");
1219*5069185fSDan Murphy 		return -EINVAL;
1220*5069185fSDan Murphy 	}
1221*5069185fSDan Murphy 
1222*5069185fSDan Murphy 
1223*5069185fSDan Murphy 	bq->state.bypass = device_property_read_bool(bq->dev,
1224*5069185fSDan Murphy 						      "ti,bypass-enable");
1225*5069185fSDan Murphy 	return 0;
1226*5069185fSDan Murphy }
1227*5069185fSDan Murphy 
1228*5069185fSDan Murphy static int bq25980_probe(struct i2c_client *client,
1229*5069185fSDan Murphy 			 const struct i2c_device_id *id)
1230*5069185fSDan Murphy {
1231*5069185fSDan Murphy 	struct device *dev = &client->dev;
1232*5069185fSDan Murphy 	struct bq25980_device *bq;
1233*5069185fSDan Murphy 	int ret;
1234*5069185fSDan Murphy 
1235*5069185fSDan Murphy 	bq = devm_kzalloc(dev, sizeof(*bq), GFP_KERNEL);
1236*5069185fSDan Murphy 	if (!bq)
1237*5069185fSDan Murphy 		return -ENOMEM;
1238*5069185fSDan Murphy 
1239*5069185fSDan Murphy 	bq->client = client;
1240*5069185fSDan Murphy 	bq->dev = dev;
1241*5069185fSDan Murphy 
1242*5069185fSDan Murphy 	mutex_init(&bq->lock);
1243*5069185fSDan Murphy 
1244*5069185fSDan Murphy 	strncpy(bq->model_name, id->name, I2C_NAME_SIZE);
1245*5069185fSDan Murphy 	bq->chip_info = &bq25980_chip_info_tbl[id->driver_data];
1246*5069185fSDan Murphy 
1247*5069185fSDan Murphy 	bq->regmap = devm_regmap_init_i2c(client,
1248*5069185fSDan Murphy 					  bq->chip_info->regmap_config);
1249*5069185fSDan Murphy 	if (IS_ERR(bq->regmap)) {
1250*5069185fSDan Murphy 		dev_err(dev, "Failed to allocate register map\n");
1251*5069185fSDan Murphy 		return PTR_ERR(bq->regmap);
1252*5069185fSDan Murphy 	}
1253*5069185fSDan Murphy 
1254*5069185fSDan Murphy 	i2c_set_clientdata(client, bq);
1255*5069185fSDan Murphy 
1256*5069185fSDan Murphy 	ret = bq25980_parse_dt(bq);
1257*5069185fSDan Murphy 	if (ret) {
1258*5069185fSDan Murphy 		dev_err(dev, "Failed to read device tree properties%d\n", ret);
1259*5069185fSDan Murphy 		return ret;
1260*5069185fSDan Murphy 	}
1261*5069185fSDan Murphy 
1262*5069185fSDan Murphy 	if (client->irq) {
1263*5069185fSDan Murphy 		ret = devm_request_threaded_irq(dev, client->irq, NULL,
1264*5069185fSDan Murphy 						bq25980_irq_handler_thread,
1265*5069185fSDan Murphy 						IRQF_TRIGGER_FALLING |
1266*5069185fSDan Murphy 						IRQF_ONESHOT,
1267*5069185fSDan Murphy 						dev_name(&client->dev), bq);
1268*5069185fSDan Murphy 		if (ret)
1269*5069185fSDan Murphy 			return ret;
1270*5069185fSDan Murphy 	}
1271*5069185fSDan Murphy 
1272*5069185fSDan Murphy 	ret = bq25980_power_supply_init(bq, dev);
1273*5069185fSDan Murphy 	if (ret) {
1274*5069185fSDan Murphy 		dev_err(dev, "Failed to register power supply\n");
1275*5069185fSDan Murphy 		return ret;
1276*5069185fSDan Murphy 	}
1277*5069185fSDan Murphy 
1278*5069185fSDan Murphy 	ret = bq25980_hw_init(bq);
1279*5069185fSDan Murphy 	if (ret) {
1280*5069185fSDan Murphy 		dev_err(dev, "Cannot initialize the chip.\n");
1281*5069185fSDan Murphy 		return ret;
1282*5069185fSDan Murphy 	}
1283*5069185fSDan Murphy 
1284*5069185fSDan Murphy 	return 0;
1285*5069185fSDan Murphy }
1286*5069185fSDan Murphy 
1287*5069185fSDan Murphy static const struct i2c_device_id bq25980_i2c_ids[] = {
1288*5069185fSDan Murphy 	{ "bq25980", BQ25980 },
1289*5069185fSDan Murphy 	{ "bq25975", BQ25975 },
1290*5069185fSDan Murphy 	{ "bq25975", BQ25975 },
1291*5069185fSDan Murphy 	{},
1292*5069185fSDan Murphy };
1293*5069185fSDan Murphy MODULE_DEVICE_TABLE(i2c, bq25980_i2c_ids);
1294*5069185fSDan Murphy 
1295*5069185fSDan Murphy static const struct of_device_id bq25980_of_match[] = {
1296*5069185fSDan Murphy 	{ .compatible = "ti,bq25980", .data = (void *)BQ25980 },
1297*5069185fSDan Murphy 	{ .compatible = "ti,bq25975", .data = (void *)BQ25975 },
1298*5069185fSDan Murphy 	{ .compatible = "ti,bq25960", .data = (void *)BQ25960 },
1299*5069185fSDan Murphy 	{ },
1300*5069185fSDan Murphy };
1301*5069185fSDan Murphy MODULE_DEVICE_TABLE(of, bq25980_of_match);
1302*5069185fSDan Murphy 
1303*5069185fSDan Murphy static struct i2c_driver bq25980_driver = {
1304*5069185fSDan Murphy 	.driver = {
1305*5069185fSDan Murphy 		.name = "bq25980-charger",
1306*5069185fSDan Murphy 		.of_match_table = bq25980_of_match,
1307*5069185fSDan Murphy 	},
1308*5069185fSDan Murphy 	.probe = bq25980_probe,
1309*5069185fSDan Murphy 	.id_table = bq25980_i2c_ids,
1310*5069185fSDan Murphy };
1311*5069185fSDan Murphy module_i2c_driver(bq25980_driver);
1312*5069185fSDan Murphy 
1313*5069185fSDan Murphy MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
1314*5069185fSDan Murphy MODULE_AUTHOR("Ricardo Rivera-Matos <r-rivera-matos@ti.com>");
1315*5069185fSDan Murphy MODULE_DESCRIPTION("bq25980 charger driver");
1316*5069185fSDan Murphy MODULE_LICENSE("GPL v2");
1317