1 /* 2 * (C) Copyright 2022 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 SGM_DBG(args...) \ 20 do { \ 21 if (dbg_enable) { \ 22 printf(args); \ 23 } \ 24 } while (0) 25 26 /* define register */ 27 #define SGM4154x_CHRG_CTRL_0 0x00 28 #define SGM4154x_CHRG_CTRL_1 0x01 29 #define SGM4154x_CHRG_CTRL_2 0x02 30 #define SGM4154x_CHRG_CTRL_3 0x03 31 #define SGM4154x_CHRG_CTRL_4 0x04 32 #define SGM4154x_CHRG_CTRL_5 0x05 33 #define SGM4154x_CHRG_CTRL_6 0x06 34 #define SGM4154x_CHRG_CTRL_7 0x07 35 #define SGM4154x_CHRG_STAT 0x08 36 #define SGM4154x_CHRG_FAULT 0x09 37 #define SGM4154x_CHRG_CTRL_a 0x0a 38 #define SGM4154x_CHRG_CTRL_b 0x0b 39 #define SGM4154x_CHRG_CTRL_c 0x0c 40 #define SGM4154x_CHRG_CTRL_d 0x0d 41 #define SGM4154x_INPUT_DET 0x0e 42 #define SGM4154x_CHRG_CTRL_f 0x0f 43 44 /* charge status flags */ 45 #define SGM4154x_CHRG_EN BIT(4) 46 #define SGM4154x_HIZ_EN BIT(7) 47 #define SGM4154x_TERM_EN BIT(7) 48 #define SGM4154x_VAC_OVP_MASK GENMASK(7, 6) 49 #define SGM4154x_DPDM_ONGOING BIT(7) 50 #define SGM4154x_VBUS_GOOD BIT(7) 51 52 #define SGM4154x_BOOSTV GENMASK(5, 4) 53 #define SGM4154x_BOOST_LIM BIT(7) 54 #define SGM4154x_OTG_EN BIT(5) 55 56 /* Part ID */ 57 #define SGM4154x_PN_MASK GENMASK(6, 3) 58 59 /* WDT TIMER SET */ 60 #define SGM4154x_WDT_TIMER_MASK GENMASK(5, 4) 61 #define SGM4154x_WDT_TIMER_DISABLE 0 62 #define SGM4154x_WDT_TIMER_40S BIT(4) 63 #define SGM4154x_WDT_TIMER_80S BIT(5) 64 #define SGM4154x_WDT_TIMER_160S (BIT(4) | BIT(5)) 65 66 #define SGM4154x_WDT_RST_MASK BIT(6) 67 68 /* SAFETY TIMER SET */ 69 #define SGM4154x_SAFETY_TIMER_MASK GENMASK(3, 3) 70 #define SGM4154x_SAFETY_TIMER_DISABLE 0 71 #define SGM4154x_SAFETY_TIMER_EN BIT(3) 72 #define SGM4154x_SAFETY_TIMER_5H 0 73 #define SGM4154x_SAFETY_TIMER_10H BIT(2) 74 75 /* recharge voltage */ 76 #define SGM4154x_VRECHARGE BIT(0) 77 #define SGM4154x_VRECHRG_STEP_mV 100 78 #define SGM4154x_VRECHRG_OFFSET_mV 100 79 80 /* charge status */ 81 #define SGM4154x_VSYS_STAT BIT(0) 82 #define SGM4154x_THERM_STAT BIT(1) 83 #define SGM4154x_PG_STAT BIT(2) 84 #define SGM4154x_CHG_STAT_MASK GENMASK(4, 3) 85 #define SGM4154x_PRECHRG BIT(3) 86 #define SGM4154x_FAST_CHRG BIT(4) 87 #define SGM4154x_TERM_CHRG (BIT(3) | BIT(4)) 88 89 /* charge type */ 90 #define SGM4154x_VBUS_STAT_MASK GENMASK(7, 5) 91 #define SGM4154x_NOT_CHRGING 0 92 #define SGM4154x_USB_SDP BIT(5) 93 #define SGM4154x_USB_CDP BIT(6) 94 #define SGM4154x_USB_DCP (BIT(5) | BIT(6)) 95 #define SGM4154x_UNKNOWN (BIT(7) | BIT(5)) 96 #define SGM4154x_NON_STANDARD (BIT(7) | BIT(6)) 97 #define SGM4154x_OTG_MODE (BIT(7) | BIT(6) | BIT(5)) 98 99 /* TEMP Status */ 100 #define SGM4154x_TEMP_MASK GENMASK(2, 0) 101 #define SGM4154x_TEMP_NORMAL BIT(0) 102 #define SGM4154x_TEMP_WARM BIT(1) 103 #define SGM4154x_TEMP_COOL (BIT(0) | BIT(1)) 104 #define SGM4154x_TEMP_COLD (BIT(0) | BIT(3)) 105 #define SGM4154x_TEMP_HOT (BIT(2) | BIT(3)) 106 107 /* precharge current */ 108 #define SGM4154x_PRECHRG_CUR_MASK GENMASK(7, 4) 109 #define SGM4154x_PRECHRG_CURRENT_STEP_uA 60000 110 #define SGM4154x_PRECHRG_I_MIN_uA 60000 111 #define SGM4154x_PRECHRG_I_MAX_uA 780000 112 #define SGM4154x_PRECHRG_I_DEF_uA 180000 113 114 /* termination current */ 115 #define SGM4154x_TERMCHRG_CUR_MASK GENMASK(3, 0) 116 #define SGM4154x_TERMCHRG_CURRENT_STEP_uA 60000 117 #define SGM4154x_TERMCHRG_I_MIN_uA 60000 118 #define SGM4154x_TERMCHRG_I_MAX_uA 960000 119 #define SGM4154x_TERMCHRG_I_DEF_uA 180000 120 121 /* charge current */ 122 #define SGM4154x_ICHRG_CUR_MASK GENMASK(5, 0) 123 #define SGM4154x_ICHRG_I_STEP_uA 60000 124 #define SGM4154x_ICHRG_I_MIN_uA 0 125 #define SGM4154x_ICHRG_I_MAX_uA 3780000 126 #define SGM4154x_ICHRG_I_DEF_uA 2040000 127 128 /* charge voltage */ 129 #define SGM4154x_VREG_V_MASK GENMASK(7, 3) 130 #define SGM4154x_VREG_V_MAX_uV 4624000 131 #define SGM4154x_VREG_V_MIN_uV 3856000 132 #define SGM4154x_VREG_V_DEF_uV 4208000 133 #define SGM4154x_VREG_V_STEP_uV 32000 134 135 /* VREG Fine Tuning */ 136 #define SGM4154x_VREG_FT_MASK GENMASK(7, 6) 137 #define SGM4154x_VREG_FT_UP_8mV BIT(6) 138 #define SGM4154x_VREG_FT_DN_8mV BIT(7) 139 #define SGM4154x_VREG_FT_DN_16mV (BIT(7) | BIT(6)) 140 141 /* iindpm current */ 142 #define SGM4154x_IINDPM_I_MASK GENMASK(4, 0) 143 #define SGM4154x_IINDPM_I_MIN_uA 100000 144 #define SGM4154x_IINDPM_I_MAX_uA 2000000 145 #define SGM4154x_IINDPM_STEP_uA 100000 146 #define SGM4154x_IINDPM_DEF_uA 2400000 147 148 #define SGM4154x_VINDPM_INT_MASK BIT(1) 149 #define SGM4154x_VINDPM_INT_DIS BIT(1) 150 #define SGM4154x_IINDPM_INT_MASK BIT(0) 151 #define SGM4154x_IINDPM_INT_DIS BIT(0) 152 153 /* vindpm voltage */ 154 #define SGM4154x_VINDPM_V_MASK GENMASK(3, 0) 155 #define SGM4154x_VINDPM_V_MIN_uV 3900000 156 #define SGM4154x_VINDPM_V_MAX_uV 12000000 157 #define SGM4154x_VINDPM_STEP_uV 100000 158 #define SGM4154x_VINDPM_DEF_uV 4500000 159 #define SGM4154x_VINDPM_OS_MASK GENMASK(1, 0) 160 161 /* DP DM SEL */ 162 #define SGM4154x_DP_VSEL_MASK GENMASK(4, 3) 163 #define SGM4154x_DM_VSEL_MASK GENMASK(2, 1) 164 165 /* PUMPX SET */ 166 #define SGM4154x_EN_PUMPX BIT(7) 167 #define SGM4154x_PUMPX_UP BIT(6) 168 #define SGM4154x_PUMPX_DN BIT(5) 169 170 struct sgm41542 { 171 struct udevice *dev; 172 struct udevice *pd; 173 bool pd_online; 174 u32 init_count; 175 u32 ichg; 176 u32 vchg; 177 int irq; 178 }; 179 180 enum power_supply_type { 181 POWER_SUPPLY_TYPE_UNKNOWN = 0, 182 POWER_SUPPLY_TYPE_USB, /* Standard Downstream Port */ 183 POWER_SUPPLY_TYPE_USB_DCP, /* Dedicated Charging Port */ 184 POWER_SUPPLY_TYPE_USB_CDP, /* Charging Downstream Port */ 185 POWER_SUPPLY_TYPE_USB_FLOATING, /* DCP without shorting D+/D- */ 186 }; 187 188 static int sgm41542_read(struct sgm41542 *charger, uint reg, u8 *buffer) 189 { 190 u8 val; 191 int ret; 192 193 ret = dm_i2c_read(charger->dev, reg, &val, 1); 194 if (ret) { 195 printf("sgm41542: read %#x error, ret=%d", reg, ret); 196 return ret; 197 } 198 199 *buffer = val; 200 return 0; 201 } 202 203 static int sgm41542_write(struct sgm41542 *charger, uint reg, u8 val) 204 { 205 int ret; 206 207 ret = dm_i2c_write(charger->dev, reg, &val, 1); 208 if (ret) 209 printf("sgm41542: write %#x error, ret=%d", reg, ret); 210 211 return ret; 212 } 213 214 static int sgm41542_update_bits(struct sgm41542 *charger, 215 u8 offset, 216 u8 mask, 217 u8 val) 218 { 219 u8 reg; 220 221 sgm41542_read(charger, offset, ®); 222 223 reg &= ~mask; 224 225 return sgm41542_write(charger, offset, reg | val); 226 } 227 228 static int sgm4154x_set_input_curr_lim(struct sgm41542 *charger, int iindpm) 229 { 230 u8 reg_val; 231 int ret; 232 233 if (iindpm < SGM4154x_IINDPM_I_MIN_uA) 234 iindpm = SGM4154x_IINDPM_I_MIN_uA; 235 if (iindpm >= SGM4154x_IINDPM_I_MAX_uA) 236 iindpm = SGM4154x_IINDPM_I_MAX_uA; 237 238 if (iindpm >= SGM4154x_IINDPM_I_MIN_uA && 239 iindpm <= SGM4154x_IINDPM_I_MAX_uA) 240 reg_val = (iindpm - SGM4154x_IINDPM_I_MIN_uA) / SGM4154x_IINDPM_STEP_uA; 241 242 ret = sgm41542_update_bits(charger, 243 SGM4154x_CHRG_CTRL_0, 244 SGM4154x_IINDPM_I_MASK, 245 reg_val); 246 247 return ret; 248 } 249 250 static int sgm41542_get_usb_type(void) 251 { 252 #ifdef CONFIG_PHY_ROCKCHIP_INNO_USB2 253 return rockchip_chg_get_type(); 254 #else 255 return 0; 256 #endif 257 } 258 259 static int sgm41542_charger_capability(struct udevice *dev) 260 { 261 return FG_CAP_CHARGER; 262 } 263 264 static int sgm4154x_set_ichrg_curr(struct sgm41542 *charger, int uA) 265 { 266 u8 reg_val; 267 int ret; 268 269 if (uA < SGM4154x_ICHRG_I_MIN_uA) 270 uA = SGM4154x_ICHRG_I_MIN_uA; 271 else if (uA > charger->ichg) 272 uA = uA > charger->ichg; 273 274 reg_val = uA / SGM4154x_ICHRG_I_STEP_uA; 275 276 ret = sgm41542_update_bits(charger, 277 SGM4154x_CHRG_CTRL_2, 278 SGM4154x_ICHRG_CUR_MASK, 279 reg_val); 280 if (ret) 281 printf("sgm41542: set icharge current error!\n"); 282 283 return ret; 284 } 285 286 static int sgm4154x_set_prechrg_curr(struct sgm41542 *charger, int uA) 287 { 288 u8 reg_val; 289 int ret; 290 291 if (uA < SGM4154x_PRECHRG_I_MIN_uA) 292 uA = SGM4154x_PRECHRG_I_MIN_uA; 293 else if (uA > SGM4154x_PRECHRG_I_MAX_uA) 294 uA = SGM4154x_PRECHRG_I_MAX_uA; 295 296 reg_val = (uA - SGM4154x_PRECHRG_I_MIN_uA) / SGM4154x_PRECHRG_CURRENT_STEP_uA; 297 298 reg_val = reg_val << 4; 299 ret = sgm41542_update_bits(charger, 300 SGM4154x_CHRG_CTRL_3, 301 SGM4154x_PRECHRG_CUR_MASK, 302 reg_val); 303 if (ret) 304 printf("sgm41542: set icharge current error!\n"); 305 306 return ret; 307 } 308 309 static int sgm4154x_set_chrg_volt(struct sgm41542 *charger, int chrg_volt) 310 { 311 u8 reg_val; 312 int ret; 313 314 if (chrg_volt < SGM4154x_VREG_V_MIN_uV) 315 chrg_volt = SGM4154x_VREG_V_MIN_uV; 316 else if (chrg_volt > SGM4154x_VREG_V_MAX_uV) 317 chrg_volt = SGM4154x_VREG_V_MAX_uV; 318 319 reg_val = (chrg_volt - SGM4154x_VREG_V_MIN_uV) / SGM4154x_VREG_V_STEP_uV; 320 reg_val = reg_val << 3; 321 SGM_DBG("reg_val: 0x%x\n", reg_val); 322 ret = sgm41542_update_bits(charger, 323 SGM4154x_CHRG_CTRL_4, 324 SGM4154x_VREG_V_MASK, 325 reg_val); 326 327 return ret; 328 } 329 330 static int sgm41542_set_charger_voltage(struct udevice *dev, int uV) 331 { 332 struct sgm41542 *charger = dev_get_priv(dev); 333 334 SGM_DBG("SGM41542: charger voltage %d\n", uV); 335 return sgm4154x_set_chrg_volt(charger, uV); 336 } 337 338 static int sgm41542_charger_enable(struct udevice *dev) 339 { 340 struct sgm41542 *charger = dev_get_priv(dev); 341 342 SGM_DBG("SGM41542: charger enable\n"); 343 sgm41542_update_bits(charger, SGM4154x_CHRG_CTRL_1, 344 SGM4154x_CHRG_EN, 345 SGM4154x_CHRG_EN); 346 return 0; 347 } 348 349 static int sgm41542_charger_disable(struct udevice *dev) 350 { 351 struct sgm41542 *charger = dev_get_priv(dev); 352 353 SGM_DBG("SGM41542: charger disable\n"); 354 sgm41542_update_bits(charger, SGM4154x_CHRG_CTRL_1, 355 SGM4154x_CHRG_EN, 356 0); 357 return 0; 358 } 359 360 static int sgm41542_iprechg_current(struct udevice *dev, int iprechrg_uA) 361 { 362 struct sgm41542 *charger = dev_get_priv(dev); 363 364 SGM_DBG("SGM41542: charger current:iprechrg_uA: %d\n", 365 iprechrg_uA); 366 367 return sgm4154x_set_prechrg_curr(charger, iprechrg_uA); 368 } 369 370 static int sgm41542_charger_current(struct udevice *dev, int ichrg_uA) 371 { 372 struct sgm41542 *charger = dev_get_priv(dev); 373 374 SGM_DBG("SGM41542: charger current:ichrg_uA%d\n", 375 ichrg_uA); 376 377 return sgm4154x_set_ichrg_curr(charger, ichrg_uA); 378 } 379 380 static int sgm41542_get_pd_output_val(struct sgm41542 *charger, 381 int *vol, 382 int *cur) 383 { 384 struct power_delivery_data pd_data; 385 int ret; 386 387 if (!charger->pd) 388 return -EINVAL; 389 390 memset(&pd_data, 0, sizeof(pd_data)); 391 ret = power_delivery_get_data(charger->pd, &pd_data); 392 if (ret) 393 return ret; 394 if (!pd_data.online || !pd_data.voltage || !pd_data.current) 395 return -EINVAL; 396 397 *vol = pd_data.voltage; 398 *cur = pd_data.current; 399 charger->pd_online = pd_data.online; 400 401 return 0; 402 } 403 404 static void sgm41542_charger_input_current_init(struct sgm41542 *charger) 405 { 406 int sdp_inputcurrent = 500 * 1000; 407 int dcp_inputcurrent = 2000 * 1000; 408 int pd_inputvol, pd_inputcurrent; 409 int ret; 410 411 if (!charger->pd) { 412 ret = uclass_get_device(UCLASS_PD, 0, &charger->pd); 413 if (ret) { 414 if (ret == -ENODEV) 415 printf("sgm41542: Can't find PD\n"); 416 else 417 printf("sgm41542: Get UCLASS PD failed: %d\n", ret); 418 charger->pd = NULL; 419 } 420 } 421 422 if (!sgm41542_get_pd_output_val(charger, &pd_inputvol, &pd_inputcurrent)) { 423 SGM_DBG("pd adapter\n"); 424 sgm4154x_set_input_curr_lim(charger, pd_inputcurrent); 425 } else { 426 SGM_DBG("normal adapter: %d\n", sgm41542_get_usb_type()); 427 if (sgm41542_get_usb_type() == POWER_SUPPLY_TYPE_USB_DCP) 428 sgm4154x_set_input_curr_lim(charger, dcp_inputcurrent); 429 else if (sgm41542_get_usb_type() == POWER_SUPPLY_TYPE_USB_CDP) 430 sgm4154x_set_input_curr_lim(charger, dcp_inputcurrent); 431 else if (sgm41542_get_usb_type() == POWER_SUPPLY_TYPE_USB_FLOATING) 432 sgm4154x_set_input_curr_lim(charger, dcp_inputcurrent); 433 else 434 sgm4154x_set_input_curr_lim(charger, sdp_inputcurrent); 435 } 436 } 437 438 static bool sgm41542_charger_status(struct udevice *dev) 439 { 440 struct sgm41542 *charger = dev_get_priv(dev); 441 int state_of_charger; 442 u8 value; 443 int i = 0; 444 445 __retry: 446 sgm41542_read(charger, SGM4154x_CHRG_STAT, &value); 447 state_of_charger = !!(value & SGM4154x_PG_STAT); 448 if (!state_of_charger && charger->pd_online) { 449 if (i < 3) { 450 i++; 451 mdelay(20); 452 goto __retry; 453 } 454 } 455 456 if ((state_of_charger) && (charger->init_count < 5)) { 457 sgm41542_charger_input_current_init(charger); 458 sgm41542_update_bits(charger, 459 SGM4154x_CHRG_CTRL_1, 460 SGM4154x_CHRG_EN, 461 SGM4154x_CHRG_EN); 462 charger->init_count++; 463 } 464 465 if (!state_of_charger) 466 sgm4154x_set_prechrg_curr(charger, SGM4154x_PRECHRG_I_DEF_uA); 467 468 SGM_DBG("dump register:\n"); 469 for (i = SGM4154x_CHRG_CTRL_0; i < SGM4154x_CHRG_CTRL_f; i++) { 470 sgm41542_read(charger, i, &value); 471 SGM_DBG("[%d]: 0x%x\n", i, value); 472 } 473 return state_of_charger; 474 } 475 476 static void sgm41542_irq_handler(int irq, void *data) 477 { 478 } 479 480 static int sgm41542_ofdata_to_platdata(struct udevice *dev) 481 { 482 struct sgm41542 *charger = dev_get_priv(dev); 483 u32 interrupt, phandle; 484 int ret; 485 486 charger->dev = dev; 487 charger->ichg = dev_read_u32_default(dev, 488 "vbat-current-limit-microamp", 489 0); 490 if (charger->ichg == 0) 491 charger->ichg = 3000 * 1000; 492 charger->vchg = dev_read_u32_default(dev, 493 "vbat-voltage-limit-microamp", 494 0); 495 if (charger->vchg == 0) 496 charger->vchg = 4400 * 1000; 497 SGM_DBG("charger->ichg: %d\n", charger->ichg); 498 SGM_DBG("charger->vchg: %d\n", charger->vchg); 499 500 phandle = dev_read_u32_default(dev, "interrupt-parent", -ENODATA); 501 if (phandle == -ENODATA) { 502 printf("sgm41542: read 'interrupt-parent' failed, ret=%d\n", 503 phandle); 504 return phandle; 505 } 506 507 ret = dev_read_u32_array(dev, "interrupts", &interrupt, 1); 508 if (ret) { 509 printf("sgm41542: read 'interrupts' failed, ret=%d\n", ret); 510 return ret; 511 } 512 513 charger->irq = phandle_gpio_to_irq(phandle, interrupt); 514 if (charger->irq < 0) 515 printf("sgm41542: failed to request irq: %d\n", charger->irq); 516 517 return 0; 518 } 519 520 static int sgm41542_probe(struct udevice *dev) 521 { 522 struct sgm41542 *charger = dev_get_priv(dev); 523 u8 value; 524 int i; 525 526 SGM_DBG("sgm41542: driver version-20220903\n"); 527 SGM_DBG("sgm41542: dump register:\n"); 528 for (i = SGM4154x_CHRG_CTRL_0; i < SGM4154x_CHRG_CTRL_f; i++) { 529 sgm41542_read(charger, i, &value); 530 SGM_DBG("gm41542: [%d]: 0x%x\n", i, value); 531 } 532 533 charger->dev = dev; 534 /* disable watchdog */ 535 sgm41542_update_bits(charger, SGM4154x_CHRG_CTRL_5, 536 SGM4154x_WDT_TIMER_MASK, 537 SGM4154x_WDT_TIMER_DISABLE); 538 539 sgm41542_update_bits(charger, SGM4154x_CHRG_CTRL_a, 540 SGM4154x_VINDPM_INT_MASK | SGM4154x_IINDPM_INT_MASK, 541 SGM4154x_VINDPM_INT_DIS | SGM4154x_IINDPM_INT_DIS); 542 543 sgm4154x_set_ichrg_curr(charger, charger->ichg); 544 sgm4154x_set_chrg_volt(charger, charger->vchg); 545 546 if (0 && charger->irq) { 547 SGM_DBG("sgm41542: enable sgm42542 irq\n"); 548 irq_install_handler(charger->irq, sgm41542_irq_handler, dev); 549 irq_handler_enable(charger->irq); 550 } 551 552 return 0; 553 } 554 555 static const struct udevice_id charger_ids[] = { 556 { .compatible = "sgm,sgm41542" }, 557 { }, 558 }; 559 560 static struct dm_fuel_gauge_ops charger_ops = { 561 .get_chrg_online = sgm41542_charger_status, 562 .capability = sgm41542_charger_capability, 563 .set_charger_voltage = sgm41542_set_charger_voltage, 564 .set_charger_enable = sgm41542_charger_enable, 565 .set_charger_disable = sgm41542_charger_disable, 566 .set_charger_current = sgm41542_charger_current, 567 .set_iprechg_current = sgm41542_iprechg_current, 568 569 }; 570 571 U_BOOT_DRIVER(sgm41542_charger) = { 572 .name = "sgm41542_charger", 573 .id = UCLASS_FG, 574 .probe = sgm41542_probe, 575 .of_match = charger_ids, 576 .ops = &charger_ops, 577 .ofdata_to_platdata = sgm41542_ofdata_to_platdata, 578 .priv_auto_alloc_size = sizeof(struct sgm41542), 579 }; 580