linux/drivers/power/supply/bq24190_charger.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Driver for the TI bq24190 battery charger.
   4 *
   5 * Author: Mark A. Greer <mgreer@animalcreek.com>
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/interrupt.h>
  10#include <linux/delay.h>
  11#include <linux/of_irq.h>
  12#include <linux/of_device.h>
  13#include <linux/pm_runtime.h>
  14#include <linux/power_supply.h>
  15#include <linux/power/bq24190_charger.h>
  16#include <linux/regulator/driver.h>
  17#include <linux/regulator/machine.h>
  18#include <linux/workqueue.h>
  19#include <linux/gpio.h>
  20#include <linux/i2c.h>
  21#include <linux/extcon-provider.h>
  22
  23#define BQ24190_MANUFACTURER    "Texas Instruments"
  24
  25#define BQ24190_REG_ISC         0x00 /* Input Source Control */
  26#define BQ24190_REG_ISC_EN_HIZ_MASK             BIT(7)
  27#define BQ24190_REG_ISC_EN_HIZ_SHIFT            7
  28#define BQ24190_REG_ISC_VINDPM_MASK             (BIT(6) | BIT(5) | BIT(4) | \
  29                                                 BIT(3))
  30#define BQ24190_REG_ISC_VINDPM_SHIFT            3
  31#define BQ24190_REG_ISC_IINLIM_MASK             (BIT(2) | BIT(1) | BIT(0))
  32#define BQ24190_REG_ISC_IINLIM_SHIFT            0
  33
  34#define BQ24190_REG_POC         0x01 /* Power-On Configuration */
  35#define BQ24190_REG_POC_RESET_MASK              BIT(7)
  36#define BQ24190_REG_POC_RESET_SHIFT             7
  37#define BQ24190_REG_POC_WDT_RESET_MASK          BIT(6)
  38#define BQ24190_REG_POC_WDT_RESET_SHIFT         6
  39#define BQ24190_REG_POC_CHG_CONFIG_MASK         (BIT(5) | BIT(4))
  40#define BQ24190_REG_POC_CHG_CONFIG_SHIFT        4
  41#define BQ24190_REG_POC_CHG_CONFIG_DISABLE              0x0
  42#define BQ24190_REG_POC_CHG_CONFIG_CHARGE               0x1
  43#define BQ24190_REG_POC_CHG_CONFIG_OTG                  0x2
  44#define BQ24190_REG_POC_SYS_MIN_MASK            (BIT(3) | BIT(2) | BIT(1))
  45#define BQ24190_REG_POC_SYS_MIN_SHIFT           1
  46#define BQ24190_REG_POC_SYS_MIN_MIN                     3000
  47#define BQ24190_REG_POC_SYS_MIN_MAX                     3700
  48#define BQ24190_REG_POC_BOOST_LIM_MASK          BIT(0)
  49#define BQ24190_REG_POC_BOOST_LIM_SHIFT         0
  50
  51#define BQ24190_REG_CCC         0x02 /* Charge Current Control */
  52#define BQ24190_REG_CCC_ICHG_MASK               (BIT(7) | BIT(6) | BIT(5) | \
  53                                                 BIT(4) | BIT(3) | BIT(2))
  54#define BQ24190_REG_CCC_ICHG_SHIFT              2
  55#define BQ24190_REG_CCC_FORCE_20PCT_MASK        BIT(0)
  56#define BQ24190_REG_CCC_FORCE_20PCT_SHIFT       0
  57
  58#define BQ24190_REG_PCTCC       0x03 /* Pre-charge/Termination Current Cntl */
  59#define BQ24190_REG_PCTCC_IPRECHG_MASK          (BIT(7) | BIT(6) | BIT(5) | \
  60                                                 BIT(4))
  61#define BQ24190_REG_PCTCC_IPRECHG_SHIFT         4
  62#define BQ24190_REG_PCTCC_IPRECHG_MIN                   128
  63#define BQ24190_REG_PCTCC_IPRECHG_MAX                   2048
  64#define BQ24190_REG_PCTCC_ITERM_MASK            (BIT(3) | BIT(2) | BIT(1) | \
  65                                                 BIT(0))
  66#define BQ24190_REG_PCTCC_ITERM_SHIFT           0
  67#define BQ24190_REG_PCTCC_ITERM_MIN                     128
  68#define BQ24190_REG_PCTCC_ITERM_MAX                     2048
  69
  70#define BQ24190_REG_CVC         0x04 /* Charge Voltage Control */
  71#define BQ24190_REG_CVC_VREG_MASK               (BIT(7) | BIT(6) | BIT(5) | \
  72                                                 BIT(4) | BIT(3) | BIT(2))
  73#define BQ24190_REG_CVC_VREG_SHIFT              2
  74#define BQ24190_REG_CVC_BATLOWV_MASK            BIT(1)
  75#define BQ24190_REG_CVC_BATLOWV_SHIFT           1
  76#define BQ24190_REG_CVC_VRECHG_MASK             BIT(0)
  77#define BQ24190_REG_CVC_VRECHG_SHIFT            0
  78
  79#define BQ24190_REG_CTTC        0x05 /* Charge Term/Timer Control */
  80#define BQ24190_REG_CTTC_EN_TERM_MASK           BIT(7)
  81#define BQ24190_REG_CTTC_EN_TERM_SHIFT          7
  82#define BQ24190_REG_CTTC_TERM_STAT_MASK         BIT(6)
  83#define BQ24190_REG_CTTC_TERM_STAT_SHIFT        6
  84#define BQ24190_REG_CTTC_WATCHDOG_MASK          (BIT(5) | BIT(4))
  85#define BQ24190_REG_CTTC_WATCHDOG_SHIFT         4
  86#define BQ24190_REG_CTTC_EN_TIMER_MASK          BIT(3)
  87#define BQ24190_REG_CTTC_EN_TIMER_SHIFT         3
  88#define BQ24190_REG_CTTC_CHG_TIMER_MASK         (BIT(2) | BIT(1))
  89#define BQ24190_REG_CTTC_CHG_TIMER_SHIFT        1
  90#define BQ24190_REG_CTTC_JEITA_ISET_MASK        BIT(0)
  91#define BQ24190_REG_CTTC_JEITA_ISET_SHIFT       0
  92
  93#define BQ24190_REG_ICTRC       0x06 /* IR Comp/Thermal Regulation Control */
  94#define BQ24190_REG_ICTRC_BAT_COMP_MASK         (BIT(7) | BIT(6) | BIT(5))
  95#define BQ24190_REG_ICTRC_BAT_COMP_SHIFT        5
  96#define BQ24190_REG_ICTRC_VCLAMP_MASK           (BIT(4) | BIT(3) | BIT(2))
  97#define BQ24190_REG_ICTRC_VCLAMP_SHIFT          2
  98#define BQ24190_REG_ICTRC_TREG_MASK             (BIT(1) | BIT(0))
  99#define BQ24190_REG_ICTRC_TREG_SHIFT            0
 100
 101#define BQ24190_REG_MOC         0x07 /* Misc. Operation Control */
 102#define BQ24190_REG_MOC_DPDM_EN_MASK            BIT(7)
 103#define BQ24190_REG_MOC_DPDM_EN_SHIFT           7
 104#define BQ24190_REG_MOC_TMR2X_EN_MASK           BIT(6)
 105#define BQ24190_REG_MOC_TMR2X_EN_SHIFT          6
 106#define BQ24190_REG_MOC_BATFET_DISABLE_MASK     BIT(5)
 107#define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT    5
 108#define BQ24190_REG_MOC_JEITA_VSET_MASK         BIT(4)
 109#define BQ24190_REG_MOC_JEITA_VSET_SHIFT        4
 110#define BQ24190_REG_MOC_INT_MASK_MASK           (BIT(1) | BIT(0))
 111#define BQ24190_REG_MOC_INT_MASK_SHIFT          0
 112
 113#define BQ24190_REG_SS          0x08 /* System Status */
 114#define BQ24190_REG_SS_VBUS_STAT_MASK           (BIT(7) | BIT(6))
 115#define BQ24190_REG_SS_VBUS_STAT_SHIFT          6
 116#define BQ24190_REG_SS_CHRG_STAT_MASK           (BIT(5) | BIT(4))
 117#define BQ24190_REG_SS_CHRG_STAT_SHIFT          4
 118#define BQ24190_REG_SS_DPM_STAT_MASK            BIT(3)
 119#define BQ24190_REG_SS_DPM_STAT_SHIFT           3
 120#define BQ24190_REG_SS_PG_STAT_MASK             BIT(2)
 121#define BQ24190_REG_SS_PG_STAT_SHIFT            2
 122#define BQ24190_REG_SS_THERM_STAT_MASK          BIT(1)
 123#define BQ24190_REG_SS_THERM_STAT_SHIFT         1
 124#define BQ24190_REG_SS_VSYS_STAT_MASK           BIT(0)
 125#define BQ24190_REG_SS_VSYS_STAT_SHIFT          0
 126
 127#define BQ24190_REG_F           0x09 /* Fault */
 128#define BQ24190_REG_F_WATCHDOG_FAULT_MASK       BIT(7)
 129#define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT      7
 130#define BQ24190_REG_F_BOOST_FAULT_MASK          BIT(6)
 131#define BQ24190_REG_F_BOOST_FAULT_SHIFT         6
 132#define BQ24190_REG_F_CHRG_FAULT_MASK           (BIT(5) | BIT(4))
 133#define BQ24190_REG_F_CHRG_FAULT_SHIFT          4
 134#define BQ24190_REG_F_BAT_FAULT_MASK            BIT(3)
 135#define BQ24190_REG_F_BAT_FAULT_SHIFT           3
 136#define BQ24190_REG_F_NTC_FAULT_MASK            (BIT(2) | BIT(1) | BIT(0))
 137#define BQ24190_REG_F_NTC_FAULT_SHIFT           0
 138
 139#define BQ24190_REG_VPRS        0x0A /* Vendor/Part/Revision Status */
 140#define BQ24190_REG_VPRS_PN_MASK                (BIT(5) | BIT(4) | BIT(3))
 141#define BQ24190_REG_VPRS_PN_SHIFT               3
 142#define BQ24190_REG_VPRS_PN_24190                       0x4
 143#define BQ24190_REG_VPRS_PN_24192                       0x5 /* Also 24193, 24196 */
 144#define BQ24190_REG_VPRS_PN_24192I                      0x3
 145#define BQ24190_REG_VPRS_TS_PROFILE_MASK        BIT(2)
 146#define BQ24190_REG_VPRS_TS_PROFILE_SHIFT       2
 147#define BQ24190_REG_VPRS_DEV_REG_MASK           (BIT(1) | BIT(0))
 148#define BQ24190_REG_VPRS_DEV_REG_SHIFT          0
 149
 150/*
 151 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
 152 * so the first read after a fault returns the latched value and subsequent
 153 * reads return the current value.  In order to return the fault status
 154 * to the user, have the interrupt handler save the reg's value and retrieve
 155 * it in the appropriate health/status routine.
 156 */
 157struct bq24190_dev_info {
 158        struct i2c_client               *client;
 159        struct device                   *dev;
 160        struct extcon_dev               *edev;
 161        struct power_supply             *charger;
 162        struct power_supply             *battery;
 163        struct delayed_work             input_current_limit_work;
 164        char                            model_name[I2C_NAME_SIZE];
 165        bool                            initialized;
 166        bool                            irq_event;
 167        u16                             sys_min;
 168        u16                             iprechg;
 169        u16                             iterm;
 170        struct mutex                    f_reg_lock;
 171        u8                              f_reg;
 172        u8                              ss_reg;
 173        u8                              watchdog;
 174};
 175
 176static const unsigned int bq24190_usb_extcon_cable[] = {
 177        EXTCON_USB,
 178        EXTCON_NONE,
 179};
 180
 181/*
 182 * The tables below provide a 2-way mapping for the value that goes in
 183 * the register field and the real-world value that it represents.
 184 * The index of the array is the value that goes in the register; the
 185 * number at that index in the array is the real-world value that it
 186 * represents.
 187 */
 188
 189/* REG00[2:0] (IINLIM) in uAh */
 190static const int bq24190_isc_iinlim_values[] = {
 191         100000,  150000,  500000,  900000, 1200000, 1500000, 2000000, 3000000
 192};
 193
 194/* REG02[7:2] (ICHG) in uAh */
 195static const int bq24190_ccc_ichg_values[] = {
 196         512000,  576000,  640000,  704000,  768000,  832000,  896000,  960000,
 197        1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
 198        1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
 199        2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
 200        2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
 201        3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
 202        3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
 203        4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
 204};
 205
 206/* REG04[7:2] (VREG) in uV */
 207static const int bq24190_cvc_vreg_values[] = {
 208        3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
 209        3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
 210        3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
 211        3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
 212        4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
 213        4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
 214        4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
 215        4400000
 216};
 217
 218/* REG06[1:0] (TREG) in tenths of degrees Celsius */
 219static const int bq24190_ictrc_treg_values[] = {
 220        600, 800, 1000, 1200
 221};
 222
 223/*
 224 * Return the index in 'tbl' of greatest value that is less than or equal to
 225 * 'val'.  The index range returned is 0 to 'tbl_size' - 1.  Assumes that
 226 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
 227 * is less than 2^8.
 228 */
 229static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
 230{
 231        int i;
 232
 233        for (i = 1; i < tbl_size; i++)
 234                if (v < tbl[i])
 235                        break;
 236
 237        return i - 1;
 238}
 239
 240/* Basic driver I/O routines */
 241
 242static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
 243{
 244        int ret;
 245
 246        ret = i2c_smbus_read_byte_data(bdi->client, reg);
 247        if (ret < 0)
 248                return ret;
 249
 250        *data = ret;
 251        return 0;
 252}
 253
 254static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
 255{
 256        return i2c_smbus_write_byte_data(bdi->client, reg, data);
 257}
 258
 259static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
 260                u8 mask, u8 shift, u8 *data)
 261{
 262        u8 v;
 263        int ret;
 264
 265        ret = bq24190_read(bdi, reg, &v);
 266        if (ret < 0)
 267                return ret;
 268
 269        v &= mask;
 270        v >>= shift;
 271        *data = v;
 272
 273        return 0;
 274}
 275
 276static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
 277                u8 mask, u8 shift, u8 data)
 278{
 279        u8 v;
 280        int ret;
 281
 282        ret = bq24190_read(bdi, reg, &v);
 283        if (ret < 0)
 284                return ret;
 285
 286        v &= ~mask;
 287        v |= ((data << shift) & mask);
 288
 289        return bq24190_write(bdi, reg, v);
 290}
 291
 292static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
 293                u8 reg, u8 mask, u8 shift,
 294                const int tbl[], int tbl_size,
 295                int *val)
 296{
 297        u8 v;
 298        int ret;
 299
 300        ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
 301        if (ret < 0)
 302                return ret;
 303
 304        v = (v >= tbl_size) ? (tbl_size - 1) : v;
 305        *val = tbl[v];
 306
 307        return 0;
 308}
 309
 310static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
 311                u8 reg, u8 mask, u8 shift,
 312                const int tbl[], int tbl_size,
 313                int val)
 314{
 315        u8 idx;
 316
 317        idx = bq24190_find_idx(tbl, tbl_size, val);
 318
 319        return bq24190_write_mask(bdi, reg, mask, shift, idx);
 320}
 321
 322#ifdef CONFIG_SYSFS
 323/*
 324 * There are a numerous options that are configurable on the bq24190
 325 * that go well beyond what the power_supply properties provide access to.
 326 * Provide sysfs access to them so they can be examined and possibly modified
 327 * on the fly.  They will be provided for the charger power_supply object only
 328 * and will be prefixed by 'f_' to make them easier to recognize.
 329 */
 330
 331#define BQ24190_SYSFS_FIELD(_name, r, f, m, store)                      \
 332{                                                                       \
 333        .attr   = __ATTR(f_##_name, m, bq24190_sysfs_show, store),      \
 334        .reg    = BQ24190_REG_##r,                                      \
 335        .mask   = BQ24190_REG_##r##_##f##_MASK,                         \
 336        .shift  = BQ24190_REG_##r##_##f##_SHIFT,                        \
 337}
 338
 339#define BQ24190_SYSFS_FIELD_RW(_name, r, f)                             \
 340                BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO,     \
 341                                bq24190_sysfs_store)
 342
 343#define BQ24190_SYSFS_FIELD_RO(_name, r, f)                             \
 344                BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
 345
 346static ssize_t bq24190_sysfs_show(struct device *dev,
 347                struct device_attribute *attr, char *buf);
 348static ssize_t bq24190_sysfs_store(struct device *dev,
 349                struct device_attribute *attr, const char *buf, size_t count);
 350
 351struct bq24190_sysfs_field_info {
 352        struct device_attribute attr;
 353        u8      reg;
 354        u8      mask;
 355        u8      shift;
 356};
 357
 358/* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
 359#undef SS
 360
 361static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
 362                        /*      sysfs name      reg     field in reg */
 363        BQ24190_SYSFS_FIELD_RW(en_hiz,          ISC,    EN_HIZ),
 364        BQ24190_SYSFS_FIELD_RW(vindpm,          ISC,    VINDPM),
 365        BQ24190_SYSFS_FIELD_RW(iinlim,          ISC,    IINLIM),
 366        BQ24190_SYSFS_FIELD_RW(chg_config,      POC,    CHG_CONFIG),
 367        BQ24190_SYSFS_FIELD_RW(sys_min,         POC,    SYS_MIN),
 368        BQ24190_SYSFS_FIELD_RW(boost_lim,       POC,    BOOST_LIM),
 369        BQ24190_SYSFS_FIELD_RW(ichg,            CCC,    ICHG),
 370        BQ24190_SYSFS_FIELD_RW(force_20_pct,    CCC,    FORCE_20PCT),
 371        BQ24190_SYSFS_FIELD_RW(iprechg,         PCTCC,  IPRECHG),
 372        BQ24190_SYSFS_FIELD_RW(iterm,           PCTCC,  ITERM),
 373        BQ24190_SYSFS_FIELD_RW(vreg,            CVC,    VREG),
 374        BQ24190_SYSFS_FIELD_RW(batlowv,         CVC,    BATLOWV),
 375        BQ24190_SYSFS_FIELD_RW(vrechg,          CVC,    VRECHG),
 376        BQ24190_SYSFS_FIELD_RW(en_term,         CTTC,   EN_TERM),
 377        BQ24190_SYSFS_FIELD_RW(term_stat,       CTTC,   TERM_STAT),
 378        BQ24190_SYSFS_FIELD_RO(watchdog,        CTTC,   WATCHDOG),
 379        BQ24190_SYSFS_FIELD_RW(en_timer,        CTTC,   EN_TIMER),
 380        BQ24190_SYSFS_FIELD_RW(chg_timer,       CTTC,   CHG_TIMER),
 381        BQ24190_SYSFS_FIELD_RW(jeta_iset,       CTTC,   JEITA_ISET),
 382        BQ24190_SYSFS_FIELD_RW(bat_comp,        ICTRC,  BAT_COMP),
 383        BQ24190_SYSFS_FIELD_RW(vclamp,          ICTRC,  VCLAMP),
 384        BQ24190_SYSFS_FIELD_RW(treg,            ICTRC,  TREG),
 385        BQ24190_SYSFS_FIELD_RW(dpdm_en,         MOC,    DPDM_EN),
 386        BQ24190_SYSFS_FIELD_RW(tmr2x_en,        MOC,    TMR2X_EN),
 387        BQ24190_SYSFS_FIELD_RW(batfet_disable,  MOC,    BATFET_DISABLE),
 388        BQ24190_SYSFS_FIELD_RW(jeita_vset,      MOC,    JEITA_VSET),
 389        BQ24190_SYSFS_FIELD_RO(int_mask,        MOC,    INT_MASK),
 390        BQ24190_SYSFS_FIELD_RO(vbus_stat,       SS,     VBUS_STAT),
 391        BQ24190_SYSFS_FIELD_RO(chrg_stat,       SS,     CHRG_STAT),
 392        BQ24190_SYSFS_FIELD_RO(dpm_stat,        SS,     DPM_STAT),
 393        BQ24190_SYSFS_FIELD_RO(pg_stat,         SS,     PG_STAT),
 394        BQ24190_SYSFS_FIELD_RO(therm_stat,      SS,     THERM_STAT),
 395        BQ24190_SYSFS_FIELD_RO(vsys_stat,       SS,     VSYS_STAT),
 396        BQ24190_SYSFS_FIELD_RO(watchdog_fault,  F,      WATCHDOG_FAULT),
 397        BQ24190_SYSFS_FIELD_RO(boost_fault,     F,      BOOST_FAULT),
 398        BQ24190_SYSFS_FIELD_RO(chrg_fault,      F,      CHRG_FAULT),
 399        BQ24190_SYSFS_FIELD_RO(bat_fault,       F,      BAT_FAULT),
 400        BQ24190_SYSFS_FIELD_RO(ntc_fault,       F,      NTC_FAULT),
 401        BQ24190_SYSFS_FIELD_RO(pn,              VPRS,   PN),
 402        BQ24190_SYSFS_FIELD_RO(ts_profile,      VPRS,   TS_PROFILE),
 403        BQ24190_SYSFS_FIELD_RO(dev_reg,         VPRS,   DEV_REG),
 404};
 405
 406static struct attribute *
 407        bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
 408
 409ATTRIBUTE_GROUPS(bq24190_sysfs);
 410
 411static void bq24190_sysfs_init_attrs(void)
 412{
 413        int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
 414
 415        for (i = 0; i < limit; i++)
 416                bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
 417
 418        bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
 419}
 420
 421static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
 422                const char *name)
 423{
 424        int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
 425
 426        for (i = 0; i < limit; i++)
 427                if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
 428                        break;
 429
 430        if (i >= limit)
 431                return NULL;
 432
 433        return &bq24190_sysfs_field_tbl[i];
 434}
 435
 436static ssize_t bq24190_sysfs_show(struct device *dev,
 437                struct device_attribute *attr, char *buf)
 438{
 439        struct power_supply *psy = dev_get_drvdata(dev);
 440        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
 441        struct bq24190_sysfs_field_info *info;
 442        ssize_t count;
 443        int ret;
 444        u8 v;
 445
 446        info = bq24190_sysfs_field_lookup(attr->attr.name);
 447        if (!info)
 448                return -EINVAL;
 449
 450        ret = pm_runtime_get_sync(bdi->dev);
 451        if (ret < 0)
 452                return ret;
 453
 454        ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
 455        if (ret)
 456                count = ret;
 457        else
 458                count = scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
 459
 460        pm_runtime_mark_last_busy(bdi->dev);
 461        pm_runtime_put_autosuspend(bdi->dev);
 462
 463        return count;
 464}
 465
 466static ssize_t bq24190_sysfs_store(struct device *dev,
 467                struct device_attribute *attr, const char *buf, size_t count)
 468{
 469        struct power_supply *psy = dev_get_drvdata(dev);
 470        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
 471        struct bq24190_sysfs_field_info *info;
 472        int ret;
 473        u8 v;
 474
 475        info = bq24190_sysfs_field_lookup(attr->attr.name);
 476        if (!info)
 477                return -EINVAL;
 478
 479        ret = kstrtou8(buf, 0, &v);
 480        if (ret < 0)
 481                return ret;
 482
 483        ret = pm_runtime_get_sync(bdi->dev);
 484        if (ret < 0) {
 485                pm_runtime_put_noidle(bdi->dev);
 486                return ret;
 487        }
 488
 489        ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
 490        if (ret)
 491                count = ret;
 492
 493        pm_runtime_mark_last_busy(bdi->dev);
 494        pm_runtime_put_autosuspend(bdi->dev);
 495
 496        return count;
 497}
 498#endif
 499
 500#ifdef CONFIG_REGULATOR
 501static int bq24190_set_charge_mode(struct regulator_dev *dev, u8 val)
 502{
 503        struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
 504        int ret;
 505
 506        ret = pm_runtime_get_sync(bdi->dev);
 507        if (ret < 0) {
 508                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
 509                pm_runtime_put_noidle(bdi->dev);
 510                return ret;
 511        }
 512
 513        ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 514                                 BQ24190_REG_POC_CHG_CONFIG_MASK,
 515                                 BQ24190_REG_POC_CHG_CONFIG_SHIFT, val);
 516
 517        pm_runtime_mark_last_busy(bdi->dev);
 518        pm_runtime_put_autosuspend(bdi->dev);
 519
 520        return ret;
 521}
 522
 523static int bq24190_vbus_enable(struct regulator_dev *dev)
 524{
 525        return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_OTG);
 526}
 527
 528static int bq24190_vbus_disable(struct regulator_dev *dev)
 529{
 530        return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_CHARGE);
 531}
 532
 533static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
 534{
 535        struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
 536        int ret;
 537        u8 val;
 538
 539        ret = pm_runtime_get_sync(bdi->dev);
 540        if (ret < 0) {
 541                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
 542                pm_runtime_put_noidle(bdi->dev);
 543                return ret;
 544        }
 545
 546        ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 547                                BQ24190_REG_POC_CHG_CONFIG_MASK,
 548                                BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
 549
 550        pm_runtime_mark_last_busy(bdi->dev);
 551        pm_runtime_put_autosuspend(bdi->dev);
 552
 553        return ret ? ret : val == BQ24190_REG_POC_CHG_CONFIG_OTG;
 554}
 555
 556static const struct regulator_ops bq24190_vbus_ops = {
 557        .enable = bq24190_vbus_enable,
 558        .disable = bq24190_vbus_disable,
 559        .is_enabled = bq24190_vbus_is_enabled,
 560};
 561
 562static const struct regulator_desc bq24190_vbus_desc = {
 563        .name = "usb_otg_vbus",
 564        .of_match = "usb-otg-vbus",
 565        .type = REGULATOR_VOLTAGE,
 566        .owner = THIS_MODULE,
 567        .ops = &bq24190_vbus_ops,
 568        .fixed_uV = 5000000,
 569        .n_voltages = 1,
 570};
 571
 572static const struct regulator_init_data bq24190_vbus_init_data = {
 573        .constraints = {
 574                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
 575        },
 576};
 577
 578static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
 579{
 580        struct bq24190_platform_data *pdata = bdi->dev->platform_data;
 581        struct regulator_config cfg = { };
 582        struct regulator_dev *reg;
 583        int ret = 0;
 584
 585        cfg.dev = bdi->dev;
 586        if (pdata && pdata->regulator_init_data)
 587                cfg.init_data = pdata->regulator_init_data;
 588        else
 589                cfg.init_data = &bq24190_vbus_init_data;
 590        cfg.driver_data = bdi;
 591        reg = devm_regulator_register(bdi->dev, &bq24190_vbus_desc, &cfg);
 592        if (IS_ERR(reg)) {
 593                ret = PTR_ERR(reg);
 594                dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
 595        }
 596
 597        return ret;
 598}
 599#else
 600static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
 601{
 602        return 0;
 603}
 604#endif
 605
 606static int bq24190_set_config(struct bq24190_dev_info *bdi)
 607{
 608        int ret;
 609        u8 v;
 610
 611        ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
 612        if (ret < 0)
 613                return ret;
 614
 615        bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
 616                                        BQ24190_REG_CTTC_WATCHDOG_SHIFT);
 617
 618        /*
 619         * According to the "Host Mode and default Mode" section of the
 620         * manual, a write to any register causes the bq24190 to switch
 621         * from default mode to host mode.  It will switch back to default
 622         * mode after a WDT timeout unless the WDT is turned off as well.
 623         * So, by simply turning off the WDT, we accomplish both with the
 624         * same write.
 625         */
 626        v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
 627
 628        ret = bq24190_write(bdi, BQ24190_REG_CTTC, v);
 629        if (ret < 0)
 630                return ret;
 631
 632        if (bdi->sys_min) {
 633                v = bdi->sys_min / 100 - 30; // manual section 9.5.1.2, table 9
 634                ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 635                                         BQ24190_REG_POC_SYS_MIN_MASK,
 636                                         BQ24190_REG_POC_SYS_MIN_SHIFT,
 637                                         v);
 638                if (ret < 0)
 639                        return ret;
 640        }
 641
 642        if (bdi->iprechg) {
 643                v = bdi->iprechg / 128 - 1; // manual section 9.5.1.4, table 11
 644                ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
 645                                         BQ24190_REG_PCTCC_IPRECHG_MASK,
 646                                         BQ24190_REG_PCTCC_IPRECHG_SHIFT,
 647                                         v);
 648                if (ret < 0)
 649                        return ret;
 650        }
 651
 652        if (bdi->iterm) {
 653                v = bdi->iterm / 128 - 1; // manual section 9.5.1.4, table 11
 654                ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
 655                                         BQ24190_REG_PCTCC_ITERM_MASK,
 656                                         BQ24190_REG_PCTCC_ITERM_SHIFT,
 657                                         v);
 658                if (ret < 0)
 659                        return ret;
 660        }
 661
 662        return 0;
 663}
 664
 665static int bq24190_register_reset(struct bq24190_dev_info *bdi)
 666{
 667        int ret, limit = 100;
 668        u8 v;
 669
 670        /*
 671         * This prop. can be passed on device instantiation from platform code:
 672         * struct property_entry pe[] =
 673         *   { PROPERTY_ENTRY_BOOL("disable-reset"), ... };
 674         * struct i2c_board_info bi =
 675         *   { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
 676         * struct i2c_adapter ad = { ... };
 677         * i2c_add_adapter(&ad);
 678         * i2c_new_client_device(&ad, &bi);
 679         */
 680        if (device_property_read_bool(bdi->dev, "disable-reset"))
 681                return 0;
 682
 683        /* Reset the registers */
 684        ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 685                        BQ24190_REG_POC_RESET_MASK,
 686                        BQ24190_REG_POC_RESET_SHIFT,
 687                        0x1);
 688        if (ret < 0)
 689                return ret;
 690
 691        /* Reset bit will be cleared by hardware so poll until it is */
 692        do {
 693                ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 694                                BQ24190_REG_POC_RESET_MASK,
 695                                BQ24190_REG_POC_RESET_SHIFT,
 696                                &v);
 697                if (ret < 0)
 698                        return ret;
 699
 700                if (v == 0)
 701                        return 0;
 702
 703                usleep_range(100, 200);
 704        } while (--limit);
 705
 706        return -EIO;
 707}
 708
 709/* Charger power supply property routines */
 710
 711static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
 712                union power_supply_propval *val)
 713{
 714        u8 v;
 715        int type, ret;
 716
 717        ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 718                        BQ24190_REG_POC_CHG_CONFIG_MASK,
 719                        BQ24190_REG_POC_CHG_CONFIG_SHIFT,
 720                        &v);
 721        if (ret < 0)
 722                return ret;
 723
 724        /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
 725        if (!v) {
 726                type = POWER_SUPPLY_CHARGE_TYPE_NONE;
 727        } else {
 728                ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 729                                BQ24190_REG_CCC_FORCE_20PCT_MASK,
 730                                BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 731                                &v);
 732                if (ret < 0)
 733                        return ret;
 734
 735                type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
 736                             POWER_SUPPLY_CHARGE_TYPE_FAST;
 737        }
 738
 739        val->intval = type;
 740
 741        return 0;
 742}
 743
 744static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
 745                const union power_supply_propval *val)
 746{
 747        u8 chg_config, force_20pct, en_term;
 748        int ret;
 749
 750        /*
 751         * According to the "Termination when REG02[0] = 1" section of
 752         * the bq24190 manual, the trickle charge could be less than the
 753         * termination current so it recommends turning off the termination
 754         * function.
 755         *
 756         * Note: AFAICT from the datasheet, the user will have to manually
 757         * turn off the charging when in 20% mode.  If its not turned off,
 758         * there could be battery damage.  So, use this mode at your own risk.
 759         */
 760        switch (val->intval) {
 761        case POWER_SUPPLY_CHARGE_TYPE_NONE:
 762                chg_config = 0x0;
 763                break;
 764        case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
 765                chg_config = 0x1;
 766                force_20pct = 0x1;
 767                en_term = 0x0;
 768                break;
 769        case POWER_SUPPLY_CHARGE_TYPE_FAST:
 770                chg_config = 0x1;
 771                force_20pct = 0x0;
 772                en_term = 0x1;
 773                break;
 774        default:
 775                return -EINVAL;
 776        }
 777
 778        if (chg_config) { /* Enabling the charger */
 779                ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
 780                                BQ24190_REG_CCC_FORCE_20PCT_MASK,
 781                                BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 782                                force_20pct);
 783                if (ret < 0)
 784                        return ret;
 785
 786                ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
 787                                BQ24190_REG_CTTC_EN_TERM_MASK,
 788                                BQ24190_REG_CTTC_EN_TERM_SHIFT,
 789                                en_term);
 790                if (ret < 0)
 791                        return ret;
 792        }
 793
 794        return bq24190_write_mask(bdi, BQ24190_REG_POC,
 795                        BQ24190_REG_POC_CHG_CONFIG_MASK,
 796                        BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
 797}
 798
 799static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
 800                union power_supply_propval *val)
 801{
 802        u8 v;
 803        int health;
 804
 805        mutex_lock(&bdi->f_reg_lock);
 806        v = bdi->f_reg;
 807        mutex_unlock(&bdi->f_reg_lock);
 808
 809        if (v & BQ24190_REG_F_NTC_FAULT_MASK) {
 810                switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
 811                case 0x1: /* TS1  Cold */
 812                case 0x3: /* TS2  Cold */
 813                case 0x5: /* Both Cold */
 814                        health = POWER_SUPPLY_HEALTH_COLD;
 815                        break;
 816                case 0x2: /* TS1  Hot */
 817                case 0x4: /* TS2  Hot */
 818                case 0x6: /* Both Hot */
 819                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
 820                        break;
 821                default:
 822                        health = POWER_SUPPLY_HEALTH_UNKNOWN;
 823                }
 824        } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
 825                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
 826        } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
 827                switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
 828                case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
 829                        /*
 830                         * This could be over-voltage or under-voltage
 831                         * and there's no way to tell which.  Instead
 832                         * of looking foolish and returning 'OVERVOLTAGE'
 833                         * when its really under-voltage, just return
 834                         * 'UNSPEC_FAILURE'.
 835                         */
 836                        health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
 837                        break;
 838                case 0x2: /* Thermal Shutdown */
 839                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
 840                        break;
 841                case 0x3: /* Charge Safety Timer Expiration */
 842                        health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
 843                        break;
 844                default:  /* prevent compiler warning */
 845                        health = -1;
 846                }
 847        } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
 848                /*
 849                 * This could be over-current or over-voltage but there's
 850                 * no way to tell which.  Return 'OVERVOLTAGE' since there
 851                 * isn't an 'OVERCURRENT' value defined that we can return
 852                 * even if it was over-current.
 853                 */
 854                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
 855        } else {
 856                health = POWER_SUPPLY_HEALTH_GOOD;
 857        }
 858
 859        val->intval = health;
 860
 861        return 0;
 862}
 863
 864static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
 865                union power_supply_propval *val)
 866{
 867        u8 pg_stat, batfet_disable;
 868        int ret;
 869
 870        ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
 871                        BQ24190_REG_SS_PG_STAT_MASK,
 872                        BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
 873        if (ret < 0)
 874                return ret;
 875
 876        ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
 877                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
 878                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
 879        if (ret < 0)
 880                return ret;
 881
 882        val->intval = pg_stat && !batfet_disable;
 883
 884        return 0;
 885}
 886
 887static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
 888                                      const union power_supply_propval *val);
 889static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
 890                                      union power_supply_propval *val);
 891static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
 892                                              union power_supply_propval *val);
 893static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
 894                                              const union power_supply_propval *val);
 895
 896static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
 897                                      const union power_supply_propval *val)
 898{
 899        return bq24190_battery_set_online(bdi, val);
 900}
 901
 902static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
 903                                      union power_supply_propval *val)
 904{
 905        return bq24190_battery_get_status(bdi, val);
 906}
 907
 908static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
 909                                              union power_supply_propval *val)
 910{
 911        return bq24190_battery_get_temp_alert_max(bdi, val);
 912}
 913
 914static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
 915                                              const union power_supply_propval *val)
 916{
 917        return bq24190_battery_set_temp_alert_max(bdi, val);
 918}
 919
 920static int bq24190_charger_get_precharge(struct bq24190_dev_info *bdi,
 921                union power_supply_propval *val)
 922{
 923        u8 v;
 924        int ret;
 925
 926        ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
 927                        BQ24190_REG_PCTCC_IPRECHG_MASK,
 928                        BQ24190_REG_PCTCC_IPRECHG_SHIFT, &v);
 929        if (ret < 0)
 930                return ret;
 931
 932        val->intval = ++v * 128 * 1000;
 933        return 0;
 934}
 935
 936static int bq24190_charger_get_charge_term(struct bq24190_dev_info *bdi,
 937                union power_supply_propval *val)
 938{
 939        u8 v;
 940        int ret;
 941
 942        ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
 943                        BQ24190_REG_PCTCC_ITERM_MASK,
 944                        BQ24190_REG_PCTCC_ITERM_SHIFT, &v);
 945        if (ret < 0)
 946                return ret;
 947
 948        val->intval = ++v * 128 * 1000;
 949        return 0;
 950}
 951
 952static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
 953                union power_supply_propval *val)
 954{
 955        u8 v;
 956        int curr, ret;
 957
 958        ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
 959                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
 960                        bq24190_ccc_ichg_values,
 961                        ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
 962        if (ret < 0)
 963                return ret;
 964
 965        ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 966                        BQ24190_REG_CCC_FORCE_20PCT_MASK,
 967                        BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 968        if (ret < 0)
 969                return ret;
 970
 971        /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
 972        if (v)
 973                curr /= 5;
 974
 975        val->intval = curr;
 976        return 0;
 977}
 978
 979static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
 980                union power_supply_propval *val)
 981{
 982        int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
 983
 984        val->intval = bq24190_ccc_ichg_values[idx];
 985        return 0;
 986}
 987
 988static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
 989                const union power_supply_propval *val)
 990{
 991        u8 v;
 992        int ret, curr = val->intval;
 993
 994        ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 995                        BQ24190_REG_CCC_FORCE_20PCT_MASK,
 996                        BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 997        if (ret < 0)
 998                return ret;
 999
1000        /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
1001        if (v)
1002                curr *= 5;
1003
1004        return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
1005                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1006                        bq24190_ccc_ichg_values,
1007                        ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
1008}
1009
1010static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
1011                union power_supply_propval *val)
1012{
1013        int voltage, ret;
1014
1015        ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
1016                        BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1017                        bq24190_cvc_vreg_values,
1018                        ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
1019        if (ret < 0)
1020                return ret;
1021
1022        val->intval = voltage;
1023        return 0;
1024}
1025
1026static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
1027                union power_supply_propval *val)
1028{
1029        int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
1030
1031        val->intval = bq24190_cvc_vreg_values[idx];
1032        return 0;
1033}
1034
1035static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
1036                const union power_supply_propval *val)
1037{
1038        return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
1039                        BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1040                        bq24190_cvc_vreg_values,
1041                        ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
1042}
1043
1044static int bq24190_charger_get_iinlimit(struct bq24190_dev_info *bdi,
1045                union power_supply_propval *val)
1046{
1047        int iinlimit, ret;
1048
1049        ret = bq24190_get_field_val(bdi, BQ24190_REG_ISC,
1050                        BQ24190_REG_ISC_IINLIM_MASK,
1051                        BQ24190_REG_ISC_IINLIM_SHIFT,
1052                        bq24190_isc_iinlim_values,
1053                        ARRAY_SIZE(bq24190_isc_iinlim_values), &iinlimit);
1054        if (ret < 0)
1055                return ret;
1056
1057        val->intval = iinlimit;
1058        return 0;
1059}
1060
1061static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi,
1062                const union power_supply_propval *val)
1063{
1064        return bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1065                        BQ24190_REG_ISC_IINLIM_MASK,
1066                        BQ24190_REG_ISC_IINLIM_SHIFT,
1067                        bq24190_isc_iinlim_values,
1068                        ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval);
1069}
1070
1071static int bq24190_charger_get_property(struct power_supply *psy,
1072                enum power_supply_property psp, union power_supply_propval *val)
1073{
1074        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1075        int ret;
1076
1077        dev_dbg(bdi->dev, "prop: %d\n", psp);
1078
1079        ret = pm_runtime_get_sync(bdi->dev);
1080        if (ret < 0)
1081                return ret;
1082
1083        switch (psp) {
1084        case POWER_SUPPLY_PROP_CHARGE_TYPE:
1085                ret = bq24190_charger_get_charge_type(bdi, val);
1086                break;
1087        case POWER_SUPPLY_PROP_HEALTH:
1088                ret = bq24190_charger_get_health(bdi, val);
1089                break;
1090        case POWER_SUPPLY_PROP_ONLINE:
1091                ret = bq24190_charger_get_online(bdi, val);
1092                break;
1093        case POWER_SUPPLY_PROP_STATUS:
1094                ret = bq24190_charger_get_status(bdi, val);
1095                break;
1096        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1097                ret =  bq24190_charger_get_temp_alert_max(bdi, val);
1098                break;
1099        case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
1100                ret = bq24190_charger_get_precharge(bdi, val);
1101                break;
1102        case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
1103                ret = bq24190_charger_get_charge_term(bdi, val);
1104                break;
1105        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1106                ret = bq24190_charger_get_current(bdi, val);
1107                break;
1108        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
1109                ret = bq24190_charger_get_current_max(bdi, val);
1110                break;
1111        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1112                ret = bq24190_charger_get_voltage(bdi, val);
1113                break;
1114        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
1115                ret = bq24190_charger_get_voltage_max(bdi, val);
1116                break;
1117        case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1118                ret = bq24190_charger_get_iinlimit(bdi, val);
1119                break;
1120        case POWER_SUPPLY_PROP_SCOPE:
1121                val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1122                ret = 0;
1123                break;
1124        case POWER_SUPPLY_PROP_MODEL_NAME:
1125                val->strval = bdi->model_name;
1126                ret = 0;
1127                break;
1128        case POWER_SUPPLY_PROP_MANUFACTURER:
1129                val->strval = BQ24190_MANUFACTURER;
1130                ret = 0;
1131                break;
1132        default:
1133                ret = -ENODATA;
1134        }
1135
1136        pm_runtime_mark_last_busy(bdi->dev);
1137        pm_runtime_put_autosuspend(bdi->dev);
1138
1139        return ret;
1140}
1141
1142static int bq24190_charger_set_property(struct power_supply *psy,
1143                enum power_supply_property psp,
1144                const union power_supply_propval *val)
1145{
1146        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1147        int ret;
1148
1149        dev_dbg(bdi->dev, "prop: %d\n", psp);
1150
1151        ret = pm_runtime_get_sync(bdi->dev);
1152        if (ret < 0)
1153                return ret;
1154
1155        switch (psp) {
1156        case POWER_SUPPLY_PROP_ONLINE:
1157                ret = bq24190_charger_set_online(bdi, val);
1158                break;
1159        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1160                ret = bq24190_charger_set_temp_alert_max(bdi, val);
1161                break;
1162        case POWER_SUPPLY_PROP_CHARGE_TYPE:
1163                ret = bq24190_charger_set_charge_type(bdi, val);
1164                break;
1165        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1166                ret = bq24190_charger_set_current(bdi, val);
1167                break;
1168        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1169                ret = bq24190_charger_set_voltage(bdi, val);
1170                break;
1171        case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1172                ret = bq24190_charger_set_iinlimit(bdi, val);
1173                break;
1174        default:
1175                ret = -EINVAL;
1176        }
1177
1178        pm_runtime_mark_last_busy(bdi->dev);
1179        pm_runtime_put_autosuspend(bdi->dev);
1180
1181        return ret;
1182}
1183
1184static int bq24190_charger_property_is_writeable(struct power_supply *psy,
1185                enum power_supply_property psp)
1186{
1187        switch (psp) {
1188        case POWER_SUPPLY_PROP_ONLINE:
1189        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1190        case POWER_SUPPLY_PROP_CHARGE_TYPE:
1191        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1192        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1193        case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1194                return 1;
1195        default:
1196                return 0;
1197        }
1198}
1199
1200static void bq24190_input_current_limit_work(struct work_struct *work)
1201{
1202        struct bq24190_dev_info *bdi =
1203                container_of(work, struct bq24190_dev_info,
1204                             input_current_limit_work.work);
1205
1206        power_supply_set_input_current_limit_from_supplier(bdi->charger);
1207}
1208
1209/* Sync the input-current-limit with our parent supply (if we have one) */
1210static void bq24190_charger_external_power_changed(struct power_supply *psy)
1211{
1212        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1213
1214        /*
1215         * The Power-Good detection may take up to 220ms, sometimes
1216         * the external charger detection is quicker, and the bq24190 will
1217         * reset to iinlim based on its own charger detection (which is not
1218         * hooked up when using external charger detection) resulting in a
1219         * too low default 500mA iinlim. Delay setting the input-current-limit
1220         * for 300ms to avoid this.
1221         */
1222        queue_delayed_work(system_wq, &bdi->input_current_limit_work,
1223                           msecs_to_jiffies(300));
1224}
1225
1226static enum power_supply_property bq24190_charger_properties[] = {
1227        POWER_SUPPLY_PROP_CHARGE_TYPE,
1228        POWER_SUPPLY_PROP_HEALTH,
1229        POWER_SUPPLY_PROP_ONLINE,
1230        POWER_SUPPLY_PROP_STATUS,
1231        POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1232        POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
1233        POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
1234        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
1235        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
1236        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
1237        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
1238        POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1239        POWER_SUPPLY_PROP_SCOPE,
1240        POWER_SUPPLY_PROP_MODEL_NAME,
1241        POWER_SUPPLY_PROP_MANUFACTURER,
1242};
1243
1244static char *bq24190_charger_supplied_to[] = {
1245        "main-battery",
1246};
1247
1248static const struct power_supply_desc bq24190_charger_desc = {
1249        .name                   = "bq24190-charger",
1250        .type                   = POWER_SUPPLY_TYPE_USB,
1251        .properties             = bq24190_charger_properties,
1252        .num_properties         = ARRAY_SIZE(bq24190_charger_properties),
1253        .get_property           = bq24190_charger_get_property,
1254        .set_property           = bq24190_charger_set_property,
1255        .property_is_writeable  = bq24190_charger_property_is_writeable,
1256        .external_power_changed = bq24190_charger_external_power_changed,
1257};
1258
1259/* Battery power supply property routines */
1260
1261static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1262                union power_supply_propval *val)
1263{
1264        u8 ss_reg, chrg_fault;
1265        int status, ret;
1266
1267        mutex_lock(&bdi->f_reg_lock);
1268        chrg_fault = bdi->f_reg;
1269        mutex_unlock(&bdi->f_reg_lock);
1270
1271        chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
1272        chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
1273
1274        ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1275        if (ret < 0)
1276                return ret;
1277
1278        /*
1279         * The battery must be discharging when any of these are true:
1280         * - there is no good power source;
1281         * - there is a charge fault.
1282         * Could also be discharging when in "supplement mode" but
1283         * there is no way to tell when its in that mode.
1284         */
1285        if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
1286                status = POWER_SUPPLY_STATUS_DISCHARGING;
1287        } else {
1288                ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
1289                ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
1290
1291                switch (ss_reg) {
1292                case 0x0: /* Not Charging */
1293                        status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1294                        break;
1295                case 0x1: /* Pre-charge */
1296                case 0x2: /* Fast Charging */
1297                        status = POWER_SUPPLY_STATUS_CHARGING;
1298                        break;
1299                case 0x3: /* Charge Termination Done */
1300                        status = POWER_SUPPLY_STATUS_FULL;
1301                        break;
1302                default:
1303                        ret = -EIO;
1304                }
1305        }
1306
1307        if (!ret)
1308                val->intval = status;
1309
1310        return ret;
1311}
1312
1313static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1314                union power_supply_propval *val)
1315{
1316        u8 v;
1317        int health;
1318
1319        mutex_lock(&bdi->f_reg_lock);
1320        v = bdi->f_reg;
1321        mutex_unlock(&bdi->f_reg_lock);
1322
1323        if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1324                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1325        } else {
1326                v &= BQ24190_REG_F_NTC_FAULT_MASK;
1327                v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1328
1329                switch (v) {
1330                case 0x0: /* Normal */
1331                        health = POWER_SUPPLY_HEALTH_GOOD;
1332                        break;
1333                case 0x1: /* TS1 Cold */
1334                case 0x3: /* TS2 Cold */
1335                case 0x5: /* Both Cold */
1336                        health = POWER_SUPPLY_HEALTH_COLD;
1337                        break;
1338                case 0x2: /* TS1 Hot */
1339                case 0x4: /* TS2 Hot */
1340                case 0x6: /* Both Hot */
1341                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
1342                        break;
1343                default:
1344                        health = POWER_SUPPLY_HEALTH_UNKNOWN;
1345                }
1346        }
1347
1348        val->intval = health;
1349        return 0;
1350}
1351
1352static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1353                union power_supply_propval *val)
1354{
1355        u8 batfet_disable;
1356        int ret;
1357
1358        ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1359                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1360                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1361        if (ret < 0)
1362                return ret;
1363
1364        val->intval = !batfet_disable;
1365        return 0;
1366}
1367
1368static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1369                const union power_supply_propval *val)
1370{
1371        return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1372                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1373                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1374}
1375
1376static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1377                union power_supply_propval *val)
1378{
1379        int temp, ret;
1380
1381        ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1382                        BQ24190_REG_ICTRC_TREG_MASK,
1383                        BQ24190_REG_ICTRC_TREG_SHIFT,
1384                        bq24190_ictrc_treg_values,
1385                        ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1386        if (ret < 0)
1387                return ret;
1388
1389        val->intval = temp;
1390        return 0;
1391}
1392
1393static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1394                const union power_supply_propval *val)
1395{
1396        return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1397                        BQ24190_REG_ICTRC_TREG_MASK,
1398                        BQ24190_REG_ICTRC_TREG_SHIFT,
1399                        bq24190_ictrc_treg_values,
1400                        ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1401}
1402
1403static int bq24190_battery_get_property(struct power_supply *psy,
1404                enum power_supply_property psp, union power_supply_propval *val)
1405{
1406        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1407        int ret;
1408
1409        dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1410        dev_dbg(bdi->dev, "prop: %d\n", psp);
1411
1412        ret = pm_runtime_get_sync(bdi->dev);
1413        if (ret < 0)
1414                return ret;
1415
1416        switch (psp) {
1417        case POWER_SUPPLY_PROP_STATUS:
1418                ret = bq24190_battery_get_status(bdi, val);
1419                break;
1420        case POWER_SUPPLY_PROP_HEALTH:
1421                ret = bq24190_battery_get_health(bdi, val);
1422                break;
1423        case POWER_SUPPLY_PROP_ONLINE:
1424                ret = bq24190_battery_get_online(bdi, val);
1425                break;
1426        case POWER_SUPPLY_PROP_TECHNOLOGY:
1427                /* Could be Li-on or Li-polymer but no way to tell which */
1428                val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1429                ret = 0;
1430                break;
1431        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1432                ret = bq24190_battery_get_temp_alert_max(bdi, val);
1433                break;
1434        case POWER_SUPPLY_PROP_SCOPE:
1435                val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1436                ret = 0;
1437                break;
1438        default:
1439                ret = -ENODATA;
1440        }
1441
1442        pm_runtime_mark_last_busy(bdi->dev);
1443        pm_runtime_put_autosuspend(bdi->dev);
1444
1445        return ret;
1446}
1447
1448static int bq24190_battery_set_property(struct power_supply *psy,
1449                enum power_supply_property psp,
1450                const union power_supply_propval *val)
1451{
1452        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1453        int ret;
1454
1455        dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1456        dev_dbg(bdi->dev, "prop: %d\n", psp);
1457
1458        ret = pm_runtime_get_sync(bdi->dev);
1459        if (ret < 0)
1460                return ret;
1461
1462        switch (psp) {
1463        case POWER_SUPPLY_PROP_ONLINE:
1464                ret = bq24190_battery_set_online(bdi, val);
1465                break;
1466        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1467                ret = bq24190_battery_set_temp_alert_max(bdi, val);
1468                break;
1469        default:
1470                ret = -EINVAL;
1471        }
1472
1473        pm_runtime_mark_last_busy(bdi->dev);
1474        pm_runtime_put_autosuspend(bdi->dev);
1475
1476        return ret;
1477}
1478
1479static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1480                enum power_supply_property psp)
1481{
1482        int ret;
1483
1484        switch (psp) {
1485        case POWER_SUPPLY_PROP_ONLINE:
1486        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1487                ret = 1;
1488                break;
1489        default:
1490                ret = 0;
1491        }
1492
1493        return ret;
1494}
1495
1496static enum power_supply_property bq24190_battery_properties[] = {
1497        POWER_SUPPLY_PROP_STATUS,
1498        POWER_SUPPLY_PROP_HEALTH,
1499        POWER_SUPPLY_PROP_ONLINE,
1500        POWER_SUPPLY_PROP_TECHNOLOGY,
1501        POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1502        POWER_SUPPLY_PROP_SCOPE,
1503};
1504
1505static const struct power_supply_desc bq24190_battery_desc = {
1506        .name                   = "bq24190-battery",
1507        .type                   = POWER_SUPPLY_TYPE_BATTERY,
1508        .properties             = bq24190_battery_properties,
1509        .num_properties         = ARRAY_SIZE(bq24190_battery_properties),
1510        .get_property           = bq24190_battery_get_property,
1511        .set_property           = bq24190_battery_set_property,
1512        .property_is_writeable  = bq24190_battery_property_is_writeable,
1513};
1514
1515static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
1516{
1517        bool otg_enabled;
1518        int ret;
1519
1520        otg_enabled = !!(ss_reg & BQ24190_REG_SS_VBUS_STAT_MASK);
1521        ret = extcon_set_state_sync(bdi->edev, EXTCON_USB, otg_enabled);
1522        if (ret < 0)
1523                dev_err(bdi->dev, "Can't set extcon state to %d: %d\n",
1524                        otg_enabled, ret);
1525
1526        return ret;
1527}
1528
1529static void bq24190_check_status(struct bq24190_dev_info *bdi)
1530{
1531        const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1532        const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1533                                | BQ24190_REG_F_NTC_FAULT_MASK;
1534        bool alert_charger = false, alert_battery = false;
1535        u8 ss_reg = 0, f_reg = 0;
1536        int i, ret;
1537
1538        ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1539        if (ret < 0) {
1540                dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1541                return;
1542        }
1543
1544        i = 0;
1545        do {
1546                ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1547                if (ret < 0) {
1548                        dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1549                        return;
1550                }
1551        } while (f_reg && ++i < 2);
1552
1553        /* ignore over/under voltage fault after disconnect */
1554        if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1555            !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1556                f_reg = 0;
1557
1558        if (f_reg != bdi->f_reg) {
1559                dev_warn(bdi->dev,
1560                        "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1561                        !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1562                        !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1563                        !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1564                        !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1565
1566                mutex_lock(&bdi->f_reg_lock);
1567                if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1568                        alert_battery = true;
1569                if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1570                        alert_charger = true;
1571                bdi->f_reg = f_reg;
1572                mutex_unlock(&bdi->f_reg_lock);
1573        }
1574
1575        if (ss_reg != bdi->ss_reg) {
1576                /*
1577                 * The device is in host mode so when PG_STAT goes from 1->0
1578                 * (i.e., power removed) HIZ needs to be disabled.
1579                 */
1580                if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1581                                !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1582                        ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1583                                        BQ24190_REG_ISC_EN_HIZ_MASK,
1584                                        BQ24190_REG_ISC_EN_HIZ_SHIFT,
1585                                        0);
1586                        if (ret < 0)
1587                                dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1588                                        ret);
1589                }
1590
1591                if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1592                        alert_battery = true;
1593                if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1594                        alert_charger = true;
1595                bdi->ss_reg = ss_reg;
1596        }
1597
1598        if (alert_charger || alert_battery) {
1599                power_supply_changed(bdi->charger);
1600                bq24190_configure_usb_otg(bdi, ss_reg);
1601        }
1602        if (alert_battery && bdi->battery)
1603                power_supply_changed(bdi->battery);
1604
1605        dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1606}
1607
1608static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1609{
1610        struct bq24190_dev_info *bdi = data;
1611        int error;
1612
1613        bdi->irq_event = true;
1614        error = pm_runtime_get_sync(bdi->dev);
1615        if (error < 0) {
1616                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1617                pm_runtime_put_noidle(bdi->dev);
1618                return IRQ_NONE;
1619        }
1620        bq24190_check_status(bdi);
1621        pm_runtime_mark_last_busy(bdi->dev);
1622        pm_runtime_put_autosuspend(bdi->dev);
1623        bdi->irq_event = false;
1624
1625        return IRQ_HANDLED;
1626}
1627
1628static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1629{
1630        u8 v;
1631        int ret;
1632
1633        /* First check that the device really is what its supposed to be */
1634        ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1635                        BQ24190_REG_VPRS_PN_MASK,
1636                        BQ24190_REG_VPRS_PN_SHIFT,
1637                        &v);
1638        if (ret < 0)
1639                return ret;
1640
1641        switch (v) {
1642        case BQ24190_REG_VPRS_PN_24190:
1643        case BQ24190_REG_VPRS_PN_24192:
1644        case BQ24190_REG_VPRS_PN_24192I:
1645                break;
1646        default:
1647                dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1648                return -ENODEV;
1649        }
1650
1651        ret = bq24190_register_reset(bdi);
1652        if (ret < 0)
1653                return ret;
1654
1655        ret = bq24190_set_config(bdi);
1656        if (ret < 0)
1657                return ret;
1658
1659        return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1660}
1661
1662static int bq24190_get_config(struct bq24190_dev_info *bdi)
1663{
1664        const char * const s = "ti,system-minimum-microvolt";
1665        struct power_supply_battery_info info = {};
1666        int v;
1667
1668        if (device_property_read_u32(bdi->dev, s, &v) == 0) {
1669                v /= 1000;
1670                if (v >= BQ24190_REG_POC_SYS_MIN_MIN
1671                 && v <= BQ24190_REG_POC_SYS_MIN_MAX)
1672                        bdi->sys_min = v;
1673                else
1674                        dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v);
1675        }
1676
1677        if (bdi->dev->of_node &&
1678            !power_supply_get_battery_info(bdi->charger, &info)) {
1679                v = info.precharge_current_ua / 1000;
1680                if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
1681                 && v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
1682                        bdi->iprechg = v;
1683                else
1684                        dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
1685                                 v);
1686
1687                v = info.charge_term_current_ua / 1000;
1688                if (v >= BQ24190_REG_PCTCC_ITERM_MIN
1689                 && v <= BQ24190_REG_PCTCC_ITERM_MAX)
1690                        bdi->iterm = v;
1691                else
1692                        dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n",
1693                                 v);
1694        }
1695
1696        return 0;
1697}
1698
1699static int bq24190_probe(struct i2c_client *client,
1700                const struct i2c_device_id *id)
1701{
1702        struct i2c_adapter *adapter = client->adapter;
1703        struct device *dev = &client->dev;
1704        struct power_supply_config charger_cfg = {}, battery_cfg = {};
1705        struct bq24190_dev_info *bdi;
1706        int ret;
1707
1708        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1709                dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1710                return -ENODEV;
1711        }
1712
1713        bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1714        if (!bdi) {
1715                dev_err(dev, "Can't alloc bdi struct\n");
1716                return -ENOMEM;
1717        }
1718
1719        bdi->client = client;
1720        bdi->dev = dev;
1721        strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1722        mutex_init(&bdi->f_reg_lock);
1723        bdi->f_reg = 0;
1724        bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1725        INIT_DELAYED_WORK(&bdi->input_current_limit_work,
1726                          bq24190_input_current_limit_work);
1727
1728        i2c_set_clientdata(client, bdi);
1729
1730        if (client->irq <= 0) {
1731                dev_err(dev, "Can't get irq info\n");
1732                return -EINVAL;
1733        }
1734
1735        bdi->edev = devm_extcon_dev_allocate(dev, bq24190_usb_extcon_cable);
1736        if (IS_ERR(bdi->edev))
1737                return PTR_ERR(bdi->edev);
1738
1739        ret = devm_extcon_dev_register(dev, bdi->edev);
1740        if (ret < 0)
1741                return ret;
1742
1743        pm_runtime_enable(dev);
1744        pm_runtime_use_autosuspend(dev);
1745        pm_runtime_set_autosuspend_delay(dev, 600);
1746        ret = pm_runtime_get_sync(dev);
1747        if (ret < 0) {
1748                dev_err(dev, "pm_runtime_get failed: %i\n", ret);
1749                goto out_pmrt;
1750        }
1751
1752#ifdef CONFIG_SYSFS
1753        bq24190_sysfs_init_attrs();
1754        charger_cfg.attr_grp = bq24190_sysfs_groups;
1755#endif
1756
1757        charger_cfg.drv_data = bdi;
1758        charger_cfg.of_node = dev->of_node;
1759        charger_cfg.supplied_to = bq24190_charger_supplied_to;
1760        charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1761        bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1762                                                &charger_cfg);
1763        if (IS_ERR(bdi->charger)) {
1764                dev_err(dev, "Can't register charger\n");
1765                ret = PTR_ERR(bdi->charger);
1766                goto out_pmrt;
1767        }
1768
1769        /* the battery class is deprecated and will be removed. */
1770        /* in the interim, this property hides it.              */
1771        if (!device_property_read_bool(dev, "omit-battery-class")) {
1772                battery_cfg.drv_data = bdi;
1773                bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1774                                                     &battery_cfg);
1775                if (IS_ERR(bdi->battery)) {
1776                        dev_err(dev, "Can't register battery\n");
1777                        ret = PTR_ERR(bdi->battery);
1778                        goto out_charger;
1779                }
1780        }
1781
1782        ret = bq24190_get_config(bdi);
1783        if (ret < 0) {
1784                dev_err(dev, "Can't get devicetree config\n");
1785                goto out_charger;
1786        }
1787
1788        ret = bq24190_hw_init(bdi);
1789        if (ret < 0) {
1790                dev_err(dev, "Hardware init failed\n");
1791                goto out_charger;
1792        }
1793
1794        ret = bq24190_configure_usb_otg(bdi, bdi->ss_reg);
1795        if (ret < 0)
1796                goto out_charger;
1797
1798        bdi->initialized = true;
1799
1800        ret = devm_request_threaded_irq(dev, client->irq, NULL,
1801                        bq24190_irq_handler_thread,
1802                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1803                        "bq24190-charger", bdi);
1804        if (ret < 0) {
1805                dev_err(dev, "Can't set up irq handler\n");
1806                goto out_charger;
1807        }
1808
1809        ret = bq24190_register_vbus_regulator(bdi);
1810        if (ret < 0)
1811                goto out_charger;
1812
1813        enable_irq_wake(client->irq);
1814
1815        pm_runtime_mark_last_busy(dev);
1816        pm_runtime_put_autosuspend(dev);
1817
1818        return 0;
1819
1820out_charger:
1821        if (!IS_ERR_OR_NULL(bdi->battery))
1822                power_supply_unregister(bdi->battery);
1823        power_supply_unregister(bdi->charger);
1824
1825out_pmrt:
1826        pm_runtime_put_sync(dev);
1827        pm_runtime_dont_use_autosuspend(dev);
1828        pm_runtime_disable(dev);
1829        return ret;
1830}
1831
1832static int bq24190_remove(struct i2c_client *client)
1833{
1834        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1835        int error;
1836
1837        error = pm_runtime_get_sync(bdi->dev);
1838        if (error < 0) {
1839                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1840                pm_runtime_put_noidle(bdi->dev);
1841        }
1842
1843        bq24190_register_reset(bdi);
1844        if (bdi->battery)
1845                power_supply_unregister(bdi->battery);
1846        power_supply_unregister(bdi->charger);
1847        if (error >= 0)
1848                pm_runtime_put_sync(bdi->dev);
1849        pm_runtime_dont_use_autosuspend(bdi->dev);
1850        pm_runtime_disable(bdi->dev);
1851
1852        return 0;
1853}
1854
1855static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
1856{
1857        struct i2c_client *client = to_i2c_client(dev);
1858        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1859
1860        if (!bdi->initialized)
1861                return 0;
1862
1863        dev_dbg(bdi->dev, "%s\n", __func__);
1864
1865        return 0;
1866}
1867
1868static __maybe_unused int bq24190_runtime_resume(struct device *dev)
1869{
1870        struct i2c_client *client = to_i2c_client(dev);
1871        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1872
1873        if (!bdi->initialized)
1874                return 0;
1875
1876        if (!bdi->irq_event) {
1877                dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
1878                bq24190_check_status(bdi);
1879        }
1880
1881        return 0;
1882}
1883
1884static __maybe_unused int bq24190_pm_suspend(struct device *dev)
1885{
1886        struct i2c_client *client = to_i2c_client(dev);
1887        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1888        int error;
1889
1890        error = pm_runtime_get_sync(bdi->dev);
1891        if (error < 0) {
1892                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1893                pm_runtime_put_noidle(bdi->dev);
1894        }
1895
1896        bq24190_register_reset(bdi);
1897
1898        if (error >= 0) {
1899                pm_runtime_mark_last_busy(bdi->dev);
1900                pm_runtime_put_autosuspend(bdi->dev);
1901        }
1902
1903        return 0;
1904}
1905
1906static __maybe_unused int bq24190_pm_resume(struct device *dev)
1907{
1908        struct i2c_client *client = to_i2c_client(dev);
1909        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1910        int error;
1911
1912        bdi->f_reg = 0;
1913        bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1914
1915        error = pm_runtime_get_sync(bdi->dev);
1916        if (error < 0) {
1917                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1918                pm_runtime_put_noidle(bdi->dev);
1919        }
1920
1921        bq24190_register_reset(bdi);
1922        bq24190_set_config(bdi);
1923        bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1924
1925        if (error >= 0) {
1926                pm_runtime_mark_last_busy(bdi->dev);
1927                pm_runtime_put_autosuspend(bdi->dev);
1928        }
1929
1930        /* Things may have changed while suspended so alert upper layer */
1931        power_supply_changed(bdi->charger);
1932        if (bdi->battery)
1933                power_supply_changed(bdi->battery);
1934
1935        return 0;
1936}
1937
1938static const struct dev_pm_ops bq24190_pm_ops = {
1939        SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
1940                           NULL)
1941        SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
1942};
1943
1944static const struct i2c_device_id bq24190_i2c_ids[] = {
1945        { "bq24190" },
1946        { "bq24192" },
1947        { "bq24192i" },
1948        { "bq24196" },
1949        { },
1950};
1951MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1952
1953#ifdef CONFIG_OF
1954static const struct of_device_id bq24190_of_match[] = {
1955        { .compatible = "ti,bq24190", },
1956        { .compatible = "ti,bq24192", },
1957        { .compatible = "ti,bq24192i", },
1958        { .compatible = "ti,bq24196", },
1959        { },
1960};
1961MODULE_DEVICE_TABLE(of, bq24190_of_match);
1962#else
1963static const struct of_device_id bq24190_of_match[] = {
1964        { },
1965};
1966#endif
1967
1968static struct i2c_driver bq24190_driver = {
1969        .probe          = bq24190_probe,
1970        .remove         = bq24190_remove,
1971        .id_table       = bq24190_i2c_ids,
1972        .driver = {
1973                .name           = "bq24190-charger",
1974                .pm             = &bq24190_pm_ops,
1975                .of_match_table = of_match_ptr(bq24190_of_match),
1976        },
1977};
1978module_i2c_driver(bq24190_driver);
1979
1980MODULE_LICENSE("GPL");
1981MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1982MODULE_DESCRIPTION("TI BQ24190 Charger Driver");
1983