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