root/drivers/power/supply/wm831x_power.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wm831x_power_check_online
  2. wm831x_power_read_voltage
  3. wm831x_wall_get_prop
  4. wm831x_usb_get_prop
  5. wm831x_usb_limit_change
  6. wm831x_battey_apply_config
  7. wm831x_config_battery
  8. wm831x_bat_check_status
  9. wm831x_bat_check_type
  10. wm831x_bat_check_health
  11. wm831x_bat_get_prop
  12. wm831x_bat_irq
  13. wm831x_syslo_irq
  14. wm831x_pwr_src_irq
  15. wm831x_power_probe
  16. wm831x_power_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * PMU driver for Wolfson Microelectronics wm831x PMICs
   4  *
   5  * Copyright 2009 Wolfson Microelectronics PLC.
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/err.h>
  10 #include <linux/platform_device.h>
  11 #include <linux/power_supply.h>
  12 #include <linux/slab.h>
  13 #include <linux/usb/phy.h>
  14 
  15 #include <linux/mfd/wm831x/core.h>
  16 #include <linux/mfd/wm831x/auxadc.h>
  17 #include <linux/mfd/wm831x/pmu.h>
  18 #include <linux/mfd/wm831x/pdata.h>
  19 
  20 struct wm831x_power {
  21         struct wm831x *wm831x;
  22         struct power_supply *wall;
  23         struct power_supply *usb;
  24         struct power_supply *battery;
  25         struct power_supply_desc wall_desc;
  26         struct power_supply_desc usb_desc;
  27         struct power_supply_desc battery_desc;
  28         char wall_name[20];
  29         char usb_name[20];
  30         char battery_name[20];
  31         bool have_battery;
  32         struct usb_phy *usb_phy;
  33         struct notifier_block usb_notify;
  34 };
  35 
  36 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
  37                                      union power_supply_propval *val)
  38 {
  39         int ret;
  40 
  41         ret = wm831x_reg_read(wm831x, WM831X_SYSTEM_STATUS);
  42         if (ret < 0)
  43                 return ret;
  44 
  45         if (ret & supply)
  46                 val->intval = 1;
  47         else
  48                 val->intval = 0;
  49 
  50         return 0;
  51 }
  52 
  53 static int wm831x_power_read_voltage(struct wm831x *wm831x,
  54                                      enum wm831x_auxadc src,
  55                                      union power_supply_propval *val)
  56 {
  57         int ret;
  58 
  59         ret = wm831x_auxadc_read_uv(wm831x, src);
  60         if (ret >= 0)
  61                 val->intval = ret;
  62 
  63         return ret;
  64 }
  65 
  66 /*********************************************************************
  67  *              WALL Power
  68  *********************************************************************/
  69 static int wm831x_wall_get_prop(struct power_supply *psy,
  70                                 enum power_supply_property psp,
  71                                 union power_supply_propval *val)
  72 {
  73         struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev.parent);
  74         struct wm831x *wm831x = wm831x_power->wm831x;
  75         int ret = 0;
  76 
  77         switch (psp) {
  78         case POWER_SUPPLY_PROP_ONLINE:
  79                 ret = wm831x_power_check_online(wm831x, WM831X_PWR_WALL, val);
  80                 break;
  81         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  82                 ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_WALL, val);
  83                 break;
  84         default:
  85                 ret = -EINVAL;
  86                 break;
  87         }
  88 
  89         return ret;
  90 }
  91 
  92 static enum power_supply_property wm831x_wall_props[] = {
  93         POWER_SUPPLY_PROP_ONLINE,
  94         POWER_SUPPLY_PROP_VOLTAGE_NOW,
  95 };
  96 
  97 /*********************************************************************
  98  *              USB Power
  99  *********************************************************************/
 100 static int wm831x_usb_get_prop(struct power_supply *psy,
 101                                enum power_supply_property psp,
 102                                union power_supply_propval *val)
 103 {
 104         struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev.parent);
 105         struct wm831x *wm831x = wm831x_power->wm831x;
 106         int ret = 0;
 107 
 108         switch (psp) {
 109         case POWER_SUPPLY_PROP_ONLINE:
 110                 ret = wm831x_power_check_online(wm831x, WM831X_PWR_USB, val);
 111                 break;
 112         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 113                 ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_USB, val);
 114                 break;
 115         default:
 116                 ret = -EINVAL;
 117                 break;
 118         }
 119 
 120         return ret;
 121 }
 122 
 123 static enum power_supply_property wm831x_usb_props[] = {
 124         POWER_SUPPLY_PROP_ONLINE,
 125         POWER_SUPPLY_PROP_VOLTAGE_NOW,
 126 };
 127 
 128 /* In milliamps */
 129 static const unsigned int wm831x_usb_limits[] = {
 130         0,
 131         2,
 132         100,
 133         500,
 134         900,
 135         1500,
 136         1800,
 137         550,
 138 };
 139 
 140 static int wm831x_usb_limit_change(struct notifier_block *nb,
 141                                    unsigned long limit, void *data)
 142 {
 143         struct wm831x_power *wm831x_power = container_of(nb,
 144                                                          struct wm831x_power,
 145                                                          usb_notify);
 146         unsigned int i, best;
 147 
 148         /* Find the highest supported limit */
 149         best = 0;
 150         for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
 151                 if (limit >= wm831x_usb_limits[i] &&
 152                     wm831x_usb_limits[best] < wm831x_usb_limits[i])
 153                         best = i;
 154         }
 155 
 156         dev_dbg(wm831x_power->wm831x->dev,
 157                 "Limiting USB current to %umA", wm831x_usb_limits[best]);
 158 
 159         wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
 160                         WM831X_USB_ILIM_MASK, best);
 161 
 162         return 0;
 163 }
 164 
 165 /*********************************************************************
 166  *              Battery properties
 167  *********************************************************************/
 168 
 169 struct chg_map {
 170         int val;
 171         int reg_val;
 172 };
 173 
 174 static struct chg_map trickle_ilims[] = {
 175         {  50, 0 << WM831X_CHG_TRKL_ILIM_SHIFT },
 176         { 100, 1 << WM831X_CHG_TRKL_ILIM_SHIFT },
 177         { 150, 2 << WM831X_CHG_TRKL_ILIM_SHIFT },
 178         { 200, 3 << WM831X_CHG_TRKL_ILIM_SHIFT },
 179 };
 180 
 181 static struct chg_map vsels[] = {
 182         { 4050, 0 << WM831X_CHG_VSEL_SHIFT },
 183         { 4100, 1 << WM831X_CHG_VSEL_SHIFT },
 184         { 4150, 2 << WM831X_CHG_VSEL_SHIFT },
 185         { 4200, 3 << WM831X_CHG_VSEL_SHIFT },
 186 };
 187 
 188 static struct chg_map fast_ilims[] = {
 189         {    0,  0 << WM831X_CHG_FAST_ILIM_SHIFT },
 190         {   50,  1 << WM831X_CHG_FAST_ILIM_SHIFT },
 191         {  100,  2 << WM831X_CHG_FAST_ILIM_SHIFT },
 192         {  150,  3 << WM831X_CHG_FAST_ILIM_SHIFT },
 193         {  200,  4 << WM831X_CHG_FAST_ILIM_SHIFT },
 194         {  250,  5 << WM831X_CHG_FAST_ILIM_SHIFT },
 195         {  300,  6 << WM831X_CHG_FAST_ILIM_SHIFT },
 196         {  350,  7 << WM831X_CHG_FAST_ILIM_SHIFT },
 197         {  400,  8 << WM831X_CHG_FAST_ILIM_SHIFT },
 198         {  450,  9 << WM831X_CHG_FAST_ILIM_SHIFT },
 199         {  500, 10 << WM831X_CHG_FAST_ILIM_SHIFT },
 200         {  600, 11 << WM831X_CHG_FAST_ILIM_SHIFT },
 201         {  700, 12 << WM831X_CHG_FAST_ILIM_SHIFT },
 202         {  800, 13 << WM831X_CHG_FAST_ILIM_SHIFT },
 203         {  900, 14 << WM831X_CHG_FAST_ILIM_SHIFT },
 204         { 1000, 15 << WM831X_CHG_FAST_ILIM_SHIFT },
 205 };
 206 
 207 static struct chg_map eoc_iterms[] = {
 208         { 20, 0 << WM831X_CHG_ITERM_SHIFT },
 209         { 30, 1 << WM831X_CHG_ITERM_SHIFT },
 210         { 40, 2 << WM831X_CHG_ITERM_SHIFT },
 211         { 50, 3 << WM831X_CHG_ITERM_SHIFT },
 212         { 60, 4 << WM831X_CHG_ITERM_SHIFT },
 213         { 70, 5 << WM831X_CHG_ITERM_SHIFT },
 214         { 80, 6 << WM831X_CHG_ITERM_SHIFT },
 215         { 90, 7 << WM831X_CHG_ITERM_SHIFT },
 216 };
 217 
 218 static struct chg_map chg_times[] = {
 219         {  60,  0 << WM831X_CHG_TIME_SHIFT },
 220         {  90,  1 << WM831X_CHG_TIME_SHIFT },
 221         { 120,  2 << WM831X_CHG_TIME_SHIFT },
 222         { 150,  3 << WM831X_CHG_TIME_SHIFT },
 223         { 180,  4 << WM831X_CHG_TIME_SHIFT },
 224         { 210,  5 << WM831X_CHG_TIME_SHIFT },
 225         { 240,  6 << WM831X_CHG_TIME_SHIFT },
 226         { 270,  7 << WM831X_CHG_TIME_SHIFT },
 227         { 300,  8 << WM831X_CHG_TIME_SHIFT },
 228         { 330,  9 << WM831X_CHG_TIME_SHIFT },
 229         { 360, 10 << WM831X_CHG_TIME_SHIFT },
 230         { 390, 11 << WM831X_CHG_TIME_SHIFT },
 231         { 420, 12 << WM831X_CHG_TIME_SHIFT },
 232         { 450, 13 << WM831X_CHG_TIME_SHIFT },
 233         { 480, 14 << WM831X_CHG_TIME_SHIFT },
 234         { 510, 15 << WM831X_CHG_TIME_SHIFT },
 235 };
 236 
 237 static void wm831x_battey_apply_config(struct wm831x *wm831x,
 238                                        struct chg_map *map, int count, int val,
 239                                        int *reg, const char *name,
 240                                        const char *units)
 241 {
 242         int i;
 243 
 244         for (i = 0; i < count; i++)
 245                 if (val == map[i].val)
 246                         break;
 247         if (i == count) {
 248                 dev_err(wm831x->dev, "Invalid %s %d%s\n",
 249                         name, val, units);
 250         } else {
 251                 *reg |= map[i].reg_val;
 252                 dev_dbg(wm831x->dev, "Set %s of %d%s\n", name, val, units);
 253         }
 254 }
 255 
 256 static void wm831x_config_battery(struct wm831x *wm831x)
 257 {
 258         struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
 259         struct wm831x_battery_pdata *pdata;
 260         int ret, reg1, reg2;
 261 
 262         if (!wm831x_pdata || !wm831x_pdata->battery) {
 263                 dev_warn(wm831x->dev,
 264                          "No battery charger configuration\n");
 265                 return;
 266         }
 267 
 268         pdata = wm831x_pdata->battery;
 269 
 270         reg1 = 0;
 271         reg2 = 0;
 272 
 273         if (!pdata->enable) {
 274                 dev_info(wm831x->dev, "Battery charger disabled\n");
 275                 return;
 276         }
 277 
 278         reg1 |= WM831X_CHG_ENA;
 279         if (pdata->off_mask)
 280                 reg2 |= WM831X_CHG_OFF_MSK;
 281         if (pdata->fast_enable)
 282                 reg1 |= WM831X_CHG_FAST;
 283 
 284         wm831x_battey_apply_config(wm831x, trickle_ilims,
 285                                    ARRAY_SIZE(trickle_ilims),
 286                                    pdata->trickle_ilim, &reg2,
 287                                    "trickle charge current limit", "mA");
 288 
 289         wm831x_battey_apply_config(wm831x, vsels, ARRAY_SIZE(vsels),
 290                                    pdata->vsel, &reg2,
 291                                    "target voltage", "mV");
 292 
 293         wm831x_battey_apply_config(wm831x, fast_ilims, ARRAY_SIZE(fast_ilims),
 294                                    pdata->fast_ilim, &reg2,
 295                                    "fast charge current limit", "mA");
 296 
 297         wm831x_battey_apply_config(wm831x, eoc_iterms, ARRAY_SIZE(eoc_iterms),
 298                                    pdata->eoc_iterm, &reg1,
 299                                    "end of charge current threshold", "mA");
 300 
 301         wm831x_battey_apply_config(wm831x, chg_times, ARRAY_SIZE(chg_times),
 302                                    pdata->timeout, &reg2,
 303                                    "charger timeout", "min");
 304 
 305         ret = wm831x_reg_unlock(wm831x);
 306         if (ret != 0) {
 307                 dev_err(wm831x->dev, "Failed to unlock registers: %d\n", ret);
 308                 return;
 309         }
 310 
 311         ret = wm831x_set_bits(wm831x, WM831X_CHARGER_CONTROL_1,
 312                               WM831X_CHG_ENA_MASK |
 313                               WM831X_CHG_FAST_MASK |
 314                               WM831X_CHG_ITERM_MASK,
 315                               reg1);
 316         if (ret != 0)
 317                 dev_err(wm831x->dev, "Failed to set charger control 1: %d\n",
 318                         ret);
 319 
 320         ret = wm831x_set_bits(wm831x, WM831X_CHARGER_CONTROL_2,
 321                               WM831X_CHG_OFF_MSK |
 322                               WM831X_CHG_TIME_MASK |
 323                               WM831X_CHG_FAST_ILIM_MASK |
 324                               WM831X_CHG_TRKL_ILIM_MASK |
 325                               WM831X_CHG_VSEL_MASK,
 326                               reg2);
 327         if (ret != 0)
 328                 dev_err(wm831x->dev, "Failed to set charger control 2: %d\n",
 329                         ret);
 330 
 331         wm831x_reg_lock(wm831x);
 332 }
 333 
 334 static int wm831x_bat_check_status(struct wm831x *wm831x, int *status)
 335 {
 336         int ret;
 337 
 338         ret = wm831x_reg_read(wm831x, WM831X_SYSTEM_STATUS);
 339         if (ret < 0)
 340                 return ret;
 341 
 342         if (ret & WM831X_PWR_SRC_BATT) {
 343                 *status = POWER_SUPPLY_STATUS_DISCHARGING;
 344                 return 0;
 345         }
 346 
 347         ret = wm831x_reg_read(wm831x, WM831X_CHARGER_STATUS);
 348         if (ret < 0)
 349                 return ret;
 350 
 351         switch (ret & WM831X_CHG_STATE_MASK) {
 352         case WM831X_CHG_STATE_OFF:
 353                 *status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 354                 break;
 355         case WM831X_CHG_STATE_TRICKLE:
 356         case WM831X_CHG_STATE_FAST:
 357                 *status = POWER_SUPPLY_STATUS_CHARGING;
 358                 break;
 359 
 360         default:
 361                 *status = POWER_SUPPLY_STATUS_UNKNOWN;
 362                 break;
 363         }
 364 
 365         return 0;
 366 }
 367 
 368 static int wm831x_bat_check_type(struct wm831x *wm831x, int *type)
 369 {
 370         int ret;
 371 
 372         ret = wm831x_reg_read(wm831x, WM831X_CHARGER_STATUS);
 373         if (ret < 0)
 374                 return ret;
 375 
 376         switch (ret & WM831X_CHG_STATE_MASK) {
 377         case WM831X_CHG_STATE_TRICKLE:
 378         case WM831X_CHG_STATE_TRICKLE_OT:
 379                 *type = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
 380                 break;
 381         case WM831X_CHG_STATE_FAST:
 382         case WM831X_CHG_STATE_FAST_OT:
 383                 *type = POWER_SUPPLY_CHARGE_TYPE_FAST;
 384                 break;
 385         default:
 386                 *type = POWER_SUPPLY_CHARGE_TYPE_NONE;
 387                 break;
 388         }
 389 
 390         return 0;
 391 }
 392 
 393 static int wm831x_bat_check_health(struct wm831x *wm831x, int *health)
 394 {
 395         int ret;
 396 
 397         ret = wm831x_reg_read(wm831x, WM831X_CHARGER_STATUS);
 398         if (ret < 0)
 399                 return ret;
 400 
 401         if (ret & WM831X_BATT_HOT_STS) {
 402                 *health = POWER_SUPPLY_HEALTH_OVERHEAT;
 403                 return 0;
 404         }
 405 
 406         if (ret & WM831X_BATT_COLD_STS) {
 407                 *health = POWER_SUPPLY_HEALTH_COLD;
 408                 return 0;
 409         }
 410 
 411         if (ret & WM831X_BATT_OV_STS) {
 412                 *health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
 413                 return 0;
 414         }
 415 
 416         switch (ret & WM831X_CHG_STATE_MASK) {
 417         case WM831X_CHG_STATE_TRICKLE_OT:
 418         case WM831X_CHG_STATE_FAST_OT:
 419                 *health = POWER_SUPPLY_HEALTH_OVERHEAT;
 420                 break;
 421         case WM831X_CHG_STATE_DEFECTIVE:
 422                 *health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
 423                 break;
 424         default:
 425                 *health = POWER_SUPPLY_HEALTH_GOOD;
 426                 break;
 427         }
 428 
 429         return 0;
 430 }
 431 
 432 static int wm831x_bat_get_prop(struct power_supply *psy,
 433                                enum power_supply_property psp,
 434                                union power_supply_propval *val)
 435 {
 436         struct wm831x_power *wm831x_power = dev_get_drvdata(psy->dev.parent);
 437         struct wm831x *wm831x = wm831x_power->wm831x;
 438         int ret = 0;
 439 
 440         switch (psp) {
 441         case POWER_SUPPLY_PROP_STATUS:
 442                 ret = wm831x_bat_check_status(wm831x, &val->intval);
 443                 break;
 444         case POWER_SUPPLY_PROP_ONLINE:
 445                 ret = wm831x_power_check_online(wm831x, WM831X_PWR_SRC_BATT,
 446                                                 val);
 447                 break;
 448         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 449                 ret = wm831x_power_read_voltage(wm831x, WM831X_AUX_BATT, val);
 450                 break;
 451         case POWER_SUPPLY_PROP_HEALTH:
 452                 ret = wm831x_bat_check_health(wm831x, &val->intval);
 453                 break;
 454         case POWER_SUPPLY_PROP_CHARGE_TYPE:
 455                 ret = wm831x_bat_check_type(wm831x, &val->intval);
 456                 break;
 457         default:
 458                 ret = -EINVAL;
 459                 break;
 460         }
 461 
 462         return ret;
 463 }
 464 
 465 static enum power_supply_property wm831x_bat_props[] = {
 466         POWER_SUPPLY_PROP_STATUS,
 467         POWER_SUPPLY_PROP_ONLINE,
 468         POWER_SUPPLY_PROP_VOLTAGE_NOW,
 469         POWER_SUPPLY_PROP_HEALTH,
 470         POWER_SUPPLY_PROP_CHARGE_TYPE,
 471 };
 472 
 473 static const char *wm831x_bat_irqs[] = {
 474         "BATT HOT",
 475         "BATT COLD",
 476         "BATT FAIL",
 477         "OV",
 478         "END",
 479         "TO",
 480         "MODE",
 481         "START",
 482 };
 483 
 484 static irqreturn_t wm831x_bat_irq(int irq, void *data)
 485 {
 486         struct wm831x_power *wm831x_power = data;
 487         struct wm831x *wm831x = wm831x_power->wm831x;
 488 
 489         dev_dbg(wm831x->dev, "Battery status changed: %d\n", irq);
 490 
 491         /* The battery charger is autonomous so we don't need to do
 492          * anything except kick user space */
 493         if (wm831x_power->have_battery)
 494                 power_supply_changed(wm831x_power->battery);
 495 
 496         return IRQ_HANDLED;
 497 }
 498 
 499 
 500 /*********************************************************************
 501  *              Initialisation
 502  *********************************************************************/
 503 
 504 static irqreturn_t wm831x_syslo_irq(int irq, void *data)
 505 {
 506         struct wm831x_power *wm831x_power = data;
 507         struct wm831x *wm831x = wm831x_power->wm831x;
 508 
 509         /* Not much we can actually *do* but tell people for
 510          * posterity, we're probably about to run out of power. */
 511         dev_crit(wm831x->dev, "SYSVDD under voltage\n");
 512 
 513         return IRQ_HANDLED;
 514 }
 515 
 516 static irqreturn_t wm831x_pwr_src_irq(int irq, void *data)
 517 {
 518         struct wm831x_power *wm831x_power = data;
 519         struct wm831x *wm831x = wm831x_power->wm831x;
 520 
 521         dev_dbg(wm831x->dev, "Power source changed\n");
 522 
 523         /* Just notify for everything - little harm in overnotifying. */
 524         if (wm831x_power->have_battery)
 525                 power_supply_changed(wm831x_power->battery);
 526         power_supply_changed(wm831x_power->usb);
 527         power_supply_changed(wm831x_power->wall);
 528 
 529         return IRQ_HANDLED;
 530 }
 531 
 532 static int wm831x_power_probe(struct platform_device *pdev)
 533 {
 534         struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 535         struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
 536         struct wm831x_power *power;
 537         int ret, irq, i;
 538 
 539         power = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_power),
 540                              GFP_KERNEL);
 541         if (power == NULL)
 542                 return -ENOMEM;
 543 
 544         power->wm831x = wm831x;
 545         platform_set_drvdata(pdev, power);
 546 
 547         if (wm831x_pdata && wm831x_pdata->wm831x_num) {
 548                 snprintf(power->wall_name, sizeof(power->wall_name),
 549                          "wm831x-wall.%d", wm831x_pdata->wm831x_num);
 550                 snprintf(power->battery_name, sizeof(power->wall_name),
 551                          "wm831x-battery.%d", wm831x_pdata->wm831x_num);
 552                 snprintf(power->usb_name, sizeof(power->wall_name),
 553                          "wm831x-usb.%d", wm831x_pdata->wm831x_num);
 554         } else {
 555                 snprintf(power->wall_name, sizeof(power->wall_name),
 556                          "wm831x-wall");
 557                 snprintf(power->battery_name, sizeof(power->wall_name),
 558                          "wm831x-battery");
 559                 snprintf(power->usb_name, sizeof(power->wall_name),
 560                          "wm831x-usb");
 561         }
 562 
 563         /* We ignore configuration failures since we can still read back
 564          * the status without enabling the charger.
 565          */
 566         wm831x_config_battery(wm831x);
 567 
 568         power->wall_desc.name = power->wall_name;
 569         power->wall_desc.type = POWER_SUPPLY_TYPE_MAINS;
 570         power->wall_desc.properties = wm831x_wall_props;
 571         power->wall_desc.num_properties = ARRAY_SIZE(wm831x_wall_props);
 572         power->wall_desc.get_property = wm831x_wall_get_prop;
 573         power->wall = power_supply_register(&pdev->dev, &power->wall_desc,
 574                                             NULL);
 575         if (IS_ERR(power->wall)) {
 576                 ret = PTR_ERR(power->wall);
 577                 goto err;
 578         }
 579 
 580         power->usb_desc.name = power->usb_name,
 581         power->usb_desc.type = POWER_SUPPLY_TYPE_USB;
 582         power->usb_desc.properties = wm831x_usb_props;
 583         power->usb_desc.num_properties = ARRAY_SIZE(wm831x_usb_props);
 584         power->usb_desc.get_property = wm831x_usb_get_prop;
 585         power->usb = power_supply_register(&pdev->dev, &power->usb_desc, NULL);
 586         if (IS_ERR(power->usb)) {
 587                 ret = PTR_ERR(power->usb);
 588                 goto err_wall;
 589         }
 590 
 591         ret = wm831x_reg_read(wm831x, WM831X_CHARGER_CONTROL_1);
 592         if (ret < 0)
 593                 goto err_wall;
 594         power->have_battery = ret & WM831X_CHG_ENA;
 595 
 596         if (power->have_battery) {
 597                 power->battery_desc.name = power->battery_name;
 598                 power->battery_desc.properties = wm831x_bat_props;
 599                 power->battery_desc.num_properties = ARRAY_SIZE(wm831x_bat_props);
 600                 power->battery_desc.get_property = wm831x_bat_get_prop;
 601                 power->battery_desc.use_for_apm = 1;
 602                 power->battery = power_supply_register(&pdev->dev,
 603                                                        &power->battery_desc,
 604                                                        NULL);
 605                 if (IS_ERR(power->battery)) {
 606                         ret = PTR_ERR(power->battery);
 607                         goto err_usb;
 608                 }
 609         }
 610 
 611         irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO"));
 612         ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq,
 613                                    IRQF_TRIGGER_RISING | IRQF_ONESHOT, "System power low",
 614                                    power);
 615         if (ret != 0) {
 616                 dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n",
 617                         irq, ret);
 618                 goto err_battery;
 619         }
 620 
 621         irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC"));
 622         ret = request_threaded_irq(irq, NULL, wm831x_pwr_src_irq,
 623                                    IRQF_TRIGGER_RISING | IRQF_ONESHOT, "Power source",
 624                                    power);
 625         if (ret != 0) {
 626                 dev_err(&pdev->dev, "Failed to request PWR SRC IRQ %d: %d\n",
 627                         irq, ret);
 628                 goto err_syslo;
 629         }
 630 
 631         for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
 632                 irq = wm831x_irq(wm831x,
 633                                  platform_get_irq_byname(pdev,
 634                                                          wm831x_bat_irqs[i]));
 635                 ret = request_threaded_irq(irq, NULL, wm831x_bat_irq,
 636                                            IRQF_TRIGGER_RISING | IRQF_ONESHOT,
 637                                            wm831x_bat_irqs[i],
 638                                            power);
 639                 if (ret != 0) {
 640                         dev_err(&pdev->dev,
 641                                 "Failed to request %s IRQ %d: %d\n",
 642                                 wm831x_bat_irqs[i], irq, ret);
 643                         goto err_bat_irq;
 644                 }
 645         }
 646 
 647         power->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "phys", 0);
 648         ret = PTR_ERR_OR_ZERO(power->usb_phy);
 649 
 650         switch (ret) {
 651         case 0:
 652                 power->usb_notify.notifier_call = wm831x_usb_limit_change;
 653                 ret = usb_register_notifier(power->usb_phy, &power->usb_notify);
 654                 if (ret) {
 655                         dev_err(&pdev->dev, "Failed to register notifier: %d\n",
 656                                 ret);
 657                         goto err_bat_irq;
 658                 }
 659                 break;
 660         case -EINVAL:
 661         case -ENODEV:
 662                 /* ignore missing usb-phy, it's optional */
 663                 power->usb_phy = NULL;
 664                 ret = 0;
 665                 break;
 666         default:
 667                 dev_err(&pdev->dev, "Failed to find USB phy: %d\n", ret);
 668                 /* fall-through */
 669         case -EPROBE_DEFER:
 670                 goto err_bat_irq;
 671                 break;
 672         }
 673 
 674         return ret;
 675 
 676 err_bat_irq:
 677         --i;
 678         for (; i >= 0; i--) {
 679                 irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
 680                 free_irq(irq, power);
 681         }
 682         irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC"));
 683         free_irq(irq, power);
 684 err_syslo:
 685         irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO"));
 686         free_irq(irq, power);
 687 err_battery:
 688         if (power->have_battery)
 689                 power_supply_unregister(power->battery);
 690 err_usb:
 691         power_supply_unregister(power->usb);
 692 err_wall:
 693         power_supply_unregister(power->wall);
 694 err:
 695         return ret;
 696 }
 697 
 698 static int wm831x_power_remove(struct platform_device *pdev)
 699 {
 700         struct wm831x_power *wm831x_power = platform_get_drvdata(pdev);
 701         struct wm831x *wm831x = wm831x_power->wm831x;
 702         int irq, i;
 703 
 704         if (wm831x_power->usb_phy) {
 705                 usb_unregister_notifier(wm831x_power->usb_phy,
 706                                         &wm831x_power->usb_notify);
 707         }
 708 
 709         for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
 710                 irq = wm831x_irq(wm831x, 
 711                                  platform_get_irq_byname(pdev,
 712                                                          wm831x_bat_irqs[i]));
 713                 free_irq(irq, wm831x_power);
 714         }
 715 
 716         irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC"));
 717         free_irq(irq, wm831x_power);
 718 
 719         irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO"));
 720         free_irq(irq, wm831x_power);
 721 
 722         if (wm831x_power->have_battery)
 723                 power_supply_unregister(wm831x_power->battery);
 724         power_supply_unregister(wm831x_power->wall);
 725         power_supply_unregister(wm831x_power->usb);
 726         return 0;
 727 }
 728 
 729 static struct platform_driver wm831x_power_driver = {
 730         .probe = wm831x_power_probe,
 731         .remove = wm831x_power_remove,
 732         .driver = {
 733                 .name = "wm831x-power",
 734         },
 735 };
 736 
 737 module_platform_driver(wm831x_power_driver);
 738 
 739 MODULE_DESCRIPTION("Power supply driver for WM831x PMICs");
 740 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 741 MODULE_LICENSE("GPL");
 742 MODULE_ALIAS("platform:wm831x-power");

/* [<][>][^][v][top][bottom][index][help] */