xref: /rk3399_rockchip-uboot/drivers/power/charge/cps5601x_charger.c (revision eb1192571a2b484fac8c2800cbb59ca145637fa2)
1 /*
2  * (C) Copyright 2025 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <dm.h>
9 #include <i2c.h>
10 #include <irq-generic.h>
11 #include <power/fuel_gauge.h>
12 #include <linux/usb/phy-rockchip-usb2.h>
13 #include <power/power_delivery/power_delivery.h>
14 
15 DECLARE_GLOBAL_DATA_PTR;
16 
17 static int dbg_enable;
18 
19 #define CPS_DBG(args...) \
20 	do { \
21 		if (dbg_enable) { \
22 			printf(args); \
23 		} \
24 	} while (0)
25 
26 #define UPDATE(x, h, l)			(((x) << (l)) & GENMASK((h), (l)))
27 
28 /* Register 00h */
29 #define CPS5601X_REG_00			0x00
30 #define CPS5601X_PRODUCT_ID_MASK	GENMASK(7, 0)
31 /* default 0xA9=CPS5601 */
32 
33 /* Register 01h */
34 #define CPS5601X_REG_01			0x01
35 
36 /* Register 02h */
37 #define CPS5601X_REG_02			0x02
38 
39 /* Register 03h */
40 #define CPS5601X_REG_03			0x03
41 #define VREG_MASK			GENMASK(6, 0)
42 #define VREG_BASE			3600000
43 #define VREG_LSB			10000
44 #define VREG_MAXVAL			0x6e
45 
46 /* Register 04h */
47 #define CPS5601X_REG_04			0x04
48 #define ICHG_MASK			GENMASK(6, 0)
49 #define ICHG_BASE			0
50 #define ICHG_LSB			25000
51 #define ICHG_MINVAL			0x4
52 #define ICHG_MAXVAL			0x78
53 
54 /* Register 05h */
55 #define CPS5601X_REG_05			0x05
56 #define EN_TERM_MASK			BIT(6)
57 #define EN_TERM_ENABLE(x)		UPDATE(x, 6, 6)
58 #define IPRECHG_MASK			GENMASK(5, 0)
59 #define IPRECHG_BASE			0
60 #define IPRECHG_LSB			12500
61 #define IPRECHG_MINVAL			0x1
62 #define IPRECHG_MAXVAL			0x3c
63 
64 /* Register 06h */
65 #define CPS5601X_REG_06			0x06
66 #define ITERM_MASK			GENMASK(5, 0)
67 #define ITERM_BASE			0
68 #define ITERM_LSB			10000
69 #define ITERM_MINVAL			0x5
70 #define ITERM_MAXVAL			0x3c
71 
72 /* Register 07h */
73 #define CPS5601X_REG_07			0x07
74 #define VINDPM_MASK			GENMASK(5, 0)
75 #define VINDPM_BASE			3400000
76 #define VINDPM_LSB			100000
77 #define VINDPM_MINVAL			0x4
78 #define VINDPM_MAXVAL			0x3e
79 
80 /* Register 08h */
81 #define CPS5601X_REG_08			0x08
82 #define IINDPM_MASK			GENMASK(5, 0)
83 #define IINDPM_BASE			50000
84 #define IINDPM_LSB			50000
85 #define IINDPM_MINVAL			0x1
86 
87 /* Register 09h */
88 #define CPS5601X_REG_09			0x09
89 #define VOTG_MASK			GENMASK(5, 0)
90 #define VOTG_BASE			3400000
91 #define VOTG_LSB			100000
92 #define VOTG_MAXVAL			0x3e
93 
94 /* Register 0Ah */
95 #define CPS5601X_REG_0A			0x0A
96 #define IOTG_MASK			GENMASK(5, 0)
97 #define IOTG_BASE			50000
98 #define IOTG_LSB			50000
99 #define IOTG_MINVAL			0x1
100 
101 /* Register 0Bh */
102 #define CPS5601X_REG_0B			0x0B
103 #define WATCHDOG_MASK			GENMASK(7, 6)
104 #define WATCHDOG_TIME(x)		UPDATE(x, 7, 6)
105 #define WATCHDOG_BASE			0
106 #define WATCHDOG_LSB			40
107 #define WD_RST_MASK			BIT(5)
108 #define WD_RST(x)			UPDATE(x, 5, 5)
109 #define EN_CHG_MASK			BIT(3)
110 #define EN_CHG(x)			UPDATE(x, 3, 3)
111 
112 /* Register 0Ch */
113 #define CPS5601X_REG_0C			0x0C
114 #define EN_OTG_MASK			BIT(3)
115 #define EN_OTG(x)			UPDATE(x, 3, 3)
116 
117 /* Register 0Dh */
118 #define CPS5601X_REG_0D			0x0D
119 
120 /* Register 0Eh */
121 #define CPS5601X_REG_0E			0x0E
122 #define TS_IGNORE_MASK			BIT(0)
123 #define EN_TS_IGNORE(x)			UPDATE(x, 0, 0)
124 
125 /* Register 0Fh */
126 #define CPS5601X_REG_0F			0x0F
127 #define PG_STAT_MASK			BIT(3)
128 
129 /* Register 10h */
130 #define CPS5601X_REG_10			0x10
131 #define CHG_STAT_MASK			GENMASK(7, 5)
132 #define CHG_STAT_SHIFT			5
133 #define CHG_STAT_NOTCHG			0
134 #define CHG_STAT_TRICKLECHG		1
135 #define CHG_STAT_PRECHG			2
136 #define CHG_STAT_FASTCHG		3
137 #define CHG_STAT_TAPERCHG		4
138 #define CHG_STAT_RESERVED		5
139 #define CHG_STAT_TOTACHG		6
140 #define CHG_STAT_CHGTERM		7
141 #define VBUS_STAT_MASK			GENMASK(4, 1)
142 #define VBUS_STAT_SHIFT			1
143 #define VBUS_STAT_NOT			0
144 #define VBUS_STAT_USBSDP		1
145 #define VBUS_STAT_USBCDP		2
146 #define VBUS_STAT_USBDCP		3
147 #define VBUS_STAT_HVDCP			4
148 #define VBUS_STAT_UNKNOWN		5
149 #define VBUS_STAT_NONSTANDARD		6
150 #define VBUS_STAT_OTGMODE		7
151 #define VBUS_STAT_NOTQUALIFIED		8
152 
153 /* Register 11h */
154 #define CPS5601X_REG_11			0x11
155 
156 /* Register 12h */
157 #define CPS5601X_REG_12			0x12
158 
159 /* Register 13h */
160 #define CPS5601X_REG_13			0x13
161 
162 /* Register 14h */
163 #define CPS5601X_REG_14			0x14
164 
165 /* Register 15h */
166 #define CPS5601X_REG_15			0x15
167 
168 /* Register 16h */
169 #define CPS5601X_REG_16			0x16
170 
171 /* Register 17h */
172 #define CPS5601X_REG_17			0x17
173 
174 /* Register 18h */
175 #define CPS5601X_REG_18			0x18
176 
177 /* Register 19h */
178 #define CPS5601X_REG_19			0x19
179 #define TREG_MK_MASK			BIT(7)
180 
181 /* Register 1Ah */
182 #define CPS5601X_REG_1A			0x1A
183 
184 /* Register 1Bh */
185 #define CPS5601X_REG_1B			0x1B
186 
187 #define CPS5601X_ICHRG_I_DEF_uA		2040000
188 #define CPS5601X_VREG_V_DEF_uV		4208000
189 #define CPS5601X_PRECHRG_I_DEF_uA	180000
190 #define CPS5601X_TERMCHRG_I_DEF_uA	180000
191 #define CPS5601X_ICHRG_I_MIN_uA		100000
192 #define CPS5601X_ICHRG_I_MAX_uA		3000000
193 #define CPS5601X_VINDPM_DEF_uV		4500000
194 #define CPS5601X_VINDPM_V_MIN_uV	3800000
195 #define CPS5601X_VINDPM_V_MAX_uV	9600000
196 #define CPS5601X_IINDPM_DEF_uA		2400000
197 #define CPS5601X_IINDPM_I_MIN_uA	100000
198 #define CPS5601X_IINDPM_I_MAX_uA	3200000
199 #define DEFAULT_INPUT_CURRENT		(500 * 1000)
200 
201 struct cps5601x {
202 	struct udevice *dev;
203 	struct udevice *pd;
204 	bool pd_online;
205 	u32 init_count;
206 	u32 ichg;
207 	u32 vchg;
208 	int irq;
209 };
210 
211 enum power_supply_type {
212 	POWER_SUPPLY_TYPE_UNKNOWN = 0,
213 	POWER_SUPPLY_TYPE_USB,          /* Standard Downstream Port */
214 	POWER_SUPPLY_TYPE_USB_DCP,      /* Dedicated Charging Port */
215 	POWER_SUPPLY_TYPE_USB_CDP,      /* Charging Downstream Port */
216 	POWER_SUPPLY_TYPE_USB_FLOATING, /* DCP without shorting D+/D- */
217 };
218 
cps5601x_read(struct cps5601x * charger,uint reg,u8 * buffer)219 static int cps5601x_read(struct cps5601x *charger, uint reg, u8 *buffer)
220 {
221 	u8 val;
222 	int ret;
223 
224 	ret = dm_i2c_read(charger->dev, reg, &val, 1);
225 	if (ret) {
226 		printf("cps5601x: read %#x error, ret=%d", reg, ret);
227 		return ret;
228 	}
229 
230 	*buffer = val;
231 
232 	return 0;
233 }
234 
cps5601x_write(struct cps5601x * charger,uint reg,u8 val)235 static int cps5601x_write(struct cps5601x *charger, uint reg, u8 val)
236 {
237 	int ret;
238 
239 	ret = dm_i2c_write(charger->dev, reg, &val, 1);
240 	if (ret)
241 		printf("cps5601x: write %#x error, ret=%d", reg, ret);
242 
243 	return ret;
244 }
245 
cps5601x_update_bits(struct cps5601x * charger,u8 offset,u8 mask,u8 val)246 static int cps5601x_update_bits(struct cps5601x *charger,
247 				u8 offset,
248 				u8 mask,
249 				u8 val)
250 {
251 	u8 reg;
252 	int ret;
253 
254 	ret = cps5601x_read(charger, offset, &reg);
255 	if (ret)
256 		return ret;
257 
258 	reg &= ~mask;
259 
260 	return cps5601x_write(charger, offset, reg | val);
261 }
262 
cps5601x_set_input_current_limit(struct cps5601x * cps,int curr)263 static int cps5601x_set_input_current_limit(struct cps5601x *cps, int curr)
264 {
265 	u8 val;
266 
267 	if (curr < IINDPM_BASE + (IINDPM_MINVAL * IINDPM_LSB))
268 		curr = IINDPM_BASE + (IINDPM_MINVAL * IINDPM_LSB);
269 
270 	val = (curr - IINDPM_BASE) / IINDPM_LSB;
271 
272 	return cps5601x_update_bits(cps, CPS5601X_REG_08, IINDPM_MASK, val);
273 }
274 
cps5601x_get_usb_type(void)275 static int cps5601x_get_usb_type(void)
276 {
277 #ifdef CONFIG_PHY_ROCKCHIP_INNO_USB2
278 	return rockchip_chg_get_type();
279 #else
280 	return 0;
281 #endif
282 }
283 
cps5601x_charger_capability(struct udevice * dev)284 static int cps5601x_charger_capability(struct udevice *dev)
285 {
286 	return FG_CAP_CHARGER;
287 }
288 
cps5601x_set_chargecurrent(struct cps5601x * cps,int curr)289 static int cps5601x_set_chargecurrent(struct cps5601x *cps, int curr)
290 {
291 	u8 ichg;
292 
293 	if (curr < (ICHG_BASE + (ICHG_MINVAL * ICHG_LSB)))
294 		curr = ICHG_BASE + (ICHG_MINVAL * ICHG_LSB);
295 	else if (curr > (ICHG_BASE + (ICHG_MAXVAL * ICHG_LSB)))
296 		curr = ICHG_BASE + (ICHG_MAXVAL * ICHG_LSB);
297 
298 	ichg = (curr - ICHG_BASE) / ICHG_LSB;
299 
300 	return cps5601x_update_bits(cps, CPS5601X_REG_04, ICHG_MASK, ichg);
301 }
302 
cps5601x_set_iprechg(struct cps5601x * cps,int curr)303 static int cps5601x_set_iprechg(struct cps5601x *cps, int curr)
304 {
305 	u8 iprechg;
306 
307 	if (curr < (IPRECHG_BASE + (IPRECHG_MINVAL * IPRECHG_LSB)))
308 		curr = IPRECHG_BASE + (IPRECHG_MINVAL * IPRECHG_LSB);
309 	else if (curr > (IPRECHG_BASE + (IPRECHG_MAXVAL * IPRECHG_LSB)))
310 		curr = IPRECHG_BASE + (IPRECHG_MAXVAL * IPRECHG_LSB);
311 
312 	iprechg = (curr - IPRECHG_BASE) / IPRECHG_LSB;
313 
314 	return cps5601x_update_bits(cps, CPS5601X_REG_05, IPRECHG_MASK,
315 				    iprechg);
316 }
317 
cps5601x_set_chargevolt(struct cps5601x * cps,int volt)318 static int cps5601x_set_chargevolt(struct cps5601x *cps, int volt)
319 {
320 	u8 val;
321 
322 	if (volt < VREG_BASE)
323 		volt = VREG_BASE;
324 	else if (volt > (VREG_BASE + (VREG_MAXVAL * VREG_LSB)))
325 		volt = VREG_BASE + (VREG_MAXVAL * VREG_LSB);
326 
327 	val = (volt - VREG_BASE) / VREG_LSB;
328 
329 	return cps5601x_update_bits(cps, CPS5601X_REG_03, VREG_MASK, val);
330 }
331 
cps5601x_set_charger_voltage(struct udevice * dev,int uV)332 static int cps5601x_set_charger_voltage(struct udevice *dev, int uV)
333 {
334 	struct cps5601x *charger = dev_get_priv(dev);
335 
336 	CPS_DBG("CPS5601X: charger voltage %d\n", uV);
337 	return cps5601x_set_chargevolt(charger, uV);
338 }
339 
cps5601x_charger_enable(struct udevice * dev)340 static int cps5601x_charger_enable(struct udevice *dev)
341 {
342 	struct cps5601x *charger = dev_get_priv(dev);
343 
344 	CPS_DBG("CPS5601X: charger enable\n");
345 	return cps5601x_update_bits(charger, CPS5601X_REG_0B, EN_CHG_MASK,
346 				    EN_CHG(1));
347 }
348 
cps5601x_charger_disable(struct udevice * dev)349 static int cps5601x_charger_disable(struct udevice *dev)
350 {
351 	struct cps5601x *charger = dev_get_priv(dev);
352 
353 	CPS_DBG("CPS5601X: charger disable\n");
354 	return cps5601x_update_bits(charger, CPS5601X_REG_0B, EN_CHG_MASK,
355 				    EN_CHG(0));
356 }
357 
cps5601x_iprechg_current(struct udevice * dev,int iprechrg_uA)358 static int cps5601x_iprechg_current(struct udevice *dev, int iprechrg_uA)
359 {
360 	struct cps5601x *charger = dev_get_priv(dev);
361 
362 	CPS_DBG("CPS5601x: charger current:iprechrg_uA: %d\n",
363 		iprechrg_uA);
364 
365 	return cps5601x_set_iprechg(charger, iprechrg_uA);
366 }
367 
cps5601x_charger_current(struct udevice * dev,int ichrg_uA)368 static int cps5601x_charger_current(struct udevice *dev, int ichrg_uA)
369 {
370 	struct cps5601x *charger = dev_get_priv(dev);
371 
372 	CPS_DBG("CPS5601X: charger current:ichrg_uA%d\n",
373 		ichrg_uA);
374 
375 	return cps5601x_set_chargecurrent(charger, ichrg_uA);
376 }
377 
cps5601x_get_pd_output_val(struct cps5601x * charger,int * vol,int * cur)378 static int cps5601x_get_pd_output_val(struct cps5601x *charger,
379 				      int *vol,
380 				      int *cur)
381 {
382 	struct power_delivery_data pd_data;
383 	int ret;
384 
385 	if (!charger->pd)
386 		return -EINVAL;
387 
388 	memset(&pd_data, 0, sizeof(pd_data));
389 	ret = power_delivery_get_data(charger->pd, &pd_data);
390 	if (ret)
391 		return ret;
392 	if (!pd_data.online || !pd_data.voltage || !pd_data.current)
393 		return -EINVAL;
394 
395 	*vol = pd_data.voltage;
396 	*cur = pd_data.current;
397 	charger->pd_online = pd_data.online;
398 
399 	return 0;
400 }
401 
cps5601x_charger_input_current_init(struct cps5601x * charger)402 static void cps5601x_charger_input_current_init(struct cps5601x *charger)
403 {
404 	int sdp_inputcurrent = 500 * 1000;
405 	int dcp_inputcurrent = 2000 * 1000;
406 	int pd_inputvol, pd_inputcurrent;
407 	int ret;
408 
409 	if (!charger->pd) {
410 		ret = uclass_get_device(UCLASS_PD, 0, &charger->pd);
411 		if (ret) {
412 			if (ret == -ENODEV)
413 				printf("cps5601x: Can't find PD\n");
414 			else
415 				printf("cps5601x: Get UCLASS PD failed: %d\n", ret);
416 			charger->pd = NULL;
417 		}
418 	}
419 
420 	if (!cps5601x_get_pd_output_val(charger, &pd_inputvol, &pd_inputcurrent)) {
421 		CPS_DBG("pd adapter\n");
422 		cps5601x_set_input_current_limit(charger, pd_inputcurrent);
423 	} else {
424 		CPS_DBG("normal adapter: %d\n", cps5601x_get_usb_type());
425 		if (cps5601x_get_usb_type() == POWER_SUPPLY_TYPE_USB_DCP)
426 			cps5601x_set_input_current_limit(charger, dcp_inputcurrent);
427 		else if (cps5601x_get_usb_type() == POWER_SUPPLY_TYPE_USB_CDP)
428 			cps5601x_set_input_current_limit(charger, dcp_inputcurrent);
429 		else if (cps5601x_get_usb_type() == POWER_SUPPLY_TYPE_USB_FLOATING)
430 			cps5601x_set_input_current_limit(charger, dcp_inputcurrent);
431 		else
432 			cps5601x_set_input_current_limit(charger, sdp_inputcurrent);
433 	}
434 }
435 
cps5601x_charger_status(struct udevice * dev)436 static bool cps5601x_charger_status(struct udevice *dev)
437 {
438 	struct cps5601x *charger = dev_get_priv(dev);
439 	int state_of_charger;
440 	u8 value;
441 	int i = 0;
442 
443 __retry:
444 	cps5601x_read(charger, CPS5601X_REG_0F, &value);
445 	state_of_charger = !!(value & PG_STAT_MASK);
446 	if (!state_of_charger && charger->pd_online) {
447 		if (i < 3) {
448 			i++;
449 			mdelay(20);
450 			goto __retry;
451 		}
452 	}
453 
454 	if ((state_of_charger) && (charger->init_count < 5)) {
455 		cps5601x_charger_input_current_init(charger);
456 		cps5601x_charger_enable(dev);
457 		charger->init_count++;
458 	}
459 
460 	if (!state_of_charger)
461 		cps5601x_set_iprechg(charger, CPS5601X_PRECHRG_I_DEF_uA);
462 
463 	CPS_DBG("dump register:\n");
464 	for (i = CPS5601X_REG_00; i < CPS5601X_REG_1B; i++) {
465 		cps5601x_read(charger, i, &value);
466 		CPS_DBG("[%d]: 0x%x\n", i, value);
467 	}
468 	return state_of_charger;
469 }
470 
cps5601x_irq_handler(int irq,void * data)471 static void cps5601x_irq_handler(int irq, void *data)
472 {
473 }
474 
cps5601x_ofdata_to_platdata(struct udevice * dev)475 static int cps5601x_ofdata_to_platdata(struct udevice *dev)
476 {
477 	struct cps5601x *charger = dev_get_priv(dev);
478 	u32 interrupt, phandle;
479 	int ret;
480 
481 	charger->dev = dev;
482 	charger->ichg = dev_read_u32_default(dev,
483 					     "vbat-current-limit-microamp",
484 					     0);
485 	if (charger->ichg == 0)
486 		charger->ichg = 3000 * 1000;
487 	charger->vchg = dev_read_u32_default(dev,
488 					     "vbat-voltage-limit-microamp",
489 					     0);
490 	if (charger->vchg == 0)
491 		charger->vchg = 4400 * 1000;
492 	CPS_DBG("charger->ichg: %d\n", charger->ichg);
493 	CPS_DBG("charger->vchg: %d\n", charger->vchg);
494 
495 	phandle = dev_read_u32_default(dev, "interrupt-parent", -ENODATA);
496 	if (phandle == -ENODATA) {
497 		printf("cps5601x: read 'interrupt-parent' failed, ret=%d\n",
498 		       phandle);
499 		return phandle;
500 	}
501 
502 	ret = dev_read_u32_array(dev, "interrupts", &interrupt, 1);
503 	if (ret) {
504 		printf("cps5601x: read 'interrupts' failed, ret=%d\n", ret);
505 		return ret;
506 	}
507 
508 	charger->irq = phandle_gpio_to_irq(phandle, interrupt);
509 	if (charger->irq < 0)
510 		printf("cps5601x: failed to request irq: %d\n", charger->irq);
511 
512 	return 0;
513 }
514 
cps5601x_probe(struct udevice * dev)515 static int cps5601x_probe(struct udevice *dev)
516 {
517 	struct cps5601x *charger = dev_get_priv(dev);
518 	u8 value;
519 	int i;
520 
521 	CPS_DBG("cps5601x: driver version-202502024\n");
522 	CPS_DBG("cps5601x: dump register:\n");
523 	for (i = CPS5601X_REG_00; i < CPS5601X_REG_1B; i++) {
524 		cps5601x_read(charger, i, &value);
525 		CPS_DBG("cps5601x: [%d]: 0x%x\n", i, value);
526 	}
527 
528 	charger->dev = dev;
529 	/* disable watchdog */
530 	cps5601x_update_bits(charger, CPS5601X_REG_0B, WATCHDOG_MASK, WATCHDOG_TIME(0));
531 
532 	cps5601x_update_bits(charger, CPS5601X_REG_0E, TS_IGNORE_MASK, EN_TS_IGNORE(1));
533 
534 	cps5601x_set_chargecurrent(charger, charger->ichg);
535 	cps5601x_set_chargevolt(charger, charger->vchg);
536 
537 	if (0 && charger->irq) {
538 		CPS_DBG("cps5601x: enable cps5601x irq\n");
539 		irq_install_handler(charger->irq, cps5601x_irq_handler, dev);
540 		irq_handler_enable(charger->irq);
541 	}
542 
543 	return 0;
544 }
545 
546 static const struct udevice_id charger_ids[] = {
547 	{ .compatible = "cps,cps5601x" },
548 	{ },
549 };
550 
551 static struct dm_fuel_gauge_ops charger_ops = {
552 	.get_chrg_online = cps5601x_charger_status,
553 	.capability = cps5601x_charger_capability,
554 	.set_charger_voltage = cps5601x_set_charger_voltage,
555 	.set_charger_enable = cps5601x_charger_enable,
556 	.set_charger_disable = cps5601x_charger_disable,
557 	.set_charger_current = cps5601x_charger_current,
558 	.set_iprechg_current = cps5601x_iprechg_current,
559 
560 };
561 
562 U_BOOT_DRIVER(cps5601x_charger) = {
563 	.name = "cps5601x_charger",
564 	.id = UCLASS_FG,
565 	.probe = cps5601x_probe,
566 	.of_match = charger_ids,
567 	.ops = &charger_ops,
568 	.ofdata_to_platdata = cps5601x_ofdata_to_platdata,
569 	.priv_auto_alloc_size = sizeof(struct cps5601x),
570 };
571