1 /* Copyright (c) 2014, Sony Mobile Communications Inc. 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License version 2 and 5 * only version 2 as published by the Free Software Foundation. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * This driver is for the multi-block Switch-Mode Battery Charger and Boost 13 * (SMBB) hardware, found in Qualcomm PM8941 PMICs. The charger is an 14 * integrated, single-cell lithium-ion battery charger. 15 * 16 * Sub-components: 17 * - Charger core 18 * - Buck 19 * - DC charge-path 20 * - USB charge-path 21 * - Battery interface 22 * - Boost (not implemented) 23 * - Misc 24 * - HF-Buck 25 */ 26 27 #include <linux/errno.h> 28 #include <linux/interrupt.h> 29 #include <linux/kernel.h> 30 #include <linux/module.h> 31 #include <linux/mutex.h> 32 #include <linux/of.h> 33 #include <linux/platform_device.h> 34 #include <linux/power_supply.h> 35 #include <linux/regmap.h> 36 #include <linux/slab.h> 37 #include <linux/extcon-provider.h> 38 #include <linux/regulator/driver.h> 39 40 #define SMBB_CHG_VMAX 0x040 41 #define SMBB_CHG_VSAFE 0x041 42 #define SMBB_CHG_CFG 0x043 43 #define SMBB_CHG_IMAX 0x044 44 #define SMBB_CHG_ISAFE 0x045 45 #define SMBB_CHG_VIN_MIN 0x047 46 #define SMBB_CHG_CTRL 0x049 47 #define CTRL_EN BIT(7) 48 #define SMBB_CHG_VBAT_WEAK 0x052 49 #define SMBB_CHG_IBAT_TERM_CHG 0x05b 50 #define IBAT_TERM_CHG_IEOC BIT(7) 51 #define IBAT_TERM_CHG_IEOC_BMS BIT(7) 52 #define IBAT_TERM_CHG_IEOC_CHG 0 53 #define SMBB_CHG_VBAT_DET 0x05d 54 #define SMBB_CHG_TCHG_MAX_EN 0x060 55 #define TCHG_MAX_EN BIT(7) 56 #define SMBB_CHG_WDOG_TIME 0x062 57 #define SMBB_CHG_WDOG_EN 0x065 58 #define WDOG_EN BIT(7) 59 60 #define SMBB_BUCK_REG_MODE 0x174 61 #define BUCK_REG_MODE BIT(0) 62 #define BUCK_REG_MODE_VBAT BIT(0) 63 #define BUCK_REG_MODE_VSYS 0 64 65 #define SMBB_BAT_PRES_STATUS 0x208 66 #define PRES_STATUS_BAT_PRES BIT(7) 67 #define SMBB_BAT_TEMP_STATUS 0x209 68 #define TEMP_STATUS_OK BIT(7) 69 #define TEMP_STATUS_HOT BIT(6) 70 #define SMBB_BAT_BTC_CTRL 0x249 71 #define BTC_CTRL_COMP_EN BIT(7) 72 #define BTC_CTRL_COLD_EXT BIT(1) 73 #define BTC_CTRL_HOT_EXT_N BIT(0) 74 75 #define SMBB_USB_IMAX 0x344 76 #define SMBB_USB_OTG_CTL 0x348 77 #define OTG_CTL_EN BIT(0) 78 #define SMBB_USB_ENUM_TIMER_STOP 0x34e 79 #define ENUM_TIMER_STOP BIT(0) 80 #define SMBB_USB_SEC_ACCESS 0x3d0 81 #define SEC_ACCESS_MAGIC 0xa5 82 #define SMBB_USB_REV_BST 0x3ed 83 #define REV_BST_CHG_GONE BIT(7) 84 85 #define SMBB_DC_IMAX 0x444 86 87 #define SMBB_MISC_REV2 0x601 88 #define SMBB_MISC_BOOT_DONE 0x642 89 #define BOOT_DONE BIT(7) 90 91 #define STATUS_USBIN_VALID BIT(0) /* USB connection is valid */ 92 #define STATUS_DCIN_VALID BIT(1) /* DC connection is valid */ 93 #define STATUS_BAT_HOT BIT(2) /* Battery temp 1=Hot, 0=Cold */ 94 #define STATUS_BAT_OK BIT(3) /* Battery temp OK */ 95 #define STATUS_BAT_PRESENT BIT(4) /* Battery is present */ 96 #define STATUS_CHG_DONE BIT(5) /* Charge cycle is complete */ 97 #define STATUS_CHG_TRKL BIT(6) /* Trickle charging */ 98 #define STATUS_CHG_FAST BIT(7) /* Fast charging */ 99 #define STATUS_CHG_GONE BIT(8) /* No charger is connected */ 100 101 enum smbb_attr { 102 ATTR_BAT_ISAFE, 103 ATTR_BAT_IMAX, 104 ATTR_USBIN_IMAX, 105 ATTR_DCIN_IMAX, 106 ATTR_BAT_VSAFE, 107 ATTR_BAT_VMAX, 108 ATTR_BAT_VMIN, 109 ATTR_CHG_VDET, 110 ATTR_VIN_MIN, 111 _ATTR_CNT, 112 }; 113 114 struct smbb_charger { 115 unsigned int revision; 116 unsigned int addr; 117 struct device *dev; 118 struct extcon_dev *edev; 119 120 bool dc_disabled; 121 bool jeita_ext_temp; 122 unsigned long status; 123 struct mutex statlock; 124 125 unsigned int attr[_ATTR_CNT]; 126 127 struct power_supply *usb_psy; 128 struct power_supply *dc_psy; 129 struct power_supply *bat_psy; 130 struct regmap *regmap; 131 132 struct regulator_desc otg_rdesc; 133 struct regulator_dev *otg_reg; 134 }; 135 136 static const unsigned int smbb_usb_extcon_cable[] = { 137 EXTCON_USB, 138 EXTCON_NONE, 139 }; 140 141 static int smbb_vbat_weak_fn(unsigned int index) 142 { 143 return 2100000 + index * 100000; 144 } 145 146 static int smbb_vin_fn(unsigned int index) 147 { 148 if (index > 42) 149 return 5600000 + (index - 43) * 200000; 150 return 3400000 + index * 50000; 151 } 152 153 static int smbb_vmax_fn(unsigned int index) 154 { 155 return 3240000 + index * 10000; 156 } 157 158 static int smbb_vbat_det_fn(unsigned int index) 159 { 160 return 3240000 + index * 20000; 161 } 162 163 static int smbb_imax_fn(unsigned int index) 164 { 165 if (index < 2) 166 return 100000 + index * 50000; 167 return index * 100000; 168 } 169 170 static int smbb_bat_imax_fn(unsigned int index) 171 { 172 return index * 50000; 173 } 174 175 static unsigned int smbb_hw_lookup(unsigned int val, int (*fn)(unsigned int)) 176 { 177 unsigned int widx; 178 unsigned int sel; 179 180 for (widx = sel = 0; (*fn)(widx) <= val; ++widx) 181 sel = widx; 182 183 return sel; 184 } 185 186 static const struct smbb_charger_attr { 187 const char *name; 188 unsigned int reg; 189 unsigned int safe_reg; 190 unsigned int max; 191 unsigned int min; 192 unsigned int fail_ok; 193 int (*hw_fn)(unsigned int); 194 } smbb_charger_attrs[] = { 195 [ATTR_BAT_ISAFE] = { 196 .name = "qcom,fast-charge-safe-current", 197 .reg = SMBB_CHG_ISAFE, 198 .max = 3000000, 199 .min = 200000, 200 .hw_fn = smbb_bat_imax_fn, 201 .fail_ok = 1, 202 }, 203 [ATTR_BAT_IMAX] = { 204 .name = "qcom,fast-charge-current-limit", 205 .reg = SMBB_CHG_IMAX, 206 .safe_reg = SMBB_CHG_ISAFE, 207 .max = 3000000, 208 .min = 200000, 209 .hw_fn = smbb_bat_imax_fn, 210 }, 211 [ATTR_DCIN_IMAX] = { 212 .name = "qcom,dc-current-limit", 213 .reg = SMBB_DC_IMAX, 214 .max = 2500000, 215 .min = 100000, 216 .hw_fn = smbb_imax_fn, 217 }, 218 [ATTR_BAT_VSAFE] = { 219 .name = "qcom,fast-charge-safe-voltage", 220 .reg = SMBB_CHG_VSAFE, 221 .max = 5000000, 222 .min = 3240000, 223 .hw_fn = smbb_vmax_fn, 224 .fail_ok = 1, 225 }, 226 [ATTR_BAT_VMAX] = { 227 .name = "qcom,fast-charge-high-threshold-voltage", 228 .reg = SMBB_CHG_VMAX, 229 .safe_reg = SMBB_CHG_VSAFE, 230 .max = 5000000, 231 .min = 3240000, 232 .hw_fn = smbb_vmax_fn, 233 }, 234 [ATTR_BAT_VMIN] = { 235 .name = "qcom,fast-charge-low-threshold-voltage", 236 .reg = SMBB_CHG_VBAT_WEAK, 237 .max = 3600000, 238 .min = 2100000, 239 .hw_fn = smbb_vbat_weak_fn, 240 }, 241 [ATTR_CHG_VDET] = { 242 .name = "qcom,auto-recharge-threshold-voltage", 243 .reg = SMBB_CHG_VBAT_DET, 244 .max = 5000000, 245 .min = 3240000, 246 .hw_fn = smbb_vbat_det_fn, 247 }, 248 [ATTR_VIN_MIN] = { 249 .name = "qcom,minimum-input-voltage", 250 .reg = SMBB_CHG_VIN_MIN, 251 .max = 9600000, 252 .min = 4200000, 253 .hw_fn = smbb_vin_fn, 254 }, 255 [ATTR_USBIN_IMAX] = { 256 .name = "usb-charge-current-limit", 257 .reg = SMBB_USB_IMAX, 258 .max = 2500000, 259 .min = 100000, 260 .hw_fn = smbb_imax_fn, 261 }, 262 }; 263 264 static int smbb_charger_attr_write(struct smbb_charger *chg, 265 enum smbb_attr which, unsigned int val) 266 { 267 const struct smbb_charger_attr *prop; 268 unsigned int wval; 269 unsigned int out; 270 int rc; 271 272 prop = &smbb_charger_attrs[which]; 273 274 if (val > prop->max || val < prop->min) { 275 dev_err(chg->dev, "value out of range for %s [%u:%u]\n", 276 prop->name, prop->min, prop->max); 277 return -EINVAL; 278 } 279 280 if (prop->safe_reg) { 281 rc = regmap_read(chg->regmap, 282 chg->addr + prop->safe_reg, &wval); 283 if (rc) { 284 dev_err(chg->dev, 285 "unable to read safe value for '%s'\n", 286 prop->name); 287 return rc; 288 } 289 290 wval = prop->hw_fn(wval); 291 292 if (val > wval) { 293 dev_warn(chg->dev, 294 "%s above safe value, clamping at %u\n", 295 prop->name, wval); 296 val = wval; 297 } 298 } 299 300 wval = smbb_hw_lookup(val, prop->hw_fn); 301 302 rc = regmap_write(chg->regmap, chg->addr + prop->reg, wval); 303 if (rc) { 304 dev_err(chg->dev, "unable to update %s", prop->name); 305 return rc; 306 } 307 out = prop->hw_fn(wval); 308 if (out != val) { 309 dev_warn(chg->dev, 310 "%s inaccurate, rounded to %u\n", 311 prop->name, out); 312 } 313 314 dev_dbg(chg->dev, "%s <= %d\n", prop->name, out); 315 316 chg->attr[which] = out; 317 318 return 0; 319 } 320 321 static int smbb_charger_attr_read(struct smbb_charger *chg, 322 enum smbb_attr which) 323 { 324 const struct smbb_charger_attr *prop; 325 unsigned int val; 326 int rc; 327 328 prop = &smbb_charger_attrs[which]; 329 330 rc = regmap_read(chg->regmap, chg->addr + prop->reg, &val); 331 if (rc) { 332 dev_err(chg->dev, "failed to read %s\n", prop->name); 333 return rc; 334 } 335 val = prop->hw_fn(val); 336 dev_dbg(chg->dev, "%s => %d\n", prop->name, val); 337 338 chg->attr[which] = val; 339 340 return 0; 341 } 342 343 static int smbb_charger_attr_parse(struct smbb_charger *chg, 344 enum smbb_attr which) 345 { 346 const struct smbb_charger_attr *prop; 347 unsigned int val; 348 int rc; 349 350 prop = &smbb_charger_attrs[which]; 351 352 rc = of_property_read_u32(chg->dev->of_node, prop->name, &val); 353 if (rc == 0) { 354 rc = smbb_charger_attr_write(chg, which, val); 355 if (!rc || !prop->fail_ok) 356 return rc; 357 } 358 return smbb_charger_attr_read(chg, which); 359 } 360 361 static void smbb_set_line_flag(struct smbb_charger *chg, int irq, int flag) 362 { 363 bool state; 364 int ret; 365 366 ret = irq_get_irqchip_state(irq, IRQCHIP_STATE_LINE_LEVEL, &state); 367 if (ret < 0) { 368 dev_err(chg->dev, "failed to read irq line\n"); 369 return; 370 } 371 372 mutex_lock(&chg->statlock); 373 if (state) 374 chg->status |= flag; 375 else 376 chg->status &= ~flag; 377 mutex_unlock(&chg->statlock); 378 379 dev_dbg(chg->dev, "status = %03lx\n", chg->status); 380 } 381 382 static irqreturn_t smbb_usb_valid_handler(int irq, void *_data) 383 { 384 struct smbb_charger *chg = _data; 385 386 smbb_set_line_flag(chg, irq, STATUS_USBIN_VALID); 387 extcon_set_state_sync(chg->edev, EXTCON_USB, 388 chg->status & STATUS_USBIN_VALID); 389 power_supply_changed(chg->usb_psy); 390 391 return IRQ_HANDLED; 392 } 393 394 static irqreturn_t smbb_dc_valid_handler(int irq, void *_data) 395 { 396 struct smbb_charger *chg = _data; 397 398 smbb_set_line_flag(chg, irq, STATUS_DCIN_VALID); 399 if (!chg->dc_disabled) 400 power_supply_changed(chg->dc_psy); 401 402 return IRQ_HANDLED; 403 } 404 405 static irqreturn_t smbb_bat_temp_handler(int irq, void *_data) 406 { 407 struct smbb_charger *chg = _data; 408 unsigned int val; 409 int rc; 410 411 rc = regmap_read(chg->regmap, chg->addr + SMBB_BAT_TEMP_STATUS, &val); 412 if (rc) 413 return IRQ_HANDLED; 414 415 mutex_lock(&chg->statlock); 416 if (val & TEMP_STATUS_OK) { 417 chg->status |= STATUS_BAT_OK; 418 } else { 419 chg->status &= ~STATUS_BAT_OK; 420 if (val & TEMP_STATUS_HOT) 421 chg->status |= STATUS_BAT_HOT; 422 } 423 mutex_unlock(&chg->statlock); 424 425 power_supply_changed(chg->bat_psy); 426 return IRQ_HANDLED; 427 } 428 429 static irqreturn_t smbb_bat_present_handler(int irq, void *_data) 430 { 431 struct smbb_charger *chg = _data; 432 433 smbb_set_line_flag(chg, irq, STATUS_BAT_PRESENT); 434 power_supply_changed(chg->bat_psy); 435 436 return IRQ_HANDLED; 437 } 438 439 static irqreturn_t smbb_chg_done_handler(int irq, void *_data) 440 { 441 struct smbb_charger *chg = _data; 442 443 smbb_set_line_flag(chg, irq, STATUS_CHG_DONE); 444 power_supply_changed(chg->bat_psy); 445 446 return IRQ_HANDLED; 447 } 448 449 static irqreturn_t smbb_chg_gone_handler(int irq, void *_data) 450 { 451 struct smbb_charger *chg = _data; 452 453 smbb_set_line_flag(chg, irq, STATUS_CHG_GONE); 454 power_supply_changed(chg->bat_psy); 455 power_supply_changed(chg->usb_psy); 456 if (!chg->dc_disabled) 457 power_supply_changed(chg->dc_psy); 458 459 return IRQ_HANDLED; 460 } 461 462 static irqreturn_t smbb_chg_fast_handler(int irq, void *_data) 463 { 464 struct smbb_charger *chg = _data; 465 466 smbb_set_line_flag(chg, irq, STATUS_CHG_FAST); 467 power_supply_changed(chg->bat_psy); 468 469 return IRQ_HANDLED; 470 } 471 472 static irqreturn_t smbb_chg_trkl_handler(int irq, void *_data) 473 { 474 struct smbb_charger *chg = _data; 475 476 smbb_set_line_flag(chg, irq, STATUS_CHG_TRKL); 477 power_supply_changed(chg->bat_psy); 478 479 return IRQ_HANDLED; 480 } 481 482 static const struct smbb_irq { 483 const char *name; 484 irqreturn_t (*handler)(int, void *); 485 } smbb_charger_irqs[] = { 486 { "chg-done", smbb_chg_done_handler }, 487 { "chg-fast", smbb_chg_fast_handler }, 488 { "chg-trkl", smbb_chg_trkl_handler }, 489 { "bat-temp-ok", smbb_bat_temp_handler }, 490 { "bat-present", smbb_bat_present_handler }, 491 { "chg-gone", smbb_chg_gone_handler }, 492 { "usb-valid", smbb_usb_valid_handler }, 493 { "dc-valid", smbb_dc_valid_handler }, 494 }; 495 496 static int smbb_usbin_get_property(struct power_supply *psy, 497 enum power_supply_property psp, 498 union power_supply_propval *val) 499 { 500 struct smbb_charger *chg = power_supply_get_drvdata(psy); 501 int rc = 0; 502 503 switch (psp) { 504 case POWER_SUPPLY_PROP_ONLINE: 505 mutex_lock(&chg->statlock); 506 val->intval = !(chg->status & STATUS_CHG_GONE) && 507 (chg->status & STATUS_USBIN_VALID); 508 mutex_unlock(&chg->statlock); 509 break; 510 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 511 val->intval = chg->attr[ATTR_USBIN_IMAX]; 512 break; 513 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: 514 val->intval = 2500000; 515 break; 516 default: 517 rc = -EINVAL; 518 break; 519 } 520 521 return rc; 522 } 523 524 static int smbb_usbin_set_property(struct power_supply *psy, 525 enum power_supply_property psp, 526 const union power_supply_propval *val) 527 { 528 struct smbb_charger *chg = power_supply_get_drvdata(psy); 529 int rc; 530 531 switch (psp) { 532 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 533 rc = smbb_charger_attr_write(chg, ATTR_USBIN_IMAX, 534 val->intval); 535 break; 536 default: 537 rc = -EINVAL; 538 break; 539 } 540 541 return rc; 542 } 543 544 static int smbb_dcin_get_property(struct power_supply *psy, 545 enum power_supply_property psp, 546 union power_supply_propval *val) 547 { 548 struct smbb_charger *chg = power_supply_get_drvdata(psy); 549 int rc = 0; 550 551 switch (psp) { 552 case POWER_SUPPLY_PROP_ONLINE: 553 mutex_lock(&chg->statlock); 554 val->intval = !(chg->status & STATUS_CHG_GONE) && 555 (chg->status & STATUS_DCIN_VALID); 556 mutex_unlock(&chg->statlock); 557 break; 558 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 559 val->intval = chg->attr[ATTR_DCIN_IMAX]; 560 break; 561 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX: 562 val->intval = 2500000; 563 break; 564 default: 565 rc = -EINVAL; 566 break; 567 } 568 569 return rc; 570 } 571 572 static int smbb_dcin_set_property(struct power_supply *psy, 573 enum power_supply_property psp, 574 const union power_supply_propval *val) 575 { 576 struct smbb_charger *chg = power_supply_get_drvdata(psy); 577 int rc; 578 579 switch (psp) { 580 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 581 rc = smbb_charger_attr_write(chg, ATTR_DCIN_IMAX, 582 val->intval); 583 break; 584 default: 585 rc = -EINVAL; 586 break; 587 } 588 589 return rc; 590 } 591 592 static int smbb_charger_writable_property(struct power_supply *psy, 593 enum power_supply_property psp) 594 { 595 return psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT; 596 } 597 598 static int smbb_battery_get_property(struct power_supply *psy, 599 enum power_supply_property psp, 600 union power_supply_propval *val) 601 { 602 struct smbb_charger *chg = power_supply_get_drvdata(psy); 603 unsigned long status; 604 int rc = 0; 605 606 mutex_lock(&chg->statlock); 607 status = chg->status; 608 mutex_unlock(&chg->statlock); 609 610 switch (psp) { 611 case POWER_SUPPLY_PROP_STATUS: 612 if (status & STATUS_CHG_GONE) 613 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 614 else if (!(status & (STATUS_DCIN_VALID | STATUS_USBIN_VALID))) 615 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 616 else if (status & STATUS_CHG_DONE) 617 val->intval = POWER_SUPPLY_STATUS_FULL; 618 else if (!(status & STATUS_BAT_OK)) 619 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 620 else if (status & (STATUS_CHG_FAST | STATUS_CHG_TRKL)) 621 val->intval = POWER_SUPPLY_STATUS_CHARGING; 622 else /* everything is ok for charging, but we are not... */ 623 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 624 break; 625 case POWER_SUPPLY_PROP_HEALTH: 626 if (status & STATUS_BAT_OK) 627 val->intval = POWER_SUPPLY_HEALTH_GOOD; 628 else if (status & STATUS_BAT_HOT) 629 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 630 else 631 val->intval = POWER_SUPPLY_HEALTH_COLD; 632 break; 633 case POWER_SUPPLY_PROP_CHARGE_TYPE: 634 if (status & STATUS_CHG_FAST) 635 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; 636 else if (status & STATUS_CHG_TRKL) 637 val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; 638 else 639 val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; 640 break; 641 case POWER_SUPPLY_PROP_PRESENT: 642 val->intval = !!(status & STATUS_BAT_PRESENT); 643 break; 644 case POWER_SUPPLY_PROP_CURRENT_MAX: 645 val->intval = chg->attr[ATTR_BAT_IMAX]; 646 break; 647 case POWER_SUPPLY_PROP_VOLTAGE_MAX: 648 val->intval = chg->attr[ATTR_BAT_VMAX]; 649 break; 650 case POWER_SUPPLY_PROP_TECHNOLOGY: 651 /* this charger is a single-cell lithium-ion battery charger 652 * only. If you hook up some other technology, there will be 653 * fireworks. 654 */ 655 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 656 break; 657 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 658 val->intval = 3000000; /* single-cell li-ion low end */ 659 break; 660 default: 661 rc = -EINVAL; 662 break; 663 } 664 665 return rc; 666 } 667 668 static int smbb_battery_set_property(struct power_supply *psy, 669 enum power_supply_property psp, 670 const union power_supply_propval *val) 671 { 672 struct smbb_charger *chg = power_supply_get_drvdata(psy); 673 int rc; 674 675 switch (psp) { 676 case POWER_SUPPLY_PROP_CURRENT_MAX: 677 rc = smbb_charger_attr_write(chg, ATTR_BAT_IMAX, val->intval); 678 break; 679 case POWER_SUPPLY_PROP_VOLTAGE_MAX: 680 rc = smbb_charger_attr_write(chg, ATTR_BAT_VMAX, val->intval); 681 break; 682 default: 683 rc = -EINVAL; 684 break; 685 } 686 687 return rc; 688 } 689 690 static int smbb_battery_writable_property(struct power_supply *psy, 691 enum power_supply_property psp) 692 { 693 switch (psp) { 694 case POWER_SUPPLY_PROP_CURRENT_MAX: 695 case POWER_SUPPLY_PROP_VOLTAGE_MAX: 696 return 1; 697 default: 698 return 0; 699 } 700 } 701 702 static enum power_supply_property smbb_charger_properties[] = { 703 POWER_SUPPLY_PROP_ONLINE, 704 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, 705 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, 706 }; 707 708 static enum power_supply_property smbb_battery_properties[] = { 709 POWER_SUPPLY_PROP_STATUS, 710 POWER_SUPPLY_PROP_HEALTH, 711 POWER_SUPPLY_PROP_PRESENT, 712 POWER_SUPPLY_PROP_CHARGE_TYPE, 713 POWER_SUPPLY_PROP_CURRENT_MAX, 714 POWER_SUPPLY_PROP_VOLTAGE_MAX, 715 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 716 POWER_SUPPLY_PROP_TECHNOLOGY, 717 }; 718 719 static const struct reg_off_mask_default { 720 unsigned int offset; 721 unsigned int mask; 722 unsigned int value; 723 unsigned int rev_mask; 724 } smbb_charger_setup[] = { 725 /* The bootloader is supposed to set this... make sure anyway. */ 726 { SMBB_MISC_BOOT_DONE, BOOT_DONE, BOOT_DONE }, 727 728 /* Disable software timer */ 729 { SMBB_CHG_TCHG_MAX_EN, TCHG_MAX_EN, 0 }, 730 731 /* Clear and disable watchdog */ 732 { SMBB_CHG_WDOG_TIME, 0xff, 160 }, 733 { SMBB_CHG_WDOG_EN, WDOG_EN, 0 }, 734 735 /* Use charger based EoC detection */ 736 { SMBB_CHG_IBAT_TERM_CHG, IBAT_TERM_CHG_IEOC, IBAT_TERM_CHG_IEOC_CHG }, 737 738 /* Disable GSM PA load adjustment. 739 * The PA signal is incorrectly connected on v2. 740 */ 741 { SMBB_CHG_CFG, 0xff, 0x00, BIT(3) }, 742 743 /* Use VBAT (not VSYS) to compensate for IR drop during fast charging */ 744 { SMBB_BUCK_REG_MODE, BUCK_REG_MODE, BUCK_REG_MODE_VBAT }, 745 746 /* Enable battery temperature comparators */ 747 { SMBB_BAT_BTC_CTRL, BTC_CTRL_COMP_EN, BTC_CTRL_COMP_EN }, 748 749 /* Stop USB enumeration timer */ 750 { SMBB_USB_ENUM_TIMER_STOP, ENUM_TIMER_STOP, ENUM_TIMER_STOP }, 751 752 #if 0 /* FIXME supposedly only to disable hardware ARB termination */ 753 { SMBB_USB_SEC_ACCESS, SEC_ACCESS_MAGIC }, 754 { SMBB_USB_REV_BST, 0xff, REV_BST_CHG_GONE }, 755 #endif 756 757 /* Stop USB enumeration timer, again */ 758 { SMBB_USB_ENUM_TIMER_STOP, ENUM_TIMER_STOP, ENUM_TIMER_STOP }, 759 760 /* Enable charging */ 761 { SMBB_CHG_CTRL, CTRL_EN, CTRL_EN }, 762 }; 763 764 static char *smbb_bif[] = { "smbb-bif" }; 765 766 static const struct power_supply_desc bat_psy_desc = { 767 .name = "smbb-bif", 768 .type = POWER_SUPPLY_TYPE_BATTERY, 769 .properties = smbb_battery_properties, 770 .num_properties = ARRAY_SIZE(smbb_battery_properties), 771 .get_property = smbb_battery_get_property, 772 .set_property = smbb_battery_set_property, 773 .property_is_writeable = smbb_battery_writable_property, 774 }; 775 776 static const struct power_supply_desc usb_psy_desc = { 777 .name = "smbb-usbin", 778 .type = POWER_SUPPLY_TYPE_USB, 779 .properties = smbb_charger_properties, 780 .num_properties = ARRAY_SIZE(smbb_charger_properties), 781 .get_property = smbb_usbin_get_property, 782 .set_property = smbb_usbin_set_property, 783 .property_is_writeable = smbb_charger_writable_property, 784 }; 785 786 static const struct power_supply_desc dc_psy_desc = { 787 .name = "smbb-dcin", 788 .type = POWER_SUPPLY_TYPE_MAINS, 789 .properties = smbb_charger_properties, 790 .num_properties = ARRAY_SIZE(smbb_charger_properties), 791 .get_property = smbb_dcin_get_property, 792 .set_property = smbb_dcin_set_property, 793 .property_is_writeable = smbb_charger_writable_property, 794 }; 795 796 static int smbb_chg_otg_enable(struct regulator_dev *rdev) 797 { 798 struct smbb_charger *chg = rdev_get_drvdata(rdev); 799 int rc; 800 801 rc = regmap_update_bits(chg->regmap, chg->addr + SMBB_USB_OTG_CTL, 802 OTG_CTL_EN, OTG_CTL_EN); 803 if (rc) 804 dev_err(chg->dev, "failed to update OTG_CTL\n"); 805 return rc; 806 } 807 808 static int smbb_chg_otg_disable(struct regulator_dev *rdev) 809 { 810 struct smbb_charger *chg = rdev_get_drvdata(rdev); 811 int rc; 812 813 rc = regmap_update_bits(chg->regmap, chg->addr + SMBB_USB_OTG_CTL, 814 OTG_CTL_EN, 0); 815 if (rc) 816 dev_err(chg->dev, "failed to update OTG_CTL\n"); 817 return rc; 818 } 819 820 static int smbb_chg_otg_is_enabled(struct regulator_dev *rdev) 821 { 822 struct smbb_charger *chg = rdev_get_drvdata(rdev); 823 unsigned int value = 0; 824 int rc; 825 826 rc = regmap_read(chg->regmap, chg->addr + SMBB_USB_OTG_CTL, &value); 827 if (rc) 828 dev_err(chg->dev, "failed to read OTG_CTL\n"); 829 830 return !!(value & OTG_CTL_EN); 831 } 832 833 static const struct regulator_ops smbb_chg_otg_ops = { 834 .enable = smbb_chg_otg_enable, 835 .disable = smbb_chg_otg_disable, 836 .is_enabled = smbb_chg_otg_is_enabled, 837 }; 838 839 static int smbb_charger_probe(struct platform_device *pdev) 840 { 841 struct power_supply_config bat_cfg = {}; 842 struct power_supply_config usb_cfg = {}; 843 struct power_supply_config dc_cfg = {}; 844 struct smbb_charger *chg; 845 struct regulator_config config = { }; 846 int rc, i; 847 848 chg = devm_kzalloc(&pdev->dev, sizeof(*chg), GFP_KERNEL); 849 if (!chg) 850 return -ENOMEM; 851 852 chg->dev = &pdev->dev; 853 mutex_init(&chg->statlock); 854 855 chg->regmap = dev_get_regmap(pdev->dev.parent, NULL); 856 if (!chg->regmap) { 857 dev_err(&pdev->dev, "failed to locate regmap\n"); 858 return -ENODEV; 859 } 860 861 rc = of_property_read_u32(pdev->dev.of_node, "reg", &chg->addr); 862 if (rc) { 863 dev_err(&pdev->dev, "missing or invalid 'reg' property\n"); 864 return rc; 865 } 866 867 rc = regmap_read(chg->regmap, chg->addr + SMBB_MISC_REV2, &chg->revision); 868 if (rc) { 869 dev_err(&pdev->dev, "unable to read revision\n"); 870 return rc; 871 } 872 873 chg->revision += 1; 874 if (chg->revision != 2 && chg->revision != 3) { 875 dev_err(&pdev->dev, "v1 hardware not supported\n"); 876 return -ENODEV; 877 } 878 dev_info(&pdev->dev, "Initializing SMBB rev %u", chg->revision); 879 880 chg->dc_disabled = of_property_read_bool(pdev->dev.of_node, "qcom,disable-dc"); 881 882 for (i = 0; i < _ATTR_CNT; ++i) { 883 rc = smbb_charger_attr_parse(chg, i); 884 if (rc) { 885 dev_err(&pdev->dev, "failed to parse/apply settings\n"); 886 return rc; 887 } 888 } 889 890 bat_cfg.drv_data = chg; 891 bat_cfg.of_node = pdev->dev.of_node; 892 chg->bat_psy = devm_power_supply_register(&pdev->dev, 893 &bat_psy_desc, 894 &bat_cfg); 895 if (IS_ERR(chg->bat_psy)) { 896 dev_err(&pdev->dev, "failed to register battery\n"); 897 return PTR_ERR(chg->bat_psy); 898 } 899 900 usb_cfg.drv_data = chg; 901 usb_cfg.supplied_to = smbb_bif; 902 usb_cfg.num_supplicants = ARRAY_SIZE(smbb_bif); 903 chg->usb_psy = devm_power_supply_register(&pdev->dev, 904 &usb_psy_desc, 905 &usb_cfg); 906 if (IS_ERR(chg->usb_psy)) { 907 dev_err(&pdev->dev, "failed to register USB power supply\n"); 908 return PTR_ERR(chg->usb_psy); 909 } 910 911 chg->edev = devm_extcon_dev_allocate(&pdev->dev, smbb_usb_extcon_cable); 912 if (IS_ERR(chg->edev)) { 913 dev_err(&pdev->dev, "failed to allocate extcon device\n"); 914 return -ENOMEM; 915 } 916 917 rc = devm_extcon_dev_register(&pdev->dev, chg->edev); 918 if (rc < 0) { 919 dev_err(&pdev->dev, "failed to register extcon device\n"); 920 return rc; 921 } 922 923 if (!chg->dc_disabled) { 924 dc_cfg.drv_data = chg; 925 dc_cfg.supplied_to = smbb_bif; 926 dc_cfg.num_supplicants = ARRAY_SIZE(smbb_bif); 927 chg->dc_psy = devm_power_supply_register(&pdev->dev, 928 &dc_psy_desc, 929 &dc_cfg); 930 if (IS_ERR(chg->dc_psy)) { 931 dev_err(&pdev->dev, "failed to register DC power supply\n"); 932 return PTR_ERR(chg->dc_psy); 933 } 934 } 935 936 for (i = 0; i < ARRAY_SIZE(smbb_charger_irqs); ++i) { 937 int irq; 938 939 irq = platform_get_irq_byname(pdev, smbb_charger_irqs[i].name); 940 if (irq < 0) { 941 dev_err(&pdev->dev, "failed to get irq '%s'\n", 942 smbb_charger_irqs[i].name); 943 return irq; 944 } 945 946 smbb_charger_irqs[i].handler(irq, chg); 947 948 rc = devm_request_threaded_irq(&pdev->dev, irq, NULL, 949 smbb_charger_irqs[i].handler, IRQF_ONESHOT, 950 smbb_charger_irqs[i].name, chg); 951 if (rc) { 952 dev_err(&pdev->dev, "failed to request irq '%s'\n", 953 smbb_charger_irqs[i].name); 954 return rc; 955 } 956 } 957 958 /* 959 * otg regulator is used to control VBUS voltage direction 960 * when USB switches between host and gadget mode 961 */ 962 chg->otg_rdesc.id = -1; 963 chg->otg_rdesc.name = "otg-vbus"; 964 chg->otg_rdesc.ops = &smbb_chg_otg_ops; 965 chg->otg_rdesc.owner = THIS_MODULE; 966 chg->otg_rdesc.type = REGULATOR_VOLTAGE; 967 chg->otg_rdesc.supply_name = "usb-otg-in"; 968 chg->otg_rdesc.of_match = "otg-vbus"; 969 970 config.dev = &pdev->dev; 971 config.driver_data = chg; 972 973 chg->otg_reg = devm_regulator_register(&pdev->dev, &chg->otg_rdesc, 974 &config); 975 if (IS_ERR(chg->otg_reg)) 976 return PTR_ERR(chg->otg_reg); 977 978 chg->jeita_ext_temp = of_property_read_bool(pdev->dev.of_node, 979 "qcom,jeita-extended-temp-range"); 980 981 /* Set temperature range to [35%:70%] or [25%:80%] accordingly */ 982 rc = regmap_update_bits(chg->regmap, chg->addr + SMBB_BAT_BTC_CTRL, 983 BTC_CTRL_COLD_EXT | BTC_CTRL_HOT_EXT_N, 984 chg->jeita_ext_temp ? 985 BTC_CTRL_COLD_EXT : 986 BTC_CTRL_HOT_EXT_N); 987 if (rc) { 988 dev_err(&pdev->dev, 989 "unable to set %s temperature range\n", 990 chg->jeita_ext_temp ? "JEITA extended" : "normal"); 991 return rc; 992 } 993 994 for (i = 0; i < ARRAY_SIZE(smbb_charger_setup); ++i) { 995 const struct reg_off_mask_default *r = &smbb_charger_setup[i]; 996 997 if (r->rev_mask & BIT(chg->revision)) 998 continue; 999 1000 rc = regmap_update_bits(chg->regmap, chg->addr + r->offset, 1001 r->mask, r->value); 1002 if (rc) { 1003 dev_err(&pdev->dev, 1004 "unable to initializing charging, bailing\n"); 1005 return rc; 1006 } 1007 } 1008 1009 platform_set_drvdata(pdev, chg); 1010 1011 return 0; 1012 } 1013 1014 static int smbb_charger_remove(struct platform_device *pdev) 1015 { 1016 struct smbb_charger *chg; 1017 1018 chg = platform_get_drvdata(pdev); 1019 1020 regmap_update_bits(chg->regmap, chg->addr + SMBB_CHG_CTRL, CTRL_EN, 0); 1021 1022 return 0; 1023 } 1024 1025 static const struct of_device_id smbb_charger_id_table[] = { 1026 { .compatible = "qcom,pm8941-charger" }, 1027 { } 1028 }; 1029 MODULE_DEVICE_TABLE(of, smbb_charger_id_table); 1030 1031 static struct platform_driver smbb_charger_driver = { 1032 .probe = smbb_charger_probe, 1033 .remove = smbb_charger_remove, 1034 .driver = { 1035 .name = "qcom-smbb", 1036 .of_match_table = smbb_charger_id_table, 1037 }, 1038 }; 1039 module_platform_driver(smbb_charger_driver); 1040 1041 MODULE_DESCRIPTION("Qualcomm Switch-Mode Battery Charger and Boost driver"); 1042 MODULE_LICENSE("GPL v2"); 1043