drm/rockchip: Don't change hdmi reference clock rate
[drm/drm-misc.git] / drivers / power / supply / bq24190_charger.c
blob2b393eb5c2820e18d6244fad53efc6ef689613de
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Driver for the TI bq24190 battery charger.
5 * Author: Mark A. Greer <mgreer@animalcreek.com>
6 */
8 #include <linux/mod_devicetable.h>
9 #include <linux/module.h>
10 #include <linux/interrupt.h>
11 #include <linux/delay.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/power_supply.h>
14 #include <linux/power/bq24190_charger.h>
15 #include <linux/regulator/driver.h>
16 #include <linux/regulator/machine.h>
17 #include <linux/workqueue.h>
18 #include <linux/i2c.h>
19 #include <linux/extcon-provider.h>
21 #define BQ24190_MANUFACTURER "Texas Instruments"
23 #define BQ24190_REG_ISC 0x00 /* Input Source Control */
24 #define BQ24190_REG_ISC_EN_HIZ_MASK BIT(7)
25 #define BQ24190_REG_ISC_EN_HIZ_SHIFT 7
26 #define BQ24190_REG_ISC_VINDPM_MASK (BIT(6) | BIT(5) | BIT(4) | \
27 BIT(3))
28 #define BQ24190_REG_ISC_VINDPM_SHIFT 3
29 #define BQ24190_REG_ISC_IINLIM_MASK (BIT(2) | BIT(1) | BIT(0))
30 #define BQ24190_REG_ISC_IINLIM_SHIFT 0
32 #define BQ24190_REG_POC 0x01 /* Power-On Configuration */
33 #define BQ24190_REG_POC_RESET_MASK BIT(7)
34 #define BQ24190_REG_POC_RESET_SHIFT 7
35 #define BQ24190_REG_POC_WDT_RESET_MASK BIT(6)
36 #define BQ24190_REG_POC_WDT_RESET_SHIFT 6
37 #define BQ24190_REG_POC_CHG_CONFIG_MASK (BIT(5) | BIT(4))
38 #define BQ24190_REG_POC_CHG_CONFIG_SHIFT 4
39 #define BQ24190_REG_POC_CHG_CONFIG_DISABLE 0x0
40 #define BQ24190_REG_POC_CHG_CONFIG_CHARGE 0x1
41 #define BQ24190_REG_POC_CHG_CONFIG_OTG 0x2
42 #define BQ24190_REG_POC_CHG_CONFIG_OTG_ALT 0x3
43 #define BQ24296_REG_POC_OTG_CONFIG_MASK BIT(5)
44 #define BQ24296_REG_POC_OTG_CONFIG_SHIFT 5
45 #define BQ24296_REG_POC_CHG_CONFIG_MASK BIT(4)
46 #define BQ24296_REG_POC_CHG_CONFIG_SHIFT 4
47 #define BQ24296_REG_POC_OTG_CONFIG_DISABLE 0x0
48 #define BQ24296_REG_POC_OTG_CONFIG_OTG 0x1
49 #define BQ24190_REG_POC_SYS_MIN_MASK (BIT(3) | BIT(2) | BIT(1))
50 #define BQ24190_REG_POC_SYS_MIN_SHIFT 1
51 #define BQ24190_REG_POC_SYS_MIN_MIN 3000
52 #define BQ24190_REG_POC_SYS_MIN_MAX 3700
53 #define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0)
54 #define BQ24190_REG_POC_BOOST_LIM_SHIFT 0
56 #define BQ24190_REG_CCC 0x02 /* Charge Current Control */
57 #define BQ24190_REG_CCC_ICHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
58 BIT(4) | BIT(3) | BIT(2))
59 #define BQ24190_REG_CCC_ICHG_SHIFT 2
60 #define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0)
61 #define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0
63 #define BQ24190_REG_PCTCC 0x03 /* Pre-charge/Termination Current Cntl */
64 #define BQ24190_REG_PCTCC_IPRECHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
65 BIT(4))
66 #define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4
67 #define BQ24190_REG_PCTCC_IPRECHG_MIN 128
68 #define BQ24190_REG_PCTCC_IPRECHG_MAX 2048
69 #define BQ24190_REG_PCTCC_ITERM_MASK (BIT(3) | BIT(2) | BIT(1) | \
70 BIT(0))
71 #define BQ24190_REG_PCTCC_ITERM_SHIFT 0
72 #define BQ24190_REG_PCTCC_ITERM_MIN 128
73 #define BQ24190_REG_PCTCC_ITERM_MAX 2048
75 #define BQ24190_REG_CVC 0x04 /* Charge Voltage Control */
76 #define BQ24190_REG_CVC_VREG_MASK (BIT(7) | BIT(6) | BIT(5) | \
77 BIT(4) | BIT(3) | BIT(2))
78 #define BQ24190_REG_CVC_VREG_SHIFT 2
79 #define BQ24190_REG_CVC_BATLOWV_MASK BIT(1)
80 #define BQ24190_REG_CVC_BATLOWV_SHIFT 1
81 #define BQ24190_REG_CVC_VRECHG_MASK BIT(0)
82 #define BQ24190_REG_CVC_VRECHG_SHIFT 0
84 #define BQ24190_REG_CTTC 0x05 /* Charge Term/Timer Control */
85 #define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7)
86 #define BQ24190_REG_CTTC_EN_TERM_SHIFT 7
87 #define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6)
88 #define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6
89 #define BQ24190_REG_CTTC_WATCHDOG_MASK (BIT(5) | BIT(4))
90 #define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4
91 #define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3)
92 #define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3
93 #define BQ24190_REG_CTTC_CHG_TIMER_MASK (BIT(2) | BIT(1))
94 #define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1
95 #define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0)
96 #define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0
98 #define BQ24190_REG_ICTRC 0x06 /* IR Comp/Thermal Regulation Control */
99 #define BQ24190_REG_ICTRC_BAT_COMP_MASK (BIT(7) | BIT(6) | BIT(5))
100 #define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5
101 #define BQ24190_REG_ICTRC_VCLAMP_MASK (BIT(4) | BIT(3) | BIT(2))
102 #define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2
103 #define BQ24190_REG_ICTRC_TREG_MASK (BIT(1) | BIT(0))
104 #define BQ24190_REG_ICTRC_TREG_SHIFT 0
106 #define BQ24190_REG_MOC 0x07 /* Misc. Operation Control */
107 #define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7)
108 #define BQ24190_REG_MOC_DPDM_EN_SHIFT 7
109 #define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6)
110 #define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6
111 #define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5)
112 #define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5
113 #define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4)
114 #define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4
115 #define BQ24190_REG_MOC_INT_MASK_MASK (BIT(1) | BIT(0))
116 #define BQ24190_REG_MOC_INT_MASK_SHIFT 0
118 #define BQ24190_REG_SS 0x08 /* System Status */
119 #define BQ24190_REG_SS_VBUS_STAT_MASK (BIT(7) | BIT(6))
120 #define BQ24190_REG_SS_VBUS_STAT_SHIFT 6
121 #define BQ24190_REG_SS_CHRG_STAT_MASK (BIT(5) | BIT(4))
122 #define BQ24190_REG_SS_CHRG_STAT_SHIFT 4
123 #define BQ24190_REG_SS_DPM_STAT_MASK BIT(3)
124 #define BQ24190_REG_SS_DPM_STAT_SHIFT 3
125 #define BQ24190_REG_SS_PG_STAT_MASK BIT(2)
126 #define BQ24190_REG_SS_PG_STAT_SHIFT 2
127 #define BQ24190_REG_SS_THERM_STAT_MASK BIT(1)
128 #define BQ24190_REG_SS_THERM_STAT_SHIFT 1
129 #define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0)
130 #define BQ24190_REG_SS_VSYS_STAT_SHIFT 0
132 #define BQ24190_REG_F 0x09 /* Fault */
133 #define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7)
134 #define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7
135 #define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6)
136 #define BQ24190_REG_F_BOOST_FAULT_SHIFT 6
137 #define BQ24190_REG_F_CHRG_FAULT_MASK (BIT(5) | BIT(4))
138 #define BQ24190_REG_F_CHRG_FAULT_SHIFT 4
139 #define BQ24190_REG_F_BAT_FAULT_MASK BIT(3)
140 #define BQ24190_REG_F_BAT_FAULT_SHIFT 3
141 #define BQ24190_REG_F_NTC_FAULT_MASK (BIT(2) | BIT(1) | BIT(0))
142 #define BQ24190_REG_F_NTC_FAULT_SHIFT 0
143 #define BQ24296_REG_F_NTC_FAULT_MASK (BIT(1) | BIT(0))
144 #define BQ24296_REG_F_NTC_FAULT_SHIFT 0
146 #define BQ24190_REG_VPRS 0x0A /* Vendor/Part/Revision Status */
147 #define BQ24190_REG_VPRS_PN_MASK (BIT(5) | BIT(4) | BIT(3))
148 #define BQ24190_REG_VPRS_PN_SHIFT 3
149 #define BQ24190_REG_VPRS_PN_24190 0x4
150 #define BQ24190_REG_VPRS_PN_24192 0x5 /* Also 24193, 24196 */
151 #define BQ24190_REG_VPRS_PN_24192I 0x3
152 #define BQ24296_REG_VPRS_PN_MASK (BIT(7) | BIT(6) | BIT(5))
153 #define BQ24296_REG_VPRS_PN_SHIFT 5
154 #define BQ24296_REG_VPRS_PN_24296 0x1
155 #define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2)
156 #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2
157 #define BQ24190_REG_VPRS_DEV_REG_MASK (BIT(1) | BIT(0))
158 #define BQ24190_REG_VPRS_DEV_REG_SHIFT 0
161 * The tables below provide a 2-way mapping for the value that goes in
162 * the register field and the real-world value that it represents.
163 * The index of the array is the value that goes in the register; the
164 * number at that index in the array is the real-world value that it
165 * represents.
168 /* REG00[2:0] (IINLIM) in uAh */
169 static const int bq24190_isc_iinlim_values[] = {
170 100000, 150000, 500000, 900000, 1200000, 1500000, 2000000, 3000000
173 /* REG02[7:2] (ICHG) in uAh */
174 static const int bq24190_ccc_ichg_values[] = {
175 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
176 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
177 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
178 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
179 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
180 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
181 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
182 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
185 /* ICHG higher than 3008mA is not supported in BQ24296 */
186 #define BQ24296_CCC_ICHG_VALUES_LEN 40
188 /* REG04[7:2] (VREG) in uV */
189 static const int bq24190_cvc_vreg_values[] = {
190 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
191 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
192 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
193 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
194 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
195 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
196 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
197 4400000
200 /* REG06[1:0] (TREG) in tenths of degrees Celsius */
201 static const int bq24190_ictrc_treg_values[] = {
202 600, 800, 1000, 1200
205 enum bq24190_chip {
206 BQ24190,
207 BQ24192,
208 BQ24192i,
209 BQ24196,
210 BQ24296,
214 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
215 * so the first read after a fault returns the latched value and subsequent
216 * reads return the current value. In order to return the fault status
217 * to the user, have the interrupt handler save the reg's value and retrieve
218 * it in the appropriate health/status routine.
220 struct bq24190_dev_info {
221 struct i2c_client *client;
222 struct device *dev;
223 struct extcon_dev *edev;
224 struct power_supply *charger;
225 struct power_supply *battery;
226 struct delayed_work input_current_limit_work;
227 char model_name[I2C_NAME_SIZE];
228 bool initialized;
229 bool irq_event;
230 bool otg_vbus_enabled;
231 int charge_type;
232 u16 sys_min;
233 u16 iprechg;
234 u16 iterm;
235 u32 ichg;
236 u32 ichg_max;
237 u32 vreg;
238 u32 vreg_max;
239 struct mutex f_reg_lock;
240 u8 f_reg;
241 u8 ss_reg;
242 u8 watchdog;
243 const struct bq24190_chip_info *info;
246 struct bq24190_chip_info {
247 int ichg_array_size;
248 #ifdef CONFIG_REGULATOR
249 const struct regulator_desc *vbus_desc;
250 #endif
251 int (*check_chip)(struct bq24190_dev_info *bdi);
252 int (*set_chg_config)(struct bq24190_dev_info *bdi, const u8 chg_config);
253 int (*set_otg_vbus)(struct bq24190_dev_info *bdi, bool enable);
254 u8 ntc_fault_mask;
255 int (*get_ntc_status)(const u8 value);
258 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
259 const union power_supply_propval *val);
261 static const unsigned int bq24190_usb_extcon_cable[] = {
262 EXTCON_USB,
263 EXTCON_NONE,
268 * Return the index in 'tbl' of greatest value that is less than or equal to
269 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
270 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
271 * is less than 2^8.
273 static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
275 int i;
277 for (i = 1; i < tbl_size; i++)
278 if (v < tbl[i])
279 break;
281 return i - 1;
284 /* Basic driver I/O routines */
286 static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
288 int ret;
290 ret = i2c_smbus_read_byte_data(bdi->client, reg);
291 if (ret < 0)
292 return ret;
294 *data = ret;
295 return 0;
298 static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
300 return i2c_smbus_write_byte_data(bdi->client, reg, data);
303 static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
304 u8 mask, u8 shift, u8 *data)
306 u8 v;
307 int ret;
309 ret = bq24190_read(bdi, reg, &v);
310 if (ret < 0)
311 return ret;
313 v &= mask;
314 v >>= shift;
315 *data = v;
317 return 0;
320 static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
321 u8 mask, u8 shift, u8 data)
323 u8 v;
324 int ret;
326 ret = bq24190_read(bdi, reg, &v);
327 if (ret < 0)
328 return ret;
330 v &= ~mask;
331 v |= ((data << shift) & mask);
333 return bq24190_write(bdi, reg, v);
336 static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
337 u8 reg, u8 mask, u8 shift,
338 const int tbl[], int tbl_size,
339 int *val)
341 u8 v;
342 int ret;
344 ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
345 if (ret < 0)
346 return ret;
348 v = (v >= tbl_size) ? (tbl_size - 1) : v;
349 *val = tbl[v];
351 return 0;
354 static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
355 u8 reg, u8 mask, u8 shift,
356 const int tbl[], int tbl_size,
357 int val)
359 u8 idx;
361 idx = bq24190_find_idx(tbl, tbl_size, val);
363 return bq24190_write_mask(bdi, reg, mask, shift, idx);
366 #ifdef CONFIG_SYSFS
368 * There are a numerous options that are configurable on the bq24190
369 * that go well beyond what the power_supply properties provide access to.
370 * Provide sysfs access to them so they can be examined and possibly modified
371 * on the fly. They will be provided for the charger power_supply object only
372 * and will be prefixed by 'f_' to make them easier to recognize.
375 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
377 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
378 .reg = BQ24190_REG_##r, \
379 .mask = BQ24190_REG_##r##_##f##_MASK, \
380 .shift = BQ24190_REG_##r##_##f##_SHIFT, \
383 #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
384 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
385 bq24190_sysfs_store)
387 #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
388 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
390 static ssize_t bq24190_sysfs_show(struct device *dev,
391 struct device_attribute *attr, char *buf);
392 static ssize_t bq24190_sysfs_store(struct device *dev,
393 struct device_attribute *attr, const char *buf, size_t count);
395 struct bq24190_sysfs_field_info {
396 struct device_attribute attr;
397 u8 reg;
398 u8 mask;
399 u8 shift;
402 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
403 #undef SS
405 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
406 /* sysfs name reg field in reg */
407 BQ24190_SYSFS_FIELD_RW(en_hiz, ISC, EN_HIZ),
408 BQ24190_SYSFS_FIELD_RW(vindpm, ISC, VINDPM),
409 BQ24190_SYSFS_FIELD_RW(iinlim, ISC, IINLIM),
410 BQ24190_SYSFS_FIELD_RW(chg_config, POC, CHG_CONFIG),
411 BQ24190_SYSFS_FIELD_RW(sys_min, POC, SYS_MIN),
412 BQ24190_SYSFS_FIELD_RW(boost_lim, POC, BOOST_LIM),
413 BQ24190_SYSFS_FIELD_RW(ichg, CCC, ICHG),
414 BQ24190_SYSFS_FIELD_RW(force_20_pct, CCC, FORCE_20PCT),
415 BQ24190_SYSFS_FIELD_RW(iprechg, PCTCC, IPRECHG),
416 BQ24190_SYSFS_FIELD_RW(iterm, PCTCC, ITERM),
417 BQ24190_SYSFS_FIELD_RW(vreg, CVC, VREG),
418 BQ24190_SYSFS_FIELD_RW(batlowv, CVC, BATLOWV),
419 BQ24190_SYSFS_FIELD_RW(vrechg, CVC, VRECHG),
420 BQ24190_SYSFS_FIELD_RW(en_term, CTTC, EN_TERM),
421 BQ24190_SYSFS_FIELD_RW(term_stat, CTTC, TERM_STAT),
422 BQ24190_SYSFS_FIELD_RO(watchdog, CTTC, WATCHDOG),
423 BQ24190_SYSFS_FIELD_RW(en_timer, CTTC, EN_TIMER),
424 BQ24190_SYSFS_FIELD_RW(chg_timer, CTTC, CHG_TIMER),
425 BQ24190_SYSFS_FIELD_RW(jeta_iset, CTTC, JEITA_ISET),
426 BQ24190_SYSFS_FIELD_RW(bat_comp, ICTRC, BAT_COMP),
427 BQ24190_SYSFS_FIELD_RW(vclamp, ICTRC, VCLAMP),
428 BQ24190_SYSFS_FIELD_RW(treg, ICTRC, TREG),
429 BQ24190_SYSFS_FIELD_RW(dpdm_en, MOC, DPDM_EN),
430 BQ24190_SYSFS_FIELD_RW(tmr2x_en, MOC, TMR2X_EN),
431 BQ24190_SYSFS_FIELD_RW(batfet_disable, MOC, BATFET_DISABLE),
432 BQ24190_SYSFS_FIELD_RW(jeita_vset, MOC, JEITA_VSET),
433 BQ24190_SYSFS_FIELD_RO(int_mask, MOC, INT_MASK),
434 BQ24190_SYSFS_FIELD_RO(vbus_stat, SS, VBUS_STAT),
435 BQ24190_SYSFS_FIELD_RO(chrg_stat, SS, CHRG_STAT),
436 BQ24190_SYSFS_FIELD_RO(dpm_stat, SS, DPM_STAT),
437 BQ24190_SYSFS_FIELD_RO(pg_stat, SS, PG_STAT),
438 BQ24190_SYSFS_FIELD_RO(therm_stat, SS, THERM_STAT),
439 BQ24190_SYSFS_FIELD_RO(vsys_stat, SS, VSYS_STAT),
440 BQ24190_SYSFS_FIELD_RO(watchdog_fault, F, WATCHDOG_FAULT),
441 BQ24190_SYSFS_FIELD_RO(boost_fault, F, BOOST_FAULT),
442 BQ24190_SYSFS_FIELD_RO(chrg_fault, F, CHRG_FAULT),
443 BQ24190_SYSFS_FIELD_RO(bat_fault, F, BAT_FAULT),
444 BQ24190_SYSFS_FIELD_RO(ntc_fault, F, NTC_FAULT),
445 BQ24190_SYSFS_FIELD_RO(pn, VPRS, PN),
446 BQ24190_SYSFS_FIELD_RO(ts_profile, VPRS, TS_PROFILE),
447 BQ24190_SYSFS_FIELD_RO(dev_reg, VPRS, DEV_REG),
450 static struct attribute *
451 bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
453 ATTRIBUTE_GROUPS(bq24190_sysfs);
455 static void bq24190_sysfs_init_attrs(void)
457 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
459 for (i = 0; i < limit; i++)
460 bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
462 bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
465 static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
466 const char *name)
468 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
470 for (i = 0; i < limit; i++)
471 if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
472 break;
474 if (i >= limit)
475 return NULL;
477 return &bq24190_sysfs_field_tbl[i];
480 static ssize_t bq24190_sysfs_show(struct device *dev,
481 struct device_attribute *attr, char *buf)
483 struct power_supply *psy = dev_get_drvdata(dev);
484 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
485 struct bq24190_sysfs_field_info *info;
486 ssize_t count;
487 int ret;
488 u8 v;
490 info = bq24190_sysfs_field_lookup(attr->attr.name);
491 if (!info)
492 return -EINVAL;
494 ret = pm_runtime_resume_and_get(bdi->dev);
495 if (ret < 0)
496 return ret;
498 ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
499 if (ret)
500 count = ret;
501 else
502 count = sysfs_emit(buf, "%hhx\n", v);
504 pm_runtime_mark_last_busy(bdi->dev);
505 pm_runtime_put_autosuspend(bdi->dev);
507 return count;
510 static ssize_t bq24190_sysfs_store(struct device *dev,
511 struct device_attribute *attr, const char *buf, size_t count)
513 struct power_supply *psy = dev_get_drvdata(dev);
514 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
515 struct bq24190_sysfs_field_info *info;
516 int ret;
517 u8 v;
519 info = bq24190_sysfs_field_lookup(attr->attr.name);
520 if (!info)
521 return -EINVAL;
523 ret = kstrtou8(buf, 0, &v);
524 if (ret < 0)
525 return ret;
527 ret = pm_runtime_resume_and_get(bdi->dev);
528 if (ret < 0)
529 return ret;
531 ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
532 if (ret)
533 count = ret;
535 pm_runtime_mark_last_busy(bdi->dev);
536 pm_runtime_put_autosuspend(bdi->dev);
538 return count;
540 #endif
542 static int bq24190_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
544 union power_supply_propval val = { .intval = bdi->charge_type };
545 int ret;
547 ret = pm_runtime_resume_and_get(bdi->dev);
548 if (ret < 0) {
549 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
550 return ret;
553 bdi->otg_vbus_enabled = enable;
554 if (enable)
555 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
556 BQ24190_REG_POC_CHG_CONFIG_MASK,
557 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
558 BQ24190_REG_POC_CHG_CONFIG_OTG);
559 else
560 ret = bq24190_charger_set_charge_type(bdi, &val);
562 pm_runtime_mark_last_busy(bdi->dev);
563 pm_runtime_put_autosuspend(bdi->dev);
565 return ret;
568 static int bq24296_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
570 int ret;
572 ret = pm_runtime_resume_and_get(bdi->dev);
573 if (ret < 0) {
574 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
575 return ret;
578 bdi->otg_vbus_enabled = enable;
579 if (enable) {
580 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
581 BQ24296_REG_POC_CHG_CONFIG_MASK,
582 BQ24296_REG_POC_CHG_CONFIG_SHIFT,
583 BQ24190_REG_POC_CHG_CONFIG_DISABLE);
585 if (ret < 0)
586 goto out;
588 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
589 BQ24296_REG_POC_OTG_CONFIG_MASK,
590 BQ24296_REG_POC_CHG_CONFIG_SHIFT,
591 BQ24296_REG_POC_OTG_CONFIG_OTG);
592 } else
593 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
594 BQ24296_REG_POC_OTG_CONFIG_MASK,
595 BQ24296_REG_POC_CHG_CONFIG_SHIFT,
596 BQ24296_REG_POC_OTG_CONFIG_DISABLE);
598 out:
599 pm_runtime_mark_last_busy(bdi->dev);
600 pm_runtime_put_autosuspend(bdi->dev);
602 return ret;
605 #ifdef CONFIG_REGULATOR
606 static int bq24190_vbus_enable(struct regulator_dev *dev)
608 return bq24190_set_otg_vbus(rdev_get_drvdata(dev), true);
611 static int bq24190_vbus_disable(struct regulator_dev *dev)
613 return bq24190_set_otg_vbus(rdev_get_drvdata(dev), false);
616 static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
618 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
619 int ret;
620 u8 val;
622 ret = pm_runtime_resume_and_get(bdi->dev);
623 if (ret < 0) {
624 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
625 return ret;
628 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
629 BQ24190_REG_POC_CHG_CONFIG_MASK,
630 BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
632 pm_runtime_mark_last_busy(bdi->dev);
633 pm_runtime_put_autosuspend(bdi->dev);
635 if (ret)
636 return ret;
638 bdi->otg_vbus_enabled = (val == BQ24190_REG_POC_CHG_CONFIG_OTG ||
639 val == BQ24190_REG_POC_CHG_CONFIG_OTG_ALT);
640 return bdi->otg_vbus_enabled;
643 static int bq24296_vbus_enable(struct regulator_dev *dev)
645 return bq24296_set_otg_vbus(rdev_get_drvdata(dev), true);
648 static int bq24296_vbus_disable(struct regulator_dev *dev)
650 return bq24296_set_otg_vbus(rdev_get_drvdata(dev), false);
653 static int bq24296_vbus_is_enabled(struct regulator_dev *dev)
655 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
656 int ret;
657 u8 val;
659 ret = pm_runtime_resume_and_get(bdi->dev);
660 if (ret < 0) {
661 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
662 return ret;
665 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
666 BQ24296_REG_POC_OTG_CONFIG_MASK,
667 BQ24296_REG_POC_OTG_CONFIG_SHIFT, &val);
669 pm_runtime_mark_last_busy(bdi->dev);
670 pm_runtime_put_autosuspend(bdi->dev);
672 if (ret)
673 return ret;
675 bdi->otg_vbus_enabled = (val == BQ24296_REG_POC_OTG_CONFIG_OTG);
677 return bdi->otg_vbus_enabled;
680 static const struct regulator_ops bq24190_vbus_ops = {
681 .enable = bq24190_vbus_enable,
682 .disable = bq24190_vbus_disable,
683 .is_enabled = bq24190_vbus_is_enabled,
686 static const struct regulator_desc bq24190_vbus_desc = {
687 .name = "usb_otg_vbus",
688 .of_match = "usb-otg-vbus",
689 .type = REGULATOR_VOLTAGE,
690 .owner = THIS_MODULE,
691 .ops = &bq24190_vbus_ops,
692 .fixed_uV = 5000000,
693 .n_voltages = 1,
696 static const struct regulator_ops bq24296_vbus_ops = {
697 .enable = bq24296_vbus_enable,
698 .disable = bq24296_vbus_disable,
699 .is_enabled = bq24296_vbus_is_enabled,
702 static const struct regulator_desc bq24296_vbus_desc = {
703 .name = "usb_otg_vbus",
704 .of_match = "usb-otg-vbus",
705 .type = REGULATOR_VOLTAGE,
706 .owner = THIS_MODULE,
707 .ops = &bq24296_vbus_ops,
708 .fixed_uV = 5000000,
709 .n_voltages = 1,
712 static const struct regulator_init_data bq24190_vbus_init_data = {
713 .constraints = {
714 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
718 static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
720 struct bq24190_platform_data *pdata = bdi->dev->platform_data;
721 struct regulator_config cfg = { };
722 struct regulator_dev *reg;
723 int ret = 0;
725 cfg.dev = bdi->dev;
726 if (pdata && pdata->regulator_init_data)
727 cfg.init_data = pdata->regulator_init_data;
728 else
729 cfg.init_data = &bq24190_vbus_init_data;
730 cfg.driver_data = bdi;
731 reg = devm_regulator_register(bdi->dev, bdi->info->vbus_desc, &cfg);
732 if (IS_ERR(reg)) {
733 ret = PTR_ERR(reg);
734 dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
737 return ret;
739 #else
740 static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
742 return 0;
744 #endif
746 static int bq24190_set_config(struct bq24190_dev_info *bdi)
748 int ret;
749 u8 v;
751 ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
752 if (ret < 0)
753 return ret;
755 bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
756 BQ24190_REG_CTTC_WATCHDOG_SHIFT);
759 * According to the "Host Mode and default Mode" section of the
760 * manual, a write to any register causes the bq24190 to switch
761 * from default mode to host mode. It will switch back to default
762 * mode after a WDT timeout unless the WDT is turned off as well.
763 * So, by simply turning off the WDT, we accomplish both with the
764 * same write.
766 v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
768 ret = bq24190_write(bdi, BQ24190_REG_CTTC, v);
769 if (ret < 0)
770 return ret;
772 if (bdi->sys_min) {
773 v = bdi->sys_min / 100 - 30; // manual section 9.5.1.2, table 9
774 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
775 BQ24190_REG_POC_SYS_MIN_MASK,
776 BQ24190_REG_POC_SYS_MIN_SHIFT,
778 if (ret < 0)
779 return ret;
782 if (bdi->iprechg) {
783 v = bdi->iprechg / 128 - 1; // manual section 9.5.1.4, table 11
784 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
785 BQ24190_REG_PCTCC_IPRECHG_MASK,
786 BQ24190_REG_PCTCC_IPRECHG_SHIFT,
788 if (ret < 0)
789 return ret;
792 if (bdi->iterm) {
793 v = bdi->iterm / 128 - 1; // manual section 9.5.1.4, table 11
794 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
795 BQ24190_REG_PCTCC_ITERM_MASK,
796 BQ24190_REG_PCTCC_ITERM_SHIFT,
798 if (ret < 0)
799 return ret;
802 if (bdi->ichg) {
803 ret = bq24190_set_field_val(bdi, BQ24190_REG_CCC,
804 BQ24190_REG_CCC_ICHG_MASK,
805 BQ24190_REG_CCC_ICHG_SHIFT,
806 bq24190_ccc_ichg_values,
807 bdi->info->ichg_array_size,
808 bdi->ichg);
809 if (ret < 0)
810 return ret;
813 if (bdi->vreg) {
814 ret = bq24190_set_field_val(bdi, BQ24190_REG_CVC,
815 BQ24190_REG_CVC_VREG_MASK,
816 BQ24190_REG_CVC_VREG_SHIFT,
817 bq24190_cvc_vreg_values,
818 ARRAY_SIZE(bq24190_cvc_vreg_values),
819 bdi->vreg);
820 if (ret < 0)
821 return ret;
824 return 0;
827 static int bq24190_register_reset(struct bq24190_dev_info *bdi)
829 int ret, limit = 100;
830 u8 v;
833 * This prop. can be passed on device instantiation from platform code:
834 * struct property_entry pe[] =
835 * { PROPERTY_ENTRY_BOOL("disable-reset"), ... };
836 * struct i2c_board_info bi =
837 * { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
838 * struct i2c_adapter ad = { ... };
839 * i2c_add_adapter(&ad);
840 * i2c_new_client_device(&ad, &bi);
842 if (device_property_read_bool(bdi->dev, "disable-reset"))
843 return 0;
845 /* Reset the registers */
846 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
847 BQ24190_REG_POC_RESET_MASK,
848 BQ24190_REG_POC_RESET_SHIFT,
849 0x1);
850 if (ret < 0)
851 return ret;
853 /* Reset bit will be cleared by hardware so poll until it is */
854 do {
855 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
856 BQ24190_REG_POC_RESET_MASK,
857 BQ24190_REG_POC_RESET_SHIFT,
858 &v);
859 if (ret < 0)
860 return ret;
862 if (v == 0)
863 return 0;
865 usleep_range(100, 200);
866 } while (--limit);
868 return -EIO;
871 /* Charger power supply property routines */
873 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
874 union power_supply_propval *val)
876 u8 v;
877 int type, ret;
879 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
880 BQ24190_REG_POC_CHG_CONFIG_MASK,
881 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
882 &v);
883 if (ret < 0)
884 return ret;
886 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
887 if (!v) {
888 type = POWER_SUPPLY_CHARGE_TYPE_NONE;
889 } else {
890 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
891 BQ24190_REG_CCC_FORCE_20PCT_MASK,
892 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
893 &v);
894 if (ret < 0)
895 return ret;
897 type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
898 POWER_SUPPLY_CHARGE_TYPE_FAST;
901 val->intval = type;
903 return 0;
906 static int bq24190_battery_set_chg_config(struct bq24190_dev_info *bdi,
907 const u8 chg_config)
909 return bq24190_write_mask(bdi, BQ24190_REG_POC,
910 BQ24190_REG_POC_CHG_CONFIG_MASK,
911 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
912 chg_config);
915 static int bq24296_battery_set_chg_config(struct bq24190_dev_info *bdi,
916 const u8 chg_config)
918 return bq24190_write_mask(bdi, BQ24190_REG_POC,
919 BQ24296_REG_POC_CHG_CONFIG_MASK,
920 BQ24296_REG_POC_CHG_CONFIG_SHIFT,
921 chg_config);
924 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
925 const union power_supply_propval *val)
927 u8 chg_config, force_20pct, en_term;
928 int ret;
931 * According to the "Termination when REG02[0] = 1" section of
932 * the bq24190 manual, the trickle charge could be less than the
933 * termination current so it recommends turning off the termination
934 * function.
936 * Note: AFAICT from the datasheet, the user will have to manually
937 * turn off the charging when in 20% mode. If its not turned off,
938 * there could be battery damage. So, use this mode at your own risk.
940 switch (val->intval) {
941 case POWER_SUPPLY_CHARGE_TYPE_NONE:
942 chg_config = 0x0;
943 break;
944 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
945 chg_config = 0x1;
946 force_20pct = 0x1;
947 en_term = 0x0;
948 break;
949 case POWER_SUPPLY_CHARGE_TYPE_FAST:
950 chg_config = 0x1;
951 force_20pct = 0x0;
952 en_term = 0x1;
953 break;
954 default:
955 return -EINVAL;
958 bdi->charge_type = val->intval;
960 * If the 5V Vbus boost regulator is enabled delay setting
961 * the charge-type until its gets disabled.
963 if (bdi->otg_vbus_enabled)
964 return 0;
966 if (chg_config) { /* Enabling the charger */
967 ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
968 BQ24190_REG_CCC_FORCE_20PCT_MASK,
969 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
970 force_20pct);
971 if (ret < 0)
972 return ret;
974 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
975 BQ24190_REG_CTTC_EN_TERM_MASK,
976 BQ24190_REG_CTTC_EN_TERM_SHIFT,
977 en_term);
978 if (ret < 0)
979 return ret;
982 return bdi->info->set_chg_config(bdi, chg_config);
985 static int bq24190_charger_get_ntc_status(u8 value)
987 int health;
989 switch (value >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
990 case 0x1: /* TS1 Cold */
991 case 0x3: /* TS2 Cold */
992 case 0x5: /* Both Cold */
993 health = POWER_SUPPLY_HEALTH_COLD;
994 break;
995 case 0x2: /* TS1 Hot */
996 case 0x4: /* TS2 Hot */
997 case 0x6: /* Both Hot */
998 health = POWER_SUPPLY_HEALTH_OVERHEAT;
999 break;
1000 default:
1001 health = POWER_SUPPLY_HEALTH_UNKNOWN;
1004 return health;
1007 static int bq24296_charger_get_ntc_status(u8 value)
1009 int health;
1011 switch (value >> BQ24296_REG_F_NTC_FAULT_SHIFT & 0x3) {
1012 case 0x0: /* Normal */
1013 health = POWER_SUPPLY_HEALTH_GOOD;
1014 break;
1015 case 0x1: /* Hot */
1016 health = POWER_SUPPLY_HEALTH_OVERHEAT;
1017 break;
1018 case 0x2: /* Cold */
1019 health = POWER_SUPPLY_HEALTH_COLD;
1020 break;
1021 default:
1022 health = POWER_SUPPLY_HEALTH_UNKNOWN;
1025 return health;
1028 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
1029 union power_supply_propval *val)
1031 u8 v;
1032 int health;
1034 mutex_lock(&bdi->f_reg_lock);
1035 v = bdi->f_reg;
1036 mutex_unlock(&bdi->f_reg_lock);
1038 if (v & bdi->info->ntc_fault_mask) {
1039 health = bdi->info->get_ntc_status(v);
1040 } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1041 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1042 } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
1043 switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
1044 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
1046 * This could be over-voltage or under-voltage
1047 * and there's no way to tell which. Instead
1048 * of looking foolish and returning 'OVERVOLTAGE'
1049 * when its really under-voltage, just return
1050 * 'UNSPEC_FAILURE'.
1052 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
1053 break;
1054 case 0x2: /* Thermal Shutdown */
1055 health = POWER_SUPPLY_HEALTH_OVERHEAT;
1056 break;
1057 case 0x3: /* Charge Safety Timer Expiration */
1058 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
1059 break;
1060 default: /* prevent compiler warning */
1061 health = -1;
1063 } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
1065 * This could be over-current or over-voltage but there's
1066 * no way to tell which. Return 'OVERVOLTAGE' since there
1067 * isn't an 'OVERCURRENT' value defined that we can return
1068 * even if it was over-current.
1070 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1071 } else {
1072 health = POWER_SUPPLY_HEALTH_GOOD;
1075 val->intval = health;
1077 return 0;
1080 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
1081 union power_supply_propval *val)
1083 u8 pg_stat, batfet_disable;
1084 int ret;
1086 ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
1087 BQ24190_REG_SS_PG_STAT_MASK,
1088 BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
1089 if (ret < 0)
1090 return ret;
1092 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1093 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1094 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1095 if (ret < 0)
1096 return ret;
1098 val->intval = pg_stat && !batfet_disable;
1100 return 0;
1103 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1104 const union power_supply_propval *val);
1105 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1106 union power_supply_propval *val);
1107 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1108 union power_supply_propval *val);
1109 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1110 const union power_supply_propval *val);
1112 static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
1113 const union power_supply_propval *val)
1115 return bq24190_battery_set_online(bdi, val);
1118 static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
1119 union power_supply_propval *val)
1121 return bq24190_battery_get_status(bdi, val);
1124 static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
1125 union power_supply_propval *val)
1127 return bq24190_battery_get_temp_alert_max(bdi, val);
1130 static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
1131 const union power_supply_propval *val)
1133 return bq24190_battery_set_temp_alert_max(bdi, val);
1136 static int bq24190_charger_get_precharge(struct bq24190_dev_info *bdi,
1137 union power_supply_propval *val)
1139 u8 v;
1140 int curr, ret;
1142 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
1143 BQ24190_REG_PCTCC_IPRECHG_MASK,
1144 BQ24190_REG_PCTCC_IPRECHG_SHIFT, &v);
1145 if (ret < 0)
1146 return ret;
1148 curr = ++v * 128 * 1000;
1150 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1151 BQ24190_REG_CCC_FORCE_20PCT_MASK,
1152 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1153 if (ret < 0)
1154 return ret;
1156 /* If FORCE_20PCT is enabled, then current is 50% of IPRECHG value */
1157 if (v)
1158 curr /= 2;
1160 val->intval = curr;
1162 return 0;
1165 static int bq24190_charger_get_charge_term(struct bq24190_dev_info *bdi,
1166 union power_supply_propval *val)
1168 u8 v;
1169 int ret;
1171 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
1172 BQ24190_REG_PCTCC_ITERM_MASK,
1173 BQ24190_REG_PCTCC_ITERM_SHIFT, &v);
1174 if (ret < 0)
1175 return ret;
1177 val->intval = ++v * 128 * 1000;
1178 return 0;
1181 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
1182 union power_supply_propval *val)
1184 u8 v;
1185 int curr, ret;
1187 ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
1188 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1189 bq24190_ccc_ichg_values,
1190 bdi->info->ichg_array_size, &curr);
1191 if (ret < 0)
1192 return ret;
1194 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1195 BQ24190_REG_CCC_FORCE_20PCT_MASK,
1196 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1197 if (ret < 0)
1198 return ret;
1200 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
1201 if (v)
1202 curr /= 5;
1204 val->intval = curr;
1205 return 0;
1208 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
1209 const union power_supply_propval *val)
1211 u8 v;
1212 int ret, curr = val->intval;
1214 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1215 BQ24190_REG_CCC_FORCE_20PCT_MASK,
1216 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1217 if (ret < 0)
1218 return ret;
1220 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
1221 if (v)
1222 curr *= 5;
1224 if (curr > bdi->ichg_max)
1225 return -EINVAL;
1227 ret = bq24190_set_field_val(bdi, BQ24190_REG_CCC,
1228 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1229 bq24190_ccc_ichg_values,
1230 bdi->info->ichg_array_size, curr);
1231 if (ret < 0)
1232 return ret;
1234 bdi->ichg = curr;
1236 return 0;
1239 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
1240 union power_supply_propval *val)
1242 int voltage, ret;
1244 ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
1245 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1246 bq24190_cvc_vreg_values,
1247 ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
1248 if (ret < 0)
1249 return ret;
1251 val->intval = voltage;
1252 return 0;
1255 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
1256 const union power_supply_propval *val)
1258 int ret;
1260 if (val->intval > bdi->vreg_max)
1261 return -EINVAL;
1263 ret = bq24190_set_field_val(bdi, BQ24190_REG_CVC,
1264 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1265 bq24190_cvc_vreg_values,
1266 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
1267 if (ret < 0)
1268 return ret;
1270 bdi->vreg = val->intval;
1272 return 0;
1275 static int bq24190_charger_get_iinlimit(struct bq24190_dev_info *bdi,
1276 union power_supply_propval *val)
1278 int iinlimit, ret;
1280 ret = bq24190_get_field_val(bdi, BQ24190_REG_ISC,
1281 BQ24190_REG_ISC_IINLIM_MASK,
1282 BQ24190_REG_ISC_IINLIM_SHIFT,
1283 bq24190_isc_iinlim_values,
1284 ARRAY_SIZE(bq24190_isc_iinlim_values), &iinlimit);
1285 if (ret < 0)
1286 return ret;
1288 val->intval = iinlimit;
1289 return 0;
1292 static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi,
1293 const union power_supply_propval *val)
1295 return bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1296 BQ24190_REG_ISC_IINLIM_MASK,
1297 BQ24190_REG_ISC_IINLIM_SHIFT,
1298 bq24190_isc_iinlim_values,
1299 ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval);
1302 static int bq24190_charger_get_property(struct power_supply *psy,
1303 enum power_supply_property psp, union power_supply_propval *val)
1305 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1306 int ret;
1308 dev_dbg(bdi->dev, "prop: %d\n", psp);
1310 ret = pm_runtime_resume_and_get(bdi->dev);
1311 if (ret < 0)
1312 return ret;
1314 switch (psp) {
1315 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1316 ret = bq24190_charger_get_charge_type(bdi, val);
1317 break;
1318 case POWER_SUPPLY_PROP_HEALTH:
1319 ret = bq24190_charger_get_health(bdi, val);
1320 break;
1321 case POWER_SUPPLY_PROP_ONLINE:
1322 ret = bq24190_charger_get_online(bdi, val);
1323 break;
1324 case POWER_SUPPLY_PROP_STATUS:
1325 ret = bq24190_charger_get_status(bdi, val);
1326 break;
1327 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1328 ret = bq24190_charger_get_temp_alert_max(bdi, val);
1329 break;
1330 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
1331 ret = bq24190_charger_get_precharge(bdi, val);
1332 break;
1333 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
1334 ret = bq24190_charger_get_charge_term(bdi, val);
1335 break;
1336 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1337 ret = bq24190_charger_get_current(bdi, val);
1338 break;
1339 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
1340 val->intval = bdi->ichg_max;
1341 ret = 0;
1342 break;
1343 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1344 ret = bq24190_charger_get_voltage(bdi, val);
1345 break;
1346 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
1347 val->intval = bdi->vreg_max;
1348 ret = 0;
1349 break;
1350 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1351 ret = bq24190_charger_get_iinlimit(bdi, val);
1352 break;
1353 case POWER_SUPPLY_PROP_SCOPE:
1354 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1355 ret = 0;
1356 break;
1357 case POWER_SUPPLY_PROP_MODEL_NAME:
1358 val->strval = bdi->model_name;
1359 ret = 0;
1360 break;
1361 case POWER_SUPPLY_PROP_MANUFACTURER:
1362 val->strval = BQ24190_MANUFACTURER;
1363 ret = 0;
1364 break;
1365 default:
1366 ret = -ENODATA;
1369 pm_runtime_mark_last_busy(bdi->dev);
1370 pm_runtime_put_autosuspend(bdi->dev);
1372 return ret;
1375 static int bq24190_charger_set_property(struct power_supply *psy,
1376 enum power_supply_property psp,
1377 const union power_supply_propval *val)
1379 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1380 int ret;
1382 dev_dbg(bdi->dev, "prop: %d\n", psp);
1384 ret = pm_runtime_resume_and_get(bdi->dev);
1385 if (ret < 0)
1386 return ret;
1388 switch (psp) {
1389 case POWER_SUPPLY_PROP_ONLINE:
1390 ret = bq24190_charger_set_online(bdi, val);
1391 break;
1392 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1393 ret = bq24190_charger_set_temp_alert_max(bdi, val);
1394 break;
1395 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1396 ret = bq24190_charger_set_charge_type(bdi, val);
1397 break;
1398 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1399 ret = bq24190_charger_set_current(bdi, val);
1400 break;
1401 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1402 ret = bq24190_charger_set_voltage(bdi, val);
1403 break;
1404 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1405 ret = bq24190_charger_set_iinlimit(bdi, val);
1406 break;
1407 default:
1408 ret = -EINVAL;
1411 pm_runtime_mark_last_busy(bdi->dev);
1412 pm_runtime_put_autosuspend(bdi->dev);
1414 return ret;
1417 static int bq24190_charger_property_is_writeable(struct power_supply *psy,
1418 enum power_supply_property psp)
1420 switch (psp) {
1421 case POWER_SUPPLY_PROP_ONLINE:
1422 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1423 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1424 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1425 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1426 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1427 return 1;
1428 default:
1429 return 0;
1433 static void bq24190_input_current_limit_work(struct work_struct *work)
1435 struct bq24190_dev_info *bdi =
1436 container_of(work, struct bq24190_dev_info,
1437 input_current_limit_work.work);
1438 union power_supply_propval val;
1439 int ret;
1441 ret = power_supply_get_property_from_supplier(bdi->charger,
1442 POWER_SUPPLY_PROP_CURRENT_MAX,
1443 &val);
1444 if (ret)
1445 return;
1447 bq24190_charger_set_property(bdi->charger,
1448 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1449 &val);
1450 power_supply_changed(bdi->charger);
1453 /* Sync the input-current-limit with our parent supply (if we have one) */
1454 static void bq24190_charger_external_power_changed(struct power_supply *psy)
1456 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1459 * The Power-Good detection may take up to 220ms, sometimes
1460 * the external charger detection is quicker, and the bq24190 will
1461 * reset to iinlim based on its own charger detection (which is not
1462 * hooked up when using external charger detection) resulting in a
1463 * too low default 500mA iinlim. Delay setting the input-current-limit
1464 * for 300ms to avoid this.
1466 queue_delayed_work(system_wq, &bdi->input_current_limit_work,
1467 msecs_to_jiffies(300));
1470 static enum power_supply_property bq24190_charger_properties[] = {
1471 POWER_SUPPLY_PROP_CHARGE_TYPE,
1472 POWER_SUPPLY_PROP_HEALTH,
1473 POWER_SUPPLY_PROP_ONLINE,
1474 POWER_SUPPLY_PROP_STATUS,
1475 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1476 POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
1477 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
1478 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
1479 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
1480 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
1481 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
1482 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1483 POWER_SUPPLY_PROP_SCOPE,
1484 POWER_SUPPLY_PROP_MODEL_NAME,
1485 POWER_SUPPLY_PROP_MANUFACTURER,
1488 static char *bq24190_charger_supplied_to[] = {
1489 "main-battery",
1492 static const struct power_supply_desc bq24190_charger_desc = {
1493 .name = "bq24190-charger",
1494 .type = POWER_SUPPLY_TYPE_USB,
1495 .properties = bq24190_charger_properties,
1496 .num_properties = ARRAY_SIZE(bq24190_charger_properties),
1497 .get_property = bq24190_charger_get_property,
1498 .set_property = bq24190_charger_set_property,
1499 .property_is_writeable = bq24190_charger_property_is_writeable,
1500 .external_power_changed = bq24190_charger_external_power_changed,
1503 /* Battery power supply property routines */
1505 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1506 union power_supply_propval *val)
1508 u8 ss_reg, chrg_fault;
1509 int status, ret;
1511 mutex_lock(&bdi->f_reg_lock);
1512 chrg_fault = bdi->f_reg;
1513 mutex_unlock(&bdi->f_reg_lock);
1515 chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
1516 chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
1518 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1519 if (ret < 0)
1520 return ret;
1523 * The battery must be discharging when any of these are true:
1524 * - there is no good power source;
1525 * - there is a charge fault.
1526 * Could also be discharging when in "supplement mode" but
1527 * there is no way to tell when its in that mode.
1529 if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
1530 status = POWER_SUPPLY_STATUS_DISCHARGING;
1531 } else {
1532 ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
1533 ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
1535 switch (ss_reg) {
1536 case 0x0: /* Not Charging */
1537 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1538 break;
1539 case 0x1: /* Pre-charge */
1540 case 0x2: /* Fast Charging */
1541 status = POWER_SUPPLY_STATUS_CHARGING;
1542 break;
1543 case 0x3: /* Charge Termination Done */
1544 status = POWER_SUPPLY_STATUS_FULL;
1545 break;
1546 default:
1547 ret = -EIO;
1551 if (!ret)
1552 val->intval = status;
1554 return ret;
1557 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1558 union power_supply_propval *val)
1560 u8 v;
1561 int health;
1563 mutex_lock(&bdi->f_reg_lock);
1564 v = bdi->f_reg;
1565 mutex_unlock(&bdi->f_reg_lock);
1567 if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1568 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1569 } else {
1570 v &= bdi->info->ntc_fault_mask;
1572 health = v ? bdi->info->get_ntc_status(v) : POWER_SUPPLY_HEALTH_GOOD;
1575 val->intval = health;
1576 return 0;
1579 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1580 union power_supply_propval *val)
1582 u8 batfet_disable;
1583 int ret;
1585 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1586 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1587 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1588 if (ret < 0)
1589 return ret;
1591 val->intval = !batfet_disable;
1592 return 0;
1595 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1596 const union power_supply_propval *val)
1598 return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1599 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1600 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1603 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1604 union power_supply_propval *val)
1606 int temp, ret;
1608 ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1609 BQ24190_REG_ICTRC_TREG_MASK,
1610 BQ24190_REG_ICTRC_TREG_SHIFT,
1611 bq24190_ictrc_treg_values,
1612 ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1613 if (ret < 0)
1614 return ret;
1616 val->intval = temp;
1617 return 0;
1620 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1621 const union power_supply_propval *val)
1623 return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1624 BQ24190_REG_ICTRC_TREG_MASK,
1625 BQ24190_REG_ICTRC_TREG_SHIFT,
1626 bq24190_ictrc_treg_values,
1627 ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1630 static int bq24190_battery_get_property(struct power_supply *psy,
1631 enum power_supply_property psp, union power_supply_propval *val)
1633 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1634 int ret;
1636 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1637 dev_dbg(bdi->dev, "prop: %d\n", psp);
1639 ret = pm_runtime_resume_and_get(bdi->dev);
1640 if (ret < 0)
1641 return ret;
1643 switch (psp) {
1644 case POWER_SUPPLY_PROP_STATUS:
1645 ret = bq24190_battery_get_status(bdi, val);
1646 break;
1647 case POWER_SUPPLY_PROP_HEALTH:
1648 ret = bq24190_battery_get_health(bdi, val);
1649 break;
1650 case POWER_SUPPLY_PROP_ONLINE:
1651 ret = bq24190_battery_get_online(bdi, val);
1652 break;
1653 case POWER_SUPPLY_PROP_TECHNOLOGY:
1654 /* Could be Li-on or Li-polymer but no way to tell which */
1655 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1656 ret = 0;
1657 break;
1658 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1659 ret = bq24190_battery_get_temp_alert_max(bdi, val);
1660 break;
1661 case POWER_SUPPLY_PROP_SCOPE:
1662 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1663 ret = 0;
1664 break;
1665 default:
1666 ret = -ENODATA;
1669 pm_runtime_mark_last_busy(bdi->dev);
1670 pm_runtime_put_autosuspend(bdi->dev);
1672 return ret;
1675 static int bq24190_battery_set_property(struct power_supply *psy,
1676 enum power_supply_property psp,
1677 const union power_supply_propval *val)
1679 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1680 int ret;
1682 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1683 dev_dbg(bdi->dev, "prop: %d\n", psp);
1685 ret = pm_runtime_resume_and_get(bdi->dev);
1686 if (ret < 0)
1687 return ret;
1689 switch (psp) {
1690 case POWER_SUPPLY_PROP_ONLINE:
1691 ret = bq24190_battery_set_online(bdi, val);
1692 break;
1693 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1694 ret = bq24190_battery_set_temp_alert_max(bdi, val);
1695 break;
1696 default:
1697 ret = -EINVAL;
1700 pm_runtime_mark_last_busy(bdi->dev);
1701 pm_runtime_put_autosuspend(bdi->dev);
1703 return ret;
1706 static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1707 enum power_supply_property psp)
1709 int ret;
1711 switch (psp) {
1712 case POWER_SUPPLY_PROP_ONLINE:
1713 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1714 ret = 1;
1715 break;
1716 default:
1717 ret = 0;
1720 return ret;
1723 static enum power_supply_property bq24190_battery_properties[] = {
1724 POWER_SUPPLY_PROP_STATUS,
1725 POWER_SUPPLY_PROP_HEALTH,
1726 POWER_SUPPLY_PROP_ONLINE,
1727 POWER_SUPPLY_PROP_TECHNOLOGY,
1728 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1729 POWER_SUPPLY_PROP_SCOPE,
1732 static const struct power_supply_desc bq24190_battery_desc = {
1733 .name = "bq24190-battery",
1734 .type = POWER_SUPPLY_TYPE_BATTERY,
1735 .properties = bq24190_battery_properties,
1736 .num_properties = ARRAY_SIZE(bq24190_battery_properties),
1737 .get_property = bq24190_battery_get_property,
1738 .set_property = bq24190_battery_set_property,
1739 .property_is_writeable = bq24190_battery_property_is_writeable,
1742 static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
1744 bool otg_enabled;
1745 int ret;
1747 otg_enabled = !!(ss_reg & BQ24190_REG_SS_VBUS_STAT_MASK);
1748 ret = extcon_set_state_sync(bdi->edev, EXTCON_USB, otg_enabled);
1749 if (ret < 0)
1750 dev_err(bdi->dev, "Can't set extcon state to %d: %d\n",
1751 otg_enabled, ret);
1753 return ret;
1756 static void bq24190_check_status(struct bq24190_dev_info *bdi)
1758 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1759 u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK;
1760 bool alert_charger = false, alert_battery = false;
1761 u8 ss_reg = 0, f_reg = 0;
1762 int i, ret;
1764 battery_mask_f |= bdi->info->ntc_fault_mask;
1766 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1767 if (ret < 0) {
1768 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1769 return;
1772 i = 0;
1773 do {
1774 ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1775 if (ret < 0) {
1776 dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1777 return;
1779 } while (f_reg && ++i < 2);
1781 /* ignore over/under voltage fault after disconnect */
1782 if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1783 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1784 f_reg = 0;
1786 if (f_reg != bdi->f_reg) {
1787 dev_warn(bdi->dev,
1788 "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1789 !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1790 !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1791 !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1792 !!(f_reg & bdi->info->ntc_fault_mask));
1794 mutex_lock(&bdi->f_reg_lock);
1795 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1796 alert_battery = true;
1797 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1798 alert_charger = true;
1799 bdi->f_reg = f_reg;
1800 mutex_unlock(&bdi->f_reg_lock);
1803 if (ss_reg != bdi->ss_reg) {
1805 * The device is in host mode so when PG_STAT goes from 1->0
1806 * (i.e., power removed) HIZ needs to be disabled.
1808 if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1809 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1810 ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1811 BQ24190_REG_ISC_EN_HIZ_MASK,
1812 BQ24190_REG_ISC_EN_HIZ_SHIFT,
1814 if (ret < 0)
1815 dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1816 ret);
1819 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1820 alert_battery = true;
1821 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1822 alert_charger = true;
1823 bdi->ss_reg = ss_reg;
1826 if (alert_charger || alert_battery) {
1827 power_supply_changed(bdi->charger);
1828 bq24190_configure_usb_otg(bdi, ss_reg);
1830 if (alert_battery && bdi->battery)
1831 power_supply_changed(bdi->battery);
1833 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1836 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1838 struct bq24190_dev_info *bdi = data;
1839 int error;
1841 bdi->irq_event = true;
1842 error = pm_runtime_resume_and_get(bdi->dev);
1843 if (error < 0) {
1844 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1845 return IRQ_NONE;
1847 bq24190_check_status(bdi);
1848 pm_runtime_mark_last_busy(bdi->dev);
1849 pm_runtime_put_autosuspend(bdi->dev);
1850 bdi->irq_event = false;
1852 return IRQ_HANDLED;
1855 static int bq24190_check_chip(struct bq24190_dev_info *bdi)
1857 u8 v;
1858 int ret;
1860 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1861 BQ24190_REG_VPRS_PN_MASK,
1862 BQ24190_REG_VPRS_PN_SHIFT,
1863 &v);
1864 if (ret < 0)
1865 return ret;
1867 switch (v) {
1868 case BQ24190_REG_VPRS_PN_24190:
1869 case BQ24190_REG_VPRS_PN_24192:
1870 case BQ24190_REG_VPRS_PN_24192I:
1871 break;
1872 default:
1873 dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1874 return -ENODEV;
1877 return 0;
1880 static int bq24296_check_chip(struct bq24190_dev_info *bdi)
1882 u8 v;
1883 int ret;
1885 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1886 BQ24296_REG_VPRS_PN_MASK,
1887 BQ24296_REG_VPRS_PN_SHIFT,
1888 &v);
1889 if (ret < 0)
1890 return ret;
1892 switch (v) {
1893 case BQ24296_REG_VPRS_PN_24296:
1894 break;
1895 default:
1896 dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1897 return -ENODEV;
1900 return 0;
1903 static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1905 int ret;
1907 ret = bdi->info->check_chip(bdi);
1908 if (ret < 0)
1909 return ret;
1911 ret = bq24190_register_reset(bdi);
1912 if (ret < 0)
1913 return ret;
1915 ret = bq24190_set_config(bdi);
1916 if (ret < 0)
1917 return ret;
1919 return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1922 static int bq24190_get_config(struct bq24190_dev_info *bdi)
1924 const char * const s = "ti,system-minimum-microvolt";
1925 struct power_supply_battery_info *info;
1926 int v, idx;
1928 idx = bdi->info->ichg_array_size - 1;
1930 bdi->ichg_max = bq24190_ccc_ichg_values[idx];
1932 idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
1933 bdi->vreg_max = bq24190_cvc_vreg_values[idx];
1935 if (device_property_read_u32(bdi->dev, s, &v) == 0) {
1936 v /= 1000;
1937 if (v >= BQ24190_REG_POC_SYS_MIN_MIN
1938 && v <= BQ24190_REG_POC_SYS_MIN_MAX)
1939 bdi->sys_min = v;
1940 else
1941 dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v);
1944 if (!power_supply_get_battery_info(bdi->charger, &info)) {
1945 v = info->precharge_current_ua / 1000;
1946 if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
1947 && v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
1948 bdi->iprechg = v;
1949 else
1950 dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
1953 v = info->charge_term_current_ua / 1000;
1954 if (v >= BQ24190_REG_PCTCC_ITERM_MIN
1955 && v <= BQ24190_REG_PCTCC_ITERM_MAX)
1956 bdi->iterm = v;
1957 else
1958 dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n",
1961 /* These are optional, so no warning when not set */
1962 v = info->constant_charge_current_max_ua;
1963 if (v >= bq24190_ccc_ichg_values[0] && v <= bdi->ichg_max)
1964 bdi->ichg = bdi->ichg_max = v;
1966 v = info->constant_charge_voltage_max_uv;
1967 if (v >= bq24190_cvc_vreg_values[0] && v <= bdi->vreg_max)
1968 bdi->vreg = bdi->vreg_max = v;
1971 return 0;
1974 static const struct bq24190_chip_info bq24190_chip_info_tbl[] = {
1975 [BQ24190] = {
1976 .ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
1977 #ifdef CONFIG_REGULATOR
1978 .vbus_desc = &bq24190_vbus_desc,
1979 #endif
1980 .check_chip = bq24190_check_chip,
1981 .set_chg_config = bq24190_battery_set_chg_config,
1982 .ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
1983 .get_ntc_status = bq24190_charger_get_ntc_status,
1984 .set_otg_vbus = bq24190_set_otg_vbus,
1986 [BQ24192] = {
1987 .ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
1988 #ifdef CONFIG_REGULATOR
1989 .vbus_desc = &bq24190_vbus_desc,
1990 #endif
1991 .check_chip = bq24190_check_chip,
1992 .set_chg_config = bq24190_battery_set_chg_config,
1993 .ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
1994 .get_ntc_status = bq24190_charger_get_ntc_status,
1995 .set_otg_vbus = bq24190_set_otg_vbus,
1997 [BQ24192i] = {
1998 .ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
1999 #ifdef CONFIG_REGULATOR
2000 .vbus_desc = &bq24190_vbus_desc,
2001 #endif
2002 .check_chip = bq24190_check_chip,
2003 .set_chg_config = bq24190_battery_set_chg_config,
2004 .ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
2005 .get_ntc_status = bq24190_charger_get_ntc_status,
2006 .set_otg_vbus = bq24190_set_otg_vbus,
2008 [BQ24196] = {
2009 .ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
2010 #ifdef CONFIG_REGULATOR
2011 .vbus_desc = &bq24190_vbus_desc,
2012 #endif
2013 .check_chip = bq24190_check_chip,
2014 .set_chg_config = bq24190_battery_set_chg_config,
2015 .ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
2016 .get_ntc_status = bq24190_charger_get_ntc_status,
2017 .set_otg_vbus = bq24190_set_otg_vbus,
2019 [BQ24296] = {
2020 .ichg_array_size = BQ24296_CCC_ICHG_VALUES_LEN,
2021 #ifdef CONFIG_REGULATOR
2022 .vbus_desc = &bq24296_vbus_desc,
2023 #endif
2024 .check_chip = bq24296_check_chip,
2025 .set_chg_config = bq24296_battery_set_chg_config,
2026 .ntc_fault_mask = BQ24296_REG_F_NTC_FAULT_MASK,
2027 .get_ntc_status = bq24296_charger_get_ntc_status,
2028 .set_otg_vbus = bq24296_set_otg_vbus,
2032 static int bq24190_probe(struct i2c_client *client)
2034 const struct i2c_device_id *id = i2c_client_get_device_id(client);
2035 struct i2c_adapter *adapter = client->adapter;
2036 struct device *dev = &client->dev;
2037 struct power_supply_config charger_cfg = {}, battery_cfg = {};
2038 struct bq24190_dev_info *bdi;
2039 int ret;
2041 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
2042 dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
2043 return -ENODEV;
2046 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
2047 if (!bdi) {
2048 dev_err(dev, "Can't alloc bdi struct\n");
2049 return -ENOMEM;
2052 bdi->client = client;
2053 bdi->dev = dev;
2054 strscpy(bdi->model_name, id->name, sizeof(bdi->model_name));
2055 bdi->info = i2c_get_match_data(client);
2056 mutex_init(&bdi->f_reg_lock);
2057 bdi->charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
2058 bdi->f_reg = 0;
2059 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
2060 INIT_DELAYED_WORK(&bdi->input_current_limit_work,
2061 bq24190_input_current_limit_work);
2063 i2c_set_clientdata(client, bdi);
2065 if (client->irq <= 0) {
2066 dev_err(dev, "Can't get irq info\n");
2067 return -EINVAL;
2070 bdi->edev = devm_extcon_dev_allocate(dev, bq24190_usb_extcon_cable);
2071 if (IS_ERR(bdi->edev))
2072 return PTR_ERR(bdi->edev);
2074 ret = devm_extcon_dev_register(dev, bdi->edev);
2075 if (ret < 0)
2076 return ret;
2078 pm_runtime_enable(dev);
2079 pm_runtime_use_autosuspend(dev);
2080 pm_runtime_set_autosuspend_delay(dev, 600);
2081 ret = pm_runtime_get_sync(dev);
2082 if (ret < 0) {
2083 dev_err(dev, "pm_runtime_get failed: %i\n", ret);
2084 goto out_pmrt;
2087 #ifdef CONFIG_SYSFS
2088 bq24190_sysfs_init_attrs();
2089 charger_cfg.attr_grp = bq24190_sysfs_groups;
2090 #endif
2092 charger_cfg.drv_data = bdi;
2093 charger_cfg.of_node = dev->of_node;
2094 charger_cfg.supplied_to = bq24190_charger_supplied_to;
2095 charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to);
2096 bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
2097 &charger_cfg);
2098 if (IS_ERR(bdi->charger)) {
2099 dev_err(dev, "Can't register charger\n");
2100 ret = PTR_ERR(bdi->charger);
2101 goto out_pmrt;
2104 /* the battery class is deprecated and will be removed. */
2105 /* in the interim, this property hides it. */
2106 if (!device_property_read_bool(dev, "omit-battery-class")) {
2107 battery_cfg.drv_data = bdi;
2108 bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
2109 &battery_cfg);
2110 if (IS_ERR(bdi->battery)) {
2111 dev_err(dev, "Can't register battery\n");
2112 ret = PTR_ERR(bdi->battery);
2113 goto out_charger;
2117 ret = bq24190_get_config(bdi);
2118 if (ret < 0) {
2119 dev_err(dev, "Can't get devicetree config\n");
2120 goto out_charger;
2123 ret = bq24190_hw_init(bdi);
2124 if (ret < 0) {
2125 dev_err(dev, "Hardware init failed\n");
2126 goto out_charger;
2129 ret = bq24190_configure_usb_otg(bdi, bdi->ss_reg);
2130 if (ret < 0)
2131 goto out_charger;
2133 bdi->initialized = true;
2135 ret = devm_request_threaded_irq(dev, client->irq, NULL,
2136 bq24190_irq_handler_thread,
2137 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2138 "bq24190-charger", bdi);
2139 if (ret < 0) {
2140 dev_err(dev, "Can't set up irq handler\n");
2141 goto out_charger;
2144 ret = bq24190_register_vbus_regulator(bdi);
2145 if (ret < 0)
2146 goto out_charger;
2148 enable_irq_wake(client->irq);
2150 pm_runtime_mark_last_busy(dev);
2151 pm_runtime_put_autosuspend(dev);
2153 return 0;
2155 out_charger:
2156 if (!IS_ERR_OR_NULL(bdi->battery))
2157 power_supply_unregister(bdi->battery);
2158 power_supply_unregister(bdi->charger);
2160 out_pmrt:
2161 pm_runtime_put_sync(dev);
2162 pm_runtime_dont_use_autosuspend(dev);
2163 pm_runtime_disable(dev);
2164 return ret;
2167 static void bq24190_remove(struct i2c_client *client)
2169 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2170 int error;
2172 cancel_delayed_work_sync(&bdi->input_current_limit_work);
2173 error = pm_runtime_resume_and_get(bdi->dev);
2174 if (error < 0)
2175 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
2177 bq24190_register_reset(bdi);
2178 if (bdi->battery)
2179 power_supply_unregister(bdi->battery);
2180 power_supply_unregister(bdi->charger);
2181 if (error >= 0)
2182 pm_runtime_put_sync(bdi->dev);
2183 pm_runtime_dont_use_autosuspend(bdi->dev);
2184 pm_runtime_disable(bdi->dev);
2187 static void bq24190_shutdown(struct i2c_client *client)
2189 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2191 /* Turn off 5V boost regulator on shutdown */
2192 bdi->info->set_otg_vbus(bdi, false);
2195 static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
2197 struct i2c_client *client = to_i2c_client(dev);
2198 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2200 if (!bdi->initialized)
2201 return 0;
2203 dev_dbg(bdi->dev, "%s\n", __func__);
2205 return 0;
2208 static __maybe_unused int bq24190_runtime_resume(struct device *dev)
2210 struct i2c_client *client = to_i2c_client(dev);
2211 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2213 if (!bdi->initialized)
2214 return 0;
2216 if (!bdi->irq_event) {
2217 dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
2218 bq24190_check_status(bdi);
2221 return 0;
2224 static __maybe_unused int bq24190_pm_suspend(struct device *dev)
2226 struct i2c_client *client = to_i2c_client(dev);
2227 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2228 int error;
2230 error = pm_runtime_resume_and_get(bdi->dev);
2231 if (error < 0)
2232 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
2234 bq24190_register_reset(bdi);
2236 if (error >= 0) {
2237 pm_runtime_mark_last_busy(bdi->dev);
2238 pm_runtime_put_autosuspend(bdi->dev);
2241 return 0;
2244 static __maybe_unused int bq24190_pm_resume(struct device *dev)
2246 struct i2c_client *client = to_i2c_client(dev);
2247 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2248 int error;
2250 bdi->f_reg = 0;
2251 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
2253 error = pm_runtime_resume_and_get(bdi->dev);
2254 if (error < 0)
2255 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
2257 bq24190_register_reset(bdi);
2258 bq24190_set_config(bdi);
2259 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
2261 if (error >= 0) {
2262 pm_runtime_mark_last_busy(bdi->dev);
2263 pm_runtime_put_autosuspend(bdi->dev);
2266 /* Things may have changed while suspended so alert upper layer */
2267 power_supply_changed(bdi->charger);
2268 if (bdi->battery)
2269 power_supply_changed(bdi->battery);
2271 return 0;
2274 static const struct dev_pm_ops bq24190_pm_ops = {
2275 SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
2276 NULL)
2277 SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
2280 static const struct i2c_device_id bq24190_i2c_ids[] = {
2281 { "bq24190", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24190] },
2282 { "bq24192", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24192] },
2283 { "bq24192i", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24192i] },
2284 { "bq24196", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24196] },
2285 { "bq24296", (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24296] },
2286 { },
2288 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
2290 static const struct of_device_id bq24190_of_match[] = {
2291 { .compatible = "ti,bq24190", .data = &bq24190_chip_info_tbl[BQ24190] },
2292 { .compatible = "ti,bq24192", .data = &bq24190_chip_info_tbl[BQ24192] },
2293 { .compatible = "ti,bq24192i", .data = &bq24190_chip_info_tbl[BQ24192i] },
2294 { .compatible = "ti,bq24196", .data = &bq24190_chip_info_tbl[BQ24196] },
2295 { .compatible = "ti,bq24296", .data = &bq24190_chip_info_tbl[BQ24296] },
2296 { },
2298 MODULE_DEVICE_TABLE(of, bq24190_of_match);
2300 static struct i2c_driver bq24190_driver = {
2301 .probe = bq24190_probe,
2302 .remove = bq24190_remove,
2303 .shutdown = bq24190_shutdown,
2304 .id_table = bq24190_i2c_ids,
2305 .driver = {
2306 .name = "bq24190-charger",
2307 .pm = &bq24190_pm_ops,
2308 .of_match_table = bq24190_of_match,
2311 module_i2c_driver(bq24190_driver);
2313 MODULE_LICENSE("GPL");
2314 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
2315 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");