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                return ret;
 486
 487        ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
 488        if (ret)
 489                count = ret;
 490
 491        pm_runtime_mark_last_busy(bdi->dev);
 492        pm_runtime_put_autosuspend(bdi->dev);
 493
 494        return count;
 495}
 496#endif
 497
 498#ifdef CONFIG_REGULATOR
 499static int bq24190_set_charge_mode(struct regulator_dev *dev, u8 val)
 500{
 501        struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
 502        int ret;
 503
 504        ret = pm_runtime_get_sync(bdi->dev);
 505        if (ret < 0) {
 506                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
 507                pm_runtime_put_noidle(bdi->dev);
 508                return ret;
 509        }
 510
 511        ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 512                                 BQ24190_REG_POC_CHG_CONFIG_MASK,
 513                                 BQ24190_REG_POC_CHG_CONFIG_SHIFT, val);
 514
 515        pm_runtime_mark_last_busy(bdi->dev);
 516        pm_runtime_put_autosuspend(bdi->dev);
 517
 518        return ret;
 519}
 520
 521static int bq24190_vbus_enable(struct regulator_dev *dev)
 522{
 523        return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_OTG);
 524}
 525
 526static int bq24190_vbus_disable(struct regulator_dev *dev)
 527{
 528        return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_CHARGE);
 529}
 530
 531static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
 532{
 533        struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
 534        int ret;
 535        u8 val;
 536
 537        ret = pm_runtime_get_sync(bdi->dev);
 538        if (ret < 0) {
 539                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
 540                pm_runtime_put_noidle(bdi->dev);
 541                return ret;
 542        }
 543
 544        ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 545                                BQ24190_REG_POC_CHG_CONFIG_MASK,
 546                                BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
 547
 548        pm_runtime_mark_last_busy(bdi->dev);
 549        pm_runtime_put_autosuspend(bdi->dev);
 550
 551        return ret ? ret : val == BQ24190_REG_POC_CHG_CONFIG_OTG;
 552}
 553
 554static const struct regulator_ops bq24190_vbus_ops = {
 555        .enable = bq24190_vbus_enable,
 556        .disable = bq24190_vbus_disable,
 557        .is_enabled = bq24190_vbus_is_enabled,
 558};
 559
 560static const struct regulator_desc bq24190_vbus_desc = {
 561        .name = "usb_otg_vbus",
 562        .of_match = "usb-otg-vbus",
 563        .type = REGULATOR_VOLTAGE,
 564        .owner = THIS_MODULE,
 565        .ops = &bq24190_vbus_ops,
 566        .fixed_uV = 5000000,
 567        .n_voltages = 1,
 568};
 569
 570static const struct regulator_init_data bq24190_vbus_init_data = {
 571        .constraints = {
 572                .valid_ops_mask = REGULATOR_CHANGE_STATUS,
 573        },
 574};
 575
 576static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
 577{
 578        struct bq24190_platform_data *pdata = bdi->dev->platform_data;
 579        struct regulator_config cfg = { };
 580        struct regulator_dev *reg;
 581        int ret = 0;
 582
 583        cfg.dev = bdi->dev;
 584        if (pdata && pdata->regulator_init_data)
 585                cfg.init_data = pdata->regulator_init_data;
 586        else
 587                cfg.init_data = &bq24190_vbus_init_data;
 588        cfg.driver_data = bdi;
 589        reg = devm_regulator_register(bdi->dev, &bq24190_vbus_desc, &cfg);
 590        if (IS_ERR(reg)) {
 591                ret = PTR_ERR(reg);
 592                dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
 593        }
 594
 595        return ret;
 596}
 597#else
 598static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
 599{
 600        return 0;
 601}
 602#endif
 603
 604static int bq24190_set_config(struct bq24190_dev_info *bdi)
 605{
 606        int ret;
 607        u8 v;
 608
 609        ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
 610        if (ret < 0)
 611                return ret;
 612
 613        bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
 614                                        BQ24190_REG_CTTC_WATCHDOG_SHIFT);
 615
 616        /*
 617         * According to the "Host Mode and default Mode" section of the
 618         * manual, a write to any register causes the bq24190 to switch
 619         * from default mode to host mode.  It will switch back to default
 620         * mode after a WDT timeout unless the WDT is turned off as well.
 621         * So, by simply turning off the WDT, we accomplish both with the
 622         * same write.
 623         */
 624        v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
 625
 626        ret = bq24190_write(bdi, BQ24190_REG_CTTC, v);
 627        if (ret < 0)
 628                return ret;
 629
 630        if (bdi->sys_min) {
 631                v = bdi->sys_min / 100 - 30; // manual section 9.5.1.2, table 9
 632                ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 633                                         BQ24190_REG_POC_SYS_MIN_MASK,
 634                                         BQ24190_REG_POC_SYS_MIN_SHIFT,
 635                                         v);
 636                if (ret < 0)
 637                        return ret;
 638        }
 639
 640        if (bdi->iprechg) {
 641                v = bdi->iprechg / 128 - 1; // manual section 9.5.1.4, table 11
 642                ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
 643                                         BQ24190_REG_PCTCC_IPRECHG_MASK,
 644                                         BQ24190_REG_PCTCC_IPRECHG_SHIFT,
 645                                         v);
 646                if (ret < 0)
 647                        return ret;
 648        }
 649
 650        if (bdi->iterm) {
 651                v = bdi->iterm / 128 - 1; // manual section 9.5.1.4, table 11
 652                ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
 653                                         BQ24190_REG_PCTCC_ITERM_MASK,
 654                                         BQ24190_REG_PCTCC_ITERM_SHIFT,
 655                                         v);
 656                if (ret < 0)
 657                        return ret;
 658        }
 659
 660        return 0;
 661}
 662
 663static int bq24190_register_reset(struct bq24190_dev_info *bdi)
 664{
 665        int ret, limit = 100;
 666        u8 v;
 667
 668        /*
 669         * This prop. can be passed on device instantiation from platform code:
 670         * struct property_entry pe[] =
 671         *   { PROPERTY_ENTRY_BOOL("disable-reset"), ... };
 672         * struct i2c_board_info bi =
 673         *   { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
 674         * struct i2c_adapter ad = { ... };
 675         * i2c_add_adapter(&ad);
 676         * i2c_new_device(&ad, &bi);
 677         */
 678        if (device_property_read_bool(bdi->dev, "disable-reset"))
 679                return 0;
 680
 681        /* Reset the registers */
 682        ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
 683                        BQ24190_REG_POC_RESET_MASK,
 684                        BQ24190_REG_POC_RESET_SHIFT,
 685                        0x1);
 686        if (ret < 0)
 687                return ret;
 688
 689        /* Reset bit will be cleared by hardware so poll until it is */
 690        do {
 691                ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 692                                BQ24190_REG_POC_RESET_MASK,
 693                                BQ24190_REG_POC_RESET_SHIFT,
 694                                &v);
 695                if (ret < 0)
 696                        return ret;
 697
 698                if (v == 0)
 699                        return 0;
 700
 701                usleep_range(100, 200);
 702        } while (--limit);
 703
 704        return -EIO;
 705}
 706
 707/* Charger power supply property routines */
 708
 709static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
 710                union power_supply_propval *val)
 711{
 712        u8 v;
 713        int type, ret;
 714
 715        ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
 716                        BQ24190_REG_POC_CHG_CONFIG_MASK,
 717                        BQ24190_REG_POC_CHG_CONFIG_SHIFT,
 718                        &v);
 719        if (ret < 0)
 720                return ret;
 721
 722        /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
 723        if (!v) {
 724                type = POWER_SUPPLY_CHARGE_TYPE_NONE;
 725        } else {
 726                ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 727                                BQ24190_REG_CCC_FORCE_20PCT_MASK,
 728                                BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 729                                &v);
 730                if (ret < 0)
 731                        return ret;
 732
 733                type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
 734                             POWER_SUPPLY_CHARGE_TYPE_FAST;
 735        }
 736
 737        val->intval = type;
 738
 739        return 0;
 740}
 741
 742static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
 743                const union power_supply_propval *val)
 744{
 745        u8 chg_config, force_20pct, en_term;
 746        int ret;
 747
 748        /*
 749         * According to the "Termination when REG02[0] = 1" section of
 750         * the bq24190 manual, the trickle charge could be less than the
 751         * termination current so it recommends turning off the termination
 752         * function.
 753         *
 754         * Note: AFAICT from the datasheet, the user will have to manually
 755         * turn off the charging when in 20% mode.  If its not turned off,
 756         * there could be battery damage.  So, use this mode at your own risk.
 757         */
 758        switch (val->intval) {
 759        case POWER_SUPPLY_CHARGE_TYPE_NONE:
 760                chg_config = 0x0;
 761                break;
 762        case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
 763                chg_config = 0x1;
 764                force_20pct = 0x1;
 765                en_term = 0x0;
 766                break;
 767        case POWER_SUPPLY_CHARGE_TYPE_FAST:
 768                chg_config = 0x1;
 769                force_20pct = 0x0;
 770                en_term = 0x1;
 771                break;
 772        default:
 773                return -EINVAL;
 774        }
 775
 776        if (chg_config) { /* Enabling the charger */
 777                ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
 778                                BQ24190_REG_CCC_FORCE_20PCT_MASK,
 779                                BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
 780                                force_20pct);
 781                if (ret < 0)
 782                        return ret;
 783
 784                ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
 785                                BQ24190_REG_CTTC_EN_TERM_MASK,
 786                                BQ24190_REG_CTTC_EN_TERM_SHIFT,
 787                                en_term);
 788                if (ret < 0)
 789                        return ret;
 790        }
 791
 792        return bq24190_write_mask(bdi, BQ24190_REG_POC,
 793                        BQ24190_REG_POC_CHG_CONFIG_MASK,
 794                        BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
 795}
 796
 797static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
 798                union power_supply_propval *val)
 799{
 800        u8 v;
 801        int health;
 802
 803        mutex_lock(&bdi->f_reg_lock);
 804        v = bdi->f_reg;
 805        mutex_unlock(&bdi->f_reg_lock);
 806
 807        if (v & BQ24190_REG_F_NTC_FAULT_MASK) {
 808                switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
 809                case 0x1: /* TS1  Cold */
 810                case 0x3: /* TS2  Cold */
 811                case 0x5: /* Both Cold */
 812                        health = POWER_SUPPLY_HEALTH_COLD;
 813                        break;
 814                case 0x2: /* TS1  Hot */
 815                case 0x4: /* TS2  Hot */
 816                case 0x6: /* Both Hot */
 817                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
 818                        break;
 819                default:
 820                        health = POWER_SUPPLY_HEALTH_UNKNOWN;
 821                }
 822        } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
 823                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
 824        } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
 825                switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
 826                case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
 827                        /*
 828                         * This could be over-voltage or under-voltage
 829                         * and there's no way to tell which.  Instead
 830                         * of looking foolish and returning 'OVERVOLTAGE'
 831                         * when its really under-voltage, just return
 832                         * 'UNSPEC_FAILURE'.
 833                         */
 834                        health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
 835                        break;
 836                case 0x2: /* Thermal Shutdown */
 837                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
 838                        break;
 839                case 0x3: /* Charge Safety Timer Expiration */
 840                        health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
 841                        break;
 842                default:  /* prevent compiler warning */
 843                        health = -1;
 844                }
 845        } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
 846                /*
 847                 * This could be over-current or over-voltage but there's
 848                 * no way to tell which.  Return 'OVERVOLTAGE' since there
 849                 * isn't an 'OVERCURRENT' value defined that we can return
 850                 * even if it was over-current.
 851                 */
 852                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
 853        } else {
 854                health = POWER_SUPPLY_HEALTH_GOOD;
 855        }
 856
 857        val->intval = health;
 858
 859        return 0;
 860}
 861
 862static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
 863                union power_supply_propval *val)
 864{
 865        u8 pg_stat, batfet_disable;
 866        int ret;
 867
 868        ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
 869                        BQ24190_REG_SS_PG_STAT_MASK,
 870                        BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
 871        if (ret < 0)
 872                return ret;
 873
 874        ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
 875                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
 876                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
 877        if (ret < 0)
 878                return ret;
 879
 880        val->intval = pg_stat && !batfet_disable;
 881
 882        return 0;
 883}
 884
 885static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
 886                                      const union power_supply_propval *val);
 887static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
 888                                      union power_supply_propval *val);
 889static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
 890                                              union power_supply_propval *val);
 891static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
 892                                              const union power_supply_propval *val);
 893
 894static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
 895                                      const union power_supply_propval *val)
 896{
 897        return bq24190_battery_set_online(bdi, val);
 898}
 899
 900static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
 901                                      union power_supply_propval *val)
 902{
 903        return bq24190_battery_get_status(bdi, val);
 904}
 905
 906static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
 907                                              union power_supply_propval *val)
 908{
 909        return bq24190_battery_get_temp_alert_max(bdi, val);
 910}
 911
 912static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
 913                                              const union power_supply_propval *val)
 914{
 915        return bq24190_battery_set_temp_alert_max(bdi, val);
 916}
 917
 918static int bq24190_charger_get_precharge(struct bq24190_dev_info *bdi,
 919                union power_supply_propval *val)
 920{
 921        u8 v;
 922        int ret;
 923
 924        ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
 925                        BQ24190_REG_PCTCC_IPRECHG_MASK,
 926                        BQ24190_REG_PCTCC_IPRECHG_SHIFT, &v);
 927        if (ret < 0)
 928                return ret;
 929
 930        val->intval = ++v * 128 * 1000;
 931        return 0;
 932}
 933
 934static int bq24190_charger_get_charge_term(struct bq24190_dev_info *bdi,
 935                union power_supply_propval *val)
 936{
 937        u8 v;
 938        int ret;
 939
 940        ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
 941                        BQ24190_REG_PCTCC_ITERM_MASK,
 942                        BQ24190_REG_PCTCC_ITERM_SHIFT, &v);
 943        if (ret < 0)
 944                return ret;
 945
 946        val->intval = ++v * 128 * 1000;
 947        return 0;
 948}
 949
 950static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
 951                union power_supply_propval *val)
 952{
 953        u8 v;
 954        int curr, ret;
 955
 956        ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
 957                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
 958                        bq24190_ccc_ichg_values,
 959                        ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
 960        if (ret < 0)
 961                return ret;
 962
 963        ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 964                        BQ24190_REG_CCC_FORCE_20PCT_MASK,
 965                        BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 966        if (ret < 0)
 967                return ret;
 968
 969        /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
 970        if (v)
 971                curr /= 5;
 972
 973        val->intval = curr;
 974        return 0;
 975}
 976
 977static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
 978                union power_supply_propval *val)
 979{
 980        int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
 981
 982        val->intval = bq24190_ccc_ichg_values[idx];
 983        return 0;
 984}
 985
 986static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
 987                const union power_supply_propval *val)
 988{
 989        u8 v;
 990        int ret, curr = val->intval;
 991
 992        ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
 993                        BQ24190_REG_CCC_FORCE_20PCT_MASK,
 994                        BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
 995        if (ret < 0)
 996                return ret;
 997
 998        /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
 999        if (v)
1000                curr *= 5;
1001
1002        return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
1003                        BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1004                        bq24190_ccc_ichg_values,
1005                        ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
1006}
1007
1008static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
1009                union power_supply_propval *val)
1010{
1011        int voltage, ret;
1012
1013        ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
1014                        BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1015                        bq24190_cvc_vreg_values,
1016                        ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
1017        if (ret < 0)
1018                return ret;
1019
1020        val->intval = voltage;
1021        return 0;
1022}
1023
1024static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
1025                union power_supply_propval *val)
1026{
1027        int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
1028
1029        val->intval = bq24190_cvc_vreg_values[idx];
1030        return 0;
1031}
1032
1033static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
1034                const union power_supply_propval *val)
1035{
1036        return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
1037                        BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1038                        bq24190_cvc_vreg_values,
1039                        ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
1040}
1041
1042static int bq24190_charger_get_iinlimit(struct bq24190_dev_info *bdi,
1043                union power_supply_propval *val)
1044{
1045        int iinlimit, ret;
1046
1047        ret = bq24190_get_field_val(bdi, BQ24190_REG_ISC,
1048                        BQ24190_REG_ISC_IINLIM_MASK,
1049                        BQ24190_REG_ISC_IINLIM_SHIFT,
1050                        bq24190_isc_iinlim_values,
1051                        ARRAY_SIZE(bq24190_isc_iinlim_values), &iinlimit);
1052        if (ret < 0)
1053                return ret;
1054
1055        val->intval = iinlimit;
1056        return 0;
1057}
1058
1059static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi,
1060                const union power_supply_propval *val)
1061{
1062        return bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1063                        BQ24190_REG_ISC_IINLIM_MASK,
1064                        BQ24190_REG_ISC_IINLIM_SHIFT,
1065                        bq24190_isc_iinlim_values,
1066                        ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval);
1067}
1068
1069static int bq24190_charger_get_property(struct power_supply *psy,
1070                enum power_supply_property psp, union power_supply_propval *val)
1071{
1072        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1073        int ret;
1074
1075        dev_dbg(bdi->dev, "prop: %d\n", psp);
1076
1077        ret = pm_runtime_get_sync(bdi->dev);
1078        if (ret < 0)
1079                return ret;
1080
1081        switch (psp) {
1082        case POWER_SUPPLY_PROP_CHARGE_TYPE:
1083                ret = bq24190_charger_get_charge_type(bdi, val);
1084                break;
1085        case POWER_SUPPLY_PROP_HEALTH:
1086                ret = bq24190_charger_get_health(bdi, val);
1087                break;
1088        case POWER_SUPPLY_PROP_ONLINE:
1089                ret = bq24190_charger_get_online(bdi, val);
1090                break;
1091        case POWER_SUPPLY_PROP_STATUS:
1092                ret = bq24190_charger_get_status(bdi, val);
1093                break;
1094        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1095                ret =  bq24190_charger_get_temp_alert_max(bdi, val);
1096                break;
1097        case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
1098                ret = bq24190_charger_get_precharge(bdi, val);
1099                break;
1100        case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
1101                ret = bq24190_charger_get_charge_term(bdi, val);
1102                break;
1103        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1104                ret = bq24190_charger_get_current(bdi, val);
1105                break;
1106        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
1107                ret = bq24190_charger_get_current_max(bdi, val);
1108                break;
1109        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1110                ret = bq24190_charger_get_voltage(bdi, val);
1111                break;
1112        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
1113                ret = bq24190_charger_get_voltage_max(bdi, val);
1114                break;
1115        case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1116                ret = bq24190_charger_get_iinlimit(bdi, val);
1117                break;
1118        case POWER_SUPPLY_PROP_SCOPE:
1119                val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1120                ret = 0;
1121                break;
1122        case POWER_SUPPLY_PROP_MODEL_NAME:
1123                val->strval = bdi->model_name;
1124                ret = 0;
1125                break;
1126        case POWER_SUPPLY_PROP_MANUFACTURER:
1127                val->strval = BQ24190_MANUFACTURER;
1128                ret = 0;
1129                break;
1130        default:
1131                ret = -ENODATA;
1132        }
1133
1134        pm_runtime_mark_last_busy(bdi->dev);
1135        pm_runtime_put_autosuspend(bdi->dev);
1136
1137        return ret;
1138}
1139
1140static int bq24190_charger_set_property(struct power_supply *psy,
1141                enum power_supply_property psp,
1142                const union power_supply_propval *val)
1143{
1144        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1145        int ret;
1146
1147        dev_dbg(bdi->dev, "prop: %d\n", psp);
1148
1149        ret = pm_runtime_get_sync(bdi->dev);
1150        if (ret < 0)
1151                return ret;
1152
1153        switch (psp) {
1154        case POWER_SUPPLY_PROP_ONLINE:
1155                ret = bq24190_charger_set_online(bdi, val);
1156                break;
1157        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1158                ret = bq24190_charger_set_temp_alert_max(bdi, val);
1159                break;
1160        case POWER_SUPPLY_PROP_CHARGE_TYPE:
1161                ret = bq24190_charger_set_charge_type(bdi, val);
1162                break;
1163        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1164                ret = bq24190_charger_set_current(bdi, val);
1165                break;
1166        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1167                ret = bq24190_charger_set_voltage(bdi, val);
1168                break;
1169        case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1170                ret = bq24190_charger_set_iinlimit(bdi, val);
1171                break;
1172        default:
1173                ret = -EINVAL;
1174        }
1175
1176        pm_runtime_mark_last_busy(bdi->dev);
1177        pm_runtime_put_autosuspend(bdi->dev);
1178
1179        return ret;
1180}
1181
1182static int bq24190_charger_property_is_writeable(struct power_supply *psy,
1183                enum power_supply_property psp)
1184{
1185        switch (psp) {
1186        case POWER_SUPPLY_PROP_ONLINE:
1187        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1188        case POWER_SUPPLY_PROP_CHARGE_TYPE:
1189        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1190        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1191        case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1192                return 1;
1193        default:
1194                return 0;
1195        }
1196}
1197
1198static void bq24190_input_current_limit_work(struct work_struct *work)
1199{
1200        struct bq24190_dev_info *bdi =
1201                container_of(work, struct bq24190_dev_info,
1202                             input_current_limit_work.work);
1203
1204        power_supply_set_input_current_limit_from_supplier(bdi->charger);
1205}
1206
1207/* Sync the input-current-limit with our parent supply (if we have one) */
1208static void bq24190_charger_external_power_changed(struct power_supply *psy)
1209{
1210        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1211
1212        /*
1213         * The Power-Good detection may take up to 220ms, sometimes
1214         * the external charger detection is quicker, and the bq24190 will
1215         * reset to iinlim based on its own charger detection (which is not
1216         * hooked up when using external charger detection) resulting in a
1217         * too low default 500mA iinlim. Delay setting the input-current-limit
1218         * for 300ms to avoid this.
1219         */
1220        queue_delayed_work(system_wq, &bdi->input_current_limit_work,
1221                           msecs_to_jiffies(300));
1222}
1223
1224static enum power_supply_property bq24190_charger_properties[] = {
1225        POWER_SUPPLY_PROP_CHARGE_TYPE,
1226        POWER_SUPPLY_PROP_HEALTH,
1227        POWER_SUPPLY_PROP_ONLINE,
1228        POWER_SUPPLY_PROP_STATUS,
1229        POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1230        POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
1231        POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
1232        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
1233        POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
1234        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
1235        POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
1236        POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1237        POWER_SUPPLY_PROP_SCOPE,
1238        POWER_SUPPLY_PROP_MODEL_NAME,
1239        POWER_SUPPLY_PROP_MANUFACTURER,
1240};
1241
1242static char *bq24190_charger_supplied_to[] = {
1243        "main-battery",
1244};
1245
1246static const struct power_supply_desc bq24190_charger_desc = {
1247        .name                   = "bq24190-charger",
1248        .type                   = POWER_SUPPLY_TYPE_USB,
1249        .properties             = bq24190_charger_properties,
1250        .num_properties         = ARRAY_SIZE(bq24190_charger_properties),
1251        .get_property           = bq24190_charger_get_property,
1252        .set_property           = bq24190_charger_set_property,
1253        .property_is_writeable  = bq24190_charger_property_is_writeable,
1254        .external_power_changed = bq24190_charger_external_power_changed,
1255};
1256
1257/* Battery power supply property routines */
1258
1259static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1260                union power_supply_propval *val)
1261{
1262        u8 ss_reg, chrg_fault;
1263        int status, ret;
1264
1265        mutex_lock(&bdi->f_reg_lock);
1266        chrg_fault = bdi->f_reg;
1267        mutex_unlock(&bdi->f_reg_lock);
1268
1269        chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
1270        chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
1271
1272        ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1273        if (ret < 0)
1274                return ret;
1275
1276        /*
1277         * The battery must be discharging when any of these are true:
1278         * - there is no good power source;
1279         * - there is a charge fault.
1280         * Could also be discharging when in "supplement mode" but
1281         * there is no way to tell when its in that mode.
1282         */
1283        if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
1284                status = POWER_SUPPLY_STATUS_DISCHARGING;
1285        } else {
1286                ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
1287                ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
1288
1289                switch (ss_reg) {
1290                case 0x0: /* Not Charging */
1291                        status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1292                        break;
1293                case 0x1: /* Pre-charge */
1294                case 0x2: /* Fast Charging */
1295                        status = POWER_SUPPLY_STATUS_CHARGING;
1296                        break;
1297                case 0x3: /* Charge Termination Done */
1298                        status = POWER_SUPPLY_STATUS_FULL;
1299                        break;
1300                default:
1301                        ret = -EIO;
1302                }
1303        }
1304
1305        if (!ret)
1306                val->intval = status;
1307
1308        return ret;
1309}
1310
1311static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1312                union power_supply_propval *val)
1313{
1314        u8 v;
1315        int health;
1316
1317        mutex_lock(&bdi->f_reg_lock);
1318        v = bdi->f_reg;
1319        mutex_unlock(&bdi->f_reg_lock);
1320
1321        if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1322                health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1323        } else {
1324                v &= BQ24190_REG_F_NTC_FAULT_MASK;
1325                v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1326
1327                switch (v) {
1328                case 0x0: /* Normal */
1329                        health = POWER_SUPPLY_HEALTH_GOOD;
1330                        break;
1331                case 0x1: /* TS1 Cold */
1332                case 0x3: /* TS2 Cold */
1333                case 0x5: /* Both Cold */
1334                        health = POWER_SUPPLY_HEALTH_COLD;
1335                        break;
1336                case 0x2: /* TS1 Hot */
1337                case 0x4: /* TS2 Hot */
1338                case 0x6: /* Both Hot */
1339                        health = POWER_SUPPLY_HEALTH_OVERHEAT;
1340                        break;
1341                default:
1342                        health = POWER_SUPPLY_HEALTH_UNKNOWN;
1343                }
1344        }
1345
1346        val->intval = health;
1347        return 0;
1348}
1349
1350static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1351                union power_supply_propval *val)
1352{
1353        u8 batfet_disable;
1354        int ret;
1355
1356        ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1357                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1358                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1359        if (ret < 0)
1360                return ret;
1361
1362        val->intval = !batfet_disable;
1363        return 0;
1364}
1365
1366static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1367                const union power_supply_propval *val)
1368{
1369        return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1370                        BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1371                        BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1372}
1373
1374static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1375                union power_supply_propval *val)
1376{
1377        int temp, ret;
1378
1379        ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1380                        BQ24190_REG_ICTRC_TREG_MASK,
1381                        BQ24190_REG_ICTRC_TREG_SHIFT,
1382                        bq24190_ictrc_treg_values,
1383                        ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1384        if (ret < 0)
1385                return ret;
1386
1387        val->intval = temp;
1388        return 0;
1389}
1390
1391static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1392                const union power_supply_propval *val)
1393{
1394        return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1395                        BQ24190_REG_ICTRC_TREG_MASK,
1396                        BQ24190_REG_ICTRC_TREG_SHIFT,
1397                        bq24190_ictrc_treg_values,
1398                        ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1399}
1400
1401static int bq24190_battery_get_property(struct power_supply *psy,
1402                enum power_supply_property psp, union power_supply_propval *val)
1403{
1404        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1405        int ret;
1406
1407        dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1408        dev_dbg(bdi->dev, "prop: %d\n", psp);
1409
1410        ret = pm_runtime_get_sync(bdi->dev);
1411        if (ret < 0)
1412                return ret;
1413
1414        switch (psp) {
1415        case POWER_SUPPLY_PROP_STATUS:
1416                ret = bq24190_battery_get_status(bdi, val);
1417                break;
1418        case POWER_SUPPLY_PROP_HEALTH:
1419                ret = bq24190_battery_get_health(bdi, val);
1420                break;
1421        case POWER_SUPPLY_PROP_ONLINE:
1422                ret = bq24190_battery_get_online(bdi, val);
1423                break;
1424        case POWER_SUPPLY_PROP_TECHNOLOGY:
1425                /* Could be Li-on or Li-polymer but no way to tell which */
1426                val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1427                ret = 0;
1428                break;
1429        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1430                ret = bq24190_battery_get_temp_alert_max(bdi, val);
1431                break;
1432        case POWER_SUPPLY_PROP_SCOPE:
1433                val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1434                ret = 0;
1435                break;
1436        default:
1437                ret = -ENODATA;
1438        }
1439
1440        pm_runtime_mark_last_busy(bdi->dev);
1441        pm_runtime_put_autosuspend(bdi->dev);
1442
1443        return ret;
1444}
1445
1446static int bq24190_battery_set_property(struct power_supply *psy,
1447                enum power_supply_property psp,
1448                const union power_supply_propval *val)
1449{
1450        struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1451        int ret;
1452
1453        dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1454        dev_dbg(bdi->dev, "prop: %d\n", psp);
1455
1456        ret = pm_runtime_get_sync(bdi->dev);
1457        if (ret < 0)
1458                return ret;
1459
1460        switch (psp) {
1461        case POWER_SUPPLY_PROP_ONLINE:
1462                ret = bq24190_battery_set_online(bdi, val);
1463                break;
1464        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1465                ret = bq24190_battery_set_temp_alert_max(bdi, val);
1466                break;
1467        default:
1468                ret = -EINVAL;
1469        }
1470
1471        pm_runtime_mark_last_busy(bdi->dev);
1472        pm_runtime_put_autosuspend(bdi->dev);
1473
1474        return ret;
1475}
1476
1477static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1478                enum power_supply_property psp)
1479{
1480        int ret;
1481
1482        switch (psp) {
1483        case POWER_SUPPLY_PROP_ONLINE:
1484        case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1485                ret = 1;
1486                break;
1487        default:
1488                ret = 0;
1489        }
1490
1491        return ret;
1492}
1493
1494static enum power_supply_property bq24190_battery_properties[] = {
1495        POWER_SUPPLY_PROP_STATUS,
1496        POWER_SUPPLY_PROP_HEALTH,
1497        POWER_SUPPLY_PROP_ONLINE,
1498        POWER_SUPPLY_PROP_TECHNOLOGY,
1499        POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1500        POWER_SUPPLY_PROP_SCOPE,
1501};
1502
1503static const struct power_supply_desc bq24190_battery_desc = {
1504        .name                   = "bq24190-battery",
1505        .type                   = POWER_SUPPLY_TYPE_BATTERY,
1506        .properties             = bq24190_battery_properties,
1507        .num_properties         = ARRAY_SIZE(bq24190_battery_properties),
1508        .get_property           = bq24190_battery_get_property,
1509        .set_property           = bq24190_battery_set_property,
1510        .property_is_writeable  = bq24190_battery_property_is_writeable,
1511};
1512
1513static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
1514{
1515        bool otg_enabled;
1516        int ret;
1517
1518        otg_enabled = !!(ss_reg & BQ24190_REG_SS_VBUS_STAT_MASK);
1519        ret = extcon_set_state_sync(bdi->edev, EXTCON_USB, otg_enabled);
1520        if (ret < 0)
1521                dev_err(bdi->dev, "Can't set extcon state to %d: %d\n",
1522                        otg_enabled, ret);
1523
1524        return ret;
1525}
1526
1527static void bq24190_check_status(struct bq24190_dev_info *bdi)
1528{
1529        const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1530        const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1531                                | BQ24190_REG_F_NTC_FAULT_MASK;
1532        bool alert_charger = false, alert_battery = false;
1533        u8 ss_reg = 0, f_reg = 0;
1534        int i, ret;
1535
1536        ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1537        if (ret < 0) {
1538                dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1539                return;
1540        }
1541
1542        i = 0;
1543        do {
1544                ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1545                if (ret < 0) {
1546                        dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1547                        return;
1548                }
1549        } while (f_reg && ++i < 2);
1550
1551        /* ignore over/under voltage fault after disconnect */
1552        if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1553            !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1554                f_reg = 0;
1555
1556        if (f_reg != bdi->f_reg) {
1557                dev_warn(bdi->dev,
1558                        "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1559                        !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1560                        !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1561                        !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1562                        !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1563
1564                mutex_lock(&bdi->f_reg_lock);
1565                if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1566                        alert_battery = true;
1567                if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1568                        alert_charger = true;
1569                bdi->f_reg = f_reg;
1570                mutex_unlock(&bdi->f_reg_lock);
1571        }
1572
1573        if (ss_reg != bdi->ss_reg) {
1574                /*
1575                 * The device is in host mode so when PG_STAT goes from 1->0
1576                 * (i.e., power removed) HIZ needs to be disabled.
1577                 */
1578                if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1579                                !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1580                        ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1581                                        BQ24190_REG_ISC_EN_HIZ_MASK,
1582                                        BQ24190_REG_ISC_EN_HIZ_SHIFT,
1583                                        0);
1584                        if (ret < 0)
1585                                dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1586                                        ret);
1587                }
1588
1589                if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1590                        alert_battery = true;
1591                if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1592                        alert_charger = true;
1593                bdi->ss_reg = ss_reg;
1594        }
1595
1596        if (alert_charger || alert_battery) {
1597                power_supply_changed(bdi->charger);
1598                bq24190_configure_usb_otg(bdi, ss_reg);
1599        }
1600        if (alert_battery && bdi->battery)
1601                power_supply_changed(bdi->battery);
1602
1603        dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1604}
1605
1606static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1607{
1608        struct bq24190_dev_info *bdi = data;
1609        int error;
1610
1611        bdi->irq_event = true;
1612        error = pm_runtime_get_sync(bdi->dev);
1613        if (error < 0) {
1614                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1615                pm_runtime_put_noidle(bdi->dev);
1616                return IRQ_NONE;
1617        }
1618        bq24190_check_status(bdi);
1619        pm_runtime_mark_last_busy(bdi->dev);
1620        pm_runtime_put_autosuspend(bdi->dev);
1621        bdi->irq_event = false;
1622
1623        return IRQ_HANDLED;
1624}
1625
1626static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1627{
1628        u8 v;
1629        int ret;
1630
1631        /* First check that the device really is what its supposed to be */
1632        ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1633                        BQ24190_REG_VPRS_PN_MASK,
1634                        BQ24190_REG_VPRS_PN_SHIFT,
1635                        &v);
1636        if (ret < 0)
1637                return ret;
1638
1639        switch (v) {
1640        case BQ24190_REG_VPRS_PN_24190:
1641        case BQ24190_REG_VPRS_PN_24192:
1642        case BQ24190_REG_VPRS_PN_24192I:
1643                break;
1644        default:
1645                dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1646                return -ENODEV;
1647        }
1648
1649        ret = bq24190_register_reset(bdi);
1650        if (ret < 0)
1651                return ret;
1652
1653        ret = bq24190_set_config(bdi);
1654        if (ret < 0)
1655                return ret;
1656
1657        return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1658}
1659
1660static int bq24190_get_config(struct bq24190_dev_info *bdi)
1661{
1662        const char * const s = "ti,system-minimum-microvolt";
1663        struct power_supply_battery_info info = {};
1664        int v;
1665
1666        if (device_property_read_u32(bdi->dev, s, &v) == 0) {
1667                v /= 1000;
1668                if (v >= BQ24190_REG_POC_SYS_MIN_MIN
1669                 && v <= BQ24190_REG_POC_SYS_MIN_MAX)
1670                        bdi->sys_min = v;
1671                else
1672                        dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v);
1673        }
1674
1675        if (bdi->dev->of_node &&
1676            !power_supply_get_battery_info(bdi->charger, &info)) {
1677                v = info.precharge_current_ua / 1000;
1678                if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
1679                 && v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
1680                        bdi->iprechg = v;
1681                else
1682                        dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
1683                                 v);
1684
1685                v = info.charge_term_current_ua / 1000;
1686                if (v >= BQ24190_REG_PCTCC_ITERM_MIN
1687                 && v <= BQ24190_REG_PCTCC_ITERM_MAX)
1688                        bdi->iterm = v;
1689                else
1690                        dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n",
1691                                 v);
1692        }
1693
1694        return 0;
1695}
1696
1697static int bq24190_probe(struct i2c_client *client,
1698                const struct i2c_device_id *id)
1699{
1700        struct i2c_adapter *adapter = client->adapter;
1701        struct device *dev = &client->dev;
1702        struct power_supply_config charger_cfg = {}, battery_cfg = {};
1703        struct bq24190_dev_info *bdi;
1704        int ret;
1705
1706        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1707                dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1708                return -ENODEV;
1709        }
1710
1711        bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1712        if (!bdi) {
1713                dev_err(dev, "Can't alloc bdi struct\n");
1714                return -ENOMEM;
1715        }
1716
1717        bdi->client = client;
1718        bdi->dev = dev;
1719        strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1720        mutex_init(&bdi->f_reg_lock);
1721        bdi->f_reg = 0;
1722        bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1723        INIT_DELAYED_WORK(&bdi->input_current_limit_work,
1724                          bq24190_input_current_limit_work);
1725
1726        i2c_set_clientdata(client, bdi);
1727
1728        if (client->irq <= 0) {
1729                dev_err(dev, "Can't get irq info\n");
1730                return -EINVAL;
1731        }
1732
1733        bdi->edev = devm_extcon_dev_allocate(dev, bq24190_usb_extcon_cable);
1734        if (IS_ERR(bdi->edev))
1735                return PTR_ERR(bdi->edev);
1736
1737        ret = devm_extcon_dev_register(dev, bdi->edev);
1738        if (ret < 0)
1739                return ret;
1740
1741        pm_runtime_enable(dev);
1742        pm_runtime_use_autosuspend(dev);
1743        pm_runtime_set_autosuspend_delay(dev, 600);
1744        ret = pm_runtime_get_sync(dev);
1745        if (ret < 0) {
1746                dev_err(dev, "pm_runtime_get failed: %i\n", ret);
1747                goto out_pmrt;
1748        }
1749
1750#ifdef CONFIG_SYSFS
1751        bq24190_sysfs_init_attrs();
1752        charger_cfg.attr_grp = bq24190_sysfs_groups;
1753#endif
1754
1755        charger_cfg.drv_data = bdi;
1756        charger_cfg.of_node = dev->of_node;
1757        charger_cfg.supplied_to = bq24190_charger_supplied_to;
1758        charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1759        bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1760                                                &charger_cfg);
1761        if (IS_ERR(bdi->charger)) {
1762                dev_err(dev, "Can't register charger\n");
1763                ret = PTR_ERR(bdi->charger);
1764                goto out_pmrt;
1765        }
1766
1767        /* the battery class is deprecated and will be removed. */
1768        /* in the interim, this property hides it.              */
1769        if (!device_property_read_bool(dev, "omit-battery-class")) {
1770                battery_cfg.drv_data = bdi;
1771                bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1772                                                     &battery_cfg);
1773                if (IS_ERR(bdi->battery)) {
1774                        dev_err(dev, "Can't register battery\n");
1775                        ret = PTR_ERR(bdi->battery);
1776                        goto out_charger;
1777                }
1778        }
1779
1780        ret = bq24190_get_config(bdi);
1781        if (ret < 0) {
1782                dev_err(dev, "Can't get devicetree config\n");
1783                goto out_charger;
1784        }
1785
1786        ret = bq24190_hw_init(bdi);
1787        if (ret < 0) {
1788                dev_err(dev, "Hardware init failed\n");
1789                goto out_charger;
1790        }
1791
1792        ret = bq24190_configure_usb_otg(bdi, bdi->ss_reg);
1793        if (ret < 0)
1794                goto out_charger;
1795
1796        bdi->initialized = true;
1797
1798        ret = devm_request_threaded_irq(dev, client->irq, NULL,
1799                        bq24190_irq_handler_thread,
1800                        IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1801                        "bq24190-charger", bdi);
1802        if (ret < 0) {
1803                dev_err(dev, "Can't set up irq handler\n");
1804                goto out_charger;
1805        }
1806
1807        ret = bq24190_register_vbus_regulator(bdi);
1808        if (ret < 0)
1809                goto out_charger;
1810
1811        enable_irq_wake(client->irq);
1812
1813        pm_runtime_mark_last_busy(dev);
1814        pm_runtime_put_autosuspend(dev);
1815
1816        return 0;
1817
1818out_charger:
1819        if (!IS_ERR_OR_NULL(bdi->battery))
1820                power_supply_unregister(bdi->battery);
1821        power_supply_unregister(bdi->charger);
1822
1823out_pmrt:
1824        pm_runtime_put_sync(dev);
1825        pm_runtime_dont_use_autosuspend(dev);
1826        pm_runtime_disable(dev);
1827        return ret;
1828}
1829
1830static int bq24190_remove(struct i2c_client *client)
1831{
1832        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1833        int error;
1834
1835        error = pm_runtime_get_sync(bdi->dev);
1836        if (error < 0) {
1837                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1838                pm_runtime_put_noidle(bdi->dev);
1839        }
1840
1841        bq24190_register_reset(bdi);
1842        if (bdi->battery)
1843                power_supply_unregister(bdi->battery);
1844        power_supply_unregister(bdi->charger);
1845        if (error >= 0)
1846                pm_runtime_put_sync(bdi->dev);
1847        pm_runtime_dont_use_autosuspend(bdi->dev);
1848        pm_runtime_disable(bdi->dev);
1849
1850        return 0;
1851}
1852
1853static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
1854{
1855        struct i2c_client *client = to_i2c_client(dev);
1856        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1857
1858        if (!bdi->initialized)
1859                return 0;
1860
1861        dev_dbg(bdi->dev, "%s\n", __func__);
1862
1863        return 0;
1864}
1865
1866static __maybe_unused int bq24190_runtime_resume(struct device *dev)
1867{
1868        struct i2c_client *client = to_i2c_client(dev);
1869        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1870
1871        if (!bdi->initialized)
1872                return 0;
1873
1874        if (!bdi->irq_event) {
1875                dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
1876                bq24190_check_status(bdi);
1877        }
1878
1879        return 0;
1880}
1881
1882static __maybe_unused int bq24190_pm_suspend(struct device *dev)
1883{
1884        struct i2c_client *client = to_i2c_client(dev);
1885        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1886        int error;
1887
1888        error = pm_runtime_get_sync(bdi->dev);
1889        if (error < 0) {
1890                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1891                pm_runtime_put_noidle(bdi->dev);
1892        }
1893
1894        bq24190_register_reset(bdi);
1895
1896        if (error >= 0) {
1897                pm_runtime_mark_last_busy(bdi->dev);
1898                pm_runtime_put_autosuspend(bdi->dev);
1899        }
1900
1901        return 0;
1902}
1903
1904static __maybe_unused int bq24190_pm_resume(struct device *dev)
1905{
1906        struct i2c_client *client = to_i2c_client(dev);
1907        struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1908        int error;
1909
1910        bdi->f_reg = 0;
1911        bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1912
1913        error = pm_runtime_get_sync(bdi->dev);
1914        if (error < 0) {
1915                dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1916                pm_runtime_put_noidle(bdi->dev);
1917        }
1918
1919        bq24190_register_reset(bdi);
1920        bq24190_set_config(bdi);
1921        bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1922
1923        if (error >= 0) {
1924                pm_runtime_mark_last_busy(bdi->dev);
1925                pm_runtime_put_autosuspend(bdi->dev);
1926        }
1927
1928        /* Things may have changed while suspended so alert upper layer */
1929        power_supply_changed(bdi->charger);
1930        if (bdi->battery)
1931                power_supply_changed(bdi->battery);
1932
1933        return 0;
1934}
1935
1936static const struct dev_pm_ops bq24190_pm_ops = {
1937        SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
1938                           NULL)
1939        SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
1940};
1941
1942static const struct i2c_device_id bq24190_i2c_ids[] = {
1943        { "bq24190" },
1944        { "bq24192" },
1945        { "bq24192i" },
1946        { "bq24196" },
1947        { },
1948};
1949MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1950
1951#ifdef CONFIG_OF
1952static const struct of_device_id bq24190_of_match[] = {
1953        { .compatible = "ti,bq24190", },
1954        { .compatible = "ti,bq24192", },
1955        { .compatible = "ti,bq24192i", },
1956        { .compatible = "ti,bq24196", },
1957        { },
1958};
1959MODULE_DEVICE_TABLE(of, bq24190_of_match);
1960#else
1961static const struct of_device_id bq24190_of_match[] = {
1962        { },
1963};
1964#endif
1965
1966static struct i2c_driver bq24190_driver = {
1967        .probe          = bq24190_probe,
1968        .remove         = bq24190_remove,
1969        .id_table       = bq24190_i2c_ids,
1970        .driver = {
1971                .name           = "bq24190-charger",
1972                .pm             = &bq24190_pm_ops,
1973                .of_match_table = of_match_ptr(bq24190_of_match),
1974        },
1975};
1976module_i2c_driver(bq24190_driver);
1977
1978MODULE_LICENSE("GPL");
1979MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1980MODULE_DESCRIPTION("TI BQ24190 Charger Driver");
1981