linux/drivers/power/supply/da9150-charger.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * DA9150 Charger Driver
   4 *
   5 * Copyright (c) 2014 Dialog Semiconductor
   6 *
   7 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/slab.h>
  12#include <linux/module.h>
  13#include <linux/platform_device.h>
  14#include <linux/of.h>
  15#include <linux/of_platform.h>
  16#include <linux/interrupt.h>
  17#include <linux/power_supply.h>
  18#include <linux/notifier.h>
  19#include <linux/usb/phy.h>
  20#include <linux/iio/consumer.h>
  21#include <linux/mfd/da9150/core.h>
  22#include <linux/mfd/da9150/registers.h>
  23
  24/* Private data */
  25struct da9150_charger {
  26        struct da9150 *da9150;
  27        struct device *dev;
  28
  29        struct power_supply *usb;
  30        struct power_supply *battery;
  31        struct power_supply *supply_online;
  32
  33        struct usb_phy *usb_phy;
  34        struct notifier_block otg_nb;
  35        struct work_struct otg_work;
  36        unsigned long usb_event;
  37
  38        struct iio_channel *ibus_chan;
  39        struct iio_channel *vbus_chan;
  40        struct iio_channel *tjunc_chan;
  41        struct iio_channel *vbat_chan;
  42};
  43
  44static inline int da9150_charger_supply_online(struct da9150_charger *charger,
  45                                               struct power_supply *psy,
  46                                               union power_supply_propval *val)
  47{
  48        val->intval = (psy == charger->supply_online) ? 1 : 0;
  49
  50        return 0;
  51}
  52
  53/* Charger Properties */
  54static int da9150_charger_vbus_voltage_now(struct da9150_charger *charger,
  55                                           union power_supply_propval *val)
  56{
  57        int v_val, ret;
  58
  59        /* Read processed value - mV units */
  60        ret = iio_read_channel_processed(charger->vbus_chan, &v_val);
  61        if (ret < 0)
  62                return ret;
  63
  64        /* Convert voltage to expected uV units */
  65        val->intval = v_val * 1000;
  66
  67        return 0;
  68}
  69
  70static int da9150_charger_ibus_current_avg(struct da9150_charger *charger,
  71                                           union power_supply_propval *val)
  72{
  73        int i_val, ret;
  74
  75        /* Read processed value - mA units */
  76        ret = iio_read_channel_processed(charger->ibus_chan, &i_val);
  77        if (ret < 0)
  78                return ret;
  79
  80        /* Convert current to expected uA units */
  81        val->intval = i_val * 1000;
  82
  83        return 0;
  84}
  85
  86static int da9150_charger_tjunc_temp(struct da9150_charger *charger,
  87                                     union power_supply_propval *val)
  88{
  89        int t_val, ret;
  90
  91        /* Read processed value - 0.001 degrees C units */
  92        ret = iio_read_channel_processed(charger->tjunc_chan, &t_val);
  93        if (ret < 0)
  94                return ret;
  95
  96        /* Convert temp to expect 0.1 degrees C units */
  97        val->intval = t_val / 100;
  98
  99        return 0;
 100}
 101
 102static enum power_supply_property da9150_charger_props[] = {
 103        POWER_SUPPLY_PROP_ONLINE,
 104        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 105        POWER_SUPPLY_PROP_CURRENT_AVG,
 106        POWER_SUPPLY_PROP_TEMP,
 107};
 108
 109static int da9150_charger_get_prop(struct power_supply *psy,
 110                                   enum power_supply_property psp,
 111                                   union power_supply_propval *val)
 112{
 113        struct da9150_charger *charger = dev_get_drvdata(psy->dev.parent);
 114        int ret;
 115
 116        switch (psp) {
 117        case POWER_SUPPLY_PROP_ONLINE:
 118                ret = da9150_charger_supply_online(charger, psy, val);
 119                break;
 120        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 121                ret = da9150_charger_vbus_voltage_now(charger, val);
 122                break;
 123        case POWER_SUPPLY_PROP_CURRENT_AVG:
 124                ret = da9150_charger_ibus_current_avg(charger, val);
 125                break;
 126        case POWER_SUPPLY_PROP_TEMP:
 127                ret = da9150_charger_tjunc_temp(charger, val);
 128                break;
 129        default:
 130                ret = -EINVAL;
 131                break;
 132        }
 133
 134        return ret;
 135}
 136
 137/* Battery Properties */
 138static int da9150_charger_battery_status(struct da9150_charger *charger,
 139                                         union power_supply_propval *val)
 140{
 141        u8 reg;
 142
 143        /* Check to see if battery is discharging */
 144        reg = da9150_reg_read(charger->da9150, DA9150_STATUS_H);
 145
 146        if (((reg & DA9150_VBUS_STAT_MASK) == DA9150_VBUS_STAT_OFF) ||
 147            ((reg & DA9150_VBUS_STAT_MASK) == DA9150_VBUS_STAT_WAIT)) {
 148                val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 149
 150                return 0;
 151        }
 152
 153        reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J);
 154
 155        /* Now check for other states */
 156        switch (reg & DA9150_CHG_STAT_MASK) {
 157        case DA9150_CHG_STAT_ACT:
 158        case DA9150_CHG_STAT_PRE:
 159        case DA9150_CHG_STAT_CC:
 160        case DA9150_CHG_STAT_CV:
 161                val->intval = POWER_SUPPLY_STATUS_CHARGING;
 162                break;
 163        case DA9150_CHG_STAT_OFF:
 164        case DA9150_CHG_STAT_SUSP:
 165        case DA9150_CHG_STAT_TEMP:
 166        case DA9150_CHG_STAT_TIME:
 167        case DA9150_CHG_STAT_BAT:
 168                val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
 169                break;
 170        case DA9150_CHG_STAT_FULL:
 171                val->intval = POWER_SUPPLY_STATUS_FULL;
 172                break;
 173        default:
 174                val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
 175                break;
 176        }
 177
 178        return 0;
 179}
 180
 181static int da9150_charger_battery_health(struct da9150_charger *charger,
 182                                         union power_supply_propval *val)
 183{
 184        u8 reg;
 185
 186        reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J);
 187
 188        /* Check if temperature limit reached */
 189        switch (reg & DA9150_CHG_TEMP_MASK) {
 190        case DA9150_CHG_TEMP_UNDER:
 191                val->intval = POWER_SUPPLY_HEALTH_COLD;
 192                return 0;
 193        case DA9150_CHG_TEMP_OVER:
 194                val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
 195                return 0;
 196        default:
 197                break;
 198        }
 199
 200        /* Check for other health states */
 201        switch (reg & DA9150_CHG_STAT_MASK) {
 202        case DA9150_CHG_STAT_ACT:
 203        case DA9150_CHG_STAT_PRE:
 204                val->intval = POWER_SUPPLY_HEALTH_DEAD;
 205                break;
 206        case DA9150_CHG_STAT_TIME:
 207                val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
 208                break;
 209        default:
 210                val->intval = POWER_SUPPLY_HEALTH_GOOD;
 211                break;
 212        }
 213
 214        return 0;
 215}
 216
 217static int da9150_charger_battery_present(struct da9150_charger *charger,
 218                                          union power_supply_propval *val)
 219{
 220        u8 reg;
 221
 222        /* Check if battery present or removed */
 223        reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J);
 224        if ((reg & DA9150_CHG_STAT_MASK) == DA9150_CHG_STAT_BAT)
 225                val->intval = 0;
 226        else
 227                val->intval = 1;
 228
 229        return 0;
 230}
 231
 232static int da9150_charger_battery_charge_type(struct da9150_charger *charger,
 233                                              union power_supply_propval *val)
 234{
 235        u8 reg;
 236
 237        reg = da9150_reg_read(charger->da9150, DA9150_STATUS_J);
 238
 239        switch (reg & DA9150_CHG_STAT_MASK) {
 240        case DA9150_CHG_STAT_CC:
 241                val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
 242                break;
 243        case DA9150_CHG_STAT_ACT:
 244        case DA9150_CHG_STAT_PRE:
 245        case DA9150_CHG_STAT_CV:
 246                val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
 247                break;
 248        default:
 249                val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
 250                break;
 251        }
 252
 253        return 0;
 254}
 255
 256static int da9150_charger_battery_voltage_min(struct da9150_charger *charger,
 257                                              union power_supply_propval *val)
 258{
 259        u8 reg;
 260
 261        reg = da9150_reg_read(charger->da9150, DA9150_PPR_CHGCTRL_C);
 262
 263        /* Value starts at 2500 mV, 50 mV increments, presented in uV */
 264        val->intval = ((reg & DA9150_CHG_VFAULT_MASK) * 50000) + 2500000;
 265
 266        return 0;
 267}
 268
 269static int da9150_charger_battery_voltage_now(struct da9150_charger *charger,
 270                                              union power_supply_propval *val)
 271{
 272        int v_val, ret;
 273
 274        /* Read processed value - mV units */
 275        ret = iio_read_channel_processed(charger->vbat_chan, &v_val);
 276        if (ret < 0)
 277                return ret;
 278
 279        val->intval = v_val * 1000;
 280
 281        return 0;
 282}
 283
 284static int da9150_charger_battery_current_max(struct da9150_charger *charger,
 285                                              union power_supply_propval *val)
 286{
 287        int reg;
 288
 289        reg = da9150_reg_read(charger->da9150, DA9150_PPR_CHGCTRL_D);
 290
 291        /* 25mA increments */
 292        val->intval = reg * 25000;
 293
 294        return 0;
 295}
 296
 297static int da9150_charger_battery_voltage_max(struct da9150_charger *charger,
 298                                              union power_supply_propval *val)
 299{
 300        u8 reg;
 301
 302        reg = da9150_reg_read(charger->da9150, DA9150_PPR_CHGCTRL_B);
 303
 304        /* Value starts at 3650 mV, 25 mV increments, presented in uV */
 305        val->intval = ((reg & DA9150_CHG_VBAT_MASK) * 25000) + 3650000;
 306        return 0;
 307}
 308
 309static enum power_supply_property da9150_charger_bat_props[] = {
 310        POWER_SUPPLY_PROP_STATUS,
 311        POWER_SUPPLY_PROP_ONLINE,
 312        POWER_SUPPLY_PROP_HEALTH,
 313        POWER_SUPPLY_PROP_PRESENT,
 314        POWER_SUPPLY_PROP_CHARGE_TYPE,
 315        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 316        POWER_SUPPLY_PROP_VOLTAGE_NOW,
 317        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
 318        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
 319};
 320
 321static int da9150_charger_battery_get_prop(struct power_supply *psy,
 322                                           enum power_supply_property psp,
 323                                           union power_supply_propval *val)
 324{
 325        struct da9150_charger *charger = dev_get_drvdata(psy->dev.parent);
 326        int ret;
 327
 328        switch (psp) {
 329        case POWER_SUPPLY_PROP_STATUS:
 330                ret = da9150_charger_battery_status(charger, val);
 331                break;
 332        case POWER_SUPPLY_PROP_ONLINE:
 333                ret = da9150_charger_supply_online(charger, psy, val);
 334                break;
 335        case POWER_SUPPLY_PROP_HEALTH:
 336                ret = da9150_charger_battery_health(charger, val);
 337                break;
 338        case POWER_SUPPLY_PROP_PRESENT:
 339                ret = da9150_charger_battery_present(charger, val);
 340                break;
 341        case POWER_SUPPLY_PROP_CHARGE_TYPE:
 342                ret = da9150_charger_battery_charge_type(charger, val);
 343                break;
 344        case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
 345                ret = da9150_charger_battery_voltage_min(charger, val);
 346                break;
 347        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 348                ret = da9150_charger_battery_voltage_now(charger, val);
 349                break;
 350        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
 351                ret = da9150_charger_battery_current_max(charger, val);
 352                break;
 353        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
 354                ret = da9150_charger_battery_voltage_max(charger, val);
 355                break;
 356        default:
 357                ret = -EINVAL;
 358                break;
 359        }
 360
 361        return ret;
 362}
 363
 364static irqreturn_t da9150_charger_chg_irq(int irq, void *data)
 365{
 366        struct da9150_charger *charger = data;
 367
 368        power_supply_changed(charger->battery);
 369
 370        return IRQ_HANDLED;
 371}
 372
 373static irqreturn_t da9150_charger_tjunc_irq(int irq, void *data)
 374{
 375        struct da9150_charger *charger = data;
 376
 377        /* Nothing we can really do except report this. */
 378        dev_crit(charger->dev, "TJunc over temperature!!!\n");
 379        power_supply_changed(charger->usb);
 380
 381        return IRQ_HANDLED;
 382}
 383
 384static irqreturn_t da9150_charger_vfault_irq(int irq, void *data)
 385{
 386        struct da9150_charger *charger = data;
 387
 388        /* Nothing we can really do except report this. */
 389        dev_crit(charger->dev, "VSYS under voltage!!!\n");
 390        power_supply_changed(charger->usb);
 391        power_supply_changed(charger->battery);
 392
 393        return IRQ_HANDLED;
 394}
 395
 396static irqreturn_t da9150_charger_vbus_irq(int irq, void *data)
 397{
 398        struct da9150_charger *charger = data;
 399        u8 reg;
 400
 401        reg = da9150_reg_read(charger->da9150, DA9150_STATUS_H);
 402
 403        /* Charger plugged in or battery only */
 404        switch (reg & DA9150_VBUS_STAT_MASK) {
 405        case DA9150_VBUS_STAT_OFF:
 406        case DA9150_VBUS_STAT_WAIT:
 407                charger->supply_online = charger->battery;
 408                break;
 409        case DA9150_VBUS_STAT_CHG:
 410                charger->supply_online = charger->usb;
 411                break;
 412        default:
 413                dev_warn(charger->dev, "Unknown VBUS state - reg = 0x%x\n",
 414                         reg);
 415                charger->supply_online = NULL;
 416                break;
 417        }
 418
 419        power_supply_changed(charger->usb);
 420        power_supply_changed(charger->battery);
 421
 422        return IRQ_HANDLED;
 423}
 424
 425static void da9150_charger_otg_work(struct work_struct *data)
 426{
 427        struct da9150_charger *charger =
 428                container_of(data, struct da9150_charger, otg_work);
 429
 430        switch (charger->usb_event) {
 431        case USB_EVENT_ID:
 432                /* Enable OTG Boost */
 433                da9150_set_bits(charger->da9150, DA9150_PPR_BKCTRL_A,
 434                                DA9150_VBUS_MODE_MASK, DA9150_VBUS_MODE_OTG);
 435                break;
 436        case USB_EVENT_NONE:
 437                /* Revert to charge mode */
 438                power_supply_changed(charger->usb);
 439                power_supply_changed(charger->battery);
 440                da9150_set_bits(charger->da9150, DA9150_PPR_BKCTRL_A,
 441                                DA9150_VBUS_MODE_MASK, DA9150_VBUS_MODE_CHG);
 442                break;
 443        }
 444}
 445
 446static int da9150_charger_otg_ncb(struct notifier_block *nb, unsigned long val,
 447                                  void *priv)
 448{
 449        struct da9150_charger *charger =
 450                container_of(nb, struct da9150_charger, otg_nb);
 451
 452        dev_dbg(charger->dev, "DA9150 OTG notify %lu\n", val);
 453
 454        charger->usb_event = val;
 455        schedule_work(&charger->otg_work);
 456
 457        return NOTIFY_OK;
 458}
 459
 460static int da9150_charger_register_irq(struct platform_device *pdev,
 461                                       irq_handler_t handler,
 462                                       const char *irq_name)
 463{
 464        struct device *dev = &pdev->dev;
 465        struct da9150_charger *charger = platform_get_drvdata(pdev);
 466        int irq, ret;
 467
 468        irq = platform_get_irq_byname(pdev, irq_name);
 469        if (irq < 0) {
 470                dev_err(dev, "Failed to get IRQ CHG_STATUS: %d\n", irq);
 471                return irq;
 472        }
 473
 474        ret = request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, irq_name,
 475                                   charger);
 476        if (ret)
 477                dev_err(dev, "Failed to request IRQ %d: %d\n", irq, ret);
 478
 479        return ret;
 480}
 481
 482static void da9150_charger_unregister_irq(struct platform_device *pdev,
 483                                          const char *irq_name)
 484{
 485        struct device *dev = &pdev->dev;
 486        struct da9150_charger *charger = platform_get_drvdata(pdev);
 487        int irq;
 488
 489        irq = platform_get_irq_byname(pdev, irq_name);
 490        if (irq < 0) {
 491                dev_err(dev, "Failed to get IRQ CHG_STATUS: %d\n", irq);
 492                return;
 493        }
 494
 495        free_irq(irq, charger);
 496}
 497
 498static const struct power_supply_desc usb_desc = {
 499        .name           = "da9150-usb",
 500        .type           = POWER_SUPPLY_TYPE_USB,
 501        .properties     = da9150_charger_props,
 502        .num_properties = ARRAY_SIZE(da9150_charger_props),
 503        .get_property   = da9150_charger_get_prop,
 504};
 505
 506static const struct power_supply_desc battery_desc = {
 507        .name           = "da9150-battery",
 508        .type           = POWER_SUPPLY_TYPE_BATTERY,
 509        .properties     = da9150_charger_bat_props,
 510        .num_properties = ARRAY_SIZE(da9150_charger_bat_props),
 511        .get_property   = da9150_charger_battery_get_prop,
 512};
 513
 514static int da9150_charger_probe(struct platform_device *pdev)
 515{
 516        struct device *dev = &pdev->dev;
 517        struct da9150 *da9150 = dev_get_drvdata(dev->parent);
 518        struct da9150_charger *charger;
 519        u8 reg;
 520        int ret;
 521
 522        charger = devm_kzalloc(dev, sizeof(struct da9150_charger), GFP_KERNEL);
 523        if (!charger)
 524                return -ENOMEM;
 525
 526        platform_set_drvdata(pdev, charger);
 527        charger->da9150 = da9150;
 528        charger->dev = dev;
 529
 530        /* Acquire ADC channels */
 531        charger->ibus_chan = iio_channel_get(dev, "CHAN_IBUS");
 532        if (IS_ERR(charger->ibus_chan)) {
 533                ret = PTR_ERR(charger->ibus_chan);
 534                goto ibus_chan_fail;
 535        }
 536
 537        charger->vbus_chan = iio_channel_get(dev, "CHAN_VBUS");
 538        if (IS_ERR(charger->vbus_chan)) {
 539                ret = PTR_ERR(charger->vbus_chan);
 540                goto vbus_chan_fail;
 541        }
 542
 543        charger->tjunc_chan = iio_channel_get(dev, "CHAN_TJUNC");
 544        if (IS_ERR(charger->tjunc_chan)) {
 545                ret = PTR_ERR(charger->tjunc_chan);
 546                goto tjunc_chan_fail;
 547        }
 548
 549        charger->vbat_chan = iio_channel_get(dev, "CHAN_VBAT");
 550        if (IS_ERR(charger->vbat_chan)) {
 551                ret = PTR_ERR(charger->vbat_chan);
 552                goto vbat_chan_fail;
 553        }
 554
 555        /* Register power supplies */
 556        charger->usb = power_supply_register(dev, &usb_desc, NULL);
 557        if (IS_ERR(charger->usb)) {
 558                ret = PTR_ERR(charger->usb);
 559                goto usb_fail;
 560        }
 561
 562        charger->battery = power_supply_register(dev, &battery_desc, NULL);
 563        if (IS_ERR(charger->battery)) {
 564                ret = PTR_ERR(charger->battery);
 565                goto battery_fail;
 566        }
 567
 568        /* Get initial online supply */
 569        reg = da9150_reg_read(da9150, DA9150_STATUS_H);
 570
 571        switch (reg & DA9150_VBUS_STAT_MASK) {
 572        case DA9150_VBUS_STAT_OFF:
 573        case DA9150_VBUS_STAT_WAIT:
 574                charger->supply_online = charger->battery;
 575                break;
 576        case DA9150_VBUS_STAT_CHG:
 577                charger->supply_online = charger->usb;
 578                break;
 579        default:
 580                dev_warn(dev, "Unknown VBUS state - reg = 0x%x\n", reg);
 581                charger->supply_online = NULL;
 582                break;
 583        }
 584
 585        /* Setup OTG reporting & configuration */
 586        charger->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
 587        if (!IS_ERR_OR_NULL(charger->usb_phy)) {
 588                INIT_WORK(&charger->otg_work, da9150_charger_otg_work);
 589                charger->otg_nb.notifier_call = da9150_charger_otg_ncb;
 590                usb_register_notifier(charger->usb_phy, &charger->otg_nb);
 591        }
 592
 593        /* Register IRQs */
 594        ret = da9150_charger_register_irq(pdev, da9150_charger_chg_irq,
 595                                          "CHG_STATUS");
 596        if (ret < 0)
 597                goto chg_irq_fail;
 598
 599        ret = da9150_charger_register_irq(pdev, da9150_charger_tjunc_irq,
 600                                          "CHG_TJUNC");
 601        if (ret < 0)
 602                goto tjunc_irq_fail;
 603
 604        ret = da9150_charger_register_irq(pdev, da9150_charger_vfault_irq,
 605                                          "CHG_VFAULT");
 606        if (ret < 0)
 607                goto vfault_irq_fail;
 608
 609        ret = da9150_charger_register_irq(pdev, da9150_charger_vbus_irq,
 610                                          "CHG_VBUS");
 611        if (ret < 0)
 612                goto vbus_irq_fail;
 613
 614        return 0;
 615
 616
 617vbus_irq_fail:
 618        da9150_charger_unregister_irq(pdev, "CHG_VFAULT");
 619vfault_irq_fail:
 620        da9150_charger_unregister_irq(pdev, "CHG_TJUNC");
 621tjunc_irq_fail:
 622        da9150_charger_unregister_irq(pdev, "CHG_STATUS");
 623chg_irq_fail:
 624        if (!IS_ERR_OR_NULL(charger->usb_phy))
 625                usb_unregister_notifier(charger->usb_phy, &charger->otg_nb);
 626battery_fail:
 627        power_supply_unregister(charger->usb);
 628
 629usb_fail:
 630        iio_channel_release(charger->vbat_chan);
 631
 632vbat_chan_fail:
 633        iio_channel_release(charger->tjunc_chan);
 634
 635tjunc_chan_fail:
 636        iio_channel_release(charger->vbus_chan);
 637
 638vbus_chan_fail:
 639        iio_channel_release(charger->ibus_chan);
 640
 641ibus_chan_fail:
 642        return ret;
 643}
 644
 645static int da9150_charger_remove(struct platform_device *pdev)
 646{
 647        struct da9150_charger *charger = platform_get_drvdata(pdev);
 648        int irq;
 649
 650        /* Make sure IRQs are released before unregistering power supplies */
 651        irq = platform_get_irq_byname(pdev, "CHG_VBUS");
 652        free_irq(irq, charger);
 653
 654        irq = platform_get_irq_byname(pdev, "CHG_VFAULT");
 655        free_irq(irq, charger);
 656
 657        irq = platform_get_irq_byname(pdev, "CHG_TJUNC");
 658        free_irq(irq, charger);
 659
 660        irq = platform_get_irq_byname(pdev, "CHG_STATUS");
 661        free_irq(irq, charger);
 662
 663        if (!IS_ERR_OR_NULL(charger->usb_phy))
 664                usb_unregister_notifier(charger->usb_phy, &charger->otg_nb);
 665
 666        power_supply_unregister(charger->battery);
 667        power_supply_unregister(charger->usb);
 668
 669        /* Release ADC channels */
 670        iio_channel_release(charger->ibus_chan);
 671        iio_channel_release(charger->vbus_chan);
 672        iio_channel_release(charger->tjunc_chan);
 673        iio_channel_release(charger->vbat_chan);
 674
 675        return 0;
 676}
 677
 678static struct platform_driver da9150_charger_driver = {
 679        .driver = {
 680                .name = "da9150-charger",
 681        },
 682        .probe = da9150_charger_probe,
 683        .remove = da9150_charger_remove,
 684};
 685
 686module_platform_driver(da9150_charger_driver);
 687
 688MODULE_DESCRIPTION("Charger Driver for DA9150");
 689MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
 690MODULE_LICENSE("GPL");
 691