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.
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/power/bq24190_charger.h>
19 #include <linux/regulator/driver.h>
20 #include <linux/regulator/machine.h>
21 #include <linux/workqueue.h>
22 #include <linux/gpio.h>
23 #include <linux/i2c.h>
25 #define BQ24190_MANUFACTURER "Texas Instruments"
27 #define BQ24190_REG_ISC 0x00 /* Input Source Control */
28 #define BQ24190_REG_ISC_EN_HIZ_MASK BIT(7)
29 #define BQ24190_REG_ISC_EN_HIZ_SHIFT 7
30 #define BQ24190_REG_ISC_VINDPM_MASK (BIT(6) | BIT(5) | BIT(4) | \
32 #define BQ24190_REG_ISC_VINDPM_SHIFT 3
33 #define BQ24190_REG_ISC_IINLIM_MASK (BIT(2) | BIT(1) | BIT(0))
34 #define BQ24190_REG_ISC_IINLIM_SHIFT 0
36 #define BQ24190_REG_POC 0x01 /* Power-On Configuration */
37 #define BQ24190_REG_POC_RESET_MASK BIT(7)
38 #define BQ24190_REG_POC_RESET_SHIFT 7
39 #define BQ24190_REG_POC_WDT_RESET_MASK BIT(6)
40 #define BQ24190_REG_POC_WDT_RESET_SHIFT 6
41 #define BQ24190_REG_POC_CHG_CONFIG_MASK (BIT(5) | BIT(4))
42 #define BQ24190_REG_POC_CHG_CONFIG_SHIFT 4
43 #define BQ24190_REG_POC_CHG_CONFIG_DISABLE 0x0
44 #define BQ24190_REG_POC_CHG_CONFIG_CHARGE 0x1
45 #define BQ24190_REG_POC_CHG_CONFIG_OTG 0x2
46 #define BQ24190_REG_POC_CHG_CONFIG_OTG_ALT 0x3
47 #define BQ24190_REG_POC_SYS_MIN_MASK (BIT(3) | BIT(2) | BIT(1))
48 #define BQ24190_REG_POC_SYS_MIN_SHIFT 1
49 #define BQ24190_REG_POC_SYS_MIN_MIN 3000
50 #define BQ24190_REG_POC_SYS_MIN_MAX 3700
51 #define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0)
52 #define BQ24190_REG_POC_BOOST_LIM_SHIFT 0
54 #define BQ24190_REG_CCC 0x02 /* Charge Current Control */
55 #define BQ24190_REG_CCC_ICHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
56 BIT(4) | BIT(3) | BIT(2))
57 #define BQ24190_REG_CCC_ICHG_SHIFT 2
58 #define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0)
59 #define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0
61 #define BQ24190_REG_PCTCC 0x03 /* Pre-charge/Termination Current Cntl */
62 #define BQ24190_REG_PCTCC_IPRECHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
64 #define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4
65 #define BQ24190_REG_PCTCC_IPRECHG_MIN 128
66 #define BQ24190_REG_PCTCC_IPRECHG_MAX 2048
67 #define BQ24190_REG_PCTCC_ITERM_MASK (BIT(3) | BIT(2) | BIT(1) | \
69 #define BQ24190_REG_PCTCC_ITERM_SHIFT 0
70 #define BQ24190_REG_PCTCC_ITERM_MIN 128
71 #define BQ24190_REG_PCTCC_ITERM_MAX 2048
73 #define BQ24190_REG_CVC 0x04 /* Charge Voltage Control */
74 #define BQ24190_REG_CVC_VREG_MASK (BIT(7) | BIT(6) | BIT(5) | \
75 BIT(4) | BIT(3) | BIT(2))
76 #define BQ24190_REG_CVC_VREG_SHIFT 2
77 #define BQ24190_REG_CVC_BATLOWV_MASK BIT(1)
78 #define BQ24190_REG_CVC_BATLOWV_SHIFT 1
79 #define BQ24190_REG_CVC_VRECHG_MASK BIT(0)
80 #define BQ24190_REG_CVC_VRECHG_SHIFT 0
82 #define BQ24190_REG_CTTC 0x05 /* Charge Term/Timer Control */
83 #define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7)
84 #define BQ24190_REG_CTTC_EN_TERM_SHIFT 7
85 #define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6)
86 #define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6
87 #define BQ24190_REG_CTTC_WATCHDOG_MASK (BIT(5) | BIT(4))
88 #define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4
89 #define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3)
90 #define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3
91 #define BQ24190_REG_CTTC_CHG_TIMER_MASK (BIT(2) | BIT(1))
92 #define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1
93 #define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0)
94 #define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0
96 #define BQ24190_REG_ICTRC 0x06 /* IR Comp/Thermal Regulation Control */
97 #define BQ24190_REG_ICTRC_BAT_COMP_MASK (BIT(7) | BIT(6) | BIT(5))
98 #define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5
99 #define BQ24190_REG_ICTRC_VCLAMP_MASK (BIT(4) | BIT(3) | BIT(2))
100 #define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2
101 #define BQ24190_REG_ICTRC_TREG_MASK (BIT(1) | BIT(0))
102 #define BQ24190_REG_ICTRC_TREG_SHIFT 0
104 #define BQ24190_REG_MOC 0x07 /* Misc. Operation Control */
105 #define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7)
106 #define BQ24190_REG_MOC_DPDM_EN_SHIFT 7
107 #define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6)
108 #define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6
109 #define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5)
110 #define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5
111 #define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4)
112 #define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4
113 #define BQ24190_REG_MOC_INT_MASK_MASK (BIT(1) | BIT(0))
114 #define BQ24190_REG_MOC_INT_MASK_SHIFT 0
116 #define BQ24190_REG_SS 0x08 /* System Status */
117 #define BQ24190_REG_SS_VBUS_STAT_MASK (BIT(7) | BIT(6))
118 #define BQ24190_REG_SS_VBUS_STAT_SHIFT 6
119 #define BQ24190_REG_SS_CHRG_STAT_MASK (BIT(5) | BIT(4))
120 #define BQ24190_REG_SS_CHRG_STAT_SHIFT 4
121 #define BQ24190_REG_SS_DPM_STAT_MASK BIT(3)
122 #define BQ24190_REG_SS_DPM_STAT_SHIFT 3
123 #define BQ24190_REG_SS_PG_STAT_MASK BIT(2)
124 #define BQ24190_REG_SS_PG_STAT_SHIFT 2
125 #define BQ24190_REG_SS_THERM_STAT_MASK BIT(1)
126 #define BQ24190_REG_SS_THERM_STAT_SHIFT 1
127 #define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0)
128 #define BQ24190_REG_SS_VSYS_STAT_SHIFT 0
130 #define BQ24190_REG_F 0x09 /* Fault */
131 #define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7)
132 #define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7
133 #define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6)
134 #define BQ24190_REG_F_BOOST_FAULT_SHIFT 6
135 #define BQ24190_REG_F_CHRG_FAULT_MASK (BIT(5) | BIT(4))
136 #define BQ24190_REG_F_CHRG_FAULT_SHIFT 4
137 #define BQ24190_REG_F_BAT_FAULT_MASK BIT(3)
138 #define BQ24190_REG_F_BAT_FAULT_SHIFT 3
139 #define BQ24190_REG_F_NTC_FAULT_MASK (BIT(2) | BIT(1) | BIT(0))
140 #define BQ24190_REG_F_NTC_FAULT_SHIFT 0
142 #define BQ24190_REG_VPRS 0x0A /* Vendor/Part/Revision Status */
143 #define BQ24190_REG_VPRS_PN_MASK (BIT(5) | BIT(4) | BIT(3))
144 #define BQ24190_REG_VPRS_PN_SHIFT 3
145 #define BQ24190_REG_VPRS_PN_24190 0x4
146 #define BQ24190_REG_VPRS_PN_24192 0x5 /* Also 24193 */
147 #define BQ24190_REG_VPRS_PN_24192I 0x3
148 #define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2)
149 #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2
150 #define BQ24190_REG_VPRS_DEV_REG_MASK (BIT(1) | BIT(0))
151 #define BQ24190_REG_VPRS_DEV_REG_SHIFT 0
154 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
155 * so the first read after a fault returns the latched value and subsequent
156 * reads return the current value. In order to return the fault status
157 * to the user, have the interrupt handler save the reg's value and retrieve
158 * it in the appropriate health/status routine.
160 struct bq24190_dev_info {
161 struct i2c_client *client;
163 struct power_supply *charger;
164 struct power_supply *battery;
165 struct delayed_work input_current_limit_work;
166 char model_name[I2C_NAME_SIZE];
172 struct mutex f_reg_lock;
179 * The tables below provide a 2-way mapping for the value that goes in
180 * the register field and the real-world value that it represents.
181 * The index of the array is the value that goes in the register; the
182 * number at that index in the array is the real-world value that it
186 /* REG00[2:0] (IINLIM) in uAh */
187 static const int bq24190_isc_iinlim_values[] = {
188 100000, 150000, 500000, 900000, 1200000, 1500000, 2000000, 3000000
191 /* REG02[7:2] (ICHG) in uAh */
192 static const int bq24190_ccc_ichg_values[] = {
193 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
194 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
195 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
196 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
197 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
198 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
199 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
200 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
203 /* REG04[7:2] (VREG) in uV */
204 static const int bq24190_cvc_vreg_values[] = {
205 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
206 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
207 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
208 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
209 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
210 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
211 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
215 /* REG06[1:0] (TREG) in tenths of degrees Celsius */
216 static const int bq24190_ictrc_treg_values[] = {
221 * Return the index in 'tbl' of greatest value that is less than or equal to
222 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
223 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
226 static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
230 for (i = 1; i < tbl_size; i++)
237 /* Basic driver I/O routines */
239 static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
243 ret = i2c_smbus_read_byte_data(bdi->client, reg);
251 static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
253 return i2c_smbus_write_byte_data(bdi->client, reg, data);
256 static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
257 u8 mask, u8 shift, u8 *data)
262 ret = bq24190_read(bdi, reg, &v);
273 static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
274 u8 mask, u8 shift, u8 data)
279 ret = bq24190_read(bdi, reg, &v);
284 v |= ((data << shift) & mask);
286 return bq24190_write(bdi, reg, v);
289 static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
290 u8 reg, u8 mask, u8 shift,
291 const int tbl[], int tbl_size,
297 ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
301 v = (v >= tbl_size) ? (tbl_size - 1) : v;
307 static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
308 u8 reg, u8 mask, u8 shift,
309 const int tbl[], int tbl_size,
314 idx = bq24190_find_idx(tbl, tbl_size, val);
316 return bq24190_write_mask(bdi, reg, mask, shift, idx);
321 * There are a numerous options that are configurable on the bq24190
322 * that go well beyond what the power_supply properties provide access to.
323 * Provide sysfs access to them so they can be examined and possibly modified
324 * on the fly. They will be provided for the charger power_supply object only
325 * and will be prefixed by 'f_' to make them easier to recognize.
328 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
330 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
331 .reg = BQ24190_REG_##r, \
332 .mask = BQ24190_REG_##r##_##f##_MASK, \
333 .shift = BQ24190_REG_##r##_##f##_SHIFT, \
336 #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
337 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
340 #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
341 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
343 static ssize_t bq24190_sysfs_show(struct device *dev,
344 struct device_attribute *attr, char *buf);
345 static ssize_t bq24190_sysfs_store(struct device *dev,
346 struct device_attribute *attr, const char *buf, size_t count);
348 struct bq24190_sysfs_field_info {
349 struct device_attribute attr;
355 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
358 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
359 /* sysfs name reg field in reg */
360 BQ24190_SYSFS_FIELD_RW(en_hiz, ISC, EN_HIZ),
361 BQ24190_SYSFS_FIELD_RW(vindpm, ISC, VINDPM),
362 BQ24190_SYSFS_FIELD_RW(iinlim, ISC, IINLIM),
363 BQ24190_SYSFS_FIELD_RW(chg_config, POC, CHG_CONFIG),
364 BQ24190_SYSFS_FIELD_RW(sys_min, POC, SYS_MIN),
365 BQ24190_SYSFS_FIELD_RW(boost_lim, POC, BOOST_LIM),
366 BQ24190_SYSFS_FIELD_RW(ichg, CCC, ICHG),
367 BQ24190_SYSFS_FIELD_RW(force_20_pct, CCC, FORCE_20PCT),
368 BQ24190_SYSFS_FIELD_RW(iprechg, PCTCC, IPRECHG),
369 BQ24190_SYSFS_FIELD_RW(iterm, PCTCC, ITERM),
370 BQ24190_SYSFS_FIELD_RW(vreg, CVC, VREG),
371 BQ24190_SYSFS_FIELD_RW(batlowv, CVC, BATLOWV),
372 BQ24190_SYSFS_FIELD_RW(vrechg, CVC, VRECHG),
373 BQ24190_SYSFS_FIELD_RW(en_term, CTTC, EN_TERM),
374 BQ24190_SYSFS_FIELD_RW(term_stat, CTTC, TERM_STAT),
375 BQ24190_SYSFS_FIELD_RO(watchdog, CTTC, WATCHDOG),
376 BQ24190_SYSFS_FIELD_RW(en_timer, CTTC, EN_TIMER),
377 BQ24190_SYSFS_FIELD_RW(chg_timer, CTTC, CHG_TIMER),
378 BQ24190_SYSFS_FIELD_RW(jeta_iset, CTTC, JEITA_ISET),
379 BQ24190_SYSFS_FIELD_RW(bat_comp, ICTRC, BAT_COMP),
380 BQ24190_SYSFS_FIELD_RW(vclamp, ICTRC, VCLAMP),
381 BQ24190_SYSFS_FIELD_RW(treg, ICTRC, TREG),
382 BQ24190_SYSFS_FIELD_RW(dpdm_en, MOC, DPDM_EN),
383 BQ24190_SYSFS_FIELD_RW(tmr2x_en, MOC, TMR2X_EN),
384 BQ24190_SYSFS_FIELD_RW(batfet_disable, MOC, BATFET_DISABLE),
385 BQ24190_SYSFS_FIELD_RW(jeita_vset, MOC, JEITA_VSET),
386 BQ24190_SYSFS_FIELD_RO(int_mask, MOC, INT_MASK),
387 BQ24190_SYSFS_FIELD_RO(vbus_stat, SS, VBUS_STAT),
388 BQ24190_SYSFS_FIELD_RO(chrg_stat, SS, CHRG_STAT),
389 BQ24190_SYSFS_FIELD_RO(dpm_stat, SS, DPM_STAT),
390 BQ24190_SYSFS_FIELD_RO(pg_stat, SS, PG_STAT),
391 BQ24190_SYSFS_FIELD_RO(therm_stat, SS, THERM_STAT),
392 BQ24190_SYSFS_FIELD_RO(vsys_stat, SS, VSYS_STAT),
393 BQ24190_SYSFS_FIELD_RO(watchdog_fault, F, WATCHDOG_FAULT),
394 BQ24190_SYSFS_FIELD_RO(boost_fault, F, BOOST_FAULT),
395 BQ24190_SYSFS_FIELD_RO(chrg_fault, F, CHRG_FAULT),
396 BQ24190_SYSFS_FIELD_RO(bat_fault, F, BAT_FAULT),
397 BQ24190_SYSFS_FIELD_RO(ntc_fault, F, NTC_FAULT),
398 BQ24190_SYSFS_FIELD_RO(pn, VPRS, PN),
399 BQ24190_SYSFS_FIELD_RO(ts_profile, VPRS, TS_PROFILE),
400 BQ24190_SYSFS_FIELD_RO(dev_reg, VPRS, DEV_REG),
403 static struct attribute *
404 bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
406 static const struct attribute_group bq24190_sysfs_attr_group = {
407 .attrs = bq24190_sysfs_attrs,
410 static void bq24190_sysfs_init_attrs(void)
412 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
414 for (i = 0; i < limit; i++)
415 bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
417 bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
420 static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
423 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
425 for (i = 0; i < limit; i++)
426 if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
432 return &bq24190_sysfs_field_tbl[i];
435 static ssize_t bq24190_sysfs_show(struct device *dev,
436 struct device_attribute *attr, char *buf)
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;
445 info = bq24190_sysfs_field_lookup(attr->attr.name);
449 ret = pm_runtime_get_sync(bdi->dev);
451 pm_runtime_put_noidle(bdi->dev);
455 ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
459 count = scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
461 pm_runtime_mark_last_busy(bdi->dev);
462 pm_runtime_put_autosuspend(bdi->dev);
467 static ssize_t bq24190_sysfs_store(struct device *dev,
468 struct device_attribute *attr, const char *buf, size_t count)
470 struct power_supply *psy = dev_get_drvdata(dev);
471 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
472 struct bq24190_sysfs_field_info *info;
476 info = bq24190_sysfs_field_lookup(attr->attr.name);
480 ret = kstrtou8(buf, 0, &v);
484 ret = pm_runtime_get_sync(bdi->dev);
488 ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
492 pm_runtime_mark_last_busy(bdi->dev);
493 pm_runtime_put_autosuspend(bdi->dev);
498 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
500 bq24190_sysfs_init_attrs();
502 return sysfs_create_group(&bdi->charger->dev.kobj,
503 &bq24190_sysfs_attr_group);
506 static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi)
508 sysfs_remove_group(&bdi->charger->dev.kobj, &bq24190_sysfs_attr_group);
511 static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
516 static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {}
519 #ifdef CONFIG_REGULATOR
520 static int bq24190_set_charge_mode(struct regulator_dev *dev, u8 val)
522 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
525 ret = pm_runtime_get_sync(bdi->dev);
527 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
528 pm_runtime_put_noidle(bdi->dev);
532 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
533 BQ24190_REG_POC_CHG_CONFIG_MASK,
534 BQ24190_REG_POC_CHG_CONFIG_SHIFT, val);
536 pm_runtime_mark_last_busy(bdi->dev);
537 pm_runtime_put_autosuspend(bdi->dev);
542 static int bq24190_vbus_enable(struct regulator_dev *dev)
544 return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_OTG);
547 static int bq24190_vbus_disable(struct regulator_dev *dev)
549 return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_CHARGE);
552 static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
554 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
558 ret = pm_runtime_get_sync(bdi->dev);
560 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
561 pm_runtime_put_noidle(bdi->dev);
565 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
566 BQ24190_REG_POC_CHG_CONFIG_MASK,
567 BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
569 pm_runtime_mark_last_busy(bdi->dev);
570 pm_runtime_put_autosuspend(bdi->dev);
575 return (val == BQ24190_REG_POC_CHG_CONFIG_OTG ||
576 val == BQ24190_REG_POC_CHG_CONFIG_OTG_ALT);
579 static const struct regulator_ops bq24190_vbus_ops = {
580 .enable = bq24190_vbus_enable,
581 .disable = bq24190_vbus_disable,
582 .is_enabled = bq24190_vbus_is_enabled,
585 static const struct regulator_desc bq24190_vbus_desc = {
586 .name = "usb_otg_vbus",
587 .type = REGULATOR_VOLTAGE,
588 .owner = THIS_MODULE,
589 .ops = &bq24190_vbus_ops,
594 static const struct regulator_init_data bq24190_vbus_init_data = {
596 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
600 static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
602 struct bq24190_platform_data *pdata = bdi->dev->platform_data;
603 struct regulator_config cfg = { };
604 struct regulator_dev *reg;
608 if (pdata && pdata->regulator_init_data)
609 cfg.init_data = pdata->regulator_init_data;
611 cfg.init_data = &bq24190_vbus_init_data;
612 cfg.driver_data = bdi;
613 reg = devm_regulator_register(bdi->dev, &bq24190_vbus_desc, &cfg);
616 dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
622 static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
628 static int bq24190_set_config(struct bq24190_dev_info *bdi)
633 ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
637 bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
638 BQ24190_REG_CTTC_WATCHDOG_SHIFT);
641 * According to the "Host Mode and default Mode" section of the
642 * manual, a write to any register causes the bq24190 to switch
643 * from default mode to host mode. It will switch back to default
644 * mode after a WDT timeout unless the WDT is turned off as well.
645 * So, by simply turning off the WDT, we accomplish both with the
648 v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
650 ret = bq24190_write(bdi, BQ24190_REG_CTTC, v);
655 v = bdi->sys_min / 100 - 30; // manual section 9.5.1.2, table 9
656 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
657 BQ24190_REG_POC_SYS_MIN_MASK,
658 BQ24190_REG_POC_SYS_MIN_SHIFT,
665 v = bdi->iprechg / 128 - 1; // manual section 9.5.1.4, table 11
666 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
667 BQ24190_REG_PCTCC_IPRECHG_MASK,
668 BQ24190_REG_PCTCC_IPRECHG_SHIFT,
675 v = bdi->iterm / 128 - 1; // manual section 9.5.1.4, table 11
676 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
677 BQ24190_REG_PCTCC_ITERM_MASK,
678 BQ24190_REG_PCTCC_ITERM_SHIFT,
687 static int bq24190_register_reset(struct bq24190_dev_info *bdi)
689 int ret, limit = 100;
693 * This prop. can be passed on device instantiation from platform code:
694 * struct property_entry pe[] =
695 * { PROPERTY_ENTRY_BOOL("disable-reset"), ... };
696 * struct i2c_board_info bi =
697 * { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
698 * struct i2c_adapter ad = { ... };
699 * i2c_add_adapter(&ad);
700 * i2c_new_device(&ad, &bi);
702 if (device_property_read_bool(bdi->dev, "disable-reset"))
705 /* Reset the registers */
706 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
707 BQ24190_REG_POC_RESET_MASK,
708 BQ24190_REG_POC_RESET_SHIFT,
713 /* Reset bit will be cleared by hardware so poll until it is */
715 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
716 BQ24190_REG_POC_RESET_MASK,
717 BQ24190_REG_POC_RESET_SHIFT,
725 usleep_range(100, 200);
731 /* Charger power supply property routines */
733 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
734 union power_supply_propval *val)
739 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
740 BQ24190_REG_POC_CHG_CONFIG_MASK,
741 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
746 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
748 type = POWER_SUPPLY_CHARGE_TYPE_NONE;
750 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
751 BQ24190_REG_CCC_FORCE_20PCT_MASK,
752 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
757 type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
758 POWER_SUPPLY_CHARGE_TYPE_FAST;
766 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
767 const union power_supply_propval *val)
769 u8 chg_config, force_20pct, en_term;
773 * According to the "Termination when REG02[0] = 1" section of
774 * the bq24190 manual, the trickle charge could be less than the
775 * termination current so it recommends turning off the termination
778 * Note: AFAICT from the datasheet, the user will have to manually
779 * turn off the charging when in 20% mode. If its not turned off,
780 * there could be battery damage. So, use this mode at your own risk.
782 switch (val->intval) {
783 case POWER_SUPPLY_CHARGE_TYPE_NONE:
786 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
791 case POWER_SUPPLY_CHARGE_TYPE_FAST:
800 if (chg_config) { /* Enabling the charger */
801 ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
802 BQ24190_REG_CCC_FORCE_20PCT_MASK,
803 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
808 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
809 BQ24190_REG_CTTC_EN_TERM_MASK,
810 BQ24190_REG_CTTC_EN_TERM_SHIFT,
816 return bq24190_write_mask(bdi, BQ24190_REG_POC,
817 BQ24190_REG_POC_CHG_CONFIG_MASK,
818 BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
821 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
822 union power_supply_propval *val)
827 mutex_lock(&bdi->f_reg_lock);
829 mutex_unlock(&bdi->f_reg_lock);
831 if (v & BQ24190_REG_F_NTC_FAULT_MASK) {
832 switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
833 case 0x1: /* TS1 Cold */
834 case 0x3: /* TS2 Cold */
835 case 0x5: /* Both Cold */
836 health = POWER_SUPPLY_HEALTH_COLD;
838 case 0x2: /* TS1 Hot */
839 case 0x4: /* TS2 Hot */
840 case 0x6: /* Both Hot */
841 health = POWER_SUPPLY_HEALTH_OVERHEAT;
844 health = POWER_SUPPLY_HEALTH_UNKNOWN;
846 } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
847 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
848 } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
849 switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
850 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
852 * This could be over-voltage or under-voltage
853 * and there's no way to tell which. Instead
854 * of looking foolish and returning 'OVERVOLTAGE'
855 * when its really under-voltage, just return
858 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
860 case 0x2: /* Thermal Shutdown */
861 health = POWER_SUPPLY_HEALTH_OVERHEAT;
863 case 0x3: /* Charge Safety Timer Expiration */
864 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
866 default: /* prevent compiler warning */
869 } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
871 * This could be over-current or over-voltage but there's
872 * no way to tell which. Return 'OVERVOLTAGE' since there
873 * isn't an 'OVERCURRENT' value defined that we can return
874 * even if it was over-current.
876 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
878 health = POWER_SUPPLY_HEALTH_GOOD;
881 val->intval = health;
886 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
887 union power_supply_propval *val)
889 u8 pg_stat, batfet_disable;
892 ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
893 BQ24190_REG_SS_PG_STAT_MASK,
894 BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
898 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
899 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
900 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
904 val->intval = pg_stat && !batfet_disable;
909 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
910 const union power_supply_propval *val);
911 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
912 union power_supply_propval *val);
913 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
914 union power_supply_propval *val);
915 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
916 const union power_supply_propval *val);
918 static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
919 const union power_supply_propval *val)
921 return bq24190_battery_set_online(bdi, val);
924 static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
925 union power_supply_propval *val)
927 return bq24190_battery_get_status(bdi, val);
930 static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
931 union power_supply_propval *val)
933 return bq24190_battery_get_temp_alert_max(bdi, val);
936 static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
937 const union power_supply_propval *val)
939 return bq24190_battery_set_temp_alert_max(bdi, val);
942 static int bq24190_charger_get_precharge(struct bq24190_dev_info *bdi,
943 union power_supply_propval *val)
948 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
949 BQ24190_REG_PCTCC_IPRECHG_MASK,
950 BQ24190_REG_PCTCC_IPRECHG_SHIFT, &v);
954 val->intval = ++v * 128 * 1000;
958 static int bq24190_charger_get_charge_term(struct bq24190_dev_info *bdi,
959 union power_supply_propval *val)
964 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
965 BQ24190_REG_PCTCC_ITERM_MASK,
966 BQ24190_REG_PCTCC_ITERM_SHIFT, &v);
970 val->intval = ++v * 128 * 1000;
974 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
975 union power_supply_propval *val)
980 ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
981 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
982 bq24190_ccc_ichg_values,
983 ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
987 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
988 BQ24190_REG_CCC_FORCE_20PCT_MASK,
989 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
993 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
1001 static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
1002 union power_supply_propval *val)
1004 int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
1006 val->intval = bq24190_ccc_ichg_values[idx];
1010 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
1011 const union power_supply_propval *val)
1014 int ret, curr = val->intval;
1016 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1017 BQ24190_REG_CCC_FORCE_20PCT_MASK,
1018 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1022 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
1026 return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
1027 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1028 bq24190_ccc_ichg_values,
1029 ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
1032 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
1033 union power_supply_propval *val)
1037 ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
1038 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1039 bq24190_cvc_vreg_values,
1040 ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
1044 val->intval = voltage;
1048 static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
1049 union power_supply_propval *val)
1051 int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
1053 val->intval = bq24190_cvc_vreg_values[idx];
1057 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
1058 const union power_supply_propval *val)
1060 return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
1061 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1062 bq24190_cvc_vreg_values,
1063 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
1066 static int bq24190_charger_get_iinlimit(struct bq24190_dev_info *bdi,
1067 union power_supply_propval *val)
1071 ret = bq24190_get_field_val(bdi, BQ24190_REG_ISC,
1072 BQ24190_REG_ISC_IINLIM_MASK,
1073 BQ24190_REG_ISC_IINLIM_SHIFT,
1074 bq24190_isc_iinlim_values,
1075 ARRAY_SIZE(bq24190_isc_iinlim_values), &iinlimit);
1079 val->intval = iinlimit;
1083 static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi,
1084 const union power_supply_propval *val)
1086 return bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1087 BQ24190_REG_ISC_IINLIM_MASK,
1088 BQ24190_REG_ISC_IINLIM_SHIFT,
1089 bq24190_isc_iinlim_values,
1090 ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval);
1093 static int bq24190_charger_get_property(struct power_supply *psy,
1094 enum power_supply_property psp, union power_supply_propval *val)
1096 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1099 dev_dbg(bdi->dev, "prop: %d\n", psp);
1101 ret = pm_runtime_get_sync(bdi->dev);
1103 pm_runtime_put_noidle(bdi->dev);
1108 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1109 ret = bq24190_charger_get_charge_type(bdi, val);
1111 case POWER_SUPPLY_PROP_HEALTH:
1112 ret = bq24190_charger_get_health(bdi, val);
1114 case POWER_SUPPLY_PROP_ONLINE:
1115 ret = bq24190_charger_get_online(bdi, val);
1117 case POWER_SUPPLY_PROP_STATUS:
1118 ret = bq24190_charger_get_status(bdi, val);
1120 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1121 ret = bq24190_charger_get_temp_alert_max(bdi, val);
1123 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
1124 ret = bq24190_charger_get_precharge(bdi, val);
1126 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
1127 ret = bq24190_charger_get_charge_term(bdi, val);
1129 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1130 ret = bq24190_charger_get_current(bdi, val);
1132 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
1133 ret = bq24190_charger_get_current_max(bdi, val);
1135 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1136 ret = bq24190_charger_get_voltage(bdi, val);
1138 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
1139 ret = bq24190_charger_get_voltage_max(bdi, val);
1141 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1142 ret = bq24190_charger_get_iinlimit(bdi, val);
1144 case POWER_SUPPLY_PROP_SCOPE:
1145 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1148 case POWER_SUPPLY_PROP_MODEL_NAME:
1149 val->strval = bdi->model_name;
1152 case POWER_SUPPLY_PROP_MANUFACTURER:
1153 val->strval = BQ24190_MANUFACTURER;
1160 pm_runtime_mark_last_busy(bdi->dev);
1161 pm_runtime_put_autosuspend(bdi->dev);
1166 static int bq24190_charger_set_property(struct power_supply *psy,
1167 enum power_supply_property psp,
1168 const union power_supply_propval *val)
1170 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1173 dev_dbg(bdi->dev, "prop: %d\n", psp);
1175 ret = pm_runtime_get_sync(bdi->dev);
1177 pm_runtime_put_noidle(bdi->dev);
1182 case POWER_SUPPLY_PROP_ONLINE:
1183 ret = bq24190_charger_set_online(bdi, val);
1185 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1186 ret = bq24190_charger_set_temp_alert_max(bdi, val);
1188 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1189 ret = bq24190_charger_set_charge_type(bdi, val);
1191 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1192 ret = bq24190_charger_set_current(bdi, val);
1194 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1195 ret = bq24190_charger_set_voltage(bdi, val);
1197 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1198 ret = bq24190_charger_set_iinlimit(bdi, val);
1204 pm_runtime_mark_last_busy(bdi->dev);
1205 pm_runtime_put_autosuspend(bdi->dev);
1210 static int bq24190_charger_property_is_writeable(struct power_supply *psy,
1211 enum power_supply_property psp)
1214 case POWER_SUPPLY_PROP_ONLINE:
1215 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1216 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1217 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1218 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1219 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1226 static void bq24190_input_current_limit_work(struct work_struct *work)
1228 struct bq24190_dev_info *bdi =
1229 container_of(work, struct bq24190_dev_info,
1230 input_current_limit_work.work);
1231 union power_supply_propval val;
1234 ret = power_supply_get_property_from_supplier(bdi->charger,
1235 POWER_SUPPLY_PROP_CURRENT_MAX,
1240 bq24190_charger_set_property(bdi->charger,
1241 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1243 power_supply_changed(bdi->charger);
1246 /* Sync the input-current-limit with our parent supply (if we have one) */
1247 static void bq24190_charger_external_power_changed(struct power_supply *psy)
1249 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1252 * The Power-Good detection may take up to 220ms, sometimes
1253 * the external charger detection is quicker, and the bq24190 will
1254 * reset to iinlim based on its own charger detection (which is not
1255 * hooked up when using external charger detection) resulting in a
1256 * too low default 500mA iinlim. Delay setting the input-current-limit
1257 * for 300ms to avoid this.
1259 queue_delayed_work(system_wq, &bdi->input_current_limit_work,
1260 msecs_to_jiffies(300));
1263 static enum power_supply_property bq24190_charger_properties[] = {
1264 POWER_SUPPLY_PROP_CHARGE_TYPE,
1265 POWER_SUPPLY_PROP_HEALTH,
1266 POWER_SUPPLY_PROP_ONLINE,
1267 POWER_SUPPLY_PROP_STATUS,
1268 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1269 POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
1270 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
1271 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
1272 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
1273 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
1274 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
1275 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1276 POWER_SUPPLY_PROP_SCOPE,
1277 POWER_SUPPLY_PROP_MODEL_NAME,
1278 POWER_SUPPLY_PROP_MANUFACTURER,
1281 static char *bq24190_charger_supplied_to[] = {
1285 static const struct power_supply_desc bq24190_charger_desc = {
1286 .name = "bq24190-charger",
1287 .type = POWER_SUPPLY_TYPE_USB,
1288 .properties = bq24190_charger_properties,
1289 .num_properties = ARRAY_SIZE(bq24190_charger_properties),
1290 .get_property = bq24190_charger_get_property,
1291 .set_property = bq24190_charger_set_property,
1292 .property_is_writeable = bq24190_charger_property_is_writeable,
1293 .external_power_changed = bq24190_charger_external_power_changed,
1296 /* Battery power supply property routines */
1298 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1299 union power_supply_propval *val)
1301 u8 ss_reg, chrg_fault;
1304 mutex_lock(&bdi->f_reg_lock);
1305 chrg_fault = bdi->f_reg;
1306 mutex_unlock(&bdi->f_reg_lock);
1308 chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
1309 chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
1311 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1316 * The battery must be discharging when any of these are true:
1317 * - there is no good power source;
1318 * - there is a charge fault.
1319 * Could also be discharging when in "supplement mode" but
1320 * there is no way to tell when its in that mode.
1322 if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
1323 status = POWER_SUPPLY_STATUS_DISCHARGING;
1325 ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
1326 ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
1329 case 0x0: /* Not Charging */
1330 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1332 case 0x1: /* Pre-charge */
1333 case 0x2: /* Fast Charging */
1334 status = POWER_SUPPLY_STATUS_CHARGING;
1336 case 0x3: /* Charge Termination Done */
1337 status = POWER_SUPPLY_STATUS_FULL;
1345 val->intval = status;
1350 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1351 union power_supply_propval *val)
1356 mutex_lock(&bdi->f_reg_lock);
1358 mutex_unlock(&bdi->f_reg_lock);
1360 if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1361 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1363 v &= BQ24190_REG_F_NTC_FAULT_MASK;
1364 v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1367 case 0x0: /* Normal */
1368 health = POWER_SUPPLY_HEALTH_GOOD;
1370 case 0x1: /* TS1 Cold */
1371 case 0x3: /* TS2 Cold */
1372 case 0x5: /* Both Cold */
1373 health = POWER_SUPPLY_HEALTH_COLD;
1375 case 0x2: /* TS1 Hot */
1376 case 0x4: /* TS2 Hot */
1377 case 0x6: /* Both Hot */
1378 health = POWER_SUPPLY_HEALTH_OVERHEAT;
1381 health = POWER_SUPPLY_HEALTH_UNKNOWN;
1385 val->intval = health;
1389 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1390 union power_supply_propval *val)
1395 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1396 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1397 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1401 val->intval = !batfet_disable;
1405 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1406 const union power_supply_propval *val)
1408 return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1409 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1410 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1413 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1414 union power_supply_propval *val)
1418 ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1419 BQ24190_REG_ICTRC_TREG_MASK,
1420 BQ24190_REG_ICTRC_TREG_SHIFT,
1421 bq24190_ictrc_treg_values,
1422 ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1430 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1431 const union power_supply_propval *val)
1433 return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1434 BQ24190_REG_ICTRC_TREG_MASK,
1435 BQ24190_REG_ICTRC_TREG_SHIFT,
1436 bq24190_ictrc_treg_values,
1437 ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1440 static int bq24190_battery_get_property(struct power_supply *psy,
1441 enum power_supply_property psp, union power_supply_propval *val)
1443 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1446 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1447 dev_dbg(bdi->dev, "prop: %d\n", psp);
1449 ret = pm_runtime_get_sync(bdi->dev);
1451 pm_runtime_put_noidle(bdi->dev);
1456 case POWER_SUPPLY_PROP_STATUS:
1457 ret = bq24190_battery_get_status(bdi, val);
1459 case POWER_SUPPLY_PROP_HEALTH:
1460 ret = bq24190_battery_get_health(bdi, val);
1462 case POWER_SUPPLY_PROP_ONLINE:
1463 ret = bq24190_battery_get_online(bdi, val);
1465 case POWER_SUPPLY_PROP_TECHNOLOGY:
1466 /* Could be Li-on or Li-polymer but no way to tell which */
1467 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1470 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1471 ret = bq24190_battery_get_temp_alert_max(bdi, val);
1473 case POWER_SUPPLY_PROP_SCOPE:
1474 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1481 pm_runtime_mark_last_busy(bdi->dev);
1482 pm_runtime_put_autosuspend(bdi->dev);
1487 static int bq24190_battery_set_property(struct power_supply *psy,
1488 enum power_supply_property psp,
1489 const union power_supply_propval *val)
1491 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1494 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1495 dev_dbg(bdi->dev, "prop: %d\n", psp);
1497 ret = pm_runtime_get_sync(bdi->dev);
1499 pm_runtime_put_noidle(bdi->dev);
1504 case POWER_SUPPLY_PROP_ONLINE:
1505 ret = bq24190_battery_set_online(bdi, val);
1507 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1508 ret = bq24190_battery_set_temp_alert_max(bdi, val);
1514 pm_runtime_mark_last_busy(bdi->dev);
1515 pm_runtime_put_autosuspend(bdi->dev);
1520 static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1521 enum power_supply_property psp)
1526 case POWER_SUPPLY_PROP_ONLINE:
1527 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1537 static enum power_supply_property bq24190_battery_properties[] = {
1538 POWER_SUPPLY_PROP_STATUS,
1539 POWER_SUPPLY_PROP_HEALTH,
1540 POWER_SUPPLY_PROP_ONLINE,
1541 POWER_SUPPLY_PROP_TECHNOLOGY,
1542 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1543 POWER_SUPPLY_PROP_SCOPE,
1546 static const struct power_supply_desc bq24190_battery_desc = {
1547 .name = "bq24190-battery",
1548 .type = POWER_SUPPLY_TYPE_BATTERY,
1549 .properties = bq24190_battery_properties,
1550 .num_properties = ARRAY_SIZE(bq24190_battery_properties),
1551 .get_property = bq24190_battery_get_property,
1552 .set_property = bq24190_battery_set_property,
1553 .property_is_writeable = bq24190_battery_property_is_writeable,
1556 static void bq24190_check_status(struct bq24190_dev_info *bdi)
1558 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1559 const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1560 | BQ24190_REG_F_NTC_FAULT_MASK;
1561 bool alert_charger = false, alert_battery = false;
1562 u8 ss_reg = 0, f_reg = 0;
1565 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1567 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1573 ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1575 dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1578 } while (f_reg && ++i < 2);
1580 /* ignore over/under voltage fault after disconnect */
1581 if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1582 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1585 if (f_reg != bdi->f_reg) {
1587 "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1588 !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1589 !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1590 !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1591 !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1593 mutex_lock(&bdi->f_reg_lock);
1594 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1595 alert_battery = true;
1596 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1597 alert_charger = true;
1599 mutex_unlock(&bdi->f_reg_lock);
1602 if (ss_reg != bdi->ss_reg) {
1604 * The device is in host mode so when PG_STAT goes from 1->0
1605 * (i.e., power removed) HIZ needs to be disabled.
1607 if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1608 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1609 ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1610 BQ24190_REG_ISC_EN_HIZ_MASK,
1611 BQ24190_REG_ISC_EN_HIZ_SHIFT,
1614 dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1618 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1619 alert_battery = true;
1620 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1621 alert_charger = true;
1622 bdi->ss_reg = ss_reg;
1625 if (alert_charger || alert_battery)
1626 power_supply_changed(bdi->charger);
1627 if (alert_battery && bdi->battery)
1628 power_supply_changed(bdi->battery);
1630 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1633 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1635 struct bq24190_dev_info *bdi = data;
1638 bdi->irq_event = true;
1639 error = pm_runtime_get_sync(bdi->dev);
1641 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1642 pm_runtime_put_noidle(bdi->dev);
1645 bq24190_check_status(bdi);
1646 pm_runtime_mark_last_busy(bdi->dev);
1647 pm_runtime_put_autosuspend(bdi->dev);
1648 bdi->irq_event = false;
1653 static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1658 /* First check that the device really is what its supposed to be */
1659 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1660 BQ24190_REG_VPRS_PN_MASK,
1661 BQ24190_REG_VPRS_PN_SHIFT,
1666 if (v != BQ24190_REG_VPRS_PN_24190 &&
1667 v != BQ24190_REG_VPRS_PN_24192I) {
1668 dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1672 ret = bq24190_register_reset(bdi);
1676 ret = bq24190_set_config(bdi);
1680 return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1683 static int bq24190_get_config(struct bq24190_dev_info *bdi)
1685 const char * const s = "ti,system-minimum-microvolt";
1686 struct power_supply_battery_info info = {};
1689 if (device_property_read_u32(bdi->dev, s, &v) == 0) {
1691 if (v >= BQ24190_REG_POC_SYS_MIN_MIN
1692 && v <= BQ24190_REG_POC_SYS_MIN_MAX)
1695 dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v);
1698 if (bdi->dev->of_node &&
1699 !power_supply_get_battery_info(bdi->charger, &info)) {
1700 v = info.precharge_current_ua / 1000;
1701 if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
1702 && v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
1705 dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
1708 v = info.charge_term_current_ua / 1000;
1709 if (v >= BQ24190_REG_PCTCC_ITERM_MIN
1710 && v <= BQ24190_REG_PCTCC_ITERM_MAX)
1713 dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n",
1720 static int bq24190_probe(struct i2c_client *client,
1721 const struct i2c_device_id *id)
1723 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1724 struct device *dev = &client->dev;
1725 struct power_supply_config charger_cfg = {}, battery_cfg = {};
1726 struct bq24190_dev_info *bdi;
1729 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1730 dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1734 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1736 dev_err(dev, "Can't alloc bdi struct\n");
1740 bdi->client = client;
1742 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1743 mutex_init(&bdi->f_reg_lock);
1745 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1746 INIT_DELAYED_WORK(&bdi->input_current_limit_work,
1747 bq24190_input_current_limit_work);
1749 i2c_set_clientdata(client, bdi);
1751 if (client->irq <= 0) {
1752 dev_err(dev, "Can't get irq info\n");
1756 pm_runtime_enable(dev);
1757 pm_runtime_use_autosuspend(dev);
1758 pm_runtime_set_autosuspend_delay(dev, 600);
1759 ret = pm_runtime_get_sync(dev);
1761 dev_err(dev, "pm_runtime_get failed: %i\n", ret);
1765 charger_cfg.drv_data = bdi;
1766 charger_cfg.of_node = dev->of_node;
1767 charger_cfg.supplied_to = bq24190_charger_supplied_to;
1768 charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1769 bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1771 if (IS_ERR(bdi->charger)) {
1772 dev_err(dev, "Can't register charger\n");
1773 ret = PTR_ERR(bdi->charger);
1777 /* the battery class is deprecated and will be removed. */
1778 /* in the interim, this property hides it. */
1779 if (!device_property_read_bool(dev, "omit-battery-class")) {
1780 battery_cfg.drv_data = bdi;
1781 bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1783 if (IS_ERR(bdi->battery)) {
1784 dev_err(dev, "Can't register battery\n");
1785 ret = PTR_ERR(bdi->battery);
1790 ret = bq24190_get_config(bdi);
1792 dev_err(dev, "Can't get devicetree config\n");
1796 ret = bq24190_hw_init(bdi);
1798 dev_err(dev, "Hardware init failed\n");
1802 ret = bq24190_sysfs_create_group(bdi);
1804 dev_err(dev, "Can't create sysfs entries\n");
1808 bdi->initialized = true;
1810 ret = devm_request_threaded_irq(dev, client->irq, NULL,
1811 bq24190_irq_handler_thread,
1812 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1813 "bq24190-charger", bdi);
1815 dev_err(dev, "Can't set up irq handler\n");
1819 ret = bq24190_register_vbus_regulator(bdi);
1823 enable_irq_wake(client->irq);
1825 pm_runtime_mark_last_busy(dev);
1826 pm_runtime_put_autosuspend(dev);
1831 bq24190_sysfs_remove_group(bdi);
1834 if (!IS_ERR_OR_NULL(bdi->battery))
1835 power_supply_unregister(bdi->battery);
1836 power_supply_unregister(bdi->charger);
1839 pm_runtime_put_sync(dev);
1840 pm_runtime_dont_use_autosuspend(dev);
1841 pm_runtime_disable(dev);
1845 static int bq24190_remove(struct i2c_client *client)
1847 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1850 error = pm_runtime_get_sync(bdi->dev);
1852 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1853 pm_runtime_put_noidle(bdi->dev);
1856 bq24190_register_reset(bdi);
1857 bq24190_sysfs_remove_group(bdi);
1859 power_supply_unregister(bdi->battery);
1860 power_supply_unregister(bdi->charger);
1862 pm_runtime_put_sync(bdi->dev);
1863 pm_runtime_dont_use_autosuspend(bdi->dev);
1864 pm_runtime_disable(bdi->dev);
1869 static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
1871 struct i2c_client *client = to_i2c_client(dev);
1872 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1874 if (!bdi->initialized)
1877 dev_dbg(bdi->dev, "%s\n", __func__);
1882 static __maybe_unused int bq24190_runtime_resume(struct device *dev)
1884 struct i2c_client *client = to_i2c_client(dev);
1885 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1887 if (!bdi->initialized)
1890 if (!bdi->irq_event) {
1891 dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
1892 bq24190_check_status(bdi);
1898 static __maybe_unused int bq24190_pm_suspend(struct device *dev)
1900 struct i2c_client *client = to_i2c_client(dev);
1901 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1904 error = pm_runtime_get_sync(bdi->dev);
1906 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1907 pm_runtime_put_noidle(bdi->dev);
1910 bq24190_register_reset(bdi);
1913 pm_runtime_mark_last_busy(bdi->dev);
1914 pm_runtime_put_autosuspend(bdi->dev);
1920 static __maybe_unused int bq24190_pm_resume(struct device *dev)
1922 struct i2c_client *client = to_i2c_client(dev);
1923 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1927 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
1929 error = pm_runtime_get_sync(bdi->dev);
1931 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1932 pm_runtime_put_noidle(bdi->dev);
1935 bq24190_register_reset(bdi);
1936 bq24190_set_config(bdi);
1937 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1940 pm_runtime_mark_last_busy(bdi->dev);
1941 pm_runtime_put_autosuspend(bdi->dev);
1944 /* Things may have changed while suspended so alert upper layer */
1945 power_supply_changed(bdi->charger);
1947 power_supply_changed(bdi->battery);
1952 static const struct dev_pm_ops bq24190_pm_ops = {
1953 SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
1955 SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
1958 static const struct i2c_device_id bq24190_i2c_ids[] = {
1963 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1966 static const struct of_device_id bq24190_of_match[] = {
1967 { .compatible = "ti,bq24190", },
1968 { .compatible = "ti,bq24192i", },
1971 MODULE_DEVICE_TABLE(of, bq24190_of_match);
1973 static const struct of_device_id bq24190_of_match[] = {
1978 static struct i2c_driver bq24190_driver = {
1979 .probe = bq24190_probe,
1980 .remove = bq24190_remove,
1981 .id_table = bq24190_i2c_ids,
1983 .name = "bq24190-charger",
1984 .pm = &bq24190_pm_ops,
1985 .of_match_table = of_match_ptr(bq24190_of_match),
1988 module_i2c_driver(bq24190_driver);
1990 MODULE_LICENSE("GPL");
1991 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1992 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");