linux/drivers/power/smb347-charger.c
<<
>>
Prefs
   1/*
   2 * Summit Microelectronics SMB347 Battery Charger Driver
   3 *
   4 * Copyright (C) 2011, Intel Corporation
   5 *
   6 * Authors: Bruce E. Robertson <bruce.e.robertson@intel.com>
   7 *          Mika Westerberg <mika.westerberg@linux.intel.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/err.h>
  15#include <linux/gpio.h>
  16#include <linux/kernel.h>
  17#include <linux/module.h>
  18#include <linux/init.h>
  19#include <linux/interrupt.h>
  20#include <linux/i2c.h>
  21#include <linux/mutex.h>
  22#include <linux/power_supply.h>
  23#include <linux/power/smb347-charger.h>
  24#include <linux/regmap.h>
  25
  26/*
  27 * Configuration registers. These are mirrored to volatile RAM and can be
  28 * written once %CMD_A_ALLOW_WRITE is set in %CMD_A register. They will be
  29 * reloaded from non-volatile registers after POR.
  30 */
  31#define CFG_CHARGE_CURRENT                      0x00
  32#define CFG_CHARGE_CURRENT_FCC_MASK             0xe0
  33#define CFG_CHARGE_CURRENT_FCC_SHIFT            5
  34#define CFG_CHARGE_CURRENT_PCC_MASK             0x18
  35#define CFG_CHARGE_CURRENT_PCC_SHIFT            3
  36#define CFG_CHARGE_CURRENT_TC_MASK              0x07
  37#define CFG_CURRENT_LIMIT                       0x01
  38#define CFG_CURRENT_LIMIT_DC_MASK               0xf0
  39#define CFG_CURRENT_LIMIT_DC_SHIFT              4
  40#define CFG_CURRENT_LIMIT_USB_MASK              0x0f
  41#define CFG_FLOAT_VOLTAGE                       0x03
  42#define CFG_FLOAT_VOLTAGE_FLOAT_MASK            0x3f
  43#define CFG_FLOAT_VOLTAGE_THRESHOLD_MASK        0xc0
  44#define CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT       6
  45#define CFG_STAT                                0x05
  46#define CFG_STAT_DISABLED                       BIT(5)
  47#define CFG_STAT_ACTIVE_HIGH                    BIT(7)
  48#define CFG_PIN                                 0x06
  49#define CFG_PIN_EN_CTRL_MASK                    0x60
  50#define CFG_PIN_EN_CTRL_ACTIVE_HIGH             0x40
  51#define CFG_PIN_EN_CTRL_ACTIVE_LOW              0x60
  52#define CFG_PIN_EN_APSD_IRQ                     BIT(1)
  53#define CFG_PIN_EN_CHARGER_ERROR                BIT(2)
  54#define CFG_THERM                               0x07
  55#define CFG_THERM_SOFT_HOT_COMPENSATION_MASK    0x03
  56#define CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT   0
  57#define CFG_THERM_SOFT_COLD_COMPENSATION_MASK   0x0c
  58#define CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT  2
  59#define CFG_THERM_MONITOR_DISABLED              BIT(4)
  60#define CFG_SYSOK                               0x08
  61#define CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED   BIT(2)
  62#define CFG_OTHER                               0x09
  63#define CFG_OTHER_RID_MASK                      0xc0
  64#define CFG_OTHER_RID_ENABLED_AUTO_OTG          0xc0
  65#define CFG_OTG                                 0x0a
  66#define CFG_OTG_TEMP_THRESHOLD_MASK             0x30
  67#define CFG_OTG_TEMP_THRESHOLD_SHIFT            4
  68#define CFG_OTG_CC_COMPENSATION_MASK            0xc0
  69#define CFG_OTG_CC_COMPENSATION_SHIFT           6
  70#define CFG_TEMP_LIMIT                          0x0b
  71#define CFG_TEMP_LIMIT_SOFT_HOT_MASK            0x03
  72#define CFG_TEMP_LIMIT_SOFT_HOT_SHIFT           0
  73#define CFG_TEMP_LIMIT_SOFT_COLD_MASK           0x0c
  74#define CFG_TEMP_LIMIT_SOFT_COLD_SHIFT          2
  75#define CFG_TEMP_LIMIT_HARD_HOT_MASK            0x30
  76#define CFG_TEMP_LIMIT_HARD_HOT_SHIFT           4
  77#define CFG_TEMP_LIMIT_HARD_COLD_MASK           0xc0
  78#define CFG_TEMP_LIMIT_HARD_COLD_SHIFT          6
  79#define CFG_FAULT_IRQ                           0x0c
  80#define CFG_FAULT_IRQ_DCIN_UV                   BIT(2)
  81#define CFG_STATUS_IRQ                          0x0d
  82#define CFG_STATUS_IRQ_TERMINATION_OR_TAPER     BIT(4)
  83#define CFG_ADDRESS                             0x0e
  84
  85/* Command registers */
  86#define CMD_A                                   0x30
  87#define CMD_A_CHG_ENABLED                       BIT(1)
  88#define CMD_A_SUSPEND_ENABLED                   BIT(2)
  89#define CMD_A_ALLOW_WRITE                       BIT(7)
  90#define CMD_B                                   0x31
  91#define CMD_C                                   0x33
  92
  93/* Interrupt Status registers */
  94#define IRQSTAT_A                               0x35
  95#define IRQSTAT_C                               0x37
  96#define IRQSTAT_C_TERMINATION_STAT              BIT(0)
  97#define IRQSTAT_C_TERMINATION_IRQ               BIT(1)
  98#define IRQSTAT_C_TAPER_IRQ                     BIT(3)
  99#define IRQSTAT_E                               0x39
 100#define IRQSTAT_E_USBIN_UV_STAT                 BIT(0)
 101#define IRQSTAT_E_USBIN_UV_IRQ                  BIT(1)
 102#define IRQSTAT_E_DCIN_UV_STAT                  BIT(4)
 103#define IRQSTAT_E_DCIN_UV_IRQ                   BIT(5)
 104#define IRQSTAT_F                               0x3a
 105
 106/* Status registers */
 107#define STAT_A                                  0x3b
 108#define STAT_A_FLOAT_VOLTAGE_MASK               0x3f
 109#define STAT_B                                  0x3c
 110#define STAT_C                                  0x3d
 111#define STAT_C_CHG_ENABLED                      BIT(0)
 112#define STAT_C_CHG_MASK                         0x06
 113#define STAT_C_CHG_SHIFT                        1
 114#define STAT_C_CHARGER_ERROR                    BIT(6)
 115#define STAT_E                                  0x3f
 116
 117#define SMB347_MAX_REGISTER                     0x3f
 118
 119/**
 120 * struct smb347_charger - smb347 charger instance
 121 * @lock: protects concurrent access to online variables
 122 * @dev: pointer to device
 123 * @regmap: pointer to driver regmap
 124 * @mains: power_supply instance for AC/DC power
 125 * @usb: power_supply instance for USB power
 126 * @battery: power_supply instance for battery
 127 * @mains_online: is AC/DC input connected
 128 * @usb_online: is USB input connected
 129 * @charging_enabled: is charging enabled
 130 * @pdata: pointer to platform data
 131 */
 132struct smb347_charger {
 133        struct mutex            lock;
 134        struct device           *dev;
 135        struct regmap           *regmap;
 136        struct power_supply     mains;
 137        struct power_supply     usb;
 138        struct power_supply     battery;
 139        bool                    mains_online;
 140        bool                    usb_online;
 141        bool                    charging_enabled;
 142        const struct smb347_charger_platform_data *pdata;
 143};
 144
 145/* Fast charge current in uA */
 146static const unsigned int fcc_tbl[] = {
 147        700000,
 148        900000,
 149        1200000,
 150        1500000,
 151        1800000,
 152        2000000,
 153        2200000,
 154        2500000,
 155};
 156
 157/* Pre-charge current in uA */
 158static const unsigned int pcc_tbl[] = {
 159        100000,
 160        150000,
 161        200000,
 162        250000,
 163};
 164
 165/* Termination current in uA */
 166static const unsigned int tc_tbl[] = {
 167        37500,
 168        50000,
 169        100000,
 170        150000,
 171        200000,
 172        250000,
 173        500000,
 174        600000,
 175};
 176
 177/* Input current limit in uA */
 178static const unsigned int icl_tbl[] = {
 179        300000,
 180        500000,
 181        700000,
 182        900000,
 183        1200000,
 184        1500000,
 185        1800000,
 186        2000000,
 187        2200000,
 188        2500000,
 189};
 190
 191/* Charge current compensation in uA */
 192static const unsigned int ccc_tbl[] = {
 193        250000,
 194        700000,
 195        900000,
 196        1200000,
 197};
 198
 199/* Convert register value to current using lookup table */
 200static int hw_to_current(const unsigned int *tbl, size_t size, unsigned int val)
 201{
 202        if (val >= size)
 203                return -EINVAL;
 204        return tbl[val];
 205}
 206
 207/* Convert current to register value using lookup table */
 208static int current_to_hw(const unsigned int *tbl, size_t size, unsigned int val)
 209{
 210        size_t i;
 211
 212        for (i = 0; i < size; i++)
 213                if (val < tbl[i])
 214                        break;
 215        return i > 0 ? i - 1 : -EINVAL;
 216}
 217
 218/**
 219 * smb347_update_ps_status - refreshes the power source status
 220 * @smb: pointer to smb347 charger instance
 221 *
 222 * Function checks whether any power source is connected to the charger and
 223 * updates internal state accordingly. If there is a change to previous state
 224 * function returns %1, otherwise %0 and negative errno in case of errror.
 225 */
 226static int smb347_update_ps_status(struct smb347_charger *smb)
 227{
 228        bool usb = false;
 229        bool dc = false;
 230        unsigned int val;
 231        int ret;
 232
 233        ret = regmap_read(smb->regmap, IRQSTAT_E, &val);
 234        if (ret < 0)
 235                return ret;
 236
 237        /*
 238         * Dc and usb are set depending on whether they are enabled in
 239         * platform data _and_ whether corresponding undervoltage is set.
 240         */
 241        if (smb->pdata->use_mains)
 242                dc = !(val & IRQSTAT_E_DCIN_UV_STAT);
 243        if (smb->pdata->use_usb)
 244                usb = !(val & IRQSTAT_E_USBIN_UV_STAT);
 245
 246        mutex_lock(&smb->lock);
 247        ret = smb->mains_online != dc || smb->usb_online != usb;
 248        smb->mains_online = dc;
 249        smb->usb_online = usb;
 250        mutex_unlock(&smb->lock);
 251
 252        return ret;
 253}
 254
 255/*
 256 * smb347_is_ps_online - returns whether input power source is connected
 257 * @smb: pointer to smb347 charger instance
 258 *
 259 * Returns %true if input power source is connected. Note that this is
 260 * dependent on what platform has configured for usable power sources. For
 261 * example if USB is disabled, this will return %false even if the USB cable
 262 * is connected.
 263 */
 264static bool smb347_is_ps_online(struct smb347_charger *smb)
 265{
 266        bool ret;
 267
 268        mutex_lock(&smb->lock);
 269        ret = smb->usb_online || smb->mains_online;
 270        mutex_unlock(&smb->lock);
 271
 272        return ret;
 273}
 274
 275/**
 276 * smb347_charging_status - returns status of charging
 277 * @smb: pointer to smb347 charger instance
 278 *
 279 * Function returns charging status. %0 means no charging is in progress,
 280 * %1 means pre-charging, %2 fast-charging and %3 taper-charging.
 281 */
 282static int smb347_charging_status(struct smb347_charger *smb)
 283{
 284        unsigned int val;
 285        int ret;
 286
 287        if (!smb347_is_ps_online(smb))
 288                return 0;
 289
 290        ret = regmap_read(smb->regmap, STAT_C, &val);
 291        if (ret < 0)
 292                return 0;
 293
 294        return (val & STAT_C_CHG_MASK) >> STAT_C_CHG_SHIFT;
 295}
 296
 297static int smb347_charging_set(struct smb347_charger *smb, bool enable)
 298{
 299        int ret = 0;
 300
 301        if (smb->pdata->enable_control != SMB347_CHG_ENABLE_SW) {
 302                dev_dbg(smb->dev, "charging enable/disable in SW disabled\n");
 303                return 0;
 304        }
 305
 306        mutex_lock(&smb->lock);
 307        if (smb->charging_enabled != enable) {
 308                ret = regmap_update_bits(smb->regmap, CMD_A, CMD_A_CHG_ENABLED,
 309                                         enable ? CMD_A_CHG_ENABLED : 0);
 310                if (!ret)
 311                        smb->charging_enabled = enable;
 312        }
 313        mutex_unlock(&smb->lock);
 314        return ret;
 315}
 316
 317static inline int smb347_charging_enable(struct smb347_charger *smb)
 318{
 319        return smb347_charging_set(smb, true);
 320}
 321
 322static inline int smb347_charging_disable(struct smb347_charger *smb)
 323{
 324        return smb347_charging_set(smb, false);
 325}
 326
 327static int smb347_start_stop_charging(struct smb347_charger *smb)
 328{
 329        int ret;
 330
 331        /*
 332         * Depending on whether valid power source is connected or not, we
 333         * disable or enable the charging. We do it manually because it
 334         * depends on how the platform has configured the valid inputs.
 335         */
 336        if (smb347_is_ps_online(smb)) {
 337                ret = smb347_charging_enable(smb);
 338                if (ret < 0)
 339                        dev_err(smb->dev, "failed to enable charging\n");
 340        } else {
 341                ret = smb347_charging_disable(smb);
 342                if (ret < 0)
 343                        dev_err(smb->dev, "failed to disable charging\n");
 344        }
 345
 346        return ret;
 347}
 348
 349static int smb347_set_charge_current(struct smb347_charger *smb)
 350{
 351        int ret;
 352
 353        if (smb->pdata->max_charge_current) {
 354                ret = current_to_hw(fcc_tbl, ARRAY_SIZE(fcc_tbl),
 355                                    smb->pdata->max_charge_current);
 356                if (ret < 0)
 357                        return ret;
 358
 359                ret = regmap_update_bits(smb->regmap, CFG_CHARGE_CURRENT,
 360                                         CFG_CHARGE_CURRENT_FCC_MASK,
 361                                         ret << CFG_CHARGE_CURRENT_FCC_SHIFT);
 362                if (ret < 0)
 363                        return ret;
 364        }
 365
 366        if (smb->pdata->pre_charge_current) {
 367                ret = current_to_hw(pcc_tbl, ARRAY_SIZE(pcc_tbl),
 368                                    smb->pdata->pre_charge_current);
 369                if (ret < 0)
 370                        return ret;
 371
 372                ret = regmap_update_bits(smb->regmap, CFG_CHARGE_CURRENT,
 373                                         CFG_CHARGE_CURRENT_PCC_MASK,
 374                                         ret << CFG_CHARGE_CURRENT_PCC_SHIFT);
 375                if (ret < 0)
 376                        return ret;
 377        }
 378
 379        if (smb->pdata->termination_current) {
 380                ret = current_to_hw(tc_tbl, ARRAY_SIZE(tc_tbl),
 381                                    smb->pdata->termination_current);
 382                if (ret < 0)
 383                        return ret;
 384
 385                ret = regmap_update_bits(smb->regmap, CFG_CHARGE_CURRENT,
 386                                         CFG_CHARGE_CURRENT_TC_MASK, ret);
 387                if (ret < 0)
 388                        return ret;
 389        }
 390
 391        return 0;
 392}
 393
 394static int smb347_set_current_limits(struct smb347_charger *smb)
 395{
 396        int ret;
 397
 398        if (smb->pdata->mains_current_limit) {
 399                ret = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl),
 400                                    smb->pdata->mains_current_limit);
 401                if (ret < 0)
 402                        return ret;
 403
 404                ret = regmap_update_bits(smb->regmap, CFG_CURRENT_LIMIT,
 405                                         CFG_CURRENT_LIMIT_DC_MASK,
 406                                         ret << CFG_CURRENT_LIMIT_DC_SHIFT);
 407                if (ret < 0)
 408                        return ret;
 409        }
 410
 411        if (smb->pdata->usb_hc_current_limit) {
 412                ret = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl),
 413                                    smb->pdata->usb_hc_current_limit);
 414                if (ret < 0)
 415                        return ret;
 416
 417                ret = regmap_update_bits(smb->regmap, CFG_CURRENT_LIMIT,
 418                                         CFG_CURRENT_LIMIT_USB_MASK, ret);
 419                if (ret < 0)
 420                        return ret;
 421        }
 422
 423        return 0;
 424}
 425
 426static int smb347_set_voltage_limits(struct smb347_charger *smb)
 427{
 428        int ret;
 429
 430        if (smb->pdata->pre_to_fast_voltage) {
 431                ret = smb->pdata->pre_to_fast_voltage;
 432
 433                /* uV */
 434                ret = clamp_val(ret, 2400000, 3000000) - 2400000;
 435                ret /= 200000;
 436
 437                ret = regmap_update_bits(smb->regmap, CFG_FLOAT_VOLTAGE,
 438                                CFG_FLOAT_VOLTAGE_THRESHOLD_MASK,
 439                                ret << CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT);
 440                if (ret < 0)
 441                        return ret;
 442        }
 443
 444        if (smb->pdata->max_charge_voltage) {
 445                ret = smb->pdata->max_charge_voltage;
 446
 447                /* uV */
 448                ret = clamp_val(ret, 3500000, 4500000) - 3500000;
 449                ret /= 20000;
 450
 451                ret = regmap_update_bits(smb->regmap, CFG_FLOAT_VOLTAGE,
 452                                         CFG_FLOAT_VOLTAGE_FLOAT_MASK, ret);
 453                if (ret < 0)
 454                        return ret;
 455        }
 456
 457        return 0;
 458}
 459
 460static int smb347_set_temp_limits(struct smb347_charger *smb)
 461{
 462        bool enable_therm_monitor = false;
 463        int ret = 0;
 464        int val;
 465
 466        if (smb->pdata->chip_temp_threshold) {
 467                val = smb->pdata->chip_temp_threshold;
 468
 469                /* degree C */
 470                val = clamp_val(val, 100, 130) - 100;
 471                val /= 10;
 472
 473                ret = regmap_update_bits(smb->regmap, CFG_OTG,
 474                                         CFG_OTG_TEMP_THRESHOLD_MASK,
 475                                         val << CFG_OTG_TEMP_THRESHOLD_SHIFT);
 476                if (ret < 0)
 477                        return ret;
 478        }
 479
 480        if (smb->pdata->soft_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) {
 481                val = smb->pdata->soft_cold_temp_limit;
 482
 483                val = clamp_val(val, 0, 15);
 484                val /= 5;
 485                /* this goes from higher to lower so invert the value */
 486                val = ~val & 0x3;
 487
 488                ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT,
 489                                         CFG_TEMP_LIMIT_SOFT_COLD_MASK,
 490                                         val << CFG_TEMP_LIMIT_SOFT_COLD_SHIFT);
 491                if (ret < 0)
 492                        return ret;
 493
 494                enable_therm_monitor = true;
 495        }
 496
 497        if (smb->pdata->soft_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) {
 498                val = smb->pdata->soft_hot_temp_limit;
 499
 500                val = clamp_val(val, 40, 55) - 40;
 501                val /= 5;
 502
 503                ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT,
 504                                         CFG_TEMP_LIMIT_SOFT_HOT_MASK,
 505                                         val << CFG_TEMP_LIMIT_SOFT_HOT_SHIFT);
 506                if (ret < 0)
 507                        return ret;
 508
 509                enable_therm_monitor = true;
 510        }
 511
 512        if (smb->pdata->hard_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) {
 513                val = smb->pdata->hard_cold_temp_limit;
 514
 515                val = clamp_val(val, -5, 10) + 5;
 516                val /= 5;
 517                /* this goes from higher to lower so invert the value */
 518                val = ~val & 0x3;
 519
 520                ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT,
 521                                         CFG_TEMP_LIMIT_HARD_COLD_MASK,
 522                                         val << CFG_TEMP_LIMIT_HARD_COLD_SHIFT);
 523                if (ret < 0)
 524                        return ret;
 525
 526                enable_therm_monitor = true;
 527        }
 528
 529        if (smb->pdata->hard_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) {
 530                val = smb->pdata->hard_hot_temp_limit;
 531
 532                val = clamp_val(val, 50, 65) - 50;
 533                val /= 5;
 534
 535                ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT,
 536                                         CFG_TEMP_LIMIT_HARD_HOT_MASK,
 537                                         val << CFG_TEMP_LIMIT_HARD_HOT_SHIFT);
 538                if (ret < 0)
 539                        return ret;
 540
 541                enable_therm_monitor = true;
 542        }
 543
 544        /*
 545         * If any of the temperature limits are set, we also enable the
 546         * thermistor monitoring.
 547         *
 548         * When soft limits are hit, the device will start to compensate
 549         * current and/or voltage depending on the configuration.
 550         *
 551         * When hard limit is hit, the device will suspend charging
 552         * depending on the configuration.
 553         */
 554        if (enable_therm_monitor) {
 555                ret = regmap_update_bits(smb->regmap, CFG_THERM,
 556                                         CFG_THERM_MONITOR_DISABLED, 0);
 557                if (ret < 0)
 558                        return ret;
 559        }
 560
 561        if (smb->pdata->suspend_on_hard_temp_limit) {
 562                ret = regmap_update_bits(smb->regmap, CFG_SYSOK,
 563                                 CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED, 0);
 564                if (ret < 0)
 565                        return ret;
 566        }
 567
 568        if (smb->pdata->soft_temp_limit_compensation !=
 569            SMB347_SOFT_TEMP_COMPENSATE_DEFAULT) {
 570                val = smb->pdata->soft_temp_limit_compensation & 0x3;
 571
 572                ret = regmap_update_bits(smb->regmap, CFG_THERM,
 573                                 CFG_THERM_SOFT_HOT_COMPENSATION_MASK,
 574                                 val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT);
 575                if (ret < 0)
 576                        return ret;
 577
 578                ret = regmap_update_bits(smb->regmap, CFG_THERM,
 579                                 CFG_THERM_SOFT_COLD_COMPENSATION_MASK,
 580                                 val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT);
 581                if (ret < 0)
 582                        return ret;
 583        }
 584
 585        if (smb->pdata->charge_current_compensation) {
 586                val = current_to_hw(ccc_tbl, ARRAY_SIZE(ccc_tbl),
 587                                    smb->pdata->charge_current_compensation);
 588                if (val < 0)
 589                        return val;
 590
 591                ret = regmap_update_bits(smb->regmap, CFG_OTG,
 592                                CFG_OTG_CC_COMPENSATION_MASK,
 593                                (val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT);
 594                if (ret < 0)
 595                        return ret;
 596        }
 597
 598        return ret;
 599}
 600
 601/*
 602 * smb347_set_writable - enables/disables writing to non-volatile registers
 603 * @smb: pointer to smb347 charger instance
 604 *
 605 * You can enable/disable writing to the non-volatile configuration
 606 * registers by calling this function.
 607 *
 608 * Returns %0 on success and negative errno in case of failure.
 609 */
 610static int smb347_set_writable(struct smb347_charger *smb, bool writable)
 611{
 612        return regmap_update_bits(smb->regmap, CMD_A, CMD_A_ALLOW_WRITE,
 613                                  writable ? CMD_A_ALLOW_WRITE : 0);
 614}
 615
 616static int smb347_hw_init(struct smb347_charger *smb)
 617{
 618        unsigned int val;
 619        int ret;
 620
 621        ret = smb347_set_writable(smb, true);
 622        if (ret < 0)
 623                return ret;
 624
 625        /*
 626         * Program the platform specific configuration values to the device
 627         * first.
 628         */
 629        ret = smb347_set_charge_current(smb);
 630        if (ret < 0)
 631                goto fail;
 632
 633        ret = smb347_set_current_limits(smb);
 634        if (ret < 0)
 635                goto fail;
 636
 637        ret = smb347_set_voltage_limits(smb);
 638        if (ret < 0)
 639                goto fail;
 640
 641        ret = smb347_set_temp_limits(smb);
 642        if (ret < 0)
 643                goto fail;
 644
 645        /* If USB charging is disabled we put the USB in suspend mode */
 646        if (!smb->pdata->use_usb) {
 647                ret = regmap_update_bits(smb->regmap, CMD_A,
 648                                         CMD_A_SUSPEND_ENABLED,
 649                                         CMD_A_SUSPEND_ENABLED);
 650                if (ret < 0)
 651                        goto fail;
 652        }
 653
 654        /*
 655         * If configured by platform data, we enable hardware Auto-OTG
 656         * support for driving VBUS. Otherwise we disable it.
 657         */
 658        ret = regmap_update_bits(smb->regmap, CFG_OTHER, CFG_OTHER_RID_MASK,
 659                smb->pdata->use_usb_otg ? CFG_OTHER_RID_ENABLED_AUTO_OTG : 0);
 660        if (ret < 0)
 661                goto fail;
 662
 663        /*
 664         * Make the charging functionality controllable by a write to the
 665         * command register unless pin control is specified in the platform
 666         * data.
 667         */
 668        switch (smb->pdata->enable_control) {
 669        case SMB347_CHG_ENABLE_PIN_ACTIVE_LOW:
 670                val = CFG_PIN_EN_CTRL_ACTIVE_LOW;
 671                break;
 672        case SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH:
 673                val = CFG_PIN_EN_CTRL_ACTIVE_HIGH;
 674                break;
 675        default:
 676                val = 0;
 677                break;
 678        }
 679
 680        ret = regmap_update_bits(smb->regmap, CFG_PIN, CFG_PIN_EN_CTRL_MASK,
 681                                 val);
 682        if (ret < 0)
 683                goto fail;
 684
 685        /* Disable Automatic Power Source Detection (APSD) interrupt. */
 686        ret = regmap_update_bits(smb->regmap, CFG_PIN, CFG_PIN_EN_APSD_IRQ, 0);
 687        if (ret < 0)
 688                goto fail;
 689
 690        ret = smb347_update_ps_status(smb);
 691        if (ret < 0)
 692                goto fail;
 693
 694        ret = smb347_start_stop_charging(smb);
 695
 696fail:
 697        smb347_set_writable(smb, false);
 698        return ret;
 699}
 700
 701static irqreturn_t smb347_interrupt(int irq, void *data)
 702{
 703        struct smb347_charger *smb = data;
 704        unsigned int stat_c, irqstat_e, irqstat_c;
 705        bool handled = false;
 706        int ret;
 707
 708        ret = regmap_read(smb->regmap, STAT_C, &stat_c);
 709        if (ret < 0) {
 710                dev_warn(smb->dev, "reading STAT_C failed\n");
 711                return IRQ_NONE;
 712        }
 713
 714        ret = regmap_read(smb->regmap, IRQSTAT_C, &irqstat_c);
 715        if (ret < 0) {
 716                dev_warn(smb->dev, "reading IRQSTAT_C failed\n");
 717                return IRQ_NONE;
 718        }
 719
 720        ret = regmap_read(smb->regmap, IRQSTAT_E, &irqstat_e);
 721        if (ret < 0) {
 722                dev_warn(smb->dev, "reading IRQSTAT_E failed\n");
 723                return IRQ_NONE;
 724        }
 725
 726        /*
 727         * If we get charger error we report the error back to user and
 728         * disable charging.
 729         */
 730        if (stat_c & STAT_C_CHARGER_ERROR) {
 731                dev_err(smb->dev, "error in charger, disabling charging\n");
 732
 733                smb347_charging_disable(smb);
 734                power_supply_changed(&smb->battery);
 735                handled = true;
 736        }
 737
 738        /*
 739         * If we reached the termination current the battery is charged and
 740         * we can update the status now. Charging is automatically
 741         * disabled by the hardware.
 742         */
 743        if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) {
 744                if (irqstat_c & IRQSTAT_C_TERMINATION_STAT)
 745                        power_supply_changed(&smb->battery);
 746                handled = true;
 747        }
 748
 749        /*
 750         * If we got an under voltage interrupt it means that AC/USB input
 751         * was connected or disconnected.
 752         */
 753        if (irqstat_e & (IRQSTAT_E_USBIN_UV_IRQ | IRQSTAT_E_DCIN_UV_IRQ)) {
 754                if (smb347_update_ps_status(smb) > 0) {
 755                        smb347_start_stop_charging(smb);
 756                        if (smb->pdata->use_mains)
 757                                power_supply_changed(&smb->mains);
 758                        if (smb->pdata->use_usb)
 759                                power_supply_changed(&smb->usb);
 760                }
 761                handled = true;
 762        }
 763
 764        return handled ? IRQ_HANDLED : IRQ_NONE;
 765}
 766
 767static int smb347_irq_set(struct smb347_charger *smb, bool enable)
 768{
 769        int ret;
 770
 771        ret = smb347_set_writable(smb, true);
 772        if (ret < 0)
 773                return ret;
 774
 775        /*
 776         * Enable/disable interrupts for:
 777         *      - under voltage
 778         *      - termination current reached
 779         *      - charger error
 780         */
 781        ret = regmap_update_bits(smb->regmap, CFG_FAULT_IRQ, 0xff,
 782                                 enable ? CFG_FAULT_IRQ_DCIN_UV : 0);
 783        if (ret < 0)
 784                goto fail;
 785
 786        ret = regmap_update_bits(smb->regmap, CFG_STATUS_IRQ, 0xff,
 787                        enable ? CFG_STATUS_IRQ_TERMINATION_OR_TAPER : 0);
 788        if (ret < 0)
 789                goto fail;
 790
 791        ret = regmap_update_bits(smb->regmap, CFG_PIN, CFG_PIN_EN_CHARGER_ERROR,
 792                                 enable ? CFG_PIN_EN_CHARGER_ERROR : 0);
 793fail:
 794        smb347_set_writable(smb, false);
 795        return ret;
 796}
 797
 798static inline int smb347_irq_enable(struct smb347_charger *smb)
 799{
 800        return smb347_irq_set(smb, true);
 801}
 802
 803static inline int smb347_irq_disable(struct smb347_charger *smb)
 804{
 805        return smb347_irq_set(smb, false);
 806}
 807
 808static int smb347_irq_init(struct smb347_charger *smb,
 809                           struct i2c_client *client)
 810{
 811        const struct smb347_charger_platform_data *pdata = smb->pdata;
 812        int ret, irq = gpio_to_irq(pdata->irq_gpio);
 813
 814        ret = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name);
 815        if (ret < 0)
 816                goto fail;
 817
 818        ret = request_threaded_irq(irq, NULL, smb347_interrupt,
 819                                   IRQF_TRIGGER_FALLING, client->name, smb);
 820        if (ret < 0)
 821                goto fail_gpio;
 822
 823        ret = smb347_set_writable(smb, true);
 824        if (ret < 0)
 825                goto fail_irq;
 826
 827        /*
 828         * Configure the STAT output to be suitable for interrupts: disable
 829         * all other output (except interrupts) and make it active low.
 830         */
 831        ret = regmap_update_bits(smb->regmap, CFG_STAT,
 832                                 CFG_STAT_ACTIVE_HIGH | CFG_STAT_DISABLED,
 833                                 CFG_STAT_DISABLED);
 834        if (ret < 0)
 835                goto fail_readonly;
 836
 837        smb347_set_writable(smb, false);
 838        client->irq = irq;
 839        return 0;
 840
 841fail_readonly:
 842        smb347_set_writable(smb, false);
 843fail_irq:
 844        free_irq(irq, smb);
 845fail_gpio:
 846        gpio_free(pdata->irq_gpio);
 847fail:
 848        client->irq = 0;
 849        return ret;
 850}
 851
 852/*
 853 * Returns the constant charge current programmed
 854 * into the charger in uA.
 855 */
 856static int get_const_charge_current(struct smb347_charger *smb)
 857{
 858        int ret, intval;
 859        unsigned int v;
 860
 861        if (!smb347_is_ps_online(smb))
 862                return -ENODATA;
 863
 864        ret = regmap_read(smb->regmap, STAT_B, &v);
 865        if (ret < 0)
 866                return ret;
 867
 868        /*
 869         * The current value is composition of FCC and PCC values
 870         * and we can detect which table to use from bit 5.
 871         */
 872        if (v & 0x20) {
 873                intval = hw_to_current(fcc_tbl, ARRAY_SIZE(fcc_tbl), v & 7);
 874        } else {
 875                v >>= 3;
 876                intval = hw_to_current(pcc_tbl, ARRAY_SIZE(pcc_tbl), v & 7);
 877        }
 878
 879        return intval;
 880}
 881
 882/*
 883 * Returns the constant charge voltage programmed
 884 * into the charger in uV.
 885 */
 886static int get_const_charge_voltage(struct smb347_charger *smb)
 887{
 888        int ret, intval;
 889        unsigned int v;
 890
 891        if (!smb347_is_ps_online(smb))
 892                return -ENODATA;
 893
 894        ret = regmap_read(smb->regmap, STAT_A, &v);
 895        if (ret < 0)
 896                return ret;
 897
 898        v &= STAT_A_FLOAT_VOLTAGE_MASK;
 899        if (v > 0x3d)
 900                v = 0x3d;
 901
 902        intval = 3500000 + v * 20000;
 903
 904        return intval;
 905}
 906
 907static int smb347_mains_get_property(struct power_supply *psy,
 908                                     enum power_supply_property prop,
 909                                     union power_supply_propval *val)
 910{
 911        struct smb347_charger *smb =
 912                container_of(psy, struct smb347_charger, mains);
 913        int ret;
 914
 915        switch (prop) {
 916        case POWER_SUPPLY_PROP_ONLINE:
 917                val->intval = smb->mains_online;
 918                break;
 919
 920        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 921                ret = get_const_charge_voltage(smb);
 922                if (ret < 0)
 923                        return ret;
 924                else
 925                        val->intval = ret;
 926                break;
 927
 928        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 929                ret = get_const_charge_current(smb);
 930                if (ret < 0)
 931                        return ret;
 932                else
 933                        val->intval = ret;
 934                break;
 935
 936        default:
 937                return -EINVAL;
 938        }
 939
 940        return 0;
 941}
 942
 943static enum power_supply_property smb347_mains_properties[] = {
 944        POWER_SUPPLY_PROP_ONLINE,
 945        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
 946        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
 947};
 948
 949static int smb347_usb_get_property(struct power_supply *psy,
 950                                   enum power_supply_property prop,
 951                                   union power_supply_propval *val)
 952{
 953        struct smb347_charger *smb =
 954                container_of(psy, struct smb347_charger, usb);
 955        int ret;
 956
 957        switch (prop) {
 958        case POWER_SUPPLY_PROP_ONLINE:
 959                val->intval = smb->usb_online;
 960                break;
 961
 962        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 963                ret = get_const_charge_voltage(smb);
 964                if (ret < 0)
 965                        return ret;
 966                else
 967                        val->intval = ret;
 968                break;
 969
 970        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 971                ret = get_const_charge_current(smb);
 972                if (ret < 0)
 973                        return ret;
 974                else
 975                        val->intval = ret;
 976                break;
 977
 978        default:
 979                return -EINVAL;
 980        }
 981
 982        return 0;
 983}
 984
 985static enum power_supply_property smb347_usb_properties[] = {
 986        POWER_SUPPLY_PROP_ONLINE,
 987        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
 988        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
 989};
 990
 991static int smb347_battery_get_property(struct power_supply *psy,
 992                                       enum power_supply_property prop,
 993                                       union power_supply_propval *val)
 994{
 995        struct smb347_charger *smb =
 996                        container_of(psy, struct smb347_charger, battery);
 997        const struct smb347_charger_platform_data *pdata = smb->pdata;
 998        int ret;
 999
1000        ret = smb347_update_ps_status(smb);
1001        if (ret < 0)
1002                return ret;
1003
1004        switch (prop) {
1005        case POWER_SUPPLY_PROP_STATUS:
1006                if (!smb347_is_ps_online(smb)) {
1007                        val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
1008                        break;
1009                }
1010                if (smb347_charging_status(smb))
1011                        val->intval = POWER_SUPPLY_STATUS_CHARGING;
1012                else
1013                        val->intval = POWER_SUPPLY_STATUS_FULL;
1014                break;
1015
1016        case POWER_SUPPLY_PROP_CHARGE_TYPE:
1017                if (!smb347_is_ps_online(smb))
1018                        return -ENODATA;
1019
1020                /*
1021                 * We handle trickle and pre-charging the same, and taper
1022                 * and none the same.
1023                 */
1024                switch (smb347_charging_status(smb)) {
1025                case 1:
1026                        val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
1027                        break;
1028                case 2:
1029                        val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
1030                        break;
1031                default:
1032                        val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
1033                        break;
1034                }
1035                break;
1036
1037        case POWER_SUPPLY_PROP_TECHNOLOGY:
1038                val->intval = pdata->battery_info.technology;
1039                break;
1040
1041        case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
1042                val->intval = pdata->battery_info.voltage_min_design;
1043                break;
1044
1045        case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
1046                val->intval = pdata->battery_info.voltage_max_design;
1047                break;
1048
1049        case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
1050                val->intval = pdata->battery_info.charge_full_design;
1051                break;
1052
1053        case POWER_SUPPLY_PROP_MODEL_NAME:
1054                val->strval = pdata->battery_info.name;
1055                break;
1056
1057        default:
1058                return -EINVAL;
1059        }
1060
1061        return 0;
1062}
1063
1064static enum power_supply_property smb347_battery_properties[] = {
1065        POWER_SUPPLY_PROP_STATUS,
1066        POWER_SUPPLY_PROP_CHARGE_TYPE,
1067        POWER_SUPPLY_PROP_TECHNOLOGY,
1068        POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
1069        POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
1070        POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
1071        POWER_SUPPLY_PROP_MODEL_NAME,
1072};
1073
1074static bool smb347_volatile_reg(struct device *dev, unsigned int reg)
1075{
1076        switch (reg) {
1077        case IRQSTAT_A:
1078        case IRQSTAT_C:
1079        case IRQSTAT_E:
1080        case IRQSTAT_F:
1081        case STAT_A:
1082        case STAT_B:
1083        case STAT_C:
1084        case STAT_E:
1085                return true;
1086        }
1087
1088        return false;
1089}
1090
1091static bool smb347_readable_reg(struct device *dev, unsigned int reg)
1092{
1093        switch (reg) {
1094        case CFG_CHARGE_CURRENT:
1095        case CFG_CURRENT_LIMIT:
1096        case CFG_FLOAT_VOLTAGE:
1097        case CFG_STAT:
1098        case CFG_PIN:
1099        case CFG_THERM:
1100        case CFG_SYSOK:
1101        case CFG_OTHER:
1102        case CFG_OTG:
1103        case CFG_TEMP_LIMIT:
1104        case CFG_FAULT_IRQ:
1105        case CFG_STATUS_IRQ:
1106        case CFG_ADDRESS:
1107        case CMD_A:
1108        case CMD_B:
1109        case CMD_C:
1110                return true;
1111        }
1112
1113        return smb347_volatile_reg(dev, reg);
1114}
1115
1116static const struct regmap_config smb347_regmap = {
1117        .reg_bits       = 8,
1118        .val_bits       = 8,
1119        .max_register   = SMB347_MAX_REGISTER,
1120        .volatile_reg   = smb347_volatile_reg,
1121        .readable_reg   = smb347_readable_reg,
1122};
1123
1124static int smb347_probe(struct i2c_client *client,
1125                        const struct i2c_device_id *id)
1126{
1127        static char *battery[] = { "smb347-battery" };
1128        const struct smb347_charger_platform_data *pdata;
1129        struct device *dev = &client->dev;
1130        struct smb347_charger *smb;
1131        int ret;
1132
1133        pdata = dev->platform_data;
1134        if (!pdata)
1135                return -EINVAL;
1136
1137        if (!pdata->use_mains && !pdata->use_usb)
1138                return -EINVAL;
1139
1140        smb = devm_kzalloc(dev, sizeof(*smb), GFP_KERNEL);
1141        if (!smb)
1142                return -ENOMEM;
1143
1144        i2c_set_clientdata(client, smb);
1145
1146        mutex_init(&smb->lock);
1147        smb->dev = &client->dev;
1148        smb->pdata = pdata;
1149
1150        smb->regmap = devm_regmap_init_i2c(client, &smb347_regmap);
1151        if (IS_ERR(smb->regmap))
1152                return PTR_ERR(smb->regmap);
1153
1154        ret = smb347_hw_init(smb);
1155        if (ret < 0)
1156                return ret;
1157
1158        if (smb->pdata->use_mains) {
1159                smb->mains.name = "smb347-mains";
1160                smb->mains.type = POWER_SUPPLY_TYPE_MAINS;
1161                smb->mains.get_property = smb347_mains_get_property;
1162                smb->mains.properties = smb347_mains_properties;
1163                smb->mains.num_properties = ARRAY_SIZE(smb347_mains_properties);
1164                smb->mains.supplied_to = battery;
1165                smb->mains.num_supplicants = ARRAY_SIZE(battery);
1166                ret = power_supply_register(dev, &smb->mains);
1167                if (ret < 0)
1168                        return ret;
1169        }
1170
1171        if (smb->pdata->use_usb) {
1172                smb->usb.name = "smb347-usb";
1173                smb->usb.type = POWER_SUPPLY_TYPE_USB;
1174                smb->usb.get_property = smb347_usb_get_property;
1175                smb->usb.properties = smb347_usb_properties;
1176                smb->usb.num_properties = ARRAY_SIZE(smb347_usb_properties);
1177                smb->usb.supplied_to = battery;
1178                smb->usb.num_supplicants = ARRAY_SIZE(battery);
1179                ret = power_supply_register(dev, &smb->usb);
1180                if (ret < 0) {
1181                        if (smb->pdata->use_mains)
1182                                power_supply_unregister(&smb->mains);
1183                        return ret;
1184                }
1185        }
1186
1187        smb->battery.name = "smb347-battery";
1188        smb->battery.type = POWER_SUPPLY_TYPE_BATTERY;
1189        smb->battery.get_property = smb347_battery_get_property;
1190        smb->battery.properties = smb347_battery_properties;
1191        smb->battery.num_properties = ARRAY_SIZE(smb347_battery_properties);
1192
1193
1194        ret = power_supply_register(dev, &smb->battery);
1195        if (ret < 0) {
1196                if (smb->pdata->use_usb)
1197                        power_supply_unregister(&smb->usb);
1198                if (smb->pdata->use_mains)
1199                        power_supply_unregister(&smb->mains);
1200                return ret;
1201        }
1202
1203        /*
1204         * Interrupt pin is optional. If it is connected, we setup the
1205         * interrupt support here.
1206         */
1207        if (pdata->irq_gpio >= 0) {
1208                ret = smb347_irq_init(smb, client);
1209                if (ret < 0) {
1210                        dev_warn(dev, "failed to initialize IRQ: %d\n", ret);
1211                        dev_warn(dev, "disabling IRQ support\n");
1212                } else {
1213                        smb347_irq_enable(smb);
1214                }
1215        }
1216
1217        return 0;
1218}
1219
1220static int smb347_remove(struct i2c_client *client)
1221{
1222        struct smb347_charger *smb = i2c_get_clientdata(client);
1223
1224        if (client->irq) {
1225                smb347_irq_disable(smb);
1226                free_irq(client->irq, smb);
1227                gpio_free(smb->pdata->irq_gpio);
1228        }
1229
1230        power_supply_unregister(&smb->battery);
1231        if (smb->pdata->use_usb)
1232                power_supply_unregister(&smb->usb);
1233        if (smb->pdata->use_mains)
1234                power_supply_unregister(&smb->mains);
1235        return 0;
1236}
1237
1238static const struct i2c_device_id smb347_id[] = {
1239        { "smb347", 0 },
1240        { }
1241};
1242MODULE_DEVICE_TABLE(i2c, smb347_id);
1243
1244static struct i2c_driver smb347_driver = {
1245        .driver = {
1246                .name = "smb347",
1247        },
1248        .probe        = smb347_probe,
1249        .remove       = __devexit_p(smb347_remove),
1250        .id_table     = smb347_id,
1251};
1252
1253module_i2c_driver(smb347_driver);
1254
1255MODULE_AUTHOR("Bruce E. Robertson <bruce.e.robertson@intel.com>");
1256MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
1257MODULE_DESCRIPTION("SMB347 battery charger driver");
1258MODULE_LICENSE("GPL");
1259MODULE_ALIAS("i2c:smb347");
1260
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.