dm thin metadata: fix __udivdi3 undefined on 32-bit
[linux/fpc-iii.git] / drivers / power / bq24190_charger.c
blobf05d2773fe00ccff87a55a177b1d27d71befabbf
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 /* Reset the registers */
510 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
511 BQ24190_REG_POC_RESET_MASK,
512 BQ24190_REG_POC_RESET_SHIFT,
513 0x1);
514 if (ret < 0)
515 return ret;
517 /* Reset bit will be cleared by hardware so poll until it is */
518 do {
519 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
520 BQ24190_REG_POC_RESET_MASK,
521 BQ24190_REG_POC_RESET_SHIFT,
522 &v);
523 if (ret < 0)
524 return ret;
526 if (!v)
527 break;
529 udelay(10);
530 } while (--limit);
532 if (!limit)
533 return -EIO;
535 return 0;
538 /* Charger power supply property routines */
540 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
541 union power_supply_propval *val)
543 u8 v;
544 int type, ret;
546 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
547 BQ24190_REG_POC_CHG_CONFIG_MASK,
548 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
549 &v);
550 if (ret < 0)
551 return ret;
553 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
554 if (!v) {
555 type = POWER_SUPPLY_CHARGE_TYPE_NONE;
556 } else {
557 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
558 BQ24190_REG_CCC_FORCE_20PCT_MASK,
559 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
560 &v);
561 if (ret < 0)
562 return ret;
564 type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
565 POWER_SUPPLY_CHARGE_TYPE_FAST;
568 val->intval = type;
570 return 0;
573 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
574 const union power_supply_propval *val)
576 u8 chg_config, force_20pct, en_term;
577 int ret;
580 * According to the "Termination when REG02[0] = 1" section of
581 * the bq24190 manual, the trickle charge could be less than the
582 * termination current so it recommends turning off the termination
583 * function.
585 * Note: AFAICT from the datasheet, the user will have to manually
586 * turn off the charging when in 20% mode. If its not turned off,
587 * there could be battery damage. So, use this mode at your own risk.
589 switch (val->intval) {
590 case POWER_SUPPLY_CHARGE_TYPE_NONE:
591 chg_config = 0x0;
592 break;
593 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
594 chg_config = 0x1;
595 force_20pct = 0x1;
596 en_term = 0x0;
597 break;
598 case POWER_SUPPLY_CHARGE_TYPE_FAST:
599 chg_config = 0x1;
600 force_20pct = 0x0;
601 en_term = 0x1;
602 break;
603 default:
604 return -EINVAL;
607 if (chg_config) { /* Enabling the charger */
608 ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
609 BQ24190_REG_CCC_FORCE_20PCT_MASK,
610 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
611 force_20pct);
612 if (ret < 0)
613 return ret;
615 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
616 BQ24190_REG_CTTC_EN_TERM_MASK,
617 BQ24190_REG_CTTC_EN_TERM_SHIFT,
618 en_term);
619 if (ret < 0)
620 return ret;
623 return bq24190_write_mask(bdi, BQ24190_REG_POC,
624 BQ24190_REG_POC_CHG_CONFIG_MASK,
625 BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
628 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
629 union power_supply_propval *val)
631 u8 v;
632 int health;
634 mutex_lock(&bdi->f_reg_lock);
635 v = bdi->f_reg;
636 mutex_unlock(&bdi->f_reg_lock);
638 if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
640 * This could be over-current or over-voltage but there's
641 * no way to tell which. Return 'OVERVOLTAGE' since there
642 * isn't an 'OVERCURRENT' value defined that we can return
643 * even if it was over-current.
645 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
646 } else {
647 v &= BQ24190_REG_F_CHRG_FAULT_MASK;
648 v >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
650 switch (v) {
651 case 0x0: /* Normal */
652 health = POWER_SUPPLY_HEALTH_GOOD;
653 break;
654 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
656 * This could be over-voltage or under-voltage
657 * and there's no way to tell which. Instead
658 * of looking foolish and returning 'OVERVOLTAGE'
659 * when its really under-voltage, just return
660 * 'UNSPEC_FAILURE'.
662 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
663 break;
664 case 0x2: /* Thermal Shutdown */
665 health = POWER_SUPPLY_HEALTH_OVERHEAT;
666 break;
667 case 0x3: /* Charge Safety Timer Expiration */
668 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
669 break;
670 default:
671 health = POWER_SUPPLY_HEALTH_UNKNOWN;
675 val->intval = health;
677 return 0;
680 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
681 union power_supply_propval *val)
683 u8 v;
684 int ret;
686 ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
687 BQ24190_REG_SS_PG_STAT_MASK,
688 BQ24190_REG_SS_PG_STAT_SHIFT, &v);
689 if (ret < 0)
690 return ret;
692 val->intval = v;
693 return 0;
696 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
697 union power_supply_propval *val)
699 u8 v;
700 int curr, ret;
702 ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
703 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
704 bq24190_ccc_ichg_values,
705 ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
706 if (ret < 0)
707 return ret;
709 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
710 BQ24190_REG_CCC_FORCE_20PCT_MASK,
711 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
712 if (ret < 0)
713 return ret;
715 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
716 if (v)
717 curr /= 5;
719 val->intval = curr;
720 return 0;
723 static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
724 union power_supply_propval *val)
726 int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
728 val->intval = bq24190_ccc_ichg_values[idx];
729 return 0;
732 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
733 const union power_supply_propval *val)
735 u8 v;
736 int ret, curr = val->intval;
738 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
739 BQ24190_REG_CCC_FORCE_20PCT_MASK,
740 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
741 if (ret < 0)
742 return ret;
744 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
745 if (v)
746 curr *= 5;
748 return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
749 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
750 bq24190_ccc_ichg_values,
751 ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
754 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
755 union power_supply_propval *val)
757 int voltage, ret;
759 ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
760 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
761 bq24190_cvc_vreg_values,
762 ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
763 if (ret < 0)
764 return ret;
766 val->intval = voltage;
767 return 0;
770 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
771 union power_supply_propval *val)
773 int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
775 val->intval = bq24190_cvc_vreg_values[idx];
776 return 0;
779 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
780 const union power_supply_propval *val)
782 return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
783 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
784 bq24190_cvc_vreg_values,
785 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
788 static int bq24190_charger_get_property(struct power_supply *psy,
789 enum power_supply_property psp, union power_supply_propval *val)
791 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
792 int ret;
794 dev_dbg(bdi->dev, "prop: %d\n", psp);
796 pm_runtime_get_sync(bdi->dev);
798 switch (psp) {
799 case POWER_SUPPLY_PROP_CHARGE_TYPE:
800 ret = bq24190_charger_get_charge_type(bdi, val);
801 break;
802 case POWER_SUPPLY_PROP_HEALTH:
803 ret = bq24190_charger_get_health(bdi, val);
804 break;
805 case POWER_SUPPLY_PROP_ONLINE:
806 ret = bq24190_charger_get_online(bdi, val);
807 break;
808 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
809 ret = bq24190_charger_get_current(bdi, val);
810 break;
811 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
812 ret = bq24190_charger_get_current_max(bdi, val);
813 break;
814 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
815 ret = bq24190_charger_get_voltage(bdi, val);
816 break;
817 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
818 ret = bq24190_charger_get_voltage_max(bdi, val);
819 break;
820 case POWER_SUPPLY_PROP_SCOPE:
821 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
822 ret = 0;
823 break;
824 case POWER_SUPPLY_PROP_MODEL_NAME:
825 val->strval = bdi->model_name;
826 ret = 0;
827 break;
828 case POWER_SUPPLY_PROP_MANUFACTURER:
829 val->strval = BQ24190_MANUFACTURER;
830 ret = 0;
831 break;
832 default:
833 ret = -ENODATA;
836 pm_runtime_put_sync(bdi->dev);
837 return ret;
840 static int bq24190_charger_set_property(struct power_supply *psy,
841 enum power_supply_property psp,
842 const union power_supply_propval *val)
844 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
845 int ret;
847 dev_dbg(bdi->dev, "prop: %d\n", psp);
849 pm_runtime_get_sync(bdi->dev);
851 switch (psp) {
852 case POWER_SUPPLY_PROP_CHARGE_TYPE:
853 ret = bq24190_charger_set_charge_type(bdi, val);
854 break;
855 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
856 ret = bq24190_charger_set_current(bdi, val);
857 break;
858 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
859 ret = bq24190_charger_set_voltage(bdi, val);
860 break;
861 default:
862 ret = -EINVAL;
865 pm_runtime_put_sync(bdi->dev);
866 return ret;
869 static int bq24190_charger_property_is_writeable(struct power_supply *psy,
870 enum power_supply_property psp)
872 int ret;
874 switch (psp) {
875 case POWER_SUPPLY_PROP_CHARGE_TYPE:
876 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
877 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
878 ret = 1;
879 break;
880 default:
881 ret = 0;
884 return ret;
887 static enum power_supply_property bq24190_charger_properties[] = {
888 POWER_SUPPLY_PROP_CHARGE_TYPE,
889 POWER_SUPPLY_PROP_HEALTH,
890 POWER_SUPPLY_PROP_ONLINE,
891 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
892 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
893 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
894 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
895 POWER_SUPPLY_PROP_SCOPE,
896 POWER_SUPPLY_PROP_MODEL_NAME,
897 POWER_SUPPLY_PROP_MANUFACTURER,
900 static char *bq24190_charger_supplied_to[] = {
901 "main-battery",
904 static const struct power_supply_desc bq24190_charger_desc = {
905 .name = "bq24190-charger",
906 .type = POWER_SUPPLY_TYPE_USB,
907 .properties = bq24190_charger_properties,
908 .num_properties = ARRAY_SIZE(bq24190_charger_properties),
909 .get_property = bq24190_charger_get_property,
910 .set_property = bq24190_charger_set_property,
911 .property_is_writeable = bq24190_charger_property_is_writeable,
914 /* Battery power supply property routines */
916 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
917 union power_supply_propval *val)
919 u8 ss_reg, chrg_fault;
920 int status, ret;
922 mutex_lock(&bdi->f_reg_lock);
923 chrg_fault = bdi->f_reg;
924 mutex_unlock(&bdi->f_reg_lock);
926 chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
927 chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
929 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
930 if (ret < 0)
931 return ret;
934 * The battery must be discharging when any of these are true:
935 * - there is no good power source;
936 * - there is a charge fault.
937 * Could also be discharging when in "supplement mode" but
938 * there is no way to tell when its in that mode.
940 if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
941 status = POWER_SUPPLY_STATUS_DISCHARGING;
942 } else {
943 ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
944 ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
946 switch (ss_reg) {
947 case 0x0: /* Not Charging */
948 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
949 break;
950 case 0x1: /* Pre-charge */
951 case 0x2: /* Fast Charging */
952 status = POWER_SUPPLY_STATUS_CHARGING;
953 break;
954 case 0x3: /* Charge Termination Done */
955 status = POWER_SUPPLY_STATUS_FULL;
956 break;
957 default:
958 ret = -EIO;
962 if (!ret)
963 val->intval = status;
965 return ret;
968 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
969 union power_supply_propval *val)
971 u8 v;
972 int health;
974 mutex_lock(&bdi->f_reg_lock);
975 v = bdi->f_reg;
976 mutex_unlock(&bdi->f_reg_lock);
978 if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
979 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
980 } else {
981 v &= BQ24190_REG_F_NTC_FAULT_MASK;
982 v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
984 switch (v) {
985 case 0x0: /* Normal */
986 health = POWER_SUPPLY_HEALTH_GOOD;
987 break;
988 case 0x1: /* TS1 Cold */
989 case 0x3: /* TS2 Cold */
990 case 0x5: /* Both Cold */
991 health = POWER_SUPPLY_HEALTH_COLD;
992 break;
993 case 0x2: /* TS1 Hot */
994 case 0x4: /* TS2 Hot */
995 case 0x6: /* Both Hot */
996 health = POWER_SUPPLY_HEALTH_OVERHEAT;
997 break;
998 default:
999 health = POWER_SUPPLY_HEALTH_UNKNOWN;
1003 val->intval = health;
1004 return 0;
1007 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1008 union power_supply_propval *val)
1010 u8 batfet_disable;
1011 int ret;
1013 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1014 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1015 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1016 if (ret < 0)
1017 return ret;
1019 val->intval = !batfet_disable;
1020 return 0;
1023 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1024 const union power_supply_propval *val)
1026 return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1027 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1028 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1031 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1032 union power_supply_propval *val)
1034 int temp, ret;
1036 ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1037 BQ24190_REG_ICTRC_TREG_MASK,
1038 BQ24190_REG_ICTRC_TREG_SHIFT,
1039 bq24190_ictrc_treg_values,
1040 ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1041 if (ret < 0)
1042 return ret;
1044 val->intval = temp;
1045 return 0;
1048 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1049 const union power_supply_propval *val)
1051 return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1052 BQ24190_REG_ICTRC_TREG_MASK,
1053 BQ24190_REG_ICTRC_TREG_SHIFT,
1054 bq24190_ictrc_treg_values,
1055 ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1058 static int bq24190_battery_get_property(struct power_supply *psy,
1059 enum power_supply_property psp, union power_supply_propval *val)
1061 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1062 int ret;
1064 dev_dbg(bdi->dev, "prop: %d\n", psp);
1066 pm_runtime_get_sync(bdi->dev);
1068 switch (psp) {
1069 case POWER_SUPPLY_PROP_STATUS:
1070 ret = bq24190_battery_get_status(bdi, val);
1071 break;
1072 case POWER_SUPPLY_PROP_HEALTH:
1073 ret = bq24190_battery_get_health(bdi, val);
1074 break;
1075 case POWER_SUPPLY_PROP_ONLINE:
1076 ret = bq24190_battery_get_online(bdi, val);
1077 break;
1078 case POWER_SUPPLY_PROP_TECHNOLOGY:
1079 /* Could be Li-on or Li-polymer but no way to tell which */
1080 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1081 ret = 0;
1082 break;
1083 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1084 ret = bq24190_battery_get_temp_alert_max(bdi, val);
1085 break;
1086 case POWER_SUPPLY_PROP_SCOPE:
1087 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1088 ret = 0;
1089 break;
1090 default:
1091 ret = -ENODATA;
1094 pm_runtime_put_sync(bdi->dev);
1095 return ret;
1098 static int bq24190_battery_set_property(struct power_supply *psy,
1099 enum power_supply_property psp,
1100 const union power_supply_propval *val)
1102 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1103 int ret;
1105 dev_dbg(bdi->dev, "prop: %d\n", psp);
1107 pm_runtime_put_sync(bdi->dev);
1109 switch (psp) {
1110 case POWER_SUPPLY_PROP_ONLINE:
1111 ret = bq24190_battery_set_online(bdi, val);
1112 break;
1113 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1114 ret = bq24190_battery_set_temp_alert_max(bdi, val);
1115 break;
1116 default:
1117 ret = -EINVAL;
1120 pm_runtime_put_sync(bdi->dev);
1121 return ret;
1124 static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1125 enum power_supply_property psp)
1127 int ret;
1129 switch (psp) {
1130 case POWER_SUPPLY_PROP_ONLINE:
1131 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1132 ret = 1;
1133 break;
1134 default:
1135 ret = 0;
1138 return ret;
1141 static enum power_supply_property bq24190_battery_properties[] = {
1142 POWER_SUPPLY_PROP_STATUS,
1143 POWER_SUPPLY_PROP_HEALTH,
1144 POWER_SUPPLY_PROP_ONLINE,
1145 POWER_SUPPLY_PROP_TECHNOLOGY,
1146 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1147 POWER_SUPPLY_PROP_SCOPE,
1150 static const struct power_supply_desc bq24190_battery_desc = {
1151 .name = "bq24190-battery",
1152 .type = POWER_SUPPLY_TYPE_BATTERY,
1153 .properties = bq24190_battery_properties,
1154 .num_properties = ARRAY_SIZE(bq24190_battery_properties),
1155 .get_property = bq24190_battery_get_property,
1156 .set_property = bq24190_battery_set_property,
1157 .property_is_writeable = bq24190_battery_property_is_writeable,
1160 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1162 struct bq24190_dev_info *bdi = data;
1163 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1164 const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1165 | BQ24190_REG_F_NTC_FAULT_MASK;
1166 bool alert_charger = false, alert_battery = false;
1167 u8 ss_reg = 0, f_reg = 0;
1168 int i, ret;
1170 pm_runtime_get_sync(bdi->dev);
1172 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1173 if (ret < 0) {
1174 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1175 goto out;
1178 i = 0;
1179 do {
1180 ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1181 if (ret < 0) {
1182 dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1183 goto out;
1185 } while (f_reg && ++i < 2);
1187 if (f_reg != bdi->f_reg) {
1188 dev_info(bdi->dev,
1189 "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1190 !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1191 !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1192 !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1193 !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1195 mutex_lock(&bdi->f_reg_lock);
1196 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1197 alert_battery = true;
1198 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1199 alert_charger = true;
1200 bdi->f_reg = f_reg;
1201 mutex_unlock(&bdi->f_reg_lock);
1204 if (ss_reg != bdi->ss_reg) {
1206 * The device is in host mode so when PG_STAT goes from 1->0
1207 * (i.e., power removed) HIZ needs to be disabled.
1209 if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1210 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1211 ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1212 BQ24190_REG_ISC_EN_HIZ_MASK,
1213 BQ24190_REG_ISC_EN_HIZ_SHIFT,
1215 if (ret < 0)
1216 dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1217 ret);
1220 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1221 alert_battery = true;
1222 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1223 alert_charger = true;
1224 bdi->ss_reg = ss_reg;
1227 if (alert_charger)
1228 power_supply_changed(bdi->charger);
1229 if (alert_battery)
1230 power_supply_changed(bdi->battery);
1232 out:
1233 pm_runtime_put_sync(bdi->dev);
1235 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1237 return IRQ_HANDLED;
1240 static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1242 u8 v;
1243 int ret;
1245 pm_runtime_get_sync(bdi->dev);
1247 /* First check that the device really is what its supposed to be */
1248 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1249 BQ24190_REG_VPRS_PN_MASK,
1250 BQ24190_REG_VPRS_PN_SHIFT,
1251 &v);
1252 if (ret < 0)
1253 goto out;
1255 if (v != bdi->model) {
1256 ret = -ENODEV;
1257 goto out;
1260 ret = bq24190_register_reset(bdi);
1261 if (ret < 0)
1262 goto out;
1264 ret = bq24190_set_mode_host(bdi);
1265 if (ret < 0)
1266 goto out;
1268 ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1269 out:
1270 pm_runtime_put_sync(bdi->dev);
1271 return ret;
1274 #ifdef CONFIG_OF
1275 static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1277 bdi->irq = irq_of_parse_and_map(bdi->dev->of_node, 0);
1278 if (bdi->irq <= 0)
1279 return -1;
1281 return 0;
1283 #else
1284 static int bq24190_setup_dt(struct bq24190_dev_info *bdi)
1286 return -1;
1288 #endif
1290 static int bq24190_setup_pdata(struct bq24190_dev_info *bdi,
1291 struct bq24190_platform_data *pdata)
1293 int ret;
1295 if (!gpio_is_valid(pdata->gpio_int))
1296 return -1;
1298 ret = gpio_request(pdata->gpio_int, dev_name(bdi->dev));
1299 if (ret < 0)
1300 return -1;
1302 ret = gpio_direction_input(pdata->gpio_int);
1303 if (ret < 0)
1304 goto out;
1306 bdi->irq = gpio_to_irq(pdata->gpio_int);
1307 if (!bdi->irq)
1308 goto out;
1310 bdi->gpio_int = pdata->gpio_int;
1311 return 0;
1313 out:
1314 gpio_free(pdata->gpio_int);
1315 return -1;
1318 static int bq24190_probe(struct i2c_client *client,
1319 const struct i2c_device_id *id)
1321 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1322 struct device *dev = &client->dev;
1323 struct bq24190_platform_data *pdata = client->dev.platform_data;
1324 struct power_supply_config charger_cfg = {}, battery_cfg = {};
1325 struct bq24190_dev_info *bdi;
1326 int ret;
1328 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1329 dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1330 return -ENODEV;
1333 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1334 if (!bdi) {
1335 dev_err(dev, "Can't alloc bdi struct\n");
1336 return -ENOMEM;
1339 bdi->client = client;
1340 bdi->dev = dev;
1341 bdi->model = id->driver_data;
1342 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1343 mutex_init(&bdi->f_reg_lock);
1344 bdi->f_reg = 0;
1345 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1347 i2c_set_clientdata(client, bdi);
1349 if (dev->of_node)
1350 ret = bq24190_setup_dt(bdi);
1351 else
1352 ret = bq24190_setup_pdata(bdi, pdata);
1354 if (ret) {
1355 dev_err(dev, "Can't get irq info\n");
1356 return -EINVAL;
1359 pm_runtime_enable(dev);
1360 pm_runtime_resume(dev);
1362 ret = bq24190_hw_init(bdi);
1363 if (ret < 0) {
1364 dev_err(dev, "Hardware init failed\n");
1365 goto out1;
1368 charger_cfg.drv_data = bdi;
1369 charger_cfg.supplied_to = bq24190_charger_supplied_to;
1370 charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1371 bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1372 &charger_cfg);
1373 if (IS_ERR(bdi->charger)) {
1374 dev_err(dev, "Can't register charger\n");
1375 ret = PTR_ERR(bdi->charger);
1376 goto out1;
1379 battery_cfg.drv_data = bdi;
1380 bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1381 &battery_cfg);
1382 if (IS_ERR(bdi->battery)) {
1383 dev_err(dev, "Can't register battery\n");
1384 ret = PTR_ERR(bdi->battery);
1385 goto out2;
1388 ret = bq24190_sysfs_create_group(bdi);
1389 if (ret) {
1390 dev_err(dev, "Can't create sysfs entries\n");
1391 goto out3;
1394 ret = devm_request_threaded_irq(dev, bdi->irq, NULL,
1395 bq24190_irq_handler_thread,
1396 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1397 "bq24190-charger", bdi);
1398 if (ret < 0) {
1399 dev_err(dev, "Can't set up irq handler\n");
1400 goto out4;
1403 return 0;
1405 out4:
1406 bq24190_sysfs_remove_group(bdi);
1407 out3:
1408 power_supply_unregister(bdi->battery);
1409 out2:
1410 power_supply_unregister(bdi->charger);
1411 out1:
1412 pm_runtime_disable(dev);
1413 if (bdi->gpio_int)
1414 gpio_free(bdi->gpio_int);
1416 return ret;
1419 static int bq24190_remove(struct i2c_client *client)
1421 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1423 pm_runtime_get_sync(bdi->dev);
1424 bq24190_register_reset(bdi);
1425 pm_runtime_put_sync(bdi->dev);
1427 bq24190_sysfs_remove_group(bdi);
1428 power_supply_unregister(bdi->battery);
1429 power_supply_unregister(bdi->charger);
1430 pm_runtime_disable(bdi->dev);
1432 if (bdi->gpio_int)
1433 gpio_free(bdi->gpio_int);
1435 return 0;
1438 #ifdef CONFIG_PM_SLEEP
1439 static int bq24190_pm_suspend(struct device *dev)
1441 struct i2c_client *client = to_i2c_client(dev);
1442 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1444 pm_runtime_get_sync(bdi->dev);
1445 bq24190_register_reset(bdi);
1446 pm_runtime_put_sync(bdi->dev);
1448 return 0;
1451 static int bq24190_pm_resume(struct device *dev)
1453 struct i2c_client *client = to_i2c_client(dev);
1454 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1456 bdi->f_reg = 0;
1457 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1459 pm_runtime_get_sync(bdi->dev);
1460 bq24190_register_reset(bdi);
1461 bq24190_set_mode_host(bdi);
1462 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1463 pm_runtime_put_sync(bdi->dev);
1465 /* Things may have changed while suspended so alert upper layer */
1466 power_supply_changed(bdi->charger);
1467 power_supply_changed(bdi->battery);
1469 return 0;
1471 #endif
1473 static SIMPLE_DEV_PM_OPS(bq24190_pm_ops, bq24190_pm_suspend, bq24190_pm_resume);
1476 * Only support the bq24190 right now. The bq24192, bq24192i, and bq24193
1477 * are similar but not identical so the driver needs to be extended to
1478 * support them.
1480 static const struct i2c_device_id bq24190_i2c_ids[] = {
1481 { "bq24190", BQ24190_REG_VPRS_PN_24190 },
1482 { },
1484 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1486 #ifdef CONFIG_OF
1487 static const struct of_device_id bq24190_of_match[] = {
1488 { .compatible = "ti,bq24190", },
1489 { },
1491 MODULE_DEVICE_TABLE(of, bq24190_of_match);
1492 #else
1493 static const struct of_device_id bq24190_of_match[] = {
1494 { },
1496 #endif
1498 static struct i2c_driver bq24190_driver = {
1499 .probe = bq24190_probe,
1500 .remove = bq24190_remove,
1501 .id_table = bq24190_i2c_ids,
1502 .driver = {
1503 .name = "bq24190-charger",
1504 .pm = &bq24190_pm_ops,
1505 .of_match_table = of_match_ptr(bq24190_of_match),
1508 module_i2c_driver(bq24190_driver);
1510 MODULE_LICENSE("GPL");
1511 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1512 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");