Version:  2.0.40 2.2.26 2.4.37 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6

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

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