Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/power/bq24190_charger.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us