1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Driver for the TI bq24190 battery charger.
4 *
5 * Author: Mark A. Greer <mgreer@animalcreek.com>
6 */
7
8 #include <linux/module.h>
9 #include <linux/interrupt.h>
10 #include <linux/delay.h>
11 #include <linux/devm-helpers.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>
20
21 #define BQ24190_MANUFACTURER "Texas Instruments"
22
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
31
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
55
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
62
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
74
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
83
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
97
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
105
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
117
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
131
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
145
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 BQ24296_REG_VPRS_PN_24297 0x3
156 #define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2)
157 #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2
158 #define BQ24190_REG_VPRS_DEV_REG_MASK (BIT(1) | BIT(0))
159 #define BQ24190_REG_VPRS_DEV_REG_SHIFT 0
160
161 /*
162 * The tables below provide a 2-way mapping for the value that goes in
163 * the register field and the real-world value that it represents.
164 * The index of the array is the value that goes in the register; the
165 * number at that index in the array is the real-world value that it
166 * represents.
167 */
168
169 /* REG00[2:0] (IINLIM) in uAh */
170 static const int bq24190_isc_iinlim_values[] = {
171 100000, 150000, 500000, 900000, 1200000, 1500000, 2000000, 3000000
172 };
173
174 /* REG02[7:2] (ICHG) in uAh */
175 static const int bq24190_ccc_ichg_values[] = {
176 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
177 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
178 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
179 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
180 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
181 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
182 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
183 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
184 };
185
186 /* ICHG higher than 3008mA is not supported in BQ24296 */
187 #define BQ24296_CCC_ICHG_VALUES_LEN 40
188
189 /* REG04[7:2] (VREG) in uV */
190 static const int bq24190_cvc_vreg_values[] = {
191 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
192 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
193 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
194 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
195 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
196 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
197 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
198 4400000
199 };
200
201 /* REG06[1:0] (TREG) in tenths of degrees Celsius */
202 static const int bq24190_ictrc_treg_values[] = {
203 600, 800, 1000, 1200
204 };
205
206 enum bq24190_chip {
207 BQ24190,
208 BQ24192,
209 BQ24192i,
210 BQ24193,
211 BQ24196,
212 BQ24296,
213 BQ24297,
214 };
215
216 /*
217 * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
218 * so the first read after a fault returns the latched value and subsequent
219 * reads return the current value. In order to return the fault status
220 * to the user, have the interrupt handler save the reg's value and retrieve
221 * it in the appropriate health/status routine.
222 */
223 struct bq24190_dev_info {
224 struct i2c_client *client;
225 struct device *dev;
226 struct extcon_dev *edev;
227 struct power_supply *charger;
228 struct power_supply *battery;
229 struct delayed_work input_current_limit_work;
230 char model_name[I2C_NAME_SIZE];
231 bool initialized;
232 bool irq_event;
233 bool otg_vbus_enabled;
234 int charge_type;
235 u16 sys_min;
236 u16 iprechg;
237 u16 iterm;
238 u32 ichg;
239 u32 ichg_max;
240 u32 vreg;
241 u32 vreg_max;
242 struct mutex f_reg_lock;
243 u8 f_reg;
244 u8 ss_reg;
245 const struct bq24190_chip_info *info;
246 };
247
248 struct bq24190_chip_info {
249 int ichg_array_size;
250 #ifdef CONFIG_REGULATOR
251 const struct regulator_desc *vbus_desc;
252 #endif
253 int (*check_chip)(struct bq24190_dev_info *bdi);
254 int (*set_chg_config)(struct bq24190_dev_info *bdi, const u8 chg_config);
255 int (*set_otg_vbus)(struct bq24190_dev_info *bdi, bool enable);
256 u8 ntc_fault_mask;
257 int (*get_ntc_status)(const u8 value);
258 };
259
260 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
261 const union power_supply_propval *val);
262
263 static const unsigned int bq24190_usb_extcon_cable[] = {
264 EXTCON_USB,
265 EXTCON_NONE,
266 };
267
268
269 /*
270 * Return the index in 'tbl' of greatest value that is less than or equal to
271 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
272 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
273 * is less than 2^8.
274 */
bq24190_find_idx(const int tbl[],int tbl_size,int v)275 static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
276 {
277 int i;
278
279 for (i = 1; i < tbl_size; i++)
280 if (v < tbl[i])
281 break;
282
283 return i - 1;
284 }
285
286 /* Basic driver I/O routines */
287
bq24190_read(struct bq24190_dev_info * bdi,u8 reg,u8 * data)288 static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
289 {
290 int ret;
291
292 ret = i2c_smbus_read_byte_data(bdi->client, reg);
293 if (ret < 0)
294 return ret;
295
296 *data = ret;
297 return 0;
298 }
299
bq24190_write(struct bq24190_dev_info * bdi,u8 reg,u8 data)300 static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
301 {
302 return i2c_smbus_write_byte_data(bdi->client, reg, data);
303 }
304
bq24190_read_mask(struct bq24190_dev_info * bdi,u8 reg,u8 mask,u8 shift,u8 * data)305 static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
306 u8 mask, u8 shift, u8 *data)
307 {
308 u8 v;
309 int ret;
310
311 ret = bq24190_read(bdi, reg, &v);
312 if (ret < 0)
313 return ret;
314
315 v &= mask;
316 v >>= shift;
317 *data = v;
318
319 return 0;
320 }
321
bq24190_write_mask(struct bq24190_dev_info * bdi,u8 reg,u8 mask,u8 shift,u8 data)322 static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
323 u8 mask, u8 shift, u8 data)
324 {
325 u8 v;
326 int ret;
327
328 ret = bq24190_read(bdi, reg, &v);
329 if (ret < 0)
330 return ret;
331
332 v &= ~mask;
333 v |= ((data << shift) & mask);
334
335 return bq24190_write(bdi, reg, v);
336 }
337
bq24190_get_field_val(struct bq24190_dev_info * bdi,u8 reg,u8 mask,u8 shift,const int tbl[],int tbl_size,int * val)338 static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
339 u8 reg, u8 mask, u8 shift,
340 const int tbl[], int tbl_size,
341 int *val)
342 {
343 u8 v;
344 int ret;
345
346 ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
347 if (ret < 0)
348 return ret;
349
350 v = (v >= tbl_size) ? (tbl_size - 1) : v;
351 *val = tbl[v];
352
353 return 0;
354 }
355
bq24190_set_field_val(struct bq24190_dev_info * bdi,u8 reg,u8 mask,u8 shift,const int tbl[],int tbl_size,int val)356 static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
357 u8 reg, u8 mask, u8 shift,
358 const int tbl[], int tbl_size,
359 int val)
360 {
361 u8 idx;
362
363 idx = bq24190_find_idx(tbl, tbl_size, val);
364
365 return bq24190_write_mask(bdi, reg, mask, shift, idx);
366 }
367
368 #ifdef CONFIG_SYSFS
369 /*
370 * There are a numerous options that are configurable on the bq24190
371 * that go well beyond what the power_supply properties provide access to.
372 * Provide sysfs access to them so they can be examined and possibly modified
373 * on the fly. They will be provided for the charger power_supply object only
374 * and will be prefixed by 'f_' to make them easier to recognize.
375 */
376
377 #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
378 { \
379 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
380 .reg = BQ24190_REG_##r, \
381 .mask = BQ24190_REG_##r##_##f##_MASK, \
382 .shift = BQ24190_REG_##r##_##f##_SHIFT, \
383 }
384
385 #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
386 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
387 bq24190_sysfs_store)
388
389 #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
390 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
391
392 static ssize_t bq24190_sysfs_show(struct device *dev,
393 struct device_attribute *attr, char *buf);
394 static ssize_t bq24190_sysfs_store(struct device *dev,
395 struct device_attribute *attr, const char *buf, size_t count);
396
397 struct bq24190_sysfs_field_info {
398 struct device_attribute attr;
399 u8 reg;
400 u8 mask;
401 u8 shift;
402 };
403
404 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
405 #undef SS
406
407 static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
408 /* sysfs name reg field in reg */
409 BQ24190_SYSFS_FIELD_RW(en_hiz, ISC, EN_HIZ),
410 BQ24190_SYSFS_FIELD_RW(vindpm, ISC, VINDPM),
411 BQ24190_SYSFS_FIELD_RW(iinlim, ISC, IINLIM),
412 BQ24190_SYSFS_FIELD_RW(chg_config, POC, CHG_CONFIG),
413 BQ24190_SYSFS_FIELD_RW(sys_min, POC, SYS_MIN),
414 BQ24190_SYSFS_FIELD_RW(boost_lim, POC, BOOST_LIM),
415 BQ24190_SYSFS_FIELD_RW(ichg, CCC, ICHG),
416 BQ24190_SYSFS_FIELD_RW(force_20_pct, CCC, FORCE_20PCT),
417 BQ24190_SYSFS_FIELD_RW(iprechg, PCTCC, IPRECHG),
418 BQ24190_SYSFS_FIELD_RW(iterm, PCTCC, ITERM),
419 BQ24190_SYSFS_FIELD_RW(vreg, CVC, VREG),
420 BQ24190_SYSFS_FIELD_RW(batlowv, CVC, BATLOWV),
421 BQ24190_SYSFS_FIELD_RW(vrechg, CVC, VRECHG),
422 BQ24190_SYSFS_FIELD_RW(en_term, CTTC, EN_TERM),
423 BQ24190_SYSFS_FIELD_RW(term_stat, CTTC, TERM_STAT),
424 BQ24190_SYSFS_FIELD_RO(watchdog, CTTC, WATCHDOG),
425 BQ24190_SYSFS_FIELD_RW(en_timer, CTTC, EN_TIMER),
426 BQ24190_SYSFS_FIELD_RW(chg_timer, CTTC, CHG_TIMER),
427 BQ24190_SYSFS_FIELD_RW(jeita_iset, CTTC, JEITA_ISET),
428 BQ24190_SYSFS_FIELD_RW(bat_comp, ICTRC, BAT_COMP),
429 BQ24190_SYSFS_FIELD_RW(vclamp, ICTRC, VCLAMP),
430 BQ24190_SYSFS_FIELD_RW(treg, ICTRC, TREG),
431 BQ24190_SYSFS_FIELD_RW(dpdm_en, MOC, DPDM_EN),
432 BQ24190_SYSFS_FIELD_RW(tmr2x_en, MOC, TMR2X_EN),
433 BQ24190_SYSFS_FIELD_RW(batfet_disable, MOC, BATFET_DISABLE),
434 BQ24190_SYSFS_FIELD_RW(jeita_vset, MOC, JEITA_VSET),
435 BQ24190_SYSFS_FIELD_RO(int_mask, MOC, INT_MASK),
436 BQ24190_SYSFS_FIELD_RO(vbus_stat, SS, VBUS_STAT),
437 BQ24190_SYSFS_FIELD_RO(chrg_stat, SS, CHRG_STAT),
438 BQ24190_SYSFS_FIELD_RO(dpm_stat, SS, DPM_STAT),
439 BQ24190_SYSFS_FIELD_RO(pg_stat, SS, PG_STAT),
440 BQ24190_SYSFS_FIELD_RO(therm_stat, SS, THERM_STAT),
441 BQ24190_SYSFS_FIELD_RO(vsys_stat, SS, VSYS_STAT),
442 BQ24190_SYSFS_FIELD_RO(watchdog_fault, F, WATCHDOG_FAULT),
443 BQ24190_SYSFS_FIELD_RO(boost_fault, F, BOOST_FAULT),
444 BQ24190_SYSFS_FIELD_RO(chrg_fault, F, CHRG_FAULT),
445 BQ24190_SYSFS_FIELD_RO(bat_fault, F, BAT_FAULT),
446 BQ24190_SYSFS_FIELD_RO(ntc_fault, F, NTC_FAULT),
447 BQ24190_SYSFS_FIELD_RO(pn, VPRS, PN),
448 BQ24190_SYSFS_FIELD_RO(ts_profile, VPRS, TS_PROFILE),
449 BQ24190_SYSFS_FIELD_RO(dev_reg, VPRS, DEV_REG),
450 };
451
452 static struct attribute *
453 bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
454
455 ATTRIBUTE_GROUPS(bq24190_sysfs);
456
bq24190_sysfs_init_attrs(void)457 static void bq24190_sysfs_init_attrs(void)
458 {
459 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
460
461 for (i = 0; i < limit; i++)
462 bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
463
464 bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
465 }
466
bq24190_sysfs_field_lookup(const char * name)467 static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
468 const char *name)
469 {
470 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
471
472 for (i = 0; i < limit; i++)
473 if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
474 break;
475
476 if (i >= limit)
477 return NULL;
478
479 return &bq24190_sysfs_field_tbl[i];
480 }
481
bq24190_sysfs_show(struct device * dev,struct device_attribute * attr,char * buf)482 static ssize_t bq24190_sysfs_show(struct device *dev,
483 struct device_attribute *attr, char *buf)
484 {
485 struct power_supply *psy = dev_to_psy(dev);
486 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
487 struct bq24190_sysfs_field_info *info;
488 ssize_t count;
489 int ret;
490 u8 v;
491
492 info = bq24190_sysfs_field_lookup(attr->attr.name);
493 if (!info)
494 return -EINVAL;
495
496 ret = pm_runtime_resume_and_get(bdi->dev);
497 if (ret < 0)
498 return ret;
499
500 ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
501 if (ret)
502 count = ret;
503 else
504 count = sysfs_emit(buf, "%hhx\n", v);
505
506 pm_runtime_put_autosuspend(bdi->dev);
507
508 return count;
509 }
510
bq24190_sysfs_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)511 static ssize_t bq24190_sysfs_store(struct device *dev,
512 struct device_attribute *attr, const char *buf, size_t count)
513 {
514 struct power_supply *psy = dev_to_psy(dev);
515 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
516 struct bq24190_sysfs_field_info *info;
517 int ret;
518 u8 v;
519
520 info = bq24190_sysfs_field_lookup(attr->attr.name);
521 if (!info)
522 return -EINVAL;
523
524 ret = kstrtou8(buf, 0, &v);
525 if (ret < 0)
526 return ret;
527
528 ret = pm_runtime_resume_and_get(bdi->dev);
529 if (ret < 0)
530 return ret;
531
532 ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
533 if (ret)
534 count = ret;
535
536 pm_runtime_put_autosuspend(bdi->dev);
537
538 return count;
539 }
540 #endif
541
bq24190_set_otg_vbus(struct bq24190_dev_info * bdi,bool enable)542 static int bq24190_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
543 {
544 union power_supply_propval val = { .intval = bdi->charge_type };
545 int ret;
546
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;
551 }
552
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);
561
562 pm_runtime_put_autosuspend(bdi->dev);
563
564 return ret;
565 }
566
bq24296_set_otg_vbus(struct bq24190_dev_info * bdi,bool enable)567 static int bq24296_set_otg_vbus(struct bq24190_dev_info *bdi, bool enable)
568 {
569 union power_supply_propval val = { .intval = bdi->charge_type };
570 int ret;
571
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;
576 }
577
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);
584
585 if (ret < 0)
586 goto out;
587
588 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
589 BQ24296_REG_POC_OTG_CONFIG_MASK,
590 BQ24296_REG_POC_OTG_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_OTG_CONFIG_SHIFT,
596 BQ24296_REG_POC_OTG_CONFIG_DISABLE);
597 if (ret < 0)
598 goto out;
599
600 ret = bq24190_charger_set_charge_type(bdi, &val);
601 }
602
603 out:
604 pm_runtime_put_autosuspend(bdi->dev);
605
606 return ret;
607 }
608
609 #ifdef CONFIG_REGULATOR
bq24190_vbus_enable(struct regulator_dev * dev)610 static int bq24190_vbus_enable(struct regulator_dev *dev)
611 {
612 return bq24190_set_otg_vbus(rdev_get_drvdata(dev), true);
613 }
614
bq24190_vbus_disable(struct regulator_dev * dev)615 static int bq24190_vbus_disable(struct regulator_dev *dev)
616 {
617 return bq24190_set_otg_vbus(rdev_get_drvdata(dev), false);
618 }
619
bq24190_vbus_is_enabled(struct regulator_dev * dev)620 static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
621 {
622 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
623 int ret;
624 u8 val;
625
626 ret = pm_runtime_resume_and_get(bdi->dev);
627 if (ret < 0) {
628 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
629 return ret;
630 }
631
632 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
633 BQ24190_REG_POC_CHG_CONFIG_MASK,
634 BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
635
636 pm_runtime_put_autosuspend(bdi->dev);
637
638 if (ret)
639 return ret;
640
641 bdi->otg_vbus_enabled = (val == BQ24190_REG_POC_CHG_CONFIG_OTG ||
642 val == BQ24190_REG_POC_CHG_CONFIG_OTG_ALT);
643 return bdi->otg_vbus_enabled;
644 }
645
bq24296_vbus_enable(struct regulator_dev * dev)646 static int bq24296_vbus_enable(struct regulator_dev *dev)
647 {
648 return bq24296_set_otg_vbus(rdev_get_drvdata(dev), true);
649 }
650
bq24296_vbus_disable(struct regulator_dev * dev)651 static int bq24296_vbus_disable(struct regulator_dev *dev)
652 {
653 return bq24296_set_otg_vbus(rdev_get_drvdata(dev), false);
654 }
655
bq24296_vbus_is_enabled(struct regulator_dev * dev)656 static int bq24296_vbus_is_enabled(struct regulator_dev *dev)
657 {
658 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
659 int ret;
660 u8 val;
661
662 ret = pm_runtime_resume_and_get(bdi->dev);
663 if (ret < 0) {
664 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
665 return ret;
666 }
667
668 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
669 BQ24296_REG_POC_OTG_CONFIG_MASK,
670 BQ24296_REG_POC_OTG_CONFIG_SHIFT, &val);
671
672 pm_runtime_put_autosuspend(bdi->dev);
673
674 if (ret)
675 return ret;
676
677 bdi->otg_vbus_enabled = (val == BQ24296_REG_POC_OTG_CONFIG_OTG);
678
679 return bdi->otg_vbus_enabled;
680 }
681
682 static const struct regulator_ops bq24190_vbus_ops = {
683 .enable = bq24190_vbus_enable,
684 .disable = bq24190_vbus_disable,
685 .is_enabled = bq24190_vbus_is_enabled,
686 };
687
688 static const struct regulator_desc bq24190_vbus_desc = {
689 .name = "usb_otg_vbus",
690 .of_match = "usb-otg-vbus",
691 .type = REGULATOR_VOLTAGE,
692 .owner = THIS_MODULE,
693 .ops = &bq24190_vbus_ops,
694 .fixed_uV = 5000000,
695 .n_voltages = 1,
696 };
697
698 static const struct regulator_ops bq24296_vbus_ops = {
699 .enable = bq24296_vbus_enable,
700 .disable = bq24296_vbus_disable,
701 .is_enabled = bq24296_vbus_is_enabled,
702 };
703
704 static const struct regulator_desc bq24296_vbus_desc = {
705 .name = "usb_otg_vbus",
706 .of_match = "usb-otg-vbus",
707 .type = REGULATOR_VOLTAGE,
708 .owner = THIS_MODULE,
709 .ops = &bq24296_vbus_ops,
710 .fixed_uV = 5000000,
711 .n_voltages = 1,
712 };
713
714 static const struct regulator_init_data bq24190_vbus_init_data = {
715 .constraints = {
716 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
717 },
718 };
719
bq24190_register_vbus_regulator(struct bq24190_dev_info * bdi)720 static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
721 {
722 struct bq24190_platform_data *pdata = bdi->dev->platform_data;
723 struct regulator_config cfg = { };
724 struct regulator_dev *reg;
725 int ret = 0;
726
727 cfg.dev = bdi->dev;
728 if (pdata && pdata->regulator_init_data)
729 cfg.init_data = pdata->regulator_init_data;
730 else
731 cfg.init_data = &bq24190_vbus_init_data;
732 cfg.driver_data = bdi;
733 reg = devm_regulator_register(bdi->dev, bdi->info->vbus_desc, &cfg);
734 if (IS_ERR(reg)) {
735 ret = PTR_ERR(reg);
736 dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
737 }
738
739 return ret;
740 }
741 #else
bq24190_register_vbus_regulator(struct bq24190_dev_info * bdi)742 static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
743 {
744 return 0;
745 }
746 #endif
747
bq24190_set_config(struct bq24190_dev_info * bdi)748 static int bq24190_set_config(struct bq24190_dev_info *bdi)
749 {
750 int ret;
751 u8 v;
752
753 /*
754 * According to the "Host Mode and default Mode" section of the
755 * manual, a write to any register causes the bq24190 to switch
756 * from default mode to host mode. It will switch back to default
757 * mode after a WDT timeout unless the WDT is turned off as well.
758 * So, by simply turning off the WDT, we accomplish both with the
759 * same write.
760 */
761 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
762 BQ24190_REG_CTTC_WATCHDOG_MASK,
763 BQ24190_REG_CTTC_WATCHDOG_SHIFT, 0);
764 if (ret < 0)
765 return ret;
766
767 if (bdi->sys_min) {
768 v = bdi->sys_min / 100 - 30; // manual section 9.5.1.2, table 9
769 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
770 BQ24190_REG_POC_SYS_MIN_MASK,
771 BQ24190_REG_POC_SYS_MIN_SHIFT,
772 v);
773 if (ret < 0)
774 return ret;
775 }
776
777 if (bdi->iprechg) {
778 v = bdi->iprechg / 128 - 1; // manual section 9.5.1.4, table 11
779 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
780 BQ24190_REG_PCTCC_IPRECHG_MASK,
781 BQ24190_REG_PCTCC_IPRECHG_SHIFT,
782 v);
783 if (ret < 0)
784 return ret;
785 }
786
787 if (bdi->iterm) {
788 v = bdi->iterm / 128 - 1; // manual section 9.5.1.4, table 11
789 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
790 BQ24190_REG_PCTCC_ITERM_MASK,
791 BQ24190_REG_PCTCC_ITERM_SHIFT,
792 v);
793 if (ret < 0)
794 return ret;
795 }
796
797 if (bdi->ichg) {
798 ret = bq24190_set_field_val(bdi, BQ24190_REG_CCC,
799 BQ24190_REG_CCC_ICHG_MASK,
800 BQ24190_REG_CCC_ICHG_SHIFT,
801 bq24190_ccc_ichg_values,
802 bdi->info->ichg_array_size,
803 bdi->ichg);
804 if (ret < 0)
805 return ret;
806 }
807
808 if (bdi->vreg) {
809 ret = bq24190_set_field_val(bdi, BQ24190_REG_CVC,
810 BQ24190_REG_CVC_VREG_MASK,
811 BQ24190_REG_CVC_VREG_SHIFT,
812 bq24190_cvc_vreg_values,
813 ARRAY_SIZE(bq24190_cvc_vreg_values),
814 bdi->vreg);
815 if (ret < 0)
816 return ret;
817 }
818
819 return 0;
820 }
821
bq24190_register_reset(struct bq24190_dev_info * bdi)822 static int bq24190_register_reset(struct bq24190_dev_info *bdi)
823 {
824 int ret, limit = 100;
825 u8 v;
826
827 /*
828 * This prop. can be passed on device instantiation from platform code:
829 * struct property_entry pe[] =
830 * { PROPERTY_ENTRY_BOOL("disable-reset"), ... };
831 * struct i2c_board_info bi =
832 * { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
833 * struct i2c_adapter ad = { ... };
834 * i2c_add_adapter(&ad);
835 * i2c_new_client_device(&ad, &bi);
836 */
837 if (device_property_read_bool(bdi->dev, "disable-reset"))
838 return 0;
839
840 /* Reset the registers */
841 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
842 BQ24190_REG_POC_RESET_MASK,
843 BQ24190_REG_POC_RESET_SHIFT,
844 0x1);
845 if (ret < 0)
846 return ret;
847
848 /* Reset bit will be cleared by hardware so poll until it is */
849 do {
850 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
851 BQ24190_REG_POC_RESET_MASK,
852 BQ24190_REG_POC_RESET_SHIFT,
853 &v);
854 if (ret < 0)
855 return ret;
856
857 if (v == 0)
858 return 0;
859
860 usleep_range(100, 200);
861 } while (--limit);
862
863 return -EIO;
864 }
865
866 /* Charger power supply property routines */
867
bq24190_charger_get_charge_type(struct bq24190_dev_info * bdi,union power_supply_propval * val)868 static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
869 union power_supply_propval *val)
870 {
871 u8 v;
872 int type, ret;
873
874 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
875 BQ24190_REG_POC_CHG_CONFIG_MASK,
876 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
877 &v);
878 if (ret < 0)
879 return ret;
880
881 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
882 if (!v) {
883 type = POWER_SUPPLY_CHARGE_TYPE_NONE;
884 } else {
885 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
886 BQ24190_REG_CCC_FORCE_20PCT_MASK,
887 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
888 &v);
889 if (ret < 0)
890 return ret;
891
892 type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
893 POWER_SUPPLY_CHARGE_TYPE_FAST;
894 }
895
896 val->intval = type;
897
898 return 0;
899 }
900
bq24190_battery_set_chg_config(struct bq24190_dev_info * bdi,const u8 chg_config)901 static int bq24190_battery_set_chg_config(struct bq24190_dev_info *bdi,
902 const u8 chg_config)
903 {
904 return bq24190_write_mask(bdi, BQ24190_REG_POC,
905 BQ24190_REG_POC_CHG_CONFIG_MASK,
906 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
907 chg_config);
908 }
909
bq24296_battery_set_chg_config(struct bq24190_dev_info * bdi,const u8 chg_config)910 static int bq24296_battery_set_chg_config(struct bq24190_dev_info *bdi,
911 const u8 chg_config)
912 {
913 return bq24190_write_mask(bdi, BQ24190_REG_POC,
914 BQ24296_REG_POC_CHG_CONFIG_MASK,
915 BQ24296_REG_POC_CHG_CONFIG_SHIFT,
916 chg_config);
917 }
918
bq24190_charger_set_charge_type(struct bq24190_dev_info * bdi,const union power_supply_propval * val)919 static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
920 const union power_supply_propval *val)
921 {
922 u8 chg_config, force_20pct, en_term;
923 int ret;
924
925 /*
926 * According to the "Termination when REG02[0] = 1" section of
927 * the bq24190 manual, the trickle charge could be less than the
928 * termination current so it recommends turning off the termination
929 * function.
930 *
931 * Note: AFAICT from the datasheet, the user will have to manually
932 * turn off the charging when in 20% mode. If its not turned off,
933 * there could be battery damage. So, use this mode at your own risk.
934 */
935 switch (val->intval) {
936 case POWER_SUPPLY_CHARGE_TYPE_NONE:
937 chg_config = 0x0;
938 break;
939 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
940 chg_config = 0x1;
941 force_20pct = 0x1;
942 en_term = 0x0;
943 break;
944 case POWER_SUPPLY_CHARGE_TYPE_FAST:
945 chg_config = 0x1;
946 force_20pct = 0x0;
947 en_term = 0x1;
948 break;
949 default:
950 return -EINVAL;
951 }
952
953 bdi->charge_type = val->intval;
954 /*
955 * If the 5V Vbus boost regulator is enabled delay setting
956 * the charge-type until its gets disabled.
957 */
958 if (bdi->otg_vbus_enabled)
959 return 0;
960
961 if (chg_config) { /* Enabling the charger */
962 ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
963 BQ24190_REG_CCC_FORCE_20PCT_MASK,
964 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
965 force_20pct);
966 if (ret < 0)
967 return ret;
968
969 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
970 BQ24190_REG_CTTC_EN_TERM_MASK,
971 BQ24190_REG_CTTC_EN_TERM_SHIFT,
972 en_term);
973 if (ret < 0)
974 return ret;
975 }
976
977 return bdi->info->set_chg_config(bdi, chg_config);
978 }
979
bq24190_charger_get_ntc_status(u8 value)980 static int bq24190_charger_get_ntc_status(u8 value)
981 {
982 int health;
983
984 switch (value >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
985 case 0x1: /* TS1 Cold */
986 case 0x3: /* TS2 Cold */
987 case 0x5: /* Both Cold */
988 health = POWER_SUPPLY_HEALTH_COLD;
989 break;
990 case 0x2: /* TS1 Hot */
991 case 0x4: /* TS2 Hot */
992 case 0x6: /* Both Hot */
993 health = POWER_SUPPLY_HEALTH_OVERHEAT;
994 break;
995 default:
996 health = POWER_SUPPLY_HEALTH_UNKNOWN;
997 }
998
999 return health;
1000 }
1001
bq24296_charger_get_ntc_status(u8 value)1002 static int bq24296_charger_get_ntc_status(u8 value)
1003 {
1004 int health;
1005
1006 switch (value >> BQ24296_REG_F_NTC_FAULT_SHIFT & 0x3) {
1007 case 0x0: /* Normal */
1008 health = POWER_SUPPLY_HEALTH_GOOD;
1009 break;
1010 case 0x1: /* Hot */
1011 health = POWER_SUPPLY_HEALTH_OVERHEAT;
1012 break;
1013 case 0x2: /* Cold */
1014 health = POWER_SUPPLY_HEALTH_COLD;
1015 break;
1016 default:
1017 health = POWER_SUPPLY_HEALTH_UNKNOWN;
1018 }
1019
1020 return health;
1021 }
1022
bq24190_charger_get_health(struct bq24190_dev_info * bdi,union power_supply_propval * val)1023 static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
1024 union power_supply_propval *val)
1025 {
1026 u8 v;
1027 int health;
1028
1029 mutex_lock(&bdi->f_reg_lock);
1030 v = bdi->f_reg;
1031 mutex_unlock(&bdi->f_reg_lock);
1032
1033 if (v & bdi->info->ntc_fault_mask) {
1034 health = bdi->info->get_ntc_status(v);
1035 } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1036 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1037 } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
1038 switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
1039 case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
1040 /*
1041 * This could be over-voltage or under-voltage
1042 * and there's no way to tell which. Instead
1043 * of looking foolish and returning 'OVERVOLTAGE'
1044 * when its really under-voltage, just return
1045 * 'UNSPEC_FAILURE'.
1046 */
1047 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
1048 break;
1049 case 0x2: /* Thermal Shutdown */
1050 health = POWER_SUPPLY_HEALTH_OVERHEAT;
1051 break;
1052 case 0x3: /* Charge Safety Timer Expiration */
1053 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
1054 break;
1055 default: /* prevent compiler warning */
1056 health = -1;
1057 }
1058 } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
1059 /*
1060 * This could be over-current or over-voltage but there's
1061 * no way to tell which. Return 'OVERVOLTAGE' since there
1062 * isn't an 'OVERCURRENT' value defined that we can return
1063 * even if it was over-current.
1064 */
1065 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1066 } else {
1067 health = POWER_SUPPLY_HEALTH_GOOD;
1068 }
1069
1070 val->intval = health;
1071
1072 return 0;
1073 }
1074
bq24190_charger_get_online(struct bq24190_dev_info * bdi,union power_supply_propval * val)1075 static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
1076 union power_supply_propval *val)
1077 {
1078 u8 pg_stat, batfet_disable;
1079 int ret;
1080
1081 ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
1082 BQ24190_REG_SS_PG_STAT_MASK,
1083 BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
1084 if (ret < 0)
1085 return ret;
1086
1087 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1088 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1089 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1090 if (ret < 0)
1091 return ret;
1092
1093 val->intval = pg_stat && !batfet_disable;
1094
1095 return 0;
1096 }
1097
1098 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1099 const union power_supply_propval *val);
1100 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1101 union power_supply_propval *val);
1102 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1103 union power_supply_propval *val);
1104 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1105 const union power_supply_propval *val);
1106
bq24190_charger_set_online(struct bq24190_dev_info * bdi,const union power_supply_propval * val)1107 static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
1108 const union power_supply_propval *val)
1109 {
1110 return bq24190_battery_set_online(bdi, val);
1111 }
1112
bq24190_charger_get_status(struct bq24190_dev_info * bdi,union power_supply_propval * val)1113 static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
1114 union power_supply_propval *val)
1115 {
1116 return bq24190_battery_get_status(bdi, val);
1117 }
1118
bq24190_charger_get_temp_alert_max(struct bq24190_dev_info * bdi,union power_supply_propval * val)1119 static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
1120 union power_supply_propval *val)
1121 {
1122 return bq24190_battery_get_temp_alert_max(bdi, val);
1123 }
1124
bq24190_charger_set_temp_alert_max(struct bq24190_dev_info * bdi,const union power_supply_propval * val)1125 static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
1126 const union power_supply_propval *val)
1127 {
1128 return bq24190_battery_set_temp_alert_max(bdi, val);
1129 }
1130
bq24190_charger_get_precharge(struct bq24190_dev_info * bdi,union power_supply_propval * val)1131 static int bq24190_charger_get_precharge(struct bq24190_dev_info *bdi,
1132 union power_supply_propval *val)
1133 {
1134 u8 v;
1135 int curr, ret;
1136
1137 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
1138 BQ24190_REG_PCTCC_IPRECHG_MASK,
1139 BQ24190_REG_PCTCC_IPRECHG_SHIFT, &v);
1140 if (ret < 0)
1141 return ret;
1142
1143 curr = ++v * 128 * 1000;
1144
1145 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1146 BQ24190_REG_CCC_FORCE_20PCT_MASK,
1147 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1148 if (ret < 0)
1149 return ret;
1150
1151 /* If FORCE_20PCT is enabled, then current is 50% of IPRECHG value */
1152 if (v)
1153 curr /= 2;
1154
1155 val->intval = curr;
1156
1157 return 0;
1158 }
1159
bq24190_charger_get_charge_term(struct bq24190_dev_info * bdi,union power_supply_propval * val)1160 static int bq24190_charger_get_charge_term(struct bq24190_dev_info *bdi,
1161 union power_supply_propval *val)
1162 {
1163 u8 v;
1164 int ret;
1165
1166 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
1167 BQ24190_REG_PCTCC_ITERM_MASK,
1168 BQ24190_REG_PCTCC_ITERM_SHIFT, &v);
1169 if (ret < 0)
1170 return ret;
1171
1172 val->intval = ++v * 128 * 1000;
1173 return 0;
1174 }
1175
bq24190_charger_get_current(struct bq24190_dev_info * bdi,union power_supply_propval * val)1176 static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
1177 union power_supply_propval *val)
1178 {
1179 u8 v;
1180 int curr, ret;
1181
1182 ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
1183 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1184 bq24190_ccc_ichg_values,
1185 bdi->info->ichg_array_size, &curr);
1186 if (ret < 0)
1187 return ret;
1188
1189 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1190 BQ24190_REG_CCC_FORCE_20PCT_MASK,
1191 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1192 if (ret < 0)
1193 return ret;
1194
1195 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
1196 if (v)
1197 curr /= 5;
1198
1199 val->intval = curr;
1200 return 0;
1201 }
1202
bq24190_charger_set_current(struct bq24190_dev_info * bdi,const union power_supply_propval * val)1203 static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
1204 const union power_supply_propval *val)
1205 {
1206 u8 v;
1207 int ret, curr = val->intval;
1208
1209 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1210 BQ24190_REG_CCC_FORCE_20PCT_MASK,
1211 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1212 if (ret < 0)
1213 return ret;
1214
1215 /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
1216 if (v)
1217 curr *= 5;
1218
1219 if (curr > bdi->ichg_max)
1220 return -EINVAL;
1221
1222 ret = bq24190_set_field_val(bdi, BQ24190_REG_CCC,
1223 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1224 bq24190_ccc_ichg_values,
1225 bdi->info->ichg_array_size, curr);
1226 if (ret < 0)
1227 return ret;
1228
1229 bdi->ichg = curr;
1230
1231 return 0;
1232 }
1233
bq24190_charger_get_voltage(struct bq24190_dev_info * bdi,union power_supply_propval * val)1234 static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
1235 union power_supply_propval *val)
1236 {
1237 int voltage, ret;
1238
1239 ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
1240 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1241 bq24190_cvc_vreg_values,
1242 ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
1243 if (ret < 0)
1244 return ret;
1245
1246 val->intval = voltage;
1247 return 0;
1248 }
1249
bq24190_charger_set_voltage(struct bq24190_dev_info * bdi,const union power_supply_propval * val)1250 static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
1251 const union power_supply_propval *val)
1252 {
1253 int ret;
1254
1255 if (val->intval > bdi->vreg_max)
1256 return -EINVAL;
1257
1258 ret = bq24190_set_field_val(bdi, BQ24190_REG_CVC,
1259 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1260 bq24190_cvc_vreg_values,
1261 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
1262 if (ret < 0)
1263 return ret;
1264
1265 bdi->vreg = val->intval;
1266
1267 return 0;
1268 }
1269
bq24190_charger_get_iinlimit(struct bq24190_dev_info * bdi,union power_supply_propval * val)1270 static int bq24190_charger_get_iinlimit(struct bq24190_dev_info *bdi,
1271 union power_supply_propval *val)
1272 {
1273 int iinlimit, ret;
1274
1275 ret = bq24190_get_field_val(bdi, BQ24190_REG_ISC,
1276 BQ24190_REG_ISC_IINLIM_MASK,
1277 BQ24190_REG_ISC_IINLIM_SHIFT,
1278 bq24190_isc_iinlim_values,
1279 ARRAY_SIZE(bq24190_isc_iinlim_values), &iinlimit);
1280 if (ret < 0)
1281 return ret;
1282
1283 val->intval = iinlimit;
1284 return 0;
1285 }
1286
bq24190_charger_set_iinlimit(struct bq24190_dev_info * bdi,const union power_supply_propval * val)1287 static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi,
1288 const union power_supply_propval *val)
1289 {
1290 return bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1291 BQ24190_REG_ISC_IINLIM_MASK,
1292 BQ24190_REG_ISC_IINLIM_SHIFT,
1293 bq24190_isc_iinlim_values,
1294 ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval);
1295 }
1296
bq24190_charger_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)1297 static int bq24190_charger_get_property(struct power_supply *psy,
1298 enum power_supply_property psp, union power_supply_propval *val)
1299 {
1300 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1301 int ret;
1302
1303 dev_dbg(bdi->dev, "prop: %d\n", psp);
1304
1305 ret = pm_runtime_resume_and_get(bdi->dev);
1306 if (ret < 0)
1307 return ret;
1308
1309 switch (psp) {
1310 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1311 case POWER_SUPPLY_PROP_CHARGE_TYPES:
1312 ret = bq24190_charger_get_charge_type(bdi, val);
1313 break;
1314 case POWER_SUPPLY_PROP_HEALTH:
1315 ret = bq24190_charger_get_health(bdi, val);
1316 break;
1317 case POWER_SUPPLY_PROP_ONLINE:
1318 ret = bq24190_charger_get_online(bdi, val);
1319 break;
1320 case POWER_SUPPLY_PROP_STATUS:
1321 ret = bq24190_charger_get_status(bdi, val);
1322 break;
1323 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1324 ret = bq24190_charger_get_temp_alert_max(bdi, val);
1325 break;
1326 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
1327 ret = bq24190_charger_get_precharge(bdi, val);
1328 break;
1329 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
1330 ret = bq24190_charger_get_charge_term(bdi, val);
1331 break;
1332 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1333 ret = bq24190_charger_get_current(bdi, val);
1334 break;
1335 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
1336 val->intval = bdi->ichg_max;
1337 ret = 0;
1338 break;
1339 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1340 ret = bq24190_charger_get_voltage(bdi, val);
1341 break;
1342 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
1343 val->intval = bdi->vreg_max;
1344 ret = 0;
1345 break;
1346 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1347 ret = bq24190_charger_get_iinlimit(bdi, val);
1348 break;
1349 case POWER_SUPPLY_PROP_SCOPE:
1350 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1351 ret = 0;
1352 break;
1353 case POWER_SUPPLY_PROP_MODEL_NAME:
1354 val->strval = bdi->model_name;
1355 ret = 0;
1356 break;
1357 case POWER_SUPPLY_PROP_MANUFACTURER:
1358 val->strval = BQ24190_MANUFACTURER;
1359 ret = 0;
1360 break;
1361 default:
1362 ret = -ENODATA;
1363 }
1364
1365 pm_runtime_put_autosuspend(bdi->dev);
1366
1367 return ret;
1368 }
1369
bq24190_charger_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)1370 static int bq24190_charger_set_property(struct power_supply *psy,
1371 enum power_supply_property psp,
1372 const union power_supply_propval *val)
1373 {
1374 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1375 int ret;
1376
1377 dev_dbg(bdi->dev, "prop: %d\n", psp);
1378
1379 ret = pm_runtime_resume_and_get(bdi->dev);
1380 if (ret < 0)
1381 return ret;
1382
1383 switch (psp) {
1384 case POWER_SUPPLY_PROP_ONLINE:
1385 ret = bq24190_charger_set_online(bdi, val);
1386 break;
1387 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1388 ret = bq24190_charger_set_temp_alert_max(bdi, val);
1389 break;
1390 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1391 case POWER_SUPPLY_PROP_CHARGE_TYPES:
1392 ret = bq24190_charger_set_charge_type(bdi, val);
1393 break;
1394 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1395 ret = bq24190_charger_set_current(bdi, val);
1396 break;
1397 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1398 ret = bq24190_charger_set_voltage(bdi, val);
1399 break;
1400 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1401 ret = bq24190_charger_set_iinlimit(bdi, val);
1402 break;
1403 default:
1404 ret = -EINVAL;
1405 }
1406
1407 pm_runtime_put_autosuspend(bdi->dev);
1408
1409 return ret;
1410 }
1411
bq24190_charger_property_is_writeable(struct power_supply * psy,enum power_supply_property psp)1412 static int bq24190_charger_property_is_writeable(struct power_supply *psy,
1413 enum power_supply_property psp)
1414 {
1415 switch (psp) {
1416 case POWER_SUPPLY_PROP_ONLINE:
1417 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1418 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1419 case POWER_SUPPLY_PROP_CHARGE_TYPES:
1420 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1421 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1422 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1423 return 1;
1424 default:
1425 return 0;
1426 }
1427 }
1428
bq24190_input_current_limit_work(struct work_struct * work)1429 static void bq24190_input_current_limit_work(struct work_struct *work)
1430 {
1431 struct bq24190_dev_info *bdi =
1432 container_of(work, struct bq24190_dev_info,
1433 input_current_limit_work.work);
1434 union power_supply_propval val;
1435 int ret;
1436
1437 ret = power_supply_get_property_from_supplier(bdi->charger,
1438 POWER_SUPPLY_PROP_CURRENT_MAX,
1439 &val);
1440 if (ret)
1441 return;
1442
1443 bq24190_charger_set_property(bdi->charger,
1444 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1445 &val);
1446 power_supply_changed(bdi->charger);
1447 }
1448
1449 /* Sync the input-current-limit with our parent supply (if we have one) */
bq24190_charger_external_power_changed(struct power_supply * psy)1450 static void bq24190_charger_external_power_changed(struct power_supply *psy)
1451 {
1452 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1453
1454 /*
1455 * The Power-Good detection may take up to 220ms, sometimes
1456 * the external charger detection is quicker, and the bq24190 will
1457 * reset to iinlim based on its own charger detection (which is not
1458 * hooked up when using external charger detection) resulting in a
1459 * too low default 500mA iinlim. Delay setting the input-current-limit
1460 * for 300ms to avoid this.
1461 */
1462 queue_delayed_work(system_percpu_wq, &bdi->input_current_limit_work,
1463 msecs_to_jiffies(300));
1464 }
1465
1466 static enum power_supply_property bq24190_charger_properties[] = {
1467 POWER_SUPPLY_PROP_CHARGE_TYPE,
1468 POWER_SUPPLY_PROP_CHARGE_TYPES,
1469 POWER_SUPPLY_PROP_HEALTH,
1470 POWER_SUPPLY_PROP_ONLINE,
1471 POWER_SUPPLY_PROP_STATUS,
1472 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1473 POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
1474 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
1475 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
1476 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
1477 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
1478 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
1479 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1480 POWER_SUPPLY_PROP_SCOPE,
1481 POWER_SUPPLY_PROP_MODEL_NAME,
1482 POWER_SUPPLY_PROP_MANUFACTURER,
1483 };
1484
1485 static char *bq24190_charger_supplied_to[] = {
1486 "main-battery",
1487 };
1488
1489 static const struct power_supply_desc bq24190_charger_desc = {
1490 .name = "bq24190-charger",
1491 .type = POWER_SUPPLY_TYPE_USB,
1492 .properties = bq24190_charger_properties,
1493 .num_properties = ARRAY_SIZE(bq24190_charger_properties),
1494 .get_property = bq24190_charger_get_property,
1495 .set_property = bq24190_charger_set_property,
1496 .property_is_writeable = bq24190_charger_property_is_writeable,
1497 .external_power_changed = bq24190_charger_external_power_changed,
1498 .charge_types = BIT(POWER_SUPPLY_CHARGE_TYPE_NONE) |
1499 BIT(POWER_SUPPLY_CHARGE_TYPE_TRICKLE) |
1500 BIT(POWER_SUPPLY_CHARGE_TYPE_FAST),
1501 };
1502
1503 /* Battery power supply property routines */
1504
bq24190_battery_get_status(struct bq24190_dev_info * bdi,union power_supply_propval * val)1505 static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1506 union power_supply_propval *val)
1507 {
1508 u8 ss_reg, chrg_fault;
1509 int status, ret;
1510
1511 mutex_lock(&bdi->f_reg_lock);
1512 chrg_fault = bdi->f_reg;
1513 mutex_unlock(&bdi->f_reg_lock);
1514
1515 chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
1516 chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
1517
1518 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1519 if (ret < 0)
1520 return ret;
1521
1522 /*
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.
1528 */
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;
1534
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;
1548 }
1549 }
1550
1551 if (!ret)
1552 val->intval = status;
1553
1554 return ret;
1555 }
1556
bq24190_battery_get_health(struct bq24190_dev_info * bdi,union power_supply_propval * val)1557 static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1558 union power_supply_propval *val)
1559 {
1560 u8 v;
1561 int health;
1562
1563 mutex_lock(&bdi->f_reg_lock);
1564 v = bdi->f_reg;
1565 mutex_unlock(&bdi->f_reg_lock);
1566
1567 if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1568 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1569 } else {
1570 v &= bdi->info->ntc_fault_mask;
1571
1572 health = v ? bdi->info->get_ntc_status(v) : POWER_SUPPLY_HEALTH_GOOD;
1573 }
1574
1575 val->intval = health;
1576 return 0;
1577 }
1578
bq24190_battery_get_online(struct bq24190_dev_info * bdi,union power_supply_propval * val)1579 static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1580 union power_supply_propval *val)
1581 {
1582 u8 batfet_disable;
1583 int ret;
1584
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;
1590
1591 val->intval = !batfet_disable;
1592 return 0;
1593 }
1594
bq24190_battery_set_online(struct bq24190_dev_info * bdi,const union power_supply_propval * val)1595 static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1596 const union power_supply_propval *val)
1597 {
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);
1601 }
1602
bq24190_battery_get_temp_alert_max(struct bq24190_dev_info * bdi,union power_supply_propval * val)1603 static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1604 union power_supply_propval *val)
1605 {
1606 int temp, ret;
1607
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;
1615
1616 val->intval = temp;
1617 return 0;
1618 }
1619
bq24190_battery_set_temp_alert_max(struct bq24190_dev_info * bdi,const union power_supply_propval * val)1620 static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1621 const union power_supply_propval *val)
1622 {
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);
1628 }
1629
bq24190_battery_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)1630 static int bq24190_battery_get_property(struct power_supply *psy,
1631 enum power_supply_property psp, union power_supply_propval *val)
1632 {
1633 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1634 int ret;
1635
1636 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1637 dev_dbg(bdi->dev, "prop: %d\n", psp);
1638
1639 ret = pm_runtime_resume_and_get(bdi->dev);
1640 if (ret < 0)
1641 return ret;
1642
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;
1667 }
1668
1669 pm_runtime_put_autosuspend(bdi->dev);
1670
1671 return ret;
1672 }
1673
bq24190_battery_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)1674 static int bq24190_battery_set_property(struct power_supply *psy,
1675 enum power_supply_property psp,
1676 const union power_supply_propval *val)
1677 {
1678 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1679 int ret;
1680
1681 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1682 dev_dbg(bdi->dev, "prop: %d\n", psp);
1683
1684 ret = pm_runtime_resume_and_get(bdi->dev);
1685 if (ret < 0)
1686 return ret;
1687
1688 switch (psp) {
1689 case POWER_SUPPLY_PROP_ONLINE:
1690 ret = bq24190_battery_set_online(bdi, val);
1691 break;
1692 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1693 ret = bq24190_battery_set_temp_alert_max(bdi, val);
1694 break;
1695 default:
1696 ret = -EINVAL;
1697 }
1698
1699 pm_runtime_put_autosuspend(bdi->dev);
1700
1701 return ret;
1702 }
1703
bq24190_battery_property_is_writeable(struct power_supply * psy,enum power_supply_property psp)1704 static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1705 enum power_supply_property psp)
1706 {
1707 int ret;
1708
1709 switch (psp) {
1710 case POWER_SUPPLY_PROP_ONLINE:
1711 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1712 ret = 1;
1713 break;
1714 default:
1715 ret = 0;
1716 }
1717
1718 return ret;
1719 }
1720
1721 static enum power_supply_property bq24190_battery_properties[] = {
1722 POWER_SUPPLY_PROP_STATUS,
1723 POWER_SUPPLY_PROP_HEALTH,
1724 POWER_SUPPLY_PROP_ONLINE,
1725 POWER_SUPPLY_PROP_TECHNOLOGY,
1726 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1727 POWER_SUPPLY_PROP_SCOPE,
1728 };
1729
1730 static const struct power_supply_desc bq24190_battery_desc = {
1731 .name = "bq24190-battery",
1732 .type = POWER_SUPPLY_TYPE_BATTERY,
1733 .properties = bq24190_battery_properties,
1734 .num_properties = ARRAY_SIZE(bq24190_battery_properties),
1735 .get_property = bq24190_battery_get_property,
1736 .set_property = bq24190_battery_set_property,
1737 .property_is_writeable = bq24190_battery_property_is_writeable,
1738 };
1739
bq24190_configure_usb_otg(struct bq24190_dev_info * bdi,u8 ss_reg)1740 static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
1741 {
1742 bool otg_enabled;
1743 int ret;
1744
1745 otg_enabled = !!(ss_reg & BQ24190_REG_SS_VBUS_STAT_MASK);
1746 ret = extcon_set_state_sync(bdi->edev, EXTCON_USB, otg_enabled);
1747 if (ret < 0)
1748 dev_err(bdi->dev, "Can't set extcon state to %d: %d\n",
1749 otg_enabled, ret);
1750
1751 return ret;
1752 }
1753
bq24190_check_status(struct bq24190_dev_info * bdi)1754 static void bq24190_check_status(struct bq24190_dev_info *bdi)
1755 {
1756 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1757 u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK;
1758 bool alert_charger = false, alert_battery = false;
1759 u8 ss_reg = 0, f_reg = 0;
1760 int i, ret;
1761
1762 battery_mask_f |= bdi->info->ntc_fault_mask;
1763
1764 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1765 if (ret < 0) {
1766 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1767 return;
1768 }
1769
1770 i = 0;
1771 do {
1772 ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1773 if (ret < 0) {
1774 dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1775 return;
1776 }
1777 } while (f_reg && ++i < 2);
1778
1779 /* ignore over/under voltage fault after disconnect */
1780 if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1781 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1782 f_reg = 0;
1783
1784 if (f_reg != bdi->f_reg) {
1785 dev_warn(bdi->dev,
1786 "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1787 !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1788 !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1789 !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1790 !!(f_reg & bdi->info->ntc_fault_mask));
1791
1792 mutex_lock(&bdi->f_reg_lock);
1793 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1794 alert_battery = true;
1795 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1796 alert_charger = true;
1797 bdi->f_reg = f_reg;
1798 mutex_unlock(&bdi->f_reg_lock);
1799 }
1800
1801 if (ss_reg != bdi->ss_reg) {
1802 /*
1803 * The device is in host mode so when PG_STAT goes from 1->0
1804 * (i.e., power removed) HIZ needs to be disabled.
1805 */
1806 if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1807 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1808 ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1809 BQ24190_REG_ISC_EN_HIZ_MASK,
1810 BQ24190_REG_ISC_EN_HIZ_SHIFT,
1811 0);
1812 if (ret < 0)
1813 dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1814 ret);
1815 }
1816
1817 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1818 alert_battery = true;
1819 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1820 alert_charger = true;
1821 bdi->ss_reg = ss_reg;
1822 }
1823
1824 if (alert_charger || alert_battery) {
1825 power_supply_changed(bdi->charger);
1826 bq24190_configure_usb_otg(bdi, ss_reg);
1827 }
1828 if (alert_battery && bdi->battery)
1829 power_supply_changed(bdi->battery);
1830
1831 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1832 }
1833
bq24190_irq_handler_thread(int irq,void * data)1834 static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1835 {
1836 struct bq24190_dev_info *bdi = data;
1837 int error;
1838
1839 bdi->irq_event = true;
1840 error = pm_runtime_resume_and_get(bdi->dev);
1841 if (error < 0) {
1842 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1843 return IRQ_NONE;
1844 }
1845 bq24190_check_status(bdi);
1846 pm_runtime_put_autosuspend(bdi->dev);
1847 bdi->irq_event = false;
1848
1849 return IRQ_HANDLED;
1850 }
1851
bq24190_check_chip(struct bq24190_dev_info * bdi)1852 static int bq24190_check_chip(struct bq24190_dev_info *bdi)
1853 {
1854 u8 v;
1855 int ret;
1856
1857 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1858 BQ24190_REG_VPRS_PN_MASK,
1859 BQ24190_REG_VPRS_PN_SHIFT,
1860 &v);
1861 if (ret < 0)
1862 return ret;
1863
1864 switch (v) {
1865 case BQ24190_REG_VPRS_PN_24190:
1866 case BQ24190_REG_VPRS_PN_24192:
1867 case BQ24190_REG_VPRS_PN_24192I:
1868 break;
1869 default:
1870 dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1871 return -ENODEV;
1872 }
1873
1874 return 0;
1875 }
1876
bq24296_check_chip(struct bq24190_dev_info * bdi)1877 static int bq24296_check_chip(struct bq24190_dev_info *bdi)
1878 {
1879 u8 v;
1880 int ret;
1881
1882 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1883 BQ24296_REG_VPRS_PN_MASK,
1884 BQ24296_REG_VPRS_PN_SHIFT,
1885 &v);
1886 if (ret < 0)
1887 return ret;
1888
1889 switch (v) {
1890 case BQ24296_REG_VPRS_PN_24296:
1891 case BQ24296_REG_VPRS_PN_24297:
1892 break;
1893 default:
1894 dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1895 return -ENODEV;
1896 }
1897
1898 return 0;
1899 }
1900
bq24190_hw_init(struct bq24190_dev_info * bdi)1901 static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1902 {
1903 int ret;
1904
1905 ret = bdi->info->check_chip(bdi);
1906 if (ret < 0)
1907 return ret;
1908
1909 ret = bq24190_register_reset(bdi);
1910 if (ret < 0)
1911 return ret;
1912
1913 ret = bq24190_set_config(bdi);
1914 if (ret < 0)
1915 return ret;
1916
1917 return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1918 }
1919
bq24190_get_config(struct bq24190_dev_info * bdi)1920 static int bq24190_get_config(struct bq24190_dev_info *bdi)
1921 {
1922 const char * const s = "ti,system-minimum-microvolt";
1923 struct power_supply_battery_info *info;
1924 int v, idx;
1925
1926 idx = bdi->info->ichg_array_size - 1;
1927
1928 bdi->ichg_max = bq24190_ccc_ichg_values[idx];
1929
1930 idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
1931 bdi->vreg_max = bq24190_cvc_vreg_values[idx];
1932
1933 if (device_property_read_u32(bdi->dev, s, &v) == 0) {
1934 v /= 1000;
1935 if (v >= BQ24190_REG_POC_SYS_MIN_MIN
1936 && v <= BQ24190_REG_POC_SYS_MIN_MAX)
1937 bdi->sys_min = v;
1938 else
1939 dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v);
1940 }
1941
1942 if (!power_supply_get_battery_info(bdi->charger, &info)) {
1943 v = info->precharge_current_ua / 1000;
1944 if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
1945 && v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
1946 bdi->iprechg = v;
1947 else
1948 dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
1949 v);
1950
1951 v = info->charge_term_current_ua / 1000;
1952 if (v >= BQ24190_REG_PCTCC_ITERM_MIN
1953 && v <= BQ24190_REG_PCTCC_ITERM_MAX)
1954 bdi->iterm = v;
1955 else
1956 dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n",
1957 v);
1958
1959 /* These are optional, so no warning when not set */
1960 v = info->constant_charge_current_max_ua;
1961 if (v >= bq24190_ccc_ichg_values[0] && v <= bdi->ichg_max)
1962 bdi->ichg = bdi->ichg_max = v;
1963
1964 v = info->constant_charge_voltage_max_uv;
1965 if (v >= bq24190_cvc_vreg_values[0] && v <= bdi->vreg_max)
1966 bdi->vreg = bdi->vreg_max = v;
1967
1968 power_supply_put_battery_info(bdi->charger, info);
1969 }
1970
1971 return 0;
1972 }
1973
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,
1985 },
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,
1996 },
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,
2007 },
2008 [BQ24193] = {
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,
2018 },
2019 [BQ24196] = {
2020 .ichg_array_size = ARRAY_SIZE(bq24190_ccc_ichg_values),
2021 #ifdef CONFIG_REGULATOR
2022 .vbus_desc = &bq24190_vbus_desc,
2023 #endif
2024 .check_chip = bq24190_check_chip,
2025 .set_chg_config = bq24190_battery_set_chg_config,
2026 .ntc_fault_mask = BQ24190_REG_F_NTC_FAULT_MASK,
2027 .get_ntc_status = bq24190_charger_get_ntc_status,
2028 .set_otg_vbus = bq24190_set_otg_vbus,
2029 },
2030 [BQ24296] = {
2031 .ichg_array_size = BQ24296_CCC_ICHG_VALUES_LEN,
2032 #ifdef CONFIG_REGULATOR
2033 .vbus_desc = &bq24296_vbus_desc,
2034 #endif
2035 .check_chip = bq24296_check_chip,
2036 .set_chg_config = bq24296_battery_set_chg_config,
2037 .ntc_fault_mask = BQ24296_REG_F_NTC_FAULT_MASK,
2038 .get_ntc_status = bq24296_charger_get_ntc_status,
2039 .set_otg_vbus = bq24296_set_otg_vbus,
2040 },
2041 [BQ24297] = {
2042 .ichg_array_size = BQ24296_CCC_ICHG_VALUES_LEN,
2043 #ifdef CONFIG_REGULATOR
2044 .vbus_desc = &bq24296_vbus_desc,
2045 #endif
2046 .check_chip = bq24296_check_chip,
2047 .set_chg_config = bq24296_battery_set_chg_config,
2048 .ntc_fault_mask = BQ24296_REG_F_NTC_FAULT_MASK,
2049 .get_ntc_status = bq24296_charger_get_ntc_status,
2050 .set_otg_vbus = bq24296_set_otg_vbus,
2051 },
2052 };
2053
bq24190_probe(struct i2c_client * client)2054 static int bq24190_probe(struct i2c_client *client)
2055 {
2056 const struct i2c_device_id *id = i2c_client_get_device_id(client);
2057 struct i2c_adapter *adapter = client->adapter;
2058 struct device *dev = &client->dev;
2059 struct power_supply_config charger_cfg = {}, battery_cfg = {};
2060 struct bq24190_dev_info *bdi;
2061 int ret;
2062
2063 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
2064 dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
2065 return -ENODEV;
2066 }
2067
2068 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
2069 if (!bdi) {
2070 dev_err(dev, "Can't alloc bdi struct\n");
2071 return -ENOMEM;
2072 }
2073
2074 bdi->client = client;
2075 bdi->dev = dev;
2076 strscpy(bdi->model_name, id->name, sizeof(bdi->model_name));
2077 bdi->info = i2c_get_match_data(client);
2078 mutex_init(&bdi->f_reg_lock);
2079 bdi->charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
2080 bdi->f_reg = 0;
2081 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
2082
2083 ret = devm_delayed_work_autocancel(dev, &bdi->input_current_limit_work,
2084 bq24190_input_current_limit_work);
2085 if (ret)
2086 return ret;
2087
2088 i2c_set_clientdata(client, bdi);
2089
2090 if (client->irq <= 0) {
2091 dev_err(dev, "Can't get irq info\n");
2092 return -EINVAL;
2093 }
2094
2095 bdi->edev = devm_extcon_dev_allocate(dev, bq24190_usb_extcon_cable);
2096 if (IS_ERR(bdi->edev))
2097 return PTR_ERR(bdi->edev);
2098
2099 ret = devm_extcon_dev_register(dev, bdi->edev);
2100 if (ret < 0)
2101 return ret;
2102
2103 pm_runtime_enable(dev);
2104 pm_runtime_use_autosuspend(dev);
2105 pm_runtime_set_autosuspend_delay(dev, 600);
2106 ret = pm_runtime_get_sync(dev);
2107 if (ret < 0) {
2108 dev_err(dev, "pm_runtime_get failed: %i\n", ret);
2109 goto out_pmrt;
2110 }
2111
2112 #ifdef CONFIG_SYSFS
2113 bq24190_sysfs_init_attrs();
2114 charger_cfg.attr_grp = bq24190_sysfs_groups;
2115 #endif
2116
2117 charger_cfg.drv_data = bdi;
2118 charger_cfg.fwnode = dev_fwnode(dev);
2119 charger_cfg.supplied_to = bq24190_charger_supplied_to;
2120 charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to);
2121 bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
2122 &charger_cfg);
2123 if (IS_ERR(bdi->charger)) {
2124 dev_err(dev, "Can't register charger\n");
2125 ret = PTR_ERR(bdi->charger);
2126 goto out_pmrt;
2127 }
2128
2129 /* the battery class is deprecated and will be removed. */
2130 /* in the interim, this property hides it. */
2131 if (!device_property_read_bool(dev, "omit-battery-class")) {
2132 battery_cfg.drv_data = bdi;
2133 bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
2134 &battery_cfg);
2135 if (IS_ERR(bdi->battery)) {
2136 dev_err(dev, "Can't register battery\n");
2137 ret = PTR_ERR(bdi->battery);
2138 goto out_charger;
2139 }
2140 }
2141
2142 ret = bq24190_get_config(bdi);
2143 if (ret < 0) {
2144 dev_err(dev, "Can't get devicetree config\n");
2145 goto out_charger;
2146 }
2147
2148 ret = bq24190_hw_init(bdi);
2149 if (ret < 0) {
2150 dev_err(dev, "Hardware init failed\n");
2151 goto out_charger;
2152 }
2153
2154 ret = bq24190_configure_usb_otg(bdi, bdi->ss_reg);
2155 if (ret < 0)
2156 goto out_charger;
2157
2158 bdi->initialized = true;
2159
2160 ret = devm_request_threaded_irq(dev, client->irq, NULL,
2161 bq24190_irq_handler_thread,
2162 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
2163 "bq24190-charger", bdi);
2164 if (ret < 0)
2165 goto out_charger;
2166
2167 ret = bq24190_register_vbus_regulator(bdi);
2168 if (ret < 0)
2169 goto out_charger;
2170
2171 enable_irq_wake(client->irq);
2172
2173 pm_runtime_put_autosuspend(dev);
2174
2175 return 0;
2176
2177 out_charger:
2178 if (!IS_ERR_OR_NULL(bdi->battery))
2179 power_supply_unregister(bdi->battery);
2180 power_supply_unregister(bdi->charger);
2181
2182 out_pmrt:
2183 pm_runtime_put_sync(dev);
2184 pm_runtime_dont_use_autosuspend(dev);
2185 pm_runtime_disable(dev);
2186 return ret;
2187 }
2188
bq24190_remove(struct i2c_client * client)2189 static void bq24190_remove(struct i2c_client *client)
2190 {
2191 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2192 int error;
2193
2194 error = pm_runtime_resume_and_get(bdi->dev);
2195 if (error < 0)
2196 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
2197
2198 bq24190_register_reset(bdi);
2199 if (bdi->battery)
2200 power_supply_unregister(bdi->battery);
2201 power_supply_unregister(bdi->charger);
2202 if (error >= 0)
2203 pm_runtime_put_sync(bdi->dev);
2204 pm_runtime_dont_use_autosuspend(bdi->dev);
2205 pm_runtime_disable(bdi->dev);
2206 }
2207
bq24190_shutdown(struct i2c_client * client)2208 static void bq24190_shutdown(struct i2c_client *client)
2209 {
2210 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2211
2212 /* Turn off 5V boost regulator on shutdown */
2213 bdi->info->set_otg_vbus(bdi, false);
2214 }
2215
bq24190_runtime_suspend(struct device * dev)2216 static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
2217 {
2218 struct i2c_client *client = to_i2c_client(dev);
2219 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2220
2221 if (!bdi->initialized)
2222 return 0;
2223
2224 dev_dbg(bdi->dev, "%s\n", __func__);
2225
2226 return 0;
2227 }
2228
bq24190_runtime_resume(struct device * dev)2229 static __maybe_unused int bq24190_runtime_resume(struct device *dev)
2230 {
2231 struct i2c_client *client = to_i2c_client(dev);
2232 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2233
2234 if (!bdi->initialized)
2235 return 0;
2236
2237 if (!bdi->irq_event) {
2238 dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
2239 bq24190_check_status(bdi);
2240 }
2241
2242 return 0;
2243 }
2244
bq24190_pm_suspend(struct device * dev)2245 static __maybe_unused int bq24190_pm_suspend(struct device *dev)
2246 {
2247 struct i2c_client *client = to_i2c_client(dev);
2248 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2249 int error;
2250
2251 error = pm_runtime_resume_and_get(bdi->dev);
2252 if (error < 0)
2253 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
2254
2255 bq24190_register_reset(bdi);
2256
2257 if (error >= 0) {
2258 pm_runtime_put_autosuspend(bdi->dev);
2259 }
2260
2261 return 0;
2262 }
2263
bq24190_pm_resume(struct device * dev)2264 static __maybe_unused int bq24190_pm_resume(struct device *dev)
2265 {
2266 struct i2c_client *client = to_i2c_client(dev);
2267 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
2268 int error;
2269
2270 bdi->f_reg = 0;
2271 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
2272
2273 error = pm_runtime_resume_and_get(bdi->dev);
2274 if (error < 0)
2275 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
2276
2277 bq24190_register_reset(bdi);
2278 bq24190_set_config(bdi);
2279 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
2280
2281 if (error >= 0) {
2282 pm_runtime_put_autosuspend(bdi->dev);
2283 }
2284
2285 /* Things may have changed while suspended so alert upper layer */
2286 power_supply_changed(bdi->charger);
2287 if (bdi->battery)
2288 power_supply_changed(bdi->battery);
2289
2290 return 0;
2291 }
2292
2293 static const struct dev_pm_ops bq24190_pm_ops = {
2294 SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
2295 NULL)
2296 SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
2297 };
2298
2299 static const struct i2c_device_id bq24190_i2c_ids[] = {
2300 { .name = "bq24190", .driver_data = (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24190] },
2301 { .name = "bq24192", .driver_data = (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24192] },
2302 { .name = "bq24192i", .driver_data = (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24192i] },
2303 { .name = "bq24193", .driver_data = (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24193] },
2304 { .name = "bq24196", .driver_data = (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24196] },
2305 { .name = "bq24296", .driver_data = (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24296] },
2306 { .name = "bq24297", .driver_data = (kernel_ulong_t)&bq24190_chip_info_tbl[BQ24297] },
2307 { }
2308 };
2309 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
2310
2311 static const struct of_device_id bq24190_of_match[] = {
2312 { .compatible = "ti,bq24190", .data = &bq24190_chip_info_tbl[BQ24190] },
2313 { .compatible = "ti,bq24192", .data = &bq24190_chip_info_tbl[BQ24192] },
2314 { .compatible = "ti,bq24192i", .data = &bq24190_chip_info_tbl[BQ24192i] },
2315 { .compatible = "ti,bq24193", .data = &bq24190_chip_info_tbl[BQ24193] },
2316 { .compatible = "ti,bq24196", .data = &bq24190_chip_info_tbl[BQ24196] },
2317 { .compatible = "ti,bq24296", .data = &bq24190_chip_info_tbl[BQ24296] },
2318 { .compatible = "ti,bq24297", .data = &bq24190_chip_info_tbl[BQ24297] },
2319 { },
2320 };
2321 MODULE_DEVICE_TABLE(of, bq24190_of_match);
2322
2323 static struct i2c_driver bq24190_driver = {
2324 .probe = bq24190_probe,
2325 .remove = bq24190_remove,
2326 .shutdown = bq24190_shutdown,
2327 .id_table = bq24190_i2c_ids,
2328 .driver = {
2329 .name = "bq24190-charger",
2330 .pm = &bq24190_pm_ops,
2331 .of_match_table = bq24190_of_match,
2332 },
2333 };
2334 module_i2c_driver(bq24190_driver);
2335
2336 MODULE_LICENSE("GPL");
2337 MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
2338 MODULE_DESCRIPTION("TI BQ24190 Charger Driver");
2339