1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * AXP20x PMIC USB power supply status driver 4 * 5 * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com> 6 * Copyright (C) 2014 Bruno Prémont <bonbons@linux-vserver.org> 7 */ 8 9 #include <linux/bitops.h> 10 #include <linux/device.h> 11 #include <linux/init.h> 12 #include <linux/interrupt.h> 13 #include <linux/kernel.h> 14 #include <linux/mfd/axp20x.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/of_device.h> 18 #include <linux/platform_device.h> 19 #include <linux/power_supply.h> 20 #include <linux/regmap.h> 21 #include <linux/slab.h> 22 #include <linux/iio/consumer.h> 23 #include <linux/workqueue.h> 24 25 #define DRVNAME "axp20x-usb-power-supply" 26 27 #define AXP20X_PWR_STATUS_VBUS_PRESENT BIT(5) 28 #define AXP20X_PWR_STATUS_VBUS_USED BIT(4) 29 30 #define AXP20X_USB_STATUS_VBUS_VALID BIT(2) 31 32 #define AXP20X_VBUS_VHOLD_uV(b) (4000000 + (((b) >> 3) & 7) * 100000) 33 #define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3) 34 #define AXP20X_VBUS_VHOLD_OFFSET 3 35 #define AXP20X_VBUS_CLIMIT_MASK 3 36 #define AXP20X_VBUS_CLIMIT_900mA 0 37 #define AXP20X_VBUS_CLIMIT_500mA 1 38 #define AXP20X_VBUS_CLIMIT_100mA 2 39 #define AXP20X_VBUS_CLIMIT_NONE 3 40 41 #define AXP813_VBUS_CLIMIT_900mA 0 42 #define AXP813_VBUS_CLIMIT_1500mA 1 43 #define AXP813_VBUS_CLIMIT_2000mA 2 44 #define AXP813_VBUS_CLIMIT_2500mA 3 45 46 #define AXP20X_ADC_EN1_VBUS_CURR BIT(2) 47 #define AXP20X_ADC_EN1_VBUS_VOLT BIT(3) 48 49 #define AXP20X_VBUS_MON_VBUS_VALID BIT(3) 50 51 /* 52 * Note do not raise the debounce time, we must report Vusb high within 53 * 100ms otherwise we get Vbus errors in musb. 54 */ 55 #define DEBOUNCE_TIME msecs_to_jiffies(50) 56 57 struct axp20x_usb_power { 58 struct device_node *np; 59 struct regmap *regmap; 60 struct power_supply *supply; 61 enum axp20x_variants axp20x_id; 62 struct iio_channel *vbus_v; 63 struct iio_channel *vbus_i; 64 struct delayed_work vbus_detect; 65 unsigned int old_status; 66 }; 67 68 static irqreturn_t axp20x_usb_power_irq(int irq, void *devid) 69 { 70 struct axp20x_usb_power *power = devid; 71 72 power_supply_changed(power->supply); 73 74 return IRQ_HANDLED; 75 } 76 77 static void axp20x_usb_power_poll_vbus(struct work_struct *work) 78 { 79 struct axp20x_usb_power *power = 80 container_of(work, struct axp20x_usb_power, vbus_detect.work); 81 unsigned int val; 82 int ret; 83 84 ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &val); 85 if (ret) 86 goto out; 87 88 val &= (AXP20X_PWR_STATUS_VBUS_PRESENT | AXP20X_PWR_STATUS_VBUS_USED); 89 if (val != power->old_status) 90 power_supply_changed(power->supply); 91 92 power->old_status = val; 93 94 out: 95 mod_delayed_work(system_wq, &power->vbus_detect, DEBOUNCE_TIME); 96 } 97 98 static bool axp20x_usb_vbus_needs_polling(struct axp20x_usb_power *power) 99 { 100 if (power->axp20x_id >= AXP221_ID) 101 return true; 102 103 return false; 104 } 105 106 static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val) 107 { 108 unsigned int v; 109 int ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v); 110 111 if (ret) 112 return ret; 113 114 switch (v & AXP20X_VBUS_CLIMIT_MASK) { 115 case AXP20X_VBUS_CLIMIT_100mA: 116 if (power->axp20x_id == AXP221_ID) 117 *val = -1; /* No 100mA limit */ 118 else 119 *val = 100000; 120 break; 121 case AXP20X_VBUS_CLIMIT_500mA: 122 *val = 500000; 123 break; 124 case AXP20X_VBUS_CLIMIT_900mA: 125 *val = 900000; 126 break; 127 case AXP20X_VBUS_CLIMIT_NONE: 128 *val = -1; 129 break; 130 } 131 132 return 0; 133 } 134 135 static int axp813_get_current_max(struct axp20x_usb_power *power, int *val) 136 { 137 unsigned int v; 138 int ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v); 139 140 if (ret) 141 return ret; 142 143 switch (v & AXP20X_VBUS_CLIMIT_MASK) { 144 case AXP813_VBUS_CLIMIT_900mA: 145 *val = 900000; 146 break; 147 case AXP813_VBUS_CLIMIT_1500mA: 148 *val = 1500000; 149 break; 150 case AXP813_VBUS_CLIMIT_2000mA: 151 *val = 2000000; 152 break; 153 case AXP813_VBUS_CLIMIT_2500mA: 154 *val = 2500000; 155 break; 156 } 157 return 0; 158 } 159 160 static int axp20x_usb_power_get_property(struct power_supply *psy, 161 enum power_supply_property psp, union power_supply_propval *val) 162 { 163 struct axp20x_usb_power *power = power_supply_get_drvdata(psy); 164 unsigned int input, v; 165 int ret; 166 167 switch (psp) { 168 case POWER_SUPPLY_PROP_VOLTAGE_MIN: 169 ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v); 170 if (ret) 171 return ret; 172 173 val->intval = AXP20X_VBUS_VHOLD_uV(v); 174 return 0; 175 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 176 if (IS_ENABLED(CONFIG_AXP20X_ADC)) { 177 ret = iio_read_channel_processed(power->vbus_v, 178 &val->intval); 179 if (ret) 180 return ret; 181 182 /* 183 * IIO framework gives mV but Power Supply framework 184 * gives uV. 185 */ 186 val->intval *= 1000; 187 return 0; 188 } 189 190 ret = axp20x_read_variable_width(power->regmap, 191 AXP20X_VBUS_V_ADC_H, 12); 192 if (ret < 0) 193 return ret; 194 195 val->intval = ret * 1700; /* 1 step = 1.7 mV */ 196 return 0; 197 case POWER_SUPPLY_PROP_CURRENT_MAX: 198 if (power->axp20x_id == AXP813_ID) 199 return axp813_get_current_max(power, &val->intval); 200 return axp20x_get_current_max(power, &val->intval); 201 case POWER_SUPPLY_PROP_CURRENT_NOW: 202 if (IS_ENABLED(CONFIG_AXP20X_ADC)) { 203 ret = iio_read_channel_processed(power->vbus_i, 204 &val->intval); 205 if (ret) 206 return ret; 207 208 /* 209 * IIO framework gives mA but Power Supply framework 210 * gives uA. 211 */ 212 val->intval *= 1000; 213 return 0; 214 } 215 216 ret = axp20x_read_variable_width(power->regmap, 217 AXP20X_VBUS_I_ADC_H, 12); 218 if (ret < 0) 219 return ret; 220 221 val->intval = ret * 375; /* 1 step = 0.375 mA */ 222 return 0; 223 default: 224 break; 225 } 226 227 /* All the properties below need the input-status reg value */ 228 ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &input); 229 if (ret) 230 return ret; 231 232 switch (psp) { 233 case POWER_SUPPLY_PROP_HEALTH: 234 if (!(input & AXP20X_PWR_STATUS_VBUS_PRESENT)) { 235 val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; 236 break; 237 } 238 239 val->intval = POWER_SUPPLY_HEALTH_GOOD; 240 241 if (power->axp20x_id == AXP202_ID) { 242 ret = regmap_read(power->regmap, 243 AXP20X_USB_OTG_STATUS, &v); 244 if (ret) 245 return ret; 246 247 if (!(v & AXP20X_USB_STATUS_VBUS_VALID)) 248 val->intval = 249 POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 250 } 251 break; 252 case POWER_SUPPLY_PROP_PRESENT: 253 val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_PRESENT); 254 break; 255 case POWER_SUPPLY_PROP_ONLINE: 256 val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_USED); 257 break; 258 default: 259 return -EINVAL; 260 } 261 262 return 0; 263 } 264 265 static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power, 266 int intval) 267 { 268 int val; 269 270 switch (intval) { 271 case 4000000: 272 case 4100000: 273 case 4200000: 274 case 4300000: 275 case 4400000: 276 case 4500000: 277 case 4600000: 278 case 4700000: 279 val = (intval - 4000000) / 100000; 280 return regmap_update_bits(power->regmap, 281 AXP20X_VBUS_IPSOUT_MGMT, 282 AXP20X_VBUS_VHOLD_MASK, 283 val << AXP20X_VBUS_VHOLD_OFFSET); 284 default: 285 return -EINVAL; 286 } 287 288 return -EINVAL; 289 } 290 291 static int axp813_usb_power_set_current_max(struct axp20x_usb_power *power, 292 int intval) 293 { 294 int val; 295 296 switch (intval) { 297 case 900000: 298 return regmap_update_bits(power->regmap, 299 AXP20X_VBUS_IPSOUT_MGMT, 300 AXP20X_VBUS_CLIMIT_MASK, 301 AXP813_VBUS_CLIMIT_900mA); 302 case 1500000: 303 case 2000000: 304 case 2500000: 305 val = (intval - 1000000) / 500000; 306 return regmap_update_bits(power->regmap, 307 AXP20X_VBUS_IPSOUT_MGMT, 308 AXP20X_VBUS_CLIMIT_MASK, val); 309 default: 310 return -EINVAL; 311 } 312 313 return -EINVAL; 314 } 315 316 static int axp20x_usb_power_set_current_max(struct axp20x_usb_power *power, 317 int intval) 318 { 319 int val; 320 321 switch (intval) { 322 case 100000: 323 if (power->axp20x_id == AXP221_ID) 324 return -EINVAL; 325 /* fall through */ 326 case 500000: 327 case 900000: 328 val = (900000 - intval) / 400000; 329 return regmap_update_bits(power->regmap, 330 AXP20X_VBUS_IPSOUT_MGMT, 331 AXP20X_VBUS_CLIMIT_MASK, val); 332 default: 333 return -EINVAL; 334 } 335 336 return -EINVAL; 337 } 338 339 static int axp20x_usb_power_set_property(struct power_supply *psy, 340 enum power_supply_property psp, 341 const union power_supply_propval *val) 342 { 343 struct axp20x_usb_power *power = power_supply_get_drvdata(psy); 344 345 switch (psp) { 346 case POWER_SUPPLY_PROP_VOLTAGE_MIN: 347 return axp20x_usb_power_set_voltage_min(power, val->intval); 348 349 case POWER_SUPPLY_PROP_CURRENT_MAX: 350 if (power->axp20x_id == AXP813_ID) 351 return axp813_usb_power_set_current_max(power, 352 val->intval); 353 return axp20x_usb_power_set_current_max(power, val->intval); 354 355 default: 356 return -EINVAL; 357 } 358 359 return -EINVAL; 360 } 361 362 static int axp20x_usb_power_prop_writeable(struct power_supply *psy, 363 enum power_supply_property psp) 364 { 365 return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN || 366 psp == POWER_SUPPLY_PROP_CURRENT_MAX; 367 } 368 369 static enum power_supply_property axp20x_usb_power_properties[] = { 370 POWER_SUPPLY_PROP_HEALTH, 371 POWER_SUPPLY_PROP_PRESENT, 372 POWER_SUPPLY_PROP_ONLINE, 373 POWER_SUPPLY_PROP_VOLTAGE_MIN, 374 POWER_SUPPLY_PROP_VOLTAGE_NOW, 375 POWER_SUPPLY_PROP_CURRENT_MAX, 376 POWER_SUPPLY_PROP_CURRENT_NOW, 377 }; 378 379 static enum power_supply_property axp22x_usb_power_properties[] = { 380 POWER_SUPPLY_PROP_HEALTH, 381 POWER_SUPPLY_PROP_PRESENT, 382 POWER_SUPPLY_PROP_ONLINE, 383 POWER_SUPPLY_PROP_VOLTAGE_MIN, 384 POWER_SUPPLY_PROP_CURRENT_MAX, 385 }; 386 387 static const struct power_supply_desc axp20x_usb_power_desc = { 388 .name = "axp20x-usb", 389 .type = POWER_SUPPLY_TYPE_USB, 390 .properties = axp20x_usb_power_properties, 391 .num_properties = ARRAY_SIZE(axp20x_usb_power_properties), 392 .property_is_writeable = axp20x_usb_power_prop_writeable, 393 .get_property = axp20x_usb_power_get_property, 394 .set_property = axp20x_usb_power_set_property, 395 }; 396 397 static const struct power_supply_desc axp22x_usb_power_desc = { 398 .name = "axp20x-usb", 399 .type = POWER_SUPPLY_TYPE_USB, 400 .properties = axp22x_usb_power_properties, 401 .num_properties = ARRAY_SIZE(axp22x_usb_power_properties), 402 .property_is_writeable = axp20x_usb_power_prop_writeable, 403 .get_property = axp20x_usb_power_get_property, 404 .set_property = axp20x_usb_power_set_property, 405 }; 406 407 static int configure_iio_channels(struct platform_device *pdev, 408 struct axp20x_usb_power *power) 409 { 410 power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v"); 411 if (IS_ERR(power->vbus_v)) { 412 if (PTR_ERR(power->vbus_v) == -ENODEV) 413 return -EPROBE_DEFER; 414 return PTR_ERR(power->vbus_v); 415 } 416 417 power->vbus_i = devm_iio_channel_get(&pdev->dev, "vbus_i"); 418 if (IS_ERR(power->vbus_i)) { 419 if (PTR_ERR(power->vbus_i) == -ENODEV) 420 return -EPROBE_DEFER; 421 return PTR_ERR(power->vbus_i); 422 } 423 424 return 0; 425 } 426 427 static int configure_adc_registers(struct axp20x_usb_power *power) 428 { 429 /* Enable vbus voltage and current measurement */ 430 return regmap_update_bits(power->regmap, AXP20X_ADC_EN1, 431 AXP20X_ADC_EN1_VBUS_CURR | 432 AXP20X_ADC_EN1_VBUS_VOLT, 433 AXP20X_ADC_EN1_VBUS_CURR | 434 AXP20X_ADC_EN1_VBUS_VOLT); 435 } 436 437 static int axp20x_usb_power_probe(struct platform_device *pdev) 438 { 439 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); 440 struct power_supply_config psy_cfg = {}; 441 struct axp20x_usb_power *power; 442 static const char * const axp20x_irq_names[] = { "VBUS_PLUGIN", 443 "VBUS_REMOVAL", "VBUS_VALID", "VBUS_NOT_VALID", NULL }; 444 static const char * const axp22x_irq_names[] = { 445 "VBUS_PLUGIN", "VBUS_REMOVAL", NULL }; 446 const char * const *irq_names; 447 const struct power_supply_desc *usb_power_desc; 448 int i, irq, ret; 449 450 if (!of_device_is_available(pdev->dev.of_node)) 451 return -ENODEV; 452 453 if (!axp20x) { 454 dev_err(&pdev->dev, "Parent drvdata not set\n"); 455 return -EINVAL; 456 } 457 458 power = devm_kzalloc(&pdev->dev, sizeof(*power), GFP_KERNEL); 459 if (!power) 460 return -ENOMEM; 461 462 platform_set_drvdata(pdev, power); 463 power->axp20x_id = (enum axp20x_variants)of_device_get_match_data( 464 &pdev->dev); 465 466 power->np = pdev->dev.of_node; 467 power->regmap = axp20x->regmap; 468 469 if (power->axp20x_id == AXP202_ID) { 470 /* Enable vbus valid checking */ 471 ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON, 472 AXP20X_VBUS_MON_VBUS_VALID, 473 AXP20X_VBUS_MON_VBUS_VALID); 474 if (ret) 475 return ret; 476 477 if (IS_ENABLED(CONFIG_AXP20X_ADC)) 478 ret = configure_iio_channels(pdev, power); 479 else 480 ret = configure_adc_registers(power); 481 482 if (ret) 483 return ret; 484 485 usb_power_desc = &axp20x_usb_power_desc; 486 irq_names = axp20x_irq_names; 487 } else if (power->axp20x_id == AXP221_ID || 488 power->axp20x_id == AXP223_ID || 489 power->axp20x_id == AXP813_ID) { 490 usb_power_desc = &axp22x_usb_power_desc; 491 irq_names = axp22x_irq_names; 492 } else { 493 dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n", 494 axp20x->variant); 495 return -EINVAL; 496 } 497 498 psy_cfg.of_node = pdev->dev.of_node; 499 psy_cfg.drv_data = power; 500 501 power->supply = devm_power_supply_register(&pdev->dev, usb_power_desc, 502 &psy_cfg); 503 if (IS_ERR(power->supply)) 504 return PTR_ERR(power->supply); 505 506 /* Request irqs after registering, as irqs may trigger immediately */ 507 for (i = 0; irq_names[i]; i++) { 508 irq = platform_get_irq_byname(pdev, irq_names[i]); 509 if (irq < 0) { 510 dev_warn(&pdev->dev, "No IRQ for %s: %d\n", 511 irq_names[i], irq); 512 continue; 513 } 514 irq = regmap_irq_get_virq(axp20x->regmap_irqc, irq); 515 ret = devm_request_any_context_irq(&pdev->dev, irq, 516 axp20x_usb_power_irq, 0, DRVNAME, power); 517 if (ret < 0) 518 dev_warn(&pdev->dev, "Error requesting %s IRQ: %d\n", 519 irq_names[i], ret); 520 } 521 522 INIT_DELAYED_WORK(&power->vbus_detect, axp20x_usb_power_poll_vbus); 523 if (axp20x_usb_vbus_needs_polling(power)) 524 queue_delayed_work(system_wq, &power->vbus_detect, 0); 525 526 return 0; 527 } 528 529 static int axp20x_usb_power_remove(struct platform_device *pdev) 530 { 531 struct axp20x_usb_power *power = platform_get_drvdata(pdev); 532 533 cancel_delayed_work_sync(&power->vbus_detect); 534 535 return 0; 536 } 537 538 static const struct of_device_id axp20x_usb_power_match[] = { 539 { 540 .compatible = "x-powers,axp202-usb-power-supply", 541 .data = (void *)AXP202_ID, 542 }, { 543 .compatible = "x-powers,axp221-usb-power-supply", 544 .data = (void *)AXP221_ID, 545 }, { 546 .compatible = "x-powers,axp223-usb-power-supply", 547 .data = (void *)AXP223_ID, 548 }, { 549 .compatible = "x-powers,axp813-usb-power-supply", 550 .data = (void *)AXP813_ID, 551 }, { /* sentinel */ } 552 }; 553 MODULE_DEVICE_TABLE(of, axp20x_usb_power_match); 554 555 static struct platform_driver axp20x_usb_power_driver = { 556 .probe = axp20x_usb_power_probe, 557 .remove = axp20x_usb_power_remove, 558 .driver = { 559 .name = DRVNAME, 560 .of_match_table = axp20x_usb_power_match, 561 }, 562 }; 563 564 module_platform_driver(axp20x_usb_power_driver); 565 566 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 567 MODULE_DESCRIPTION("AXP20x PMIC USB power supply status driver"); 568 MODULE_LICENSE("GPL"); 569