linux/drivers/power/bq24190_charger.c
<<
>>
Prefs
   1/*
   2 * Driver for the TI bq24190 battery charger.
   3 *
   4 * Author: Mark A. Greer <mgreer@animalcreek.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/interrupt.h>
  13#include <linux/delay.h>
  14#include <linux/of_irq.h>
  15#include <linux/of_device.h>
  16#include <linux/pm_runtime.h>
  17#include <linux/power_supply.h>
  18#include <linux/gpio.h>
  19#include <linux/i2c.h>
  20
  21#include <linux/power/bq24190_charger.h>
  22
  23
  24#define BQ24190_MANUFACTURER    "Texas Instruments"
  25
  26#define BQ24190_REG_ISC         0x00 /* Input Source Control */
  27#define BQ24190_REG_ISC_EN_HIZ_MASK             BIT(7)
  28#define BQ24190_REG_ISC_EN_HIZ_SHIFT            7
  29#define BQ24190_REG_ISC_VINDPM_MASK             (BIT(6) | BIT(5) | BIT(4) | \
  30                                                 BIT(3))
  31#define BQ24190_REG_ISC_VINDPM_SHIFT            3
  32#define BQ24190_REG_ISC_IINLIM_MASK             (BIT(2) | BIT(1) | BIT(0))
  33#define BQ24190_REG_ISC_IINLIM_SHIFT            0
  34
  35#define BQ24190_REG_POC         0x01 /* Power-On Configuration */
  36#define BQ24190_REG_POC_RESET_MASK              BIT(7)
  37#define BQ24190_REG_POC_RESET_SHIFT             7
  38#define BQ24190_REG_POC_WDT_RESET_MASK          BIT(6)
  39#define BQ24190_REG_POC_WDT_RESET_SHIFT         6
  40#define BQ24190_REG_POC_CHG_CONFIG_MASK         (BIT(5) | BIT(4))
  41#define BQ24190_REG_POC_CHG_CONFIG_SHIFT        4
  42#define BQ24190_REG_POC_SYS_MIN_MASK            (BIT(3) | BIT(2) | BIT(1))
  43#define BQ24190_REG_POC_SYS_MIN_SHIFT           1
  44#define BQ24190_REG_POC_BOOST_LIM_MASK          BIT(0)
  45#define BQ24190_REG_POC_BOOST_LIM_SHIFT         0
  46
  47#define BQ24190_REG_CCC         0x02 /* Charge Current Control */
  48#define BQ24190_REG_CCC_ICHG_MASK               (BIT(7) | BIT(6) | BIT(5) | \
  49                                                 BIT(4) | BIT(3) | BIT(2))
  50#define BQ24190_REG_CCC_ICHG_SHIFT              2
  51#define BQ24190_REG_CCC_FORCE_20PCT_MASK        BIT(0)
  52#define BQ24190_REG_CCC_FORCE_20PCT_SHIFT       0
  53
  54#define BQ24190_REG_PCTCC       0x03 /* Pre-charge/Termination Current Cntl */
  55#define BQ24190_REG_PCTCC_IPRECHG_MASK          (BIT(7) | BIT(6) | BIT(5) | \
  56                                                 BIT(4))
  57#define BQ24190_REG_PCTCC_IPRECHG_SHIFT         4
  58#define BQ24190_REG_PCTCC_ITERM_MASK            (BIT(3) | BIT(2) | BIT(1) | \
  59                                                 BIT(0))
  60#define BQ24190_REG_PCTCC_ITERM_SHIFT           0
  61
  62#define BQ24190_REG_CVC         0x04 /* Charge Voltage Control */
  63#define BQ24190_REG_CVC_VREG_MASK               (BIT(7) | BIT(6) | BIT(5) | \
  64                                                 BIT(4) | BIT(3) | BIT(2))
  65#define BQ24190_REG_CVC_VREG_SHIFT              2
  66#define BQ24190_REG_CVC_BATLOWV_MASK            BIT(1)
  67#define BQ24190_REG_CVC_BATLOWV_SHIFT           1
  68#define BQ24190_REG_CVC_VRECHG_MASK             BIT(0)
  69#define BQ24190_REG_CVC_VRECHG_SHIFT            0
  70
  71#define BQ24190_REG_CTTC        0x05 /* Charge Term/Timer Control */
  72#define BQ24190_REG_CTTC_EN_TERM_MASK           BIT(7)
  73#define BQ24190_REG_CTTC_EN_TERM_SHIFT          7
  74#define BQ24190_REG_CTTC_TERM_STAT_MASK         BIT(6)
  75#define BQ24190_REG_CTTC_TERM_STAT_SHIFT        6
  76#define BQ24190_REG_CTTC_WATCHDOG_MASK          (BIT(5) | BIT(4))
  77#define BQ24190_REG_CTTC_WATCHDOG_SHIFT         4
  78#define BQ24190_REG_CTTC_EN_TIMER_MASK          BIT(3)
  79#define BQ24190_REG_CTTC_EN_TIMER_SHIFT         3
  80#define BQ24190_REG_CTTC_CHG_TIMER_MASK         (BIT(2) | BIT(1))
  81#define BQ24190_REG_CTTC_CHG_TIMER_SHIFT        1
  82#define BQ24190_REG_CTTC_JEITA_ISET_MASK        BIT(0)
  83#define BQ24190_REG_CTTC_JEITA_ISET_SHIFT       0
  84
  85#define BQ24190_REG_ICTRC       0x06 /* IR Comp/Thermal Regulation Control */
  86#define BQ24190_REG_ICTRC_BAT_COMP_MASK         (BIT(7) | BIT(6) | BIT(5))
  87#define BQ24190_REG_ICTRC_BAT_COMP_SHIFT        5
  88#define BQ24190_REG_ICTRC_VCLAMP_MASK           (BIT(4) | BIT(3) | BIT(2))
  89#define BQ24190_REG_ICTRC_VCLAMP_SHIFT          2
  90#define BQ24190_REG_ICTRC_TREG_MASK             (BIT(1) | BIT(0))
  91#define BQ24190_REG_ICTRC_TREG_SHIFT            0
  92
  93#define BQ24190_REG_MOC         0x07 /* Misc. Operation Control */
  94#define BQ24190_REG_MOC_DPDM_EN_MASK            BIT(7)
  95#define BQ24190_REG_MOC_DPDM_EN_SHIFT           7
  96#define BQ24190_REG_MOC_TMR2X_EN_MASK           BIT(6)
  97#define BQ24190_REG_MOC_TMR2X_EN_SHIFT          6
  98#define BQ24190_REG_MOC_BATFET_DISABLE_MASK     BIT(5)
  99#define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT    5
 100#define BQ24190_REG_MOC_JEITA_VSET_MASK         BIT(4)
 101#define BQ24190_REG_MOC_JEITA_VSET_SHIFT        4
 102#define BQ24190_REG_MOC_INT_MASK_MASK           (BIT(1) | BIT(0))
 103#define BQ24190_REG_MOC_INT_MASK_SHIFT          0
 104
 105#define BQ24190_REG_SS          0x08 /* System Status */
 106#define BQ24190_REG_SS_VBUS_STAT_MASK           (BIT(7) | BIT(6))
 107#define BQ24190_REG_SS_VBUS_STAT_SHIFT          6
 108#define BQ24190_REG_SS_CHRG_STAT_MASK           (BIT(5) | BIT(4))
 109#define BQ24190_REG_SS_CHRG_STAT_SHIFT          4
 110#define BQ24190_REG_SS_DPM_STAT_MASK            BIT(3)
 111#define BQ24190_REG_SS_DPM_STAT_SHIFT           3
 112#define BQ24190_REG_SS_PG_STAT_MASK             BIT(2)
 113#define BQ24190_REG_SS_PG_STAT_SHIFT            2
 114#define BQ24190_REG_SS_THERM_STAT_MASK          BIT(1)
 115#define BQ24190_REG_SS_THERM_STAT_SHIFT         1
 116#define BQ24190_REG_SS_VSYS_STAT_MASK           BIT(0)
 117#define BQ24190_REG_SS_VSYS_STAT_SHIFT          0
 118
 119#define BQ24190_REG_F           0x09 /* Fault */
 120#define BQ24190_REG_F_WATCHDOG_FAULT_MASK       BIT(7)
 121#define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT      7
 122#define BQ24190_REG_F_BOOST_FAULT_MASK          BIT(6)
 123#define BQ24190_REG_F_BOOST_FAULT_SHIFT         6
 124#define BQ24190_REG_F_CHRG_FAULT_MASK           (BIT(5) | BIT(4))
 125#define BQ24190_REG_F_CHRG_FAULT_SHIFT          4
 126#define BQ24190_REG_F_BAT_FAULT_MASK            BIT(3)
 127#define BQ24190_REG_F_BAT_FAULT_SHIFT           3
 128#define BQ24190_REG_F_NTC_FAULT_MASK            (BIT(2) | BIT(1) | BIT(0))
 129#define BQ24190_REG_F_NTC_FAULT_SHIFT           0
 130
 131#define BQ24190_REG_VPRS        0x0A /* Vendor/Part/Revision Status */
 132#define BQ24190_REG_VPRS_PN_MASK                (BIT(5) | BIT(4) | BIT(3))
 133#define BQ24190_REG_VPRS_PN_SHIFT               3
 134#define BQ24190_REG_VPRS_PN_24190                       0x4
 135#define BQ24190_REG_VPRS_PN_24192                       0x5 /* Also 24193 */
 136#define BQ24190_REG_VPRS_PN_24192I                      0x3
 137#define BQ24190_REG_VPRS_TS_PROFILE_MASK        BIT(2)
 138#define BQ24190_REG_VPRS_TS_PROFILE_SHIFT       2
 139#define BQ24190_REG_VPRS_DEV_REG_MASK           (BIT(1) | BIT(0))
 140#define BQ24190_REG_VPRS_DEV_REG_SHIFT          0
 141
 142/*
 143 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
 144 * so the first read after a fault returns the latched value and subsequent
 145 * reads return the current value.  In order to return the fault status
 146 * to the user, have the interrupt handler save the reg's value and retrieve
 147 * it in the appropriate health/status routine.  Each routine has its own
 148 * flag indicating whether it should use the value stored by the last run
 149 * of the interrupt handler or do an actual reg read.  That way each routine
 150 * can report back whatever fault may have occured.
 151 */
 152struct bq24190_dev_info {
 153        struct i2c_client               *client;
 154        struct device                   *dev;
 155        struct power_supply             *charger;
 156        struct power_supply             *battery;
 157        char                            model_name[I2C_NAME_SIZE];
 158        kernel_ulong_t                  model;
 159        unsigned int                    gpio_int;
 160        unsigned int                    irq;
 161        struct mutex                    f_reg_lock;
 162        bool                            first_time;
 163        bool                            charger_health_valid;
 164        bool                            battery_health_valid;
 165        bool                            battery_status_valid;
 166        u8                              f_reg;
 167        u8                              ss_reg;
 168        u8                              watchdog;
 169};
 170
 171/*
 172 * The tables below provide a 2-way mapping for the value that goes in
 173 * the register field and the real-world value that it represents.
 174 * The index of the array is the value that goes in the register; the
 175 * number at that index in the array is the real-world value that it
 176 * represents.
 177 */
 178/* REG02[7:2] (ICHG) in uAh */
 179static const int bq24190_ccc_ichg_values[] = {
 180         512000,  576000,  640000,  704000,  768000,  832000,  896000,  960000,
 181        1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
 182        1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
 183        2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
 184        2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
 185        3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
 186        3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
 187        4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
 188};
 189
 190/* REG04[7:2] (VREG) in uV */
 191static const int bq24190_cvc_vreg_values[] = {
 192        3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
 193        3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
 194        3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
 195        3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
 196        4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
 197        4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
 198        4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
 199        4400000
 200};
 201
 202/* REG06[1:0] (TREG) in tenths of degrees Celcius */
 203static const int bq24190_ictrc_treg_values[] = {
 204        600, 800, 1000, 1200
 205};
 206
 207/*
 208 * Return the index in 'tbl' of greatest value that is less than or equal to
 209 * 'val'.  The index range returned is 0 to 'tbl_size' - 1.  Assumes that
 210 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
 211 * is less than 2^8.
 212 */
 213static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
 214{
 215        int i;
 216
 217        for (i = 1; i < tbl_size; i++)
 218                if (v < tbl[i])
 219                        break;
 220
 221        return i - 1;
 222}
 223
 224/* Basic driver I/O routines */
 225
 226static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
 227{
 228        int ret;
 229
 230        ret = i2c_smbus_read_byte_data(bdi->client, reg);
 231        if (ret < 0)
 232                return ret;
 233
 234        *data = ret;
 235        return 0;
 236}
 237
 238static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
 239{
 240        return i2c_smbus_write_byte_data(bdi->client, reg, data);
 241}
 242
 243static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
 244                u8 mask, u8 shift, u8 *data)
 245{
 246        u8 v;
 247        int ret;
 248
 249        ret = bq24190_read(bdi, reg, &v);
 250        if (ret < 0)
 251                return ret;
 252
 253        v &= mask;
 254        v >>= shift;
 255        *data = v;
 256
 257        return 0;
 258}
 259
 260static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
 261                u8 mask, u8 shift, u8 data)
 262{
 263        u8 v;
 264        int ret;
 265
 266        ret = bq24190_read(bdi, reg, &v);
 267        if (ret < 0)
 268                return ret;
 269
 270        v &= ~mask;
 271        v |= ((data << shift) & mask);
 272
 273        return bq24190_write(bdi, reg, v);
 274}
 275
 276static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
 277                u8 reg, u8 mask, u8 shift,
 278                const int tbl[], int tbl_size,
 279                int *val)
 280{
 281        u8 v;
 282        int ret;
 283
 284        ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
 285        if (ret < 0)
 286                return ret;
 287
 288        v = (v >= tbl_size) ? (tbl_size - 1) : v;
 289        *val = tbl[v];
 290
 291        return 0;
 292}
 293
 294static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
 295                u8 reg, u8 mask, u8 shift,
 296                const int tbl[], int tbl_size,
 297                int val)
 298{
 299        u8 idx;
 300
 301        idx = bq24190_find_idx(tbl, tbl_size, val);
 302
 303        return bq24190_write_mask(bdi, reg, mask, shift, idx);
 304}
 305
 306#ifdef CONFIG_SYSFS
 307/*
 308 * There are a numerous options that are configurable on the bq24190
 309 * that go well beyond what the power_supply properties provide access to.
 310 * Provide sysfs access to them so they can be examined and possibly modified
 311 * on the fly.  They will be provided for the charger power_supply object only
 312 * and will be prefixed by 'f_' to make them easier to recognize.
 313 */
 314
 315#define BQ24190_SYSFS_FIELD(_name, r, f, m, store)                      \
 316{                                                                       \
 317        .attr   = __ATTR(f_##_name, m, bq24190_sysfs_show, store),      \
 318        .reg    = BQ24190_REG_##r,                                      \
 319        .mask   = BQ24190_REG_##r##_##f##_MASK,                         \
 320        .shift  = BQ24190_REG_##r##_##f##_SHIFT,                        \
 321}
 322
 323#define BQ24190_SYSFS_FIELD_RW(_name, r, f)                             \
 324                BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO,     \
 325                                bq24190_sysfs_store)
 326
 327#define BQ24190_SYSFS_FIELD_RO(_name, r, f)                             \
 328                BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
 329
 330static ssize_t bq24190_sysfs_show(struct device *dev,
 331                struct device_attribute *attr, char *buf);
 332static ssize_t bq24190_sysfs_store(struct device *dev,
 333                struct device_attribute *attr, const char *buf, size_t count);
 334
 335struct bq24190_sysfs_field_info {
 336        struct device_attribute attr;
 337        u8      reg;
 338        u8      mask;
 339        u8      shift;
 340};
 341
 342/* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
 343#undef SS
 344
 345static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
 346                        /*      sysfs name      reg     field in reg */
 347        BQ24190_SYSFS_FIELD_RW(en_hiz,          ISC,    EN_HIZ),
 348        BQ24190_SYSFS_FIELD_RW(vindpm,          ISC,    VINDPM),
 349        BQ24190_SYSFS_FIELD_RW(iinlim,          ISC,    IINLIM),
 350        BQ24190_SYSFS_FIELD_RW(chg_config,      POC,    CHG_CONFIG),
 351        BQ24190_SYSFS_FIELD_RW(sys_min,         POC,    SYS_MIN),
 352        BQ24190_SYSFS_FIELD_RW(boost_lim,       POC,    BOOST_LIM),
 353        BQ24190_SYSFS_FIELD_RW(ichg,            CCC,    ICHG),
 354        BQ24190_SYSFS_FIELD_RW(force_20_pct,    CCC,    FORCE_20PCT),
 355        BQ24190_SYSFS_FIELD_RW(iprechg,         PCTCC,  IPRECHG),
 356        BQ24190_SYSFS_FIELD_RW(iterm,           PCTCC,  ITERM),
 357        BQ24190_SYSFS_FIELD_RW(vreg,            CVC,    VREG),
 358        BQ24190_SYSFS_FIELD_RW(batlowv,         CVC,    BATLOWV),
 359        BQ24190_SYSFS_FIELD_RW(vrechg,          CVC,    VRECHG),
 360        BQ24190_SYSFS_FIELD_RW(en_term,         CTTC,   EN_TERM),
 361        BQ24190_SYSFS_FIELD_RW(term_stat,       CTTC,   TERM_STAT),
 362        BQ24190_SYSFS_FIELD_RO(watchdog,        CTTC,   WATCHDOG),
 363        BQ24190_SYSFS_FIELD_RW(en_timer,        CTTC,   EN_TIMER),
 364        BQ24190_SYSFS_FIELD_RW(chg_timer,       CTTC,   CHG_TIMER),
 365        BQ24190_SYSFS_FIELD_RW(jeta_iset,       CTTC,   JEITA_ISET),
 366        BQ24190_SYSFS_FIELD_RW(bat_comp,        ICTRC,  BAT_COMP),
 367        BQ24190_SYSFS_FIELD_RW(vclamp,          ICTRC,  VCLAMP),
 368        BQ24190_SYSFS_FIELD_RW(treg,            ICTRC,  TREG),
 369        BQ24190_SYSFS_FIELD_RW(dpdm_en,         MOC,    DPDM_EN),
 370        BQ24190_SYSFS_FIELD_RW(tmr2x_en,        MOC,    TMR2X_EN),
 371        BQ24190_SYSFS_FIELD_RW(batfet_disable,  MOC,    BATFET_DISABLE),
 372        BQ24190_SYSFS_FIELD_RW(jeita_vset,      MOC,    JEITA_VSET),
 373        BQ24190_SYSFS_FIELD_RO(int_mask,        MOC,    INT_MASK),
 374        BQ24190_SYSFS_FIELD_RO(vbus_stat,       SS,     VBUS_STAT),
 375        BQ24190_SYSFS_FIELD_RO(chrg_stat,       SS,     CHRG_STAT),
 376        BQ24190_SYSFS_FIELD_RO(dpm_stat,        SS,     DPM_STAT),
 377        BQ24190_SYSFS_FIELD_RO(pg_stat,         SS,     PG_STAT),
 378        BQ24190_SYSFS_FIELD_RO(therm_stat,      SS,     THERM_STAT),
 379        BQ24190_SYSFS_FIELD_RO(vsys_stat,       SS,     VSYS_STAT),
 380        BQ24190_SYSFS_FIELD_RO(watchdog_fault,  F,      WATCHDOG_FAULT),
 381        BQ24190_SYSFS_FIELD_RO(boost_fault,     F,      BOOST_FAULT),
 382        BQ24190_SYSFS_FIELD_RO(chrg_fault,      F,      CHRG_FAULT),
 383        BQ24190_SYSFS_FIELD_RO(bat_fault,       F,      BAT_FAULT),
 384        BQ24190_SYSFS_FIELD_RO(ntc_fault,       F,      NTC_FAULT),
 385        BQ24190_SYSFS_FIELD_RO(pn,              VPRS,   PN),
 386        BQ24190_SYSFS_FIELD_RO(ts_profile,      VPRS,   TS_PROFILE),
 387        BQ24190_SYSFS_FIELD_RO(dev_reg,         VPRS,   DEV_REG),
 388};
 389
 390static struct attribute *
 391        bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
 392
 393static const struct attribute_group bq24190_sysfs_attr_group = {
 394        .attrs = bq24190_sysfs_attrs,
 395};
 396
 397static void bq24190_sysfs_init_attrs(void)
 398{
 399        int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
 400
 401        for (i = 0; i < limit; i++)
 402                bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
 403
 404        bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
 405}
 406
 407static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
 408                const char *name)
 409{
 410        int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
 411
 412        for (i = 0; i < limit; i++)
 413                if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
 414                        break;
 415
 416        if (i >= limit)
 417                return NULL;
 418
 419        return &bq24190_sysfs_field_tbl[i];
 420}
 421
 422static ssize_t bq24190_sysfs_show(struct device *dev,
 423                struct device_attribute *attr, char *buf)
 424{
 425        struct power_supply *psy = dev_get_drvdata(dev);
 426        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
 427        struct bq24190_sysfs_field_info *info;
 428        int ret;
 429        u8 v;
 430
 431        info = bq24190_sysfs_field_lookup(attr->attr.name);
 432        if (!info)
 433                return -EINVAL;
 434
 435        ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
 436        if (ret)
 437                return ret;
 438
 439        return scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
 440}
 441
 442static ssize_t bq24190_sysfs_store(struct device *dev,
 443                struct device_attribute *attr, const char *buf, size_t count)
 444{
 445        struct power_supply *psy = dev_get_drvdata(dev);
 446        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
 447        struct bq24190_sysfs_field_info *info;
 448        int ret;
 449        u8 v;
 450
 451        info = bq24190_sysfs_field_lookup(attr->attr.name);
 452        if (!info)
 453                return -EINVAL;
 454
 455        ret = kstrtou8(buf, 0, &v);
 456        if (ret < 0)
 457                return ret;
 458
 459        ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
 460        if (ret)
 461                return ret;
 462
 463        return count;
 464}
 465
 466static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
 467{
 468        bq24190_sysfs_init_attrs();
 469
 470        return sysfs_create_group(&bdi->charger->dev.kobj,
 471                        &bq24190_sysfs_attr_group);
 472}
 473
 474static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi)
 475{
 476        sysfs_remove_group(&bdi->charger->dev.kobj, &bq24190_sysfs_attr_group);
 477}
 478#else
 479static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
 480{
 481        return 0;
 482}
 483
 484static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {}
 485#endif
 486
 487/*
 488 * According to the "Host Mode and default Mode" section of the
 489 * manual, a write to any register causes the bq24190 to switch
 490 * from default mode to host mode.  It will switch back to default
 491 * mode after a WDT timeout unless the WDT is turned off as well.
 492 * So, by simply turning off the WDT, we accomplish both with the
 493 * same write.
 494 */
 495static int bq24190_set_mode_host(struct bq24190_dev_info *bdi)
 496{
 497        int ret;
 498        u8 v;
 499
 500        ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
 501        if (ret < 0)
 502                return ret;
 503
 504        bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
 505                                        BQ24190_REG_CTTC_WATCHDOG_SHIFT);
 506        v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
 507
 508        return bq24190_write(bdi, BQ24190_REG_CTTC, v);
 509}
 510
 511static int bq24190_register_reset(struct bq24190_dev_info *bdi)
 512{
 513        int ret, limit = 100;
 514        u8 v;
 515
 516        /* Reset the registers */
 517        ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 518                        BQ24190_REG_POC_RESET_MASK,
 519                        BQ24190_REG_POC_RESET_SHIFT,
 520                        0x1);
 521        if (ret < 0)
 522                return ret;
 523
 524        /* Reset bit will be cleared by hardware so poll until it is */
 525        do {
 526                ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 527                                BQ24190_REG_POC_RESET_MASK,
 528                                BQ24190_REG_POC_RESET_SHIFT,
 529                                &v);
 530                if (ret < 0)
 531                        return ret;
 532
 533                if (!v)
 534                        break;
 535
 536                udelay(10);
 537        } while (--limit);
 538
 539        if (!limit)
 540                return -EIO;
 541
 542        return 0;
 543}
 544
 545/* Charger power supply property routines */
 546
 547static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
 548                union power_supply_propval *val)
 549{
 550        u8 v;
 551        int type, ret;
 552
 553        ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 554                        BQ24190_REG_POC_CHG_CONFIG_MASK,
 555                        BQ24190_REG_POC_CHG_CONFIG_SHIFT,
 556                        &v);
 557        if (ret < 0)
 558                return ret;
 559
 560        /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
 561        if (!v) {
 562                type = POWER_SUPPLY_CHARGE_TYPE_NONE;
 563        } else {
 564                ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 565                                BQ24190_REG_CCC_FORCE_20PCT_MASK,
 566                                BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 567                                &v);
 568                if (ret < 0)
 569                        return ret;
 570
 571                type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
 572                             POWER_SUPPLY_CHARGE_TYPE_FAST;
 573        }
 574
 575        val->intval = type;
 576
 577        return 0;
 578}
 579
 580static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
 581                const union power_supply_propval *val)
 582{
 583        u8 chg_config, force_20pct, en_term;
 584        int ret;
 585
 586        /*
 587         * According to the "Termination when REG02[0] = 1" section of
 588         * the bq24190 manual, the trickle charge could be less than the
 589         * termination current so it recommends turning off the termination
 590         * function.
 591         *
 592         * Note: AFAICT from the datasheet, the user will have to manually
 593         * turn off the charging when in 20% mode.  If its not turned off,
 594         * there could be battery damage.  So, use this mode at your own risk.
 595         */
 596        switch (val->intval) {
 597        case POWER_SUPPLY_CHARGE_TYPE_NONE:
 598                chg_config = 0x0;
 599                break;
 600        case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
 601                chg_config = 0x1;
 602                force_20pct = 0x1;
 603                en_term = 0x0;
 604                break;
 605        case POWER_SUPPLY_CHARGE_TYPE_FAST:
 606                chg_config = 0x1;
 607                force_20pct = 0x0;
 608                en_term = 0x1;
 609                break;
 610        default:
 611                return -EINVAL;
 612        }
 613
 614        if (chg_config) { /* Enabling the charger */
 615                ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
 616                                BQ24190_REG_CCC_FORCE_20PCT_MASK,
 617                                BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 618                                force_20pct);
 619                if (ret < 0)
 620                        return ret;
 621
 622                ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
 623                                BQ24190_REG_CTTC_EN_TERM_MASK,
 624                                BQ24190_REG_CTTC_EN_TERM_SHIFT,
 625                                en_term);
 626                if (ret < 0)
 627                        return ret;
 628        }
 629
 630        return bq24190_write_mask(bdi, BQ24190_REG_POC,
 631                        BQ24190_REG_POC_CHG_CONFIG_MASK,
 632                        BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
 633}
 634
 635static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
 636                union power_supply_propval *val)
 637{
 638        u8 v;
 639        int health, ret;
 640
 641        mutex_lock(&bdi->f_reg_lock);
 642
 643        if (bdi->charger_health_valid) {
 644                v = bdi->f_reg;
 645                bdi->charger_health_valid = false;
 646                mutex_unlock(&bdi->f_reg_lock);
 647        } else {
 648                mutex_unlock(&bdi->f_reg_lock);
 649
 650                ret = bq24190_read(bdi, BQ24190_REG_F, &v);
 651                if (ret < 0)
 652                        return ret;
 653        }
 654
 655        if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
 656                /*
 657                 * This could be over-current or over-voltage but there's
 658                 * no way to tell which.  Return 'OVERVOLTAGE' since there
 659                 * isn't an 'OVERCURRENT' value defined that we can return
 660                 * even if it was over-current.
 661                 */
 662                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
 663        } else {
 664                v &= BQ24190_REG_F_CHRG_FAULT_MASK;
 665                v >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
 666
 667                switch (v) {
 668                case 0x0: /* Normal */
 669                        health = POWER_SUPPLY_HEALTH_GOOD;
 670                        break;
 671                case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
 672                        /*
 673                         * This could be over-voltage or under-voltage
 674                         * and there's no way to tell which.  Instead
 675                         * of looking foolish and returning 'OVERVOLTAGE'
 676                         * when its really under-voltage, just return
 677                         * 'UNSPEC_FAILURE'.
 678                         */
 679                        health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
 680                        break;
 681                case 0x2: /* Thermal Shutdown */
 682                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
 683                        break;
 684                case 0x3: /* Charge Safety Timer Expiration */
 685                        health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
 686                        break;
 687                default:
 688                        health = POWER_SUPPLY_HEALTH_UNKNOWN;
 689                }
 690        }
 691
 692        val->intval = health;
 693
 694        return 0;
 695}
 696
 697static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
 698                union power_supply_propval *val)
 699{
 700        u8 v;
 701        int ret;
 702
 703        ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
 704                        BQ24190_REG_SS_PG_STAT_MASK,
 705                        BQ24190_REG_SS_PG_STAT_SHIFT, &v);
 706        if (ret < 0)
 707                return ret;
 708
 709        val->intval = v;
 710        return 0;
 711}
 712
 713static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
 714                union power_supply_propval *val)
 715{
 716        u8 v;
 717        int curr, ret;
 718
 719        ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
 720                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
 721                        bq24190_ccc_ichg_values,
 722                        ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
 723        if (ret < 0)
 724                return ret;
 725
 726        ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 727                        BQ24190_REG_CCC_FORCE_20PCT_MASK,
 728                        BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 729        if (ret < 0)
 730                return ret;
 731
 732        /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
 733        if (v)
 734                curr /= 5;
 735
 736        val->intval = curr;
 737        return 0;
 738}
 739
 740static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
 741                union power_supply_propval *val)
 742{
 743        int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
 744
 745        val->intval = bq24190_ccc_ichg_values[idx];
 746        return 0;
 747}
 748
 749static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
 750                const union power_supply_propval *val)
 751{
 752        u8 v;
 753        int ret, curr = val->intval;
 754
 755        ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 756                        BQ24190_REG_CCC_FORCE_20PCT_MASK,
 757                        BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 758        if (ret < 0)
 759                return ret;
 760
 761        /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
 762        if (v)
 763                curr *= 5;
 764
 765        return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
 766                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
 767                        bq24190_ccc_ichg_values,
 768                        ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
 769}
 770
 771static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
 772                union power_supply_propval *val)
 773{
 774        int voltage, ret;
 775
 776        ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
 777                        BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
 778                        bq24190_cvc_vreg_values,
 779                        ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
 780        if (ret < 0)
 781                return ret;
 782
 783        val->intval = voltage;
 784        return 0;
 785}
 786
 787static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
 788                union power_supply_propval *val)
 789{
 790        int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
 791
 792        val->intval = bq24190_cvc_vreg_values[idx];
 793        return 0;
 794}
 795
 796static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
 797                const union power_supply_propval *val)
 798{
 799        return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
 800                        BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
 801                        bq24190_cvc_vreg_values,
 802                        ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
 803}
 804
 805static int bq24190_charger_get_property(struct power_supply *psy,
 806                enum power_supply_property psp, union power_supply_propval *val)
 807{
 808        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
 809        int ret;
 810
 811        dev_dbg(bdi->dev, "prop: %d\n", psp);
 812
 813        pm_runtime_get_sync(bdi->dev);
 814
 815        switch (psp) {
 816        case POWER_SUPPLY_PROP_CHARGE_TYPE:
 817                ret = bq24190_charger_get_charge_type(bdi, val);
 818                break;
 819        case POWER_SUPPLY_PROP_HEALTH:
 820                ret = bq24190_charger_get_health(bdi, val);
 821                break;
 822        case POWER_SUPPLY_PROP_ONLINE:
 823                ret = bq24190_charger_get_online(bdi, val);
 824                break;
 825        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 826                ret = bq24190_charger_get_current(bdi, val);
 827                break;
 828        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
 829                ret = bq24190_charger_get_current_max(bdi, val);
 830                break;
 831        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 832                ret = bq24190_charger_get_voltage(bdi, val);
 833                break;
 834        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
 835                ret = bq24190_charger_get_voltage_max(bdi, val);
 836                break;
 837        case POWER_SUPPLY_PROP_SCOPE:
 838                val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
 839                ret = 0;
 840                break;
 841        case POWER_SUPPLY_PROP_MODEL_NAME:
 842                val->strval = bdi->model_name;
 843                ret = 0;
 844                break;
 845        case POWER_SUPPLY_PROP_MANUFACTURER:
 846                val->strval = BQ24190_MANUFACTURER;
 847                ret = 0;
 848                break;
 849        default:
 850                ret = -ENODATA;
 851        }
 852
 853        pm_runtime_put_sync(bdi->dev);
 854        return ret;
 855}
 856
 857static int bq24190_charger_set_property(struct power_supply *psy,
 858                enum power_supply_property psp,
 859                const union power_supply_propval *val)
 860{
 861        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
 862        int ret;
 863
 864        dev_dbg(bdi->dev, "prop: %d\n", psp);
 865
 866        pm_runtime_get_sync(bdi->dev);
 867
 868        switch (psp) {
 869        case POWER_SUPPLY_PROP_CHARGE_TYPE:
 870                ret = bq24190_charger_set_charge_type(bdi, val);
 871                break;
 872        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 873                ret = bq24190_charger_set_current(bdi, val);
 874                break;
 875        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 876                ret = bq24190_charger_set_voltage(bdi, val);
 877                break;
 878        default:
 879                ret = -EINVAL;
 880        }
 881
 882        pm_runtime_put_sync(bdi->dev);
 883        return ret;
 884}
 885
 886static int bq24190_charger_property_is_writeable(struct power_supply *psy,
 887                enum power_supply_property psp)
 888{
 889        int ret;
 890
 891        switch (psp) {
 892        case POWER_SUPPLY_PROP_CHARGE_TYPE:
 893        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 894        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 895                ret = 1;
 896                break;
 897        default:
 898                ret = 0;
 899        }
 900
 901        return ret;
 902}
 903
 904static enum power_supply_property bq24190_charger_properties[] = {
 905        POWER_SUPPLY_PROP_TYPE,
 906        POWER_SUPPLY_PROP_HEALTH,
 907        POWER_SUPPLY_PROP_ONLINE,
 908        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
 909        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
 910        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
 911        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
 912        POWER_SUPPLY_PROP_SCOPE,
 913        POWER_SUPPLY_PROP_MODEL_NAME,
 914        POWER_SUPPLY_PROP_MANUFACTURER,
 915};
 916
 917static char *bq24190_charger_supplied_to[] = {
 918        "main-battery",
 919};
 920
 921static const struct power_supply_desc bq24190_charger_desc = {
 922        .name                   = "bq24190-charger",
 923        .type                   = POWER_SUPPLY_TYPE_USB,
 924        .properties             = bq24190_charger_properties,
 925        .num_properties         = ARRAY_SIZE(bq24190_charger_properties),
 926        .get_property           = bq24190_charger_get_property,
 927        .set_property           = bq24190_charger_set_property,
 928        .property_is_writeable  = bq24190_charger_property_is_writeable,
 929};
 930
 931/* Battery power supply property routines */
 932
 933static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
 934                union power_supply_propval *val)
 935{
 936        u8 ss_reg, chrg_fault;
 937        int status, ret;
 938
 939        mutex_lock(&bdi->f_reg_lock);
 940
 941        if (bdi->battery_status_valid) {
 942                chrg_fault = bdi->f_reg;
 943                bdi->battery_status_valid = false;
 944                mutex_unlock(&bdi->f_reg_lock);
 945        } else {
 946                mutex_unlock(&bdi->f_reg_lock);
 947
 948                ret = bq24190_read(bdi, BQ24190_REG_F, &chrg_fault);
 949                if (ret < 0)
 950                        return ret;
 951        }
 952
 953        chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
 954        chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
 955
 956        ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
 957        if (ret < 0)
 958                return ret;
 959
 960        /*
 961         * The battery must be discharging when any of these are true:
 962         * - there is no good power source;
 963         * - there is a charge fault.
 964         * Could also be discharging when in "supplement mode" but
 965         * there is no way to tell when its in that mode.
 966         */
 967        if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
 968                status = POWER_SUPPLY_STATUS_DISCHARGING;
 969        } else {
 970                ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
 971                ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
 972
 973                switch (ss_reg) {
 974                case 0x0: /* Not Charging */
 975                        status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 976                        break;
 977                case 0x1: /* Pre-charge */
 978                case 0x2: /* Fast Charging */
 979                        status = POWER_SUPPLY_STATUS_CHARGING;
 980                        break;
 981                case 0x3: /* Charge Termination Done */
 982                        status = POWER_SUPPLY_STATUS_FULL;
 983                        break;
 984                default:
 985                        ret = -EIO;
 986                }
 987        }
 988
 989        if (!ret)
 990                val->intval = status;
 991
 992        return ret;
 993}
 994
 995static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
 996                union power_supply_propval *val)
 997{
 998        u8 v;
 999        int health, ret;
1000
1001        mutex_lock(&bdi->f_reg_lock);
1002
1003        if (bdi->battery_health_valid) {
1004                v = bdi->f_reg;
1005                bdi->battery_health_valid = false;
1006                mutex_unlock(&bdi->f_reg_lock);
1007        } else {
1008                mutex_unlock(&bdi->f_reg_lock);
1009
1010                ret = bq24190_read(bdi, BQ24190_REG_F, &v);
1011                if (ret < 0)
1012                        return ret;
1013        }
1014
1015        if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1016                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1017        } else {
1018                v &= BQ24190_REG_F_NTC_FAULT_MASK;
1019                v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1020
1021                switch (v) {
1022                case 0x0: /* Normal */
1023                        health = POWER_SUPPLY_HEALTH_GOOD;
1024                        break;
1025                case 0x1: /* TS1 Cold */
1026                case 0x3: /* TS2 Cold */
1027                case 0x5: /* Both Cold */
1028                        health = POWER_SUPPLY_HEALTH_COLD;
1029                        break;
1030                case 0x2: /* TS1 Hot */
1031                case 0x4: /* TS2 Hot */
1032                case 0x6: /* Both Hot */
1033                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
1034                        break;
1035                default:
1036                        health = POWER_SUPPLY_HEALTH_UNKNOWN;
1037                }
1038        }
1039
1040        val->intval = health;
1041        return 0;
1042}
1043
1044static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1045                union power_supply_propval *val)
1046{
1047        u8 batfet_disable;
1048        int ret;
1049
1050        ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1051                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1052                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1053        if (ret < 0)
1054                return ret;
1055
1056        val->intval = !batfet_disable;
1057        return 0;
1058}
1059
1060static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1061                const union power_supply_propval *val)
1062{
1063        return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1064                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1065                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1066}
1067
1068static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1069                union power_supply_propval *val)
1070{
1071        int temp, ret;
1072
1073        ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1074                        BQ24190_REG_ICTRC_TREG_MASK,
1075                        BQ24190_REG_ICTRC_TREG_SHIFT,
1076                        bq24190_ictrc_treg_values,
1077                        ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1078        if (ret < 0)
1079                return ret;
1080
1081        val->intval = temp;
1082        return 0;
1083}
1084
1085static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1086                const union power_supply_propval *val)
1087{
1088        return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1089                        BQ24190_REG_ICTRC_TREG_MASK,
1090                        BQ24190_REG_ICTRC_TREG_SHIFT,
1091                        bq24190_ictrc_treg_values,
1092                        ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1093}
1094
1095static int bq24190_battery_get_property(struct power_supply *psy,
1096                enum power_supply_property psp, union power_supply_propval *val)
1097{
1098        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1099        int ret;
1100
1101        dev_dbg(bdi->dev, "prop: %d\n", psp);
1102
1103        pm_runtime_get_sync(bdi->dev);
1104
1105        switch (psp) {
1106        case POWER_SUPPLY_PROP_STATUS:
1107                ret = bq24190_battery_get_status(bdi, val);
1108                break;
1109        case POWER_SUPPLY_PROP_HEALTH:
1110                ret = bq24190_battery_get_health(bdi, val);
1111                break;
1112        case POWER_SUPPLY_PROP_ONLINE:
1113                ret = bq24190_battery_get_online(bdi, val);
1114                break;
1115        case POWER_SUPPLY_PROP_TECHNOLOGY:
1116                /* Could be Li-on or Li-polymer but no way to tell which */
1117                val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1118                ret = 0;
1119                break;
1120        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1121                ret = bq24190_battery_get_temp_alert_max(bdi, val);
1122                break;
1123        case POWER_SUPPLY_PROP_SCOPE:
1124                val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1125                ret = 0;
1126                break;
1127        default:
1128                ret = -ENODATA;
1129        }
1130
1131        pm_runtime_put_sync(bdi->dev);
1132        return ret;
1133}
1134
1135static int bq24190_battery_set_property(struct power_supply *psy,
1136                enum power_supply_property psp,
1137                const union power_supply_propval *val)
1138{
1139        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1140        int ret;
1141
1142        dev_dbg(bdi->dev, "prop: %d\n", psp);
1143
1144        pm_runtime_put_sync(bdi->dev);
1145
1146        switch (psp) {
1147        case POWER_SUPPLY_PROP_ONLINE:
1148                ret = bq24190_battery_set_online(bdi, val);
1149                break;
1150        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1151                ret = bq24190_battery_set_temp_alert_max(bdi, val);
1152                break;
1153        default:
1154                ret = -EINVAL;
1155        }
1156
1157        pm_runtime_put_sync(bdi->dev);
1158        return ret;
1159}
1160
1161static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1162                enum power_supply_property psp)
1163{
1164        int ret;
1165
1166        switch (psp) {
1167        case POWER_SUPPLY_PROP_ONLINE:
1168        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1169                ret = 1;
1170                break;
1171        default:
1172                ret = 0;
1173        }
1174
1175        return ret;
1176}
1177
1178static enum power_supply_property bq24190_battery_properties[] = {
1179        POWER_SUPPLY_PROP_STATUS,
1180        POWER_SUPPLY_PROP_HEALTH,
1181        POWER_SUPPLY_PROP_ONLINE,
1182        POWER_SUPPLY_PROP_TECHNOLOGY,
1183        POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1184        POWER_SUPPLY_PROP_SCOPE,
1185};
1186
1187static const struct power_supply_desc bq24190_battery_desc = {
1188        .name                   = "bq24190-battery",
1189        .type                   = POWER_SUPPLY_TYPE_BATTERY,
1190        .properties             = bq24190_battery_properties,
1191        .num_properties         = ARRAY_SIZE(bq24190_battery_properties),
1192        .get_property           = bq24190_battery_get_property,
1193        .set_property           = bq24190_battery_set_property,
1194        .property_is_writeable  = bq24190_battery_property_is_writeable,
1195};
1196
1197static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1198{
1199        struct bq24190_dev_info *bdi = data;
1200        bool alert_userspace = false;
1201        u8 ss_reg = 0, f_reg = 0;
1202        int ret;
1203
1204        pm_runtime_get_sync(bdi->dev);
1205
1206        ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1207        if (ret < 0) {
1208                dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1209                goto out;
1210        }
1211
1212        if (ss_reg != bdi->ss_reg) {
1213                /*
1214                 * The device is in host mode so when PG_STAT goes from 1->0
1215                 * (i.e., power removed) HIZ needs to be disabled.
1216                 */
1217                if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1218                                !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1219                        ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1220                                        BQ24190_REG_ISC_EN_HIZ_MASK,
1221                                        BQ24190_REG_ISC_EN_HIZ_SHIFT,
1222                                        0);
1223                        if (ret < 0)
1224                                dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1225                                        ret);
1226                }
1227
1228                bdi->ss_reg = ss_reg;
1229                alert_userspace = true;
1230        }
1231
1232        mutex_lock(&bdi->f_reg_lock);
1233
1234        ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1235        if (ret < 0) {
1236                mutex_unlock(&bdi->f_reg_lock);
1237                dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1238                goto out;
1239        }
1240
1241        if (f_reg != bdi->f_reg) {
1242                bdi->f_reg = f_reg;
1243                bdi->charger_health_valid = true;
1244                bdi->battery_health_valid = true;
1245                bdi->battery_status_valid = true;
1246
1247                alert_userspace = true;
1248        }
1249
1250        mutex_unlock(&bdi->f_reg_lock);
1251
1252        /*
1253         * Sometimes bq24190 gives a steady trickle of interrupts even
1254         * though the watchdog timer is turned off and neither the STATUS
1255         * nor FAULT registers have changed.  Weed out these sprurious
1256         * interrupts so userspace isn't alerted for no reason.
1257         * In addition, the chip always generates an interrupt after
1258         * register reset so we should ignore that one (the very first
1259         * interrupt received).
1260         */
1261        if (alert_userspace && !bdi->first_time) {
1262                power_supply_changed(bdi->charger);
1263                power_supply_changed(bdi->battery);
1264                bdi->first_time = false;
1265        }
1266
1267out:
1268        pm_runtime_put_sync(bdi->dev);
1269
1270        dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1271
1272        return IRQ_HANDLED;
1273}
1274
1275static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1276{
1277        u8 v;
1278        int ret;
1279
1280        pm_runtime_get_sync(bdi->dev);
1281
1282        /* First check that the device really is what its supposed to be */
1283        ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1284                        BQ24190_REG_VPRS_PN_MASK,
1285                        BQ24190_REG_VPRS_PN_SHIFT,
1286                        &v);
1287        if (ret < 0)
1288                goto out;
1289
1290        if (v != bdi->model) {
1291                ret = -ENODEV;
1292                goto out;
1293        }
1294
1295        ret = bq24190_register_reset(bdi);
1296        if (ret < 0)
1297                goto out;
1298
1299        ret = bq24190_set_mode_host(bdi);
1300out:
1301        pm_runtime_put_sync(bdi->dev);
1302        return ret;
1303}
1304
1305#ifdef CONFIG_OF
1306static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1307{
1308        bdi->irq = irq_of_parse_and_map(bdi->dev->of_node, 0);
1309        if (bdi->irq <= 0)
1310                return -1;
1311
1312        return 0;
1313}
1314#else
1315static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1316{
1317        return -1;
1318}
1319#endif
1320
1321static int bq24190_setup_pdata(struct bq24190_dev_info *bdi,
1322                struct bq24190_platform_data *pdata)
1323{
1324        int ret;
1325
1326        if (!gpio_is_valid(pdata->gpio_int))
1327                return -1;
1328
1329        ret = gpio_request(pdata->gpio_int, dev_name(bdi->dev));
1330        if (ret < 0)
1331                return -1;
1332
1333        ret = gpio_direction_input(pdata->gpio_int);
1334        if (ret < 0)
1335                goto out;
1336
1337        bdi->irq = gpio_to_irq(pdata->gpio_int);
1338        if (!bdi->irq)
1339                goto out;
1340
1341        bdi->gpio_int = pdata->gpio_int;
1342        return 0;
1343
1344out:
1345        gpio_free(pdata->gpio_int);
1346        return -1;
1347}
1348
1349static int bq24190_probe(struct i2c_client *client,
1350                const struct i2c_device_id *id)
1351{
1352        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1353        struct device *dev = &client->dev;
1354        struct bq24190_platform_data *pdata = client->dev.platform_data;
1355        struct power_supply_config charger_cfg = {}, battery_cfg = {};
1356        struct bq24190_dev_info *bdi;
1357        int ret;
1358
1359        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1360                dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1361                return -ENODEV;
1362        }
1363
1364        bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1365        if (!bdi) {
1366                dev_err(dev, "Can't alloc bdi struct\n");
1367                return -ENOMEM;
1368        }
1369
1370        bdi->client = client;
1371        bdi->dev = dev;
1372        bdi->model = id->driver_data;
1373        strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1374        mutex_init(&bdi->f_reg_lock);
1375        bdi->first_time = true;
1376        bdi->charger_health_valid = false;
1377        bdi->battery_health_valid = false;
1378        bdi->battery_status_valid = false;
1379
1380        i2c_set_clientdata(client, bdi);
1381
1382        if (dev->of_node)
1383                ret = bq24190_setup_dt(bdi);
1384        else
1385                ret = bq24190_setup_pdata(bdi, pdata);
1386
1387        if (ret) {
1388                dev_err(dev, "Can't get irq info\n");
1389                return -EINVAL;
1390        }
1391
1392        ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
1393                        bq24190_irq_handler_thread,
1394                        IRQF_TRIGGER_RISING | IRQF_ONESHOT,
1395                        "bq24190-charger", bdi);
1396        if (ret < 0) {
1397                dev_err(dev, "Can't set up irq handler\n");
1398                goto out1;
1399        }
1400
1401        pm_runtime_enable(dev);
1402        pm_runtime_resume(dev);
1403
1404        ret = bq24190_hw_init(bdi);
1405        if (ret < 0) {
1406                dev_err(dev, "Hardware init failed\n");
1407                goto out2;
1408        }
1409
1410        charger_cfg.drv_data = bdi;
1411        charger_cfg.supplied_to = bq24190_charger_supplied_to;
1412        charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1413        bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1414                                                &charger_cfg);
1415        if (IS_ERR(bdi->charger)) {
1416                dev_err(dev, "Can't register charger\n");
1417                ret = PTR_ERR(bdi->charger);
1418                goto out2;
1419        }
1420
1421        battery_cfg.drv_data = bdi;
1422        bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1423                                                &battery_cfg);
1424        if (IS_ERR(bdi->battery)) {
1425                dev_err(dev, "Can't register battery\n");
1426                ret = PTR_ERR(bdi->battery);
1427                goto out3;
1428        }
1429
1430        ret = bq24190_sysfs_create_group(bdi);
1431        if (ret) {
1432                dev_err(dev, "Can't create sysfs entries\n");
1433                goto out4;
1434        }
1435
1436        return 0;
1437
1438out4:
1439        power_supply_unregister(bdi->battery);
1440out3:
1441        power_supply_unregister(bdi->charger);
1442out2:
1443        pm_runtime_disable(dev);
1444out1:
1445        if (bdi->gpio_int)
1446                gpio_free(bdi->gpio_int);
1447
1448        return ret;
1449}
1450
1451static int bq24190_remove(struct i2c_client *client)
1452{
1453        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1454
1455        pm_runtime_get_sync(bdi->dev);
1456        bq24190_register_reset(bdi);
1457        pm_runtime_put_sync(bdi->dev);
1458
1459        bq24190_sysfs_remove_group(bdi);
1460        power_supply_unregister(bdi->battery);
1461        power_supply_unregister(bdi->charger);
1462        pm_runtime_disable(bdi->dev);
1463
1464        if (bdi->gpio_int)
1465                gpio_free(bdi->gpio_int);
1466
1467        return 0;
1468}
1469
1470#ifdef CONFIG_PM_SLEEP
1471static int bq24190_pm_suspend(struct device *dev)
1472{
1473        struct i2c_client *client = to_i2c_client(dev);
1474        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1475
1476        pm_runtime_get_sync(bdi->dev);
1477        bq24190_register_reset(bdi);
1478        pm_runtime_put_sync(bdi->dev);
1479
1480        return 0;
1481}
1482
1483static int bq24190_pm_resume(struct device *dev)
1484{
1485        struct i2c_client *client = to_i2c_client(dev);
1486        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1487
1488        bdi->charger_health_valid = false;
1489        bdi->battery_health_valid = false;
1490        bdi->battery_status_valid = false;
1491
1492        pm_runtime_get_sync(bdi->dev);
1493        bq24190_register_reset(bdi);
1494        pm_runtime_put_sync(bdi->dev);
1495
1496        /* Things may have changed while suspended so alert upper layer */
1497        power_supply_changed(bdi->charger);
1498        power_supply_changed(bdi->battery);
1499
1500        return 0;
1501}
1502#endif
1503
1504static SIMPLE_DEV_PM_OPS(bq24190_pm_ops, bq24190_pm_suspend, bq24190_pm_resume);
1505
1506/*
1507 * Only support the bq24190 right now.  The bq24192, bq24192i, and bq24193
1508 * are similar but not identical so the driver needs to be extended to
1509 * support them.
1510 */
1511static const struct i2c_device_id bq24190_i2c_ids[] = {
1512        { "bq24190", BQ24190_REG_VPRS_PN_24190 },
1513        { },
1514};
1515
1516#ifdef CONFIG_OF
1517static const struct of_device_id bq24190_of_match[] = {
1518        { .compatible = "ti,bq24190", },
1519        { },
1520};
1521MODULE_DEVICE_TABLE(of, bq24190_of_match);
1522#else
1523static const struct of_device_id bq24190_of_match[] = {
1524        { },
1525};
1526#endif
1527
1528static struct i2c_driver bq24190_driver = {
1529        .probe          = bq24190_probe,
1530        .remove         = bq24190_remove,
1531        .id_table       = bq24190_i2c_ids,
1532        .driver = {
1533                .name           = "bq24190-charger",
1534                .owner          = THIS_MODULE,
1535                .pm             = &bq24190_pm_ops,
1536                .of_match_table = of_match_ptr(bq24190_of_match),
1537        },
1538};
1539module_i2c_driver(bq24190_driver);
1540
1541MODULE_LICENSE("GPL");
1542MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1543MODULE_ALIAS("i2c:bq24190-charger");
1544MODULE_DESCRIPTION("TI BQ24190 Charger Driver");
1545