1
2
3
4
5
6
7
8
9
10
11#include <linux/module.h>
12#include <linux/interrupt.h>
13#include <linux/delay.h>
14#include <linux/of_irq.h>
15#include <linux/of_device.h>
16#include <linux/pm_runtime.h>
17#include <linux/power_supply.h>
18#include <linux/power/bq24190_charger.h>
19#include <linux/regulator/driver.h>
20#include <linux/regulator/machine.h>
21#include <linux/workqueue.h>
22#include <linux/gpio.h>
23#include <linux/i2c.h>
24
25#define BQ24190_MANUFACTURER "Texas Instruments"
26
27#define BQ24190_REG_ISC 0x00
28#define BQ24190_REG_ISC_EN_HIZ_MASK BIT(7)
29#define BQ24190_REG_ISC_EN_HIZ_SHIFT 7
30#define BQ24190_REG_ISC_VINDPM_MASK (BIT(6) | BIT(5) | BIT(4) | \
31 BIT(3))
32#define BQ24190_REG_ISC_VINDPM_SHIFT 3
33#define BQ24190_REG_ISC_IINLIM_MASK (BIT(2) | BIT(1) | BIT(0))
34#define BQ24190_REG_ISC_IINLIM_SHIFT 0
35
36#define BQ24190_REG_POC 0x01
37#define BQ24190_REG_POC_RESET_MASK BIT(7)
38#define BQ24190_REG_POC_RESET_SHIFT 7
39#define BQ24190_REG_POC_WDT_RESET_MASK BIT(6)
40#define BQ24190_REG_POC_WDT_RESET_SHIFT 6
41#define BQ24190_REG_POC_CHG_CONFIG_MASK (BIT(5) | BIT(4))
42#define BQ24190_REG_POC_CHG_CONFIG_SHIFT 4
43#define BQ24190_REG_POC_CHG_CONFIG_DISABLE 0x0
44#define BQ24190_REG_POC_CHG_CONFIG_CHARGE 0x1
45#define BQ24190_REG_POC_CHG_CONFIG_OTG 0x2
46#define BQ24190_REG_POC_SYS_MIN_MASK (BIT(3) | BIT(2) | BIT(1))
47#define BQ24190_REG_POC_SYS_MIN_SHIFT 1
48#define BQ24190_REG_POC_SYS_MIN_MIN 3000
49#define BQ24190_REG_POC_SYS_MIN_MAX 3700
50#define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0)
51#define BQ24190_REG_POC_BOOST_LIM_SHIFT 0
52
53#define BQ24190_REG_CCC 0x02
54#define BQ24190_REG_CCC_ICHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
55 BIT(4) | BIT(3) | BIT(2))
56#define BQ24190_REG_CCC_ICHG_SHIFT 2
57#define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0)
58#define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0
59
60#define BQ24190_REG_PCTCC 0x03
61#define BQ24190_REG_PCTCC_IPRECHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
62 BIT(4))
63#define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4
64#define BQ24190_REG_PCTCC_IPRECHG_MIN 128
65#define BQ24190_REG_PCTCC_IPRECHG_MAX 2048
66#define BQ24190_REG_PCTCC_ITERM_MASK (BIT(3) | BIT(2) | BIT(1) | \
67 BIT(0))
68#define BQ24190_REG_PCTCC_ITERM_SHIFT 0
69#define BQ24190_REG_PCTCC_ITERM_MIN 128
70#define BQ24190_REG_PCTCC_ITERM_MAX 2048
71
72#define BQ24190_REG_CVC 0x04
73#define BQ24190_REG_CVC_VREG_MASK (BIT(7) | BIT(6) | BIT(5) | \
74 BIT(4) | BIT(3) | BIT(2))
75#define BQ24190_REG_CVC_VREG_SHIFT 2
76#define BQ24190_REG_CVC_BATLOWV_MASK BIT(1)
77#define BQ24190_REG_CVC_BATLOWV_SHIFT 1
78#define BQ24190_REG_CVC_VRECHG_MASK BIT(0)
79#define BQ24190_REG_CVC_VRECHG_SHIFT 0
80
81#define BQ24190_REG_CTTC 0x05
82#define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7)
83#define BQ24190_REG_CTTC_EN_TERM_SHIFT 7
84#define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6)
85#define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6
86#define BQ24190_REG_CTTC_WATCHDOG_MASK (BIT(5) | BIT(4))
87#define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4
88#define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3)
89#define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3
90#define BQ24190_REG_CTTC_CHG_TIMER_MASK (BIT(2) | BIT(1))
91#define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1
92#define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0)
93#define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0
94
95#define BQ24190_REG_ICTRC 0x06
96#define BQ24190_REG_ICTRC_BAT_COMP_MASK (BIT(7) | BIT(6) | BIT(5))
97#define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5
98#define BQ24190_REG_ICTRC_VCLAMP_MASK (BIT(4) | BIT(3) | BIT(2))
99#define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2
100#define BQ24190_REG_ICTRC_TREG_MASK (BIT(1) | BIT(0))
101#define BQ24190_REG_ICTRC_TREG_SHIFT 0
102
103#define BQ24190_REG_MOC 0x07
104#define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7)
105#define BQ24190_REG_MOC_DPDM_EN_SHIFT 7
106#define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6)
107#define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6
108#define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5)
109#define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5
110#define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4)
111#define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4
112#define BQ24190_REG_MOC_INT_MASK_MASK (BIT(1) | BIT(0))
113#define BQ24190_REG_MOC_INT_MASK_SHIFT 0
114
115#define BQ24190_REG_SS 0x08
116#define BQ24190_REG_SS_VBUS_STAT_MASK (BIT(7) | BIT(6))
117#define BQ24190_REG_SS_VBUS_STAT_SHIFT 6
118#define BQ24190_REG_SS_CHRG_STAT_MASK (BIT(5) | BIT(4))
119#define BQ24190_REG_SS_CHRG_STAT_SHIFT 4
120#define BQ24190_REG_SS_DPM_STAT_MASK BIT(3)
121#define BQ24190_REG_SS_DPM_STAT_SHIFT 3
122#define BQ24190_REG_SS_PG_STAT_MASK BIT(2)
123#define BQ24190_REG_SS_PG_STAT_SHIFT 2
124#define BQ24190_REG_SS_THERM_STAT_MASK BIT(1)
125#define BQ24190_REG_SS_THERM_STAT_SHIFT 1
126#define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0)
127#define BQ24190_REG_SS_VSYS_STAT_SHIFT 0
128
129#define BQ24190_REG_F 0x09
130#define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7)
131#define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7
132#define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6)
133#define BQ24190_REG_F_BOOST_FAULT_SHIFT 6
134#define BQ24190_REG_F_CHRG_FAULT_MASK (BIT(5) | BIT(4))
135#define BQ24190_REG_F_CHRG_FAULT_SHIFT 4
136#define BQ24190_REG_F_BAT_FAULT_MASK BIT(3)
137#define BQ24190_REG_F_BAT_FAULT_SHIFT 3
138#define BQ24190_REG_F_NTC_FAULT_MASK (BIT(2) | BIT(1) | BIT(0))
139#define BQ24190_REG_F_NTC_FAULT_SHIFT 0
140
141#define BQ24190_REG_VPRS 0x0A
142#define BQ24190_REG_VPRS_PN_MASK (BIT(5) | BIT(4) | BIT(3))
143#define BQ24190_REG_VPRS_PN_SHIFT 3
144#define BQ24190_REG_VPRS_PN_24190 0x4
145#define BQ24190_REG_VPRS_PN_24192 0x5
146#define BQ24190_REG_VPRS_PN_24192I 0x3
147#define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2)
148#define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2
149#define BQ24190_REG_VPRS_DEV_REG_MASK (BIT(1) | BIT(0))
150#define BQ24190_REG_VPRS_DEV_REG_SHIFT 0
151
152
153
154
155
156
157
158
159struct bq24190_dev_info {
160 struct i2c_client *client;
161 struct device *dev;
162 struct power_supply *charger;
163 struct power_supply *battery;
164 struct delayed_work input_current_limit_work;
165 char model_name[I2C_NAME_SIZE];
166 bool initialized;
167 bool irq_event;
168 u16 sys_min;
169 u16 iprechg;
170 u16 iterm;
171 struct mutex f_reg_lock;
172 u8 f_reg;
173 u8 ss_reg;
174 u8 watchdog;
175};
176
177
178
179
180
181
182
183
184
185
186static const int bq24190_isc_iinlim_values[] = {
187 100000, 150000, 500000, 900000, 1200000, 1500000, 2000000, 3000000
188};
189
190
191static const int bq24190_ccc_ichg_values[] = {
192 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
193 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
194 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
195 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
196 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
197 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
198 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
199 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
200};
201
202
203static const int bq24190_cvc_vreg_values[] = {
204 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
205 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
206 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
207 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
208 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
209 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
210 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
211 4400000
212};
213
214
215static const int bq24190_ictrc_treg_values[] = {
216 600, 800, 1000, 1200
217};
218
219
220
221
222
223
224
225static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
226{
227 int i;
228
229 for (i = 1; i < tbl_size; i++)
230 if (v < tbl[i])
231 break;
232
233 return i - 1;
234}
235
236
237
238static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
239{
240 int ret;
241
242 ret = i2c_smbus_read_byte_data(bdi->client, reg);
243 if (ret < 0)
244 return ret;
245
246 *data = ret;
247 return 0;
248}
249
250static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
251{
252 return i2c_smbus_write_byte_data(bdi->client, reg, data);
253}
254
255static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
256 u8 mask, u8 shift, u8 *data)
257{
258 u8 v;
259 int ret;
260
261 ret = bq24190_read(bdi, reg, &v);
262 if (ret < 0)
263 return ret;
264
265 v &= mask;
266 v >>= shift;
267 *data = v;
268
269 return 0;
270}
271
272static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
273 u8 mask, u8 shift, u8 data)
274{
275 u8 v;
276 int ret;
277
278 ret = bq24190_read(bdi, reg, &v);
279 if (ret < 0)
280 return ret;
281
282 v &= ~mask;
283 v |= ((data << shift) & mask);
284
285 return bq24190_write(bdi, reg, v);
286}
287
288static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
289 u8 reg, u8 mask, u8 shift,
290 const int tbl[], int tbl_size,
291 int *val)
292{
293 u8 v;
294 int ret;
295
296 ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
297 if (ret < 0)
298 return ret;
299
300 v = (v >= tbl_size) ? (tbl_size - 1) : v;
301 *val = tbl[v];
302
303 return 0;
304}
305
306static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
307 u8 reg, u8 mask, u8 shift,
308 const int tbl[], int tbl_size,
309 int val)
310{
311 u8 idx;
312
313 idx = bq24190_find_idx(tbl, tbl_size, val);
314
315 return bq24190_write_mask(bdi, reg, mask, shift, idx);
316}
317
318#ifdef CONFIG_SYSFS
319
320
321
322
323
324
325
326
327#define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
328{ \
329 .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
330 .reg = BQ24190_REG_##r, \
331 .mask = BQ24190_REG_##r##_##f##_MASK, \
332 .shift = BQ24190_REG_##r##_##f##_SHIFT, \
333}
334
335#define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
336 BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
337 bq24190_sysfs_store)
338
339#define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
340 BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
341
342static ssize_t bq24190_sysfs_show(struct device *dev,
343 struct device_attribute *attr, char *buf);
344static ssize_t bq24190_sysfs_store(struct device *dev,
345 struct device_attribute *attr, const char *buf, size_t count);
346
347struct bq24190_sysfs_field_info {
348 struct device_attribute attr;
349 u8 reg;
350 u8 mask;
351 u8 shift;
352};
353
354
355#undef SS
356
357static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
358
359 BQ24190_SYSFS_FIELD_RW(en_hiz, ISC, EN_HIZ),
360 BQ24190_SYSFS_FIELD_RW(vindpm, ISC, VINDPM),
361 BQ24190_SYSFS_FIELD_RW(iinlim, ISC, IINLIM),
362 BQ24190_SYSFS_FIELD_RW(chg_config, POC, CHG_CONFIG),
363 BQ24190_SYSFS_FIELD_RW(sys_min, POC, SYS_MIN),
364 BQ24190_SYSFS_FIELD_RW(boost_lim, POC, BOOST_LIM),
365 BQ24190_SYSFS_FIELD_RW(ichg, CCC, ICHG),
366 BQ24190_SYSFS_FIELD_RW(force_20_pct, CCC, FORCE_20PCT),
367 BQ24190_SYSFS_FIELD_RW(iprechg, PCTCC, IPRECHG),
368 BQ24190_SYSFS_FIELD_RW(iterm, PCTCC, ITERM),
369 BQ24190_SYSFS_FIELD_RW(vreg, CVC, VREG),
370 BQ24190_SYSFS_FIELD_RW(batlowv, CVC, BATLOWV),
371 BQ24190_SYSFS_FIELD_RW(vrechg, CVC, VRECHG),
372 BQ24190_SYSFS_FIELD_RW(en_term, CTTC, EN_TERM),
373 BQ24190_SYSFS_FIELD_RW(term_stat, CTTC, TERM_STAT),
374 BQ24190_SYSFS_FIELD_RO(watchdog, CTTC, WATCHDOG),
375 BQ24190_SYSFS_FIELD_RW(en_timer, CTTC, EN_TIMER),
376 BQ24190_SYSFS_FIELD_RW(chg_timer, CTTC, CHG_TIMER),
377 BQ24190_SYSFS_FIELD_RW(jeta_iset, CTTC, JEITA_ISET),
378 BQ24190_SYSFS_FIELD_RW(bat_comp, ICTRC, BAT_COMP),
379 BQ24190_SYSFS_FIELD_RW(vclamp, ICTRC, VCLAMP),
380 BQ24190_SYSFS_FIELD_RW(treg, ICTRC, TREG),
381 BQ24190_SYSFS_FIELD_RW(dpdm_en, MOC, DPDM_EN),
382 BQ24190_SYSFS_FIELD_RW(tmr2x_en, MOC, TMR2X_EN),
383 BQ24190_SYSFS_FIELD_RW(batfet_disable, MOC, BATFET_DISABLE),
384 BQ24190_SYSFS_FIELD_RW(jeita_vset, MOC, JEITA_VSET),
385 BQ24190_SYSFS_FIELD_RO(int_mask, MOC, INT_MASK),
386 BQ24190_SYSFS_FIELD_RO(vbus_stat, SS, VBUS_STAT),
387 BQ24190_SYSFS_FIELD_RO(chrg_stat, SS, CHRG_STAT),
388 BQ24190_SYSFS_FIELD_RO(dpm_stat, SS, DPM_STAT),
389 BQ24190_SYSFS_FIELD_RO(pg_stat, SS, PG_STAT),
390 BQ24190_SYSFS_FIELD_RO(therm_stat, SS, THERM_STAT),
391 BQ24190_SYSFS_FIELD_RO(vsys_stat, SS, VSYS_STAT),
392 BQ24190_SYSFS_FIELD_RO(watchdog_fault, F, WATCHDOG_FAULT),
393 BQ24190_SYSFS_FIELD_RO(boost_fault, F, BOOST_FAULT),
394 BQ24190_SYSFS_FIELD_RO(chrg_fault, F, CHRG_FAULT),
395 BQ24190_SYSFS_FIELD_RO(bat_fault, F, BAT_FAULT),
396 BQ24190_SYSFS_FIELD_RO(ntc_fault, F, NTC_FAULT),
397 BQ24190_SYSFS_FIELD_RO(pn, VPRS, PN),
398 BQ24190_SYSFS_FIELD_RO(ts_profile, VPRS, TS_PROFILE),
399 BQ24190_SYSFS_FIELD_RO(dev_reg, VPRS, DEV_REG),
400};
401
402static struct attribute *
403 bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
404
405static const struct attribute_group bq24190_sysfs_attr_group = {
406 .attrs = bq24190_sysfs_attrs,
407};
408
409static void bq24190_sysfs_init_attrs(void)
410{
411 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
412
413 for (i = 0; i < limit; i++)
414 bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
415
416 bq24190_sysfs_attrs[limit] = NULL;
417}
418
419static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
420 const char *name)
421{
422 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
423
424 for (i = 0; i < limit; i++)
425 if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
426 break;
427
428 if (i >= limit)
429 return NULL;
430
431 return &bq24190_sysfs_field_tbl[i];
432}
433
434static ssize_t bq24190_sysfs_show(struct device *dev,
435 struct device_attribute *attr, char *buf)
436{
437 struct power_supply *psy = dev_get_drvdata(dev);
438 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
439 struct bq24190_sysfs_field_info *info;
440 ssize_t count;
441 int ret;
442 u8 v;
443
444 info = bq24190_sysfs_field_lookup(attr->attr.name);
445 if (!info)
446 return -EINVAL;
447
448 ret = pm_runtime_get_sync(bdi->dev);
449 if (ret < 0)
450 return ret;
451
452 ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
453 if (ret)
454 count = ret;
455 else
456 count = scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
457
458 pm_runtime_mark_last_busy(bdi->dev);
459 pm_runtime_put_autosuspend(bdi->dev);
460
461 return count;
462}
463
464static ssize_t bq24190_sysfs_store(struct device *dev,
465 struct device_attribute *attr, const char *buf, size_t count)
466{
467 struct power_supply *psy = dev_get_drvdata(dev);
468 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
469 struct bq24190_sysfs_field_info *info;
470 int ret;
471 u8 v;
472
473 info = bq24190_sysfs_field_lookup(attr->attr.name);
474 if (!info)
475 return -EINVAL;
476
477 ret = kstrtou8(buf, 0, &v);
478 if (ret < 0)
479 return ret;
480
481 ret = pm_runtime_get_sync(bdi->dev);
482 if (ret < 0)
483 return ret;
484
485 ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
486 if (ret)
487 count = ret;
488
489 pm_runtime_mark_last_busy(bdi->dev);
490 pm_runtime_put_autosuspend(bdi->dev);
491
492 return count;
493}
494
495static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
496{
497 bq24190_sysfs_init_attrs();
498
499 return sysfs_create_group(&bdi->charger->dev.kobj,
500 &bq24190_sysfs_attr_group);
501}
502
503static void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi)
504{
505 sysfs_remove_group(&bdi->charger->dev.kobj, &bq24190_sysfs_attr_group);
506}
507#else
508static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi)
509{
510 return 0;
511}
512
513static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {}
514#endif
515
516#ifdef CONFIG_REGULATOR
517static int bq24190_set_charge_mode(struct regulator_dev *dev, u8 val)
518{
519 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
520 int ret;
521
522 ret = pm_runtime_get_sync(bdi->dev);
523 if (ret < 0) {
524 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
525 pm_runtime_put_noidle(bdi->dev);
526 return ret;
527 }
528
529 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
530 BQ24190_REG_POC_CHG_CONFIG_MASK,
531 BQ24190_REG_POC_CHG_CONFIG_SHIFT, val);
532
533 pm_runtime_mark_last_busy(bdi->dev);
534 pm_runtime_put_autosuspend(bdi->dev);
535
536 return ret;
537}
538
539static int bq24190_vbus_enable(struct regulator_dev *dev)
540{
541 return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_OTG);
542}
543
544static int bq24190_vbus_disable(struct regulator_dev *dev)
545{
546 return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_CHARGE);
547}
548
549static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
550{
551 struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
552 int ret;
553 u8 val;
554
555 ret = pm_runtime_get_sync(bdi->dev);
556 if (ret < 0) {
557 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
558 pm_runtime_put_noidle(bdi->dev);
559 return ret;
560 }
561
562 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
563 BQ24190_REG_POC_CHG_CONFIG_MASK,
564 BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
565
566 pm_runtime_mark_last_busy(bdi->dev);
567 pm_runtime_put_autosuspend(bdi->dev);
568
569 return ret ? ret : val == BQ24190_REG_POC_CHG_CONFIG_OTG;
570}
571
572static const struct regulator_ops bq24190_vbus_ops = {
573 .enable = bq24190_vbus_enable,
574 .disable = bq24190_vbus_disable,
575 .is_enabled = bq24190_vbus_is_enabled,
576};
577
578static const struct regulator_desc bq24190_vbus_desc = {
579 .name = "usb_otg_vbus",
580 .type = REGULATOR_VOLTAGE,
581 .owner = THIS_MODULE,
582 .ops = &bq24190_vbus_ops,
583 .fixed_uV = 5000000,
584 .n_voltages = 1,
585};
586
587static const struct regulator_init_data bq24190_vbus_init_data = {
588 .constraints = {
589 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
590 },
591};
592
593static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
594{
595 struct bq24190_platform_data *pdata = bdi->dev->platform_data;
596 struct regulator_config cfg = { };
597 struct regulator_dev *reg;
598 int ret = 0;
599
600 cfg.dev = bdi->dev;
601 if (pdata && pdata->regulator_init_data)
602 cfg.init_data = pdata->regulator_init_data;
603 else
604 cfg.init_data = &bq24190_vbus_init_data;
605 cfg.driver_data = bdi;
606 reg = devm_regulator_register(bdi->dev, &bq24190_vbus_desc, &cfg);
607 if (IS_ERR(reg)) {
608 ret = PTR_ERR(reg);
609 dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
610 }
611
612 return ret;
613}
614#else
615static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
616{
617 return 0;
618}
619#endif
620
621static int bq24190_set_config(struct bq24190_dev_info *bdi)
622{
623 int ret;
624 u8 v;
625
626 ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
627 if (ret < 0)
628 return ret;
629
630 bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
631 BQ24190_REG_CTTC_WATCHDOG_SHIFT);
632
633
634
635
636
637
638
639
640
641 v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
642
643 ret = bq24190_write(bdi, BQ24190_REG_CTTC, v);
644 if (ret < 0)
645 return ret;
646
647 if (bdi->sys_min) {
648 v = bdi->sys_min / 100 - 30;
649 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
650 BQ24190_REG_POC_SYS_MIN_MASK,
651 BQ24190_REG_POC_SYS_MIN_SHIFT,
652 v);
653 if (ret < 0)
654 return ret;
655 }
656
657 if (bdi->iprechg) {
658 v = bdi->iprechg / 128 - 1;
659 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
660 BQ24190_REG_PCTCC_IPRECHG_MASK,
661 BQ24190_REG_PCTCC_IPRECHG_SHIFT,
662 v);
663 if (ret < 0)
664 return ret;
665 }
666
667 if (bdi->iterm) {
668 v = bdi->iterm / 128 - 1;
669 ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
670 BQ24190_REG_PCTCC_ITERM_MASK,
671 BQ24190_REG_PCTCC_ITERM_SHIFT,
672 v);
673 if (ret < 0)
674 return ret;
675 }
676
677 return 0;
678}
679
680static int bq24190_register_reset(struct bq24190_dev_info *bdi)
681{
682 int ret, limit = 100;
683 u8 v;
684
685
686
687
688
689
690
691
692
693
694
695 if (device_property_read_bool(bdi->dev, "disable-reset"))
696 return 0;
697
698
699 ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
700 BQ24190_REG_POC_RESET_MASK,
701 BQ24190_REG_POC_RESET_SHIFT,
702 0x1);
703 if (ret < 0)
704 return ret;
705
706
707 do {
708 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
709 BQ24190_REG_POC_RESET_MASK,
710 BQ24190_REG_POC_RESET_SHIFT,
711 &v);
712 if (ret < 0)
713 return ret;
714
715 if (v == 0)
716 return 0;
717
718 usleep_range(100, 200);
719 } while (--limit);
720
721 return -EIO;
722}
723
724
725
726static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
727 union power_supply_propval *val)
728{
729 u8 v;
730 int type, ret;
731
732 ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
733 BQ24190_REG_POC_CHG_CONFIG_MASK,
734 BQ24190_REG_POC_CHG_CONFIG_SHIFT,
735 &v);
736 if (ret < 0)
737 return ret;
738
739
740 if (!v) {
741 type = POWER_SUPPLY_CHARGE_TYPE_NONE;
742 } else {
743 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
744 BQ24190_REG_CCC_FORCE_20PCT_MASK,
745 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
746 &v);
747 if (ret < 0)
748 return ret;
749
750 type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
751 POWER_SUPPLY_CHARGE_TYPE_FAST;
752 }
753
754 val->intval = type;
755
756 return 0;
757}
758
759static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
760 const union power_supply_propval *val)
761{
762 u8 chg_config, force_20pct, en_term;
763 int ret;
764
765
766
767
768
769
770
771
772
773
774
775 switch (val->intval) {
776 case POWER_SUPPLY_CHARGE_TYPE_NONE:
777 chg_config = 0x0;
778 break;
779 case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
780 chg_config = 0x1;
781 force_20pct = 0x1;
782 en_term = 0x0;
783 break;
784 case POWER_SUPPLY_CHARGE_TYPE_FAST:
785 chg_config = 0x1;
786 force_20pct = 0x0;
787 en_term = 0x1;
788 break;
789 default:
790 return -EINVAL;
791 }
792
793 if (chg_config) {
794 ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
795 BQ24190_REG_CCC_FORCE_20PCT_MASK,
796 BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
797 force_20pct);
798 if (ret < 0)
799 return ret;
800
801 ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
802 BQ24190_REG_CTTC_EN_TERM_MASK,
803 BQ24190_REG_CTTC_EN_TERM_SHIFT,
804 en_term);
805 if (ret < 0)
806 return ret;
807 }
808
809 return bq24190_write_mask(bdi, BQ24190_REG_POC,
810 BQ24190_REG_POC_CHG_CONFIG_MASK,
811 BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
812}
813
814static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
815 union power_supply_propval *val)
816{
817 u8 v;
818 int health;
819
820 mutex_lock(&bdi->f_reg_lock);
821 v = bdi->f_reg;
822 mutex_unlock(&bdi->f_reg_lock);
823
824 if (v & BQ24190_REG_F_NTC_FAULT_MASK) {
825 switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
826 case 0x1:
827 case 0x3:
828 case 0x5:
829 health = POWER_SUPPLY_HEALTH_COLD;
830 break;
831 case 0x2:
832 case 0x4:
833 case 0x6:
834 health = POWER_SUPPLY_HEALTH_OVERHEAT;
835 break;
836 default:
837 health = POWER_SUPPLY_HEALTH_UNKNOWN;
838 }
839 } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
840 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
841 } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
842 switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
843 case 0x1:
844
845
846
847
848
849
850
851 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
852 break;
853 case 0x2:
854 health = POWER_SUPPLY_HEALTH_OVERHEAT;
855 break;
856 case 0x3:
857 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
858 break;
859 default:
860 health = -1;
861 }
862 } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
863
864
865
866
867
868
869 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
870 } else {
871 health = POWER_SUPPLY_HEALTH_GOOD;
872 }
873
874 val->intval = health;
875
876 return 0;
877}
878
879static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
880 union power_supply_propval *val)
881{
882 u8 pg_stat, batfet_disable;
883 int ret;
884
885 ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
886 BQ24190_REG_SS_PG_STAT_MASK,
887 BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
888 if (ret < 0)
889 return ret;
890
891 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
892 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
893 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
894 if (ret < 0)
895 return ret;
896
897 val->intval = pg_stat && !batfet_disable;
898
899 return 0;
900}
901
902static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
903 const union power_supply_propval *val);
904static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
905 union power_supply_propval *val);
906static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
907 union power_supply_propval *val);
908static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
909 const union power_supply_propval *val);
910
911static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
912 const union power_supply_propval *val)
913{
914 return bq24190_battery_set_online(bdi, val);
915}
916
917static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
918 union power_supply_propval *val)
919{
920 return bq24190_battery_get_status(bdi, val);
921}
922
923static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
924 union power_supply_propval *val)
925{
926 return bq24190_battery_get_temp_alert_max(bdi, val);
927}
928
929static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
930 const union power_supply_propval *val)
931{
932 return bq24190_battery_set_temp_alert_max(bdi, val);
933}
934
935static int bq24190_charger_get_precharge(struct bq24190_dev_info *bdi,
936 union power_supply_propval *val)
937{
938 u8 v;
939 int ret;
940
941 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
942 BQ24190_REG_PCTCC_IPRECHG_MASK,
943 BQ24190_REG_PCTCC_IPRECHG_SHIFT, &v);
944 if (ret < 0)
945 return ret;
946
947 val->intval = ++v * 128 * 1000;
948 return 0;
949}
950
951static int bq24190_charger_get_charge_term(struct bq24190_dev_info *bdi,
952 union power_supply_propval *val)
953{
954 u8 v;
955 int ret;
956
957 ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
958 BQ24190_REG_PCTCC_ITERM_MASK,
959 BQ24190_REG_PCTCC_ITERM_SHIFT, &v);
960 if (ret < 0)
961 return ret;
962
963 val->intval = ++v * 128 * 1000;
964 return 0;
965}
966
967static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
968 union power_supply_propval *val)
969{
970 u8 v;
971 int curr, ret;
972
973 ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
974 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
975 bq24190_ccc_ichg_values,
976 ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
977 if (ret < 0)
978 return ret;
979
980 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
981 BQ24190_REG_CCC_FORCE_20PCT_MASK,
982 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
983 if (ret < 0)
984 return ret;
985
986
987 if (v)
988 curr /= 5;
989
990 val->intval = curr;
991 return 0;
992}
993
994static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
995 union power_supply_propval *val)
996{
997 int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
998
999 val->intval = bq24190_ccc_ichg_values[idx];
1000 return 0;
1001}
1002
1003static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
1004 const union power_supply_propval *val)
1005{
1006 u8 v;
1007 int ret, curr = val->intval;
1008
1009 ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
1010 BQ24190_REG_CCC_FORCE_20PCT_MASK,
1011 BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
1012 if (ret < 0)
1013 return ret;
1014
1015
1016 if (v)
1017 curr *= 5;
1018
1019 return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
1020 BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
1021 bq24190_ccc_ichg_values,
1022 ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
1023}
1024
1025static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
1026 union power_supply_propval *val)
1027{
1028 int voltage, ret;
1029
1030 ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
1031 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1032 bq24190_cvc_vreg_values,
1033 ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
1034 if (ret < 0)
1035 return ret;
1036
1037 val->intval = voltage;
1038 return 0;
1039}
1040
1041static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
1042 union power_supply_propval *val)
1043{
1044 int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
1045
1046 val->intval = bq24190_cvc_vreg_values[idx];
1047 return 0;
1048}
1049
1050static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
1051 const union power_supply_propval *val)
1052{
1053 return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
1054 BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
1055 bq24190_cvc_vreg_values,
1056 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
1057}
1058
1059static int bq24190_charger_get_iinlimit(struct bq24190_dev_info *bdi,
1060 union power_supply_propval *val)
1061{
1062 int iinlimit, ret;
1063
1064 ret = bq24190_get_field_val(bdi, BQ24190_REG_ISC,
1065 BQ24190_REG_ISC_IINLIM_MASK,
1066 BQ24190_REG_ISC_IINLIM_SHIFT,
1067 bq24190_isc_iinlim_values,
1068 ARRAY_SIZE(bq24190_isc_iinlim_values), &iinlimit);
1069 if (ret < 0)
1070 return ret;
1071
1072 val->intval = iinlimit;
1073 return 0;
1074}
1075
1076static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi,
1077 const union power_supply_propval *val)
1078{
1079 return bq24190_set_field_val(bdi, BQ24190_REG_ISC,
1080 BQ24190_REG_ISC_IINLIM_MASK,
1081 BQ24190_REG_ISC_IINLIM_SHIFT,
1082 bq24190_isc_iinlim_values,
1083 ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval);
1084}
1085
1086static int bq24190_charger_get_property(struct power_supply *psy,
1087 enum power_supply_property psp, union power_supply_propval *val)
1088{
1089 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1090 int ret;
1091
1092 dev_dbg(bdi->dev, "prop: %d\n", psp);
1093
1094 ret = pm_runtime_get_sync(bdi->dev);
1095 if (ret < 0)
1096 return ret;
1097
1098 switch (psp) {
1099 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1100 ret = bq24190_charger_get_charge_type(bdi, val);
1101 break;
1102 case POWER_SUPPLY_PROP_HEALTH:
1103 ret = bq24190_charger_get_health(bdi, val);
1104 break;
1105 case POWER_SUPPLY_PROP_ONLINE:
1106 ret = bq24190_charger_get_online(bdi, val);
1107 break;
1108 case POWER_SUPPLY_PROP_STATUS:
1109 ret = bq24190_charger_get_status(bdi, val);
1110 break;
1111 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1112 ret = bq24190_charger_get_temp_alert_max(bdi, val);
1113 break;
1114 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
1115 ret = bq24190_charger_get_precharge(bdi, val);
1116 break;
1117 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
1118 ret = bq24190_charger_get_charge_term(bdi, val);
1119 break;
1120 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1121 ret = bq24190_charger_get_current(bdi, val);
1122 break;
1123 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
1124 ret = bq24190_charger_get_current_max(bdi, val);
1125 break;
1126 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1127 ret = bq24190_charger_get_voltage(bdi, val);
1128 break;
1129 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
1130 ret = bq24190_charger_get_voltage_max(bdi, val);
1131 break;
1132 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1133 ret = bq24190_charger_get_iinlimit(bdi, val);
1134 break;
1135 case POWER_SUPPLY_PROP_SCOPE:
1136 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1137 ret = 0;
1138 break;
1139 case POWER_SUPPLY_PROP_MODEL_NAME:
1140 val->strval = bdi->model_name;
1141 ret = 0;
1142 break;
1143 case POWER_SUPPLY_PROP_MANUFACTURER:
1144 val->strval = BQ24190_MANUFACTURER;
1145 ret = 0;
1146 break;
1147 default:
1148 ret = -ENODATA;
1149 }
1150
1151 pm_runtime_mark_last_busy(bdi->dev);
1152 pm_runtime_put_autosuspend(bdi->dev);
1153
1154 return ret;
1155}
1156
1157static int bq24190_charger_set_property(struct power_supply *psy,
1158 enum power_supply_property psp,
1159 const union power_supply_propval *val)
1160{
1161 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1162 int ret;
1163
1164 dev_dbg(bdi->dev, "prop: %d\n", psp);
1165
1166 ret = pm_runtime_get_sync(bdi->dev);
1167 if (ret < 0)
1168 return ret;
1169
1170 switch (psp) {
1171 case POWER_SUPPLY_PROP_ONLINE:
1172 ret = bq24190_charger_set_online(bdi, val);
1173 break;
1174 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1175 ret = bq24190_charger_set_temp_alert_max(bdi, val);
1176 break;
1177 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1178 ret = bq24190_charger_set_charge_type(bdi, val);
1179 break;
1180 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1181 ret = bq24190_charger_set_current(bdi, val);
1182 break;
1183 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1184 ret = bq24190_charger_set_voltage(bdi, val);
1185 break;
1186 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1187 ret = bq24190_charger_set_iinlimit(bdi, val);
1188 break;
1189 default:
1190 ret = -EINVAL;
1191 }
1192
1193 pm_runtime_mark_last_busy(bdi->dev);
1194 pm_runtime_put_autosuspend(bdi->dev);
1195
1196 return ret;
1197}
1198
1199static int bq24190_charger_property_is_writeable(struct power_supply *psy,
1200 enum power_supply_property psp)
1201{
1202 switch (psp) {
1203 case POWER_SUPPLY_PROP_ONLINE:
1204 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1205 case POWER_SUPPLY_PROP_CHARGE_TYPE:
1206 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
1207 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
1208 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
1209 return 1;
1210 default:
1211 return 0;
1212 }
1213}
1214
1215static void bq24190_input_current_limit_work(struct work_struct *work)
1216{
1217 struct bq24190_dev_info *bdi =
1218 container_of(work, struct bq24190_dev_info,
1219 input_current_limit_work.work);
1220
1221 power_supply_set_input_current_limit_from_supplier(bdi->charger);
1222}
1223
1224
1225static void bq24190_charger_external_power_changed(struct power_supply *psy)
1226{
1227 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237 queue_delayed_work(system_wq, &bdi->input_current_limit_work,
1238 msecs_to_jiffies(300));
1239}
1240
1241static enum power_supply_property bq24190_charger_properties[] = {
1242 POWER_SUPPLY_PROP_CHARGE_TYPE,
1243 POWER_SUPPLY_PROP_HEALTH,
1244 POWER_SUPPLY_PROP_ONLINE,
1245 POWER_SUPPLY_PROP_STATUS,
1246 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1247 POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
1248 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
1249 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
1250 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
1251 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
1252 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
1253 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
1254 POWER_SUPPLY_PROP_SCOPE,
1255 POWER_SUPPLY_PROP_MODEL_NAME,
1256 POWER_SUPPLY_PROP_MANUFACTURER,
1257};
1258
1259static char *bq24190_charger_supplied_to[] = {
1260 "main-battery",
1261};
1262
1263static const struct power_supply_desc bq24190_charger_desc = {
1264 .name = "bq24190-charger",
1265 .type = POWER_SUPPLY_TYPE_USB,
1266 .properties = bq24190_charger_properties,
1267 .num_properties = ARRAY_SIZE(bq24190_charger_properties),
1268 .get_property = bq24190_charger_get_property,
1269 .set_property = bq24190_charger_set_property,
1270 .property_is_writeable = bq24190_charger_property_is_writeable,
1271 .external_power_changed = bq24190_charger_external_power_changed,
1272};
1273
1274
1275
1276static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
1277 union power_supply_propval *val)
1278{
1279 u8 ss_reg, chrg_fault;
1280 int status, ret;
1281
1282 mutex_lock(&bdi->f_reg_lock);
1283 chrg_fault = bdi->f_reg;
1284 mutex_unlock(&bdi->f_reg_lock);
1285
1286 chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
1287 chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
1288
1289 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1290 if (ret < 0)
1291 return ret;
1292
1293
1294
1295
1296
1297
1298
1299
1300 if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
1301 status = POWER_SUPPLY_STATUS_DISCHARGING;
1302 } else {
1303 ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
1304 ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
1305
1306 switch (ss_reg) {
1307 case 0x0:
1308 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1309 break;
1310 case 0x1:
1311 case 0x2:
1312 status = POWER_SUPPLY_STATUS_CHARGING;
1313 break;
1314 case 0x3:
1315 status = POWER_SUPPLY_STATUS_FULL;
1316 break;
1317 default:
1318 ret = -EIO;
1319 }
1320 }
1321
1322 if (!ret)
1323 val->intval = status;
1324
1325 return ret;
1326}
1327
1328static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
1329 union power_supply_propval *val)
1330{
1331 u8 v;
1332 int health;
1333
1334 mutex_lock(&bdi->f_reg_lock);
1335 v = bdi->f_reg;
1336 mutex_unlock(&bdi->f_reg_lock);
1337
1338 if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
1339 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
1340 } else {
1341 v &= BQ24190_REG_F_NTC_FAULT_MASK;
1342 v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
1343
1344 switch (v) {
1345 case 0x0:
1346 health = POWER_SUPPLY_HEALTH_GOOD;
1347 break;
1348 case 0x1:
1349 case 0x3:
1350 case 0x5:
1351 health = POWER_SUPPLY_HEALTH_COLD;
1352 break;
1353 case 0x2:
1354 case 0x4:
1355 case 0x6:
1356 health = POWER_SUPPLY_HEALTH_OVERHEAT;
1357 break;
1358 default:
1359 health = POWER_SUPPLY_HEALTH_UNKNOWN;
1360 }
1361 }
1362
1363 val->intval = health;
1364 return 0;
1365}
1366
1367static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
1368 union power_supply_propval *val)
1369{
1370 u8 batfet_disable;
1371 int ret;
1372
1373 ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
1374 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1375 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
1376 if (ret < 0)
1377 return ret;
1378
1379 val->intval = !batfet_disable;
1380 return 0;
1381}
1382
1383static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
1384 const union power_supply_propval *val)
1385{
1386 return bq24190_write_mask(bdi, BQ24190_REG_MOC,
1387 BQ24190_REG_MOC_BATFET_DISABLE_MASK,
1388 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
1389}
1390
1391static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
1392 union power_supply_propval *val)
1393{
1394 int temp, ret;
1395
1396 ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
1397 BQ24190_REG_ICTRC_TREG_MASK,
1398 BQ24190_REG_ICTRC_TREG_SHIFT,
1399 bq24190_ictrc_treg_values,
1400 ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
1401 if (ret < 0)
1402 return ret;
1403
1404 val->intval = temp;
1405 return 0;
1406}
1407
1408static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
1409 const union power_supply_propval *val)
1410{
1411 return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
1412 BQ24190_REG_ICTRC_TREG_MASK,
1413 BQ24190_REG_ICTRC_TREG_SHIFT,
1414 bq24190_ictrc_treg_values,
1415 ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
1416}
1417
1418static int bq24190_battery_get_property(struct power_supply *psy,
1419 enum power_supply_property psp, union power_supply_propval *val)
1420{
1421 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1422 int ret;
1423
1424 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1425 dev_dbg(bdi->dev, "prop: %d\n", psp);
1426
1427 ret = pm_runtime_get_sync(bdi->dev);
1428 if (ret < 0)
1429 return ret;
1430
1431 switch (psp) {
1432 case POWER_SUPPLY_PROP_STATUS:
1433 ret = bq24190_battery_get_status(bdi, val);
1434 break;
1435 case POWER_SUPPLY_PROP_HEALTH:
1436 ret = bq24190_battery_get_health(bdi, val);
1437 break;
1438 case POWER_SUPPLY_PROP_ONLINE:
1439 ret = bq24190_battery_get_online(bdi, val);
1440 break;
1441 case POWER_SUPPLY_PROP_TECHNOLOGY:
1442
1443 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
1444 ret = 0;
1445 break;
1446 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1447 ret = bq24190_battery_get_temp_alert_max(bdi, val);
1448 break;
1449 case POWER_SUPPLY_PROP_SCOPE:
1450 val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
1451 ret = 0;
1452 break;
1453 default:
1454 ret = -ENODATA;
1455 }
1456
1457 pm_runtime_mark_last_busy(bdi->dev);
1458 pm_runtime_put_autosuspend(bdi->dev);
1459
1460 return ret;
1461}
1462
1463static int bq24190_battery_set_property(struct power_supply *psy,
1464 enum power_supply_property psp,
1465 const union power_supply_propval *val)
1466{
1467 struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
1468 int ret;
1469
1470 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
1471 dev_dbg(bdi->dev, "prop: %d\n", psp);
1472
1473 ret = pm_runtime_get_sync(bdi->dev);
1474 if (ret < 0)
1475 return ret;
1476
1477 switch (psp) {
1478 case POWER_SUPPLY_PROP_ONLINE:
1479 ret = bq24190_battery_set_online(bdi, val);
1480 break;
1481 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1482 ret = bq24190_battery_set_temp_alert_max(bdi, val);
1483 break;
1484 default:
1485 ret = -EINVAL;
1486 }
1487
1488 pm_runtime_mark_last_busy(bdi->dev);
1489 pm_runtime_put_autosuspend(bdi->dev);
1490
1491 return ret;
1492}
1493
1494static int bq24190_battery_property_is_writeable(struct power_supply *psy,
1495 enum power_supply_property psp)
1496{
1497 int ret;
1498
1499 switch (psp) {
1500 case POWER_SUPPLY_PROP_ONLINE:
1501 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
1502 ret = 1;
1503 break;
1504 default:
1505 ret = 0;
1506 }
1507
1508 return ret;
1509}
1510
1511static enum power_supply_property bq24190_battery_properties[] = {
1512 POWER_SUPPLY_PROP_STATUS,
1513 POWER_SUPPLY_PROP_HEALTH,
1514 POWER_SUPPLY_PROP_ONLINE,
1515 POWER_SUPPLY_PROP_TECHNOLOGY,
1516 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
1517 POWER_SUPPLY_PROP_SCOPE,
1518};
1519
1520static const struct power_supply_desc bq24190_battery_desc = {
1521 .name = "bq24190-battery",
1522 .type = POWER_SUPPLY_TYPE_BATTERY,
1523 .properties = bq24190_battery_properties,
1524 .num_properties = ARRAY_SIZE(bq24190_battery_properties),
1525 .get_property = bq24190_battery_get_property,
1526 .set_property = bq24190_battery_set_property,
1527 .property_is_writeable = bq24190_battery_property_is_writeable,
1528};
1529
1530static void bq24190_check_status(struct bq24190_dev_info *bdi)
1531{
1532 const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
1533 const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
1534 | BQ24190_REG_F_NTC_FAULT_MASK;
1535 bool alert_charger = false, alert_battery = false;
1536 u8 ss_reg = 0, f_reg = 0;
1537 int i, ret;
1538
1539 ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
1540 if (ret < 0) {
1541 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
1542 return;
1543 }
1544
1545 i = 0;
1546 do {
1547 ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
1548 if (ret < 0) {
1549 dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
1550 return;
1551 }
1552 } while (f_reg && ++i < 2);
1553
1554
1555 if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
1556 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
1557 f_reg = 0;
1558
1559 if (f_reg != bdi->f_reg) {
1560 dev_warn(bdi->dev,
1561 "Fault: boost %d, charge %d, battery %d, ntc %d\n",
1562 !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
1563 !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
1564 !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
1565 !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
1566
1567 mutex_lock(&bdi->f_reg_lock);
1568 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
1569 alert_battery = true;
1570 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
1571 alert_charger = true;
1572 bdi->f_reg = f_reg;
1573 mutex_unlock(&bdi->f_reg_lock);
1574 }
1575
1576 if (ss_reg != bdi->ss_reg) {
1577
1578
1579
1580
1581 if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
1582 !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
1583 ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
1584 BQ24190_REG_ISC_EN_HIZ_MASK,
1585 BQ24190_REG_ISC_EN_HIZ_SHIFT,
1586 0);
1587 if (ret < 0)
1588 dev_err(bdi->dev, "Can't access ISC reg: %d\n",
1589 ret);
1590 }
1591
1592 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
1593 alert_battery = true;
1594 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
1595 alert_charger = true;
1596 bdi->ss_reg = ss_reg;
1597 }
1598
1599 if (alert_charger || alert_battery)
1600 power_supply_changed(bdi->charger);
1601 if (alert_battery && bdi->battery)
1602 power_supply_changed(bdi->battery);
1603
1604 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
1605}
1606
1607static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
1608{
1609 struct bq24190_dev_info *bdi = data;
1610 int error;
1611
1612 bdi->irq_event = true;
1613 error = pm_runtime_get_sync(bdi->dev);
1614 if (error < 0) {
1615 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1616 pm_runtime_put_noidle(bdi->dev);
1617 return IRQ_NONE;
1618 }
1619 bq24190_check_status(bdi);
1620 pm_runtime_mark_last_busy(bdi->dev);
1621 pm_runtime_put_autosuspend(bdi->dev);
1622 bdi->irq_event = false;
1623
1624 return IRQ_HANDLED;
1625}
1626
1627static int bq24190_hw_init(struct bq24190_dev_info *bdi)
1628{
1629 u8 v;
1630 int ret;
1631
1632
1633 ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
1634 BQ24190_REG_VPRS_PN_MASK,
1635 BQ24190_REG_VPRS_PN_SHIFT,
1636 &v);
1637 if (ret < 0)
1638 return ret;
1639
1640 if (v != BQ24190_REG_VPRS_PN_24190 &&
1641 v != BQ24190_REG_VPRS_PN_24192I) {
1642 dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
1643 return -ENODEV;
1644 }
1645
1646 ret = bq24190_register_reset(bdi);
1647 if (ret < 0)
1648 return ret;
1649
1650 ret = bq24190_set_config(bdi);
1651 if (ret < 0)
1652 return ret;
1653
1654 return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1655}
1656
1657static int bq24190_get_config(struct bq24190_dev_info *bdi)
1658{
1659 const char * const s = "ti,system-minimum-microvolt";
1660 struct power_supply_battery_info info = {};
1661 int v;
1662
1663 if (device_property_read_u32(bdi->dev, s, &v) == 0) {
1664 v /= 1000;
1665 if (v >= BQ24190_REG_POC_SYS_MIN_MIN
1666 && v <= BQ24190_REG_POC_SYS_MIN_MAX)
1667 bdi->sys_min = v;
1668 else
1669 dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v);
1670 }
1671
1672 if (bdi->dev->of_node &&
1673 !power_supply_get_battery_info(bdi->charger, &info)) {
1674 v = info.precharge_current_ua / 1000;
1675 if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
1676 && v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
1677 bdi->iprechg = v;
1678 else
1679 dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
1680 v);
1681
1682 v = info.charge_term_current_ua / 1000;
1683 if (v >= BQ24190_REG_PCTCC_ITERM_MIN
1684 && v <= BQ24190_REG_PCTCC_ITERM_MAX)
1685 bdi->iterm = v;
1686 else
1687 dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n",
1688 v);
1689 }
1690
1691 return 0;
1692}
1693
1694static int bq24190_probe(struct i2c_client *client,
1695 const struct i2c_device_id *id)
1696{
1697 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1698 struct device *dev = &client->dev;
1699 struct power_supply_config charger_cfg = {}, battery_cfg = {};
1700 struct bq24190_dev_info *bdi;
1701 int ret;
1702
1703 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1704 dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
1705 return -ENODEV;
1706 }
1707
1708 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
1709 if (!bdi) {
1710 dev_err(dev, "Can't alloc bdi struct\n");
1711 return -ENOMEM;
1712 }
1713
1714 bdi->client = client;
1715 bdi->dev = dev;
1716 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
1717 mutex_init(&bdi->f_reg_lock);
1718 bdi->f_reg = 0;
1719 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK;
1720 INIT_DELAYED_WORK(&bdi->input_current_limit_work,
1721 bq24190_input_current_limit_work);
1722
1723 i2c_set_clientdata(client, bdi);
1724
1725 if (client->irq <= 0) {
1726 dev_err(dev, "Can't get irq info\n");
1727 return -EINVAL;
1728 }
1729
1730 pm_runtime_enable(dev);
1731 pm_runtime_use_autosuspend(dev);
1732 pm_runtime_set_autosuspend_delay(dev, 600);
1733 ret = pm_runtime_get_sync(dev);
1734 if (ret < 0) {
1735 dev_err(dev, "pm_runtime_get failed: %i\n", ret);
1736 goto out_pmrt;
1737 }
1738
1739 charger_cfg.drv_data = bdi;
1740 charger_cfg.of_node = dev->of_node;
1741 charger_cfg.supplied_to = bq24190_charger_supplied_to;
1742 charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
1743 bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
1744 &charger_cfg);
1745 if (IS_ERR(bdi->charger)) {
1746 dev_err(dev, "Can't register charger\n");
1747 ret = PTR_ERR(bdi->charger);
1748 goto out_pmrt;
1749 }
1750
1751
1752
1753 if (!device_property_read_bool(dev, "omit-battery-class")) {
1754 battery_cfg.drv_data = bdi;
1755 bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
1756 &battery_cfg);
1757 if (IS_ERR(bdi->battery)) {
1758 dev_err(dev, "Can't register battery\n");
1759 ret = PTR_ERR(bdi->battery);
1760 goto out_charger;
1761 }
1762 }
1763
1764 ret = bq24190_get_config(bdi);
1765 if (ret < 0) {
1766 dev_err(dev, "Can't get devicetree config\n");
1767 goto out_charger;
1768 }
1769
1770 ret = bq24190_hw_init(bdi);
1771 if (ret < 0) {
1772 dev_err(dev, "Hardware init failed\n");
1773 goto out_charger;
1774 }
1775
1776 ret = bq24190_sysfs_create_group(bdi);
1777 if (ret < 0) {
1778 dev_err(dev, "Can't create sysfs entries\n");
1779 goto out_charger;
1780 }
1781
1782 bdi->initialized = true;
1783
1784 ret = devm_request_threaded_irq(dev, client->irq, NULL,
1785 bq24190_irq_handler_thread,
1786 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1787 "bq24190-charger", bdi);
1788 if (ret < 0) {
1789 dev_err(dev, "Can't set up irq handler\n");
1790 goto out_sysfs;
1791 }
1792
1793 ret = bq24190_register_vbus_regulator(bdi);
1794 if (ret < 0)
1795 goto out_sysfs;
1796
1797 enable_irq_wake(client->irq);
1798
1799 pm_runtime_mark_last_busy(dev);
1800 pm_runtime_put_autosuspend(dev);
1801
1802 return 0;
1803
1804out_sysfs:
1805 bq24190_sysfs_remove_group(bdi);
1806
1807out_charger:
1808 if (!IS_ERR_OR_NULL(bdi->battery))
1809 power_supply_unregister(bdi->battery);
1810 power_supply_unregister(bdi->charger);
1811
1812out_pmrt:
1813 pm_runtime_put_sync(dev);
1814 pm_runtime_dont_use_autosuspend(dev);
1815 pm_runtime_disable(dev);
1816 return ret;
1817}
1818
1819static int bq24190_remove(struct i2c_client *client)
1820{
1821 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1822 int error;
1823
1824 error = pm_runtime_get_sync(bdi->dev);
1825 if (error < 0) {
1826 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1827 pm_runtime_put_noidle(bdi->dev);
1828 }
1829
1830 bq24190_register_reset(bdi);
1831 bq24190_sysfs_remove_group(bdi);
1832 if (bdi->battery)
1833 power_supply_unregister(bdi->battery);
1834 power_supply_unregister(bdi->charger);
1835 if (error >= 0)
1836 pm_runtime_put_sync(bdi->dev);
1837 pm_runtime_dont_use_autosuspend(bdi->dev);
1838 pm_runtime_disable(bdi->dev);
1839
1840 return 0;
1841}
1842
1843static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
1844{
1845 struct i2c_client *client = to_i2c_client(dev);
1846 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1847
1848 if (!bdi->initialized)
1849 return 0;
1850
1851 dev_dbg(bdi->dev, "%s\n", __func__);
1852
1853 return 0;
1854}
1855
1856static __maybe_unused int bq24190_runtime_resume(struct device *dev)
1857{
1858 struct i2c_client *client = to_i2c_client(dev);
1859 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1860
1861 if (!bdi->initialized)
1862 return 0;
1863
1864 if (!bdi->irq_event) {
1865 dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
1866 bq24190_check_status(bdi);
1867 }
1868
1869 return 0;
1870}
1871
1872static __maybe_unused int bq24190_pm_suspend(struct device *dev)
1873{
1874 struct i2c_client *client = to_i2c_client(dev);
1875 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1876 int error;
1877
1878 error = pm_runtime_get_sync(bdi->dev);
1879 if (error < 0) {
1880 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1881 pm_runtime_put_noidle(bdi->dev);
1882 }
1883
1884 bq24190_register_reset(bdi);
1885
1886 if (error >= 0) {
1887 pm_runtime_mark_last_busy(bdi->dev);
1888 pm_runtime_put_autosuspend(bdi->dev);
1889 }
1890
1891 return 0;
1892}
1893
1894static __maybe_unused int bq24190_pm_resume(struct device *dev)
1895{
1896 struct i2c_client *client = to_i2c_client(dev);
1897 struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1898 int error;
1899
1900 bdi->f_reg = 0;
1901 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK;
1902
1903 error = pm_runtime_get_sync(bdi->dev);
1904 if (error < 0) {
1905 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1906 pm_runtime_put_noidle(bdi->dev);
1907 }
1908
1909 bq24190_register_reset(bdi);
1910 bq24190_set_config(bdi);
1911 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1912
1913 if (error >= 0) {
1914 pm_runtime_mark_last_busy(bdi->dev);
1915 pm_runtime_put_autosuspend(bdi->dev);
1916 }
1917
1918
1919 power_supply_changed(bdi->charger);
1920 if (bdi->battery)
1921 power_supply_changed(bdi->battery);
1922
1923 return 0;
1924}
1925
1926static const struct dev_pm_ops bq24190_pm_ops = {
1927 SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
1928 NULL)
1929 SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
1930};
1931
1932static const struct i2c_device_id bq24190_i2c_ids[] = {
1933 { "bq24190" },
1934 { "bq24192i" },
1935 { },
1936};
1937MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
1938
1939#ifdef CONFIG_OF
1940static const struct of_device_id bq24190_of_match[] = {
1941 { .compatible = "ti,bq24190", },
1942 { .compatible = "ti,bq24192i", },
1943 { },
1944};
1945MODULE_DEVICE_TABLE(of, bq24190_of_match);
1946#else
1947static const struct of_device_id bq24190_of_match[] = {
1948 { },
1949};
1950#endif
1951
1952static struct i2c_driver bq24190_driver = {
1953 .probe = bq24190_probe,
1954 .remove = bq24190_remove,
1955 .id_table = bq24190_i2c_ids,
1956 .driver = {
1957 .name = "bq24190-charger",
1958 .pm = &bq24190_pm_ops,
1959 .of_match_table = of_match_ptr(bq24190_of_match),
1960 },
1961};
1962module_i2c_driver(bq24190_driver);
1963
1964MODULE_LICENSE("GPL");
1965MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
1966MODULE_DESCRIPTION("TI BQ24190 Charger Driver");
1967