1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 /* #include <adc.h> */ 8 #include <dm.h> 9 #include <errno.h> 10 #include <common.h> 11 #include <malloc.h> 12 #include <fdtdec.h> 13 #include <asm/gpio.h> 14 #include <common.h> 15 #include <power/pmic.h> 16 #include <dm/uclass-internal.h> 17 #include <power/charge_display.h> 18 #include <power/fuel_gauge.h> 19 #include <power/rk8xx_pmic.h> 20 #include <linux/usb/phy-rockchip-inno-usb2.h> 21 #include "fg_regs.h" 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 static int dbg_enable = 0; 26 #define DBG(args...) \ 27 do { \ 28 if (dbg_enable) { \ 29 printf(args); \ 30 } \ 31 } while (0) 32 33 #define BAT_INFO(fmt, args...) printf("rk816-bat: "fmt, ##args) 34 35 #define DRIVER_VERSION "2.0" 36 37 /* THERMAL_REG */ 38 #define TEMP_115C (0x03 << 2) 39 #define FB_TEMP_MSK 0x0c 40 41 /* CHRG_CTRL_REG2*/ 42 #define FINISH_100MA (0x00 << 6) 43 #define FINISH_150MA (0x01 << 6) 44 #define FINISH_200MA (0x02 << 6) 45 #define FINISH_250MA (0x03 << 6) 46 #define FINISH_CUR_MSK 0xc7 47 48 /* CHRG_CTRL_REG3*/ 49 #define CHRG_TERM_DIG_SIGNAL (1 << 5) 50 #define CHRG_TIMER_CCCV_EN (1 << 2) 51 52 /* CHRG_CTRL_REG */ 53 #define ILIM_450MA (0x00) 54 #define ILIM_2000MA (0x07) 55 #define CHRG_CT_EN (1 << 7) 56 57 /* USB_CTRL_REG */ 58 #define INPUT_CUR_MSK 0x0f 59 60 /* VB_MON_REG */ 61 #define PLUG_IN_STS (1 << 6) 62 63 /* GGSTS */ 64 #define BAT_CON (1 << 4) 65 #define VOL_INSTANT (1 << 0) 66 #define VOL_AVG (0 << 0) 67 68 /* TS_CTRL_REG */ 69 #define GG_EN (1 << 7) 70 71 /* CHRG_USB_CTRL*/ 72 #define CHRG_EN (1 << 7) 73 74 /*SUP_STS_REG*/ 75 #define BAT_EXS (1 << 7) 76 #define USB_EXIST (1 << 1) 77 #define USB_EFF (1 << 0) 78 #define CHARGE_OFF (0x00 << 4) 79 #define DEAD_CHARGE (0x01 << 4) 80 #define TRICKLE_CHARGE (0x02 << 4) 81 #define CC_OR_CV (0x03 << 4) 82 #define CHARGE_FINISH (0x04 << 4) 83 #define USB_OVER_VOL (0x05 << 4) 84 #define BAT_TMP_ERR (0x06 << 4) 85 #define TIMER_ERR (0x07 << 4) 86 #define USB_VLIMIT_EN (1 << 3) 87 #define USB_CLIMIT_EN (1 << 2) 88 #define BAT_STATUS_MSK 0x70 89 90 /* GGCON */ 91 #define ADC_CUR_MODE (1 << 1) 92 93 /* CALI PARAM */ 94 #define FINISH_CALI_CURR 1500 95 #define TERM_CALI_CURR 600 96 #define VIRTUAL_POWER_VOL 4200 97 #define VIRTUAL_POWER_SOC 66 98 #define SECONDS(n) ((n) * 1000) 99 100 /* CALC PARAM */ 101 #define MAX_PERCENTAGE 100 102 #define MAX_INTERPOLATE 1000 103 #define MAX_INT 0x7fff 104 #define MIN_FCC 500 105 106 /* DC ADC */ 107 #define FG_INIT (1 << 3) 108 #define FG_RESET_LATE (1 << 1) 109 #define FG_RESET_NOW (1 << 0) 110 #define CHRG_TERM_DSOC 90 111 #define CHRG_TERM_K 650 112 #define CHRG_FULL_K 400 113 #define ADC_CALIB_THRESHOLD 4 114 #define DC_ADC_TRIGGER 150 115 #define DIV(x) ((x) ? (x) : 1) 116 117 /***********************************************************/ 118 struct battery_info { 119 int chrg_type; 120 int poffset; 121 int bat_res; 122 int current_avg; 123 int voltage_avg; 124 int voltage_ocv; 125 int voltage_k; 126 int voltage_b; 127 int dsoc; 128 int rsoc; 129 int fcc; 130 int qmax; 131 int remain_cap; 132 int design_cap; 133 int nac; 134 u32 *ocv_table; 135 u32 ocv_size; 136 int virtual_power; 137 int pwroff_min; 138 int sm_old_cap; 139 int sm_linek; 140 int sm_chrg_dsoc; 141 int adc_allow_update; 142 int chrg_vol_sel; 143 int chrg_cur_input; 144 int chrg_cur_sel; 145 int dts_vol_sel; 146 int dts_cur_input; 147 int dts_cur_sel; 148 int max_soc_offset; 149 struct gpio_desc *dc_det; 150 int dc_type; 151 int dc_det_adc; 152 ulong vol_mode_base; 153 ulong finish_chrg_base; 154 u8 calc_dsoc; 155 u8 calc_rsoc; 156 int sm_meet_soc; 157 u8 halt_cnt; 158 bool is_halt; 159 bool is_ocv_calib; 160 bool is_max_soc_offset; 161 bool is_first_power_on; 162 bool is_sw_reset; 163 int pwr_dsoc; 164 int pwr_rsoc; 165 int pwr_vol; 166 }; 167 168 enum charger_type { 169 NO_CHARGER = 0, 170 USB_CHARGER, 171 AC_CHARGER, 172 DC_CHARGER, 173 UNDEF_CHARGER, 174 }; 175 176 enum dc_type { 177 DC_TYPE_OF_NONE = 0, 178 DC_TYPE_OF_GPIO, 179 DC_TYPE_OF_ADC, 180 }; 181 182 static struct udevice *g_pmic_dev; 183 184 static const u32 CHRG_VOL_SEL[] = { 185 4050, 4100, 4150, 4200, 4250, 4300, 4350 186 }; 187 188 static const u32 CHRG_CUR_SEL[] = { 189 1000, 1200, 1400, 1600, 1800, 2000, 2250, 2400 190 }; 191 192 static const u32 CHRG_CUR_INPUT[] = { 193 450, 800, 850, 1000, 1250, 1500, 1750, 2000 194 }; 195 196 static int rk816_bat_read(u8 reg) 197 { 198 return pmic_reg_read(g_pmic_dev, reg); 199 } 200 201 static void rk816_bat_write(u8 reg, u8 buf) 202 { 203 pmic_reg_write(g_pmic_dev, reg, buf); 204 } 205 206 static int rk816_bat_dwc_otg_check_dpdm(void) 207 { 208 #ifdef CONFIG_PHY_ROCKCHIP_INNO_USB2 209 return rockchip_chg_get_type(); 210 #else 211 BAT_INFO("rockchip_chg_get_type() is not implement\n"); 212 return NO_CHARGER; 213 #endif 214 } 215 216 static int rk816_bat_get_rsoc(struct battery_info *di) 217 { 218 return (di->remain_cap + di->fcc / 200) * 100 / DIV(di->fcc); 219 } 220 221 static int rk816_bat_get_dsoc(struct battery_info *di) 222 { 223 return rk816_bat_read(SOC_REG); 224 } 225 226 static void rk816_bat_enable_gauge(struct battery_info *di) 227 { 228 u8 val; 229 230 val = rk816_bat_read(TS_CTRL_REG); 231 val |= GG_EN; 232 rk816_bat_write(TS_CTRL_REG, val); 233 } 234 235 static void rk816_bat_set_vol_instant_mode(struct battery_info *di) 236 { 237 u8 val; 238 239 val = rk816_bat_read(GGSTS_REG); 240 val |= VOL_INSTANT; 241 rk816_bat_write(GGSTS_REG, val); 242 } 243 244 static void rk816_bat_set_vol_avg_mode(struct battery_info *di) 245 { 246 u8 val; 247 248 val = rk816_bat_read(GGSTS_REG); 249 val &= ~0x01; 250 val |= VOL_AVG; 251 rk816_bat_write(GGSTS_REG, val); 252 } 253 254 static int rk816_bat_get_vcalib0(struct battery_info *di) 255 { 256 int val = 0; 257 258 val |= rk816_bat_read(VCALIB0_REGL) << 0; 259 val |= rk816_bat_read(VCALIB0_REGH) << 8; 260 261 return val; 262 } 263 264 static int rk816_bat_get_vcalib1(struct battery_info *di) 265 { 266 int val = 0; 267 268 val |= rk816_bat_read(VCALIB1_REGL) << 0; 269 val |= rk816_bat_read(VCALIB1_REGH) << 8; 270 271 DBG("<%s>. coffset: 0x%x\n", __func__, val); 272 return val; 273 } 274 275 static void rk816_bat_set_coffset(struct battery_info *di, int val) 276 { 277 u8 buf; 278 279 buf = (val >> 0) & 0xff; 280 rk816_bat_write(CAL_OFFSET_REGL, buf); 281 buf = (val >> 8) & 0xff; 282 rk816_bat_write(CAL_OFFSET_REGH, buf); 283 284 DBG("<%s>. set coffset: 0x%x\n", __func__, val); 285 } 286 287 static int rk816_bat_get_ioffset(struct battery_info *di) 288 { 289 int val = 0; 290 291 val |= rk816_bat_read(IOFFSET_REGL) << 0; 292 val |= rk816_bat_read(IOFFSET_REGH) << 8; 293 294 return val; 295 } 296 297 static void rk816_bat_init_voltage_kb(struct battery_info *di) 298 { 299 int vcalib0, vcalib1; 300 301 vcalib0 = rk816_bat_get_vcalib0(di); 302 vcalib1 = rk816_bat_get_vcalib1(di); 303 di->voltage_k = (4200 - 3000) * 1000 / DIV(vcalib1 - vcalib0); 304 di->voltage_b = 4200 - (di->voltage_k * vcalib1) / 1000; 305 DBG("%s. vk=%d, vb=%d\n", __func__, di->voltage_k, di->voltage_b); 306 } 307 308 static int rk816_bat_get_ocv_voltage(struct battery_info *di) 309 { 310 int vol, val = 0; 311 312 val |= rk816_bat_read(BAT_OCV_REGL) << 0; 313 val |= rk816_bat_read(BAT_OCV_REGH) << 8; 314 vol = di->voltage_k * val / 1000 + di->voltage_b; 315 vol = vol * 1100 / 1000; 316 317 return vol; 318 } 319 320 static int rk816_bat_get_avg_current(struct battery_info *di) 321 { 322 int val = 0; 323 324 val |= rk816_bat_read(BAT_CUR_AVG_REGL) << 0; 325 val |= rk816_bat_read(BAT_CUR_AVG_REGH) << 8; 326 327 if (val & 0x800) 328 val -= 4096; 329 val = val * 1506 / 1000; 330 331 return val; 332 } 333 334 static int rk816_bat_get_avg_voltage(struct battery_info *di) 335 { 336 int vol, val = 0; 337 338 val |= rk816_bat_read(BAT_VOL_REGL) << 0; 339 val |= rk816_bat_read(BAT_VOL_REGH) << 8; 340 vol = di->voltage_k * val / 1000 + di->voltage_b; 341 vol = vol * 1100 / 1000; 342 343 return vol; 344 } 345 346 static int rk816_bat_get_est_voltage(struct battery_info *di) 347 { 348 int est_vol, vol, curr; 349 350 vol = rk816_bat_get_avg_voltage(di); 351 curr = rk816_bat_get_avg_current(di); 352 est_vol = vol - (di->bat_res * curr / 1000); 353 354 return (est_vol > 2800) ? est_vol : vol; 355 } 356 357 static u8 rk816_bat_finish_ma(int fcc) 358 { 359 u8 ma; 360 361 if (fcc > 5000) 362 ma = FINISH_250MA; 363 else if (fcc >= 4000) 364 ma = FINISH_200MA; 365 else if (fcc >= 3000) 366 ma = FINISH_150MA; 367 else 368 ma = FINISH_100MA; 369 370 return ma; 371 } 372 373 static void rk816_bat_select_chrg_cv(struct battery_info *di) 374 { 375 int index, chrg_vol_sel, chrg_cur_sel, chrg_cur_input; 376 377 chrg_vol_sel = di->dts_vol_sel; 378 chrg_cur_sel = di->dts_cur_sel; 379 chrg_cur_input = di->dts_cur_input; 380 381 for (index = 0; index < ARRAY_SIZE(CHRG_VOL_SEL); index++) { 382 if (chrg_vol_sel < CHRG_VOL_SEL[index]) 383 break; 384 di->chrg_vol_sel = (index << 4); 385 } 386 387 for (index = 0; index < ARRAY_SIZE(CHRG_CUR_INPUT); index++) { 388 if (chrg_cur_input < CHRG_CUR_INPUT[index]) 389 break; 390 di->chrg_cur_input = (index << 0); 391 } 392 393 for (index = 0; index < ARRAY_SIZE(CHRG_CUR_SEL); index++) { 394 if (chrg_cur_sel < CHRG_CUR_SEL[index]) 395 break; 396 di->chrg_cur_sel = (index << 0); 397 } 398 399 DBG("<%s>. vol=0x%x, input=0x%x, sel=0x%x\n", 400 __func__, di->chrg_vol_sel, di->chrg_cur_input, di->chrg_cur_sel); 401 } 402 403 static void rk816_bat_init_chrg_config(struct battery_info *di) 404 { 405 u8 chrg_ctrl1, usb_ctrl, chrg_ctrl2, chrg_ctrl3; 406 u8 sup_sts, ggcon, thermal, finish_ma; 407 408 rk816_bat_select_chrg_cv(di); 409 finish_ma = rk816_bat_finish_ma(di->fcc); 410 411 ggcon = rk816_bat_read(GGCON_REG); 412 sup_sts = rk816_bat_read(SUP_STS_REG); 413 usb_ctrl = rk816_bat_read(USB_CTRL_REG); 414 thermal = rk816_bat_read(THERMAL_REG); 415 chrg_ctrl2 = rk816_bat_read(CHRG_CTRL_REG2); 416 chrg_ctrl3 = rk816_bat_read(CHRG_CTRL_REG3); 417 418 /* set charge current and voltage */ 419 usb_ctrl &= ~INPUT_CUR_MSK; 420 usb_ctrl |= di->chrg_cur_input; 421 chrg_ctrl1 = (CHRG_EN | di->chrg_vol_sel | di->chrg_cur_sel); 422 423 /* digital signal and finish current*/ 424 chrg_ctrl3 |= CHRG_TERM_DIG_SIGNAL; 425 chrg_ctrl2 &= ~FINISH_CUR_MSK; 426 chrg_ctrl2 |= finish_ma; 427 428 /* cccv mode */ 429 chrg_ctrl3 &= ~CHRG_TIMER_CCCV_EN; 430 431 /* enable voltage limit and enable input current limit */ 432 sup_sts |= USB_VLIMIT_EN; 433 sup_sts |= USB_CLIMIT_EN; 434 435 /* set feedback temperature */ 436 usb_ctrl |= CHRG_CT_EN; 437 thermal &= ~FB_TEMP_MSK; 438 thermal |= TEMP_115C; 439 440 /* adc current mode */ 441 ggcon |= ADC_CUR_MODE; 442 443 rk816_bat_write(GGCON_REG, ggcon); 444 rk816_bat_write(SUP_STS_REG, sup_sts); 445 rk816_bat_write(USB_CTRL_REG, usb_ctrl); 446 rk816_bat_write(THERMAL_REG, thermal); 447 rk816_bat_write(CHRG_CTRL_REG1, chrg_ctrl1); 448 rk816_bat_write(CHRG_CTRL_REG2, chrg_ctrl2); 449 rk816_bat_write(CHRG_CTRL_REG3, chrg_ctrl3); 450 } 451 452 static u32 interpolate(int value, u32 *table, int size) 453 { 454 uint8_t i; 455 uint16_t d; 456 457 for (i = 0; i < size; i++) { 458 if (value < table[i]) 459 break; 460 } 461 462 if ((i > 0) && (i < size)) { 463 d = (value - table[i - 1]) * (MAX_INTERPOLATE / (size - 1)); 464 d /= table[i] - table[i - 1]; 465 d = d + (i - 1) * (MAX_INTERPOLATE / (size - 1)); 466 } else { 467 d = i * ((MAX_INTERPOLATE + size / 2) / size); 468 } 469 470 if (d > 1000) 471 d = 1000; 472 473 return d; 474 } 475 476 /* returns (a * b) / c */ 477 static int32_t ab_div_c(u32 a, u32 b, u32 c) 478 { 479 bool sign; 480 u32 ans = MAX_INT; 481 int32_t tmp; 482 483 sign = ((((a ^ b) ^ c) & 0x80000000) != 0); 484 485 if (c != 0) { 486 if (sign) 487 c = -c; 488 tmp = ((int32_t)a * b + (c >> 1)) / c; 489 if (tmp < MAX_INT) 490 ans = tmp; 491 } 492 493 if (sign) 494 ans = -ans; 495 496 return ans; 497 } 498 499 static int rk816_bat_vol_to_cap(struct battery_info *di, int voltage) 500 { 501 u32 *ocv_table, tmp; 502 int ocv_size, ocv_cap; 503 504 ocv_table = di->ocv_table; 505 ocv_size = di->ocv_size; 506 tmp = interpolate(voltage, ocv_table, ocv_size); 507 ocv_cap = ab_div_c(tmp, di->fcc, MAX_INTERPOLATE); 508 509 return ocv_cap; 510 } 511 512 static int rk816_bat_vol_to_soc(struct battery_info *di, int voltage) 513 { 514 u32 *ocv_table, tmp; 515 int ocv_size, ocv_soc; 516 517 ocv_table = di->ocv_table; 518 ocv_size = di->ocv_size; 519 tmp = interpolate(voltage, ocv_table, ocv_size); 520 ocv_soc = ab_div_c(tmp, MAX_PERCENTAGE, MAX_INTERPOLATE); 521 522 return ocv_soc; 523 } 524 525 static int rk816_bat_get_prev_cap(struct battery_info *di) 526 { 527 int val = 0; 528 529 val |= rk816_bat_read(REMAIN_CAP_REG3) << 24; 530 val |= rk816_bat_read(REMAIN_CAP_REG2) << 16; 531 val |= rk816_bat_read(REMAIN_CAP_REG1) << 8; 532 val |= rk816_bat_read(REMAIN_CAP_REG0) << 0; 533 534 return val; 535 } 536 537 static void rk816_bat_save_fcc(struct battery_info *di, u32 cap) 538 { 539 u8 buf; 540 541 buf = (cap >> 24) & 0xff; 542 rk816_bat_write(NEW_FCC_REG3, buf); 543 buf = (cap >> 16) & 0xff; 544 rk816_bat_write(NEW_FCC_REG2, buf); 545 buf = (cap >> 8) & 0xff; 546 rk816_bat_write(NEW_FCC_REG1, buf); 547 buf = (cap >> 0) & 0xff; 548 rk816_bat_write(NEW_FCC_REG0, buf); 549 } 550 551 static int rk816_bat_get_fcc(struct battery_info *di) 552 { 553 int val = 0; 554 555 val |= rk816_bat_read(NEW_FCC_REG3) << 24; 556 val |= rk816_bat_read(NEW_FCC_REG2) << 16; 557 val |= rk816_bat_read(NEW_FCC_REG1) << 8; 558 val |= rk816_bat_read(NEW_FCC_REG0) << 0; 559 560 if (val < MIN_FCC) 561 val = di->design_cap; 562 else if (val > di->qmax) 563 val = di->qmax; 564 565 return val; 566 } 567 568 static u8 rk816_bat_get_pwroff_min(struct battery_info *di) 569 { 570 u8 cur, last; 571 572 cur = rk816_bat_read(NON_ACT_TIMER_CNT_REG); 573 last = rk816_bat_read(NON_ACT_TIMER_CNT_SAVE_REG); 574 rk816_bat_write(NON_ACT_TIMER_CNT_SAVE_REG, cur); 575 576 return (cur != last) ? cur : 0; 577 } 578 579 static int rk816_bat_get_coulomb_cap(struct battery_info *di) 580 { 581 int val = 0; 582 583 val |= rk816_bat_read(GASCNT_REG3) << 24; 584 val |= rk816_bat_read(GASCNT_REG2) << 16; 585 val |= rk816_bat_read(GASCNT_REG1) << 8; 586 val |= rk816_bat_read(GASCNT_REG0) << 0; 587 val /= 2390; 588 589 return val; 590 } 591 592 static void rk816_bat_init_capacity(struct battery_info *di, u32 capacity) 593 { 594 u8 buf; 595 u32 cap; 596 int delta; 597 598 delta = capacity - di->remain_cap; 599 if (!delta) 600 return; 601 602 cap = capacity * 2390; 603 buf = (cap >> 24) & 0xff; 604 rk816_bat_write(GASCNT_CAL_REG3, buf); 605 buf = (cap >> 16) & 0xff; 606 rk816_bat_write(GASCNT_CAL_REG2, buf); 607 buf = (cap >> 8) & 0xff; 608 rk816_bat_write(GASCNT_CAL_REG1, buf); 609 buf = (cap >> 0) & 0xff; 610 rk816_bat_write(GASCNT_CAL_REG0, buf); 611 612 di->remain_cap = rk816_bat_get_coulomb_cap(di); 613 di->rsoc = rk816_bat_get_rsoc(di); 614 } 615 616 static bool is_rk816_bat_ocv_valid(struct battery_info *di) 617 { 618 return di->pwroff_min >= 30 ? true : false; 619 } 620 621 static int rk816_bat_get_usb_state(struct battery_info *di) 622 { 623 int charger_type; 624 625 switch (rk816_bat_dwc_otg_check_dpdm()) { 626 case 0: 627 if ((rk816_bat_read(VB_MON_REG) & PLUG_IN_STS) != 0) 628 charger_type = DC_CHARGER; 629 else 630 charger_type = NO_CHARGER; 631 break; 632 case 1: 633 case 3: 634 charger_type = USB_CHARGER; 635 break; 636 case 2: 637 charger_type = AC_CHARGER; 638 break; 639 default: 640 charger_type = NO_CHARGER; 641 } 642 643 return charger_type; 644 } 645 646 static void rk816_bat_clr_initialized_state(struct battery_info *di) 647 { 648 u8 val; 649 650 val = rk816_bat_read(MISC_MARK_REG); 651 val &= ~FG_INIT; 652 rk816_bat_write(MISC_MARK_REG, val); 653 } 654 655 static bool rk816_bat_is_initialized(struct battery_info *di) 656 { 657 return (rk816_bat_read(MISC_MARK_REG) & FG_INIT) ? true : false; 658 } 659 660 static void rk816_bat_set_initialized_state(struct battery_info *di) 661 { 662 u8 val; 663 664 val = rk816_bat_read(MISC_MARK_REG); 665 if (rk816_bat_get_usb_state(di) != NO_CHARGER) { 666 val |= FG_INIT; 667 rk816_bat_write(MISC_MARK_REG, val); 668 BAT_INFO("fuel gauge initialized... estv=%d, ch=%d\n", 669 rk816_bat_get_est_voltage(di), 670 rk816_bat_get_usb_state(di)); 671 } 672 } 673 674 static void rk816_bat_first_pwron(struct battery_info *di) 675 { 676 int ocv_vol; 677 678 rk816_bat_save_fcc(di, di->design_cap); 679 ocv_vol = rk816_bat_get_ocv_voltage(di); 680 di->fcc = rk816_bat_get_fcc(di); 681 di->nac = rk816_bat_vol_to_cap(di, ocv_vol); 682 di->rsoc = rk816_bat_vol_to_soc(di, ocv_vol); 683 di->dsoc = di->rsoc; 684 rk816_bat_init_capacity(di, di->nac); 685 rk816_bat_set_initialized_state(di); 686 687 BAT_INFO("first power on: soc=%d\n", di->dsoc); 688 } 689 690 static u8 rk816_bat_get_halt_cnt(struct battery_info *di) 691 { 692 return rk816_bat_read(HALT_CNT_REG); 693 } 694 695 static void rk816_bat_inc_halt_cnt(struct battery_info *di) 696 { 697 u8 cnt; 698 699 cnt = rk816_bat_read(HALT_CNT_REG); 700 rk816_bat_write(HALT_CNT_REG, ++cnt); 701 } 702 703 static bool is_rk816_bat_last_halt(struct battery_info *di) 704 { 705 int pre_cap = rk816_bat_get_prev_cap(di); 706 int now_cap = rk816_bat_get_coulomb_cap(di); 707 708 /* over 5%: system halt last time */ 709 if (abs(now_cap - pre_cap) > (di->fcc / 20)) { 710 rk816_bat_inc_halt_cnt(di); 711 return true; 712 } else { 713 return false; 714 } 715 } 716 717 static void rk816_bat_not_first_pwron(struct battery_info *di) 718 { 719 int pre_soc, pre_cap, ocv_cap, ocv_soc, ocv_vol, now_cap; 720 721 di->fcc = rk816_bat_get_fcc(di); 722 pre_soc = rk816_bat_get_dsoc(di); 723 pre_cap = rk816_bat_get_prev_cap(di); 724 now_cap = rk816_bat_get_coulomb_cap(di); 725 di->pwr_dsoc = pre_soc; 726 di->pwr_rsoc = (now_cap + di->fcc / 200) * 100 / DIV(di->fcc); 727 di->is_halt = is_rk816_bat_last_halt(di); 728 di->halt_cnt = rk816_bat_get_halt_cnt(di); 729 di->is_ocv_calib = is_rk816_bat_ocv_valid(di); 730 731 if (di->is_halt) { 732 BAT_INFO("system halt last time... cap: pre=%d, now=%d\n", 733 pre_cap, now_cap); 734 if (now_cap < 0) 735 now_cap = 0; 736 rk816_bat_init_capacity(di, now_cap); 737 pre_cap = di->remain_cap; 738 pre_soc = di->rsoc; 739 goto finish; 740 } else if (di->is_ocv_calib) { 741 ocv_vol = rk816_bat_get_ocv_voltage(di); 742 ocv_soc = rk816_bat_vol_to_soc(di, ocv_vol); 743 ocv_cap = rk816_bat_vol_to_cap(di, ocv_vol); 744 pre_cap = ocv_cap; 745 BAT_INFO("do ocv calib.. rsoc=%d\n", ocv_soc); 746 747 if (abs(ocv_soc - pre_soc) >= di->max_soc_offset) { 748 BAT_INFO("trigger max soc offset, soc: %d -> %d\n", 749 pre_soc, ocv_soc); 750 pre_soc = ocv_soc; 751 di->is_max_soc_offset = true; 752 } 753 BAT_INFO("OCV calib: cap=%d, rsoc=%d\n", ocv_cap, ocv_soc); 754 } 755 finish: 756 di->dsoc = pre_soc; 757 di->nac = pre_cap; 758 rk816_bat_init_capacity(di, di->nac); 759 rk816_bat_set_initialized_state(di); 760 BAT_INFO("dl=%d rl=%d cap=%d m=%d v=%d ov=%d c=%d pl=%d ch=%d Ver=%s\n", 761 di->dsoc, di->rsoc, di->remain_cap, di->pwroff_min, 762 rk816_bat_get_avg_voltage(di), rk816_bat_get_ocv_voltage(di), 763 rk816_bat_get_avg_current(di), rk816_bat_get_dsoc(di), 764 rk816_bat_get_usb_state(di), DRIVER_VERSION 765 ); 766 } 767 768 static bool is_rk816_bat_first_poweron(struct battery_info *di) 769 { 770 u8 buf; 771 772 buf = rk816_bat_read(GGSTS_REG); 773 if (buf & BAT_CON) { 774 buf &= ~BAT_CON; 775 rk816_bat_write(GGSTS_REG, buf); 776 return true; 777 } 778 779 return false; 780 } 781 782 static bool rk816_bat_ocv_sw_reset(struct battery_info *di) 783 { 784 u8 buf; 785 786 buf = rk816_bat_read(MISC_MARK_REG); 787 if (((buf & FG_RESET_LATE) && di->pwroff_min >= 30) || 788 (buf & FG_RESET_NOW)) { 789 buf &= ~FG_RESET_LATE; 790 buf &= ~FG_RESET_NOW; 791 rk816_bat_write(MISC_MARK_REG, buf); 792 BAT_INFO("manual reset fuel gauge\n"); 793 return true; 794 } else { 795 return false; 796 } 797 } 798 799 static int rk816_bat_calc_linek(struct battery_info *di) 800 { 801 int linek, diff, delta; 802 803 di->calc_dsoc = di->dsoc; 804 di->calc_rsoc = di->rsoc; 805 di->sm_old_cap = di->remain_cap; 806 807 delta = abs(di->dsoc - di->rsoc); 808 diff = delta * 3; 809 di->sm_meet_soc = (di->dsoc >= di->rsoc) ? 810 (di->dsoc + diff) : (di->rsoc + diff); 811 812 if (di->dsoc < di->rsoc) 813 linek = 1000 * (delta + diff) / DIV(diff); 814 else if (di->dsoc > di->rsoc) 815 linek = 1000 * diff / DIV(delta + diff); 816 else 817 linek = 1000; 818 819 di->sm_chrg_dsoc = di->dsoc * 1000; 820 821 DBG("<%s>. meet=%d, diff=%d, link=%d, calc: dsoc=%d, rsoc=%d\n", 822 __func__, di->sm_meet_soc, diff, linek, 823 di->calc_dsoc, di->calc_rsoc); 824 825 return linek; 826 } 827 828 static int rk816_bat_get_coffset(struct battery_info *di) 829 { 830 int val = 0; 831 832 val |= rk816_bat_read(CAL_OFFSET_REGL) << 0; 833 val |= rk816_bat_read(CAL_OFFSET_REGH) << 8; 834 835 return val; 836 } 837 838 static void rk816_bat_init_poffset(struct battery_info *di) 839 { 840 int coffset, ioffset; 841 842 coffset = rk816_bat_get_coffset(di); 843 ioffset = rk816_bat_get_ioffset(di); 844 di->poffset = coffset - ioffset; 845 } 846 847 static bool is_rk816_bat_exist(struct battery_info *di) 848 { 849 return (rk816_bat_read(SUP_STS_REG) & BAT_EXS) ? true : false; 850 } 851 852 static void rk816_bat_set_current(int input_current) 853 { 854 u8 usb_ctrl; 855 856 usb_ctrl = rk816_bat_read(USB_CTRL_REG); 857 usb_ctrl &= ~INPUT_CUR_MSK; 858 usb_ctrl |= (input_current); 859 rk816_bat_write(USB_CTRL_REG, usb_ctrl); 860 } 861 862 static void rk816_bat_charger_setting(struct battery_info *di, int charger) 863 { 864 static u8 old_charger = UNDEF_CHARGER; 865 866 /*charger changed*/ 867 if (old_charger != charger) { 868 if (charger == NO_CHARGER) 869 rk816_bat_set_current(ILIM_450MA); 870 else if (charger == USB_CHARGER) 871 rk816_bat_set_current(ILIM_450MA); 872 else if (charger == DC_CHARGER || charger == AC_CHARGER) 873 rk816_bat_set_current(di->chrg_cur_input); 874 else 875 BAT_INFO("charger setting error %d\n", charger); 876 877 old_charger = charger; 878 } 879 } 880 881 static int rk816_bat_get_dc_state(struct battery_info *di) 882 { 883 /* struct adc_channel val; */ 884 885 if (di->dc_type == DC_TYPE_OF_NONE) { 886 return NO_CHARGER; 887 } else if (di->dc_type == DC_TYPE_OF_ADC) { 888 /* 889 if (adc_channels_single_shot("saradc", 0, &val)) { 890 printf("read saradc value failed\n"); 891 return NO_CHARGER; 892 } 893 894 return (val.data >= DC_ADC_TRIGGER) ? DC_CHARGER : NO_CHARGER; 895 */ 896 return NO_CHARGER; 897 } else { 898 return (dm_gpio_get_value(di->dc_det)) ? 899 DC_CHARGER : NO_CHARGER; 900 } 901 } 902 903 static int rk816_bat_get_charger_type(struct battery_info *di) 904 { 905 int charger_type = NO_CHARGER; 906 907 /* check by ic hardware: this check make check work safer */ 908 if ((rk816_bat_read(VB_MON_REG) & PLUG_IN_STS) == 0) 909 return NO_CHARGER; 910 911 /* virtual or bat not exist */ 912 if (di->virtual_power) 913 return DC_CHARGER; 914 915 /* check DC first */ 916 charger_type = rk816_bat_get_dc_state(di); 917 if (charger_type == DC_CHARGER) 918 return charger_type; 919 920 /* check USB second */ 921 return rk816_bat_get_usb_state(di); 922 } 923 924 static bool rk816_bat_is_under_threshold(struct battery_info *di) 925 { 926 bool initialize = false; 927 #ifdef CONFIG_DM_CHARGE_DISPLAY 928 struct udevice *dev; 929 int soc, voltage, est_voltage; 930 int err; 931 932 err = uclass_find_first_device(UCLASS_CHARGE_DISPLAY, &dev); 933 if (!err) { 934 est_voltage = rk816_bat_get_avg_voltage(di); 935 soc = charge_display_get_power_on_soc(dev); 936 voltage = charge_display_get_power_on_voltage(dev); 937 DBG("threshold: %d%%, %dmv; now: %d%%, %dmv\n", 938 soc, voltage, di->dsoc, est_voltage); 939 if ((di->dsoc <= soc) || (est_voltage <= voltage)) 940 initialize = true; 941 } 942 #endif 943 944 return initialize; 945 } 946 947 void rk816_bat_init_rsoc(struct battery_info *di) 948 { 949 bool initialize = false; 950 951 di->is_first_power_on = is_rk816_bat_first_poweron(di); 952 /* If first power on, we must do initialization */ 953 if (di->is_first_power_on) 954 initialize = true; 955 /* Only charger online and under threshold, we do initialization */ 956 else if (rk816_bat_get_charger_type(di) != NO_CHARGER) 957 initialize = rk816_bat_is_under_threshold(di); 958 959 if (!initialize) 960 return; 961 962 di->pwroff_min = rk816_bat_get_pwroff_min(di); 963 di->is_sw_reset = rk816_bat_ocv_sw_reset(di); 964 965 if (di->is_first_power_on || di->is_sw_reset) 966 rk816_bat_first_pwron(di); 967 else 968 rk816_bat_not_first_pwron(di); 969 } 970 971 static int rk816_fg_init(struct battery_info *di) 972 { 973 rk816_bat_enable_gauge(di); 974 rk816_bat_set_vol_instant_mode(di); 975 rk816_bat_init_voltage_kb(di); 976 rk816_bat_init_poffset(di); 977 rk816_bat_clr_initialized_state(di); 978 di->dsoc = rk816_bat_get_dsoc(di); 979 980 /* 981 * It's better to init fg in kernel, 982 * so avoid init in uboot as far as possible. 983 */ 984 rk816_bat_init_rsoc(di); 985 rk816_bat_init_chrg_config(di); 986 di->chrg_type = rk816_bat_get_charger_type(di); 987 di->voltage_avg = rk816_bat_get_avg_voltage(di); 988 di->voltage_ocv = rk816_bat_get_ocv_voltage(di); 989 di->current_avg = rk816_bat_get_avg_current(di); 990 di->sm_linek = rk816_bat_calc_linek(di); 991 di->finish_chrg_base = get_timer(0); 992 di->pwr_vol = di->voltage_avg; 993 rk816_bat_charger_setting(di, di->chrg_type); 994 995 printf("Battery: soc=%d%%, voltage=%dmv\n", di->dsoc, di->voltage_avg); 996 997 return 0; 998 } 999 1000 static void rk816_bat_save_dsoc(struct battery_info *di, u8 save_soc) 1001 { 1002 static int old_soc = -1; 1003 1004 if (old_soc != save_soc) { 1005 old_soc = save_soc; 1006 rk816_bat_write(SOC_REG, save_soc); 1007 } 1008 } 1009 1010 static void rk816_bat_save_cap(struct battery_info *di, int cap) 1011 { 1012 u8 buf; 1013 static int old_cap; 1014 1015 if (old_cap == cap) 1016 return; 1017 1018 if (cap >= di->qmax) 1019 cap = di->qmax; 1020 1021 old_cap = cap; 1022 buf = (cap >> 24) & 0xff; 1023 rk816_bat_write(REMAIN_CAP_REG3, buf); 1024 buf = (cap >> 16) & 0xff; 1025 rk816_bat_write(REMAIN_CAP_REG2, buf); 1026 buf = (cap >> 8) & 0xff; 1027 rk816_bat_write(REMAIN_CAP_REG1, buf); 1028 buf = (cap >> 0) & 0xff; 1029 rk816_bat_write(REMAIN_CAP_REG0, buf); 1030 } 1031 1032 static u8 rk816_bat_get_chrg_status(struct battery_info *di) 1033 { 1034 u8 status; 1035 1036 status = rk816_bat_read(SUP_STS_REG) & BAT_STATUS_MSK; 1037 switch (status) { 1038 case CHARGE_OFF: 1039 DBG("CHARGE-OFF...\n"); 1040 break; 1041 case DEAD_CHARGE: 1042 DBG("DEAD CHARGE...\n"); 1043 break; 1044 case TRICKLE_CHARGE: 1045 DBG("TRICKLE CHARGE...\n "); 1046 break; 1047 case CC_OR_CV: 1048 DBG("CC or CV...\n"); 1049 break; 1050 case CHARGE_FINISH: 1051 DBG("CHARGE FINISH...\n"); 1052 break; 1053 case USB_OVER_VOL: 1054 DBG("USB OVER VOL...\n"); 1055 break; 1056 case BAT_TMP_ERR: 1057 DBG("BAT TMP ERROR...\n"); 1058 break; 1059 case TIMER_ERR: 1060 DBG("TIMER ERROR...\n"); 1061 break; 1062 case USB_EXIST: 1063 DBG("USB EXIST...\n"); 1064 break; 1065 case USB_EFF: 1066 DBG(" USB EFF...\n"); 1067 break; 1068 default: 1069 return -EINVAL; 1070 } 1071 1072 return status; 1073 } 1074 1075 static void rk816_bat_finish_chrg(struct battery_info *di) 1076 { 1077 u32 tgt_sec = 0; 1078 1079 if (di->dsoc < 100) { 1080 tgt_sec = di->fcc * 3600 / 100 / FINISH_CALI_CURR; 1081 if (get_timer(di->finish_chrg_base) > SECONDS(tgt_sec)) { 1082 di->finish_chrg_base = get_timer(0); 1083 di->dsoc++; 1084 } 1085 } 1086 DBG("<%s>. sec=%d, finish_sec=%lu\n", __func__, SECONDS(tgt_sec), 1087 get_timer(di->finish_chrg_base)); 1088 } 1089 1090 static void rk816_bat_debug_info(struct battery_info *di) 1091 { 1092 u8 sup_sts, ggcon, ggsts, vb_mod, rtc, thermal, misc; 1093 u8 usb_ctrl, chrg_ctrl1, chrg_ctrl2, chrg_ctrl3; 1094 static const char *name[] = {"NONE", "USB", "AC", "DC", "UNDEF"}; 1095 1096 if (!dbg_enable) 1097 return; 1098 ggcon = rk816_bat_read(GGCON_REG); 1099 ggsts = rk816_bat_read(GGSTS_REG); 1100 sup_sts = rk816_bat_read(SUP_STS_REG); 1101 usb_ctrl = rk816_bat_read(USB_CTRL_REG); 1102 thermal = rk816_bat_read(THERMAL_REG); 1103 vb_mod = rk816_bat_read(VB_MON_REG); 1104 misc = rk816_bat_read(MISC_MARK_REG); 1105 rtc = rk816_bat_read(SECONDS_REG); 1106 chrg_ctrl1 = rk816_bat_read(CHRG_CTRL_REG1); 1107 chrg_ctrl2 = rk816_bat_read(CHRG_CTRL_REG2); 1108 chrg_ctrl3 = rk816_bat_read(CHRG_CTRL_REG3); 1109 1110 DBG("\n---------------------- DEBUG REGS ------------------------\n" 1111 "GGCON=0x%2x, GGSTS=0x%2x, RTC=0x%2x, SUP_STS= 0x%2x\n" 1112 "VB_MOD=0x%2x, USB_CTRL=0x%2x, THERMAL=0x%2x, MISC=0x%2x\n" 1113 "CHRG_CTRL:REG1=0x%2x, REG2=0x%2x, REG3=0x%2x\n", 1114 ggcon, ggsts, rtc, sup_sts, vb_mod, usb_ctrl, 1115 thermal, misc, chrg_ctrl1, chrg_ctrl2, chrg_ctrl3 1116 ); 1117 DBG("----------------------------------------------------------\n" 1118 "Dsoc=%d, Rsoc=%d, Vavg=%d, Iavg=%d, Cap=%d, Fcc=%d, d=%d\n" 1119 "K=%d, old_cap=%d, charger=%s, Is=%d, Ip=%d, Vs=%d\n" 1120 "min=%d, meet: soc=%d, calc: dsoc=%d, rsoc=%d, Vocv=%d\n" 1121 "off: i=0x%x, c=0x%x, max=%d, ocv_c=%d, halt: st=%d, cnt=%d\n" 1122 "pwr: dsoc=%d, rsoc=%d, vol=%d, exist=%d\n", 1123 di->dsoc, rk816_bat_get_rsoc(di), rk816_bat_get_avg_voltage(di), 1124 rk816_bat_get_avg_current(di), di->remain_cap, di->fcc, 1125 di->rsoc - di->dsoc, 1126 di->sm_linek, di->sm_old_cap, name[di->chrg_type], 1127 CHRG_CUR_SEL[chrg_ctrl1 & 0x0f], 1128 CHRG_CUR_INPUT[usb_ctrl & 0x0f], 1129 CHRG_VOL_SEL[(chrg_ctrl1 & 0x70) >> 4], di->pwroff_min, 1130 di->sm_meet_soc, di->calc_dsoc, di->calc_rsoc, 1131 rk816_bat_get_ocv_voltage(di), rk816_bat_get_ioffset(di), 1132 rk816_bat_get_coffset(di), di->is_max_soc_offset, 1133 di->is_ocv_calib, di->is_halt, di->halt_cnt, di->pwr_dsoc, 1134 di->pwr_rsoc, di->pwr_vol, is_rk816_bat_exist(di) 1135 ); 1136 rk816_bat_get_chrg_status(di); 1137 DBG("###########################################################\n"); 1138 } 1139 1140 static void rk816_bat_linek_algorithm(struct battery_info *di) 1141 { 1142 int delta_cap, ydsoc, tmp; 1143 u8 chg_st = rk816_bat_get_chrg_status(di); 1144 1145 /* slow down */ 1146 if (di->dsoc == 99) 1147 di->sm_linek = CHRG_FULL_K; 1148 else if (di->dsoc >= CHRG_TERM_DSOC && di->current_avg > TERM_CALI_CURR) 1149 di->sm_linek = CHRG_TERM_K; 1150 1151 delta_cap = di->remain_cap - di->sm_old_cap; 1152 ydsoc = di->sm_linek * delta_cap * 100 / DIV(di->fcc); 1153 if (ydsoc > 0) { 1154 tmp = (di->sm_chrg_dsoc + 1) / 1000; 1155 if (tmp != di->dsoc) 1156 di->sm_chrg_dsoc = di->dsoc * 1000; 1157 di->sm_chrg_dsoc += ydsoc; 1158 di->dsoc = (di->sm_chrg_dsoc + 1) / 1000; 1159 di->sm_old_cap = di->remain_cap; 1160 if (di->dsoc == di->rsoc && di->sm_linek != CHRG_FULL_K && 1161 di->sm_linek != CHRG_TERM_K) 1162 di->sm_linek = 1000; 1163 } 1164 1165 if ((di->sm_linek == 1000 || di->dsoc >= 100) && 1166 (chg_st != CHARGE_FINISH)) { 1167 if (di->sm_linek == 1000) 1168 di->dsoc = di->rsoc; 1169 di->sm_chrg_dsoc = di->dsoc * 1000; 1170 } 1171 1172 DBG("linek=%d, sm_dsoc=%d, delta_cap=%d, ydsoc=%d, old_cap=%d\n" 1173 "calc: dsoc=%d, rsoc=%d, meet=%d\n", 1174 di->sm_linek, di->sm_chrg_dsoc, delta_cap, ydsoc, di->sm_old_cap, 1175 di->calc_dsoc, di->calc_rsoc, di->sm_meet_soc); 1176 } 1177 1178 static int rk816_bat_get_iadc(struct battery_info *di) 1179 { 1180 int val = 0; 1181 1182 val |= rk816_bat_read(BAT_CUR_AVG_REGL) << 0; 1183 val |= rk816_bat_read(BAT_CUR_AVG_REGH) << 8; 1184 if (val > 2047) 1185 val -= 4096; 1186 1187 return val; 1188 } 1189 1190 static bool rk816_bat_adc_calib(struct battery_info *di) 1191 { 1192 int i, ioffset, coffset, adc; 1193 1194 if (abs(di->current_avg) < ADC_CALIB_THRESHOLD) 1195 return false; 1196 1197 for (i = 0; i < 5; i++) { 1198 adc = rk816_bat_get_iadc(di); 1199 coffset = rk816_bat_get_coffset(di); 1200 rk816_bat_set_coffset(di, coffset + adc); 1201 mdelay(200); 1202 adc = rk816_bat_get_iadc(di); 1203 if (abs(adc) < ADC_CALIB_THRESHOLD) { 1204 coffset = rk816_bat_get_coffset(di); 1205 ioffset = rk816_bat_get_ioffset(di); 1206 di->poffset = coffset - ioffset; 1207 rk816_bat_write(POFFSET_REG, di->poffset); 1208 BAT_INFO("new offset:c=0x%x, i=0x%x, p=0x%x\n", 1209 coffset, ioffset, di->poffset); 1210 return true; 1211 } else { 1212 BAT_INFO("coffset calib again %d..\n", i); 1213 rk816_bat_set_coffset(di, coffset); 1214 mdelay(200); 1215 } 1216 } 1217 1218 return false; 1219 } 1220 1221 static void rk816_bat_smooth_charge(struct battery_info *di) 1222 { 1223 u8 chg_st = rk816_bat_get_chrg_status(di); 1224 1225 if (di->vol_mode_base && get_timer(di->vol_mode_base) > SECONDS(10)) { 1226 rk816_bat_set_vol_avg_mode(di); 1227 di->vol_mode_base = 0; 1228 } 1229 1230 /* not charge mode and not keep in uboot charge: exit */ 1231 if ((di->chrg_type == NO_CHARGER) || 1232 !rk816_bat_is_initialized(di)) { 1233 DBG("chrg=%d, initialized=%d\n", di->chrg_type, 1234 rk816_bat_is_initialized(di)); 1235 goto out; 1236 } 1237 1238 /* update rsoc and remain cap */ 1239 di->remain_cap = rk816_bat_get_coulomb_cap(di); 1240 di->rsoc = rk816_bat_get_rsoc(di); 1241 if (di->remain_cap > di->fcc) { 1242 di->sm_old_cap -= (di->remain_cap - di->fcc); 1243 rk816_bat_init_capacity(di, di->fcc); 1244 } 1245 1246 /* finish charge step */ 1247 if (chg_st == CHARGE_FINISH) { 1248 DBG("finish charge step...\n"); 1249 if (di->adc_allow_update) 1250 di->adc_allow_update = !rk816_bat_adc_calib(di); 1251 rk816_bat_finish_chrg(di); 1252 rk816_bat_init_capacity(di, di->fcc); 1253 } else { 1254 DBG("smooth charge step...\n"); 1255 di->adc_allow_update = true; 1256 di->finish_chrg_base = get_timer(0); 1257 rk816_bat_linek_algorithm(di); 1258 } 1259 1260 /* dsoc limit */ 1261 if (di->dsoc > 100) 1262 di->dsoc = 100; 1263 else if (di->dsoc < 0) 1264 di->dsoc = 0; 1265 1266 rk816_bat_save_dsoc(di, di->dsoc); 1267 rk816_bat_save_cap(di, di->remain_cap); 1268 out: 1269 rk816_bat_debug_info(di); 1270 } 1271 1272 static int rk816_bat_update_get_soc(struct udevice *dev) 1273 { 1274 struct battery_info *di = dev_get_priv(dev); 1275 static ulong seconds; 1276 1277 /* set charge current */ 1278 di->chrg_type = 1279 rk816_bat_get_charger_type(di); 1280 rk816_bat_charger_setting(di, di->chrg_type); 1281 1282 /* fg calc every 5 seconds */ 1283 if (!seconds) 1284 seconds = get_timer(0); 1285 if (get_timer(seconds) >= SECONDS(5)) { 1286 seconds = get_timer(0); 1287 rk816_bat_smooth_charge(di); 1288 } 1289 1290 /* bat exist, fg init success(dts pass) and uboot charge: report data */ 1291 if (!di->virtual_power && di->voltage_k) 1292 return di->dsoc; 1293 else 1294 return VIRTUAL_POWER_SOC; 1295 } 1296 1297 static int rk816_bat_update_get_voltage(struct udevice *dev) 1298 { 1299 struct battery_info *di = dev_get_priv(dev); 1300 1301 if (!di->virtual_power && di->voltage_k) 1302 return rk816_bat_get_est_voltage(di); 1303 else 1304 return VIRTUAL_POWER_VOL; 1305 } 1306 1307 static bool rk816_bat_update_get_chrg_online(struct udevice *dev) 1308 { 1309 struct battery_info *di = dev_get_priv(dev); 1310 1311 return rk816_bat_get_charger_type(di); 1312 } 1313 1314 static struct dm_fuel_gauge_ops fg_ops = { 1315 .get_soc = rk816_bat_update_get_soc, 1316 .get_voltage = rk816_bat_update_get_voltage, 1317 .get_chrg_online = rk816_bat_update_get_chrg_online, 1318 }; 1319 1320 static int rk816_bat_parse_dt(struct battery_info *di, void const *blob) 1321 { 1322 int node, parent, len, err; 1323 const char *prop; 1324 1325 parent = fdt_node_offset_by_compatible(blob, 0, "rockchip,rk816"); 1326 if (parent < 0) { 1327 printf("can't find rockchip,rk816 node\n"); 1328 return -ENODEV; 1329 } 1330 1331 if (!fdtdec_get_is_enabled(blob, parent)) { 1332 DBG("rk816 node disabled\n"); 1333 return -ENODEV; 1334 } 1335 1336 node = fdt_subnode_offset_namelen(blob, parent, "battery", 7); 1337 if (node < 0) { 1338 debug("can't find battery node\n"); 1339 di->chrg_cur_input = ILIM_2000MA; 1340 return -EINVAL; 1341 } 1342 1343 prop = fdt_getprop(blob, node, "ocv_table", &len); 1344 if (!prop) { 1345 printf("can't find ocv_table prop\n"); 1346 return -EINVAL; 1347 } 1348 1349 di->ocv_table = calloc(len, 1); 1350 if (!di->ocv_table) { 1351 printf("can't calloc ocv_table\n"); 1352 return -ENOMEM; 1353 } 1354 1355 di->ocv_size = len / 4; 1356 err = fdtdec_get_int_array(blob, node, "ocv_table", 1357 di->ocv_table, di->ocv_size); 1358 if (err < 0) { 1359 printf("read ocv_table error\n"); 1360 free(di->ocv_table); 1361 return -EINVAL; 1362 } 1363 1364 di->design_cap = fdtdec_get_int(blob, node, "design_capacity", -1); 1365 if (di->design_cap < 0) { 1366 printf("read design_capacity error\n"); 1367 return -EINVAL; 1368 } 1369 1370 di->qmax = fdtdec_get_int(blob, node, "design_qmax", -1); 1371 if (di->qmax < 0) { 1372 printf("read design_qmax error\n"); 1373 return -EINVAL; 1374 } 1375 1376 di->dts_vol_sel = fdtdec_get_int(blob, node, "max_chrg_voltage", 4200); 1377 di->dts_cur_input = fdtdec_get_int(blob, node, 1378 "max_input_current", 2000); 1379 di->dts_cur_sel = fdtdec_get_int(blob, node, "max_chrg_current", 1200); 1380 di->max_soc_offset = fdtdec_get_int(blob, node, "max_soc_offset", 70); 1381 di->virtual_power = fdtdec_get_int(blob, node, "virtual_power", 0); 1382 di->bat_res = fdtdec_get_int(blob, node, "bat_res", 135); 1383 di->dc_det_adc = fdtdec_get_int(blob, node, "dc_det_adc", 0); 1384 if (di->dc_det_adc <= 0) { 1385 if (!gpio_request_by_name_nodev(offset_to_ofnode(node), 1386 "dc_det_gpio", 1387 0, di->dc_det, GPIOD_IS_IN)) { 1388 di->dc_type = DC_TYPE_OF_GPIO; 1389 } else { 1390 di->dc_type = DC_TYPE_OF_NONE; 1391 } 1392 } else { 1393 di->dc_type = DC_TYPE_OF_ADC; 1394 } 1395 1396 if (!is_rk816_bat_exist(di)) 1397 di->virtual_power = 1; 1398 1399 DBG("-------------------------------:\n"); 1400 DBG("max_input_current:%d\n", di->dts_cur_input); 1401 DBG("max_chrg_current:%d\n", di->dts_cur_sel); 1402 DBG("max_chrg_voltage:%d\n", di->dts_vol_sel); 1403 DBG("design_capacity :%d\n", di->design_cap); 1404 DBG("design_qmax:%d\n", di->qmax); 1405 DBG("max_soc_offset:%d\n", di->max_soc_offset); 1406 DBG("dc_det_adc:%d\n", di->dc_det_adc); 1407 1408 return 0; 1409 } 1410 1411 static int rk816_fg_probe(struct udevice *dev) 1412 { 1413 struct rk8xx_priv *priv = dev_get_priv(dev->parent); 1414 struct battery_info *di = dev_get_priv(dev); 1415 int ret; 1416 1417 if (priv->variant != 0x8160) { 1418 debug("Not support pmic variant: rk%x\n", priv->variant); 1419 return -EINVAL; 1420 } 1421 1422 g_pmic_dev = dev->parent; 1423 ret = rk816_bat_parse_dt(di, gd->fdt_blob); 1424 if (ret) 1425 return ret; 1426 1427 return rk816_fg_init(di); 1428 } 1429 1430 U_BOOT_DRIVER(rk816_fg) = { 1431 .name = "rk816_fg", 1432 .id = UCLASS_FG, 1433 .probe = rk816_fg_probe, 1434 .ops = &fg_ops, 1435 .priv_auto_alloc_size = sizeof(struct battery_info), 1436 }; 1437 1438