1 /* 2 * TI LP8788 MFD - battery charger driver 3 * 4 * Copyright 2012 Texas Instruments 5 * 6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 */ 13 14 #include <linux/err.h> 15 #include <linux/iio/consumer.h> 16 #include <linux/interrupt.h> 17 #include <linux/irqdomain.h> 18 #include <linux/mfd/lp8788.h> 19 #include <linux/module.h> 20 #include <linux/platform_device.h> 21 #include <linux/power_supply.h> 22 #include <linux/slab.h> 23 #include <linux/workqueue.h> 24 25 /* register address */ 26 #define LP8788_CHG_STATUS 0x07 27 #define LP8788_CHG_IDCIN 0x13 28 #define LP8788_CHG_IBATT 0x14 29 #define LP8788_CHG_VTERM 0x15 30 #define LP8788_CHG_EOC 0x16 31 32 /* mask/shift bits */ 33 #define LP8788_CHG_INPUT_STATE_M 0x03 /* Addr 07h */ 34 #define LP8788_CHG_STATE_M 0x3C 35 #define LP8788_CHG_STATE_S 2 36 #define LP8788_NO_BATT_M BIT(6) 37 #define LP8788_BAD_BATT_M BIT(7) 38 #define LP8788_CHG_IBATT_M 0x1F /* Addr 14h */ 39 #define LP8788_CHG_VTERM_M 0x0F /* Addr 15h */ 40 #define LP8788_CHG_EOC_LEVEL_M 0x30 /* Addr 16h */ 41 #define LP8788_CHG_EOC_LEVEL_S 4 42 #define LP8788_CHG_EOC_TIME_M 0x0E 43 #define LP8788_CHG_EOC_TIME_S 1 44 #define LP8788_CHG_EOC_MODE_M BIT(0) 45 46 #define LP8788_CHARGER_NAME "charger" 47 #define LP8788_BATTERY_NAME "main_batt" 48 49 #define LP8788_CHG_START 0x11 50 #define LP8788_CHG_END 0x1C 51 52 #define LP8788_ISEL_MAX 23 53 #define LP8788_ISEL_STEP 50 54 #define LP8788_VTERM_MIN 4100 55 #define LP8788_VTERM_STEP 25 56 #define LP8788_MAX_BATT_CAPACITY 100 57 #define LP8788_MAX_CHG_IRQS 11 58 59 enum lp8788_charging_state { 60 LP8788_OFF, 61 LP8788_WARM_UP, 62 LP8788_LOW_INPUT = 0x3, 63 LP8788_PRECHARGE, 64 LP8788_CC, 65 LP8788_CV, 66 LP8788_MAINTENANCE, 67 LP8788_BATTERY_FAULT, 68 LP8788_SYSTEM_SUPPORT = 0xC, 69 LP8788_HIGH_CURRENT = 0xF, 70 LP8788_MAX_CHG_STATE, 71 }; 72 73 enum lp8788_charger_adc_sel { 74 LP8788_VBATT, 75 LP8788_BATT_TEMP, 76 LP8788_NUM_CHG_ADC, 77 }; 78 79 enum lp8788_charger_input_state { 80 LP8788_SYSTEM_SUPPLY = 1, 81 LP8788_FULL_FUNCTION, 82 }; 83 84 /* 85 * struct lp8788_chg_irq 86 * @which : lp8788 interrupt id 87 * @virq : Linux IRQ number from irq_domain 88 */ 89 struct lp8788_chg_irq { 90 enum lp8788_int_id which; 91 int virq; 92 }; 93 94 /* 95 * struct lp8788_charger 96 * @lp : used for accessing the registers of mfd lp8788 device 97 * @charger : power supply driver for the battery charger 98 * @battery : power supply driver for the battery 99 * @charger_work : work queue for charger input interrupts 100 * @chan : iio channels for getting adc values 101 * eg) battery voltage, capacity and temperature 102 * @irqs : charger dedicated interrupts 103 * @num_irqs : total numbers of charger interrupts 104 * @pdata : charger platform specific data 105 */ 106 struct lp8788_charger { 107 struct lp8788 *lp; 108 struct power_supply *charger; 109 struct power_supply *battery; 110 struct work_struct charger_work; 111 struct iio_channel *chan[LP8788_NUM_CHG_ADC]; 112 struct lp8788_chg_irq irqs[LP8788_MAX_CHG_IRQS]; 113 int num_irqs; 114 struct lp8788_charger_platform_data *pdata; 115 }; 116 117 static char *battery_supplied_to[] = { 118 LP8788_BATTERY_NAME, 119 }; 120 121 static enum power_supply_property lp8788_charger_prop[] = { 122 POWER_SUPPLY_PROP_ONLINE, 123 POWER_SUPPLY_PROP_CURRENT_MAX, 124 }; 125 126 static enum power_supply_property lp8788_battery_prop[] = { 127 POWER_SUPPLY_PROP_STATUS, 128 POWER_SUPPLY_PROP_HEALTH, 129 POWER_SUPPLY_PROP_PRESENT, 130 POWER_SUPPLY_PROP_VOLTAGE_NOW, 131 POWER_SUPPLY_PROP_CAPACITY, 132 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 133 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 134 POWER_SUPPLY_PROP_TEMP, 135 }; 136 137 static bool lp8788_is_charger_detected(struct lp8788_charger *pchg) 138 { 139 u8 data; 140 141 lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 142 data &= LP8788_CHG_INPUT_STATE_M; 143 144 return data == LP8788_SYSTEM_SUPPLY || data == LP8788_FULL_FUNCTION; 145 } 146 147 static int lp8788_charger_get_property(struct power_supply *psy, 148 enum power_supply_property psp, 149 union power_supply_propval *val) 150 { 151 struct lp8788_charger *pchg = dev_get_drvdata(psy->dev.parent); 152 u8 read; 153 154 switch (psp) { 155 case POWER_SUPPLY_PROP_ONLINE: 156 val->intval = lp8788_is_charger_detected(pchg); 157 break; 158 case POWER_SUPPLY_PROP_CURRENT_MAX: 159 lp8788_read_byte(pchg->lp, LP8788_CHG_IDCIN, &read); 160 val->intval = LP8788_ISEL_STEP * 161 (min_t(int, read, LP8788_ISEL_MAX) + 1); 162 break; 163 default: 164 return -EINVAL; 165 } 166 167 return 0; 168 } 169 170 static int lp8788_get_battery_status(struct lp8788_charger *pchg, 171 union power_supply_propval *val) 172 { 173 enum lp8788_charging_state state; 174 u8 data; 175 int ret; 176 177 ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 178 if (ret) 179 return ret; 180 181 state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S; 182 switch (state) { 183 case LP8788_OFF: 184 val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 185 break; 186 case LP8788_PRECHARGE: 187 case LP8788_CC: 188 case LP8788_CV: 189 case LP8788_HIGH_CURRENT: 190 val->intval = POWER_SUPPLY_STATUS_CHARGING; 191 break; 192 case LP8788_MAINTENANCE: 193 val->intval = POWER_SUPPLY_STATUS_FULL; 194 break; 195 default: 196 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 197 break; 198 } 199 200 return 0; 201 } 202 203 static int lp8788_get_battery_health(struct lp8788_charger *pchg, 204 union power_supply_propval *val) 205 { 206 u8 data; 207 int ret; 208 209 ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 210 if (ret) 211 return ret; 212 213 if (data & LP8788_NO_BATT_M) 214 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 215 else if (data & LP8788_BAD_BATT_M) 216 val->intval = POWER_SUPPLY_HEALTH_DEAD; 217 else 218 val->intval = POWER_SUPPLY_HEALTH_GOOD; 219 220 return 0; 221 } 222 223 static int lp8788_get_battery_present(struct lp8788_charger *pchg, 224 union power_supply_propval *val) 225 { 226 u8 data; 227 int ret; 228 229 ret = lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 230 if (ret) 231 return ret; 232 233 val->intval = !(data & LP8788_NO_BATT_M); 234 return 0; 235 } 236 237 static int lp8788_get_vbatt_adc(struct lp8788_charger *pchg, int *result) 238 { 239 struct iio_channel *channel = pchg->chan[LP8788_VBATT]; 240 241 if (!channel) 242 return -EINVAL; 243 244 return iio_read_channel_processed(channel, result); 245 } 246 247 static int lp8788_get_battery_voltage(struct lp8788_charger *pchg, 248 union power_supply_propval *val) 249 { 250 return lp8788_get_vbatt_adc(pchg, &val->intval); 251 } 252 253 static int lp8788_get_battery_capacity(struct lp8788_charger *pchg, 254 union power_supply_propval *val) 255 { 256 struct lp8788 *lp = pchg->lp; 257 struct lp8788_charger_platform_data *pdata = pchg->pdata; 258 unsigned int max_vbatt; 259 int vbatt; 260 enum lp8788_charging_state state; 261 u8 data; 262 int ret; 263 264 if (!pdata) 265 return -EINVAL; 266 267 max_vbatt = pdata->max_vbatt_mv; 268 if (max_vbatt == 0) 269 return -EINVAL; 270 271 ret = lp8788_read_byte(lp, LP8788_CHG_STATUS, &data); 272 if (ret) 273 return ret; 274 275 state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S; 276 277 if (state == LP8788_MAINTENANCE) { 278 val->intval = LP8788_MAX_BATT_CAPACITY; 279 } else { 280 ret = lp8788_get_vbatt_adc(pchg, &vbatt); 281 if (ret) 282 return ret; 283 284 val->intval = (vbatt * LP8788_MAX_BATT_CAPACITY) / max_vbatt; 285 val->intval = min(val->intval, LP8788_MAX_BATT_CAPACITY); 286 } 287 288 return 0; 289 } 290 291 static int lp8788_get_battery_temperature(struct lp8788_charger *pchg, 292 union power_supply_propval *val) 293 { 294 struct iio_channel *channel = pchg->chan[LP8788_BATT_TEMP]; 295 int result; 296 int ret; 297 298 if (!channel) 299 return -EINVAL; 300 301 ret = iio_read_channel_processed(channel, &result); 302 if (ret < 0) 303 return -EINVAL; 304 305 /* unit: 0.1 'C */ 306 val->intval = result * 10; 307 308 return 0; 309 } 310 311 static int lp8788_get_battery_charging_current(struct lp8788_charger *pchg, 312 union power_supply_propval *val) 313 { 314 u8 read; 315 316 lp8788_read_byte(pchg->lp, LP8788_CHG_IBATT, &read); 317 read &= LP8788_CHG_IBATT_M; 318 val->intval = LP8788_ISEL_STEP * 319 (min_t(int, read, LP8788_ISEL_MAX) + 1); 320 321 return 0; 322 } 323 324 static int lp8788_get_charging_termination_voltage(struct lp8788_charger *pchg, 325 union power_supply_propval *val) 326 { 327 u8 read; 328 329 lp8788_read_byte(pchg->lp, LP8788_CHG_VTERM, &read); 330 read &= LP8788_CHG_VTERM_M; 331 val->intval = LP8788_VTERM_MIN + LP8788_VTERM_STEP * read; 332 333 return 0; 334 } 335 336 static int lp8788_battery_get_property(struct power_supply *psy, 337 enum power_supply_property psp, 338 union power_supply_propval *val) 339 { 340 struct lp8788_charger *pchg = dev_get_drvdata(psy->dev.parent); 341 342 switch (psp) { 343 case POWER_SUPPLY_PROP_STATUS: 344 return lp8788_get_battery_status(pchg, val); 345 case POWER_SUPPLY_PROP_HEALTH: 346 return lp8788_get_battery_health(pchg, val); 347 case POWER_SUPPLY_PROP_PRESENT: 348 return lp8788_get_battery_present(pchg, val); 349 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 350 return lp8788_get_battery_voltage(pchg, val); 351 case POWER_SUPPLY_PROP_CAPACITY: 352 return lp8788_get_battery_capacity(pchg, val); 353 case POWER_SUPPLY_PROP_TEMP: 354 return lp8788_get_battery_temperature(pchg, val); 355 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 356 return lp8788_get_battery_charging_current(pchg, val); 357 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 358 return lp8788_get_charging_termination_voltage(pchg, val); 359 default: 360 return -EINVAL; 361 } 362 } 363 364 static inline bool lp8788_is_valid_charger_register(u8 addr) 365 { 366 return addr >= LP8788_CHG_START && addr <= LP8788_CHG_END; 367 } 368 369 static int lp8788_update_charger_params(struct platform_device *pdev, 370 struct lp8788_charger *pchg) 371 { 372 struct lp8788 *lp = pchg->lp; 373 struct lp8788_charger_platform_data *pdata = pchg->pdata; 374 struct lp8788_chg_param *param; 375 int i; 376 int ret; 377 378 if (!pdata || !pdata->chg_params) { 379 dev_info(&pdev->dev, "skip updating charger parameters\n"); 380 return 0; 381 } 382 383 /* settting charging parameters */ 384 for (i = 0; i < pdata->num_chg_params; i++) { 385 param = pdata->chg_params + i; 386 387 if (lp8788_is_valid_charger_register(param->addr)) { 388 ret = lp8788_write_byte(lp, param->addr, param->val); 389 if (ret) 390 return ret; 391 } 392 } 393 394 return 0; 395 } 396 397 static const struct power_supply_desc lp8788_psy_charger_desc = { 398 .name = LP8788_CHARGER_NAME, 399 .type = POWER_SUPPLY_TYPE_MAINS, 400 .properties = lp8788_charger_prop, 401 .num_properties = ARRAY_SIZE(lp8788_charger_prop), 402 .get_property = lp8788_charger_get_property, 403 }; 404 405 static const struct power_supply_desc lp8788_psy_battery_desc = { 406 .name = LP8788_BATTERY_NAME, 407 .type = POWER_SUPPLY_TYPE_BATTERY, 408 .properties = lp8788_battery_prop, 409 .num_properties = ARRAY_SIZE(lp8788_battery_prop), 410 .get_property = lp8788_battery_get_property, 411 }; 412 413 static void lp8788_psy_unregister(struct lp8788_charger *pchg) 414 { 415 power_supply_unregister(pchg->battery); 416 power_supply_unregister(pchg->charger); 417 } 418 419 static void lp8788_charger_event(struct work_struct *work) 420 { 421 struct lp8788_charger *pchg = 422 container_of(work, struct lp8788_charger, charger_work); 423 struct lp8788_charger_platform_data *pdata = pchg->pdata; 424 enum lp8788_charger_event event = lp8788_is_charger_detected(pchg); 425 426 pdata->charger_event(pchg->lp, event); 427 } 428 429 static bool lp8788_find_irq_id(struct lp8788_charger *pchg, int virq, int *id) 430 { 431 bool found = false; 432 int i; 433 434 for (i = 0; i < pchg->num_irqs; i++) { 435 if (pchg->irqs[i].virq == virq) { 436 *id = pchg->irqs[i].which; 437 found = true; 438 break; 439 } 440 } 441 442 return found; 443 } 444 445 static irqreturn_t lp8788_charger_irq_thread(int virq, void *ptr) 446 { 447 struct lp8788_charger *pchg = ptr; 448 struct lp8788_charger_platform_data *pdata = pchg->pdata; 449 int id = -1; 450 451 if (!lp8788_find_irq_id(pchg, virq, &id)) 452 return IRQ_NONE; 453 454 switch (id) { 455 case LP8788_INT_CHG_INPUT_STATE: 456 case LP8788_INT_CHG_STATE: 457 case LP8788_INT_EOC: 458 case LP8788_INT_BATT_LOW: 459 case LP8788_INT_NO_BATT: 460 power_supply_changed(pchg->charger); 461 power_supply_changed(pchg->battery); 462 break; 463 default: 464 break; 465 } 466 467 /* report charger dectection event if used */ 468 if (!pdata) 469 goto irq_handled; 470 471 if (pdata->charger_event && id == LP8788_INT_CHG_INPUT_STATE) 472 schedule_work(&pchg->charger_work); 473 474 irq_handled: 475 return IRQ_HANDLED; 476 } 477 478 static int lp8788_set_irqs(struct platform_device *pdev, 479 struct lp8788_charger *pchg, const char *name) 480 { 481 struct resource *r; 482 struct irq_domain *irqdm = pchg->lp->irqdm; 483 int irq_start; 484 int irq_end; 485 int virq; 486 int nr_irq; 487 int i; 488 int ret; 489 490 /* no error even if no irq resource */ 491 r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, name); 492 if (!r) 493 return 0; 494 495 irq_start = r->start; 496 irq_end = r->end; 497 498 for (i = irq_start; i <= irq_end; i++) { 499 nr_irq = pchg->num_irqs; 500 501 virq = irq_create_mapping(irqdm, i); 502 pchg->irqs[nr_irq].virq = virq; 503 pchg->irqs[nr_irq].which = i; 504 pchg->num_irqs++; 505 506 ret = request_threaded_irq(virq, NULL, 507 lp8788_charger_irq_thread, 508 0, name, pchg); 509 if (ret) 510 break; 511 } 512 513 if (i <= irq_end) 514 goto err_free_irq; 515 516 return 0; 517 518 err_free_irq: 519 for (i = 0; i < pchg->num_irqs; i++) 520 free_irq(pchg->irqs[i].virq, pchg); 521 return ret; 522 } 523 524 static int lp8788_irq_register(struct platform_device *pdev, 525 struct lp8788_charger *pchg) 526 { 527 const char *name[] = { 528 LP8788_CHG_IRQ, LP8788_PRSW_IRQ, LP8788_BATT_IRQ 529 }; 530 int i; 531 int ret; 532 533 INIT_WORK(&pchg->charger_work, lp8788_charger_event); 534 pchg->num_irqs = 0; 535 536 for (i = 0; i < ARRAY_SIZE(name); i++) { 537 ret = lp8788_set_irqs(pdev, pchg, name[i]); 538 if (ret) { 539 dev_warn(&pdev->dev, "irq setup failed: %s\n", name[i]); 540 return ret; 541 } 542 } 543 544 if (pchg->num_irqs > LP8788_MAX_CHG_IRQS) { 545 dev_err(&pdev->dev, "invalid total number of irqs: %d\n", 546 pchg->num_irqs); 547 return -EINVAL; 548 } 549 550 551 return 0; 552 } 553 554 static void lp8788_irq_unregister(struct platform_device *pdev, 555 struct lp8788_charger *pchg) 556 { 557 int i; 558 int irq; 559 560 for (i = 0; i < pchg->num_irqs; i++) { 561 irq = pchg->irqs[i].virq; 562 if (!irq) 563 continue; 564 565 free_irq(irq, pchg); 566 } 567 } 568 569 static void lp8788_setup_adc_channel(struct device *dev, 570 struct lp8788_charger *pchg) 571 { 572 struct lp8788_charger_platform_data *pdata = pchg->pdata; 573 struct iio_channel *chan; 574 575 if (!pdata) 576 return; 577 578 /* ADC channel for battery voltage */ 579 chan = iio_channel_get(dev, pdata->adc_vbatt); 580 pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan; 581 582 /* ADC channel for battery temperature */ 583 chan = iio_channel_get(dev, pdata->adc_batt_temp); 584 pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan; 585 } 586 587 static void lp8788_release_adc_channel(struct lp8788_charger *pchg) 588 { 589 int i; 590 591 for (i = 0; i < LP8788_NUM_CHG_ADC; i++) { 592 if (!pchg->chan[i]) 593 continue; 594 595 iio_channel_release(pchg->chan[i]); 596 pchg->chan[i] = NULL; 597 } 598 } 599 600 static ssize_t lp8788_show_charger_status(struct device *dev, 601 struct device_attribute *attr, char *buf) 602 { 603 struct lp8788_charger *pchg = dev_get_drvdata(dev); 604 enum lp8788_charging_state state; 605 static const char * const desc[LP8788_MAX_CHG_STATE] = { 606 [LP8788_OFF] = "CHARGER OFF", 607 [LP8788_WARM_UP] = "WARM UP", 608 [LP8788_LOW_INPUT] = "LOW INPUT STATE", 609 [LP8788_PRECHARGE] = "CHARGING - PRECHARGE", 610 [LP8788_CC] = "CHARGING - CC", 611 [LP8788_CV] = "CHARGING - CV", 612 [LP8788_MAINTENANCE] = "NO CHARGING - MAINTENANCE", 613 [LP8788_BATTERY_FAULT] = "BATTERY FAULT", 614 [LP8788_SYSTEM_SUPPORT] = "SYSTEM SUPPORT", 615 [LP8788_HIGH_CURRENT] = "HIGH CURRENT", 616 }; 617 u8 data; 618 619 lp8788_read_byte(pchg->lp, LP8788_CHG_STATUS, &data); 620 state = (data & LP8788_CHG_STATE_M) >> LP8788_CHG_STATE_S; 621 622 return scnprintf(buf, PAGE_SIZE, "%s\n", desc[state]); 623 } 624 625 static ssize_t lp8788_show_eoc_time(struct device *dev, 626 struct device_attribute *attr, char *buf) 627 { 628 struct lp8788_charger *pchg = dev_get_drvdata(dev); 629 static const char * const stime[] = { 630 "400ms", "5min", "10min", "15min", 631 "20min", "25min", "30min", "No timeout" 632 }; 633 u8 val; 634 635 lp8788_read_byte(pchg->lp, LP8788_CHG_EOC, &val); 636 val = (val & LP8788_CHG_EOC_TIME_M) >> LP8788_CHG_EOC_TIME_S; 637 638 return scnprintf(buf, PAGE_SIZE, "End Of Charge Time: %s\n", 639 stime[val]); 640 } 641 642 static ssize_t lp8788_show_eoc_level(struct device *dev, 643 struct device_attribute *attr, char *buf) 644 { 645 struct lp8788_charger *pchg = dev_get_drvdata(dev); 646 static const char * const abs_level[] = { 647 "25mA", "49mA", "75mA", "98mA" 648 }; 649 static const char * const relative_level[] = { 650 "5%", "10%", "15%", "20%" 651 }; 652 const char *level; 653 u8 val; 654 u8 mode; 655 656 lp8788_read_byte(pchg->lp, LP8788_CHG_EOC, &val); 657 658 mode = val & LP8788_CHG_EOC_MODE_M; 659 val = (val & LP8788_CHG_EOC_LEVEL_M) >> LP8788_CHG_EOC_LEVEL_S; 660 level = mode ? abs_level[val] : relative_level[val]; 661 662 return scnprintf(buf, PAGE_SIZE, "End Of Charge Level: %s\n", level); 663 } 664 665 static DEVICE_ATTR(charger_status, S_IRUSR, lp8788_show_charger_status, NULL); 666 static DEVICE_ATTR(eoc_time, S_IRUSR, lp8788_show_eoc_time, NULL); 667 static DEVICE_ATTR(eoc_level, S_IRUSR, lp8788_show_eoc_level, NULL); 668 669 static struct attribute *lp8788_charger_sysfs_attrs[] = { 670 &dev_attr_charger_status.attr, 671 &dev_attr_eoc_time.attr, 672 &dev_attr_eoc_level.attr, 673 NULL, 674 }; 675 676 ATTRIBUTE_GROUPS(lp8788_charger_sysfs); 677 678 static int lp8788_psy_register(struct platform_device *pdev, 679 struct lp8788_charger *pchg) 680 { 681 struct power_supply_config charger_cfg = {}; 682 683 charger_cfg.attr_grp = lp8788_charger_sysfs_groups; 684 charger_cfg.supplied_to = battery_supplied_to; 685 charger_cfg.num_supplicants = ARRAY_SIZE(battery_supplied_to); 686 687 pchg->charger = power_supply_register(&pdev->dev, 688 &lp8788_psy_charger_desc, 689 &charger_cfg); 690 if (IS_ERR(pchg->charger)) 691 return -EPERM; 692 693 pchg->battery = power_supply_register(&pdev->dev, 694 &lp8788_psy_battery_desc, NULL); 695 if (IS_ERR(pchg->battery)) { 696 power_supply_unregister(pchg->charger); 697 return -EPERM; 698 } 699 700 return 0; 701 } 702 703 static int lp8788_charger_probe(struct platform_device *pdev) 704 { 705 struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent); 706 struct lp8788_charger *pchg; 707 struct device *dev = &pdev->dev; 708 int ret; 709 710 pchg = devm_kzalloc(dev, sizeof(struct lp8788_charger), GFP_KERNEL); 711 if (!pchg) 712 return -ENOMEM; 713 714 pchg->lp = lp; 715 pchg->pdata = lp->pdata ? lp->pdata->chg_pdata : NULL; 716 platform_set_drvdata(pdev, pchg); 717 718 ret = lp8788_update_charger_params(pdev, pchg); 719 if (ret) 720 return ret; 721 722 lp8788_setup_adc_channel(&pdev->dev, pchg); 723 724 ret = lp8788_psy_register(pdev, pchg); 725 if (ret) 726 return ret; 727 728 ret = lp8788_irq_register(pdev, pchg); 729 if (ret) 730 dev_warn(dev, "failed to register charger irq: %d\n", ret); 731 732 return 0; 733 } 734 735 static int lp8788_charger_remove(struct platform_device *pdev) 736 { 737 struct lp8788_charger *pchg = platform_get_drvdata(pdev); 738 739 flush_work(&pchg->charger_work); 740 lp8788_irq_unregister(pdev, pchg); 741 lp8788_psy_unregister(pchg); 742 lp8788_release_adc_channel(pchg); 743 744 return 0; 745 } 746 747 static struct platform_driver lp8788_charger_driver = { 748 .probe = lp8788_charger_probe, 749 .remove = lp8788_charger_remove, 750 .driver = { 751 .name = LP8788_DEV_CHARGER, 752 }, 753 }; 754 module_platform_driver(lp8788_charger_driver); 755 756 MODULE_DESCRIPTION("TI LP8788 Charger Driver"); 757 MODULE_AUTHOR("Milo Kim"); 758 MODULE_LICENSE("GPL"); 759 MODULE_ALIAS("platform:lp8788-charger"); 760