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 AXP20X_CHRG_CTRL1_TGT_CURR GENMASK(3, 0) 53 54 #define AXP20X_V_OFF_MASK GENMASK(2, 0) 55 56 struct axp20x_batt_ps { 57 struct regmap *regmap; 58 struct power_supply *batt; 59 struct device *dev; 60 struct iio_channel *batt_chrg_i; 61 struct iio_channel *batt_dischrg_i; 62 struct iio_channel *batt_v; 63 /* Maximum constant charge current */ 64 unsigned int max_ccc; 65 u8 axp_id; 66 }; 67 68 static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, 69 int *val) 70 { 71 int ret, reg; 72 73 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, ®); 74 if (ret) 75 return ret; 76 77 switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) { 78 case AXP20X_CHRG_CTRL1_TGT_4_1V: 79 *val = 4100000; 80 break; 81 case AXP20X_CHRG_CTRL1_TGT_4_15V: 82 *val = 4150000; 83 break; 84 case AXP20X_CHRG_CTRL1_TGT_4_2V: 85 *val = 4200000; 86 break; 87 case AXP20X_CHRG_CTRL1_TGT_4_36V: 88 *val = 4360000; 89 break; 90 default: 91 return -EINVAL; 92 } 93 94 return 0; 95 } 96 97 static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, 98 int *val) 99 { 100 int ret, reg; 101 102 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, ®); 103 if (ret) 104 return ret; 105 106 switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) { 107 case AXP20X_CHRG_CTRL1_TGT_4_1V: 108 *val = 4100000; 109 break; 110 case AXP20X_CHRG_CTRL1_TGT_4_2V: 111 *val = 4200000; 112 break; 113 case AXP22X_CHRG_CTRL1_TGT_4_22V: 114 *val = 4220000; 115 break; 116 case AXP22X_CHRG_CTRL1_TGT_4_24V: 117 *val = 4240000; 118 break; 119 default: 120 return -EINVAL; 121 } 122 123 return 0; 124 } 125 126 static void raw_to_constant_charge_current(struct axp20x_batt_ps *axp, int *val) 127 { 128 if (axp->axp_id == AXP209_ID) 129 *val = *val * 100000 + 300000; 130 else 131 *val = *val * 150000 + 300000; 132 } 133 134 static void constant_charge_current_to_raw(struct axp20x_batt_ps *axp, int *val) 135 { 136 if (axp->axp_id == AXP209_ID) 137 *val = (*val - 300000) / 100000; 138 else 139 *val = (*val - 300000) / 150000; 140 } 141 142 static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp, 143 int *val) 144 { 145 int ret; 146 147 ret = regmap_read(axp->regmap, AXP20X_CHRG_CTRL1, val); 148 if (ret) 149 return ret; 150 151 *val &= AXP20X_CHRG_CTRL1_TGT_CURR; 152 153 raw_to_constant_charge_current(axp, val); 154 155 return 0; 156 } 157 158 static int axp20x_battery_get_prop(struct power_supply *psy, 159 enum power_supply_property psp, 160 union power_supply_propval *val) 161 { 162 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); 163 struct iio_channel *chan; 164 int ret = 0, reg, val1; 165 166 switch (psp) { 167 case POWER_SUPPLY_PROP_PRESENT: 168 case POWER_SUPPLY_PROP_ONLINE: 169 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE, 170 ®); 171 if (ret) 172 return ret; 173 174 val->intval = !!(reg & AXP20X_PWR_OP_BATT_PRESENT); 175 break; 176 177 case POWER_SUPPLY_PROP_STATUS: 178 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS, 179 ®); 180 if (ret) 181 return ret; 182 183 if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) { 184 val->intval = POWER_SUPPLY_STATUS_CHARGING; 185 return 0; 186 } 187 188 ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i, 189 &val1); 190 if (ret) 191 return ret; 192 193 if (val1) { 194 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 195 return 0; 196 } 197 198 ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &val1); 199 if (ret) 200 return ret; 201 202 /* 203 * Fuel Gauge data takes 7 bits but the stored value seems to be 204 * directly the raw percentage without any scaling to 7 bits. 205 */ 206 if ((val1 & AXP209_FG_PERCENT) == 100) 207 val->intval = POWER_SUPPLY_STATUS_FULL; 208 else 209 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 210 break; 211 212 case POWER_SUPPLY_PROP_HEALTH: 213 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE, 214 &val1); 215 if (ret) 216 return ret; 217 218 if (val1 & AXP20X_PWR_OP_BATT_ACTIVATED) { 219 val->intval = POWER_SUPPLY_HEALTH_DEAD; 220 return 0; 221 } 222 223 val->intval = POWER_SUPPLY_HEALTH_GOOD; 224 break; 225 226 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 227 ret = axp20x_get_constant_charge_current(axp20x_batt, 228 &val->intval); 229 if (ret) 230 return ret; 231 break; 232 233 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 234 val->intval = axp20x_batt->max_ccc; 235 break; 236 237 case POWER_SUPPLY_PROP_CURRENT_NOW: 238 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS, 239 ®); 240 if (ret) 241 return ret; 242 243 if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) 244 chan = axp20x_batt->batt_chrg_i; 245 else 246 chan = axp20x_batt->batt_dischrg_i; 247 248 ret = iio_read_channel_processed(chan, &val->intval); 249 if (ret) 250 return ret; 251 252 /* IIO framework gives mA but Power Supply framework gives uA */ 253 val->intval *= 1000; 254 break; 255 256 case POWER_SUPPLY_PROP_CAPACITY: 257 /* When no battery is present, return capacity is 100% */ 258 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE, 259 ®); 260 if (ret) 261 return ret; 262 263 if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) { 264 val->intval = 100; 265 return 0; 266 } 267 268 ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, ®); 269 if (ret) 270 return ret; 271 272 if (axp20x_batt->axp_id == AXP221_ID && 273 !(reg & AXP22X_FG_VALID)) 274 return -EINVAL; 275 276 /* 277 * Fuel Gauge data takes 7 bits but the stored value seems to be 278 * directly the raw percentage without any scaling to 7 bits. 279 */ 280 val->intval = reg & AXP209_FG_PERCENT; 281 break; 282 283 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 284 if (axp20x_batt->axp_id == AXP209_ID) 285 return axp20x_battery_get_max_voltage(axp20x_batt, 286 &val->intval); 287 return axp22x_battery_get_max_voltage(axp20x_batt, 288 &val->intval); 289 290 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 291 ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, ®); 292 if (ret) 293 return ret; 294 295 val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK); 296 break; 297 298 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 299 ret = iio_read_channel_processed(axp20x_batt->batt_v, 300 &val->intval); 301 if (ret) 302 return ret; 303 304 /* IIO framework gives mV but Power Supply framework gives uV */ 305 val->intval *= 1000; 306 break; 307 308 default: 309 return -EINVAL; 310 } 311 312 return 0; 313 } 314 315 static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, 316 int val) 317 { 318 switch (val) { 319 case 4100000: 320 val = AXP20X_CHRG_CTRL1_TGT_4_1V; 321 break; 322 323 case 4150000: 324 if (axp20x_batt->axp_id == AXP221_ID) 325 return -EINVAL; 326 327 val = AXP20X_CHRG_CTRL1_TGT_4_15V; 328 break; 329 330 case 4200000: 331 val = AXP20X_CHRG_CTRL1_TGT_4_2V; 332 break; 333 334 default: 335 /* 336 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage 337 * can be set to 4.22V and 4.24V, but these voltages are too 338 * high for Lithium based batteries (AXP PMICs are supposed to 339 * be used with these kinds of battery). 340 */ 341 return -EINVAL; 342 } 343 344 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, 345 AXP20X_CHRG_CTRL1_TGT_VOLT, val); 346 } 347 348 static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, 349 int charge_current) 350 { 351 if (charge_current > axp_batt->max_ccc) 352 return -EINVAL; 353 354 constant_charge_current_to_raw(axp_batt, &charge_current); 355 356 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) 357 return -EINVAL; 358 359 return regmap_update_bits(axp_batt->regmap, AXP20X_CHRG_CTRL1, 360 AXP20X_CHRG_CTRL1_TGT_CURR, charge_current); 361 } 362 363 static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp, 364 int charge_current) 365 { 366 bool lower_max = false; 367 368 constant_charge_current_to_raw(axp, &charge_current); 369 370 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0) 371 return -EINVAL; 372 373 raw_to_constant_charge_current(axp, &charge_current); 374 375 if (charge_current > axp->max_ccc) 376 dev_warn(axp->dev, 377 "Setting max constant charge current higher than previously defined. Note that increasing the constant charge current may damage your battery.\n"); 378 else 379 lower_max = true; 380 381 axp->max_ccc = charge_current; 382 383 if (lower_max) { 384 int current_cc; 385 386 axp20x_get_constant_charge_current(axp, ¤t_cc); 387 if (current_cc > charge_current) 388 axp20x_set_constant_charge_current(axp, charge_current); 389 } 390 391 return 0; 392 } 393 static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt, 394 int min_voltage) 395 { 396 int val1 = (min_voltage - 2600000) / 100000; 397 398 if (val1 < 0 || val1 > AXP20X_V_OFF_MASK) 399 return -EINVAL; 400 401 return regmap_update_bits(axp_batt->regmap, AXP20X_V_OFF, 402 AXP20X_V_OFF_MASK, val1); 403 } 404 405 static int axp20x_battery_set_prop(struct power_supply *psy, 406 enum power_supply_property psp, 407 const union power_supply_propval *val) 408 { 409 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); 410 411 switch (psp) { 412 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 413 return axp20x_set_voltage_min_design(axp20x_batt, val->intval); 414 415 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 416 return axp20x_battery_set_max_voltage(axp20x_batt, val->intval); 417 418 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 419 return axp20x_set_constant_charge_current(axp20x_batt, 420 val->intval); 421 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 422 return axp20x_set_max_constant_charge_current(axp20x_batt, 423 val->intval); 424 425 default: 426 return -EINVAL; 427 } 428 } 429 430 static enum power_supply_property axp20x_battery_props[] = { 431 POWER_SUPPLY_PROP_PRESENT, 432 POWER_SUPPLY_PROP_ONLINE, 433 POWER_SUPPLY_PROP_STATUS, 434 POWER_SUPPLY_PROP_VOLTAGE_NOW, 435 POWER_SUPPLY_PROP_CURRENT_NOW, 436 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 437 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 438 POWER_SUPPLY_PROP_HEALTH, 439 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 440 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 441 POWER_SUPPLY_PROP_CAPACITY, 442 }; 443 444 static int axp20x_battery_prop_writeable(struct power_supply *psy, 445 enum power_supply_property psp) 446 { 447 return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN || 448 psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN || 449 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT || 450 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; 451 } 452 453 static const struct power_supply_desc axp20x_batt_ps_desc = { 454 .name = "axp20x-battery", 455 .type = POWER_SUPPLY_TYPE_BATTERY, 456 .properties = axp20x_battery_props, 457 .num_properties = ARRAY_SIZE(axp20x_battery_props), 458 .property_is_writeable = axp20x_battery_prop_writeable, 459 .get_property = axp20x_battery_get_prop, 460 .set_property = axp20x_battery_set_prop, 461 }; 462 463 static const struct of_device_id axp20x_battery_ps_id[] = { 464 { 465 .compatible = "x-powers,axp209-battery-power-supply", 466 .data = (void *)AXP209_ID, 467 }, { 468 .compatible = "x-powers,axp221-battery-power-supply", 469 .data = (void *)AXP221_ID, 470 }, { /* sentinel */ }, 471 }; 472 MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id); 473 474 static int axp20x_power_probe(struct platform_device *pdev) 475 { 476 struct axp20x_batt_ps *axp20x_batt; 477 struct power_supply_config psy_cfg = {}; 478 struct power_supply_battery_info info; 479 480 if (!of_device_is_available(pdev->dev.of_node)) 481 return -ENODEV; 482 483 axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt), 484 GFP_KERNEL); 485 if (!axp20x_batt) 486 return -ENOMEM; 487 488 axp20x_batt->dev = &pdev->dev; 489 490 axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v"); 491 if (IS_ERR(axp20x_batt->batt_v)) { 492 if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV) 493 return -EPROBE_DEFER; 494 return PTR_ERR(axp20x_batt->batt_v); 495 } 496 497 axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev, 498 "batt_chrg_i"); 499 if (IS_ERR(axp20x_batt->batt_chrg_i)) { 500 if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV) 501 return -EPROBE_DEFER; 502 return PTR_ERR(axp20x_batt->batt_chrg_i); 503 } 504 505 axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev, 506 "batt_dischrg_i"); 507 if (IS_ERR(axp20x_batt->batt_dischrg_i)) { 508 if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV) 509 return -EPROBE_DEFER; 510 return PTR_ERR(axp20x_batt->batt_dischrg_i); 511 } 512 513 axp20x_batt->regmap = dev_get_regmap(pdev->dev.parent, NULL); 514 platform_set_drvdata(pdev, axp20x_batt); 515 516 psy_cfg.drv_data = axp20x_batt; 517 psy_cfg.of_node = pdev->dev.of_node; 518 519 axp20x_batt->axp_id = (uintptr_t)of_device_get_match_data(&pdev->dev); 520 521 axp20x_batt->batt = devm_power_supply_register(&pdev->dev, 522 &axp20x_batt_ps_desc, 523 &psy_cfg); 524 if (IS_ERR(axp20x_batt->batt)) { 525 dev_err(&pdev->dev, "failed to register power supply: %ld\n", 526 PTR_ERR(axp20x_batt->batt)); 527 return PTR_ERR(axp20x_batt->batt); 528 } 529 530 if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) { 531 int vmin = info.voltage_min_design_uv; 532 int ccc = info.constant_charge_current_max_ua; 533 534 if (vmin > 0 && axp20x_set_voltage_min_design(axp20x_batt, 535 vmin)) 536 dev_err(&pdev->dev, 537 "couldn't set voltage_min_design\n"); 538 539 /* Set max to unverified value to be able to set CCC */ 540 axp20x_batt->max_ccc = ccc; 541 542 if (ccc <= 0 || axp20x_set_constant_charge_current(axp20x_batt, 543 ccc)) { 544 dev_err(&pdev->dev, 545 "couldn't set constant charge current from DT: fallback to minimum value\n"); 546 ccc = 300000; 547 axp20x_batt->max_ccc = ccc; 548 axp20x_set_constant_charge_current(axp20x_batt, ccc); 549 } 550 } 551 552 /* 553 * Update max CCC to a valid value if battery info is present or set it 554 * to current register value by default. 555 */ 556 axp20x_get_constant_charge_current(axp20x_batt, 557 &axp20x_batt->max_ccc); 558 559 return 0; 560 } 561 562 static struct platform_driver axp20x_batt_driver = { 563 .probe = axp20x_power_probe, 564 .driver = { 565 .name = "axp20x-battery-power-supply", 566 .of_match_table = axp20x_battery_ps_id, 567 }, 568 }; 569 570 module_platform_driver(axp20x_batt_driver); 571 572 MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs"); 573 MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>"); 574 MODULE_LICENSE("GPL"); 575