1 /* 2 * Battery power supply driver for X-Powers AXP20X and AXP22X PMICs 3 * 4 * Copyright 2016 Free Electrons NextThing Co. 5 * Quentin Schulz <quentin.schulz@free-electrons.com> 6 * 7 * This driver is based on a previous upstreaming attempt by: 8 * Bruno Prémont <bonbons@linux-vserver.org> 9 * 10 * This file is subject to the terms and conditions of the GNU General 11 * Public License. See the file "COPYING" in the main directory of this 12 * archive for more details. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 */ 19 20 #include <linux/err.h> 21 #include <linux/interrupt.h> 22 #include <linux/irq.h> 23 #include <linux/module.h> 24 #include <linux/of.h> 25 #include <linux/of_device.h> 26 #include <linux/platform_device.h> 27 #include <linux/power_supply.h> 28 #include <linux/regmap.h> 29 #include <linux/slab.h> 30 #include <linux/time.h> 31 #include <linux/iio/iio.h> 32 #include <linux/iio/consumer.h> 33 #include <linux/mfd/axp20x.h> 34 35 #define AXP20X_PWR_STATUS_BAT_CHARGING BIT(2) 36 37 #define AXP20X_PWR_OP_BATT_PRESENT BIT(5) 38 #define AXP20X_PWR_OP_BATT_ACTIVATED BIT(3) 39 40 #define AXP209_FG_PERCENT GENMASK(6, 0) 41 #define AXP22X_FG_VALID BIT(7) 42 43 #define AXP20X_CHRG_CTRL1_TGT_VOLT GENMASK(6, 5) 44 #define AXP20X_CHRG_CTRL1_TGT_4_1V (0 << 5) 45 #define AXP20X_CHRG_CTRL1_TGT_4_15V (1 << 5) 46 #define AXP20X_CHRG_CTRL1_TGT_4_2V (2 << 5) 47 #define AXP20X_CHRG_CTRL1_TGT_4_36V (3 << 5) 48 49 #define AXP22X_CHRG_CTRL1_TGT_4_22V (1 << 5) 50 #define AXP22X_CHRG_CTRL1_TGT_4_24V (3 << 5) 51 52 #define AXP813_CHRG_CTRL1_TGT_4_35V (3 << 5) 53 54 #define AXP20X_CHRG_CTRL1_TGT_CURR GENMASK(3, 0) 55 56 #define AXP20X_V_OFF_MASK GENMASK(2, 0) 57 58 struct axp20x_batt_ps; 59 60 struct axp_data { 61 int ccc_scale; 62 int ccc_offset; 63 bool has_fg_valid; 64 int (*get_max_voltage)(struct axp20x_batt_ps *batt, int *val); 65 int (*set_max_voltage)(struct axp20x_batt_ps *batt, int val); 66 }; 67 68 struct axp20x_batt_ps { 69 struct regmap *regmap; 70 struct power_supply *batt; 71 struct device *dev; 72 struct iio_channel *batt_chrg_i; 73 struct iio_channel *batt_dischrg_i; 74 struct iio_channel *batt_v; 75 /* Maximum constant charge current */ 76 unsigned int max_ccc; 77 const struct axp_data *data; 78 }; 79 80 static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, 81 int *val) 82 { 83 int ret, reg; 84 85 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, ®); 86 if (ret) 87 return ret; 88 89 switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) { 90 case AXP20X_CHRG_CTRL1_TGT_4_1V: 91 *val = 4100000; 92 break; 93 case AXP20X_CHRG_CTRL1_TGT_4_15V: 94 *val = 4150000; 95 break; 96 case AXP20X_CHRG_CTRL1_TGT_4_2V: 97 *val = 4200000; 98 break; 99 case AXP20X_CHRG_CTRL1_TGT_4_36V: 100 *val = 4360000; 101 break; 102 default: 103 return -EINVAL; 104 } 105 106 return 0; 107 } 108 109 static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, 110 int *val) 111 { 112 int ret, reg; 113 114 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, ®); 115 if (ret) 116 return ret; 117 118 switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) { 119 case AXP20X_CHRG_CTRL1_TGT_4_1V: 120 *val = 4100000; 121 break; 122 case AXP20X_CHRG_CTRL1_TGT_4_2V: 123 *val = 4200000; 124 break; 125 case AXP22X_CHRG_CTRL1_TGT_4_22V: 126 *val = 4220000; 127 break; 128 case AXP22X_CHRG_CTRL1_TGT_4_24V: 129 *val = 4240000; 130 break; 131 default: 132 return -EINVAL; 133 } 134 135 return 0; 136 } 137 138 static int axp813_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, 139 int *val) 140 { 141 int ret, reg; 142 143 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, ®); 144 if (ret) 145 return ret; 146 147 switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) { 148 case AXP20X_CHRG_CTRL1_TGT_4_1V: 149 *val = 4100000; 150 break; 151 case AXP20X_CHRG_CTRL1_TGT_4_15V: 152 *val = 4150000; 153 break; 154 case AXP20X_CHRG_CTRL1_TGT_4_2V: 155 *val = 4200000; 156 break; 157 case AXP813_CHRG_CTRL1_TGT_4_35V: 158 *val = 4350000; 159 break; 160 default: 161 return -EINVAL; 162 } 163 164 return 0; 165 } 166 167 static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp, 168 int *val) 169 { 170 int ret; 171 172 ret = regmap_read(axp->regmap, AXP20X_CHRG_CTRL1, val); 173 if (ret) 174 return ret; 175 176 *val &= AXP20X_CHRG_CTRL1_TGT_CURR; 177 178 *val = *val * axp->data->ccc_scale + axp->data->ccc_offset; 179 180 return 0; 181 } 182 183 static int axp20x_battery_get_prop(struct power_supply *psy, 184 enum power_supply_property psp, 185 union power_supply_propval *val) 186 { 187 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); 188 struct iio_channel *chan; 189 int ret = 0, reg, val1; 190 191 switch (psp) { 192 case POWER_SUPPLY_PROP_PRESENT: 193 case POWER_SUPPLY_PROP_ONLINE: 194 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE, 195 ®); 196 if (ret) 197 return ret; 198 199 val->intval = !!(reg & AXP20X_PWR_OP_BATT_PRESENT); 200 break; 201 202 case POWER_SUPPLY_PROP_STATUS: 203 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS, 204 ®); 205 if (ret) 206 return ret; 207 208 if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) { 209 val->intval = POWER_SUPPLY_STATUS_CHARGING; 210 return 0; 211 } 212 213 ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i, 214 &val1); 215 if (ret) 216 return ret; 217 218 if (val1) { 219 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 220 return 0; 221 } 222 223 ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &val1); 224 if (ret) 225 return ret; 226 227 /* 228 * Fuel Gauge data takes 7 bits but the stored value seems to be 229 * directly the raw percentage without any scaling to 7 bits. 230 */ 231 if ((val1 & AXP209_FG_PERCENT) == 100) 232 val->intval = POWER_SUPPLY_STATUS_FULL; 233 else 234 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 235 break; 236 237 case POWER_SUPPLY_PROP_HEALTH: 238 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE, 239 &val1); 240 if (ret) 241 return ret; 242 243 if (val1 & AXP20X_PWR_OP_BATT_ACTIVATED) { 244 val->intval = POWER_SUPPLY_HEALTH_DEAD; 245 return 0; 246 } 247 248 val->intval = POWER_SUPPLY_HEALTH_GOOD; 249 break; 250 251 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 252 ret = axp20x_get_constant_charge_current(axp20x_batt, 253 &val->intval); 254 if (ret) 255 return ret; 256 break; 257 258 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 259 val->intval = axp20x_batt->max_ccc; 260 break; 261 262 case POWER_SUPPLY_PROP_CURRENT_NOW: 263 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS, 264 ®); 265 if (ret) 266 return ret; 267 268 if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) 269 chan = axp20x_batt->batt_chrg_i; 270 else 271 chan = axp20x_batt->batt_dischrg_i; 272 273 ret = iio_read_channel_processed(chan, &val->intval); 274 if (ret) 275 return ret; 276 277 /* IIO framework gives mA but Power Supply framework gives uA */ 278 val->intval *= 1000; 279 break; 280 281 case POWER_SUPPLY_PROP_CAPACITY: 282 /* When no battery is present, return capacity is 100% */ 283 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE, 284 ®); 285 if (ret) 286 return ret; 287 288 if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) { 289 val->intval = 100; 290 return 0; 291 } 292 293 ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, ®); 294 if (ret) 295 return ret; 296 297 if (axp20x_batt->data->has_fg_valid && !(reg & AXP22X_FG_VALID)) 298 return -EINVAL; 299 300 /* 301 * Fuel Gauge data takes 7 bits but the stored value seems to be 302 * directly the raw percentage without any scaling to 7 bits. 303 */ 304 val->intval = reg & AXP209_FG_PERCENT; 305 break; 306 307 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 308 return axp20x_batt->data->get_max_voltage(axp20x_batt, 309 &val->intval); 310 311 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 312 ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, ®); 313 if (ret) 314 return ret; 315 316 val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK); 317 break; 318 319 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 320 ret = iio_read_channel_processed(axp20x_batt->batt_v, 321 &val->intval); 322 if (ret) 323 return ret; 324 325 /* IIO framework gives mV but Power Supply framework gives uV */ 326 val->intval *= 1000; 327 break; 328 329 default: 330 return -EINVAL; 331 } 332 333 return 0; 334 } 335 336 static int axp22x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, 337 int val) 338 { 339 switch (val) { 340 case 4100000: 341 val = AXP20X_CHRG_CTRL1_TGT_4_1V; 342 break; 343 344 case 4200000: 345 val = AXP20X_CHRG_CTRL1_TGT_4_2V; 346 break; 347 348 default: 349 /* 350 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage 351 * can be set to 4.22V and 4.24V, but these voltages are too 352 * high for Lithium based batteries (AXP PMICs are supposed to 353 * be used with these kinds of battery). 354 */ 355 return -EINVAL; 356 } 357 358 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, 359 AXP20X_CHRG_CTRL1_TGT_VOLT, val); 360 } 361 362 static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, 363 int val) 364 { 365 switch (val) { 366 case 4100000: 367 val = AXP20X_CHRG_CTRL1_TGT_4_1V; 368 break; 369 370 case 4150000: 371 val = AXP20X_CHRG_CTRL1_TGT_4_15V; 372 break; 373 374 case 4200000: 375 val = AXP20X_CHRG_CTRL1_TGT_4_2V; 376 break; 377 378 default: 379 /* 380 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage 381 * can be set to 4.22V and 4.24V, but these voltages are too 382 * high for Lithium based batteries (AXP PMICs are supposed to 383 * be used with these kinds of battery). 384 */ 385 return -EINVAL; 386 } 387 388 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, 389 AXP20X_CHRG_CTRL1_TGT_VOLT, val); 390 } 391 392 static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, 393 int charge_current) 394 { 395 if (charge_current > axp_batt->max_ccc) 396 return -EINVAL; 397 398 charge_current = (charge_current - axp_batt->data->ccc_offset) / 399 axp_batt->data->ccc_scale; 400 401 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) 402 return -EINVAL; 403 404 return regmap_update_bits(axp_batt->regmap, AXP20X_CHRG_CTRL1, 405 AXP20X_CHRG_CTRL1_TGT_CURR, charge_current); 406 } 407 408 static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp, 409 int charge_current) 410 { 411 bool lower_max = false; 412 413 charge_current = (charge_current - axp->data->ccc_offset) / 414 axp->data->ccc_scale; 415 416 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) 417 return -EINVAL; 418 419 charge_current = charge_current * axp->data->ccc_scale + 420 axp->data->ccc_offset; 421 422 if (charge_current > axp->max_ccc) 423 dev_warn(axp->dev, 424 "Setting max constant charge current higher than previously defined. Note that increasing the constant charge current may damage your battery.\n"); 425 else 426 lower_max = true; 427 428 axp->max_ccc = charge_current; 429 430 if (lower_max) { 431 int current_cc; 432 433 axp20x_get_constant_charge_current(axp, ¤t_cc); 434 if (current_cc > charge_current) 435 axp20x_set_constant_charge_current(axp, charge_current); 436 } 437 438 return 0; 439 } 440 static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt, 441 int min_voltage) 442 { 443 int val1 = (min_voltage - 2600000) / 100000; 444 445 if (val1 < 0 || val1 > AXP20X_V_OFF_MASK) 446 return -EINVAL; 447 448 return regmap_update_bits(axp_batt->regmap, AXP20X_V_OFF, 449 AXP20X_V_OFF_MASK, val1); 450 } 451 452 static int axp20x_battery_set_prop(struct power_supply *psy, 453 enum power_supply_property psp, 454 const union power_supply_propval *val) 455 { 456 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); 457 458 switch (psp) { 459 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 460 return axp20x_set_voltage_min_design(axp20x_batt, val->intval); 461 462 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 463 return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval); 464 465 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 466 return axp20x_set_constant_charge_current(axp20x_batt, 467 val->intval); 468 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 469 return axp20x_set_max_constant_charge_current(axp20x_batt, 470 val->intval); 471 472 default: 473 return -EINVAL; 474 } 475 } 476 477 static enum power_supply_property axp20x_battery_props[] = { 478 POWER_SUPPLY_PROP_PRESENT, 479 POWER_SUPPLY_PROP_ONLINE, 480 POWER_SUPPLY_PROP_STATUS, 481 POWER_SUPPLY_PROP_VOLTAGE_NOW, 482 POWER_SUPPLY_PROP_CURRENT_NOW, 483 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 484 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 485 POWER_SUPPLY_PROP_HEALTH, 486 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 487 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 488 POWER_SUPPLY_PROP_CAPACITY, 489 }; 490 491 static int axp20x_battery_prop_writeable(struct power_supply *psy, 492 enum power_supply_property psp) 493 { 494 return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN || 495 psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN || 496 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT || 497 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; 498 } 499 500 static const struct power_supply_desc axp20x_batt_ps_desc = { 501 .name = "axp20x-battery", 502 .type = POWER_SUPPLY_TYPE_BATTERY, 503 .properties = axp20x_battery_props, 504 .num_properties = ARRAY_SIZE(axp20x_battery_props), 505 .property_is_writeable = axp20x_battery_prop_writeable, 506 .get_property = axp20x_battery_get_prop, 507 .set_property = axp20x_battery_set_prop, 508 }; 509 510 static const struct axp_data axp209_data = { 511 .ccc_scale = 100000, 512 .ccc_offset = 300000, 513 .get_max_voltage = axp20x_battery_get_max_voltage, 514 .set_max_voltage = axp20x_battery_set_max_voltage, 515 }; 516 517 static const struct axp_data axp221_data = { 518 .ccc_scale = 150000, 519 .ccc_offset = 300000, 520 .has_fg_valid = true, 521 .get_max_voltage = axp22x_battery_get_max_voltage, 522 .set_max_voltage = axp22x_battery_set_max_voltage, 523 }; 524 525 static const struct axp_data axp813_data = { 526 .ccc_scale = 200000, 527 .ccc_offset = 200000, 528 .has_fg_valid = true, 529 .get_max_voltage = axp813_battery_get_max_voltage, 530 .set_max_voltage = axp20x_battery_set_max_voltage, 531 }; 532 533 static const struct of_device_id axp20x_battery_ps_id[] = { 534 { 535 .compatible = "x-powers,axp209-battery-power-supply", 536 .data = (void *)&axp209_data, 537 }, { 538 .compatible = "x-powers,axp221-battery-power-supply", 539 .data = (void *)&axp221_data, 540 }, { 541 .compatible = "x-powers,axp813-battery-power-supply", 542 .data = (void *)&axp813_data, 543 }, { /* sentinel */ }, 544 }; 545 MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id); 546 547 static int axp20x_power_probe(struct platform_device *pdev) 548 { 549 struct axp20x_batt_ps *axp20x_batt; 550 struct power_supply_config psy_cfg = {}; 551 struct power_supply_battery_info info; 552 struct device *dev = &pdev->dev; 553 554 if (!of_device_is_available(pdev->dev.of_node)) 555 return -ENODEV; 556 557 axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt), 558 GFP_KERNEL); 559 if (!axp20x_batt) 560 return -ENOMEM; 561 562 axp20x_batt->dev = &pdev->dev; 563 564 axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v"); 565 if (IS_ERR(axp20x_batt->batt_v)) { 566 if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV) 567 return -EPROBE_DEFER; 568 return PTR_ERR(axp20x_batt->batt_v); 569 } 570 571 axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev, 572 "batt_chrg_i"); 573 if (IS_ERR(axp20x_batt->batt_chrg_i)) { 574 if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV) 575 return -EPROBE_DEFER; 576 return PTR_ERR(axp20x_batt->batt_chrg_i); 577 } 578 579 axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev, 580 "batt_dischrg_i"); 581 if (IS_ERR(axp20x_batt->batt_dischrg_i)) { 582 if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV) 583 return -EPROBE_DEFER; 584 return PTR_ERR(axp20x_batt->batt_dischrg_i); 585 } 586 587 axp20x_batt->regmap = dev_get_regmap(pdev->dev.parent, NULL); 588 platform_set_drvdata(pdev, axp20x_batt); 589 590 psy_cfg.drv_data = axp20x_batt; 591 psy_cfg.of_node = pdev->dev.of_node; 592 593 axp20x_batt->data = (struct axp_data *)of_device_get_match_data(dev); 594 595 axp20x_batt->batt = devm_power_supply_register(&pdev->dev, 596 &axp20x_batt_ps_desc, 597 &psy_cfg); 598 if (IS_ERR(axp20x_batt->batt)) { 599 dev_err(&pdev->dev, "failed to register power supply: %ld\n", 600 PTR_ERR(axp20x_batt->batt)); 601 return PTR_ERR(axp20x_batt->batt); 602 } 603 604 if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) { 605 int vmin = info.voltage_min_design_uv; 606 int ccc = info.constant_charge_current_max_ua; 607 608 if (vmin > 0 && axp20x_set_voltage_min_design(axp20x_batt, 609 vmin)) 610 dev_err(&pdev->dev, 611 "couldn't set voltage_min_design\n"); 612 613 /* Set max to unverified value to be able to set CCC */ 614 axp20x_batt->max_ccc = ccc; 615 616 if (ccc <= 0 || axp20x_set_constant_charge_current(axp20x_batt, 617 ccc)) { 618 dev_err(&pdev->dev, 619 "couldn't set constant charge current from DT: fallback to minimum value\n"); 620 ccc = 300000; 621 axp20x_batt->max_ccc = ccc; 622 axp20x_set_constant_charge_current(axp20x_batt, ccc); 623 } 624 } 625 626 /* 627 * Update max CCC to a valid value if battery info is present or set it 628 * to current register value by default. 629 */ 630 axp20x_get_constant_charge_current(axp20x_batt, 631 &axp20x_batt->max_ccc); 632 633 return 0; 634 } 635 636 static struct platform_driver axp20x_batt_driver = { 637 .probe = axp20x_power_probe, 638 .driver = { 639 .name = "axp20x-battery-power-supply", 640 .of_match_table = axp20x_battery_ps_id, 641 }, 642 }; 643 644 module_platform_driver(axp20x_batt_driver); 645 646 MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs"); 647 MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>"); 648 MODULE_LICENSE("GPL"); 649