1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Motorola CPCAP PMIC battery charger driver |
4 | * |
5 | * Copyright (C) 2017 Tony Lindgren <tony@atomide.com> |
6 | * |
7 | * Rewritten for Linux power framework with some parts based on |
8 | * earlier driver found in the Motorola Linux kernel: |
9 | * |
10 | * Copyright (C) 2009-2010 Motorola, Inc. |
11 | */ |
12 | |
13 | #include <linux/atomic.h> |
14 | #include <linux/init.h> |
15 | #include <linux/module.h> |
16 | #include <linux/slab.h> |
17 | #include <linux/err.h> |
18 | #include <linux/interrupt.h> |
19 | #include <linux/notifier.h> |
20 | #include <linux/mod_devicetable.h> |
21 | #include <linux/platform_device.h> |
22 | #include <linux/power_supply.h> |
23 | #include <linux/regmap.h> |
24 | |
25 | #include <linux/gpio/consumer.h> |
26 | #include <linux/usb/phy_companion.h> |
27 | #include <linux/phy/omap_usb.h> |
28 | #include <linux/usb/otg.h> |
29 | #include <linux/iio/consumer.h> |
30 | #include <linux/mfd/motorola-cpcap.h> |
31 | |
32 | /* |
33 | * CPCAP_REG_CRM register bits. For documentation of somewhat similar hardware, |
34 | * see NXP "MC13783 Power Management and Audio Circuit Users's Guide" |
35 | * MC13783UG.pdf chapter "8.5 Battery Interface Register Summary". The registers |
36 | * and values for CPCAP are different, but some of the internal components seem |
37 | * similar. Also see the Motorola Linux kernel cpcap-regbits.h. CPCAP_REG_CHRGR_1 |
38 | * bits that seem to describe the CRM register. |
39 | */ |
40 | #define CPCAP_REG_CRM_UNUSED_641_15 BIT(15) /* 641 = register number */ |
41 | #define CPCAP_REG_CRM_UNUSED_641_14 BIT(14) /* 641 = register number */ |
42 | #define CPCAP_REG_CRM_CHRG_LED_EN BIT(13) /* Charger LED */ |
43 | #define CPCAP_REG_CRM_RVRSMODE BIT(12) /* USB VBUS output enable */ |
44 | #define CPCAP_REG_CRM_ICHRG_TR1 BIT(11) /* Trickle charge current */ |
45 | #define CPCAP_REG_CRM_ICHRG_TR0 BIT(10) |
46 | #define CPCAP_REG_CRM_FET_OVRD BIT(9) /* 0 = hardware, 1 = FET_CTRL */ |
47 | #define CPCAP_REG_CRM_FET_CTRL BIT(8) /* BPFET 1 if FET_OVRD set */ |
48 | #define CPCAP_REG_CRM_VCHRG3 BIT(7) /* Charge voltage bits */ |
49 | #define CPCAP_REG_CRM_VCHRG2 BIT(6) |
50 | #define CPCAP_REG_CRM_VCHRG1 BIT(5) |
51 | #define CPCAP_REG_CRM_VCHRG0 BIT(4) |
52 | #define CPCAP_REG_CRM_ICHRG3 BIT(3) /* Charge current bits */ |
53 | #define CPCAP_REG_CRM_ICHRG2 BIT(2) |
54 | #define CPCAP_REG_CRM_ICHRG1 BIT(1) |
55 | #define CPCAP_REG_CRM_ICHRG0 BIT(0) |
56 | |
57 | /* CPCAP_REG_CRM trickle charge voltages */ |
58 | #define CPCAP_REG_CRM_TR(val) (((val) & 0x3) << 10) |
59 | #define CPCAP_REG_CRM_TR_0A00 CPCAP_REG_CRM_TR(0x0) |
60 | #define CPCAP_REG_CRM_TR_0A24 CPCAP_REG_CRM_TR(0x1) |
61 | #define CPCAP_REG_CRM_TR_0A48 CPCAP_REG_CRM_TR(0x2) |
62 | #define CPCAP_REG_CRM_TR_0A72 CPCAP_REG_CRM_TR(0x4) |
63 | |
64 | /* |
65 | * CPCAP_REG_CRM charge voltages based on the ADC channel 1 values. |
66 | * Note that these register bits don't match MC13783UG.pdf VCHRG |
67 | * register bits. |
68 | */ |
69 | #define CPCAP_REG_CRM_VCHRG(val) (((val) & 0xf) << 4) |
70 | #define CPCAP_REG_CRM_VCHRG_3V80 CPCAP_REG_CRM_VCHRG(0x0) |
71 | #define CPCAP_REG_CRM_VCHRG_4V10 CPCAP_REG_CRM_VCHRG(0x1) |
72 | #define CPCAP_REG_CRM_VCHRG_4V12 CPCAP_REG_CRM_VCHRG(0x2) |
73 | #define CPCAP_REG_CRM_VCHRG_4V15 CPCAP_REG_CRM_VCHRG(0x3) |
74 | #define CPCAP_REG_CRM_VCHRG_4V17 CPCAP_REG_CRM_VCHRG(0x4) |
75 | #define CPCAP_REG_CRM_VCHRG_4V20 CPCAP_REG_CRM_VCHRG(0x5) |
76 | #define CPCAP_REG_CRM_VCHRG_4V23 CPCAP_REG_CRM_VCHRG(0x6) |
77 | #define CPCAP_REG_CRM_VCHRG_4V25 CPCAP_REG_CRM_VCHRG(0x7) |
78 | #define CPCAP_REG_CRM_VCHRG_4V27 CPCAP_REG_CRM_VCHRG(0x8) |
79 | #define CPCAP_REG_CRM_VCHRG_4V30 CPCAP_REG_CRM_VCHRG(0x9) |
80 | #define CPCAP_REG_CRM_VCHRG_4V33 CPCAP_REG_CRM_VCHRG(0xa) |
81 | #define CPCAP_REG_CRM_VCHRG_4V35 CPCAP_REG_CRM_VCHRG(0xb) |
82 | #define CPCAP_REG_CRM_VCHRG_4V38 CPCAP_REG_CRM_VCHRG(0xc) |
83 | #define CPCAP_REG_CRM_VCHRG_4V40 CPCAP_REG_CRM_VCHRG(0xd) |
84 | #define CPCAP_REG_CRM_VCHRG_4V42 CPCAP_REG_CRM_VCHRG(0xe) |
85 | #define CPCAP_REG_CRM_VCHRG_4V44 CPCAP_REG_CRM_VCHRG(0xf) |
86 | |
87 | /* |
88 | * CPCAP_REG_CRM charge currents. These seem to match MC13783UG.pdf |
89 | * values in "Table 8-3. Charge Path Regulator Current Limit |
90 | * Characteristics" for the nominal values. |
91 | * |
92 | * Except 70mA and 1.596A and unlimited, these are simply 88.7mA / step. |
93 | */ |
94 | #define CPCAP_REG_CRM_ICHRG(val) (((val) & 0xf) << 0) |
95 | #define CPCAP_REG_CRM_ICHRG_0A000 CPCAP_REG_CRM_ICHRG(0x0) |
96 | #define CPCAP_REG_CRM_ICHRG_0A070 CPCAP_REG_CRM_ICHRG(0x1) |
97 | #define CPCAP_REG_CRM_ICHRG_0A177 CPCAP_REG_CRM_ICHRG(0x2) |
98 | #define CPCAP_REG_CRM_ICHRG_0A266 CPCAP_REG_CRM_ICHRG(0x3) |
99 | #define CPCAP_REG_CRM_ICHRG_0A355 CPCAP_REG_CRM_ICHRG(0x4) |
100 | #define CPCAP_REG_CRM_ICHRG_0A443 CPCAP_REG_CRM_ICHRG(0x5) |
101 | #define CPCAP_REG_CRM_ICHRG_0A532 CPCAP_REG_CRM_ICHRG(0x6) |
102 | #define CPCAP_REG_CRM_ICHRG_0A621 CPCAP_REG_CRM_ICHRG(0x7) |
103 | #define CPCAP_REG_CRM_ICHRG_0A709 CPCAP_REG_CRM_ICHRG(0x8) |
104 | #define CPCAP_REG_CRM_ICHRG_0A798 CPCAP_REG_CRM_ICHRG(0x9) |
105 | #define CPCAP_REG_CRM_ICHRG_0A886 CPCAP_REG_CRM_ICHRG(0xa) |
106 | #define CPCAP_REG_CRM_ICHRG_0A975 CPCAP_REG_CRM_ICHRG(0xb) |
107 | #define CPCAP_REG_CRM_ICHRG_1A064 CPCAP_REG_CRM_ICHRG(0xc) |
108 | #define CPCAP_REG_CRM_ICHRG_1A152 CPCAP_REG_CRM_ICHRG(0xd) |
109 | #define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe) |
110 | #define CPCAP_REG_CRM_ICHRG_NO_LIMIT CPCAP_REG_CRM_ICHRG(0xf) |
111 | |
112 | /* CPCAP_REG_VUSBC register bits needed for VBUS */ |
113 | #define CPCAP_BIT_VBUS_SWITCH BIT(0) /* VBUS boost to 5V */ |
114 | |
115 | enum { |
116 | CPCAP_CHARGER_IIO_BATTDET, |
117 | CPCAP_CHARGER_IIO_VOLTAGE, |
118 | CPCAP_CHARGER_IIO_VBUS, |
119 | CPCAP_CHARGER_IIO_CHRG_CURRENT, |
120 | CPCAP_CHARGER_IIO_BATT_CURRENT, |
121 | CPCAP_CHARGER_IIO_NR, |
122 | }; |
123 | |
124 | struct cpcap_charger_ddata { |
125 | struct device *dev; |
126 | struct regmap *reg; |
127 | struct list_head irq_list; |
128 | struct delayed_work detect_work; |
129 | struct delayed_work vbus_work; |
130 | struct gpio_desc *gpio[2]; /* gpio_reven0 & 1 */ |
131 | |
132 | struct iio_channel *channels[CPCAP_CHARGER_IIO_NR]; |
133 | |
134 | struct power_supply *usb; |
135 | |
136 | struct phy_companion comparator; /* For USB VBUS */ |
137 | unsigned int vbus_enabled:1; |
138 | unsigned int feeding_vbus:1; |
139 | atomic_t active; |
140 | |
141 | int status; |
142 | int voltage; |
143 | int limit_current; |
144 | }; |
145 | |
146 | struct cpcap_interrupt_desc { |
147 | int irq; |
148 | struct list_head node; |
149 | const char *name; |
150 | }; |
151 | |
152 | struct cpcap_charger_ints_state { |
153 | bool chrg_det; |
154 | bool rvrs_chrg; |
155 | bool vbusov; |
156 | |
157 | bool chrg_se1b; |
158 | bool rvrs_mode; |
159 | bool chrgcurr2; |
160 | bool chrgcurr1; |
161 | bool vbusvld; |
162 | |
163 | bool battdetb; |
164 | }; |
165 | |
166 | static enum power_supply_property cpcap_charger_props[] = { |
167 | POWER_SUPPLY_PROP_STATUS, |
168 | POWER_SUPPLY_PROP_ONLINE, |
169 | POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, |
170 | POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, |
171 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
172 | POWER_SUPPLY_PROP_CURRENT_NOW, |
173 | }; |
174 | |
175 | static int cpcap_charger_get_charge_voltage(struct cpcap_charger_ddata *ddata) |
176 | { |
177 | struct iio_channel *channel; |
178 | int error, value = 0; |
179 | |
180 | channel = ddata->channels[CPCAP_CHARGER_IIO_VOLTAGE]; |
181 | error = iio_read_channel_processed(chan: channel, val: &value); |
182 | if (error < 0) { |
183 | dev_warn(ddata->dev, "%s failed: %i\n" , __func__, error); |
184 | |
185 | return 0; |
186 | } |
187 | |
188 | return value; |
189 | } |
190 | |
191 | static int cpcap_charger_get_charge_current(struct cpcap_charger_ddata *ddata) |
192 | { |
193 | struct iio_channel *channel; |
194 | int error, value = 0; |
195 | |
196 | channel = ddata->channels[CPCAP_CHARGER_IIO_CHRG_CURRENT]; |
197 | error = iio_read_channel_processed(chan: channel, val: &value); |
198 | if (error < 0) { |
199 | dev_warn(ddata->dev, "%s failed: %i\n" , __func__, error); |
200 | |
201 | return 0; |
202 | } |
203 | |
204 | return value; |
205 | } |
206 | |
207 | static int cpcap_charger_get_property(struct power_supply *psy, |
208 | enum power_supply_property psp, |
209 | union power_supply_propval *val) |
210 | { |
211 | struct cpcap_charger_ddata *ddata = dev_get_drvdata(dev: psy->dev.parent); |
212 | |
213 | switch (psp) { |
214 | case POWER_SUPPLY_PROP_STATUS: |
215 | val->intval = ddata->status; |
216 | break; |
217 | case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: |
218 | val->intval = ddata->limit_current; |
219 | break; |
220 | case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: |
221 | val->intval = ddata->voltage; |
222 | break; |
223 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: |
224 | if (ddata->status == POWER_SUPPLY_STATUS_CHARGING) |
225 | val->intval = cpcap_charger_get_charge_voltage(ddata) * |
226 | 1000; |
227 | else |
228 | val->intval = 0; |
229 | break; |
230 | case POWER_SUPPLY_PROP_CURRENT_NOW: |
231 | if (ddata->status == POWER_SUPPLY_STATUS_CHARGING) |
232 | val->intval = cpcap_charger_get_charge_current(ddata) * |
233 | 1000; |
234 | else |
235 | val->intval = 0; |
236 | break; |
237 | case POWER_SUPPLY_PROP_ONLINE: |
238 | val->intval = ddata->status == POWER_SUPPLY_STATUS_CHARGING; |
239 | break; |
240 | default: |
241 | return -EINVAL; |
242 | } |
243 | |
244 | return 0; |
245 | } |
246 | |
247 | static int cpcap_charger_match_voltage(int voltage) |
248 | { |
249 | switch (voltage) { |
250 | case 0 ... 4100000 - 1: return 3800000; |
251 | case 4100000 ... 4120000 - 1: return 4100000; |
252 | case 4120000 ... 4150000 - 1: return 4120000; |
253 | case 4150000 ... 4170000 - 1: return 4150000; |
254 | case 4170000 ... 4200000 - 1: return 4170000; |
255 | case 4200000 ... 4230000 - 1: return 4200000; |
256 | case 4230000 ... 4250000 - 1: return 4230000; |
257 | case 4250000 ... 4270000 - 1: return 4250000; |
258 | case 4270000 ... 4300000 - 1: return 4270000; |
259 | case 4300000 ... 4330000 - 1: return 4300000; |
260 | case 4330000 ... 4350000 - 1: return 4330000; |
261 | case 4350000 ... 4380000 - 1: return 4350000; |
262 | case 4380000 ... 4400000 - 1: return 4380000; |
263 | case 4400000 ... 4420000 - 1: return 4400000; |
264 | case 4420000 ... 4440000 - 1: return 4420000; |
265 | case 4440000: return 4440000; |
266 | default: return 0; |
267 | } |
268 | } |
269 | |
270 | static int |
271 | cpcap_charger_get_bat_const_charge_voltage(struct cpcap_charger_ddata *ddata) |
272 | { |
273 | union power_supply_propval prop; |
274 | struct power_supply *battery; |
275 | int voltage = ddata->voltage; |
276 | int error; |
277 | |
278 | battery = power_supply_get_by_name(name: "battery" ); |
279 | if (battery) { |
280 | error = power_supply_get_property(psy: battery, |
281 | psp: POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, |
282 | val: &prop); |
283 | if (!error) |
284 | voltage = prop.intval; |
285 | |
286 | power_supply_put(psy: battery); |
287 | } |
288 | |
289 | return voltage; |
290 | } |
291 | |
292 | static int cpcap_charger_current_to_regval(int microamp) |
293 | { |
294 | int miliamp = microamp / 1000; |
295 | int res; |
296 | |
297 | if (miliamp < 0) |
298 | return -EINVAL; |
299 | if (miliamp < 70) |
300 | return CPCAP_REG_CRM_ICHRG(0x0); |
301 | if (miliamp < 177) |
302 | return CPCAP_REG_CRM_ICHRG(0x1); |
303 | if (miliamp >= 1596) |
304 | return CPCAP_REG_CRM_ICHRG(0xe); |
305 | |
306 | res = microamp / 88666; |
307 | if (res > 0xd) |
308 | res = 0xd; |
309 | return CPCAP_REG_CRM_ICHRG(res); |
310 | } |
311 | |
312 | static int cpcap_charger_set_property(struct power_supply *psy, |
313 | enum power_supply_property psp, |
314 | const union power_supply_propval *val) |
315 | { |
316 | struct cpcap_charger_ddata *ddata = dev_get_drvdata(dev: psy->dev.parent); |
317 | int voltage, batvolt; |
318 | |
319 | switch (psp) { |
320 | case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: |
321 | if (cpcap_charger_current_to_regval(microamp: val->intval) < 0) |
322 | return -EINVAL; |
323 | ddata->limit_current = val->intval; |
324 | schedule_delayed_work(dwork: &ddata->detect_work, delay: 0); |
325 | break; |
326 | case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: |
327 | voltage = cpcap_charger_match_voltage(voltage: val->intval); |
328 | batvolt = cpcap_charger_get_bat_const_charge_voltage(ddata); |
329 | if (voltage > batvolt) |
330 | voltage = batvolt; |
331 | ddata->voltage = voltage; |
332 | schedule_delayed_work(dwork: &ddata->detect_work, delay: 0); |
333 | break; |
334 | default: |
335 | return -EINVAL; |
336 | } |
337 | |
338 | return 0; |
339 | } |
340 | |
341 | static int cpcap_charger_property_is_writeable(struct power_supply *psy, |
342 | enum power_supply_property psp) |
343 | { |
344 | switch (psp) { |
345 | case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: |
346 | case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: |
347 | return 1; |
348 | default: |
349 | return 0; |
350 | } |
351 | } |
352 | |
353 | static void cpcap_charger_set_cable_path(struct cpcap_charger_ddata *ddata, |
354 | bool enabled) |
355 | { |
356 | if (!ddata->gpio[0]) |
357 | return; |
358 | |
359 | gpiod_set_value(desc: ddata->gpio[0], value: enabled); |
360 | } |
361 | |
362 | static void cpcap_charger_set_inductive_path(struct cpcap_charger_ddata *ddata, |
363 | bool enabled) |
364 | { |
365 | if (!ddata->gpio[1]) |
366 | return; |
367 | |
368 | gpiod_set_value(desc: ddata->gpio[1], value: enabled); |
369 | } |
370 | |
371 | static void cpcap_charger_update_state(struct cpcap_charger_ddata *ddata, |
372 | int state) |
373 | { |
374 | const char *status; |
375 | |
376 | if (state > POWER_SUPPLY_STATUS_FULL) { |
377 | dev_warn(ddata->dev, "unknown state: %i\n" , state); |
378 | |
379 | return; |
380 | } |
381 | |
382 | ddata->status = state; |
383 | |
384 | switch (state) { |
385 | case POWER_SUPPLY_STATUS_DISCHARGING: |
386 | status = "DISCONNECTED" ; |
387 | break; |
388 | case POWER_SUPPLY_STATUS_NOT_CHARGING: |
389 | status = "DETECTING" ; |
390 | break; |
391 | case POWER_SUPPLY_STATUS_CHARGING: |
392 | status = "CHARGING" ; |
393 | break; |
394 | case POWER_SUPPLY_STATUS_FULL: |
395 | status = "DONE" ; |
396 | break; |
397 | default: |
398 | return; |
399 | } |
400 | |
401 | dev_dbg(ddata->dev, "state: %s\n" , status); |
402 | } |
403 | |
404 | static int cpcap_charger_disable(struct cpcap_charger_ddata *ddata) |
405 | { |
406 | int error; |
407 | |
408 | error = regmap_update_bits(map: ddata->reg, CPCAP_REG_CRM, mask: 0x3fff, |
409 | CPCAP_REG_CRM_FET_OVRD | |
410 | CPCAP_REG_CRM_FET_CTRL); |
411 | if (error) |
412 | dev_err(ddata->dev, "%s failed with %i\n" , __func__, error); |
413 | |
414 | return error; |
415 | } |
416 | |
417 | static int cpcap_charger_enable(struct cpcap_charger_ddata *ddata, |
418 | int max_voltage, int charge_current, |
419 | int trickle_current) |
420 | { |
421 | int error; |
422 | |
423 | if (!max_voltage || !charge_current) |
424 | return -EINVAL; |
425 | |
426 | dev_dbg(ddata->dev, "enable: %i %i %i\n" , |
427 | max_voltage, charge_current, trickle_current); |
428 | |
429 | error = regmap_update_bits(map: ddata->reg, CPCAP_REG_CRM, mask: 0x3fff, |
430 | CPCAP_REG_CRM_CHRG_LED_EN | |
431 | trickle_current | |
432 | CPCAP_REG_CRM_FET_OVRD | |
433 | CPCAP_REG_CRM_FET_CTRL | |
434 | max_voltage | |
435 | charge_current); |
436 | if (error) |
437 | dev_err(ddata->dev, "%s failed with %i\n" , __func__, error); |
438 | |
439 | return error; |
440 | } |
441 | |
442 | static bool cpcap_charger_vbus_valid(struct cpcap_charger_ddata *ddata) |
443 | { |
444 | int error, value = 0; |
445 | struct iio_channel *channel = |
446 | ddata->channels[CPCAP_CHARGER_IIO_VBUS]; |
447 | |
448 | error = iio_read_channel_processed(chan: channel, val: &value); |
449 | if (error >= 0) |
450 | return value > 3900; |
451 | |
452 | dev_err(ddata->dev, "error reading VBUS: %i\n" , error); |
453 | |
454 | return false; |
455 | } |
456 | |
457 | /* VBUS control functions for the USB PHY companion */ |
458 | static void cpcap_charger_vbus_work(struct work_struct *work) |
459 | { |
460 | struct cpcap_charger_ddata *ddata; |
461 | bool vbus = false; |
462 | int error; |
463 | |
464 | ddata = container_of(work, struct cpcap_charger_ddata, |
465 | vbus_work.work); |
466 | |
467 | if (ddata->vbus_enabled) { |
468 | vbus = cpcap_charger_vbus_valid(ddata); |
469 | if (vbus) { |
470 | dev_dbg(ddata->dev, "VBUS already provided\n" ); |
471 | |
472 | return; |
473 | } |
474 | |
475 | ddata->feeding_vbus = true; |
476 | cpcap_charger_set_cable_path(ddata, enabled: false); |
477 | cpcap_charger_set_inductive_path(ddata, enabled: false); |
478 | |
479 | error = cpcap_charger_disable(ddata); |
480 | if (error) |
481 | goto out_err; |
482 | |
483 | cpcap_charger_update_state(ddata, |
484 | state: POWER_SUPPLY_STATUS_DISCHARGING); |
485 | |
486 | error = regmap_update_bits(map: ddata->reg, CPCAP_REG_VUSBC, |
487 | CPCAP_BIT_VBUS_SWITCH, |
488 | CPCAP_BIT_VBUS_SWITCH); |
489 | if (error) |
490 | goto out_err; |
491 | |
492 | error = regmap_update_bits(map: ddata->reg, CPCAP_REG_CRM, |
493 | CPCAP_REG_CRM_RVRSMODE, |
494 | CPCAP_REG_CRM_RVRSMODE); |
495 | if (error) |
496 | goto out_err; |
497 | } else { |
498 | error = regmap_update_bits(map: ddata->reg, CPCAP_REG_VUSBC, |
499 | CPCAP_BIT_VBUS_SWITCH, val: 0); |
500 | if (error) |
501 | goto out_err; |
502 | |
503 | error = regmap_update_bits(map: ddata->reg, CPCAP_REG_CRM, |
504 | CPCAP_REG_CRM_RVRSMODE, val: 0); |
505 | if (error) |
506 | goto out_err; |
507 | |
508 | cpcap_charger_set_cable_path(ddata, enabled: true); |
509 | cpcap_charger_set_inductive_path(ddata, enabled: true); |
510 | ddata->feeding_vbus = false; |
511 | } |
512 | |
513 | return; |
514 | |
515 | out_err: |
516 | cpcap_charger_update_state(ddata, state: POWER_SUPPLY_STATUS_UNKNOWN); |
517 | dev_err(ddata->dev, "%s could not %s vbus: %i\n" , __func__, |
518 | ddata->vbus_enabled ? "enable" : "disable" , error); |
519 | } |
520 | |
521 | static int cpcap_charger_set_vbus(struct phy_companion *comparator, |
522 | bool enabled) |
523 | { |
524 | struct cpcap_charger_ddata *ddata = |
525 | container_of(comparator, struct cpcap_charger_ddata, |
526 | comparator); |
527 | |
528 | ddata->vbus_enabled = enabled; |
529 | schedule_delayed_work(dwork: &ddata->vbus_work, delay: 0); |
530 | |
531 | return 0; |
532 | } |
533 | |
534 | /* Charger interrupt handling functions */ |
535 | |
536 | static int cpcap_charger_get_ints_state(struct cpcap_charger_ddata *ddata, |
537 | struct cpcap_charger_ints_state *s) |
538 | { |
539 | int val, error; |
540 | |
541 | error = regmap_read(map: ddata->reg, CPCAP_REG_INTS1, val: &val); |
542 | if (error) |
543 | return error; |
544 | |
545 | s->chrg_det = val & BIT(13); |
546 | s->rvrs_chrg = val & BIT(12); |
547 | s->vbusov = val & BIT(11); |
548 | |
549 | error = regmap_read(map: ddata->reg, CPCAP_REG_INTS2, val: &val); |
550 | if (error) |
551 | return error; |
552 | |
553 | s->chrg_se1b = val & BIT(13); |
554 | s->rvrs_mode = val & BIT(6); |
555 | s->chrgcurr2 = val & BIT(5); |
556 | s->chrgcurr1 = val & BIT(4); |
557 | s->vbusvld = val & BIT(3); |
558 | |
559 | error = regmap_read(map: ddata->reg, CPCAP_REG_INTS4, val: &val); |
560 | if (error) |
561 | return error; |
562 | |
563 | s->battdetb = val & BIT(6); |
564 | |
565 | return 0; |
566 | } |
567 | |
568 | static int cpcap_charger_voltage_to_regval(int voltage) |
569 | { |
570 | int offset; |
571 | |
572 | switch (voltage) { |
573 | case 0 ... 4100000 - 1: |
574 | return 0; |
575 | case 4100000 ... 4200000 - 1: |
576 | offset = 1; |
577 | break; |
578 | case 4200000 ... 4300000 - 1: |
579 | offset = 0; |
580 | break; |
581 | case 4300000 ... 4380000 - 1: |
582 | offset = -1; |
583 | break; |
584 | case 4380000 ... 4440000: |
585 | offset = -2; |
586 | break; |
587 | default: |
588 | return 0; |
589 | } |
590 | |
591 | return ((voltage - 4100000) / 20000) + offset; |
592 | } |
593 | |
594 | static void cpcap_charger_disconnect(struct cpcap_charger_ddata *ddata, |
595 | int state, unsigned long delay) |
596 | { |
597 | int error; |
598 | |
599 | /* Update battery state before disconnecting the charger */ |
600 | switch (state) { |
601 | case POWER_SUPPLY_STATUS_DISCHARGING: |
602 | case POWER_SUPPLY_STATUS_FULL: |
603 | power_supply_changed(psy: ddata->usb); |
604 | break; |
605 | default: |
606 | break; |
607 | } |
608 | |
609 | error = cpcap_charger_disable(ddata); |
610 | if (error) { |
611 | cpcap_charger_update_state(ddata, state: POWER_SUPPLY_STATUS_UNKNOWN); |
612 | return; |
613 | } |
614 | |
615 | cpcap_charger_update_state(ddata, state); |
616 | power_supply_changed(psy: ddata->usb); |
617 | schedule_delayed_work(dwork: &ddata->detect_work, delay); |
618 | } |
619 | |
620 | static void cpcap_usb_detect(struct work_struct *work) |
621 | { |
622 | struct cpcap_charger_ddata *ddata; |
623 | struct cpcap_charger_ints_state s; |
624 | int error, new_state; |
625 | |
626 | ddata = container_of(work, struct cpcap_charger_ddata, |
627 | detect_work.work); |
628 | |
629 | error = cpcap_charger_get_ints_state(ddata, s: &s); |
630 | if (error) |
631 | return; |
632 | |
633 | /* Just init the state if a charger is connected with no chrg_det set */ |
634 | if (!s.chrg_det && s.chrgcurr1 && s.vbusvld) { |
635 | cpcap_charger_update_state(ddata, |
636 | state: POWER_SUPPLY_STATUS_NOT_CHARGING); |
637 | |
638 | return; |
639 | } |
640 | |
641 | /* |
642 | * If battery voltage is higher than charge voltage, it may have been |
643 | * charged to 4.35V by Android. Try again in 10 minutes. |
644 | */ |
645 | if (cpcap_charger_get_charge_voltage(ddata) > ddata->voltage) { |
646 | cpcap_charger_disconnect(ddata, |
647 | state: POWER_SUPPLY_STATUS_NOT_CHARGING, |
648 | HZ * 60 * 10); |
649 | |
650 | return; |
651 | } |
652 | |
653 | /* Delay for 80ms to avoid vbus bouncing when usb cable is plugged in */ |
654 | usleep_range(min: 80000, max: 120000); |
655 | |
656 | /* Throttle chrgcurr2 interrupt for charger done and retry */ |
657 | switch (ddata->status) { |
658 | case POWER_SUPPLY_STATUS_CHARGING: |
659 | if (s.chrgcurr2) |
660 | break; |
661 | new_state = POWER_SUPPLY_STATUS_FULL; |
662 | |
663 | if (s.chrgcurr1 && s.vbusvld) { |
664 | cpcap_charger_disconnect(ddata, state: new_state, HZ * 5); |
665 | return; |
666 | } |
667 | break; |
668 | case POWER_SUPPLY_STATUS_FULL: |
669 | if (!s.chrgcurr2) |
670 | break; |
671 | if (s.vbusvld) |
672 | new_state = POWER_SUPPLY_STATUS_NOT_CHARGING; |
673 | else |
674 | new_state = POWER_SUPPLY_STATUS_DISCHARGING; |
675 | |
676 | cpcap_charger_disconnect(ddata, state: new_state, HZ * 5); |
677 | |
678 | return; |
679 | default: |
680 | break; |
681 | } |
682 | |
683 | if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) && |
684 | s.chrgcurr1) { |
685 | int max_current; |
686 | int vchrg, ichrg; |
687 | union power_supply_propval val; |
688 | struct power_supply *battery; |
689 | |
690 | battery = power_supply_get_by_name(name: "battery" ); |
691 | if (IS_ERR_OR_NULL(ptr: battery)) { |
692 | dev_err(ddata->dev, "battery power_supply not available %li\n" , |
693 | PTR_ERR(battery)); |
694 | return; |
695 | } |
696 | |
697 | error = power_supply_get_property(psy: battery, psp: POWER_SUPPLY_PROP_PRESENT, val: &val); |
698 | power_supply_put(psy: battery); |
699 | if (error) |
700 | goto out_err; |
701 | |
702 | if (val.intval) { |
703 | max_current = 1596000; |
704 | } else { |
705 | dev_info(ddata->dev, "battery not inserted, charging disabled\n" ); |
706 | max_current = 0; |
707 | } |
708 | |
709 | if (max_current > ddata->limit_current) |
710 | max_current = ddata->limit_current; |
711 | |
712 | ichrg = cpcap_charger_current_to_regval(microamp: max_current); |
713 | vchrg = cpcap_charger_voltage_to_regval(voltage: ddata->voltage); |
714 | error = cpcap_charger_enable(ddata, |
715 | CPCAP_REG_CRM_VCHRG(vchrg), |
716 | charge_current: ichrg, trickle_current: 0); |
717 | if (error) |
718 | goto out_err; |
719 | cpcap_charger_update_state(ddata, |
720 | state: POWER_SUPPLY_STATUS_CHARGING); |
721 | } else { |
722 | error = cpcap_charger_disable(ddata); |
723 | if (error) |
724 | goto out_err; |
725 | cpcap_charger_update_state(ddata, |
726 | state: POWER_SUPPLY_STATUS_DISCHARGING); |
727 | } |
728 | |
729 | power_supply_changed(psy: ddata->usb); |
730 | return; |
731 | |
732 | out_err: |
733 | cpcap_charger_update_state(ddata, state: POWER_SUPPLY_STATUS_UNKNOWN); |
734 | dev_err(ddata->dev, "%s failed with %i\n" , __func__, error); |
735 | } |
736 | |
737 | static irqreturn_t cpcap_charger_irq_thread(int irq, void *data) |
738 | { |
739 | struct cpcap_charger_ddata *ddata = data; |
740 | |
741 | if (!atomic_read(v: &ddata->active)) |
742 | return IRQ_NONE; |
743 | |
744 | schedule_delayed_work(dwork: &ddata->detect_work, delay: 0); |
745 | |
746 | return IRQ_HANDLED; |
747 | } |
748 | |
749 | static int cpcap_usb_init_irq(struct platform_device *pdev, |
750 | struct cpcap_charger_ddata *ddata, |
751 | const char *name) |
752 | { |
753 | struct cpcap_interrupt_desc *d; |
754 | int irq, error; |
755 | |
756 | irq = platform_get_irq_byname(pdev, name); |
757 | if (irq < 0) |
758 | return -ENODEV; |
759 | |
760 | error = devm_request_threaded_irq(dev: ddata->dev, irq, NULL, |
761 | thread_fn: cpcap_charger_irq_thread, |
762 | IRQF_SHARED | IRQF_ONESHOT, |
763 | devname: name, dev_id: ddata); |
764 | if (error) { |
765 | dev_err(ddata->dev, "could not get irq %s: %i\n" , |
766 | name, error); |
767 | |
768 | return error; |
769 | } |
770 | |
771 | d = devm_kzalloc(dev: ddata->dev, size: sizeof(*d), GFP_KERNEL); |
772 | if (!d) |
773 | return -ENOMEM; |
774 | |
775 | d->name = name; |
776 | d->irq = irq; |
777 | list_add(new: &d->node, head: &ddata->irq_list); |
778 | |
779 | return 0; |
780 | } |
781 | |
782 | static const char * const cpcap_charger_irqs[] = { |
783 | /* REG_INT_0 */ |
784 | "chrg_det" , "rvrs_chrg" , |
785 | |
786 | /* REG_INT1 */ |
787 | "chrg_se1b" , "se0conn" , "rvrs_mode" , "chrgcurr2" , "chrgcurr1" , "vbusvld" , |
788 | |
789 | /* REG_INT_3 */ |
790 | "battdetb" , |
791 | }; |
792 | |
793 | static int cpcap_usb_init_interrupts(struct platform_device *pdev, |
794 | struct cpcap_charger_ddata *ddata) |
795 | { |
796 | int i, error; |
797 | |
798 | for (i = 0; i < ARRAY_SIZE(cpcap_charger_irqs); i++) { |
799 | error = cpcap_usb_init_irq(pdev, ddata, name: cpcap_charger_irqs[i]); |
800 | if (error) |
801 | return error; |
802 | } |
803 | |
804 | return 0; |
805 | } |
806 | |
807 | static void cpcap_charger_init_optional_gpios(struct cpcap_charger_ddata *ddata) |
808 | { |
809 | int i; |
810 | |
811 | for (i = 0; i < 2; i++) { |
812 | ddata->gpio[i] = devm_gpiod_get_index(dev: ddata->dev, con_id: "mode" , |
813 | idx: i, flags: GPIOD_OUT_HIGH); |
814 | if (IS_ERR(ptr: ddata->gpio[i])) { |
815 | dev_info(ddata->dev, "no mode change GPIO%i: %li\n" , |
816 | i, PTR_ERR(ddata->gpio[i])); |
817 | ddata->gpio[i] = NULL; |
818 | } |
819 | } |
820 | } |
821 | |
822 | static int cpcap_charger_init_iio(struct cpcap_charger_ddata *ddata) |
823 | { |
824 | const char * const names[CPCAP_CHARGER_IIO_NR] = { |
825 | "battdetb" , "battp" , "vbus" , "chg_isense" , "batti" , |
826 | }; |
827 | int error, i; |
828 | |
829 | for (i = 0; i < CPCAP_CHARGER_IIO_NR; i++) { |
830 | ddata->channels[i] = devm_iio_channel_get(dev: ddata->dev, |
831 | consumer_channel: names[i]); |
832 | if (IS_ERR(ptr: ddata->channels[i])) { |
833 | error = PTR_ERR(ptr: ddata->channels[i]); |
834 | goto out_err; |
835 | } |
836 | |
837 | if (!ddata->channels[i]->indio_dev) { |
838 | error = -ENXIO; |
839 | goto out_err; |
840 | } |
841 | } |
842 | |
843 | return 0; |
844 | |
845 | out_err: |
846 | if (error != -EPROBE_DEFER) |
847 | dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n" , |
848 | error); |
849 | |
850 | return error; |
851 | } |
852 | |
853 | static char *cpcap_charger_supplied_to[] = { |
854 | "battery" , |
855 | }; |
856 | |
857 | static const struct power_supply_desc cpcap_charger_usb_desc = { |
858 | .name = "usb" , |
859 | .type = POWER_SUPPLY_TYPE_USB, |
860 | .properties = cpcap_charger_props, |
861 | .num_properties = ARRAY_SIZE(cpcap_charger_props), |
862 | .get_property = cpcap_charger_get_property, |
863 | .set_property = cpcap_charger_set_property, |
864 | .property_is_writeable = cpcap_charger_property_is_writeable, |
865 | }; |
866 | |
867 | static const struct of_device_id cpcap_charger_id_table[] = { |
868 | { |
869 | .compatible = "motorola,mapphone-cpcap-charger" , |
870 | }, |
871 | {}, |
872 | }; |
873 | MODULE_DEVICE_TABLE(of, cpcap_charger_id_table); |
874 | |
875 | static int cpcap_charger_probe(struct platform_device *pdev) |
876 | { |
877 | struct cpcap_charger_ddata *ddata; |
878 | struct power_supply_config psy_cfg = {}; |
879 | int error; |
880 | |
881 | ddata = devm_kzalloc(dev: &pdev->dev, size: sizeof(*ddata), GFP_KERNEL); |
882 | if (!ddata) |
883 | return -ENOMEM; |
884 | |
885 | ddata->dev = &pdev->dev; |
886 | ddata->voltage = 4200000; |
887 | ddata->limit_current = 532000; |
888 | |
889 | ddata->reg = dev_get_regmap(dev: ddata->dev->parent, NULL); |
890 | if (!ddata->reg) |
891 | return -ENODEV; |
892 | |
893 | INIT_LIST_HEAD(list: &ddata->irq_list); |
894 | INIT_DELAYED_WORK(&ddata->detect_work, cpcap_usb_detect); |
895 | INIT_DELAYED_WORK(&ddata->vbus_work, cpcap_charger_vbus_work); |
896 | platform_set_drvdata(pdev, data: ddata); |
897 | |
898 | error = cpcap_charger_init_iio(ddata); |
899 | if (error) |
900 | return error; |
901 | |
902 | atomic_set(v: &ddata->active, i: 1); |
903 | |
904 | psy_cfg.of_node = pdev->dev.of_node; |
905 | psy_cfg.drv_data = ddata; |
906 | psy_cfg.supplied_to = cpcap_charger_supplied_to; |
907 | psy_cfg.num_supplicants = ARRAY_SIZE(cpcap_charger_supplied_to), |
908 | |
909 | ddata->usb = devm_power_supply_register(parent: ddata->dev, |
910 | desc: &cpcap_charger_usb_desc, |
911 | cfg: &psy_cfg); |
912 | if (IS_ERR(ptr: ddata->usb)) { |
913 | error = PTR_ERR(ptr: ddata->usb); |
914 | dev_err(ddata->dev, "failed to register USB charger: %i\n" , |
915 | error); |
916 | |
917 | return error; |
918 | } |
919 | |
920 | error = cpcap_usb_init_interrupts(pdev, ddata); |
921 | if (error) |
922 | return error; |
923 | |
924 | ddata->comparator.set_vbus = cpcap_charger_set_vbus; |
925 | error = omap_usb2_set_comparator(comparator: &ddata->comparator); |
926 | if (error == -ENODEV) { |
927 | dev_info(ddata->dev, "charger needs phy, deferring probe\n" ); |
928 | return -EPROBE_DEFER; |
929 | } |
930 | |
931 | cpcap_charger_init_optional_gpios(ddata); |
932 | |
933 | schedule_delayed_work(dwork: &ddata->detect_work, delay: 0); |
934 | |
935 | return 0; |
936 | } |
937 | |
938 | static void cpcap_charger_shutdown(struct platform_device *pdev) |
939 | { |
940 | struct cpcap_charger_ddata *ddata = platform_get_drvdata(pdev); |
941 | int error; |
942 | |
943 | atomic_set(v: &ddata->active, i: 0); |
944 | error = omap_usb2_set_comparator(NULL); |
945 | if (error) |
946 | dev_warn(ddata->dev, "could not clear USB comparator: %i\n" , |
947 | error); |
948 | |
949 | error = cpcap_charger_disable(ddata); |
950 | if (error) { |
951 | cpcap_charger_update_state(ddata, state: POWER_SUPPLY_STATUS_UNKNOWN); |
952 | dev_warn(ddata->dev, "could not clear charger: %i\n" , |
953 | error); |
954 | } |
955 | cpcap_charger_update_state(ddata, state: POWER_SUPPLY_STATUS_DISCHARGING); |
956 | cancel_delayed_work_sync(dwork: &ddata->vbus_work); |
957 | cancel_delayed_work_sync(dwork: &ddata->detect_work); |
958 | } |
959 | |
960 | static void cpcap_charger_remove(struct platform_device *pdev) |
961 | { |
962 | cpcap_charger_shutdown(pdev); |
963 | } |
964 | |
965 | static struct platform_driver cpcap_charger_driver = { |
966 | .probe = cpcap_charger_probe, |
967 | .driver = { |
968 | .name = "cpcap-charger" , |
969 | .of_match_table = cpcap_charger_id_table, |
970 | }, |
971 | .shutdown = cpcap_charger_shutdown, |
972 | .remove_new = cpcap_charger_remove, |
973 | }; |
974 | module_platform_driver(cpcap_charger_driver); |
975 | |
976 | MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>" ); |
977 | MODULE_DESCRIPTION("CPCAP Battery Charger Interface driver" ); |
978 | MODULE_LICENSE("GPL v2" ); |
979 | MODULE_ALIAS("platform:cpcap-charger" ); |
980 | |