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 =
 427                        container_of(psy, struct bq24190_dev_info, charger);
 428        struct bq24190_sysfs_field_info *info;
 429        int ret;
 430        u8 v;
 431
 432        info = bq24190_sysfs_field_lookup(attr->attr.name);
 433        if (!info)
 434                return -EINVAL;
 435
 436        ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
 437        if (ret)
 438                return ret;
 439
 440        return scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
 441}
 442
 443static ssize_t bq24190_sysfs_store(struct device *dev,
 444                struct device_attribute *attr, const char *buf, size_t count)
 445{
 446        struct power_supply *psy = dev_get_drvdata(dev);
 447        struct bq24190_dev_info *bdi =
 448                        container_of(psy, struct bq24190_dev_info, charger);
 449        struct bq24190_sysfs_field_info *info;
 450        int ret;
 451        u8 v;
 452
 453        info = bq24190_sysfs_field_lookup(attr->attr.name);
 454        if (!info)
 455                return -EINVAL;
 456
 457        ret = kstrtou8(buf, 0, &v);
 458        if (ret < 0)
 459                return ret;
 460
 461        ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
 462        if (ret)
 463                return ret;
 464
 465        return count;
 466}
 467
 468static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
 469{
 470        bq24190_sysfs_init_attrs();
 471
 472        return sysfs_create_group(&bdi->charger.dev->kobj,
 473                        &bq24190_sysfs_attr_group);
 474}
 475
 476static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi)
 477{
 478        sysfs_remove_group(&bdi->charger.dev->kobj, &bq24190_sysfs_attr_group);
 479}
 480#else
 481static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
 482{
 483        return 0;
 484}
 485
 486static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {}
 487#endif
 488
 489/*
 490 * According to the "Host Mode and default Mode" section of the
 491 * manual, a write to any register causes the bq24190 to switch
 492 * from default mode to host mode.  It will switch back to default
 493 * mode after a WDT timeout unless the WDT is turned off as well.
 494 * So, by simply turning off the WDT, we accomplish both with the
 495 * same write.
 496 */
 497static int bq24190_set_mode_host(struct bq24190_dev_info *bdi)
 498{
 499        int ret;
 500        u8 v;
 501
 502        ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
 503        if (ret < 0)
 504                return ret;
 505
 506        bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
 507                                        BQ24190_REG_CTTC_WATCHDOG_SHIFT);
 508        v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
 509
 510        return bq24190_write(bdi, BQ24190_REG_CTTC, v);
 511}
 512
 513static int bq24190_register_reset(struct bq24190_dev_info *bdi)
 514{
 515        int ret, limit = 100;
 516        u8 v;
 517
 518        /* Reset the registers */
 519        ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 520                        BQ24190_REG_POC_RESET_MASK,
 521                        BQ24190_REG_POC_RESET_SHIFT,
 522                        0x1);
 523        if (ret < 0)
 524                return ret;
 525
 526        /* Reset bit will be cleared by hardware so poll until it is */
 527        do {
 528                ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 529                                BQ24190_REG_POC_RESET_MASK,
 530                                BQ24190_REG_POC_RESET_SHIFT,
 531                                &v);
 532                if (ret < 0)
 533                        return ret;
 534
 535                if (!v)
 536                        break;
 537
 538                udelay(10);
 539        } while (--limit);
 540
 541        if (!limit)
 542                return -EIO;
 543
 544        return 0;
 545}
 546
 547/* Charger power supply property routines */
 548
 549static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
 550                union power_supply_propval *val)
 551{
 552        u8 v;
 553        int type, ret;
 554
 555        ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 556                        BQ24190_REG_POC_CHG_CONFIG_MASK,
 557                        BQ24190_REG_POC_CHG_CONFIG_SHIFT,
 558                        &v);
 559        if (ret < 0)
 560                return ret;
 561
 562        /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
 563        if (!v) {
 564                type = POWER_SUPPLY_CHARGE_TYPE_NONE;
 565        } else {
 566                ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 567                                BQ24190_REG_CCC_FORCE_20PCT_MASK,
 568                                BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 569                                &v);
 570                if (ret < 0)
 571                        return ret;
 572
 573                type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
 574                             POWER_SUPPLY_CHARGE_TYPE_FAST;
 575        }
 576
 577        val->intval = type;
 578
 579        return 0;
 580}
 581
 582static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
 583                const union power_supply_propval *val)
 584{
 585        u8 chg_config, force_20pct, en_term;
 586        int ret;
 587
 588        /*
 589         * According to the "Termination when REG02[0] = 1" section of
 590         * the bq24190 manual, the trickle charge could be less than the
 591         * termination current so it recommends turning off the termination
 592         * function.
 593         *
 594         * Note: AFAICT from the datasheet, the user will have to manually
 595         * turn off the charging when in 20% mode.  If its not turned off,
 596         * there could be battery damage.  So, use this mode at your own risk.
 597         */
 598        switch (val->intval) {
 599        case POWER_SUPPLY_CHARGE_TYPE_NONE:
 600                chg_config = 0x0;
 601                break;
 602        case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
 603                chg_config = 0x1;
 604                force_20pct = 0x1;
 605                en_term = 0x0;
 606                break;
 607        case POWER_SUPPLY_CHARGE_TYPE_FAST:
 608                chg_config = 0x1;
 609                force_20pct = 0x0;
 610                en_term = 0x1;
 611                break;
 612        default:
 613                return -EINVAL;
 614        }
 615
 616        if (chg_config) { /* Enabling the charger */
 617                ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
 618                                BQ24190_REG_CCC_FORCE_20PCT_MASK,
 619                                BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 620                                force_20pct);
 621                if (ret < 0)
 622                        return ret;
 623
 624                ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
 625                                BQ24190_REG_CTTC_EN_TERM_MASK,
 626                                BQ24190_REG_CTTC_EN_TERM_SHIFT,
 627                                en_term);
 628                if (ret < 0)
 629                        return ret;
 630        }
 631
 632        return bq24190_write_mask(bdi, BQ24190_REG_POC,
 633                        BQ24190_REG_POC_CHG_CONFIG_MASK,
 634                        BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
 635}
 636
 637static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
 638                union power_supply_propval *val)
 639{
 640        u8 v;
 641        int health, ret;
 642
 643        mutex_lock(&bdi->f_reg_lock);
 644
 645        if (bdi->charger_health_valid) {
 646                v = bdi->f_reg;
 647                bdi->charger_health_valid = false;
 648                mutex_unlock(&bdi->f_reg_lock);
 649        } else {
 650                mutex_unlock(&bdi->f_reg_lock);
 651
 652                ret = bq24190_read(bdi, BQ24190_REG_F, &v);
 653                if (ret < 0)
 654                        return ret;
 655        }
 656
 657        if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
 658                /*
 659                 * This could be over-current or over-voltage but there's
 660                 * no way to tell which.  Return 'OVERVOLTAGE' since there
 661                 * isn't an 'OVERCURRENT' value defined that we can return
 662                 * even if it was over-current.
 663                 */
 664                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
 665        } else {
 666                v &= BQ24190_REG_F_CHRG_FAULT_MASK;
 667                v >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
 668
 669                switch (v) {
 670                case 0x0: /* Normal */
 671                        health = POWER_SUPPLY_HEALTH_GOOD;
 672                        break;
 673                case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
 674                        /*
 675                         * This could be over-voltage or under-voltage
 676                         * and there's no way to tell which.  Instead
 677                         * of looking foolish and returning 'OVERVOLTAGE'
 678                         * when its really under-voltage, just return
 679                         * 'UNSPEC_FAILURE'.
 680                         */
 681                        health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
 682                        break;
 683                case 0x2: /* Thermal Shutdown */
 684                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
 685                        break;
 686                case 0x3: /* Charge Safety Timer Expiration */
 687                        health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
 688                        break;
 689                default:
 690                        health = POWER_SUPPLY_HEALTH_UNKNOWN;
 691                }
 692        }
 693
 694        val->intval = health;
 695
 696        return 0;
 697}
 698
 699static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
 700                union power_supply_propval *val)
 701{
 702        u8 v;
 703        int ret;
 704
 705        ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
 706                        BQ24190_REG_SS_PG_STAT_MASK,
 707                        BQ24190_REG_SS_PG_STAT_SHIFT, &v);
 708        if (ret < 0)
 709                return ret;
 710
 711        val->intval = v;
 712        return 0;
 713}
 714
 715static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
 716                union power_supply_propval *val)
 717{
 718        u8 v;
 719        int curr, ret;
 720
 721        ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
 722                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
 723                        bq24190_ccc_ichg_values,
 724                        ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
 725        if (ret < 0)
 726                return ret;
 727
 728        ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 729                        BQ24190_REG_CCC_FORCE_20PCT_MASK,
 730                        BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 731        if (ret < 0)
 732                return ret;
 733
 734        /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
 735        if (v)
 736                curr /= 5;
 737
 738        val->intval = curr;
 739        return 0;
 740}
 741
 742static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
 743                union power_supply_propval *val)
 744{
 745        int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
 746
 747        val->intval = bq24190_ccc_ichg_values[idx];
 748        return 0;
 749}
 750
 751static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
 752                const union power_supply_propval *val)
 753{
 754        u8 v;
 755        int ret, curr = val->intval;
 756
 757        ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 758                        BQ24190_REG_CCC_FORCE_20PCT_MASK,
 759                        BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 760        if (ret < 0)
 761                return ret;
 762
 763        /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
 764        if (v)
 765                curr *= 5;
 766
 767        return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
 768                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
 769                        bq24190_ccc_ichg_values,
 770                        ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
 771}
 772
 773static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
 774                union power_supply_propval *val)
 775{
 776        int voltage, ret;
 777
 778        ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
 779                        BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
 780                        bq24190_cvc_vreg_values,
 781                        ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
 782        if (ret < 0)
 783                return ret;
 784
 785        val->intval = voltage;
 786        return 0;
 787}
 788
 789static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
 790                union power_supply_propval *val)
 791{
 792        int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
 793
 794        val->intval = bq24190_cvc_vreg_values[idx];
 795        return 0;
 796}
 797
 798static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
 799                const union power_supply_propval *val)
 800{
 801        return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
 802                        BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
 803                        bq24190_cvc_vreg_values,
 804                        ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
 805}
 806
 807static int bq24190_charger_get_property(struct power_supply *psy,
 808                enum power_supply_property psp, union power_supply_propval *val)
 809{
 810        struct bq24190_dev_info *bdi =
 811                        container_of(psy, struct bq24190_dev_info, charger);
 812        int ret;
 813
 814        dev_dbg(bdi->dev, "prop: %d\n", psp);
 815
 816        pm_runtime_get_sync(bdi->dev);
 817
 818        switch (psp) {
 819        case POWER_SUPPLY_PROP_CHARGE_TYPE:
 820                ret = bq24190_charger_get_charge_type(bdi, val);
 821                break;
 822        case POWER_SUPPLY_PROP_HEALTH:
 823                ret = bq24190_charger_get_health(bdi, val);
 824                break;
 825        case POWER_SUPPLY_PROP_ONLINE:
 826                ret = bq24190_charger_get_online(bdi, val);
 827                break;
 828        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 829                ret = bq24190_charger_get_current(bdi, val);
 830                break;
 831        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
 832                ret = bq24190_charger_get_current_max(bdi, val);
 833                break;
 834        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 835                ret = bq24190_charger_get_voltage(bdi, val);
 836                break;
 837        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
 838                ret = bq24190_charger_get_voltage_max(bdi, val);
 839                break;
 840        case POWER_SUPPLY_PROP_SCOPE:
 841                val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
 842                ret = 0;
 843                break;
 844        case POWER_SUPPLY_PROP_MODEL_NAME:
 845                val->strval = bdi->model_name;
 846                ret = 0;
 847                break;
 848        case POWER_SUPPLY_PROP_MANUFACTURER:
 849                val->strval = BQ24190_MANUFACTURER;
 850                ret = 0;
 851                break;
 852        default:
 853                ret = -ENODATA;
 854        }
 855
 856        pm_runtime_put_sync(bdi->dev);
 857        return ret;
 858}
 859
 860static int bq24190_charger_set_property(struct power_supply *psy,
 861                enum power_supply_property psp,
 862                const union power_supply_propval *val)
 863{
 864        struct bq24190_dev_info *bdi =
 865                        container_of(psy, struct bq24190_dev_info, charger);
 866        int ret;
 867
 868        dev_dbg(bdi->dev, "prop: %d\n", psp);
 869
 870        pm_runtime_get_sync(bdi->dev);
 871
 872        switch (psp) {
 873        case POWER_SUPPLY_PROP_CHARGE_TYPE:
 874                ret = bq24190_charger_set_charge_type(bdi, val);
 875                break;
 876        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 877                ret = bq24190_charger_set_current(bdi, val);
 878                break;
 879        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 880                ret = bq24190_charger_set_voltage(bdi, val);
 881                break;
 882        default:
 883                ret = -EINVAL;
 884        }
 885
 886        pm_runtime_put_sync(bdi->dev);
 887        return ret;
 888}
 889
 890static int bq24190_charger_property_is_writeable(struct power_supply *psy,
 891                enum power_supply_property psp)
 892{
 893        int ret;
 894
 895        switch (psp) {
 896        case POWER_SUPPLY_PROP_CHARGE_TYPE:
 897        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
 898        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
 899                ret = 1;
 900                break;
 901        default:
 902                ret = 0;
 903        }
 904
 905        return ret;
 906}
 907
 908static enum power_supply_property bq24190_charger_properties[] = {
 909        POWER_SUPPLY_PROP_TYPE,
 910        POWER_SUPPLY_PROP_HEALTH,
 911        POWER_SUPPLY_PROP_ONLINE,
 912        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
 913        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
 914        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
 915        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
 916        POWER_SUPPLY_PROP_SCOPE,
 917        POWER_SUPPLY_PROP_MODEL_NAME,
 918        POWER_SUPPLY_PROP_MANUFACTURER,
 919};
 920
 921static char *bq24190_charger_supplied_to[] = {
 922        "main-battery",
 923};
 924
 925static void bq24190_charger_init(struct power_supply *charger)
 926{
 927        charger->name = "bq24190-charger";
 928        charger->type = POWER_SUPPLY_TYPE_USB;
 929        charger->properties = bq24190_charger_properties;
 930        charger->num_properties = ARRAY_SIZE(bq24190_charger_properties);
 931        charger->supplied_to = bq24190_charger_supplied_to;
 932        charger->num_supplies = ARRAY_SIZE(bq24190_charger_supplied_to);
 933        charger->get_property = bq24190_charger_get_property;
 934        charger->set_property = bq24190_charger_set_property;
 935        charger->property_is_writeable = bq24190_charger_property_is_writeable;
 936}
 937
 938/* Battery power supply property routines */
 939
 940static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
 941                union power_supply_propval *val)
 942{
 943        u8 ss_reg, chrg_fault;
 944        int status, ret;
 945
 946        mutex_lock(&bdi->f_reg_lock);
 947
 948        if (bdi->battery_status_valid) {
 949                chrg_fault = bdi->f_reg;
 950                bdi->battery_status_valid = false;
 951                mutex_unlock(&bdi->f_reg_lock);
 952        } else {
 953                mutex_unlock(&bdi->f_reg_lock);
 954
 955                ret = bq24190_read(bdi, BQ24190_REG_F, &chrg_fault);
 956                if (ret < 0)
 957                        return ret;
 958        }
 959
 960        chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
 961        chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
 962
 963        ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
 964        if (ret < 0)
 965                return ret;
 966
 967        /*
 968         * The battery must be discharging when any of these are true:
 969         * - there is no good power source;
 970         * - there is a charge fault.
 971         * Could also be discharging when in "supplement mode" but
 972         * there is no way to tell when its in that mode.
 973         */
 974        if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
 975                status = POWER_SUPPLY_STATUS_DISCHARGING;
 976        } else {
 977                ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
 978                ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
 979
 980                switch (ss_reg) {
 981                case 0x0: /* Not Charging */
 982                        status = POWER_SUPPLY_STATUS_NOT_CHARGING;
 983                        break;
 984                case 0x1: /* Pre-charge */
 985                case 0x2: /* Fast Charging */
 986                        status = POWER_SUPPLY_STATUS_CHARGING;
 987                        break;
 988                case 0x3: /* Charge Termination Done */
 989                        status = POWER_SUPPLY_STATUS_FULL;
 990                        break;
 991                default:
 992                        ret = -EIO;
 993                }
 994        }
 995
 996        if (!ret)
 997                val->intval = status;
 998
 999        return ret;
1000}
1001
1002static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1003                union power_supply_propval *val)
1004{
1005        u8 v;
1006        int health, ret;
1007
1008        mutex_lock(&bdi->f_reg_lock);
1009
1010        if (bdi->battery_health_valid) {
1011                v = bdi->f_reg;
1012                bdi->battery_health_valid = false;
1013                mutex_unlock(&bdi->f_reg_lock);
1014        } else {
1015                mutex_unlock(&bdi->f_reg_lock);
1016
1017                ret = bq24190_read(bdi, BQ24190_REG_F, &v);
1018                if (ret < 0)
1019                        return ret;
1020        }
1021
1022        if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1023                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1024        } else {
1025                v &= BQ24190_REG_F_NTC_FAULT_MASK;
1026                v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1027
1028                switch (v) {
1029                case 0x0: /* Normal */
1030                        health = POWER_SUPPLY_HEALTH_GOOD;
1031                        break;
1032                case 0x1: /* TS1 Cold */
1033                case 0x3: /* TS2 Cold */
1034                case 0x5: /* Both Cold */
1035                        health = POWER_SUPPLY_HEALTH_COLD;
1036                        break;
1037                case 0x2: /* TS1 Hot */
1038                case 0x4: /* TS2 Hot */
1039                case 0x6: /* Both Hot */
1040                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
1041                        break;
1042                default:
1043                        health = POWER_SUPPLY_HEALTH_UNKNOWN;
1044                }
1045        }
1046
1047        val->intval = health;
1048        return 0;
1049}
1050
1051static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1052                union power_supply_propval *val)
1053{
1054        u8 batfet_disable;
1055        int ret;
1056
1057        ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1058                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1059                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1060        if (ret < 0)
1061                return ret;
1062
1063        val->intval = !batfet_disable;
1064        return 0;
1065}
1066
1067static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1068                const union power_supply_propval *val)
1069{
1070        return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1071                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1072                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1073}
1074
1075static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1076                union power_supply_propval *val)
1077{
1078        int temp, ret;
1079
1080        ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1081                        BQ24190_REG_ICTRC_TREG_MASK,
1082                        BQ24190_REG_ICTRC_TREG_SHIFT,
1083                        bq24190_ictrc_treg_values,
1084                        ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1085        if (ret < 0)
1086                return ret;
1087
1088        val->intval = temp;
1089        return 0;
1090}
1091
1092static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1093                const union power_supply_propval *val)
1094{
1095        return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1096                        BQ24190_REG_ICTRC_TREG_MASK,
1097                        BQ24190_REG_ICTRC_TREG_SHIFT,
1098                        bq24190_ictrc_treg_values,
1099                        ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1100}
1101
1102static int bq24190_battery_get_property(struct power_supply *psy,
1103                enum power_supply_property psp, union power_supply_propval *val)
1104{
1105        struct bq24190_dev_info *bdi =
1106                        container_of(psy, struct bq24190_dev_info, battery);
1107        int ret;
1108
1109        dev_dbg(bdi->dev, "prop: %d\n", psp);
1110
1111        pm_runtime_get_sync(bdi->dev);
1112
1113        switch (psp) {
1114        case POWER_SUPPLY_PROP_STATUS:
1115                ret = bq24190_battery_get_status(bdi, val);
1116                break;
1117        case POWER_SUPPLY_PROP_HEALTH:
1118                ret = bq24190_battery_get_health(bdi, val);
1119                break;
1120        case POWER_SUPPLY_PROP_ONLINE:
1121                ret = bq24190_battery_get_online(bdi, val);
1122                break;
1123        case POWER_SUPPLY_PROP_TECHNOLOGY:
1124                /* Could be Li-on or Li-polymer but no way to tell which */
1125                val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1126                ret = 0;
1127                break;
1128        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1129                ret = bq24190_battery_get_temp_alert_max(bdi, val);
1130                break;
1131        case POWER_SUPPLY_PROP_SCOPE:
1132                val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1133                ret = 0;
1134                break;
1135        default:
1136                ret = -ENODATA;
1137        }
1138
1139        pm_runtime_put_sync(bdi->dev);
1140        return ret;
1141}
1142
1143static int bq24190_battery_set_property(struct power_supply *psy,
1144                enum power_supply_property psp,
1145                const union power_supply_propval *val)
1146{
1147        struct bq24190_dev_info *bdi =
1148                        container_of(psy, struct bq24190_dev_info, battery);
1149        int ret;
1150
1151        dev_dbg(bdi->dev, "prop: %d\n", psp);
1152
1153        pm_runtime_put_sync(bdi->dev);
1154
1155        switch (psp) {
1156        case POWER_SUPPLY_PROP_ONLINE:
1157                ret = bq24190_battery_set_online(bdi, val);
1158                break;
1159        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1160                ret = bq24190_battery_set_temp_alert_max(bdi, val);
1161                break;
1162        default:
1163                ret = -EINVAL;
1164        }
1165
1166        pm_runtime_put_sync(bdi->dev);
1167        return ret;
1168}
1169
1170static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1171                enum power_supply_property psp)
1172{
1173        int ret;
1174
1175        switch (psp) {
1176        case POWER_SUPPLY_PROP_ONLINE:
1177        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1178                ret = 1;
1179                break;
1180        default:
1181                ret = 0;
1182        }
1183
1184        return ret;
1185}
1186
1187static enum power_supply_property bq24190_battery_properties[] = {
1188        POWER_SUPPLY_PROP_STATUS,
1189        POWER_SUPPLY_PROP_HEALTH,
1190        POWER_SUPPLY_PROP_ONLINE,
1191        POWER_SUPPLY_PROP_TECHNOLOGY,
1192        POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1193        POWER_SUPPLY_PROP_SCOPE,
1194};
1195
1196static void bq24190_battery_init(struct power_supply *battery)
1197{
1198        battery->name = "bq24190-battery";
1199        battery->type = POWER_SUPPLY_TYPE_BATTERY;
1200        battery->properties = bq24190_battery_properties;
1201        battery->num_properties = ARRAY_SIZE(bq24190_battery_properties);
1202        battery->get_property = bq24190_battery_get_property;
1203        battery->set_property = bq24190_battery_set_property;
1204        battery->property_is_writeable = bq24190_battery_property_is_writeable;
1205}
1206
1207static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1208{
1209        struct bq24190_dev_info *bdi = data;
1210        bool alert_userspace = false;
1211        u8 ss_reg, f_reg;
1212        int ret;
1213
1214        pm_runtime_get_sync(bdi->dev);
1215
1216        ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1217        if (ret < 0) {
1218                dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1219                goto out;
1220        }
1221
1222        if (ss_reg != bdi->ss_reg) {
1223                /*
1224                 * The device is in host mode so when PG_STAT goes from 1->0
1225                 * (i.e., power removed) HIZ needs to be disabled.
1226                 */
1227                if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1228                                !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1229                        ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1230                                        BQ24190_REG_ISC_EN_HIZ_MASK,
1231                                        BQ24190_REG_ISC_EN_HIZ_SHIFT,
1232                                        0);
1233                        if (ret < 0)
1234                                dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1235                                        ret);
1236                }
1237
1238                bdi->ss_reg = ss_reg;
1239                alert_userspace = true;
1240        }
1241
1242        mutex_lock(&bdi->f_reg_lock);
1243
1244        ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1245        if (ret < 0) {
1246                mutex_unlock(&bdi->f_reg_lock);
1247                dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1248                goto out;
1249        }
1250
1251        if (f_reg != bdi->f_reg) {
1252                bdi->f_reg = f_reg;
1253                bdi->charger_health_valid = true;
1254                bdi->battery_health_valid = true;
1255                bdi->battery_status_valid = true;
1256
1257                alert_userspace = true;
1258        }
1259
1260        mutex_unlock(&bdi->f_reg_lock);
1261
1262        /*
1263         * Sometimes bq24190 gives a steady trickle of interrupts even
1264         * though the watchdog timer is turned off and neither the STATUS
1265         * nor FAULT registers have changed.  Weed out these sprurious
1266         * interrupts so userspace isn't alerted for no reason.
1267         * In addition, the chip always generates an interrupt after
1268         * register reset so we should ignore that one (the very first
1269         * interrupt received).
1270         */
1271        if (alert_userspace && !bdi->first_time) {
1272                power_supply_changed(&bdi->charger);
1273                power_supply_changed(&bdi->battery);
1274                bdi->first_time = false;
1275        }
1276
1277out:
1278        pm_runtime_put_sync(bdi->dev);
1279
1280        dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1281
1282        return IRQ_HANDLED;
1283}
1284
1285static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1286{
1287        u8 v;
1288        int ret;
1289
1290        pm_runtime_get_sync(bdi->dev);
1291
1292        /* First check that the device really is what its supposed to be */
1293        ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1294                        BQ24190_REG_VPRS_PN_MASK,
1295                        BQ24190_REG_VPRS_PN_SHIFT,
1296                        &v);
1297        if (ret < 0)
1298                goto out;
1299
1300        if (v != bdi->model) {
1301                ret = -ENODEV;
1302                goto out;
1303        }
1304
1305        ret = bq24190_register_reset(bdi);
1306        if (ret < 0)
1307                goto out;
1308
1309        ret = bq24190_set_mode_host(bdi);
1310out:
1311        pm_runtime_put_sync(bdi->dev);
1312        return ret;
1313}
1314
1315#ifdef CONFIG_OF
1316static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1317{
1318        bdi->irq = irq_of_parse_and_map(bdi->dev->of_node, 0);
1319        if (bdi->irq <= 0)
1320                return -1;
1321
1322        return 0;
1323}
1324#else
1325static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1326{
1327        return -1;
1328}
1329#endif
1330
1331static int bq24190_setup_pdata(struct bq24190_dev_info *bdi,
1332                struct bq24190_platform_data *pdata)
1333{
1334        int ret;
1335
1336        if (!gpio_is_valid(pdata->gpio_int))
1337                return -1;
1338
1339        ret = gpio_request(pdata->gpio_int, dev_name(bdi->dev));
1340        if (ret < 0)
1341                return -1;
1342
1343        ret = gpio_direction_input(pdata->gpio_int);
1344        if (ret < 0)
1345                goto out;
1346
1347        bdi->irq = gpio_to_irq(pdata->gpio_int);
1348        if (!bdi->irq)
1349                goto out;
1350
1351        bdi->gpio_int = pdata->gpio_int;
1352        return 0;
1353
1354out:
1355        gpio_free(pdata->gpio_int);
1356        return -1;
1357}
1358
1359static int bq24190_probe(struct i2c_client *client,
1360                const struct i2c_device_id *id)
1361{
1362        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1363        struct device *dev = &client->dev;
1364        struct bq24190_platform_data *pdata = client->dev.platform_data;
1365        struct bq24190_dev_info *bdi;
1366        int ret;
1367
1368        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1369                dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1370                return -ENODEV;
1371        }
1372
1373        bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1374        if (!bdi) {
1375                dev_err(dev, "Can't alloc bdi struct\n");
1376                return -ENOMEM;
1377        }
1378
1379        bdi->client = client;
1380        bdi->dev = dev;
1381        bdi->model = id->driver_data;
1382        strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1383        mutex_init(&bdi->f_reg_lock);
1384        bdi->first_time = true;
1385        bdi->charger_health_valid = false;
1386        bdi->battery_health_valid = false;
1387        bdi->battery_status_valid = false;
1388
1389        i2c_set_clientdata(client, bdi);
1390
1391        if (dev->of_node)
1392                ret = bq24190_setup_dt(bdi);
1393        else
1394                ret = bq24190_setup_pdata(bdi, pdata);
1395
1396        if (ret) {
1397                dev_err(dev, "Can't get irq info\n");
1398                return -EINVAL;
1399        }
1400
1401        ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
1402                        bq24190_irq_handler_thread,
1403                        IRQF_TRIGGER_RISING | IRQF_ONESHOT,
1404                        "bq24190-charger", bdi);
1405        if (ret < 0) {
1406                dev_err(dev, "Can't set up irq handler\n");
1407                goto out1;
1408        }
1409
1410        pm_runtime_enable(dev);
1411        pm_runtime_resume(dev);
1412
1413        ret = bq24190_hw_init(bdi);
1414        if (ret < 0) {
1415                dev_err(dev, "Hardware init failed\n");
1416                goto out2;
1417        }
1418
1419        bq24190_charger_init(&bdi->charger);
1420
1421        ret = power_supply_register(dev, &bdi->charger);
1422        if (ret) {
1423                dev_err(dev, "Can't register charger\n");
1424                goto out2;
1425        }
1426
1427        bq24190_battery_init(&bdi->battery);
1428
1429        ret = power_supply_register(dev, &bdi->battery);
1430        if (ret) {
1431                dev_err(dev, "Can't register battery\n");
1432                goto out3;
1433        }
1434
1435        ret = bq24190_sysfs_create_group(bdi);
1436        if (ret) {
1437                dev_err(dev, "Can't create sysfs entries\n");
1438                goto out4;
1439        }
1440
1441        return 0;
1442
1443out4:
1444        power_supply_unregister(&bdi->battery);
1445out3:
1446        power_supply_unregister(&bdi->charger);
1447out2:
1448        pm_runtime_disable(dev);
1449out1:
1450        if (bdi->gpio_int)
1451                gpio_free(bdi->gpio_int);
1452
1453        return ret;
1454}
1455
1456static int bq24190_remove(struct i2c_client *client)
1457{
1458        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1459
1460        pm_runtime_get_sync(bdi->dev);
1461        bq24190_register_reset(bdi);
1462        pm_runtime_put_sync(bdi->dev);
1463
1464        bq24190_sysfs_remove_group(bdi);
1465        power_supply_unregister(&bdi->battery);
1466        power_supply_unregister(&bdi->charger);
1467        pm_runtime_disable(bdi->dev);
1468
1469        if (bdi->gpio_int)
1470                gpio_free(bdi->gpio_int);
1471
1472        return 0;
1473}
1474
1475#ifdef CONFIG_PM_SLEEP
1476static int bq24190_pm_suspend(struct device *dev)
1477{
1478        struct i2c_client *client = to_i2c_client(dev);
1479        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1480
1481        pm_runtime_get_sync(bdi->dev);
1482        bq24190_register_reset(bdi);
1483        pm_runtime_put_sync(bdi->dev);
1484
1485        return 0;
1486}
1487
1488static int bq24190_pm_resume(struct device *dev)
1489{
1490        struct i2c_client *client = to_i2c_client(dev);
1491        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1492
1493        bdi->charger_health_valid = false;
1494        bdi->battery_health_valid = false;
1495        bdi->battery_status_valid = false;
1496
1497        pm_runtime_get_sync(bdi->dev);
1498        bq24190_register_reset(bdi);
1499        pm_runtime_put_sync(bdi->dev);
1500
1501        /* Things may have changed while suspended so alert upper layer */
1502        power_supply_changed(&bdi->charger);
1503        power_supply_changed(&bdi->battery);
1504
1505        return 0;
1506}
1507#endif
1508
1509static SIMPLE_DEV_PM_OPS(bq24190_pm_ops, bq24190_pm_suspend, bq24190_pm_resume);
1510
1511/*
1512 * Only support the bq24190 right now.  The bq24192, bq24192i, and bq24193
1513 * are similar but not identical so the driver needs to be extended to
1514 * support them.
1515 */
1516static const struct i2c_device_id bq24190_i2c_ids[] = {
1517        { "bq24190", BQ24190_REG_VPRS_PN_24190 },
1518        { },
1519};
1520
1521#ifdef CONFIG_OF
1522static const struct of_device_id bq24190_of_match[] = {
1523        { .compatible = "ti,bq24190", },
1524        { },
1525};
1526MODULE_DEVICE_TABLE(of, bq24190_of_match);
1527#else
1528static const struct of_device_id bq24190_of_match[] = {
1529        { },
1530};
1531#endif
1532
1533static struct i2c_driver bq24190_driver = {
1534        .probe          = bq24190_probe,
1535        .remove         = bq24190_remove,
1536        .id_table       = bq24190_i2c_ids,
1537        .driver = {
1538                .name           = "bq24190-charger",
1539                .owner          = THIS_MODULE,
1540                .pm             = &bq24190_pm_ops,
1541                .of_match_table = of_match_ptr(bq24190_of_match),
1542        },
1543};
1544module_i2c_driver(bq24190_driver);
1545
1546MODULE_LICENSE("GPL");
1547MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1548MODULE_ALIAS("i2c:bq24190-charger");
1549MODULE_DESCRIPTION("TI BQ24190 Charger Driver");
1550
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.