root/drivers/power/supply/cpcap-battery.c

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

DEFINITIONS

This source file includes following definitions.
  1. cpcap_battery_get_state
  2. cpcap_battery_latest
  3. cpcap_battery_previous
  4. cpcap_charger_battery_temperature
  5. cpcap_battery_get_voltage
  6. cpcap_battery_get_current
  7. cpcap_battery_cc_raw_div
  8. cpcap_battery_cc_to_uah
  9. cpcap_battery_cc_to_ua
  10. cpcap_battery_read_accumulated
  11. cpcap_battery_cc_get_avg_current
  12. cpcap_battery_full
  13. cpcap_battery_update_status
  14. cpcap_battery_get_property
  15. cpcap_battery_irq_thread
  16. cpcap_battery_init_irq
  17. cpcap_battery_init_interrupts
  18. cpcap_battery_init_iio
  19. cpcap_battery_probe
  20. cpcap_battery_remove

   1 /*
   2  * Battery driver for CPCAP PMIC
   3  *
   4  * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
   5  *
   6  * Some parts of the code based on earlie Motorola mapphone Linux kernel
   7  * drivers:
   8  *
   9  * Copyright (C) 2009-2010 Motorola, Inc.
  10  *
  11  * This program is free software; you can redistribute it and/or modify
  12  * it under the terms of the GNU General Public License version 2 as
  13  * published by the Free Software Foundation.
  14 
  15  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  16  * kind, whether express or implied; without even the implied warranty
  17  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18  * GNU General Public License for more details.
  19  */
  20 
  21 #include <linux/delay.h>
  22 #include <linux/err.h>
  23 #include <linux/interrupt.h>
  24 #include <linux/kernel.h>
  25 #include <linux/module.h>
  26 #include <linux/of_device.h>
  27 #include <linux/platform_device.h>
  28 #include <linux/power_supply.h>
  29 #include <linux/reboot.h>
  30 #include <linux/regmap.h>
  31 
  32 #include <linux/iio/consumer.h>
  33 #include <linux/iio/types.h>
  34 #include <linux/mfd/motorola-cpcap.h>
  35 
  36 #include <asm/div64.h>
  37 
  38 /*
  39  * Register bit defines for CPCAP_REG_BPEOL. Some of these seem to
  40  * map to MC13783UG.pdf "Table 5-19. Register 13, Power Control 0"
  41  * to enable BATTDETEN, LOBAT and EOL features. We currently use
  42  * LOBAT interrupts instead of EOL.
  43  */
  44 #define CPCAP_REG_BPEOL_BIT_EOL9        BIT(9)  /* Set for EOL irq */
  45 #define CPCAP_REG_BPEOL_BIT_EOL8        BIT(8)  /* Set for EOL irq */
  46 #define CPCAP_REG_BPEOL_BIT_UNKNOWN7    BIT(7)
  47 #define CPCAP_REG_BPEOL_BIT_UNKNOWN6    BIT(6)
  48 #define CPCAP_REG_BPEOL_BIT_UNKNOWN5    BIT(5)
  49 #define CPCAP_REG_BPEOL_BIT_EOL_MULTI   BIT(4)  /* Set for multiple EOL irqs */
  50 #define CPCAP_REG_BPEOL_BIT_UNKNOWN3    BIT(3)
  51 #define CPCAP_REG_BPEOL_BIT_UNKNOWN2    BIT(2)
  52 #define CPCAP_REG_BPEOL_BIT_BATTDETEN   BIT(1)  /* Enable battery detect */
  53 #define CPCAP_REG_BPEOL_BIT_EOLSEL      BIT(0)  /* BPDET = 0, EOL = 1 */
  54 
  55 #define CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS       250
  56 
  57 enum {
  58         CPCAP_BATTERY_IIO_BATTDET,
  59         CPCAP_BATTERY_IIO_VOLTAGE,
  60         CPCAP_BATTERY_IIO_CHRG_CURRENT,
  61         CPCAP_BATTERY_IIO_BATT_CURRENT,
  62         CPCAP_BATTERY_IIO_NR,
  63 };
  64 
  65 enum cpcap_battery_irq_action {
  66         CPCAP_BATTERY_IRQ_ACTION_NONE,
  67         CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW,
  68         CPCAP_BATTERY_IRQ_ACTION_POWEROFF,
  69 };
  70 
  71 struct cpcap_interrupt_desc {
  72         const char *name;
  73         struct list_head node;
  74         int irq;
  75         enum cpcap_battery_irq_action action;
  76 };
  77 
  78 struct cpcap_battery_config {
  79         int ccm;
  80         int cd_factor;
  81         struct power_supply_info info;
  82 };
  83 
  84 struct cpcap_coulomb_counter_data {
  85         s32 sample;             /* 24 or 32 bits */
  86         s32 accumulator;
  87         s16 offset;             /* 9 bits */
  88 };
  89 
  90 enum cpcap_battery_state {
  91         CPCAP_BATTERY_STATE_PREVIOUS,
  92         CPCAP_BATTERY_STATE_LATEST,
  93         CPCAP_BATTERY_STATE_NR,
  94 };
  95 
  96 struct cpcap_battery_state_data {
  97         int voltage;
  98         int current_ua;
  99         int counter_uah;
 100         int temperature;
 101         ktime_t time;
 102         struct cpcap_coulomb_counter_data cc;
 103 };
 104 
 105 struct cpcap_battery_ddata {
 106         struct device *dev;
 107         struct regmap *reg;
 108         struct list_head irq_list;
 109         struct iio_channel *channels[CPCAP_BATTERY_IIO_NR];
 110         struct power_supply *psy;
 111         struct cpcap_battery_config config;
 112         struct cpcap_battery_state_data state[CPCAP_BATTERY_STATE_NR];
 113         atomic_t active;
 114         int status;
 115         u16 vendor;
 116 };
 117 
 118 #define CPCAP_NO_BATTERY        -400
 119 
 120 static struct cpcap_battery_state_data *
 121 cpcap_battery_get_state(struct cpcap_battery_ddata *ddata,
 122                         enum cpcap_battery_state state)
 123 {
 124         if (state >= CPCAP_BATTERY_STATE_NR)
 125                 return NULL;
 126 
 127         return &ddata->state[state];
 128 }
 129 
 130 static struct cpcap_battery_state_data *
 131 cpcap_battery_latest(struct cpcap_battery_ddata *ddata)
 132 {
 133         return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_LATEST);
 134 }
 135 
 136 static struct cpcap_battery_state_data *
 137 cpcap_battery_previous(struct cpcap_battery_ddata *ddata)
 138 {
 139         return cpcap_battery_get_state(ddata, CPCAP_BATTERY_STATE_PREVIOUS);
 140 }
 141 
 142 static int cpcap_charger_battery_temperature(struct cpcap_battery_ddata *ddata,
 143                                              int *value)
 144 {
 145         struct iio_channel *channel;
 146         int error;
 147 
 148         channel = ddata->channels[CPCAP_BATTERY_IIO_BATTDET];
 149         error = iio_read_channel_processed(channel, value);
 150         if (error < 0) {
 151                 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
 152                 *value = CPCAP_NO_BATTERY;
 153 
 154                 return error;
 155         }
 156 
 157         *value /= 100;
 158 
 159         return 0;
 160 }
 161 
 162 static int cpcap_battery_get_voltage(struct cpcap_battery_ddata *ddata)
 163 {
 164         struct iio_channel *channel;
 165         int error, value = 0;
 166 
 167         channel = ddata->channels[CPCAP_BATTERY_IIO_VOLTAGE];
 168         error = iio_read_channel_processed(channel, &value);
 169         if (error < 0) {
 170                 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
 171 
 172                 return 0;
 173         }
 174 
 175         return value * 1000;
 176 }
 177 
 178 static int cpcap_battery_get_current(struct cpcap_battery_ddata *ddata)
 179 {
 180         struct iio_channel *channel;
 181         int error, value = 0;
 182 
 183         channel = ddata->channels[CPCAP_BATTERY_IIO_BATT_CURRENT];
 184         error = iio_read_channel_processed(channel, &value);
 185         if (error < 0) {
 186                 dev_warn(ddata->dev, "%s failed: %i\n", __func__, error);
 187 
 188                 return 0;
 189         }
 190 
 191         return value * 1000;
 192 }
 193 
 194 /**
 195  * cpcap_battery_cc_raw_div - calculate and divide coulomb counter μAms values
 196  * @ddata: device driver data
 197  * @sample: coulomb counter sample value
 198  * @accumulator: coulomb counter integrator value
 199  * @offset: coulomb counter offset value
 200  * @divider: conversion divider
 201  *
 202  * Note that cc_lsb and cc_dur values are from Motorola Linux kernel
 203  * function data_get_avg_curr_ua() and seem to be based on measured test
 204  * results. It also has the following comment:
 205  *
 206  * Adjustment factors are applied here as a temp solution per the test
 207  * results. Need to work out a formal solution for this adjustment.
 208  *
 209  * A coulomb counter for similar hardware seems to be documented in
 210  * "TWL6030 Gas Gauging Basics (Rev. A)" swca095a.pdf in chapter
 211  * "10 Calculating Accumulated Current". We however follow what the
 212  * Motorola mapphone Linux kernel is doing as there may be either a
 213  * TI or ST coulomb counter in the PMIC.
 214  */
 215 static int cpcap_battery_cc_raw_div(struct cpcap_battery_ddata *ddata,
 216                                     s32 sample, s32 accumulator,
 217                                     s16 offset, u32 divider)
 218 {
 219         s64 acc;
 220         u64 tmp;
 221         int avg_current;
 222         u32 cc_lsb;
 223 
 224         if (!divider)
 225                 return 0;
 226 
 227         switch (ddata->vendor) {
 228         case CPCAP_VENDOR_ST:
 229                 cc_lsb = 95374;         /* μAms per LSB */
 230                 break;
 231         case CPCAP_VENDOR_TI:
 232                 cc_lsb = 91501;         /* μAms per LSB */
 233                 break;
 234         default:
 235                 return -EINVAL;
 236         }
 237 
 238         acc = accumulator;
 239         acc = acc - ((s64)sample * offset);
 240         cc_lsb = (cc_lsb * ddata->config.cd_factor) / 1000;
 241 
 242         if (acc >=  0)
 243                 tmp = acc;
 244         else
 245                 tmp = acc * -1;
 246 
 247         tmp = tmp * cc_lsb;
 248         do_div(tmp, divider);
 249         avg_current = tmp;
 250 
 251         if (acc >= 0)
 252                 return -avg_current;
 253         else
 254                 return avg_current;
 255 }
 256 
 257 /* 3600000μAms = 1μAh */
 258 static int cpcap_battery_cc_to_uah(struct cpcap_battery_ddata *ddata,
 259                                    s32 sample, s32 accumulator,
 260                                    s16 offset)
 261 {
 262         return cpcap_battery_cc_raw_div(ddata, sample,
 263                                         accumulator, offset,
 264                                         3600000);
 265 }
 266 
 267 static int cpcap_battery_cc_to_ua(struct cpcap_battery_ddata *ddata,
 268                                   s32 sample, s32 accumulator,
 269                                   s16 offset)
 270 {
 271         return cpcap_battery_cc_raw_div(ddata, sample,
 272                                         accumulator, offset,
 273                                         sample *
 274                                         CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS);
 275 }
 276 
 277 /**
 278  * cpcap_battery_read_accumulated - reads cpcap coulomb counter
 279  * @ddata: device driver data
 280  * @regs: coulomb counter values
 281  *
 282  * Based on Motorola mapphone kernel function data_read_regs().
 283  * Looking at the registers, the coulomb counter seems similar to
 284  * the coulomb counter in TWL6030. See "TWL6030 Gas Gauging Basics
 285  * (Rev. A) swca095a.pdf for "10 Calculating Accumulated Current".
 286  *
 287  * Note that swca095a.pdf instructs to stop the coulomb counter
 288  * before reading to avoid values changing. Motorola mapphone
 289  * Linux kernel does not do it, so let's assume they've verified
 290  * the data produced is correct.
 291  */
 292 static int
 293 cpcap_battery_read_accumulated(struct cpcap_battery_ddata *ddata,
 294                                struct cpcap_coulomb_counter_data *ccd)
 295 {
 296         u16 buf[7];     /* CPCAP_REG_CC1 to CCI */
 297         int error;
 298 
 299         ccd->sample = 0;
 300         ccd->accumulator = 0;
 301         ccd->offset = 0;
 302 
 303         /* Read coulomb counter register range */
 304         error = regmap_bulk_read(ddata->reg, CPCAP_REG_CCS1,
 305                                  buf, ARRAY_SIZE(buf));
 306         if (error)
 307                 return 0;
 308 
 309         /* Sample value CPCAP_REG_CCS1 & 2 */
 310         ccd->sample = (buf[1] & 0x0fff) << 16;
 311         ccd->sample |= buf[0];
 312         if (ddata->vendor == CPCAP_VENDOR_TI)
 313                 ccd->sample = sign_extend32(24, ccd->sample);
 314 
 315         /* Accumulator value CPCAP_REG_CCA1 & 2 */
 316         ccd->accumulator = ((s16)buf[3]) << 16;
 317         ccd->accumulator |= buf[2];
 318 
 319         /*
 320          * Coulomb counter calibration offset is CPCAP_REG_CCM,
 321          * REG_CCO seems unused
 322          */
 323         ccd->offset = buf[4];
 324         ccd->offset = sign_extend32(ccd->offset, 9);
 325 
 326         return cpcap_battery_cc_to_uah(ddata,
 327                                        ccd->sample,
 328                                        ccd->accumulator,
 329                                        ccd->offset);
 330 }
 331 
 332 /**
 333  * cpcap_battery_cc_get_avg_current - read cpcap coulumb counter
 334  * @ddata: cpcap battery driver device data
 335  */
 336 static int cpcap_battery_cc_get_avg_current(struct cpcap_battery_ddata *ddata)
 337 {
 338         int value, acc, error;
 339         s32 sample = 1;
 340         s16 offset;
 341 
 342         if (ddata->vendor == CPCAP_VENDOR_ST)
 343                 sample = 4;
 344 
 345         /* Coulomb counter integrator */
 346         error = regmap_read(ddata->reg, CPCAP_REG_CCI, &value);
 347         if (error)
 348                 return error;
 349 
 350         if ((ddata->vendor == CPCAP_VENDOR_TI) && (value > 0x2000))
 351                 value = value | 0xc000;
 352 
 353         acc = (s16)value;
 354 
 355         /* Coulomb counter sample time */
 356         error = regmap_read(ddata->reg, CPCAP_REG_CCM, &value);
 357         if (error)
 358                 return error;
 359 
 360         if (value < 0x200)
 361                 offset = value;
 362         else
 363                 offset = value | 0xfc00;
 364 
 365         return cpcap_battery_cc_to_ua(ddata, sample, acc, offset);
 366 }
 367 
 368 static bool cpcap_battery_full(struct cpcap_battery_ddata *ddata)
 369 {
 370         struct cpcap_battery_state_data *state = cpcap_battery_latest(ddata);
 371 
 372         /* Basically anything that measures above 4347000 is full */
 373         if (state->voltage >= (ddata->config.info.voltage_max_design - 4000))
 374                 return true;
 375 
 376         return false;
 377 }
 378 
 379 static int cpcap_battery_update_status(struct cpcap_battery_ddata *ddata)
 380 {
 381         struct cpcap_battery_state_data state, *latest, *previous;
 382         ktime_t now;
 383         int error;
 384 
 385         memset(&state, 0, sizeof(state));
 386         now = ktime_get();
 387 
 388         latest = cpcap_battery_latest(ddata);
 389         if (latest) {
 390                 s64 delta_ms = ktime_to_ms(ktime_sub(now, latest->time));
 391 
 392                 if (delta_ms < CPCAP_BATTERY_CC_SAMPLE_PERIOD_MS)
 393                         return delta_ms;
 394         }
 395 
 396         state.time = now;
 397         state.voltage = cpcap_battery_get_voltage(ddata);
 398         state.current_ua = cpcap_battery_get_current(ddata);
 399         state.counter_uah = cpcap_battery_read_accumulated(ddata, &state.cc);
 400 
 401         error = cpcap_charger_battery_temperature(ddata,
 402                                                   &state.temperature);
 403         if (error)
 404                 return error;
 405 
 406         previous = cpcap_battery_previous(ddata);
 407         memcpy(previous, latest, sizeof(*previous));
 408         memcpy(latest, &state, sizeof(*latest));
 409 
 410         return 0;
 411 }
 412 
 413 static enum power_supply_property cpcap_battery_props[] = {
 414         POWER_SUPPLY_PROP_STATUS,
 415         POWER_SUPPLY_PROP_PRESENT,
 416         POWER_SUPPLY_PROP_TECHNOLOGY,
 417         POWER_SUPPLY_PROP_VOLTAGE_NOW,
 418         POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
 419         POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 420         POWER_SUPPLY_PROP_CURRENT_AVG,
 421         POWER_SUPPLY_PROP_CURRENT_NOW,
 422         POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 423         POWER_SUPPLY_PROP_CHARGE_COUNTER,
 424         POWER_SUPPLY_PROP_POWER_NOW,
 425         POWER_SUPPLY_PROP_POWER_AVG,
 426         POWER_SUPPLY_PROP_CAPACITY_LEVEL,
 427         POWER_SUPPLY_PROP_SCOPE,
 428         POWER_SUPPLY_PROP_TEMP,
 429 };
 430 
 431 static int cpcap_battery_get_property(struct power_supply *psy,
 432                                       enum power_supply_property psp,
 433                                       union power_supply_propval *val)
 434 {
 435         struct cpcap_battery_ddata *ddata = power_supply_get_drvdata(psy);
 436         struct cpcap_battery_state_data *latest, *previous;
 437         u32 sample;
 438         s32 accumulator;
 439         int cached;
 440         s64 tmp;
 441 
 442         cached = cpcap_battery_update_status(ddata);
 443         if (cached < 0)
 444                 return cached;
 445 
 446         latest = cpcap_battery_latest(ddata);
 447         previous = cpcap_battery_previous(ddata);
 448 
 449         switch (psp) {
 450         case POWER_SUPPLY_PROP_PRESENT:
 451                 if (latest->temperature > CPCAP_NO_BATTERY)
 452                         val->intval = 1;
 453                 else
 454                         val->intval = 0;
 455                 break;
 456         case POWER_SUPPLY_PROP_STATUS:
 457                 if (cpcap_battery_full(ddata)) {
 458                         val->intval = POWER_SUPPLY_STATUS_FULL;
 459                         break;
 460                 }
 461                 if (cpcap_battery_cc_get_avg_current(ddata) < 0)
 462                         val->intval = POWER_SUPPLY_STATUS_CHARGING;
 463                 else
 464                         val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 465                 break;
 466         case POWER_SUPPLY_PROP_TECHNOLOGY:
 467                 val->intval = ddata->config.info.technology;
 468                 break;
 469         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 470                 val->intval = cpcap_battery_get_voltage(ddata);
 471                 break;
 472         case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
 473                 val->intval = ddata->config.info.voltage_max_design;
 474                 break;
 475         case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
 476                 val->intval = ddata->config.info.voltage_min_design;
 477                 break;
 478         case POWER_SUPPLY_PROP_CURRENT_AVG:
 479                 sample = latest->cc.sample - previous->cc.sample;
 480                 if (!sample) {
 481                         val->intval = cpcap_battery_cc_get_avg_current(ddata);
 482                         break;
 483                 }
 484                 accumulator = latest->cc.accumulator - previous->cc.accumulator;
 485                 val->intval = cpcap_battery_cc_to_ua(ddata, sample,
 486                                                      accumulator,
 487                                                      latest->cc.offset);
 488                 break;
 489         case POWER_SUPPLY_PROP_CURRENT_NOW:
 490                 val->intval = latest->current_ua;
 491                 break;
 492         case POWER_SUPPLY_PROP_CHARGE_COUNTER:
 493                 val->intval = latest->counter_uah;
 494                 break;
 495         case POWER_SUPPLY_PROP_POWER_NOW:
 496                 tmp = (latest->voltage / 10000) * latest->current_ua;
 497                 val->intval = div64_s64(tmp, 100);
 498                 break;
 499         case POWER_SUPPLY_PROP_POWER_AVG:
 500                 sample = latest->cc.sample - previous->cc.sample;
 501                 if (!sample) {
 502                         tmp = cpcap_battery_cc_get_avg_current(ddata);
 503                         tmp *= (latest->voltage / 10000);
 504                         val->intval = div64_s64(tmp, 100);
 505                         break;
 506                 }
 507                 accumulator = latest->cc.accumulator - previous->cc.accumulator;
 508                 tmp = cpcap_battery_cc_to_ua(ddata, sample, accumulator,
 509                                              latest->cc.offset);
 510                 tmp *= ((latest->voltage + previous->voltage) / 20000);
 511                 val->intval = div64_s64(tmp, 100);
 512                 break;
 513         case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
 514                 if (cpcap_battery_full(ddata))
 515                         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
 516                 else if (latest->voltage >= 3750000)
 517                         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
 518                 else if (latest->voltage >= 3300000)
 519                         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
 520                 else if (latest->voltage > 3100000)
 521                         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
 522                 else if (latest->voltage <= 3100000)
 523                         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
 524                 else
 525                         val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
 526                 break;
 527         case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 528                 val->intval = ddata->config.info.charge_full_design;
 529                 break;
 530         case POWER_SUPPLY_PROP_SCOPE:
 531                 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
 532                 break;
 533         case POWER_SUPPLY_PROP_TEMP:
 534                 val->intval = latest->temperature;
 535                 break;
 536         default:
 537                 return -EINVAL;
 538         }
 539 
 540         return 0;
 541 }
 542 
 543 static irqreturn_t cpcap_battery_irq_thread(int irq, void *data)
 544 {
 545         struct cpcap_battery_ddata *ddata = data;
 546         struct cpcap_battery_state_data *latest;
 547         struct cpcap_interrupt_desc *d;
 548 
 549         if (!atomic_read(&ddata->active))
 550                 return IRQ_NONE;
 551 
 552         list_for_each_entry(d, &ddata->irq_list, node) {
 553                 if (irq == d->irq)
 554                         break;
 555         }
 556 
 557         if (!d)
 558                 return IRQ_NONE;
 559 
 560         latest = cpcap_battery_latest(ddata);
 561 
 562         switch (d->action) {
 563         case CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW:
 564                 if (latest->current_ua >= 0)
 565                         dev_warn(ddata->dev, "Battery low at %imV!\n",
 566                                 latest->voltage / 1000);
 567                 break;
 568         case CPCAP_BATTERY_IRQ_ACTION_POWEROFF:
 569                 if (latest->current_ua >= 0 && latest->voltage <= 3200000) {
 570                         dev_emerg(ddata->dev,
 571                                   "Battery empty at %imV, powering off\n",
 572                                   latest->voltage / 1000);
 573                         orderly_poweroff(true);
 574                 }
 575                 break;
 576         default:
 577                 break;
 578         }
 579 
 580         power_supply_changed(ddata->psy);
 581 
 582         return IRQ_HANDLED;
 583 }
 584 
 585 static int cpcap_battery_init_irq(struct platform_device *pdev,
 586                                   struct cpcap_battery_ddata *ddata,
 587                                   const char *name)
 588 {
 589         struct cpcap_interrupt_desc *d;
 590         int irq, error;
 591 
 592         irq = platform_get_irq_byname(pdev, name);
 593         if (irq < 0)
 594                 return irq;
 595 
 596         error = devm_request_threaded_irq(ddata->dev, irq, NULL,
 597                                           cpcap_battery_irq_thread,
 598                                           IRQF_SHARED,
 599                                           name, ddata);
 600         if (error) {
 601                 dev_err(ddata->dev, "could not get irq %s: %i\n",
 602                         name, error);
 603 
 604                 return error;
 605         }
 606 
 607         d = devm_kzalloc(ddata->dev, sizeof(*d), GFP_KERNEL);
 608         if (!d)
 609                 return -ENOMEM;
 610 
 611         d->name = name;
 612         d->irq = irq;
 613 
 614         if (!strncmp(name, "lowbph", 6))
 615                 d->action = CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW;
 616         else if (!strncmp(name, "lowbpl", 6))
 617                 d->action = CPCAP_BATTERY_IRQ_ACTION_POWEROFF;
 618 
 619         list_add(&d->node, &ddata->irq_list);
 620 
 621         return 0;
 622 }
 623 
 624 static int cpcap_battery_init_interrupts(struct platform_device *pdev,
 625                                          struct cpcap_battery_ddata *ddata)
 626 {
 627         static const char * const cpcap_battery_irqs[] = {
 628                 "eol", "lowbph", "lowbpl",
 629                 "chrgcurr1", "battdetb"
 630         };
 631         int i, error;
 632 
 633         for (i = 0; i < ARRAY_SIZE(cpcap_battery_irqs); i++) {
 634                 error = cpcap_battery_init_irq(pdev, ddata,
 635                                                cpcap_battery_irqs[i]);
 636                 if (error)
 637                         return error;
 638         }
 639 
 640         /* Enable low battery interrupts for 3.3V high and 3.1V low */
 641         error = regmap_update_bits(ddata->reg, CPCAP_REG_BPEOL,
 642                                    0xffff,
 643                                    CPCAP_REG_BPEOL_BIT_BATTDETEN);
 644         if (error)
 645                 return error;
 646 
 647         return 0;
 648 }
 649 
 650 static int cpcap_battery_init_iio(struct cpcap_battery_ddata *ddata)
 651 {
 652         const char * const names[CPCAP_BATTERY_IIO_NR] = {
 653                 "battdetb", "battp", "chg_isense", "batti",
 654         };
 655         int error, i;
 656 
 657         for (i = 0; i < CPCAP_BATTERY_IIO_NR; i++) {
 658                 ddata->channels[i] = devm_iio_channel_get(ddata->dev,
 659                                                           names[i]);
 660                 if (IS_ERR(ddata->channels[i])) {
 661                         error = PTR_ERR(ddata->channels[i]);
 662                         goto out_err;
 663                 }
 664 
 665                 if (!ddata->channels[i]->indio_dev) {
 666                         error = -ENXIO;
 667                         goto out_err;
 668                 }
 669         }
 670 
 671         return 0;
 672 
 673 out_err:
 674         if (error != -EPROBE_DEFER)
 675                 dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n",
 676                         error);
 677 
 678         return error;
 679 }
 680 
 681 /*
 682  * Based on the values from Motorola mapphone Linux kernel. In the
 683  * the Motorola mapphone Linux kernel tree the value for pm_cd_factor
 684  * is passed to the kernel via device tree. If it turns out to be
 685  * something device specific we can consider that too later.
 686  *
 687  * And looking at the battery full and shutdown values for the stock
 688  * kernel on droid 4, full is 4351000 and software initiates shutdown
 689  * at 3078000. The device will die around 2743000.
 690  */
 691 static const struct cpcap_battery_config cpcap_battery_default_data = {
 692         .ccm = 0x3ff,
 693         .cd_factor = 0x3cc,
 694         .info.technology = POWER_SUPPLY_TECHNOLOGY_LION,
 695         .info.voltage_max_design = 4351000,
 696         .info.voltage_min_design = 3100000,
 697         .info.charge_full_design = 1740000,
 698 };
 699 
 700 #ifdef CONFIG_OF
 701 static const struct of_device_id cpcap_battery_id_table[] = {
 702         {
 703                 .compatible = "motorola,cpcap-battery",
 704                 .data = &cpcap_battery_default_data,
 705         },
 706         {},
 707 };
 708 MODULE_DEVICE_TABLE(of, cpcap_battery_id_table);
 709 #endif
 710 
 711 static int cpcap_battery_probe(struct platform_device *pdev)
 712 {
 713         struct power_supply_desc *psy_desc;
 714         struct cpcap_battery_ddata *ddata;
 715         const struct of_device_id *match;
 716         struct power_supply_config psy_cfg = {};
 717         int error;
 718 
 719         match = of_match_device(of_match_ptr(cpcap_battery_id_table),
 720                                 &pdev->dev);
 721         if (!match)
 722                 return -EINVAL;
 723 
 724         if (!match->data) {
 725                 dev_err(&pdev->dev, "no configuration data found\n");
 726 
 727                 return -ENODEV;
 728         }
 729 
 730         ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
 731         if (!ddata)
 732                 return -ENOMEM;
 733 
 734         INIT_LIST_HEAD(&ddata->irq_list);
 735         ddata->dev = &pdev->dev;
 736         memcpy(&ddata->config, match->data, sizeof(ddata->config));
 737 
 738         ddata->reg = dev_get_regmap(ddata->dev->parent, NULL);
 739         if (!ddata->reg)
 740                 return -ENODEV;
 741 
 742         error = cpcap_get_vendor(ddata->dev, ddata->reg, &ddata->vendor);
 743         if (error)
 744                 return error;
 745 
 746         platform_set_drvdata(pdev, ddata);
 747 
 748         error = regmap_update_bits(ddata->reg, CPCAP_REG_CCM,
 749                                    0xffff, ddata->config.ccm);
 750         if (error)
 751                 return error;
 752 
 753         error = cpcap_battery_init_interrupts(pdev, ddata);
 754         if (error)
 755                 return error;
 756 
 757         error = cpcap_battery_init_iio(ddata);
 758         if (error)
 759                 return error;
 760 
 761         psy_desc = devm_kzalloc(ddata->dev, sizeof(*psy_desc), GFP_KERNEL);
 762         if (!psy_desc)
 763                 return -ENOMEM;
 764 
 765         psy_desc->name = "battery",
 766         psy_desc->type = POWER_SUPPLY_TYPE_BATTERY,
 767         psy_desc->properties = cpcap_battery_props,
 768         psy_desc->num_properties = ARRAY_SIZE(cpcap_battery_props),
 769         psy_desc->get_property = cpcap_battery_get_property,
 770 
 771         psy_cfg.of_node = pdev->dev.of_node;
 772         psy_cfg.drv_data = ddata;
 773 
 774         ddata->psy = devm_power_supply_register(ddata->dev, psy_desc,
 775                                                 &psy_cfg);
 776         error = PTR_ERR_OR_ZERO(ddata->psy);
 777         if (error) {
 778                 dev_err(ddata->dev, "failed to register power supply\n");
 779                 return error;
 780         }
 781 
 782         atomic_set(&ddata->active, 1);
 783 
 784         return 0;
 785 }
 786 
 787 static int cpcap_battery_remove(struct platform_device *pdev)
 788 {
 789         struct cpcap_battery_ddata *ddata = platform_get_drvdata(pdev);
 790         int error;
 791 
 792         atomic_set(&ddata->active, 0);
 793         error = regmap_update_bits(ddata->reg, CPCAP_REG_BPEOL,
 794                                    0xffff, 0);
 795         if (error)
 796                 dev_err(&pdev->dev, "could not disable: %i\n", error);
 797 
 798         return 0;
 799 }
 800 
 801 static struct platform_driver cpcap_battery_driver = {
 802         .driver = {
 803                 .name           = "cpcap_battery",
 804                 .of_match_table = of_match_ptr(cpcap_battery_id_table),
 805         },
 806         .probe  = cpcap_battery_probe,
 807         .remove = cpcap_battery_remove,
 808 };
 809 module_platform_driver(cpcap_battery_driver);
 810 
 811 MODULE_LICENSE("GPL v2");
 812 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
 813 MODULE_DESCRIPTION("CPCAP PMIC Battery Driver");

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