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, ®);
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