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