power: supply: bq24190_charger: Add disable-reset device-property
[linux/fpc-iii.git] / drivers / power / supply / bq24190_charger.c
blob8ed2782d1bb1b228390c472a8e022f96522fab54
1 /*
2 * Driver for the TI bq24190 battery charger.
4 * Author: Mark A. Greer <mgreer@animalcreek.com>
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 */
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>
21 #include <linux/power/bq24190_charger.h>
24 #define BQ24190_MANUFACTURER "Texas Instruments"
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
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
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
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
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
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
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
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
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
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
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
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.
149 struct bq24190_dev_info {
150 struct i2c_client *client;
151 struct device *dev;
152 struct power_supply *charger;
153 struct power_supply *battery;
154 char model_name[I2C_NAME_SIZE];
155 kernel_ulong_t model;
156 unsigned int gpio_int;
157 unsigned int irq;
158 struct mutex f_reg_lock;
159 u8 f_reg;
160 u8 ss_reg;
161 u8 watchdog;
165 * The tables below provide a 2-way mapping for the value that goes in
166 * the register field and the real-world value that it represents.
167 * The index of the array is the value that goes in the register; the
168 * number at that index in the array is the real-world value that it
169 * represents.
171 /* REG02[7:2] (ICHG) in uAh */
172 static const int bq24190_ccc_ichg_values[] = {
173 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
174 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
175 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
176 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
177 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
178 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
179 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
180 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
183 /* REG04[7:2] (VREG) in uV */
184 static const int bq24190_cvc_vreg_values[] = {
185 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
186 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
187 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
188 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
189 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
190 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
191 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
192 4400000
195 /* REG06[1:0] (TREG) in tenths of degrees Celcius */
196 static const int bq24190_ictrc_treg_values[] = {
197 600, 800, 1000, 1200
201 * Return the index in 'tbl' of greatest value that is less than or equal to
202 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
203 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
204 * is less than 2^8.
206 static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
208 int i;
210 for (i = 1; i < tbl_size; i++)
211 if (v < tbl[i])
212 break;
214 return i - 1;
217 /* Basic driver I/O routines */
219 static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
221 int ret;
223 ret = i2c_smbus_read_byte_data(bdi->client, reg);
224 if (ret < 0)
225 return ret;
227 *data = ret;
228 return 0;
231 static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
233 return i2c_smbus_write_byte_data(bdi->client, reg, data);
236 static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
237 u8 mask, u8 shift, u8 *data)
239 u8 v;
240 int ret;
242 ret = bq24190_read(bdi, reg, &v);
243 if (ret < 0)
244 return ret;
246 v &= mask;
247 v >>= shift;
248 *data = v;
250 return 0;
253 static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
254 u8 mask, u8 shift, u8 data)
256 u8 v;
257 int ret;
259 ret = bq24190_read(bdi, reg, &v);
260 if (ret < 0)
261 return ret;
263 v &= ~mask;
264 v |= ((data << shift) & mask);
266 return bq24190_write(bdi, reg, v);
269 static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
270 u8 reg, u8 mask, u8 shift,
271 const int tbl[], int tbl_size,
272 int *val)
274 u8 v;
275 int ret;
277 ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
278 if (ret < 0)
279 return ret;
281 v = (v >= tbl_size) ? (tbl_size - 1) : v;
282 *val = tbl[v];
284 return 0;
287 static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
288 u8 reg, u8 mask, u8 shift,
289 const int tbl[], int tbl_size,
290 int val)
292 u8 idx;
294 idx = bq24190_find_idx(tbl, tbl_size, val);
296 return bq24190_write_mask(bdi, reg, mask, shift, idx);
299 #ifdef CONFIG_SYSFS
301 * There are a numerous options that are configurable on the bq24190
302 * that go well beyond what the power_supply properties provide access to.
303 * Provide sysfs access to them so they can be examined and possibly modified
304 * on the fly. They will be provided for the charger power_supply object only
305 * and will be prefixed by 'f_' to make them easier to recognize.
308 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
310 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
311 .reg = BQ24190_REG_##r, \
312 .mask = BQ24190_REG_##r##_##f##_MASK, \
313 .shift = BQ24190_REG_##r##_##f##_SHIFT, \
316 #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
317 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
318 bq24190_sysfs_store)
320 #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
321 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
323 static ssize_t bq24190_sysfs_show(struct device *dev,
324 struct device_attribute *attr, char *buf);
325 static ssize_t bq24190_sysfs_store(struct device *dev,
326 struct device_attribute *attr, const char *buf, size_t count);
328 struct bq24190_sysfs_field_info {
329 struct device_attribute attr;
330 u8 reg;
331 u8 mask;
332 u8 shift;
335 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
336 #undef SS
338 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
339 /* sysfs name reg field in reg */
340 BQ24190_SYSFS_FIELD_RW(en_hiz, ISC, EN_HIZ),
341 BQ24190_SYSFS_FIELD_RW(vindpm, ISC, VINDPM),
342 BQ24190_SYSFS_FIELD_RW(iinlim, ISC, IINLIM),
343 BQ24190_SYSFS_FIELD_RW(chg_config, POC, CHG_CONFIG),
344 BQ24190_SYSFS_FIELD_RW(sys_min, POC, SYS_MIN),
345 BQ24190_SYSFS_FIELD_RW(boost_lim, POC, BOOST_LIM),
346 BQ24190_SYSFS_FIELD_RW(ichg, CCC, ICHG),
347 BQ24190_SYSFS_FIELD_RW(force_20_pct, CCC, FORCE_20PCT),
348 BQ24190_SYSFS_FIELD_RW(iprechg, PCTCC, IPRECHG),
349 BQ24190_SYSFS_FIELD_RW(iterm, PCTCC, ITERM),
350 BQ24190_SYSFS_FIELD_RW(vreg, CVC, VREG),
351 BQ24190_SYSFS_FIELD_RW(batlowv, CVC, BATLOWV),
352 BQ24190_SYSFS_FIELD_RW(vrechg, CVC, VRECHG),
353 BQ24190_SYSFS_FIELD_RW(en_term, CTTC, EN_TERM),
354 BQ24190_SYSFS_FIELD_RW(term_stat, CTTC, TERM_STAT),
355 BQ24190_SYSFS_FIELD_RO(watchdog, CTTC, WATCHDOG),
356 BQ24190_SYSFS_FIELD_RW(en_timer, CTTC, EN_TIMER),
357 BQ24190_SYSFS_FIELD_RW(chg_timer, CTTC, CHG_TIMER),
358 BQ24190_SYSFS_FIELD_RW(jeta_iset, CTTC, JEITA_ISET),
359 BQ24190_SYSFS_FIELD_RW(bat_comp, ICTRC, BAT_COMP),
360 BQ24190_SYSFS_FIELD_RW(vclamp, ICTRC, VCLAMP),
361 BQ24190_SYSFS_FIELD_RW(treg, ICTRC, TREG),
362 BQ24190_SYSFS_FIELD_RW(dpdm_en, MOC, DPDM_EN),
363 BQ24190_SYSFS_FIELD_RW(tmr2x_en, MOC, TMR2X_EN),
364 BQ24190_SYSFS_FIELD_RW(batfet_disable, MOC, BATFET_DISABLE),
365 BQ24190_SYSFS_FIELD_RW(jeita_vset, MOC, JEITA_VSET),
366 BQ24190_SYSFS_FIELD_RO(int_mask, MOC, INT_MASK),
367 BQ24190_SYSFS_FIELD_RO(vbus_stat, SS, VBUS_STAT),
368 BQ24190_SYSFS_FIELD_RO(chrg_stat, SS, CHRG_STAT),
369 BQ24190_SYSFS_FIELD_RO(dpm_stat, SS, DPM_STAT),
370 BQ24190_SYSFS_FIELD_RO(pg_stat, SS, PG_STAT),
371 BQ24190_SYSFS_FIELD_RO(therm_stat, SS, THERM_STAT),
372 BQ24190_SYSFS_FIELD_RO(vsys_stat, SS, VSYS_STAT),
373 BQ24190_SYSFS_FIELD_RO(watchdog_fault, F, WATCHDOG_FAULT),
374 BQ24190_SYSFS_FIELD_RO(boost_fault, F, BOOST_FAULT),
375 BQ24190_SYSFS_FIELD_RO(chrg_fault, F, CHRG_FAULT),
376 BQ24190_SYSFS_FIELD_RO(bat_fault, F, BAT_FAULT),
377 BQ24190_SYSFS_FIELD_RO(ntc_fault, F, NTC_FAULT),
378 BQ24190_SYSFS_FIELD_RO(pn, VPRS, PN),
379 BQ24190_SYSFS_FIELD_RO(ts_profile, VPRS, TS_PROFILE),
380 BQ24190_SYSFS_FIELD_RO(dev_reg, VPRS, DEV_REG),
383 static struct attribute *
384 bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
386 static const struct attribute_group bq24190_sysfs_attr_group = {
387 .attrs = bq24190_sysfs_attrs,
390 static void bq24190_sysfs_init_attrs(void)
392 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
394 for (i = 0; i < limit; i++)
395 bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
397 bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
400 static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
401 const char *name)
403 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
405 for (i = 0; i < limit; i++)
406 if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
407 break;
409 if (i >= limit)
410 return NULL;
412 return &bq24190_sysfs_field_tbl[i];
415 static ssize_t bq24190_sysfs_show(struct device *dev,
416 struct device_attribute *attr, char *buf)
418 struct power_supply *psy = dev_get_drvdata(dev);
419 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
420 struct bq24190_sysfs_field_info *info;
421 int ret;
422 u8 v;
424 info = bq24190_sysfs_field_lookup(attr->attr.name);
425 if (!info)
426 return -EINVAL;
428 ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
429 if (ret)
430 return ret;
432 return scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
435 static ssize_t bq24190_sysfs_store(struct device *dev,
436 struct device_attribute *attr, const char *buf, size_t count)
438 struct power_supply *psy = dev_get_drvdata(dev);
439 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
440 struct bq24190_sysfs_field_info *info;
441 int ret;
442 u8 v;
444 info = bq24190_sysfs_field_lookup(attr->attr.name);
445 if (!info)
446 return -EINVAL;
448 ret = kstrtou8(buf, 0, &v);
449 if (ret < 0)
450 return ret;
452 ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
453 if (ret)
454 return ret;
456 return count;
459 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
461 bq24190_sysfs_init_attrs();
463 return sysfs_create_group(&bdi->charger->dev.kobj,
464 &bq24190_sysfs_attr_group);
467 static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi)
469 sysfs_remove_group(&bdi->charger->dev.kobj, &bq24190_sysfs_attr_group);
471 #else
472 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
474 return 0;
477 static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {}
478 #endif
481 * According to the "Host Mode and default Mode" section of the
482 * manual, a write to any register causes the bq24190 to switch
483 * from default mode to host mode. It will switch back to default
484 * mode after a WDT timeout unless the WDT is turned off as well.
485 * So, by simply turning off the WDT, we accomplish both with the
486 * same write.
488 static int bq24190_set_mode_host(struct bq24190_dev_info *bdi)
490 int ret;
491 u8 v;
493 ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
494 if (ret < 0)
495 return ret;
497 bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
498 BQ24190_REG_CTTC_WATCHDOG_SHIFT);
499 v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
501 return bq24190_write(bdi, BQ24190_REG_CTTC, v);
504 static int bq24190_register_reset(struct bq24190_dev_info *bdi)
506 int ret, limit = 100;
507 u8 v;
509 if (device_property_read_bool(bdi->dev, "disable-reset"))
510 return 0;
512 /* Reset the registers */
513 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
514 BQ24190_REG_POC_RESET_MASK,
515 BQ24190_REG_POC_RESET_SHIFT,
516 0x1);
517 if (ret < 0)
518 return ret;
520 /* Reset bit will be cleared by hardware so poll until it is */
521 do {
522 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
523 BQ24190_REG_POC_RESET_MASK,
524 BQ24190_REG_POC_RESET_SHIFT,
525 &v);
526 if (ret < 0)
527 return ret;
529 if (!v)
530 break;
532 udelay(10);
533 } while (--limit);
535 if (!limit)
536 return -EIO;
538 return 0;
541 /* Charger power supply property routines */
543 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
544 union power_supply_propval *val)
546 u8 v;
547 int type, ret;
549 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
550 BQ24190_REG_POC_CHG_CONFIG_MASK,
551 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
552 &v);
553 if (ret < 0)
554 return ret;
556 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
557 if (!v) {
558 type = POWER_SUPPLY_CHARGE_TYPE_NONE;
559 } else {
560 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
561 BQ24190_REG_CCC_FORCE_20PCT_MASK,
562 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
563 &v);
564 if (ret < 0)
565 return ret;
567 type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
568 POWER_SUPPLY_CHARGE_TYPE_FAST;
571 val->intval = type;
573 return 0;
576 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
577 const union power_supply_propval *val)
579 u8 chg_config, force_20pct, en_term;
580 int ret;
583 * According to the "Termination when REG02[0] = 1" section of
584 * the bq24190 manual, the trickle charge could be less than the
585 * termination current so it recommends turning off the termination
586 * function.
588 * Note: AFAICT from the datasheet, the user will have to manually
589 * turn off the charging when in 20% mode. If its not turned off,
590 * there could be battery damage. So, use this mode at your own risk.
592 switch (val->intval) {
593 case POWER_SUPPLY_CHARGE_TYPE_NONE:
594 chg_config = 0x0;
595 break;
596 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
597 chg_config = 0x1;
598 force_20pct = 0x1;
599 en_term = 0x0;
600 break;
601 case POWER_SUPPLY_CHARGE_TYPE_FAST:
602 chg_config = 0x1;
603 force_20pct = 0x0;
604 en_term = 0x1;
605 break;
606 default:
607 return -EINVAL;
610 if (chg_config) { /* Enabling the charger */
611 ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
612 BQ24190_REG_CCC_FORCE_20PCT_MASK,
613 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
614 force_20pct);
615 if (ret < 0)
616 return ret;
618 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
619 BQ24190_REG_CTTC_EN_TERM_MASK,
620 BQ24190_REG_CTTC_EN_TERM_SHIFT,
621 en_term);
622 if (ret < 0)
623 return ret;
626 return bq24190_write_mask(bdi, BQ24190_REG_POC,
627 BQ24190_REG_POC_CHG_CONFIG_MASK,
628 BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
631 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
632 union power_supply_propval *val)
634 u8 v;
635 int health;
637 mutex_lock(&bdi->f_reg_lock);
638 v = bdi->f_reg;
639 mutex_unlock(&bdi->f_reg_lock);
641 if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
643 * This could be over-current or over-voltage but there's
644 * no way to tell which. Return 'OVERVOLTAGE' since there
645 * isn't an 'OVERCURRENT' value defined that we can return
646 * even if it was over-current.
648 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
649 } else {
650 v &= BQ24190_REG_F_CHRG_FAULT_MASK;
651 v >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
653 switch (v) {
654 case 0x0: /* Normal */
655 health = POWER_SUPPLY_HEALTH_GOOD;
656 break;
657 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
659 * This could be over-voltage or under-voltage
660 * and there's no way to tell which. Instead
661 * of looking foolish and returning 'OVERVOLTAGE'
662 * when its really under-voltage, just return
663 * 'UNSPEC_FAILURE'.
665 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
666 break;
667 case 0x2: /* Thermal Shutdown */
668 health = POWER_SUPPLY_HEALTH_OVERHEAT;
669 break;
670 case 0x3: /* Charge Safety Timer Expiration */
671 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
672 break;
673 default:
674 health = POWER_SUPPLY_HEALTH_UNKNOWN;
678 val->intval = health;
680 return 0;
683 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
684 union power_supply_propval *val)
686 u8 v;
687 int ret;
689 ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
690 BQ24190_REG_SS_PG_STAT_MASK,
691 BQ24190_REG_SS_PG_STAT_SHIFT, &v);
692 if (ret < 0)
693 return ret;
695 val->intval = v;
696 return 0;
699 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
700 union power_supply_propval *val)
702 u8 v;
703 int curr, ret;
705 ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
706 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
707 bq24190_ccc_ichg_values,
708 ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
709 if (ret < 0)
710 return ret;
712 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
713 BQ24190_REG_CCC_FORCE_20PCT_MASK,
714 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
715 if (ret < 0)
716 return ret;
718 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
719 if (v)
720 curr /= 5;
722 val->intval = curr;
723 return 0;
726 static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
727 union power_supply_propval *val)
729 int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
731 val->intval = bq24190_ccc_ichg_values[idx];
732 return 0;
735 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
736 const union power_supply_propval *val)
738 u8 v;
739 int ret, curr = val->intval;
741 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
742 BQ24190_REG_CCC_FORCE_20PCT_MASK,
743 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
744 if (ret < 0)
745 return ret;
747 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
748 if (v)
749 curr *= 5;
751 return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
752 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
753 bq24190_ccc_ichg_values,
754 ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
757 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
758 union power_supply_propval *val)
760 int voltage, ret;
762 ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
763 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
764 bq24190_cvc_vreg_values,
765 ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
766 if (ret < 0)
767 return ret;
769 val->intval = voltage;
770 return 0;
773 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
774 union power_supply_propval *val)
776 int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
778 val->intval = bq24190_cvc_vreg_values[idx];
779 return 0;
782 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
783 const union power_supply_propval *val)
785 return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
786 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
787 bq24190_cvc_vreg_values,
788 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
791 static int bq24190_charger_get_property(struct power_supply *psy,
792 enum power_supply_property psp, union power_supply_propval *val)
794 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
795 int ret;
797 dev_dbg(bdi->dev, "prop: %d\n", psp);
799 pm_runtime_get_sync(bdi->dev);
801 switch (psp) {
802 case POWER_SUPPLY_PROP_CHARGE_TYPE:
803 ret = bq24190_charger_get_charge_type(bdi, val);
804 break;
805 case POWER_SUPPLY_PROP_HEALTH:
806 ret = bq24190_charger_get_health(bdi, val);
807 break;
808 case POWER_SUPPLY_PROP_ONLINE:
809 ret = bq24190_charger_get_online(bdi, val);
810 break;
811 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
812 ret = bq24190_charger_get_current(bdi, val);
813 break;
814 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
815 ret = bq24190_charger_get_current_max(bdi, val);
816 break;
817 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
818 ret = bq24190_charger_get_voltage(bdi, val);
819 break;
820 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
821 ret = bq24190_charger_get_voltage_max(bdi, val);
822 break;
823 case POWER_SUPPLY_PROP_SCOPE:
824 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
825 ret = 0;
826 break;
827 case POWER_SUPPLY_PROP_MODEL_NAME:
828 val->strval = bdi->model_name;
829 ret = 0;
830 break;
831 case POWER_SUPPLY_PROP_MANUFACTURER:
832 val->strval = BQ24190_MANUFACTURER;
833 ret = 0;
834 break;
835 default:
836 ret = -ENODATA;
839 pm_runtime_put_sync(bdi->dev);
840 return ret;
843 static int bq24190_charger_set_property(struct power_supply *psy,
844 enum power_supply_property psp,
845 const union power_supply_propval *val)
847 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
848 int ret;
850 dev_dbg(bdi->dev, "prop: %d\n", psp);
852 pm_runtime_get_sync(bdi->dev);
854 switch (psp) {
855 case POWER_SUPPLY_PROP_CHARGE_TYPE:
856 ret = bq24190_charger_set_charge_type(bdi, val);
857 break;
858 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
859 ret = bq24190_charger_set_current(bdi, val);
860 break;
861 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
862 ret = bq24190_charger_set_voltage(bdi, val);
863 break;
864 default:
865 ret = -EINVAL;
868 pm_runtime_put_sync(bdi->dev);
869 return ret;
872 static int bq24190_charger_property_is_writeable(struct power_supply *psy,
873 enum power_supply_property psp)
875 int ret;
877 switch (psp) {
878 case POWER_SUPPLY_PROP_CHARGE_TYPE:
879 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
880 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
881 ret = 1;
882 break;
883 default:
884 ret = 0;
887 return ret;
890 static enum power_supply_property bq24190_charger_properties[] = {
891 POWER_SUPPLY_PROP_CHARGE_TYPE,
892 POWER_SUPPLY_PROP_HEALTH,
893 POWER_SUPPLY_PROP_ONLINE,
894 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
895 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
896 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
897 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
898 POWER_SUPPLY_PROP_SCOPE,
899 POWER_SUPPLY_PROP_MODEL_NAME,
900 POWER_SUPPLY_PROP_MANUFACTURER,
903 static char *bq24190_charger_supplied_to[] = {
904 "main-battery",
907 static const struct power_supply_desc bq24190_charger_desc = {
908 .name = "bq24190-charger",
909 .type = POWER_SUPPLY_TYPE_USB,
910 .properties = bq24190_charger_properties,
911 .num_properties = ARRAY_SIZE(bq24190_charger_properties),
912 .get_property = bq24190_charger_get_property,
913 .set_property = bq24190_charger_set_property,
914 .property_is_writeable = bq24190_charger_property_is_writeable,
917 /* Battery power supply property routines */
919 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
920 union power_supply_propval *val)
922 u8 ss_reg, chrg_fault;
923 int status, ret;
925 mutex_lock(&bdi->f_reg_lock);
926 chrg_fault = bdi->f_reg;
927 mutex_unlock(&bdi->f_reg_lock);
929 chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
930 chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
932 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
933 if (ret < 0)
934 return ret;
937 * The battery must be discharging when any of these are true:
938 * - there is no good power source;
939 * - there is a charge fault.
940 * Could also be discharging when in "supplement mode" but
941 * there is no way to tell when its in that mode.
943 if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
944 status = POWER_SUPPLY_STATUS_DISCHARGING;
945 } else {
946 ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
947 ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
949 switch (ss_reg) {
950 case 0x0: /* Not Charging */
951 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
952 break;
953 case 0x1: /* Pre-charge */
954 case 0x2: /* Fast Charging */
955 status = POWER_SUPPLY_STATUS_CHARGING;
956 break;
957 case 0x3: /* Charge Termination Done */
958 status = POWER_SUPPLY_STATUS_FULL;
959 break;
960 default:
961 ret = -EIO;
965 if (!ret)
966 val->intval = status;
968 return ret;
971 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
972 union power_supply_propval *val)
974 u8 v;
975 int health;
977 mutex_lock(&bdi->f_reg_lock);
978 v = bdi->f_reg;
979 mutex_unlock(&bdi->f_reg_lock);
981 if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
982 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
983 } else {
984 v &= BQ24190_REG_F_NTC_FAULT_MASK;
985 v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
987 switch (v) {
988 case 0x0: /* Normal */
989 health = POWER_SUPPLY_HEALTH_GOOD;
990 break;
991 case 0x1: /* TS1 Cold */
992 case 0x3: /* TS2 Cold */
993 case 0x5: /* Both Cold */
994 health = POWER_SUPPLY_HEALTH_COLD;
995 break;
996 case 0x2: /* TS1 Hot */
997 case 0x4: /* TS2 Hot */
998 case 0x6: /* Both Hot */
999 health = POWER_SUPPLY_HEALTH_OVERHEAT;
1000 break;
1001 default:
1002 health = POWER_SUPPLY_HEALTH_UNKNOWN;
1006 val->intval = health;
1007 return 0;
1010 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1011 union power_supply_propval *val)
1013 u8 batfet_disable;
1014 int ret;
1016 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1017 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1018 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1019 if (ret < 0)
1020 return ret;
1022 val->intval = !batfet_disable;
1023 return 0;
1026 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1027 const union power_supply_propval *val)
1029 return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1030 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1031 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1034 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1035 union power_supply_propval *val)
1037 int temp, ret;
1039 ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1040 BQ24190_REG_ICTRC_TREG_MASK,
1041 BQ24190_REG_ICTRC_TREG_SHIFT,
1042 bq24190_ictrc_treg_values,
1043 ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1044 if (ret < 0)
1045 return ret;
1047 val->intval = temp;
1048 return 0;
1051 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1052 const union power_supply_propval *val)
1054 return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1055 BQ24190_REG_ICTRC_TREG_MASK,
1056 BQ24190_REG_ICTRC_TREG_SHIFT,
1057 bq24190_ictrc_treg_values,
1058 ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1061 static int bq24190_battery_get_property(struct power_supply *psy,
1062 enum power_supply_property psp, union power_supply_propval *val)
1064 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1065 int ret;
1067 dev_dbg(bdi->dev, "prop: %d\n", psp);
1069 pm_runtime_get_sync(bdi->dev);
1071 switch (psp) {
1072 case POWER_SUPPLY_PROP_STATUS:
1073 ret = bq24190_battery_get_status(bdi, val);
1074 break;
1075 case POWER_SUPPLY_PROP_HEALTH:
1076 ret = bq24190_battery_get_health(bdi, val);
1077 break;
1078 case POWER_SUPPLY_PROP_ONLINE:
1079 ret = bq24190_battery_get_online(bdi, val);
1080 break;
1081 case POWER_SUPPLY_PROP_TECHNOLOGY:
1082 /* Could be Li-on or Li-polymer but no way to tell which */
1083 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1084 ret = 0;
1085 break;
1086 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1087 ret = bq24190_battery_get_temp_alert_max(bdi, val);
1088 break;
1089 case POWER_SUPPLY_PROP_SCOPE:
1090 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1091 ret = 0;
1092 break;
1093 default:
1094 ret = -ENODATA;
1097 pm_runtime_put_sync(bdi->dev);
1098 return ret;
1101 static int bq24190_battery_set_property(struct power_supply *psy,
1102 enum power_supply_property psp,
1103 const union power_supply_propval *val)
1105 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1106 int ret;
1108 dev_dbg(bdi->dev, "prop: %d\n", psp);
1110 pm_runtime_get_sync(bdi->dev);
1112 switch (psp) {
1113 case POWER_SUPPLY_PROP_ONLINE:
1114 ret = bq24190_battery_set_online(bdi, val);
1115 break;
1116 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1117 ret = bq24190_battery_set_temp_alert_max(bdi, val);
1118 break;
1119 default:
1120 ret = -EINVAL;
1123 pm_runtime_put_sync(bdi->dev);
1124 return ret;
1127 static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1128 enum power_supply_property psp)
1130 int ret;
1132 switch (psp) {
1133 case POWER_SUPPLY_PROP_ONLINE:
1134 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1135 ret = 1;
1136 break;
1137 default:
1138 ret = 0;
1141 return ret;
1144 static enum power_supply_property bq24190_battery_properties[] = {
1145 POWER_SUPPLY_PROP_STATUS,
1146 POWER_SUPPLY_PROP_HEALTH,
1147 POWER_SUPPLY_PROP_ONLINE,
1148 POWER_SUPPLY_PROP_TECHNOLOGY,
1149 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1150 POWER_SUPPLY_PROP_SCOPE,
1153 static const struct power_supply_desc bq24190_battery_desc = {
1154 .name = "bq24190-battery",
1155 .type = POWER_SUPPLY_TYPE_BATTERY,
1156 .properties = bq24190_battery_properties,
1157 .num_properties = ARRAY_SIZE(bq24190_battery_properties),
1158 .get_property = bq24190_battery_get_property,
1159 .set_property = bq24190_battery_set_property,
1160 .property_is_writeable = bq24190_battery_property_is_writeable,
1163 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1165 struct bq24190_dev_info *bdi = data;
1166 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1167 const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1168 | BQ24190_REG_F_NTC_FAULT_MASK;
1169 bool alert_charger = false, alert_battery = false;
1170 u8 ss_reg = 0, f_reg = 0;
1171 int i, ret;
1173 pm_runtime_get_sync(bdi->dev);
1175 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1176 if (ret < 0) {
1177 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1178 goto out;
1181 i = 0;
1182 do {
1183 ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1184 if (ret < 0) {
1185 dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1186 goto out;
1188 } while (f_reg && ++i < 2);
1190 /* ignore over/under voltage fault after disconnect */
1191 if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1192 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1193 f_reg = 0;
1195 if (f_reg != bdi->f_reg) {
1196 dev_warn(bdi->dev,
1197 "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1198 !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1199 !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1200 !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1201 !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1203 mutex_lock(&bdi->f_reg_lock);
1204 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1205 alert_battery = true;
1206 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1207 alert_charger = true;
1208 bdi->f_reg = f_reg;
1209 mutex_unlock(&bdi->f_reg_lock);
1212 if (ss_reg != bdi->ss_reg) {
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.
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,
1223 if (ret < 0)
1224 dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1225 ret);
1228 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1229 alert_battery = true;
1230 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1231 alert_charger = true;
1232 bdi->ss_reg = ss_reg;
1235 if (alert_charger)
1236 power_supply_changed(bdi->charger);
1237 if (alert_battery)
1238 power_supply_changed(bdi->battery);
1240 out:
1241 pm_runtime_put_sync(bdi->dev);
1243 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1245 return IRQ_HANDLED;
1248 static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1250 u8 v;
1251 int ret;
1253 pm_runtime_get_sync(bdi->dev);
1255 /* First check that the device really is what its supposed to be */
1256 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1257 BQ24190_REG_VPRS_PN_MASK,
1258 BQ24190_REG_VPRS_PN_SHIFT,
1259 &v);
1260 if (ret < 0)
1261 goto out;
1263 if (v != bdi->model) {
1264 ret = -ENODEV;
1265 goto out;
1268 ret = bq24190_register_reset(bdi);
1269 if (ret < 0)
1270 goto out;
1272 ret = bq24190_set_mode_host(bdi);
1273 if (ret < 0)
1274 goto out;
1276 ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1277 out:
1278 pm_runtime_put_sync(bdi->dev);
1279 return ret;
1282 #ifdef CONFIG_OF
1283 static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1285 bdi->irq = irq_of_parse_and_map(bdi->dev->of_node, 0);
1286 if (bdi->irq <= 0)
1287 return -1;
1289 return 0;
1291 #else
1292 static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1294 return -1;
1296 #endif
1298 static int bq24190_setup_pdata(struct bq24190_dev_info *bdi,
1299 struct bq24190_platform_data *pdata)
1301 int ret;
1303 if (!gpio_is_valid(pdata->gpio_int))
1304 return -1;
1306 ret = gpio_request(pdata->gpio_int, dev_name(bdi->dev));
1307 if (ret < 0)
1308 return -1;
1310 ret = gpio_direction_input(pdata->gpio_int);
1311 if (ret < 0)
1312 goto out;
1314 bdi->irq = gpio_to_irq(pdata->gpio_int);
1315 if (!bdi->irq)
1316 goto out;
1318 bdi->gpio_int = pdata->gpio_int;
1319 return 0;
1321 out:
1322 gpio_free(pdata->gpio_int);
1323 return -1;
1326 static int bq24190_probe(struct i2c_client *client,
1327 const struct i2c_device_id *id)
1329 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1330 struct device *dev = &client->dev;
1331 struct bq24190_platform_data *pdata = client->dev.platform_data;
1332 struct power_supply_config charger_cfg = {}, battery_cfg = {};
1333 struct bq24190_dev_info *bdi;
1334 int ret;
1336 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1337 dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1338 return -ENODEV;
1341 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1342 if (!bdi) {
1343 dev_err(dev, "Can't alloc bdi struct\n");
1344 return -ENOMEM;
1347 bdi->client = client;
1348 bdi->dev = dev;
1349 bdi->model = id->driver_data;
1350 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1351 mutex_init(&bdi->f_reg_lock);
1352 bdi->f_reg = 0;
1353 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1355 i2c_set_clientdata(client, bdi);
1357 if (dev->of_node)
1358 ret = bq24190_setup_dt(bdi);
1359 else
1360 ret = bq24190_setup_pdata(bdi, pdata);
1362 if (ret) {
1363 dev_err(dev, "Can't get irq info\n");
1364 return -EINVAL;
1367 pm_runtime_enable(dev);
1368 pm_runtime_resume(dev);
1370 ret = bq24190_hw_init(bdi);
1371 if (ret < 0) {
1372 dev_err(dev, "Hardware init failed\n");
1373 goto out1;
1376 charger_cfg.drv_data = bdi;
1377 charger_cfg.supplied_to = bq24190_charger_supplied_to;
1378 charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1379 bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1380 &charger_cfg);
1381 if (IS_ERR(bdi->charger)) {
1382 dev_err(dev, "Can't register charger\n");
1383 ret = PTR_ERR(bdi->charger);
1384 goto out1;
1387 battery_cfg.drv_data = bdi;
1388 bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1389 &battery_cfg);
1390 if (IS_ERR(bdi->battery)) {
1391 dev_err(dev, "Can't register battery\n");
1392 ret = PTR_ERR(bdi->battery);
1393 goto out2;
1396 ret = bq24190_sysfs_create_group(bdi);
1397 if (ret) {
1398 dev_err(dev, "Can't create sysfs entries\n");
1399 goto out3;
1402 ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
1403 bq24190_irq_handler_thread,
1404 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1405 "bq24190-charger", bdi);
1406 if (ret < 0) {
1407 dev_err(dev, "Can't set up irq handler\n");
1408 goto out4;
1411 return 0;
1413 out4:
1414 bq24190_sysfs_remove_group(bdi);
1415 out3:
1416 power_supply_unregister(bdi->battery);
1417 out2:
1418 power_supply_unregister(bdi->charger);
1419 out1:
1420 pm_runtime_disable(dev);
1421 if (bdi->gpio_int)
1422 gpio_free(bdi->gpio_int);
1424 return ret;
1427 static int bq24190_remove(struct i2c_client *client)
1429 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1431 pm_runtime_get_sync(bdi->dev);
1432 bq24190_register_reset(bdi);
1433 pm_runtime_put_sync(bdi->dev);
1435 bq24190_sysfs_remove_group(bdi);
1436 power_supply_unregister(bdi->battery);
1437 power_supply_unregister(bdi->charger);
1438 pm_runtime_disable(bdi->dev);
1440 if (bdi->gpio_int)
1441 gpio_free(bdi->gpio_int);
1443 return 0;
1446 #ifdef CONFIG_PM_SLEEP
1447 static int bq24190_pm_suspend(struct device *dev)
1449 struct i2c_client *client = to_i2c_client(dev);
1450 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1452 pm_runtime_get_sync(bdi->dev);
1453 bq24190_register_reset(bdi);
1454 pm_runtime_put_sync(bdi->dev);
1456 return 0;
1459 static int bq24190_pm_resume(struct device *dev)
1461 struct i2c_client *client = to_i2c_client(dev);
1462 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1464 bdi->f_reg = 0;
1465 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1467 pm_runtime_get_sync(bdi->dev);
1468 bq24190_register_reset(bdi);
1469 bq24190_set_mode_host(bdi);
1470 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1471 pm_runtime_put_sync(bdi->dev);
1473 /* Things may have changed while suspended so alert upper layer */
1474 power_supply_changed(bdi->charger);
1475 power_supply_changed(bdi->battery);
1477 return 0;
1479 #endif
1481 static SIMPLE_DEV_PM_OPS(bq24190_pm_ops, bq24190_pm_suspend, bq24190_pm_resume);
1484 * Only support the bq24190 right now. The bq24192, bq24192i, and bq24193
1485 * are similar but not identical so the driver needs to be extended to
1486 * support them.
1488 static const struct i2c_device_id bq24190_i2c_ids[] = {
1489 { "bq24190", BQ24190_REG_VPRS_PN_24190 },
1490 { },
1492 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1494 #ifdef CONFIG_OF
1495 static const struct of_device_id bq24190_of_match[] = {
1496 { .compatible = "ti,bq24190", },
1497 { },
1499 MODULE_DEVICE_TABLE(of, bq24190_of_match);
1500 #else
1501 static const struct of_device_id bq24190_of_match[] = {
1502 { },
1504 #endif
1506 static struct i2c_driver bq24190_driver = {
1507 .probe = bq24190_probe,
1508 .remove = bq24190_remove,
1509 .id_table = bq24190_i2c_ids,
1510 .driver = {
1511 .name = "bq24190-charger",
1512 .pm = &bq24190_pm_ops,
1513 .of_match_table = of_match_ptr(bq24190_of_match),
1516 module_i2c_driver(bq24190_driver);
1518 MODULE_LICENSE("GPL");
1519 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1520 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");