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

source code of linux/drivers/power/supply/bq24190_charger.c