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