1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* ROHM BD71815, BD71828 and BD71878 Charger driver */ 3 4 #include <linux/interrupt.h> 5 #include <linux/kernel.h> 6 #include <linux/mfd/rohm-bd71815.h> 7 #include <linux/mfd/rohm-bd71828.h> 8 #include <linux/module.h> 9 #include <linux/mod_devicetable.h> 10 #include <linux/platform_device.h> 11 #include <linux/property.h> 12 #include <linux/power_supply.h> 13 #include <linux/slab.h> 14 15 /* common defines */ 16 #define BD7182x_MASK_VBAT_U 0x1f 17 #define BD7182x_MASK_VDCIN_U 0x0f 18 #define BD7182x_MASK_IBAT_U 0x3f 19 #define BD7182x_MASK_CURDIR_DISCHG 0x80 20 #define BD7182x_MASK_CHG_STATE 0x7f 21 #define BD7182x_MASK_BAT_TEMP 0x07 22 #define BD7182x_MASK_DCIN_DET BIT(0) 23 #define BD7182x_MASK_CONF_PON BIT(0) 24 #define BD71815_MASK_CONF_XSTB BIT(1) 25 #define BD7182x_MASK_BAT_STAT 0x3f 26 #define BD7182x_MASK_DCIN_STAT 0x07 27 28 #define BD7182x_MASK_WDT_AUTO 0x40 29 #define BD7182x_MASK_VBAT_ALM_LIMIT_U 0x01 30 #define BD7182x_MASK_CHG_EN 0x01 31 32 #define BD7182x_DCIN_COLLAPSE_DEFAULT 0x36 33 34 #define MAX_CURRENT_DEFAULT 890000 /* uA */ 35 #define AC_NAME "bd71828_ac" 36 #define BAT_NAME "bd71828_bat" 37 38 #define BAT_OPEN 0x7 39 40 /* 41 * VBAT Low voltage detection Threshold 42 * 0x00D4*16mV = 212*0.016 = 3.392v 43 */ 44 #define VBAT_LOW_TH 0x00D4 45 46 struct pwr_regs { 47 u8 vbat_avg; 48 u8 ibat; 49 u8 ibat_avg; 50 u8 btemp_vth; 51 u8 chg_state; 52 u8 bat_temp; 53 u8 dcin_stat; 54 u8 dcin_collapse_limit; 55 u8 chg_set1; 56 u8 chg_en; 57 u8 vbat_alm_limit_u; 58 u8 conf; 59 u8 vdcin; 60 }; 61 62 static const struct pwr_regs pwr_regs_bd71828 = { 63 .vbat_avg = BD71828_REG_VBAT_U, 64 .ibat = BD71828_REG_IBAT_U, 65 .ibat_avg = BD71828_REG_IBAT_AVG_U, 66 .btemp_vth = BD71828_REG_VM_BTMP_U, 67 .chg_state = BD71828_REG_CHG_STATE, 68 .bat_temp = BD71828_REG_BAT_TEMP, 69 .dcin_stat = BD71828_REG_DCIN_STAT, 70 .dcin_collapse_limit = BD71828_REG_DCIN_CLPS, 71 .chg_set1 = BD71828_REG_CHG_SET1, 72 .chg_en = BD71828_REG_CHG_EN, 73 .vbat_alm_limit_u = BD71828_REG_ALM_VBAT_LIMIT_U, 74 .conf = BD71828_REG_CONF, 75 .vdcin = BD71828_REG_VDCIN_U, 76 }; 77 78 static const struct pwr_regs pwr_regs_bd71815 = { 79 .vbat_avg = BD71815_REG_VM_SA_VBAT_U, 80 /* BD71815 does not have separate current and current avg */ 81 .ibat = BD71815_REG_CC_CURCD_U, 82 .ibat_avg = BD71815_REG_CC_CURCD_U, 83 84 .btemp_vth = BD71815_REG_VM_BTMP, 85 .chg_state = BD71815_REG_CHG_STATE, 86 .bat_temp = BD71815_REG_BAT_TEMP, 87 .dcin_stat = BD71815_REG_DCIN_STAT, 88 .dcin_collapse_limit = BD71815_REG_DCIN_CLPS, 89 .chg_set1 = BD71815_REG_CHG_SET1, 90 .chg_en = BD71815_REG_CHG_SET1, 91 .vbat_alm_limit_u = BD71815_REG_ALM_VBAT_TH_U, 92 .conf = BD71815_REG_CONF, 93 94 .vdcin = BD71815_REG_VM_DCIN_U, 95 }; 96 97 struct bd71828_power { 98 struct regmap *regmap; 99 enum rohm_chip_type chip_type; 100 struct device *dev; 101 struct power_supply *ac; 102 struct power_supply *bat; 103 104 const struct pwr_regs *regs; 105 /* Reg val to uA */ 106 int curr_factor; 107 int rsens; 108 int (*get_temp)(struct bd71828_power *pwr, int *temp); 109 int (*bat_inserted)(struct bd71828_power *pwr); 110 }; 111 112 static int bd7182x_write16(struct bd71828_power *pwr, int reg, u16 val) 113 { 114 __be16 tmp; 115 116 tmp = cpu_to_be16(val); 117 118 return regmap_bulk_write(pwr->regmap, reg, &tmp, sizeof(tmp)); 119 } 120 121 static int bd7182x_read16_himask(struct bd71828_power *pwr, int reg, int himask, 122 u16 *val) 123 { 124 struct regmap *regmap = pwr->regmap; 125 int ret; 126 __be16 rvals; 127 u8 *tmp = (u8 *)&rvals; 128 129 ret = regmap_bulk_read(regmap, reg, &rvals, sizeof(*val)); 130 if (!ret) { 131 *tmp &= himask; 132 *val = be16_to_cpu(rvals); 133 } 134 135 return ret; 136 } 137 138 static int bd71828_get_vbat(struct bd71828_power *pwr, int *vcell) 139 { 140 u16 tmp_vcell; 141 int ret; 142 143 ret = bd7182x_read16_himask(pwr, pwr->regs->vbat_avg, 144 BD7182x_MASK_VBAT_U, &tmp_vcell); 145 if (ret) 146 dev_err(pwr->dev, "Failed to read battery average voltage\n"); 147 else 148 *vcell = ((int)tmp_vcell) * 1000; 149 150 return ret; 151 } 152 153 static int bd71828_get_current_ds_adc(struct bd71828_power *pwr, int *curr, int *curr_avg) 154 { 155 __be16 tmp_curr; 156 char *tmp = (char *)&tmp_curr; 157 int dir = 1; 158 int regs[] = { pwr->regs->ibat, pwr->regs->ibat_avg }; 159 int *vals[] = { curr, curr_avg }; 160 int ret, i; 161 162 for (dir = 1, i = 0; i < ARRAY_SIZE(regs); i++) { 163 ret = regmap_bulk_read(pwr->regmap, regs[i], &tmp_curr, 164 sizeof(tmp_curr)); 165 if (ret) 166 break; 167 168 if (*tmp & BD7182x_MASK_CURDIR_DISCHG) 169 dir = -1; 170 171 *tmp &= BD7182x_MASK_IBAT_U; 172 173 *vals[i] = dir * ((int)be16_to_cpu(tmp_curr)) * pwr->curr_factor; 174 } 175 176 return ret; 177 } 178 179 /* Unit is tenths of degree C */ 180 static int bd71815_get_temp(struct bd71828_power *pwr, int *temp) 181 { 182 struct regmap *regmap = pwr->regmap; 183 int ret; 184 int t; 185 186 ret = regmap_read(regmap, pwr->regs->btemp_vth, &t); 187 if (ret) 188 return ret; 189 190 t = 200 - t; 191 192 if (t > 200) { 193 dev_err(pwr->dev, "Failed to read battery temperature\n"); 194 return -ENODATA; 195 } 196 197 return 0; 198 } 199 200 /* Unit is tenths of degree C */ 201 static int bd71828_get_temp(struct bd71828_power *pwr, int *temp) 202 { 203 u16 t; 204 int ret; 205 int tmp = 200 * 10000; 206 207 ret = bd7182x_read16_himask(pwr, pwr->regs->btemp_vth, 208 BD71828_MASK_VM_BTMP_U, &t); 209 if (ret) 210 return ret; 211 212 if (t > 3200) { 213 dev_err(pwr->dev, 214 "Failed to read battery temperature\n"); 215 return -ENODATA; 216 } 217 218 tmp -= 625ULL * (unsigned int)t; 219 *temp = tmp / 1000; 220 221 return ret; 222 } 223 224 static int bd71828_charge_status(struct bd71828_power *pwr, 225 int *s, int *h) 226 { 227 unsigned int state; 228 int status, health; 229 int ret = 1; 230 231 ret = regmap_read(pwr->regmap, pwr->regs->chg_state, &state); 232 if (ret) { 233 dev_err(pwr->dev, "charger status reading failed (%d)\n", ret); 234 return ret; 235 } 236 237 state &= BD7182x_MASK_CHG_STATE; 238 239 dev_dbg(pwr->dev, "CHG_STATE %d\n", state); 240 241 switch (state) { 242 case 0x00: 243 status = POWER_SUPPLY_STATUS_DISCHARGING; 244 health = POWER_SUPPLY_HEALTH_GOOD; 245 break; 246 case 0x01: 247 case 0x02: 248 case 0x03: 249 case 0x0E: 250 status = POWER_SUPPLY_STATUS_CHARGING; 251 health = POWER_SUPPLY_HEALTH_GOOD; 252 break; 253 case 0x0F: 254 status = POWER_SUPPLY_STATUS_FULL; 255 health = POWER_SUPPLY_HEALTH_GOOD; 256 break; 257 case 0x10: 258 case 0x11: 259 case 0x12: 260 case 0x13: 261 case 0x14: 262 case 0x20: 263 case 0x21: 264 case 0x22: 265 case 0x23: 266 case 0x24: 267 status = POWER_SUPPLY_STATUS_NOT_CHARGING; 268 health = POWER_SUPPLY_HEALTH_OVERHEAT; 269 break; 270 case 0x30: 271 case 0x31: 272 case 0x32: 273 case 0x40: 274 status = POWER_SUPPLY_STATUS_DISCHARGING; 275 health = POWER_SUPPLY_HEALTH_GOOD; 276 break; 277 case 0x7f: 278 default: 279 status = POWER_SUPPLY_STATUS_NOT_CHARGING; 280 health = POWER_SUPPLY_HEALTH_DEAD; 281 break; 282 } 283 284 if (s) 285 *s = status; 286 if (h) 287 *h = health; 288 289 return ret; 290 } 291 292 static int get_chg_online(struct bd71828_power *pwr, int *chg_online) 293 { 294 int r, ret; 295 296 ret = regmap_read(pwr->regmap, pwr->regs->dcin_stat, &r); 297 if (ret) { 298 dev_err(pwr->dev, "Failed to read DCIN status\n"); 299 return ret; 300 } 301 *chg_online = ((r & BD7182x_MASK_DCIN_DET) != 0); 302 303 return 0; 304 } 305 306 static int get_bat_online(struct bd71828_power *pwr, int *bat_online) 307 { 308 int r, ret; 309 310 ret = regmap_read(pwr->regmap, pwr->regs->bat_temp, &r); 311 if (ret) { 312 dev_err(pwr->dev, "Failed to read battery temperature\n"); 313 return ret; 314 } 315 *bat_online = ((r & BD7182x_MASK_BAT_TEMP) != BAT_OPEN); 316 317 return 0; 318 } 319 320 static int bd71828_bat_inserted(struct bd71828_power *pwr) 321 { 322 int ret, val; 323 324 ret = regmap_read(pwr->regmap, pwr->regs->conf, &val); 325 if (ret) { 326 dev_err(pwr->dev, "Failed to read CONF register\n"); 327 return 0; 328 } 329 ret = val & BD7182x_MASK_CONF_PON; 330 331 if (ret) 332 regmap_update_bits(pwr->regmap, pwr->regs->conf, 333 BD7182x_MASK_CONF_PON, 0); 334 335 return ret; 336 } 337 338 static int bd71815_bat_inserted(struct bd71828_power *pwr) 339 { 340 int ret, val; 341 342 ret = regmap_read(pwr->regmap, pwr->regs->conf, &val); 343 if (ret) { 344 dev_err(pwr->dev, "Failed to read CONF register\n"); 345 return ret; 346 } 347 348 ret = !(val & BD71815_MASK_CONF_XSTB); 349 if (ret) 350 regmap_write(pwr->regmap, pwr->regs->conf, val | 351 BD71815_MASK_CONF_XSTB); 352 353 return ret; 354 } 355 356 static int bd71828_init_hardware(struct bd71828_power *pwr) 357 { 358 int ret; 359 360 /* TODO: Collapse limit should come from device-tree ? */ 361 ret = regmap_write(pwr->regmap, pwr->regs->dcin_collapse_limit, 362 BD7182x_DCIN_COLLAPSE_DEFAULT); 363 if (ret) { 364 dev_err(pwr->dev, "Failed to write DCIN collapse limit\n"); 365 return ret; 366 } 367 368 ret = pwr->bat_inserted(pwr); 369 if (ret < 0) 370 return ret; 371 372 if (ret) { 373 /* WDT_FST auto set */ 374 ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_set1, 375 BD7182x_MASK_WDT_AUTO, 376 BD7182x_MASK_WDT_AUTO); 377 if (ret) 378 return ret; 379 380 ret = bd7182x_write16(pwr, pwr->regs->vbat_alm_limit_u, 381 VBAT_LOW_TH); 382 if (ret) 383 return ret; 384 385 /* 386 * On BD71815 "we mask the power-state" from relax detection. 387 * I am unsure what the impact of the power-state would be if 388 * we didn't - but this is what the vendor driver did - and 389 * that driver has been used in few projects so I just assume 390 * this is needed. 391 */ 392 if (pwr->chip_type == ROHM_CHIP_TYPE_BD71815) { 393 ret = regmap_set_bits(pwr->regmap, 394 BD71815_REG_REX_CTRL_1, 395 REX_PMU_STATE_MASK); 396 if (ret) 397 return ret; 398 } 399 } 400 401 return 0; 402 } 403 404 static int bd71828_charger_get_property(struct power_supply *psy, 405 enum power_supply_property psp, 406 union power_supply_propval *val) 407 { 408 struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent); 409 u32 vot; 410 u16 tmp; 411 int online; 412 int ret; 413 414 switch (psp) { 415 case POWER_SUPPLY_PROP_ONLINE: 416 ret = get_chg_online(pwr, &online); 417 if (!ret) 418 val->intval = online; 419 break; 420 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 421 ret = bd7182x_read16_himask(pwr, pwr->regs->vdcin, 422 BD7182x_MASK_VDCIN_U, &tmp); 423 if (ret) 424 return ret; 425 426 vot = tmp; 427 /* 5 milli volt steps */ 428 val->intval = 5000 * vot; 429 break; 430 default: 431 return -EINVAL; 432 } 433 434 return 0; 435 } 436 437 static int bd71828_battery_get_property(struct power_supply *psy, 438 enum power_supply_property psp, 439 union power_supply_propval *val) 440 { 441 struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent); 442 int ret = 0; 443 int status, health, tmp, curr, curr_avg, chg_en; 444 445 if (psp == POWER_SUPPLY_PROP_STATUS || 446 psp == POWER_SUPPLY_PROP_HEALTH || 447 psp == POWER_SUPPLY_PROP_CHARGE_TYPE) 448 ret = bd71828_charge_status(pwr, &status, &health); 449 else if (psp == POWER_SUPPLY_PROP_CURRENT_AVG || 450 psp == POWER_SUPPLY_PROP_CURRENT_NOW) 451 ret = bd71828_get_current_ds_adc(pwr, &curr, &curr_avg); 452 if (ret) 453 return ret; 454 455 switch (psp) { 456 case POWER_SUPPLY_PROP_STATUS: 457 val->intval = status; 458 break; 459 case POWER_SUPPLY_PROP_HEALTH: 460 val->intval = health; 461 break; 462 case POWER_SUPPLY_PROP_PRESENT: 463 ret = get_bat_online(pwr, &tmp); 464 if (!ret) 465 val->intval = tmp; 466 break; 467 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 468 ret = bd71828_get_vbat(pwr, &tmp); 469 val->intval = tmp; 470 break; 471 case POWER_SUPPLY_PROP_TECHNOLOGY: 472 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 473 break; 474 case POWER_SUPPLY_PROP_CURRENT_AVG: 475 val->intval = curr_avg; 476 break; 477 case POWER_SUPPLY_PROP_CURRENT_NOW: 478 val->intval = curr; 479 break; 480 case POWER_SUPPLY_PROP_CURRENT_MAX: 481 val->intval = MAX_CURRENT_DEFAULT; 482 break; 483 case POWER_SUPPLY_PROP_TEMP: 484 ret = pwr->get_temp(pwr, &val->intval); 485 break; 486 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 487 ret = regmap_read(pwr->regmap, pwr->regs->chg_en, &chg_en); 488 if (ret) 489 return ret; 490 491 val->intval = (chg_en & BD7182x_MASK_CHG_EN) ? 492 POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO : 493 POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE; 494 break; 495 default: 496 ret = -EINVAL; 497 break; 498 } 499 500 return ret; 501 } 502 503 static int bd71828_battery_set_property(struct power_supply *psy, 504 enum power_supply_property psp, 505 const union power_supply_propval *val) 506 { 507 struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent); 508 int ret = 0; 509 510 switch (psp) { 511 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 512 if (val->intval == POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) 513 ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_en, 514 BD7182x_MASK_CHG_EN, 515 BD7182x_MASK_CHG_EN); 516 else 517 ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_en, 518 BD7182x_MASK_CHG_EN, 519 0); 520 break; 521 default: 522 return -EINVAL; 523 } 524 525 return ret; 526 } 527 528 static int bd71828_battery_property_is_writeable(struct power_supply *psy, 529 enum power_supply_property psp) 530 { 531 switch (psp) { 532 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 533 return true; 534 default: 535 return false; 536 } 537 } 538 539 /** @brief ac properties */ 540 static const enum power_supply_property bd71828_charger_props[] = { 541 POWER_SUPPLY_PROP_ONLINE, 542 POWER_SUPPLY_PROP_VOLTAGE_NOW, 543 }; 544 545 static const enum power_supply_property bd71828_battery_props[] = { 546 POWER_SUPPLY_PROP_STATUS, 547 POWER_SUPPLY_PROP_HEALTH, 548 POWER_SUPPLY_PROP_VOLTAGE_NOW, 549 POWER_SUPPLY_PROP_HEALTH, 550 POWER_SUPPLY_PROP_PRESENT, 551 POWER_SUPPLY_PROP_TECHNOLOGY, 552 POWER_SUPPLY_PROP_TEMP, 553 POWER_SUPPLY_PROP_CURRENT_AVG, 554 POWER_SUPPLY_PROP_CURRENT_NOW, 555 POWER_SUPPLY_PROP_CURRENT_MAX, 556 POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR, 557 }; 558 559 /** @brief powers supplied by bd71828_ac */ 560 static char *bd71828_ac_supplied_to[] = { 561 BAT_NAME, 562 }; 563 564 static const struct power_supply_desc bd71828_ac_desc = { 565 .name = AC_NAME, 566 .type = POWER_SUPPLY_TYPE_MAINS, 567 .properties = bd71828_charger_props, 568 .num_properties = ARRAY_SIZE(bd71828_charger_props), 569 .get_property = bd71828_charger_get_property, 570 }; 571 572 static const struct power_supply_desc bd71828_bat_desc = { 573 .name = BAT_NAME, 574 .type = POWER_SUPPLY_TYPE_BATTERY, 575 .charge_behaviours = BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) | 576 BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE), 577 .properties = bd71828_battery_props, 578 .num_properties = ARRAY_SIZE(bd71828_battery_props), 579 .get_property = bd71828_battery_get_property, 580 .set_property = bd71828_battery_set_property, 581 .property_is_writeable = bd71828_battery_property_is_writeable, 582 }; 583 584 #define RSENS_CURR 10000000LLU 585 586 #define BD_ISR_NAME(name) \ 587 bd7181x_##name##_isr 588 589 #define BD_ISR_BAT(name, print, run_gauge) \ 590 static irqreturn_t BD_ISR_NAME(name)(int irq, void *data) \ 591 { \ 592 struct bd71828_power *pwr = (struct bd71828_power *)data; \ 593 \ 594 dev_dbg(pwr->dev, "%s\n", print); \ 595 power_supply_changed(pwr->bat); \ 596 \ 597 return IRQ_HANDLED; \ 598 } 599 600 #define BD_ISR_AC(name, print, run_gauge) \ 601 static irqreturn_t BD_ISR_NAME(name)(int irq, void *data) \ 602 { \ 603 struct bd71828_power *pwr = (struct bd71828_power *)data; \ 604 \ 605 power_supply_changed(pwr->ac); \ 606 dev_dbg(pwr->dev, "%s\n", print); \ 607 power_supply_changed(pwr->bat); \ 608 \ 609 return IRQ_HANDLED; \ 610 } 611 612 #define BD_ISR_DUMMY(name, print) \ 613 static irqreturn_t BD_ISR_NAME(name)(int irq, void *data) \ 614 { \ 615 struct bd71828_power *pwr = (struct bd71828_power *)data; \ 616 \ 617 dev_dbg(pwr->dev, "%s\n", print); \ 618 \ 619 return IRQ_HANDLED; \ 620 } 621 622 BD_ISR_BAT(chg_state_changed, "CHG state changed", true) 623 /* DCIN voltage changes */ 624 BD_ISR_AC(dcin_removed, "DCIN removed", true) 625 BD_ISR_AC(clps_out, "DCIN voltage back to normal", true) 626 BD_ISR_AC(clps_in, "DCIN voltage collapsed", false) 627 BD_ISR_AC(dcin_ovp_res, "DCIN voltage normal", true) 628 BD_ISR_AC(dcin_ovp_det, "DCIN OVER VOLTAGE", true) 629 630 BD_ISR_DUMMY(dcin_mon_det, "DCIN voltage below threshold") 631 BD_ISR_DUMMY(dcin_mon_res, "DCIN voltage above threshold") 632 633 BD_ISR_DUMMY(vsys_uv_res, "VSYS under-voltage cleared") 634 BD_ISR_DUMMY(vsys_uv_det, "VSYS under-voltage") 635 BD_ISR_DUMMY(vsys_low_res, "'VSYS low' cleared") 636 BD_ISR_DUMMY(vsys_low_det, "VSYS low") 637 BD_ISR_DUMMY(vsys_mon_res, "VSYS mon - resumed") 638 BD_ISR_DUMMY(vsys_mon_det, "VSYS mon - detected") 639 BD_ISR_BAT(chg_wdg_temp, "charger temperature watchdog triggered", true) 640 BD_ISR_BAT(chg_wdg, "charging watchdog triggered", true) 641 BD_ISR_BAT(bat_removed, "Battery removed", true) 642 BD_ISR_BAT(bat_det, "Battery detected", true) 643 /* TODO: Verify the meaning of these interrupts */ 644 BD_ISR_BAT(rechg_det, "Recharging", true) 645 BD_ISR_BAT(rechg_res, "Recharge ending", true) 646 BD_ISR_DUMMY(temp_transit, "Temperature transition") 647 BD_ISR_BAT(therm_rmv, "bd71815-therm-rmv", false) 648 BD_ISR_BAT(therm_det, "bd71815-therm-det", true) 649 BD_ISR_BAT(bat_dead, "bd71815-bat-dead", false) 650 BD_ISR_BAT(bat_short_res, "bd71815-bat-short-res", true) 651 BD_ISR_BAT(bat_short, "bd71815-bat-short-det", false) 652 BD_ISR_BAT(bat_low_res, "bd71815-bat-low-res", true) 653 BD_ISR_BAT(bat_low, "bd71815-bat-low-det", true) 654 BD_ISR_BAT(bat_ov_res, "bd71815-bat-over-res", true) 655 /* What should we do here? */ 656 BD_ISR_BAT(bat_ov, "bd71815-bat-over-det", false) 657 BD_ISR_BAT(bat_mon_res, "bd71815-bat-mon-res", true) 658 BD_ISR_BAT(bat_mon, "bd71815-bat-mon-det", true) 659 BD_ISR_BAT(bat_cc_mon, "bd71815-bat-cc-mon2", false) 660 BD_ISR_BAT(bat_oc1_res, "bd71815-bat-oc1-res", true) 661 BD_ISR_BAT(bat_oc1, "bd71815-bat-oc1-det", false) 662 BD_ISR_BAT(bat_oc2_res, "bd71815-bat-oc2-res", true) 663 BD_ISR_BAT(bat_oc2, "bd71815-bat-oc2-det", false) 664 BD_ISR_BAT(bat_oc3_res, "bd71815-bat-oc3-res", true) 665 BD_ISR_BAT(bat_oc3, "bd71815-bat-oc3-det", false) 666 BD_ISR_BAT(temp_bat_low_res, "bd71815-temp-bat-low-res", true) 667 BD_ISR_BAT(temp_bat_low, "bd71815-temp-bat-low-det", true) 668 BD_ISR_BAT(temp_bat_hi_res, "bd71815-temp-bat-hi-res", true) 669 BD_ISR_BAT(temp_bat_hi, "bd71815-temp-bat-hi-det", true) 670 671 static irqreturn_t bd7182x_dcin_removed(int irq, void *data) 672 { 673 struct bd71828_power *pwr = (struct bd71828_power *)data; 674 675 power_supply_changed(pwr->ac); 676 dev_dbg(pwr->dev, "DCIN removed\n"); 677 678 return IRQ_HANDLED; 679 } 680 681 static irqreturn_t bd718x7_chg_done(int irq, void *data) 682 { 683 struct bd71828_power *pwr = (struct bd71828_power *)data; 684 685 power_supply_changed(pwr->bat); 686 687 return IRQ_HANDLED; 688 } 689 690 static irqreturn_t bd7182x_dcin_detected(int irq, void *data) 691 { 692 struct bd71828_power *pwr = (struct bd71828_power *)data; 693 694 dev_dbg(pwr->dev, "DCIN inserted\n"); 695 power_supply_changed(pwr->ac); 696 697 return IRQ_HANDLED; 698 } 699 700 static irqreturn_t bd71828_vbat_low_res(int irq, void *data) 701 { 702 struct bd71828_power *pwr = (struct bd71828_power *)data; 703 704 dev_dbg(pwr->dev, "VBAT LOW Resumed\n"); 705 706 return IRQ_HANDLED; 707 } 708 709 static irqreturn_t bd71828_vbat_low_det(int irq, void *data) 710 { 711 struct bd71828_power *pwr = (struct bd71828_power *)data; 712 713 dev_dbg(pwr->dev, "VBAT LOW Detected\n"); 714 715 return IRQ_HANDLED; 716 } 717 718 static irqreturn_t bd71828_temp_bat_hi_det(int irq, void *data) 719 { 720 struct bd71828_power *pwr = (struct bd71828_power *)data; 721 722 dev_warn(pwr->dev, "Overtemp Detected\n"); 723 power_supply_changed(pwr->bat); 724 725 return IRQ_HANDLED; 726 } 727 728 static irqreturn_t bd71828_temp_bat_hi_res(int irq, void *data) 729 { 730 struct bd71828_power *pwr = (struct bd71828_power *)data; 731 732 dev_dbg(pwr->dev, "Overtemp Resumed\n"); 733 power_supply_changed(pwr->bat); 734 735 return IRQ_HANDLED; 736 } 737 738 static irqreturn_t bd71828_temp_bat_low_det(int irq, void *data) 739 { 740 struct bd71828_power *pwr = (struct bd71828_power *)data; 741 742 dev_dbg(pwr->dev, "Lowtemp Detected\n"); 743 power_supply_changed(pwr->bat); 744 745 return IRQ_HANDLED; 746 } 747 748 static irqreturn_t bd71828_temp_bat_low_res(int irq, void *data) 749 { 750 struct bd71828_power *pwr = (struct bd71828_power *)data; 751 752 dev_dbg(pwr->dev, "Lowtemp Resumed\n"); 753 power_supply_changed(pwr->bat); 754 755 return IRQ_HANDLED; 756 } 757 758 static irqreturn_t bd71828_temp_vf_det(int irq, void *data) 759 { 760 struct bd71828_power *pwr = (struct bd71828_power *)data; 761 762 dev_dbg(pwr->dev, "VF Detected\n"); 763 power_supply_changed(pwr->bat); 764 765 return IRQ_HANDLED; 766 } 767 768 static irqreturn_t bd71828_temp_vf_res(int irq, void *data) 769 { 770 struct bd71828_power *pwr = (struct bd71828_power *)data; 771 772 dev_dbg(pwr->dev, "VF Resumed\n"); 773 power_supply_changed(pwr->bat); 774 775 return IRQ_HANDLED; 776 } 777 778 static irqreturn_t bd71828_temp_vf125_det(int irq, void *data) 779 { 780 struct bd71828_power *pwr = (struct bd71828_power *)data; 781 782 dev_dbg(pwr->dev, "VF125 Detected\n"); 783 power_supply_changed(pwr->bat); 784 785 return IRQ_HANDLED; 786 } 787 788 static irqreturn_t bd71828_temp_vf125_res(int irq, void *data) 789 { 790 struct bd71828_power *pwr = (struct bd71828_power *)data; 791 792 dev_dbg(pwr->dev, "VF125 Resumed\n"); 793 power_supply_changed(pwr->bat); 794 795 return IRQ_HANDLED; 796 } 797 798 struct bd7182x_irq_res { 799 const char *name; 800 irq_handler_t handler; 801 }; 802 803 #define BDIRQ(na, hn) { .name = (na), .handler = (hn) } 804 805 static int bd7182x_get_irqs(struct platform_device *pdev, 806 struct bd71828_power *pwr) 807 { 808 int i, irq, ret; 809 static const struct bd7182x_irq_res bd71815_irqs[] = { 810 BDIRQ("bd71815-dcin-rmv", BD_ISR_NAME(dcin_removed)), 811 BDIRQ("bd71815-dcin-clps-out", BD_ISR_NAME(clps_out)), 812 BDIRQ("bd71815-dcin-clps-in", BD_ISR_NAME(clps_in)), 813 BDIRQ("bd71815-dcin-ovp-res", BD_ISR_NAME(dcin_ovp_res)), 814 BDIRQ("bd71815-dcin-ovp-det", BD_ISR_NAME(dcin_ovp_det)), 815 BDIRQ("bd71815-dcin-mon-res", BD_ISR_NAME(dcin_mon_res)), 816 BDIRQ("bd71815-dcin-mon-det", BD_ISR_NAME(dcin_mon_det)), 817 818 BDIRQ("bd71815-vsys-uv-res", BD_ISR_NAME(vsys_uv_res)), 819 BDIRQ("bd71815-vsys-uv-det", BD_ISR_NAME(vsys_uv_det)), 820 BDIRQ("bd71815-vsys-low-res", BD_ISR_NAME(vsys_low_res)), 821 BDIRQ("bd71815-vsys-low-det", BD_ISR_NAME(vsys_low_det)), 822 BDIRQ("bd71815-vsys-mon-res", BD_ISR_NAME(vsys_mon_res)), 823 BDIRQ("bd71815-vsys-mon-det", BD_ISR_NAME(vsys_mon_det)), 824 BDIRQ("bd71815-chg-wdg-temp", BD_ISR_NAME(chg_wdg_temp)), 825 BDIRQ("bd71815-chg-wdg", BD_ISR_NAME(chg_wdg)), 826 BDIRQ("bd71815-rechg-det", BD_ISR_NAME(rechg_det)), 827 BDIRQ("bd71815-rechg-res", BD_ISR_NAME(rechg_res)), 828 BDIRQ("bd71815-ranged-temp-transit", BD_ISR_NAME(temp_transit)), 829 BDIRQ("bd71815-chg-state-change", BD_ISR_NAME(chg_state_changed)), 830 BDIRQ("bd71815-bat-temp-normal", bd71828_temp_bat_hi_res), 831 BDIRQ("bd71815-bat-temp-erange", bd71828_temp_bat_hi_det), 832 BDIRQ("bd71815-bat-rmv", BD_ISR_NAME(bat_removed)), 833 BDIRQ("bd71815-bat-det", BD_ISR_NAME(bat_det)), 834 835 /* Add ISRs for these */ 836 BDIRQ("bd71815-therm-rmv", BD_ISR_NAME(therm_rmv)), 837 BDIRQ("bd71815-therm-det", BD_ISR_NAME(therm_det)), 838 BDIRQ("bd71815-bat-dead", BD_ISR_NAME(bat_dead)), 839 BDIRQ("bd71815-bat-short-res", BD_ISR_NAME(bat_short_res)), 840 BDIRQ("bd71815-bat-short-det", BD_ISR_NAME(bat_short)), 841 BDIRQ("bd71815-bat-low-res", BD_ISR_NAME(bat_low_res)), 842 BDIRQ("bd71815-bat-low-det", BD_ISR_NAME(bat_low)), 843 BDIRQ("bd71815-bat-over-res", BD_ISR_NAME(bat_ov_res)), 844 BDIRQ("bd71815-bat-over-det", BD_ISR_NAME(bat_ov)), 845 BDIRQ("bd71815-bat-mon-res", BD_ISR_NAME(bat_mon_res)), 846 BDIRQ("bd71815-bat-mon-det", BD_ISR_NAME(bat_mon)), 847 /* cc-mon 1 & 3 ? */ 848 BDIRQ("bd71815-bat-cc-mon2", BD_ISR_NAME(bat_cc_mon)), 849 BDIRQ("bd71815-bat-oc1-res", BD_ISR_NAME(bat_oc1_res)), 850 BDIRQ("bd71815-bat-oc1-det", BD_ISR_NAME(bat_oc1)), 851 BDIRQ("bd71815-bat-oc2-res", BD_ISR_NAME(bat_oc2_res)), 852 BDIRQ("bd71815-bat-oc2-det", BD_ISR_NAME(bat_oc2)), 853 BDIRQ("bd71815-bat-oc3-res", BD_ISR_NAME(bat_oc3_res)), 854 BDIRQ("bd71815-bat-oc3-det", BD_ISR_NAME(bat_oc3)), 855 BDIRQ("bd71815-temp-bat-low-res", BD_ISR_NAME(temp_bat_low_res)), 856 BDIRQ("bd71815-temp-bat-low-det", BD_ISR_NAME(temp_bat_low)), 857 BDIRQ("bd71815-temp-bat-hi-res", BD_ISR_NAME(temp_bat_hi_res)), 858 BDIRQ("bd71815-temp-bat-hi-det", BD_ISR_NAME(temp_bat_hi)), 859 /* 860 * TODO: add rest of the IRQs and re-check the handling. 861 * Check the bd71815-bat-cc-mon1, bd71815-bat-cc-mon3, 862 * bd71815-bat-low-res, bd71815-bat-low-det, 863 * bd71815-bat-hi-res, bd71815-bat-hi-det. 864 */ 865 }; 866 static const struct bd7182x_irq_res bd71828_irqs[] = { 867 BDIRQ("bd71828-chg-done", bd718x7_chg_done), 868 BDIRQ("bd71828-pwr-dcin-in", bd7182x_dcin_detected), 869 BDIRQ("bd71828-pwr-dcin-out", bd7182x_dcin_removed), 870 BDIRQ("bd71828-vbat-normal", bd71828_vbat_low_res), 871 BDIRQ("bd71828-vbat-low", bd71828_vbat_low_det), 872 BDIRQ("bd71828-btemp-hi", bd71828_temp_bat_hi_det), 873 BDIRQ("bd71828-btemp-cool", bd71828_temp_bat_hi_res), 874 BDIRQ("bd71828-btemp-lo", bd71828_temp_bat_low_det), 875 BDIRQ("bd71828-btemp-warm", bd71828_temp_bat_low_res), 876 BDIRQ("bd71828-temp-hi", bd71828_temp_vf_det), 877 BDIRQ("bd71828-temp-norm", bd71828_temp_vf_res), 878 BDIRQ("bd71828-temp-125-over", bd71828_temp_vf125_det), 879 BDIRQ("bd71828-temp-125-under", bd71828_temp_vf125_res), 880 }; 881 int num_irqs; 882 const struct bd7182x_irq_res *irqs; 883 884 switch (pwr->chip_type) { 885 case ROHM_CHIP_TYPE_BD71828: 886 irqs = &bd71828_irqs[0]; 887 num_irqs = ARRAY_SIZE(bd71828_irqs); 888 break; 889 case ROHM_CHIP_TYPE_BD71815: 890 irqs = &bd71815_irqs[0]; 891 num_irqs = ARRAY_SIZE(bd71815_irqs); 892 break; 893 default: 894 return -EINVAL; 895 } 896 897 for (i = 0; i < num_irqs; i++) { 898 irq = platform_get_irq_byname(pdev, irqs[i].name); 899 900 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 901 irqs[i].handler, 0, 902 irqs[i].name, pwr); 903 if (ret) 904 break; 905 } 906 907 return ret; 908 } 909 910 #define RSENS_DEFAULT_30MOHM 30000 /* 30 mOhm in uOhms*/ 911 912 static int bd7182x_get_rsens(struct bd71828_power *pwr) 913 { 914 u64 tmp = RSENS_CURR; 915 int rsens_ohm = RSENS_DEFAULT_30MOHM; 916 struct fwnode_handle *node = NULL; 917 918 if (pwr->dev->parent) 919 node = dev_fwnode(pwr->dev->parent); 920 921 if (node) { 922 int ret; 923 u32 rs; 924 925 ret = fwnode_property_read_u32(node, 926 "rohm,charger-sense-resistor-micro-ohms", 927 &rs); 928 if (ret) { 929 if (ret == -EINVAL) { 930 rs = RSENS_DEFAULT_30MOHM; 931 } else { 932 dev_err(pwr->dev, "Bad RSENS dt property\n"); 933 return ret; 934 } 935 } 936 if (!rs) { 937 dev_err(pwr->dev, "Bad RSENS value\n"); 938 return -EINVAL; 939 } 940 941 rsens_ohm = (int)rs; 942 } 943 944 /* Reg val to uA */ 945 do_div(tmp, rsens_ohm); 946 947 pwr->curr_factor = tmp; 948 pwr->rsens = rsens_ohm; 949 dev_dbg(pwr->dev, "Setting rsens to %u micro ohm\n", pwr->rsens); 950 dev_dbg(pwr->dev, "Setting curr-factor to %u\n", pwr->curr_factor); 951 952 return 0; 953 } 954 955 static int bd71828_power_probe(struct platform_device *pdev) 956 { 957 struct bd71828_power *pwr; 958 struct power_supply_config ac_cfg = {}; 959 struct power_supply_config bat_cfg = {}; 960 int ret; 961 struct regmap *regmap; 962 963 regmap = dev_get_regmap(pdev->dev.parent, NULL); 964 if (!regmap) { 965 dev_err(&pdev->dev, "No parent regmap\n"); 966 return -EINVAL; 967 } 968 969 pwr = devm_kzalloc(&pdev->dev, sizeof(*pwr), GFP_KERNEL); 970 if (!pwr) 971 return -ENOMEM; 972 973 pwr->regmap = regmap; 974 pwr->dev = &pdev->dev; 975 pwr->chip_type = platform_get_device_id(pdev)->driver_data; 976 977 switch (pwr->chip_type) { 978 case ROHM_CHIP_TYPE_BD71828: 979 pwr->bat_inserted = bd71828_bat_inserted; 980 pwr->get_temp = bd71828_get_temp; 981 pwr->regs = &pwr_regs_bd71828; 982 break; 983 case ROHM_CHIP_TYPE_BD71815: 984 pwr->bat_inserted = bd71815_bat_inserted; 985 pwr->get_temp = bd71815_get_temp; 986 pwr->regs = &pwr_regs_bd71815; 987 break; 988 default: 989 dev_err(pwr->dev, "Unknown PMIC\n"); 990 return -EINVAL; 991 } 992 993 ret = bd7182x_get_rsens(pwr); 994 if (ret) 995 return dev_err_probe(&pdev->dev, ret, "sense resistor missing\n"); 996 997 dev_set_drvdata(&pdev->dev, pwr); 998 bd71828_init_hardware(pwr); 999 1000 bat_cfg.drv_data = pwr; 1001 bat_cfg.fwnode = dev_fwnode(&pdev->dev); 1002 1003 ac_cfg.supplied_to = bd71828_ac_supplied_to; 1004 ac_cfg.num_supplicants = ARRAY_SIZE(bd71828_ac_supplied_to); 1005 ac_cfg.drv_data = pwr; 1006 1007 pwr->ac = devm_power_supply_register(&pdev->dev, &bd71828_ac_desc, 1008 &ac_cfg); 1009 if (IS_ERR(pwr->ac)) 1010 return dev_err_probe(&pdev->dev, PTR_ERR(pwr->ac), 1011 "failed to register ac\n"); 1012 1013 pwr->bat = devm_power_supply_register(&pdev->dev, &bd71828_bat_desc, 1014 &bat_cfg); 1015 if (IS_ERR(pwr->bat)) 1016 return dev_err_probe(&pdev->dev, PTR_ERR(pwr->bat), 1017 "failed to register bat\n"); 1018 1019 ret = bd7182x_get_irqs(pdev, pwr); 1020 if (ret) 1021 return dev_err_probe(&pdev->dev, ret, "failed to request IRQs"); 1022 1023 /* Configure wakeup capable */ 1024 device_set_wakeup_capable(pwr->dev, 1); 1025 device_set_wakeup_enable(pwr->dev, 1); 1026 1027 return 0; 1028 } 1029 1030 static const struct platform_device_id bd71828_charger_id[] = { 1031 { "bd71815-power", ROHM_CHIP_TYPE_BD71815 }, 1032 { "bd71828-power", ROHM_CHIP_TYPE_BD71828 }, 1033 { }, 1034 }; 1035 MODULE_DEVICE_TABLE(platform, bd71828_charger_id); 1036 1037 static struct platform_driver bd71828_power_driver = { 1038 .driver = { 1039 .name = "bd718xx-power", 1040 }, 1041 .probe = bd71828_power_probe, 1042 .id_table = bd71828_charger_id, 1043 }; 1044 1045 module_platform_driver(bd71828_power_driver); 1046 1047 MODULE_AUTHOR("Cong Pham <cpham2403@gmail.com>"); 1048 MODULE_DESCRIPTION("ROHM BD718(15/28/78) PMIC Battery Charger driver"); 1049 MODULE_LICENSE("GPL"); 1050