1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Copyright (C) 2021 Samuel Holland <samuel@sholland.org> 4 5 #include <linux/i2c.h> 6 #include <linux/module.h> 7 #include <linux/power_supply.h> 8 #include <linux/regmap.h> 9 10 #define IP5XXX_BAT_TYPE_4_2V 0x0 11 #define IP5XXX_BAT_TYPE_4_3V 0x1 12 #define IP5XXX_BAT_TYPE_4_35V 0x2 13 #define IP5XXX_BAT_TYPE_4_4V 0x3 14 #define IP5XXX_CHG_STAT_IDLE 0x0 15 #define IP5XXX_CHG_STAT_TRICKLE 0x1 16 #define IP5XXX_CHG_STAT_CONST_VOLT 0x2 17 #define IP5XXX_CHG_STAT_CONST_CUR 0x3 18 #define IP5XXX_CHG_STAT_CONST_VOLT_STOP 0x4 19 #define IP5XXX_CHG_STAT_FULL 0x5 20 #define IP5XXX_CHG_STAT_TIMEOUT 0x6 21 22 struct ip5xxx { 23 struct regmap *regmap; 24 bool initialized; 25 struct { 26 struct { 27 /* Charger enable */ 28 struct regmap_field *enable; 29 /* Constant voltage value */ 30 struct regmap_field *const_volt_sel; 31 /* Constant current value */ 32 struct regmap_field *const_curr_sel; 33 /* Charger status */ 34 struct regmap_field *status; 35 /* Charging ended flag */ 36 struct regmap_field *chg_end; 37 /* Timeout flags (CV, charge, trickle) */ 38 struct regmap_field *timeout; 39 /* Overvoltage limit */ 40 struct regmap_field *vin_overvolt; 41 } charger; 42 struct { 43 /* Boost converter enable */ 44 struct regmap_field *enable; 45 struct { 46 /* Light load shutdown enable */ 47 struct regmap_field *enable; 48 /* Light load shutdown current limit */ 49 struct regmap_field *i_limit; 50 } light_load_shutdown; 51 /* Automatic powerup on increased load */ 52 struct regmap_field *load_powerup_en; 53 /* Automatic powerup on VIN pull-out */ 54 struct regmap_field *vin_pullout_en; 55 /* Undervoltage limit */ 56 struct regmap_field *undervolt_limit; 57 /* Light load status flag */ 58 struct regmap_field *light_load_status; 59 } boost; 60 struct { 61 /* NTC disable */ 62 struct regmap_field *ntc_dis; 63 /* Battery voltage type */ 64 struct regmap_field *type; 65 /* Battery voltage autoset from Vset pin */ 66 struct regmap_field *vset_en; 67 struct { 68 /* Battery measurement registers */ 69 struct ip5xxx_battery_adc_regs { 70 struct regmap_field *low; 71 struct regmap_field *high; 72 } volt, curr, open_volt; 73 } adc; 74 } battery; 75 struct { 76 /* Double/long press shutdown enable */ 77 struct regmap_field *shdn_enable; 78 /* WLED activation: double press or long press */ 79 struct regmap_field *wled_mode; 80 /* Shutdown activation: double press or long press */ 81 struct regmap_field *shdn_mode; 82 /* Long press time */ 83 struct regmap_field *long_press_time; 84 /* Button pressed */ 85 struct regmap_field *pressed; 86 /* Button long-pressed */ 87 struct regmap_field *long_pressed; 88 /* Button short-pressed */ 89 struct regmap_field *short_pressed; 90 } btn; 91 struct { 92 /* WLED enable */ 93 struct regmap_field *enable; 94 /* WLED detect */ 95 struct regmap_field *detect_en; 96 /* WLED present */ 97 struct regmap_field *present; 98 } wled; 99 } regs; 100 101 /* Maximum supported battery voltage (via regs.battery.type) */ 102 int vbat_max; 103 /* Scaling constants for regs.boost.undervolt_limit */ 104 struct { 105 int setpoint; 106 int microvolts_per_bit; 107 } boost_undervolt; 108 /* Scaling constants for regs.charger.const_curr_sel */ 109 struct { 110 int setpoint; 111 } const_curr; 112 /* Whether regs.charger.chg_end is inverted */ 113 u8 chg_end_inverted; 114 }; 115 116 #define REG_FIELD_UNSUPPORTED { .lsb = 1 } 117 /* Register fields layout. Unsupported registers marked as { .lsb = 1 } */ 118 struct ip5xxx_regfield_config { 119 const struct reg_field charger_enable; 120 const struct reg_field charger_const_volt_sel; 121 const struct reg_field charger_const_curr_sel; 122 const struct reg_field charger_status; 123 const struct reg_field charger_chg_end; 124 const struct reg_field charger_timeout; 125 const struct reg_field charger_vin_overvolt; 126 const struct reg_field boost_enable; 127 const struct reg_field boost_llshdn_enable; 128 const struct reg_field boost_llshdn_i_limit; 129 const struct reg_field boost_load_powerup_en; 130 const struct reg_field boost_vin_pullout_en; 131 const struct reg_field boost_undervolt_limit; 132 const struct reg_field boost_light_load_status; 133 const struct reg_field battery_ntc_dis; 134 const struct reg_field battery_type; 135 const struct reg_field battery_vset_en; 136 const struct reg_field battery_adc_volt_low; 137 const struct reg_field battery_adc_volt_high; 138 const struct reg_field battery_adc_curr_low; 139 const struct reg_field battery_adc_curr_high; 140 const struct reg_field battery_adc_ovolt_low; 141 const struct reg_field battery_adc_ovolt_high; 142 const struct reg_field btn_shdn_enable; 143 const struct reg_field btn_wled_mode; 144 const struct reg_field btn_shdn_mode; 145 const struct reg_field btn_long_press_time; 146 const struct reg_field btn_pressed; 147 const struct reg_field btn_long_pressed; 148 const struct reg_field btn_short_pressed; 149 const struct reg_field wled_enable; 150 const struct reg_field wled_detect_en; 151 const struct reg_field wled_present; 152 153 int vbat_max; 154 int boost_undervolt_setpoint; 155 int boost_undervolt_uv_per_bit; 156 int const_curr_setpoint; 157 u8 chg_end_inverted; 158 }; 159 160 /* 161 * The IP5xxx charger only responds on I2C when it is "awake". The charger is 162 * generally only awake when VIN is powered or when its boost converter is 163 * enabled. Going into shutdown resets all register values. To handle this: 164 * 1) When any bus error occurs, assume the charger has gone into shutdown. 165 * 2) Attempt the initialization sequence on each subsequent register access 166 * until it succeeds. 167 */ 168 static int ip5xxx_read(struct ip5xxx *ip5xxx, struct regmap_field *field, 169 unsigned int *val) 170 { 171 int ret; 172 173 if (!field) 174 return -EOPNOTSUPP; 175 176 ret = regmap_field_read(field, val); 177 if (ret) 178 ip5xxx->initialized = false; 179 180 return ret; 181 } 182 183 static int ip5xxx_write(struct ip5xxx *ip5xxx, struct regmap_field *field, 184 unsigned int val) 185 { 186 int ret; 187 188 if (!field) 189 return -EOPNOTSUPP; 190 191 ret = regmap_field_write(field, val); 192 if (ret) 193 ip5xxx->initialized = false; 194 195 return ret; 196 } 197 198 static int ip5xxx_initialize(struct power_supply *psy) 199 { 200 struct ip5xxx *ip5xxx = power_supply_get_drvdata(psy); 201 int ret; 202 203 if (ip5xxx->initialized) 204 return 0; 205 206 /* 207 * Disable shutdown under light load. 208 * Enable power on when under load. 209 */ 210 if (ip5xxx->regs.boost.light_load_shutdown.enable) { 211 ret = ip5xxx_write(ip5xxx, ip5xxx->regs.boost.light_load_shutdown.enable, 0); 212 if (ret) 213 return ret; 214 } 215 ret = ip5xxx_write(ip5xxx, ip5xxx->regs.boost.load_powerup_en, 1); 216 if (ret) 217 return ret; 218 219 /* 220 * Enable shutdown after a long button press (as configured below). 221 */ 222 ret = ip5xxx_write(ip5xxx, ip5xxx->regs.btn.shdn_enable, 1); 223 if (ret) 224 return ret; 225 226 /* 227 * Power on automatically when VIN is removed. 228 */ 229 ret = ip5xxx_write(ip5xxx, ip5xxx->regs.boost.vin_pullout_en, 1); 230 if (ret) 231 return ret; 232 233 /* 234 * Enable the NTC. 235 * Configure the button for two presses => LED, long press => shutdown. 236 */ 237 if (ip5xxx->regs.battery.ntc_dis) { 238 ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.ntc_dis, 0); 239 if (ret) 240 return ret; 241 } 242 ret = ip5xxx_write(ip5xxx, ip5xxx->regs.btn.wled_mode, 1); 243 if (ret) 244 return ret; 245 ret = ip5xxx_write(ip5xxx, ip5xxx->regs.btn.shdn_mode, 1); 246 if (ret) 247 return ret; 248 249 ip5xxx->initialized = true; 250 dev_dbg(psy->dev.parent, "Initialized after power on\n"); 251 252 return 0; 253 } 254 255 static const enum power_supply_property ip5xxx_battery_properties[] = { 256 POWER_SUPPLY_PROP_STATUS, 257 POWER_SUPPLY_PROP_CHARGE_TYPE, 258 POWER_SUPPLY_PROP_HEALTH, 259 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 260 POWER_SUPPLY_PROP_VOLTAGE_NOW, 261 POWER_SUPPLY_PROP_VOLTAGE_OCV, 262 POWER_SUPPLY_PROP_CURRENT_NOW, 263 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 264 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 265 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 266 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 267 }; 268 269 static int ip5xxx_battery_get_status(struct ip5xxx *ip5xxx, int *val) 270 { 271 unsigned int rval; 272 int ret; 273 274 if (!ip5xxx->regs.charger.status) { 275 // Fall-back to Charging Ended bit 276 ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.chg_end, &rval); 277 if (ret) 278 return ret; 279 280 if (rval == ip5xxx->chg_end_inverted) 281 *val = POWER_SUPPLY_STATUS_CHARGING; 282 else 283 *val = POWER_SUPPLY_STATUS_NOT_CHARGING; 284 return 0; 285 } 286 287 ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.status, &rval); 288 if (ret) 289 return ret; 290 291 switch (rval) { 292 case IP5XXX_CHG_STAT_IDLE: 293 *val = POWER_SUPPLY_STATUS_DISCHARGING; 294 break; 295 case IP5XXX_CHG_STAT_TRICKLE: 296 case IP5XXX_CHG_STAT_CONST_CUR: 297 case IP5XXX_CHG_STAT_CONST_VOLT: 298 *val = POWER_SUPPLY_STATUS_CHARGING; 299 break; 300 case IP5XXX_CHG_STAT_CONST_VOLT_STOP: 301 case IP5XXX_CHG_STAT_FULL: 302 *val = POWER_SUPPLY_STATUS_FULL; 303 break; 304 case IP5XXX_CHG_STAT_TIMEOUT: 305 *val = POWER_SUPPLY_STATUS_NOT_CHARGING; 306 break; 307 default: 308 return -EINVAL; 309 } 310 311 return 0; 312 } 313 314 static int ip5xxx_battery_get_charge_type(struct ip5xxx *ip5xxx, int *val) 315 { 316 unsigned int rval; 317 int ret; 318 319 ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.status, &rval); 320 if (ret) 321 return ret; 322 323 switch (rval) { 324 case IP5XXX_CHG_STAT_IDLE: 325 case IP5XXX_CHG_STAT_CONST_VOLT_STOP: 326 case IP5XXX_CHG_STAT_FULL: 327 case IP5XXX_CHG_STAT_TIMEOUT: 328 *val = POWER_SUPPLY_CHARGE_TYPE_NONE; 329 break; 330 case IP5XXX_CHG_STAT_TRICKLE: 331 *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; 332 break; 333 case IP5XXX_CHG_STAT_CONST_CUR: 334 case IP5XXX_CHG_STAT_CONST_VOLT: 335 *val = POWER_SUPPLY_CHARGE_TYPE_STANDARD; 336 break; 337 default: 338 return -EINVAL; 339 } 340 341 return 0; 342 } 343 344 static int ip5xxx_battery_get_health(struct ip5xxx *ip5xxx, int *val) 345 { 346 unsigned int rval; 347 int ret; 348 349 ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.timeout, &rval); 350 if (ret) 351 return ret; 352 353 if (rval) 354 *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; 355 else 356 *val = POWER_SUPPLY_HEALTH_GOOD; 357 358 return 0; 359 } 360 361 static int ip5xxx_battery_get_voltage_max(struct ip5xxx *ip5xxx, int *val) 362 { 363 unsigned int rval; 364 int ret; 365 366 ret = ip5xxx_read(ip5xxx, ip5xxx->regs.battery.type, &rval); 367 if (ret) 368 return ret; 369 370 /* 371 * It is not clear what this will return if 372 * IP5XXX_CHG_CTL4_BAT_TYPE_SEL_EN is not set... 373 */ 374 switch (rval) { 375 case IP5XXX_BAT_TYPE_4_2V: 376 *val = 4200000; 377 break; 378 case IP5XXX_BAT_TYPE_4_3V: 379 *val = 4300000; 380 break; 381 case IP5XXX_BAT_TYPE_4_35V: 382 *val = 4350000; 383 break; 384 case IP5XXX_BAT_TYPE_4_4V: 385 *val = 4400000; 386 break; 387 default: 388 return -EINVAL; 389 } 390 391 return 0; 392 } 393 394 static int ip5xxx_battery_read_adc(struct ip5xxx *ip5xxx, 395 struct ip5xxx_battery_adc_regs *regs, int *val) 396 { 397 unsigned int hi, lo; 398 int ret; 399 400 ret = ip5xxx_read(ip5xxx, regs->low, &lo); 401 if (ret) 402 return ret; 403 404 ret = ip5xxx_read(ip5xxx, regs->high, &hi); 405 if (ret) 406 return ret; 407 408 *val = sign_extend32(hi << 8 | lo, 13); 409 410 return 0; 411 } 412 413 static int ip5xxx_battery_get_property(struct power_supply *psy, 414 enum power_supply_property psp, 415 union power_supply_propval *val) 416 { 417 struct ip5xxx *ip5xxx = power_supply_get_drvdata(psy); 418 int raw, ret, vmax; 419 unsigned int rval; 420 421 ret = ip5xxx_initialize(psy); 422 if (ret) 423 return ret; 424 425 switch (psp) { 426 case POWER_SUPPLY_PROP_STATUS: 427 return ip5xxx_battery_get_status(ip5xxx, &val->intval); 428 429 case POWER_SUPPLY_PROP_CHARGE_TYPE: 430 return ip5xxx_battery_get_charge_type(ip5xxx, &val->intval); 431 432 case POWER_SUPPLY_PROP_HEALTH: 433 return ip5xxx_battery_get_health(ip5xxx, &val->intval); 434 435 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 436 return ip5xxx_battery_get_voltage_max(ip5xxx, &val->intval); 437 438 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 439 ret = ip5xxx_battery_read_adc(ip5xxx, &ip5xxx->regs.battery.adc.volt, &raw); 440 if (ret) 441 return ret; 442 443 val->intval = 2600000 + DIV_ROUND_CLOSEST(raw * 26855, 100); 444 return 0; 445 446 case POWER_SUPPLY_PROP_VOLTAGE_OCV: 447 ret = ip5xxx_battery_read_adc(ip5xxx, &ip5xxx->regs.battery.adc.open_volt, &raw); 448 if (ret) 449 return ret; 450 451 val->intval = 2600000 + DIV_ROUND_CLOSEST(raw * 26855, 100); 452 return 0; 453 454 case POWER_SUPPLY_PROP_CURRENT_NOW: 455 ret = ip5xxx_battery_read_adc(ip5xxx, &ip5xxx->regs.battery.adc.curr, &raw); 456 if (ret) 457 return ret; 458 459 val->intval = DIV_ROUND_CLOSEST(raw * 149197, 200); 460 return 0; 461 462 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 463 ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.const_curr_sel, &rval); 464 if (ret) 465 return ret; 466 467 val->intval = ip5xxx->const_curr.setpoint + 100000 * rval; 468 return 0; 469 470 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 471 val->intval = 100000 * 0x1f; 472 return 0; 473 474 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 475 ret = ip5xxx_battery_get_voltage_max(ip5xxx, &vmax); 476 if (ret) 477 return ret; 478 479 ret = ip5xxx_read(ip5xxx, ip5xxx->regs.charger.const_volt_sel, &rval); 480 if (ret) 481 return ret; 482 483 val->intval = vmax + 14000 * rval; 484 return 0; 485 486 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 487 ret = ip5xxx_battery_get_voltage_max(ip5xxx, &vmax); 488 if (ret) 489 return ret; 490 491 val->intval = vmax + 14000 * 3; 492 return 0; 493 494 default: 495 return -EINVAL; 496 } 497 } 498 499 static int ip5xxx_battery_set_voltage_max(struct ip5xxx *ip5xxx, int val) 500 { 501 unsigned int rval; 502 int ret; 503 504 if (val > ip5xxx->vbat_max) 505 return -EINVAL; 506 507 switch (val) { 508 case 4200000: 509 rval = IP5XXX_BAT_TYPE_4_2V; 510 break; 511 case 4300000: 512 rval = IP5XXX_BAT_TYPE_4_3V; 513 break; 514 case 4350000: 515 rval = IP5XXX_BAT_TYPE_4_35V; 516 break; 517 case 4400000: 518 rval = IP5XXX_BAT_TYPE_4_4V; 519 break; 520 default: 521 return -EINVAL; 522 } 523 524 ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.type, rval); 525 if (ret) 526 return ret; 527 528 /* Don't try to auto-detect battery type, even if the IC could */ 529 if (ip5xxx->regs.battery.vset_en) { 530 ret = ip5xxx_write(ip5xxx, ip5xxx->regs.battery.vset_en, 1); 531 if (ret) 532 return ret; 533 } 534 535 return 0; 536 } 537 538 static int ip5xxx_battery_set_property(struct power_supply *psy, 539 enum power_supply_property psp, 540 const union power_supply_propval *val) 541 { 542 struct ip5xxx *ip5xxx = power_supply_get_drvdata(psy); 543 unsigned int rval; 544 int ret, vmax; 545 546 ret = ip5xxx_initialize(psy); 547 if (ret) 548 return ret; 549 550 switch (psp) { 551 case POWER_SUPPLY_PROP_STATUS: 552 switch (val->intval) { 553 case POWER_SUPPLY_STATUS_CHARGING: 554 rval = 1; 555 break; 556 case POWER_SUPPLY_STATUS_DISCHARGING: 557 case POWER_SUPPLY_STATUS_NOT_CHARGING: 558 rval = 0; 559 break; 560 default: 561 return -EINVAL; 562 } 563 return ip5xxx_write(ip5xxx, ip5xxx->regs.charger.enable, rval); 564 565 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 566 return ip5xxx_battery_set_voltage_max(ip5xxx, val->intval); 567 568 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 569 rval = (val->intval - ip5xxx->const_curr.setpoint) / 100000; 570 return ip5xxx_write(ip5xxx, ip5xxx->regs.charger.const_curr_sel, rval); 571 572 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 573 ret = ip5xxx_battery_get_voltage_max(ip5xxx, &vmax); 574 if (ret) 575 return ret; 576 577 rval = (val->intval - vmax) / 14000; 578 return ip5xxx_write(ip5xxx, ip5xxx->regs.charger.const_volt_sel, rval); 579 580 default: 581 return -EINVAL; 582 } 583 } 584 585 static int ip5xxx_battery_property_is_writeable(struct power_supply *psy, 586 enum power_supply_property psp) 587 { 588 return psp == POWER_SUPPLY_PROP_STATUS || 589 psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN || 590 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT || 591 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE; 592 } 593 594 static const struct power_supply_desc ip5xxx_battery_desc = { 595 .name = "ip5xxx-battery", 596 .type = POWER_SUPPLY_TYPE_BATTERY, 597 .properties = ip5xxx_battery_properties, 598 .num_properties = ARRAY_SIZE(ip5xxx_battery_properties), 599 .get_property = ip5xxx_battery_get_property, 600 .set_property = ip5xxx_battery_set_property, 601 .property_is_writeable = ip5xxx_battery_property_is_writeable, 602 }; 603 604 static const enum power_supply_property ip5xxx_boost_properties[] = { 605 POWER_SUPPLY_PROP_ONLINE, 606 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 607 }; 608 609 static int ip5xxx_boost_get_property(struct power_supply *psy, 610 enum power_supply_property psp, 611 union power_supply_propval *val) 612 { 613 struct ip5xxx *ip5xxx = power_supply_get_drvdata(psy); 614 unsigned int rval; 615 int ret; 616 617 ret = ip5xxx_initialize(psy); 618 if (ret) 619 return ret; 620 621 switch (psp) { 622 case POWER_SUPPLY_PROP_ONLINE: 623 ret = ip5xxx_read(ip5xxx, ip5xxx->regs.boost.enable, &rval); 624 if (ret) 625 return ret; 626 627 val->intval = !!rval; 628 return 0; 629 630 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 631 ret = ip5xxx_read(ip5xxx, ip5xxx->regs.boost.undervolt_limit, &rval); 632 if (ret) 633 return ret; 634 635 val->intval = ip5xxx->boost_undervolt.setpoint + 636 ip5xxx->boost_undervolt.microvolts_per_bit * rval; 637 return 0; 638 639 default: 640 return -EINVAL; 641 } 642 } 643 644 static int ip5xxx_boost_set_property(struct power_supply *psy, 645 enum power_supply_property psp, 646 const union power_supply_propval *val) 647 { 648 struct ip5xxx *ip5xxx = power_supply_get_drvdata(psy); 649 unsigned int rval; 650 int ret; 651 652 ret = ip5xxx_initialize(psy); 653 if (ret) 654 return ret; 655 656 switch (psp) { 657 case POWER_SUPPLY_PROP_ONLINE: 658 return ip5xxx_write(ip5xxx, ip5xxx->regs.boost.enable, !!val->intval); 659 660 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 661 rval = (val->intval - ip5xxx->boost_undervolt.setpoint) / 662 ip5xxx->boost_undervolt.microvolts_per_bit; 663 return ip5xxx_write(ip5xxx, ip5xxx->regs.boost.undervolt_limit, rval); 664 665 default: 666 return -EINVAL; 667 } 668 } 669 670 static int ip5xxx_boost_property_is_writeable(struct power_supply *psy, 671 enum power_supply_property psp) 672 { 673 return true; 674 } 675 676 static const struct power_supply_desc ip5xxx_boost_desc = { 677 .name = "ip5xxx-boost", 678 .type = POWER_SUPPLY_TYPE_USB, 679 .properties = ip5xxx_boost_properties, 680 .num_properties = ARRAY_SIZE(ip5xxx_boost_properties), 681 .get_property = ip5xxx_boost_get_property, 682 .set_property = ip5xxx_boost_set_property, 683 .property_is_writeable = ip5xxx_boost_property_is_writeable, 684 }; 685 686 static const struct regmap_config ip5xxx_regmap_config = { 687 .reg_bits = 8, 688 .val_bits = 8, 689 .max_register = 0xa9, 690 }; 691 692 static struct ip5xxx_regfield_config ip51xx_fields = { 693 .charger_enable = REG_FIELD(0x01, 1, 1), 694 .charger_const_volt_sel = REG_FIELD(0x24, 1, 2), 695 .charger_const_curr_sel = REG_FIELD(0x25, 0, 4), 696 .charger_status = REG_FIELD(0x71, 5, 7), 697 .charger_chg_end = REG_FIELD(0x71, 3, 3), 698 .charger_timeout = REG_FIELD(0x71, 0, 2), 699 .charger_vin_overvolt = REG_FIELD(0x72, 5, 5), 700 .boost_enable = REG_FIELD(0x01, 2, 2), 701 .boost_llshdn_enable = REG_FIELD(0x02, 1, 1), 702 .boost_llshdn_i_limit = REG_FIELD(0x0c, 3, 7), 703 .boost_load_powerup_en = REG_FIELD(0x02, 0, 0), 704 .boost_vin_pullout_en = REG_FIELD(0x04, 5, 5), 705 .boost_undervolt_limit = REG_FIELD(0x22, 2, 3), 706 .boost_light_load_status = REG_FIELD(0x72, 6, 6), 707 .battery_ntc_dis = REG_FIELD(0x07, 6, 6), 708 .battery_type = REG_FIELD(0x24, 5, 6), 709 .battery_vset_en = REG_FIELD(0x26, 6, 6), 710 .battery_adc_volt_low = REG_FIELD(0xa2, 0, 7), 711 .battery_adc_volt_high = REG_FIELD(0xa3, 0, 5), 712 .battery_adc_curr_low = REG_FIELD(0xa4, 0, 7), 713 .battery_adc_curr_high = REG_FIELD(0xa5, 0, 5), 714 .battery_adc_ovolt_low = REG_FIELD(0xa8, 0, 7), 715 .battery_adc_ovolt_high = REG_FIELD(0xa9, 0, 5), 716 .btn_shdn_enable = REG_FIELD(0x03, 5, 5), 717 .btn_wled_mode = REG_FIELD(0x07, 1, 1), 718 .btn_shdn_mode = REG_FIELD(0x07, 0, 0), 719 .btn_long_press_time = REG_FIELD(0x03, 6, 7), 720 .btn_pressed = REG_FIELD(0x77, 3, 3), 721 .btn_long_pressed = REG_FIELD(0x77, 1, 1), 722 .btn_short_pressed = REG_FIELD(0x77, 0, 0), 723 .wled_enable = REG_FIELD(0x01, 3, 3), 724 .wled_detect_en = REG_FIELD(0x01, 4, 4), 725 .wled_present = REG_FIELD(0x72, 7, 7), 726 727 .vbat_max = 4350000, 728 .boost_undervolt_setpoint = 4530000, 729 .boost_undervolt_uv_per_bit = 100000, 730 }; 731 732 static struct ip5xxx_regfield_config ip5306_fields = { 733 .charger_enable = REG_FIELD(0x00, 4, 4), 734 .charger_const_volt_sel = REG_FIELD(0x22, 0, 1), 735 .charger_const_curr_sel = REG_FIELD(0x24, 0, 4), 736 .charger_status = REG_FIELD_UNSUPPORTED, // other bits... 737 .charger_chg_end = REG_FIELD(0x71, 3, 3), 738 .charger_timeout = REG_FIELD_UNSUPPORTED, 739 .charger_vin_overvolt = REG_FIELD_UNSUPPORTED, 740 .boost_enable = REG_FIELD(0x00, 5, 5), 741 .boost_llshdn_enable = REG_FIELD_UNSUPPORTED, 742 .boost_llshdn_i_limit = REG_FIELD_UNSUPPORTED, 743 .boost_load_powerup_en = REG_FIELD(0x00, 2, 2), 744 .boost_vin_pullout_en = REG_FIELD(0x01, 2, 2), 745 .boost_undervolt_limit = REG_FIELD(0x21, 2, 4), 746 .boost_light_load_status = REG_FIELD(0x72, 2, 2), 747 .battery_ntc_dis = REG_FIELD_UNSUPPORTED, 748 .battery_type = REG_FIELD(0x22, 2, 3), 749 .battery_vset_en = REG_FIELD_UNSUPPORTED, 750 .battery_adc_volt_low = REG_FIELD_UNSUPPORTED, 751 .battery_adc_volt_high = REG_FIELD_UNSUPPORTED, 752 .battery_adc_curr_low = REG_FIELD_UNSUPPORTED, 753 .battery_adc_curr_high = REG_FIELD_UNSUPPORTED, 754 .battery_adc_ovolt_low = REG_FIELD_UNSUPPORTED, 755 .battery_adc_ovolt_high = REG_FIELD_UNSUPPORTED, 756 .btn_shdn_enable = REG_FIELD(0x00, 0, 0), 757 .btn_wled_mode = REG_FIELD(0x01, 6, 6), 758 .btn_shdn_mode = REG_FIELD(0x01, 7, 7), 759 .btn_long_press_time = REG_FIELD(0x02, 4, 4), // +1s 760 .btn_pressed = REG_FIELD_UNSUPPORTED, 761 /* TODO: double press */ 762 .btn_long_pressed = REG_FIELD(0x77, 1, 1), 763 .btn_short_pressed = REG_FIELD(0x77, 0, 0), 764 .wled_enable = REG_FIELD_UNSUPPORTED, 765 .wled_detect_en = REG_FIELD_UNSUPPORTED, 766 .wled_present = REG_FIELD_UNSUPPORTED, 767 768 .vbat_max = 4400000, 769 .boost_undervolt_setpoint = 4450000, 770 .boost_undervolt_uv_per_bit = 50000, 771 .const_curr_setpoint = 50000, 772 .chg_end_inverted = 1, 773 }; 774 775 #define ip5xxx_setup_reg(_field, _reg) \ 776 do { \ 777 if (likely(cfg->_field.lsb <= cfg->_field.msb)) { \ 778 struct regmap_field *_tmp = devm_regmap_field_alloc(dev, \ 779 ip5xxx->regmap, cfg->_field); \ 780 if (!IS_ERR(_tmp)) \ 781 ip5xxx->regs._reg = _tmp; \ 782 } \ 783 } while (0) 784 785 static void ip5xxx_setup_regs(struct device *dev, struct ip5xxx *ip5xxx, 786 const struct ip5xxx_regfield_config *cfg) 787 { 788 ip5xxx_setup_reg(charger_enable, charger.enable); 789 ip5xxx_setup_reg(charger_const_volt_sel, charger.const_volt_sel); 790 ip5xxx_setup_reg(charger_const_curr_sel, charger.const_curr_sel); 791 ip5xxx_setup_reg(charger_status, charger.status); 792 ip5xxx_setup_reg(charger_chg_end, charger.chg_end); 793 ip5xxx_setup_reg(charger_timeout, charger.timeout); 794 ip5xxx_setup_reg(charger_vin_overvolt, charger.vin_overvolt); 795 ip5xxx_setup_reg(boost_enable, boost.enable); 796 ip5xxx_setup_reg(boost_llshdn_enable, boost.light_load_shutdown.enable); 797 ip5xxx_setup_reg(boost_llshdn_i_limit, boost.light_load_shutdown.i_limit); 798 ip5xxx_setup_reg(boost_load_powerup_en, boost.load_powerup_en); 799 ip5xxx_setup_reg(boost_vin_pullout_en, boost.vin_pullout_en); 800 ip5xxx_setup_reg(boost_undervolt_limit, boost.undervolt_limit); 801 ip5xxx_setup_reg(boost_light_load_status, boost.light_load_status); 802 ip5xxx_setup_reg(battery_ntc_dis, battery.ntc_dis); 803 ip5xxx_setup_reg(battery_type, battery.type); 804 ip5xxx_setup_reg(battery_vset_en, battery.vset_en); 805 ip5xxx_setup_reg(battery_adc_volt_low, battery.adc.volt.low); 806 ip5xxx_setup_reg(battery_adc_volt_high, battery.adc.volt.high); 807 ip5xxx_setup_reg(battery_adc_curr_low, battery.adc.curr.low); 808 ip5xxx_setup_reg(battery_adc_curr_high, battery.adc.curr.high); 809 ip5xxx_setup_reg(battery_adc_ovolt_low, battery.adc.open_volt.low); 810 ip5xxx_setup_reg(battery_adc_ovolt_high, battery.adc.open_volt.high); 811 ip5xxx_setup_reg(btn_shdn_enable, btn.shdn_enable); 812 ip5xxx_setup_reg(btn_wled_mode, btn.wled_mode); 813 ip5xxx_setup_reg(btn_shdn_mode, btn.shdn_mode); 814 ip5xxx_setup_reg(btn_long_press_time, btn.long_press_time); 815 ip5xxx_setup_reg(btn_pressed, btn.pressed); 816 ip5xxx_setup_reg(btn_long_pressed, btn.long_pressed); 817 ip5xxx_setup_reg(btn_short_pressed, btn.short_pressed); 818 ip5xxx_setup_reg(wled_enable, wled.enable); 819 ip5xxx_setup_reg(wled_detect_en, wled.detect_en); 820 ip5xxx_setup_reg(wled_present, wled.present); 821 822 ip5xxx->vbat_max = cfg->vbat_max; 823 ip5xxx->boost_undervolt.setpoint = cfg->boost_undervolt_setpoint; 824 ip5xxx->boost_undervolt.microvolts_per_bit = cfg->boost_undervolt_uv_per_bit; 825 ip5xxx->const_curr.setpoint = cfg->const_curr_setpoint; 826 ip5xxx->chg_end_inverted = cfg->chg_end_inverted; 827 } 828 829 static int ip5xxx_power_probe(struct i2c_client *client) 830 { 831 const struct ip5xxx_regfield_config *fields = &ip51xx_fields; 832 struct power_supply_config psy_cfg = {}; 833 struct device *dev = &client->dev; 834 const struct of_device_id *of_id; 835 struct power_supply *psy; 836 struct ip5xxx *ip5xxx; 837 838 ip5xxx = devm_kzalloc(dev, sizeof(*ip5xxx), GFP_KERNEL); 839 if (!ip5xxx) 840 return -ENOMEM; 841 842 ip5xxx->regmap = devm_regmap_init_i2c(client, &ip5xxx_regmap_config); 843 if (IS_ERR(ip5xxx->regmap)) 844 return PTR_ERR(ip5xxx->regmap); 845 846 of_id = i2c_of_match_device(dev->driver->of_match_table, client); 847 if (of_id) 848 fields = (const struct ip5xxx_regfield_config *)of_id->data; 849 ip5xxx_setup_regs(dev, ip5xxx, fields); 850 851 psy_cfg.of_node = dev->of_node; 852 psy_cfg.drv_data = ip5xxx; 853 854 psy = devm_power_supply_register(dev, &ip5xxx_battery_desc, &psy_cfg); 855 if (IS_ERR(psy)) 856 return PTR_ERR(psy); 857 858 psy = devm_power_supply_register(dev, &ip5xxx_boost_desc, &psy_cfg); 859 if (IS_ERR(psy)) 860 return PTR_ERR(psy); 861 862 return 0; 863 } 864 865 static const struct of_device_id ip5xxx_power_of_match[] = { 866 { .compatible = "injoinic,ip5108", .data = &ip51xx_fields }, 867 { .compatible = "injoinic,ip5109", .data = &ip51xx_fields }, 868 { .compatible = "injoinic,ip5207", .data = &ip51xx_fields }, 869 { .compatible = "injoinic,ip5209", .data = &ip51xx_fields }, 870 { .compatible = "injoinic,ip5306", .data = &ip5306_fields }, 871 { } 872 }; 873 MODULE_DEVICE_TABLE(of, ip5xxx_power_of_match); 874 875 static struct i2c_driver ip5xxx_power_driver = { 876 .probe = ip5xxx_power_probe, 877 .driver = { 878 .name = "ip5xxx-power", 879 .of_match_table = ip5xxx_power_of_match, 880 } 881 }; 882 module_i2c_driver(ip5xxx_power_driver); 883 884 MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>"); 885 MODULE_DESCRIPTION("Injoinic IP5xxx power bank IC driver"); 886 MODULE_LICENSE("GPL"); 887