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