xref: /OK3568_Linux_fs/u-boot/drivers/power/charge/bq25700_charger.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <asm/gpio.h>
9*4882a593Smuzhiyun #include <dm/device.h>
10*4882a593Smuzhiyun #include <dm/uclass.h>
11*4882a593Smuzhiyun #include <power/fuel_gauge.h>
12*4882a593Smuzhiyun #include <power/pmic.h>
13*4882a593Smuzhiyun #include <power/power_delivery/power_delivery.h>
14*4882a593Smuzhiyun #include <linux/usb/phy-rockchip-usb2.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #define BQ25700_ID				0x25700
19*4882a593Smuzhiyun #define BQ25703_ID				0x25703
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #define COMPAT_BQ25700				"ti,bq25700"
22*4882a593Smuzhiyun #define COMPAT_BQ25703				"ti,bq25703"
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #define BQ25700_I2C_SPEED			100000
25*4882a593Smuzhiyun #define BQ25700_CHARGE_CURRENT_1500MA		0x5C0
26*4882a593Smuzhiyun #define BQ25700_SDP_INPUT_CURRENT_500MA		0xA00
27*4882a593Smuzhiyun #define BQ25700_DCP_INPUT_CURRENT_1500MA	0x1E00
28*4882a593Smuzhiyun #define BQ25700_DCP_INPUT_CURRENT_2000MA	0x2800
29*4882a593Smuzhiyun #define BQ25700_DCP_INPUT_CURRENT_3000MA	0x3C00
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define WATCHDOG_ENSABLE			(0x03 << 13)
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define BQ25700_CHARGEOPTION0_REG		0x12
34*4882a593Smuzhiyun #define BQ25700_CHARGECURREN_REG		0x14
35*4882a593Smuzhiyun #define BQ25700_CHARGERSTAUS_REG		0x20
36*4882a593Smuzhiyun #define BQ25700_INPUTVOLTAGE_REG		0x3D
37*4882a593Smuzhiyun #define BQ25700_INPUTCURREN_REG			0x3F
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define BQ25703_CHARGEOPTION0_REG		0x00
40*4882a593Smuzhiyun #define BQ25703_CHARGECURREN_REG		0x02
41*4882a593Smuzhiyun #define BQ25703_CHARGERSTAUS_REG		0x20
42*4882a593Smuzhiyun #define BQ25703_INPUTVOLTAGE_REG		0x0A
43*4882a593Smuzhiyun #define BQ25703_INPUTCURREN_REG			0x0E
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun enum bq25700_table_ids {
46*4882a593Smuzhiyun 	/* range tables */
47*4882a593Smuzhiyun 	TBL_ICHG,
48*4882a593Smuzhiyun 	TBL_CHGMAX,
49*4882a593Smuzhiyun 	TBL_INPUTVOL,
50*4882a593Smuzhiyun 	TBL_INPUTCUR,
51*4882a593Smuzhiyun 	TBL_SYSVMIN,
52*4882a593Smuzhiyun 	TBL_OTGVOL,
53*4882a593Smuzhiyun 	TBL_OTGCUR,
54*4882a593Smuzhiyun 	TBL_EXTCON,
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun struct bq25700 {
58*4882a593Smuzhiyun 	struct udevice *dev;
59*4882a593Smuzhiyun 	u32 ichg;
60*4882a593Smuzhiyun 	u32 chip_id;
61*4882a593Smuzhiyun 	struct udevice *pd;
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun struct bq25700_range {
65*4882a593Smuzhiyun 	u32 min;
66*4882a593Smuzhiyun 	u32 max;
67*4882a593Smuzhiyun 	u32 step;
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun 
bq25700_read(struct bq25700 * charger,uint reg)70*4882a593Smuzhiyun static int bq25700_read(struct bq25700 *charger, uint reg)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	u16 val;
73*4882a593Smuzhiyun 	int ret;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	ret = dm_i2c_read(charger->dev, reg, (u8 *)&val, 2);
76*4882a593Smuzhiyun 	if (ret) {
77*4882a593Smuzhiyun 		debug("write error to device: %p register: %#x!",
78*4882a593Smuzhiyun 		      charger->dev, reg);
79*4882a593Smuzhiyun 		return ret;
80*4882a593Smuzhiyun 	}
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	return val;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
bq25700_write(struct bq25700 * charger,uint reg,u16 val)85*4882a593Smuzhiyun static int bq25700_write(struct bq25700 *charger, uint reg, u16 val)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	int ret;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	ret = dm_i2c_write(charger->dev, reg, (u8 *)&val, 2);
90*4882a593Smuzhiyun 	if (ret) {
91*4882a593Smuzhiyun 		debug("write error to device: %p register: %#x!",
92*4882a593Smuzhiyun 		      charger->dev, reg);
93*4882a593Smuzhiyun 		return ret;
94*4882a593Smuzhiyun 	}
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	return 0;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun static const union {
100*4882a593Smuzhiyun 	struct bq25700_range  rt;
101*4882a593Smuzhiyun } bq25700_tables[] = {
102*4882a593Smuzhiyun 	/* range tables */
103*4882a593Smuzhiyun 	[TBL_ICHG] = { .rt = {0, 8128000, 64000} },
104*4882a593Smuzhiyun 	/* uV */
105*4882a593Smuzhiyun 	[TBL_CHGMAX] = { .rt = {0, 19200000, 16000} },
106*4882a593Smuzhiyun 	/* uV  max charge voltage*/
107*4882a593Smuzhiyun 	[TBL_INPUTVOL] = { .rt = {3200000, 19520000, 64000} },
108*4882a593Smuzhiyun 	/* uV  input charge voltage*/
109*4882a593Smuzhiyun 	[TBL_INPUTCUR] = {.rt = {0, 6350000, 50000} },
110*4882a593Smuzhiyun 	/*uA input current*/
111*4882a593Smuzhiyun 	[TBL_SYSVMIN] = { .rt = {1024000, 16182000, 256000} },
112*4882a593Smuzhiyun 	/* uV min system voltage*/
113*4882a593Smuzhiyun 	[TBL_OTGVOL] = {.rt = {4480000, 20800000, 64000} },
114*4882a593Smuzhiyun 	/*uV OTG volage*/
115*4882a593Smuzhiyun 	[TBL_OTGCUR] = {.rt = {0, 6350000, 50000} },
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun 
bq25700_find_idx(u32 value,enum bq25700_table_ids id)118*4882a593Smuzhiyun static u32 bq25700_find_idx(u32 value, enum bq25700_table_ids id)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	const struct bq25700_range *rtbl = &bq25700_tables[id].rt;
121*4882a593Smuzhiyun 	u32 rtbl_size;
122*4882a593Smuzhiyun 	u32 idx;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	rtbl_size = (rtbl->max - rtbl->min) / rtbl->step + 1;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	for (idx = 1;
127*4882a593Smuzhiyun 	     idx < rtbl_size && (idx * rtbl->step + rtbl->min <= value);
128*4882a593Smuzhiyun 	     idx++)
129*4882a593Smuzhiyun 		;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	return idx - 1;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun 
bq25700_charger_status(struct bq25700 * charger)134*4882a593Smuzhiyun static bool bq25700_charger_status(struct bq25700 *charger)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun 	int state_of_charger;
137*4882a593Smuzhiyun 	u16 value;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	value = bq25700_read(charger, BQ25700_CHARGERSTAUS_REG);
140*4882a593Smuzhiyun 	state_of_charger = value >> 15;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	return state_of_charger;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
bq25703_charger_status(struct bq25700 * charger)145*4882a593Smuzhiyun static bool bq25703_charger_status(struct bq25700 *charger)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	int state_of_charger;
148*4882a593Smuzhiyun 	u16 value;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	value = bq25700_read(charger, BQ25703_CHARGERSTAUS_REG);
151*4882a593Smuzhiyun 	state_of_charger = value >> 15;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	return state_of_charger;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
bq257xx_charger_status(struct udevice * dev)156*4882a593Smuzhiyun static bool bq257xx_charger_status(struct udevice *dev)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun 	struct bq25700 *charger = dev_get_priv(dev);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	if (charger->chip_id == BQ25700_ID)
161*4882a593Smuzhiyun 		return bq25700_charger_status(charger);
162*4882a593Smuzhiyun 	else
163*4882a593Smuzhiyun 		return bq25703_charger_status(charger);
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
bq25700_charger_capability(struct udevice * dev)166*4882a593Smuzhiyun static int bq25700_charger_capability(struct udevice *dev)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	return FG_CAP_CHARGER;
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun 
bq25700_get_usb_type(void)171*4882a593Smuzhiyun static int bq25700_get_usb_type(void)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun #ifdef CONFIG_PHY_ROCKCHIP_INNO_USB2
174*4882a593Smuzhiyun 	return rockchip_chg_get_type();
175*4882a593Smuzhiyun #else
176*4882a593Smuzhiyun 	return 0;
177*4882a593Smuzhiyun #endif
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun 
bq25700_get_pd_output_val(struct bq25700 * charger,int * vol,int * cur)180*4882a593Smuzhiyun static int bq25700_get_pd_output_val(struct bq25700 *charger,
181*4882a593Smuzhiyun 				     int *vol, int *cur)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun 	struct power_delivery_data pd_data;
184*4882a593Smuzhiyun 	int ret;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	if (!charger->pd)
187*4882a593Smuzhiyun 		return -EINVAL;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	memset(&pd_data, 0, sizeof(pd_data));
190*4882a593Smuzhiyun 	ret = power_delivery_get_data(charger->pd, &pd_data);
191*4882a593Smuzhiyun 	if (ret)
192*4882a593Smuzhiyun 		return ret;
193*4882a593Smuzhiyun 	if (!pd_data.online || !pd_data.voltage || !pd_data.current)
194*4882a593Smuzhiyun 		return -EINVAL;
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	*vol = pd_data.voltage;
197*4882a593Smuzhiyun 	*cur = pd_data.current;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	return 0;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun 
bq25700_charger_current_init(struct bq25700 * charger)202*4882a593Smuzhiyun static void bq25700_charger_current_init(struct bq25700 *charger)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	u16 charge_current = BQ25700_CHARGE_CURRENT_1500MA;
205*4882a593Smuzhiyun 	u16 sdp_inputcurrent = BQ25700_SDP_INPUT_CURRENT_500MA;
206*4882a593Smuzhiyun 	u16 dcp_inputcurrent = BQ25700_DCP_INPUT_CURRENT_1500MA;
207*4882a593Smuzhiyun 	int pd_inputvol, pd_inputcurrent;
208*4882a593Smuzhiyun 	u16 vol_idx = 0, cur_idx;
209*4882a593Smuzhiyun 	u16 temp;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	temp = bq25700_read(charger, BQ25700_CHARGEOPTION0_REG);
212*4882a593Smuzhiyun 	temp &= (~WATCHDOG_ENSABLE);
213*4882a593Smuzhiyun 	bq25700_write(charger, BQ25700_CHARGEOPTION0_REG, temp);
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	if (!bq25700_get_pd_output_val(charger, &pd_inputvol,
216*4882a593Smuzhiyun 				       &pd_inputcurrent)) {
217*4882a593Smuzhiyun 		printf("%s pd charge input vol:%duv current:%dua\n",
218*4882a593Smuzhiyun 		       __func__, pd_inputvol, pd_inputcurrent);
219*4882a593Smuzhiyun 		if (pd_inputvol > 5000000) {
220*4882a593Smuzhiyun 			vol_idx = bq25700_find_idx((pd_inputvol - 1280000 - 3200000),
221*4882a593Smuzhiyun 						   TBL_INPUTVOL);
222*4882a593Smuzhiyun 			vol_idx = vol_idx << 6;
223*4882a593Smuzhiyun 		}
224*4882a593Smuzhiyun 		cur_idx = bq25700_find_idx(pd_inputcurrent,
225*4882a593Smuzhiyun 					   TBL_INPUTCUR);
226*4882a593Smuzhiyun 		cur_idx  = cur_idx << 8;
227*4882a593Smuzhiyun 		if (pd_inputcurrent != 0) {
228*4882a593Smuzhiyun 			bq25700_write(charger, BQ25700_INPUTCURREN_REG,
229*4882a593Smuzhiyun 				      cur_idx);
230*4882a593Smuzhiyun 			if (vol_idx)
231*4882a593Smuzhiyun 				bq25700_write(charger, BQ25700_INPUTVOLTAGE_REG,
232*4882a593Smuzhiyun 					      vol_idx);
233*4882a593Smuzhiyun 			charge_current = bq25700_find_idx(charger->ichg,
234*4882a593Smuzhiyun 							  TBL_ICHG);
235*4882a593Smuzhiyun 			charge_current = charge_current << 8;
236*4882a593Smuzhiyun 		}
237*4882a593Smuzhiyun 	} else {
238*4882a593Smuzhiyun 		if (bq25700_get_usb_type() > 1)
239*4882a593Smuzhiyun 			bq25700_write(charger, BQ25700_INPUTCURREN_REG,
240*4882a593Smuzhiyun 				      dcp_inputcurrent);
241*4882a593Smuzhiyun 		else
242*4882a593Smuzhiyun 			bq25700_write(charger, BQ25700_INPUTCURREN_REG,
243*4882a593Smuzhiyun 				      sdp_inputcurrent);
244*4882a593Smuzhiyun 	}
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	if (bq25700_charger_status(charger))
247*4882a593Smuzhiyun 		bq25700_write(charger, BQ25700_CHARGECURREN_REG,
248*4882a593Smuzhiyun 			      charge_current);
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun 
bq25703_charger_current_init(struct bq25700 * charger)251*4882a593Smuzhiyun static void bq25703_charger_current_init(struct bq25700 *charger)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun 	u16 charge_current = BQ25700_CHARGE_CURRENT_1500MA;
254*4882a593Smuzhiyun 	u16 sdp_inputcurrent = BQ25700_SDP_INPUT_CURRENT_500MA;
255*4882a593Smuzhiyun 	u16 dcp_inputcurrent = BQ25700_DCP_INPUT_CURRENT_1500MA;
256*4882a593Smuzhiyun 	int pd_inputvol,  pd_inputcurrent;
257*4882a593Smuzhiyun 	u16 vol_idx = 0, cur_idx;
258*4882a593Smuzhiyun 	u16 temp;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	temp = bq25700_read(charger, BQ25703_CHARGEOPTION0_REG);
261*4882a593Smuzhiyun 	temp &= (~WATCHDOG_ENSABLE);
262*4882a593Smuzhiyun 	bq25700_write(charger, BQ25703_CHARGEOPTION0_REG, temp);
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	if (!bq25700_get_pd_output_val(charger, &pd_inputvol,
265*4882a593Smuzhiyun 				       &pd_inputcurrent)) {
266*4882a593Smuzhiyun 		printf("%s pd charge input vol:%duv current:%dua\n",
267*4882a593Smuzhiyun 		       __func__, pd_inputvol, pd_inputcurrent);
268*4882a593Smuzhiyun 		if (pd_inputvol > 5000000) {
269*4882a593Smuzhiyun 			vol_idx = bq25700_find_idx(pd_inputvol - 1280000 - 3200000,
270*4882a593Smuzhiyun 						   TBL_INPUTVOL);
271*4882a593Smuzhiyun 			vol_idx = vol_idx << 6;
272*4882a593Smuzhiyun 		}
273*4882a593Smuzhiyun 		cur_idx = bq25700_find_idx(pd_inputcurrent,
274*4882a593Smuzhiyun 					   TBL_INPUTCUR);
275*4882a593Smuzhiyun 		cur_idx  = cur_idx << 8;
276*4882a593Smuzhiyun 		if (pd_inputcurrent != 0) {
277*4882a593Smuzhiyun 			bq25700_write(charger, BQ25703_INPUTCURREN_REG,
278*4882a593Smuzhiyun 				      cur_idx);
279*4882a593Smuzhiyun 			if (vol_idx)
280*4882a593Smuzhiyun 				bq25700_write(charger, BQ25703_INPUTVOLTAGE_REG,
281*4882a593Smuzhiyun 					      vol_idx);
282*4882a593Smuzhiyun 			charge_current = bq25700_find_idx(charger->ichg,
283*4882a593Smuzhiyun 							  TBL_ICHG);
284*4882a593Smuzhiyun 			charge_current = charge_current << 8;
285*4882a593Smuzhiyun 		}
286*4882a593Smuzhiyun 	} else {
287*4882a593Smuzhiyun 		if (bq25700_get_usb_type() > 1)
288*4882a593Smuzhiyun 			bq25700_write(charger, BQ25703_INPUTCURREN_REG,
289*4882a593Smuzhiyun 				      dcp_inputcurrent);
290*4882a593Smuzhiyun 		else
291*4882a593Smuzhiyun 			bq25700_write(charger, BQ25703_INPUTCURREN_REG,
292*4882a593Smuzhiyun 				      sdp_inputcurrent);
293*4882a593Smuzhiyun 	}
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	if (bq25703_charger_status(charger))
296*4882a593Smuzhiyun 		bq25700_write(charger, BQ25703_CHARGECURREN_REG,
297*4882a593Smuzhiyun 			      charge_current);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun 
bq25700_ofdata_to_platdata(struct udevice * dev)300*4882a593Smuzhiyun static int bq25700_ofdata_to_platdata(struct udevice *dev)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	struct bq25700 *charger = dev_get_priv(dev);
303*4882a593Smuzhiyun 	const void *blob = gd->fdt_blob;
304*4882a593Smuzhiyun 	int node, node1;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	charger->dev = dev;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	node = fdt_node_offset_by_compatible(blob, 0, COMPAT_BQ25700);
309*4882a593Smuzhiyun 	node1 = fdt_node_offset_by_compatible(blob, 0, COMPAT_BQ25703);
310*4882a593Smuzhiyun 	if ((node < 0) && (node1 < 0)) {
311*4882a593Smuzhiyun 		printf("Can't find dts node for charger bq25700\n");
312*4882a593Smuzhiyun 		return -ENODEV;
313*4882a593Smuzhiyun 	}
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	if (node < 0) {
316*4882a593Smuzhiyun 		node = node1;
317*4882a593Smuzhiyun 		charger->chip_id = BQ25703_ID;
318*4882a593Smuzhiyun 	} else {
319*4882a593Smuzhiyun 		charger->chip_id = BQ25700_ID;
320*4882a593Smuzhiyun 	}
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	charger->ichg = fdtdec_get_int(blob, node, "ti,charge-current", 0);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	return 0;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun 
bq25700_probe(struct udevice * dev)327*4882a593Smuzhiyun static int bq25700_probe(struct udevice *dev)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun 	struct bq25700 *charger = dev_get_priv(dev);
330*4882a593Smuzhiyun 	int ret;
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	ret = uclass_get_device(UCLASS_PD, 0, &charger->pd);
333*4882a593Smuzhiyun 	if (ret) {
334*4882a593Smuzhiyun 		if (ret == -ENODEV)
335*4882a593Smuzhiyun 			printf("Can't find PMIC\n");
336*4882a593Smuzhiyun 		else
337*4882a593Smuzhiyun 			printf("Get UCLASS PMIC failed: %d\n", ret);
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 		charger->pd = NULL;
340*4882a593Smuzhiyun 	}
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	if (charger->chip_id == BQ25700_ID)
343*4882a593Smuzhiyun 		bq25700_charger_current_init(charger);
344*4882a593Smuzhiyun 	else
345*4882a593Smuzhiyun 		bq25703_charger_current_init(charger);
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	return 0;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun static const struct udevice_id charger_ids[] = {
351*4882a593Smuzhiyun 	{ .compatible = "ti,bq25700" },
352*4882a593Smuzhiyun 	{ .compatible = "ti,bq25703" },
353*4882a593Smuzhiyun 	{ },
354*4882a593Smuzhiyun };
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun static struct dm_fuel_gauge_ops charger_ops = {
357*4882a593Smuzhiyun 	.get_chrg_online = bq257xx_charger_status,
358*4882a593Smuzhiyun 	.capability = bq25700_charger_capability,
359*4882a593Smuzhiyun };
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun U_BOOT_DRIVER(bq25700_charger) = {
362*4882a593Smuzhiyun 	.name = "bq25700_charger",
363*4882a593Smuzhiyun 	.id = UCLASS_FG,
364*4882a593Smuzhiyun 	.probe = bq25700_probe,
365*4882a593Smuzhiyun 	.of_match = charger_ids,
366*4882a593Smuzhiyun 	.ops = &charger_ops,
367*4882a593Smuzhiyun 	.ofdata_to_platdata = bq25700_ofdata_to_platdata,
368*4882a593Smuzhiyun 	.priv_auto_alloc_size = sizeof(struct bq25700),
369*4882a593Smuzhiyun };
370