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