1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * AXP20x PMIC USB power supply status driver
4 *
5 * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
6 * Copyright (C) 2014 Bruno Prémont <bonbons@linux-vserver.org>
7 */
8
9 #include <linux/bitops.h>
10 #include <linux/device.h>
11 #include <linux/devm-helpers.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/kernel.h>
15 #include <linux/mfd/axp20x.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm.h>
20 #include <linux/power_supply.h>
21 #include <linux/regmap.h>
22 #include <linux/slab.h>
23 #include <linux/iio/consumer.h>
24 #include <linux/workqueue.h>
25
26 #define DRVNAME "axp20x-usb-power-supply"
27
28 #define AXP192_USB_OTG_STATUS 0x04
29
30 #define AXP20X_PWR_STATUS_VBUS_PRESENT BIT(5)
31 #define AXP20X_PWR_STATUS_VBUS_USED BIT(4)
32
33 #define AXP717_PWR_STATUS_VBUS_GOOD BIT(5)
34
35 #define AXP20X_USB_STATUS_VBUS_VALID BIT(2)
36
37 #define AXP717_PMU_FAULT_VBUS BIT(5)
38 #define AXP717_PMU_FAULT_VSYS BIT(3)
39
40 #define AXP20X_VBUS_VHOLD_uV(b) (4000000 + (((b) >> 3) & 7) * 100000)
41 #define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3)
42 #define AXP20X_VBUS_VHOLD_OFFSET 3
43
44 #define AXP20X_ADC_EN1_VBUS_CURR BIT(2)
45 #define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
46
47 #define AXP717_INPUT_VOL_LIMIT_MASK GENMASK(3, 0)
48 #define AXP717_INPUT_CUR_LIMIT_MASK GENMASK(5, 0)
49 #define AXP717_ADC_DATA_MASK GENMASK(14, 0)
50
51 #define AXP717_ADC_EN_VBUS_VOLT BIT(2)
52
53 /*
54 * Note do not raise the debounce time, we must report Vusb high within
55 * 100ms otherwise we get Vbus errors in musb.
56 */
57 #define DEBOUNCE_TIME msecs_to_jiffies(50)
58
59 struct axp20x_usb_power;
60
61 struct axp_data {
62 const struct power_supply_desc *power_desc;
63 const char * const *irq_names;
64 unsigned int num_irq_names;
65 const int *curr_lim_table;
66 int curr_lim_table_size;
67 struct reg_field curr_lim_fld;
68 struct reg_field vbus_valid_bit;
69 struct reg_field vbus_mon_bit;
70 struct reg_field usb_bc_en_bit;
71 struct reg_field usb_bc_det_fld;
72 struct reg_field vbus_disable_bit;
73 bool vbus_needs_polling: 1;
74 void (*axp20x_read_vbus)(struct work_struct *work);
75 int (*axp20x_cfg_iio_chan)(struct platform_device *pdev,
76 struct axp20x_usb_power *power);
77 int (*axp20x_cfg_adc_reg)(struct axp20x_usb_power *power);
78 };
79
80 struct axp20x_usb_power {
81 struct device *dev;
82 struct regmap *regmap;
83 struct regmap_field *curr_lim_fld;
84 struct regmap_field *vbus_valid_bit;
85 struct regmap_field *vbus_mon_bit;
86 struct regmap_field *usb_bc_en_bit;
87 struct regmap_field *usb_bc_det_fld;
88 struct regmap_field *vbus_disable_bit;
89 struct power_supply *supply;
90 const struct axp_data *axp_data;
91 struct iio_channel *vbus_v;
92 struct iio_channel *vbus_i;
93 struct delayed_work vbus_detect;
94 int max_input_cur;
95 unsigned int old_status;
96 unsigned int online;
97 unsigned int num_irqs;
98 unsigned int irqs[] __counted_by(num_irqs);
99 };
100
axp20x_usb_vbus_needs_polling(struct axp20x_usb_power * power)101 static bool axp20x_usb_vbus_needs_polling(struct axp20x_usb_power *power)
102 {
103 /*
104 * Polling is only necessary while VBUS is offline. While online, a
105 * present->absent transition implies an online->offline transition
106 * and will trigger the VBUS_REMOVAL IRQ.
107 */
108 if (power->axp_data->vbus_needs_polling && !power->online)
109 return true;
110
111 return false;
112 }
113
axp20x_usb_power_irq(int irq,void * devid)114 static irqreturn_t axp20x_usb_power_irq(int irq, void *devid)
115 {
116 struct axp20x_usb_power *power = devid;
117
118 power_supply_changed(power->supply);
119
120 mod_delayed_work(system_power_efficient_wq, &power->vbus_detect, DEBOUNCE_TIME);
121
122 return IRQ_HANDLED;
123 }
124
axp20x_usb_power_poll_vbus(struct work_struct * work)125 static void axp20x_usb_power_poll_vbus(struct work_struct *work)
126 {
127 struct axp20x_usb_power *power =
128 container_of(work, struct axp20x_usb_power, vbus_detect.work);
129 unsigned int val;
130 int ret;
131
132 ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &val);
133 if (ret)
134 goto out;
135
136 val &= (AXP20X_PWR_STATUS_VBUS_PRESENT | AXP20X_PWR_STATUS_VBUS_USED);
137 if (val != power->old_status)
138 power_supply_changed(power->supply);
139
140 if (power->usb_bc_en_bit && (val & AXP20X_PWR_STATUS_VBUS_PRESENT) !=
141 (power->old_status & AXP20X_PWR_STATUS_VBUS_PRESENT)) {
142 dev_dbg(power->dev, "Cable status changed, re-enabling USB BC");
143 ret = regmap_field_write(power->usb_bc_en_bit, 1);
144 if (ret)
145 dev_err(power->dev, "failed to enable USB BC: errno %d",
146 ret);
147 }
148
149 power->old_status = val;
150 power->online = val & AXP20X_PWR_STATUS_VBUS_USED;
151
152 out:
153 if (axp20x_usb_vbus_needs_polling(power))
154 mod_delayed_work(system_power_efficient_wq, &power->vbus_detect, DEBOUNCE_TIME);
155 }
156
axp717_usb_power_poll_vbus(struct work_struct * work)157 static void axp717_usb_power_poll_vbus(struct work_struct *work)
158 {
159 struct axp20x_usb_power *power =
160 container_of(work, struct axp20x_usb_power, vbus_detect.work);
161 unsigned int val;
162 int ret;
163
164 ret = regmap_read(power->regmap, AXP717_ON_INDICATE, &val);
165 if (ret)
166 return;
167
168 val &= AXP717_PWR_STATUS_VBUS_GOOD;
169 if (val != power->old_status)
170 power_supply_changed(power->supply);
171
172 power->old_status = val;
173 }
174
axp20x_get_usb_type(struct axp20x_usb_power * power,union power_supply_propval * val)175 static int axp20x_get_usb_type(struct axp20x_usb_power *power,
176 union power_supply_propval *val)
177 {
178 unsigned int reg;
179 int ret;
180
181 if (!power->usb_bc_det_fld)
182 return -EINVAL;
183
184 ret = regmap_field_read(power->usb_bc_det_fld, ®);
185 if (ret)
186 return ret;
187
188 switch (reg) {
189 case 1:
190 val->intval = POWER_SUPPLY_USB_TYPE_SDP;
191 break;
192 case 2:
193 val->intval = POWER_SUPPLY_USB_TYPE_CDP;
194 break;
195 case 3:
196 val->intval = POWER_SUPPLY_USB_TYPE_DCP;
197 break;
198 default:
199 val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN;
200 break;
201 }
202
203 return 0;
204 }
205
axp20x_usb_power_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)206 static int axp20x_usb_power_get_property(struct power_supply *psy,
207 enum power_supply_property psp, union power_supply_propval *val)
208 {
209 struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
210 unsigned int input, v;
211 int ret;
212
213 switch (psp) {
214 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
215 ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
216 if (ret)
217 return ret;
218
219 val->intval = AXP20X_VBUS_VHOLD_uV(v);
220 return 0;
221 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
222 if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
223 /*
224 * IIO framework gives mV but Power Supply framework
225 * gives uV.
226 */
227 ret = iio_read_channel_processed_scale(power->vbus_v,
228 &val->intval, 1000);
229 if (ret)
230 return ret;
231
232 return 0;
233 }
234
235 ret = axp20x_read_variable_width(power->regmap,
236 AXP20X_VBUS_V_ADC_H, 12);
237 if (ret < 0)
238 return ret;
239
240 val->intval = ret * 1700; /* 1 step = 1.7 mV */
241 return 0;
242 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
243 ret = regmap_field_read(power->curr_lim_fld, &v);
244 if (ret)
245 return ret;
246
247 if (v < power->axp_data->curr_lim_table_size)
248 val->intval = power->axp_data->curr_lim_table[v];
249 else
250 val->intval = power->axp_data->curr_lim_table[
251 power->axp_data->curr_lim_table_size - 1];
252 return 0;
253 case POWER_SUPPLY_PROP_CURRENT_NOW:
254 if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
255 /*
256 * IIO framework gives mA but Power Supply framework
257 * gives uA.
258 */
259 ret = iio_read_channel_processed_scale(power->vbus_i,
260 &val->intval, 1000);
261 if (ret)
262 return ret;
263
264 return 0;
265 }
266
267 ret = axp20x_read_variable_width(power->regmap,
268 AXP20X_VBUS_I_ADC_H, 12);
269 if (ret < 0)
270 return ret;
271
272 val->intval = ret * 375; /* 1 step = 0.375 mA */
273 return 0;
274
275 case POWER_SUPPLY_PROP_USB_TYPE:
276 return axp20x_get_usb_type(power, val);
277 default:
278 break;
279 }
280
281 /* All the properties below need the input-status reg value */
282 ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &input);
283 if (ret)
284 return ret;
285
286 switch (psp) {
287 case POWER_SUPPLY_PROP_HEALTH:
288 if (!(input & AXP20X_PWR_STATUS_VBUS_PRESENT)) {
289 val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
290 break;
291 }
292
293 val->intval = POWER_SUPPLY_HEALTH_GOOD;
294
295 if (power->vbus_valid_bit) {
296 ret = regmap_field_read(power->vbus_valid_bit, &v);
297 if (ret)
298 return ret;
299
300 if (v == 0)
301 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
302 }
303
304 break;
305 case POWER_SUPPLY_PROP_PRESENT:
306 val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_PRESENT);
307 break;
308 case POWER_SUPPLY_PROP_ONLINE:
309 val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_USED);
310 break;
311 default:
312 return -EINVAL;
313 }
314
315 return 0;
316 }
317
axp717_usb_power_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)318 static int axp717_usb_power_get_property(struct power_supply *psy,
319 enum power_supply_property psp, union power_supply_propval *val)
320 {
321 struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
322 unsigned int v;
323 int ret;
324
325 switch (psp) {
326 case POWER_SUPPLY_PROP_HEALTH:
327 val->intval = POWER_SUPPLY_HEALTH_GOOD;
328 ret = regmap_read(power->regmap, AXP717_ON_INDICATE, &v);
329 if (ret)
330 return ret;
331
332 if (!(v & AXP717_PWR_STATUS_VBUS_GOOD))
333 val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
334
335 ret = regmap_read(power->regmap, AXP717_PMU_FAULT_VBUS, &v);
336 if (ret)
337 return ret;
338
339 v &= (AXP717_PMU_FAULT_VBUS | AXP717_PMU_FAULT_VSYS);
340 if (v) {
341 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
342 regmap_write(power->regmap, AXP717_PMU_FAULT_VBUS, v);
343 }
344
345 break;
346 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
347 ret = regmap_read(power->regmap, AXP717_INPUT_CUR_LIMIT_CTRL, &v);
348 if (ret)
349 return ret;
350
351 /* 50ma step size with 100ma offset. */
352 v &= AXP717_INPUT_CUR_LIMIT_MASK;
353 val->intval = (v * 50000) + 100000;
354 break;
355 case POWER_SUPPLY_PROP_ONLINE:
356 case POWER_SUPPLY_PROP_PRESENT:
357 ret = regmap_read(power->regmap, AXP717_ON_INDICATE, &v);
358 if (ret)
359 return ret;
360 val->intval = !!(v & AXP717_PWR_STATUS_VBUS_GOOD);
361 break;
362 case POWER_SUPPLY_PROP_USB_TYPE:
363 return axp20x_get_usb_type(power, val);
364 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
365 ret = regmap_read(power->regmap, AXP717_INPUT_VOL_LIMIT_CTRL, &v);
366 if (ret)
367 return ret;
368
369 /* 80mv step size with 3.88v offset. */
370 v &= AXP717_INPUT_VOL_LIMIT_MASK;
371 val->intval = (v * 80000) + 3880000;
372 break;
373 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
374 if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
375 /*
376 * IIO framework gives mV but Power Supply framework
377 * gives uV.
378 */
379 ret = iio_read_channel_processed_scale(power->vbus_v,
380 &val->intval, 1000);
381 if (ret)
382 return ret;
383
384 return 0;
385 }
386
387 ret = axp20x_read_variable_width(power->regmap,
388 AXP717_VBUS_V_H, 16);
389 if (ret < 0)
390 return ret;
391
392 val->intval = (ret % AXP717_ADC_DATA_MASK) * 1000;
393 break;
394 default:
395 return -EINVAL;
396 }
397
398 return 0;
399
400 }
401
axp20x_usb_power_set_voltage_min(struct axp20x_usb_power * power,int intval)402 static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
403 int intval)
404 {
405 int val;
406
407 switch (intval) {
408 case 4000000:
409 case 4100000:
410 case 4200000:
411 case 4300000:
412 case 4400000:
413 case 4500000:
414 case 4600000:
415 case 4700000:
416 val = (intval - 4000000) / 100000;
417 return regmap_update_bits(power->regmap,
418 AXP20X_VBUS_IPSOUT_MGMT,
419 AXP20X_VBUS_VHOLD_MASK,
420 val << AXP20X_VBUS_VHOLD_OFFSET);
421 default:
422 return -EINVAL;
423 }
424
425 return -EINVAL;
426 }
427
axp717_usb_power_set_voltage_min(struct axp20x_usb_power * power,int intval)428 static int axp717_usb_power_set_voltage_min(struct axp20x_usb_power *power,
429 int intval)
430 {
431 int val;
432
433 /* Minimum value of 3.88v and maximum of 5.08v. */
434 if (intval < 3880000 || intval > 5080000)
435 return -EINVAL;
436
437 /* step size of 80ma with 3.88v offset. */
438 val = (intval - 3880000) / 80000;
439 return regmap_update_bits(power->regmap,
440 AXP717_INPUT_VOL_LIMIT_CTRL,
441 AXP717_INPUT_VOL_LIMIT_MASK, val);
442 }
443
axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power * power,int intval)444 static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power *power,
445 int intval)
446 {
447 int ret;
448 unsigned int reg;
449 const unsigned int max = power->axp_data->curr_lim_table_size;
450
451 if (intval == -1)
452 return -EINVAL;
453
454 if (power->max_input_cur && (intval > power->max_input_cur)) {
455 dev_warn(power->dev,
456 "requested current %d clamped to max current %d\n",
457 intval, power->max_input_cur);
458 intval = power->max_input_cur;
459 }
460
461 /*
462 * BC1.2 detection can cause a race condition if we try to set a current
463 * limit while it's in progress. When it finishes it will overwrite the
464 * current limit we just set.
465 */
466 if (power->usb_bc_en_bit) {
467 dev_dbg(power->dev,
468 "disabling BC1.2 detection because current limit was set");
469 ret = regmap_field_write(power->usb_bc_en_bit, 0);
470 if (ret)
471 return ret;
472 }
473
474 for (reg = max - 1; reg > 0; reg--)
475 if (power->axp_data->curr_lim_table[reg] <= intval)
476 break;
477
478 dev_dbg(power->dev, "setting input current limit reg to %d (%d uA), requested %d uA",
479 reg, power->axp_data->curr_lim_table[reg], intval);
480
481 return regmap_field_write(power->curr_lim_fld, reg);
482 }
483
axp717_usb_power_set_input_current_limit(struct axp20x_usb_power * power,int intval)484 static int axp717_usb_power_set_input_current_limit(struct axp20x_usb_power *power,
485 int intval)
486 {
487 int tmp;
488
489 /* Minimum value of 100mA and maximum value of 3.25A*/
490 if (intval < 100000 || intval > 3250000)
491 return -EINVAL;
492
493 if (power->max_input_cur && (intval > power->max_input_cur)) {
494 dev_warn(power->dev,
495 "reqested current %d clamped to max current %d\n",
496 intval, power->max_input_cur);
497 intval = power->max_input_cur;
498 }
499
500 /* Minimum value of 100mA with step size of 50mA. */
501 tmp = (intval - 100000) / 50000;
502 return regmap_update_bits(power->regmap,
503 AXP717_INPUT_CUR_LIMIT_CTRL,
504 AXP717_INPUT_CUR_LIMIT_MASK, tmp);
505 }
506
axp20x_usb_power_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)507 static int axp20x_usb_power_set_property(struct power_supply *psy,
508 enum power_supply_property psp,
509 const union power_supply_propval *val)
510 {
511 struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
512
513 switch (psp) {
514 case POWER_SUPPLY_PROP_ONLINE:
515 if (!power->vbus_disable_bit)
516 return -EINVAL;
517
518 return regmap_field_write(power->vbus_disable_bit, !val->intval);
519
520 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
521 return axp20x_usb_power_set_voltage_min(power, val->intval);
522
523 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
524 return axp20x_usb_power_set_input_current_limit(power, val->intval);
525
526 default:
527 return -EINVAL;
528 }
529 }
530
axp717_usb_power_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)531 static int axp717_usb_power_set_property(struct power_supply *psy,
532 enum power_supply_property psp,
533 const union power_supply_propval *val)
534 {
535 struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
536
537 switch (psp) {
538 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
539 return axp717_usb_power_set_input_current_limit(power, val->intval);
540
541 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
542 return axp717_usb_power_set_voltage_min(power, val->intval);
543
544 default:
545 return -EINVAL;
546 }
547
548 return -EINVAL;
549 }
550
axp20x_usb_power_prop_writeable(struct power_supply * psy,enum power_supply_property psp)551 static int axp20x_usb_power_prop_writeable(struct power_supply *psy,
552 enum power_supply_property psp)
553 {
554 struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
555
556 /*
557 * The VBUS path select flag works differently on AXP288 and newer:
558 * - On AXP20x and AXP22x, the flag enables VBUS (ignoring N_VBUSEN).
559 * - On AXP288 and AXP8xx, the flag disables VBUS (ignoring N_VBUSEN).
560 * We only expose the control on variants where it can be used to force
561 * the VBUS input offline.
562 */
563 if (psp == POWER_SUPPLY_PROP_ONLINE)
564 return power->vbus_disable_bit != NULL;
565
566 return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
567 psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
568 }
569
axp717_usb_power_prop_writeable(struct power_supply * psy,enum power_supply_property psp)570 static int axp717_usb_power_prop_writeable(struct power_supply *psy,
571 enum power_supply_property psp)
572 {
573 return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
574 psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
575 }
576
axp20x_configure_iio_channels(struct platform_device * pdev,struct axp20x_usb_power * power)577 static int axp20x_configure_iio_channels(struct platform_device *pdev,
578 struct axp20x_usb_power *power)
579 {
580 power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v");
581 if (IS_ERR(power->vbus_v)) {
582 if (PTR_ERR(power->vbus_v) == -ENODEV)
583 return -EPROBE_DEFER;
584 return PTR_ERR(power->vbus_v);
585 }
586
587 power->vbus_i = devm_iio_channel_get(&pdev->dev, "vbus_i");
588 if (IS_ERR(power->vbus_i)) {
589 if (PTR_ERR(power->vbus_i) == -ENODEV)
590 return -EPROBE_DEFER;
591 return PTR_ERR(power->vbus_i);
592 }
593
594 return 0;
595 }
596
axp717_configure_iio_channels(struct platform_device * pdev,struct axp20x_usb_power * power)597 static int axp717_configure_iio_channels(struct platform_device *pdev,
598 struct axp20x_usb_power *power)
599 {
600 power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v");
601 if (IS_ERR(power->vbus_v)) {
602 if (PTR_ERR(power->vbus_v) == -ENODEV)
603 return -EPROBE_DEFER;
604 return PTR_ERR(power->vbus_v);
605 }
606
607 return 0;
608 }
609
axp20x_configure_adc_registers(struct axp20x_usb_power * power)610 static int axp20x_configure_adc_registers(struct axp20x_usb_power *power)
611 {
612 /* Enable vbus voltage and current measurement */
613 return regmap_update_bits(power->regmap, AXP20X_ADC_EN1,
614 AXP20X_ADC_EN1_VBUS_CURR |
615 AXP20X_ADC_EN1_VBUS_VOLT,
616 AXP20X_ADC_EN1_VBUS_CURR |
617 AXP20X_ADC_EN1_VBUS_VOLT);
618 }
619
axp717_configure_adc_registers(struct axp20x_usb_power * power)620 static int axp717_configure_adc_registers(struct axp20x_usb_power *power)
621 {
622 /* Enable vbus voltage measurement */
623 return regmap_update_bits(power->regmap, AXP717_ADC_CH_EN_CONTROL,
624 AXP717_ADC_EN_VBUS_VOLT,
625 AXP717_ADC_EN_VBUS_VOLT);
626 }
627
628 static enum power_supply_property axp20x_usb_power_properties[] = {
629 POWER_SUPPLY_PROP_HEALTH,
630 POWER_SUPPLY_PROP_PRESENT,
631 POWER_SUPPLY_PROP_ONLINE,
632 POWER_SUPPLY_PROP_VOLTAGE_MIN,
633 POWER_SUPPLY_PROP_VOLTAGE_NOW,
634 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
635 POWER_SUPPLY_PROP_CURRENT_NOW,
636 };
637
638 static enum power_supply_property axp22x_usb_power_properties[] = {
639 POWER_SUPPLY_PROP_HEALTH,
640 POWER_SUPPLY_PROP_PRESENT,
641 POWER_SUPPLY_PROP_ONLINE,
642 POWER_SUPPLY_PROP_VOLTAGE_MIN,
643 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
644 };
645
646 static enum power_supply_property axp717_usb_power_properties[] = {
647 POWER_SUPPLY_PROP_HEALTH,
648 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
649 POWER_SUPPLY_PROP_ONLINE,
650 POWER_SUPPLY_PROP_PRESENT,
651 POWER_SUPPLY_PROP_USB_TYPE,
652 POWER_SUPPLY_PROP_VOLTAGE_MIN,
653 POWER_SUPPLY_PROP_VOLTAGE_NOW,
654 };
655
656 static enum power_supply_property axp813_usb_power_properties[] = {
657 POWER_SUPPLY_PROP_HEALTH,
658 POWER_SUPPLY_PROP_PRESENT,
659 POWER_SUPPLY_PROP_ONLINE,
660 POWER_SUPPLY_PROP_VOLTAGE_MIN,
661 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
662 POWER_SUPPLY_PROP_USB_TYPE,
663 };
664
665 static const struct power_supply_desc axp20x_usb_power_desc = {
666 .name = "axp20x-usb",
667 .type = POWER_SUPPLY_TYPE_USB,
668 .properties = axp20x_usb_power_properties,
669 .num_properties = ARRAY_SIZE(axp20x_usb_power_properties),
670 .property_is_writeable = axp20x_usb_power_prop_writeable,
671 .get_property = axp20x_usb_power_get_property,
672 .set_property = axp20x_usb_power_set_property,
673 };
674
675 static const struct power_supply_desc axp22x_usb_power_desc = {
676 .name = "axp20x-usb",
677 .type = POWER_SUPPLY_TYPE_USB,
678 .properties = axp22x_usb_power_properties,
679 .num_properties = ARRAY_SIZE(axp22x_usb_power_properties),
680 .property_is_writeable = axp20x_usb_power_prop_writeable,
681 .get_property = axp20x_usb_power_get_property,
682 .set_property = axp20x_usb_power_set_property,
683 };
684
685 static const struct power_supply_desc axp717_usb_power_desc = {
686 .name = "axp20x-usb",
687 .type = POWER_SUPPLY_TYPE_USB,
688 .properties = axp717_usb_power_properties,
689 .num_properties = ARRAY_SIZE(axp717_usb_power_properties),
690 .property_is_writeable = axp717_usb_power_prop_writeable,
691 .get_property = axp717_usb_power_get_property,
692 .set_property = axp717_usb_power_set_property,
693 .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
694 BIT(POWER_SUPPLY_USB_TYPE_CDP) |
695 BIT(POWER_SUPPLY_USB_TYPE_DCP) |
696 BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
697 };
698
699 static const struct power_supply_desc axp813_usb_power_desc = {
700 .name = "axp20x-usb",
701 .type = POWER_SUPPLY_TYPE_USB,
702 .properties = axp813_usb_power_properties,
703 .num_properties = ARRAY_SIZE(axp813_usb_power_properties),
704 .property_is_writeable = axp20x_usb_power_prop_writeable,
705 .get_property = axp20x_usb_power_get_property,
706 .set_property = axp20x_usb_power_set_property,
707 .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
708 BIT(POWER_SUPPLY_USB_TYPE_CDP) |
709 BIT(POWER_SUPPLY_USB_TYPE_DCP) |
710 BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
711 };
712
713 static const char * const axp20x_irq_names[] = {
714 "VBUS_PLUGIN",
715 "VBUS_REMOVAL",
716 "VBUS_VALID",
717 "VBUS_NOT_VALID",
718 };
719
720 static const char * const axp22x_irq_names[] = {
721 "VBUS_PLUGIN",
722 "VBUS_REMOVAL",
723 };
724
725 static const char * const axp717_irq_names[] = {
726 "VBUS_PLUGIN",
727 "VBUS_REMOVAL",
728 "VBUS_OVER_V",
729 };
730
731 static int axp192_usb_curr_lim_table[] = {
732 -1,
733 -1,
734 500000,
735 100000,
736 };
737
738 static int axp20x_usb_curr_lim_table[] = {
739 900000,
740 500000,
741 100000,
742 -1,
743 };
744
745 static int axp221_usb_curr_lim_table[] = {
746 900000,
747 500000,
748 -1,
749 -1,
750 };
751
752 static int axp813_usb_curr_lim_table[] = {
753 100000,
754 500000,
755 900000,
756 1500000,
757 2000000,
758 2500000,
759 3000000,
760 3500000,
761 4000000,
762 };
763
764 static const struct axp_data axp192_data = {
765 .power_desc = &axp20x_usb_power_desc,
766 .irq_names = axp20x_irq_names,
767 .num_irq_names = ARRAY_SIZE(axp20x_irq_names),
768 .curr_lim_table = axp192_usb_curr_lim_table,
769 .curr_lim_table_size = ARRAY_SIZE(axp192_usb_curr_lim_table),
770 .curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
771 .vbus_valid_bit = REG_FIELD(AXP192_USB_OTG_STATUS, 2, 2),
772 .vbus_mon_bit = REG_FIELD(AXP20X_VBUS_MON, 3, 3),
773 .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
774 .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
775 .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
776 };
777
778 static const struct axp_data axp202_data = {
779 .power_desc = &axp20x_usb_power_desc,
780 .irq_names = axp20x_irq_names,
781 .num_irq_names = ARRAY_SIZE(axp20x_irq_names),
782 .curr_lim_table = axp20x_usb_curr_lim_table,
783 .curr_lim_table_size = ARRAY_SIZE(axp20x_usb_curr_lim_table),
784 .curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
785 .vbus_valid_bit = REG_FIELD(AXP20X_USB_OTG_STATUS, 2, 2),
786 .vbus_mon_bit = REG_FIELD(AXP20X_VBUS_MON, 3, 3),
787 .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
788 .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
789 .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
790 };
791
792 static const struct axp_data axp221_data = {
793 .power_desc = &axp22x_usb_power_desc,
794 .irq_names = axp22x_irq_names,
795 .num_irq_names = ARRAY_SIZE(axp22x_irq_names),
796 .curr_lim_table = axp221_usb_curr_lim_table,
797 .curr_lim_table_size = ARRAY_SIZE(axp221_usb_curr_lim_table),
798 .curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
799 .vbus_needs_polling = true,
800 .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
801 .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
802 .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
803 };
804
805 static const struct axp_data axp223_data = {
806 .power_desc = &axp22x_usb_power_desc,
807 .irq_names = axp22x_irq_names,
808 .num_irq_names = ARRAY_SIZE(axp22x_irq_names),
809 .curr_lim_table = axp20x_usb_curr_lim_table,
810 .curr_lim_table_size = ARRAY_SIZE(axp20x_usb_curr_lim_table),
811 .curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
812 .vbus_needs_polling = true,
813 .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
814 .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
815 .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
816 };
817
818 static const struct axp_data axp717_data = {
819 .power_desc = &axp717_usb_power_desc,
820 .irq_names = axp717_irq_names,
821 .num_irq_names = ARRAY_SIZE(axp717_irq_names),
822 .curr_lim_fld = REG_FIELD(AXP717_INPUT_CUR_LIMIT_CTRL, 0, 5),
823 .usb_bc_en_bit = REG_FIELD(AXP717_MODULE_EN_CONTROL_1, 4, 4),
824 .usb_bc_det_fld = REG_FIELD(AXP717_BC_DETECT, 5, 7),
825 .vbus_mon_bit = REG_FIELD(AXP717_ADC_CH_EN_CONTROL, 2, 2),
826 .vbus_needs_polling = false,
827 .axp20x_read_vbus = &axp717_usb_power_poll_vbus,
828 .axp20x_cfg_iio_chan = axp717_configure_iio_channels,
829 .axp20x_cfg_adc_reg = axp717_configure_adc_registers,
830 };
831
832 static const struct axp_data axp813_data = {
833 .power_desc = &axp813_usb_power_desc,
834 .irq_names = axp22x_irq_names,
835 .num_irq_names = ARRAY_SIZE(axp22x_irq_names),
836 .curr_lim_table = axp813_usb_curr_lim_table,
837 .curr_lim_table_size = ARRAY_SIZE(axp813_usb_curr_lim_table),
838 .curr_lim_fld = REG_FIELD(AXP22X_CHRG_CTRL3, 4, 7),
839 .usb_bc_en_bit = REG_FIELD(AXP288_BC_GLOBAL, 0, 0),
840 .usb_bc_det_fld = REG_FIELD(AXP288_BC_DET_STAT, 5, 7),
841 .vbus_disable_bit = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 7, 7),
842 .vbus_needs_polling = true,
843 .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
844 .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
845 .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
846 };
847
848 #ifdef CONFIG_PM_SLEEP
axp20x_usb_power_suspend(struct device * dev)849 static int axp20x_usb_power_suspend(struct device *dev)
850 {
851 struct axp20x_usb_power *power = dev_get_drvdata(dev);
852 int i = 0;
853
854 /*
855 * Allow wake via VBUS_PLUGIN only.
856 *
857 * As nested threaded IRQs are not automatically disabled during
858 * suspend, we must explicitly disable the remainder of the IRQs.
859 */
860 if (device_may_wakeup(&power->supply->dev))
861 enable_irq_wake(power->irqs[i++]);
862 while (i < power->num_irqs)
863 disable_irq(power->irqs[i++]);
864
865 return 0;
866 }
867
axp20x_usb_power_resume(struct device * dev)868 static int axp20x_usb_power_resume(struct device *dev)
869 {
870 struct axp20x_usb_power *power = dev_get_drvdata(dev);
871 int i = 0;
872
873 if (device_may_wakeup(&power->supply->dev))
874 disable_irq_wake(power->irqs[i++]);
875 while (i < power->num_irqs)
876 enable_irq(power->irqs[i++]);
877
878 mod_delayed_work(system_power_efficient_wq, &power->vbus_detect, DEBOUNCE_TIME);
879
880 return 0;
881 }
882 #endif
883
884 static SIMPLE_DEV_PM_OPS(axp20x_usb_power_pm_ops, axp20x_usb_power_suspend,
885 axp20x_usb_power_resume);
886
axp20x_regmap_field_alloc_optional(struct device * dev,struct regmap * regmap,struct reg_field fdesc,struct regmap_field ** fieldp)887 static int axp20x_regmap_field_alloc_optional(struct device *dev,
888 struct regmap *regmap,
889 struct reg_field fdesc,
890 struct regmap_field **fieldp)
891 {
892 struct regmap_field *field;
893
894 if (fdesc.reg == 0) {
895 *fieldp = NULL;
896 return 0;
897 }
898
899 field = devm_regmap_field_alloc(dev, regmap, fdesc);
900 if (IS_ERR(field))
901 return PTR_ERR(field);
902
903 *fieldp = field;
904 return 0;
905 }
906
907 /* Optionally allow users to specify a maximum charging current. */
axp20x_usb_power_parse_dt(struct device * dev,struct axp20x_usb_power * power)908 static void axp20x_usb_power_parse_dt(struct device *dev,
909 struct axp20x_usb_power *power)
910 {
911 int ret;
912
913 ret = device_property_read_u32(dev, "input-current-limit-microamp",
914 &power->max_input_cur);
915 if (ret)
916 dev_dbg(dev, "%s() no input-current-limit specified\n", __func__);
917 }
918
axp20x_usb_power_probe(struct platform_device * pdev)919 static int axp20x_usb_power_probe(struct platform_device *pdev)
920 {
921 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
922 struct power_supply_config psy_cfg = {};
923 struct axp20x_usb_power *power;
924 const struct axp_data *axp_data;
925 int i, irq, ret;
926
927 if (!of_device_is_available(pdev->dev.of_node))
928 return -ENODEV;
929
930 if (!axp20x) {
931 dev_err(&pdev->dev, "Parent drvdata not set\n");
932 return -EINVAL;
933 }
934
935 axp_data = of_device_get_match_data(&pdev->dev);
936
937 power = devm_kzalloc(&pdev->dev,
938 struct_size(power, irqs, axp_data->num_irq_names),
939 GFP_KERNEL);
940 if (!power)
941 return -ENOMEM;
942
943 platform_set_drvdata(pdev, power);
944
945 power->dev = &pdev->dev;
946 power->axp_data = axp_data;
947 power->regmap = axp20x->regmap;
948 power->num_irqs = axp_data->num_irq_names;
949
950 power->curr_lim_fld = devm_regmap_field_alloc(&pdev->dev, power->regmap,
951 axp_data->curr_lim_fld);
952 if (IS_ERR(power->curr_lim_fld))
953 return PTR_ERR(power->curr_lim_fld);
954
955 axp20x_usb_power_parse_dt(&pdev->dev, power);
956
957 ret = axp20x_regmap_field_alloc_optional(&pdev->dev, power->regmap,
958 axp_data->vbus_valid_bit,
959 &power->vbus_valid_bit);
960 if (ret)
961 return ret;
962
963 ret = axp20x_regmap_field_alloc_optional(&pdev->dev, power->regmap,
964 axp_data->vbus_mon_bit,
965 &power->vbus_mon_bit);
966 if (ret)
967 return ret;
968
969 ret = axp20x_regmap_field_alloc_optional(&pdev->dev, power->regmap,
970 axp_data->usb_bc_en_bit,
971 &power->usb_bc_en_bit);
972 if (ret)
973 return ret;
974
975 ret = axp20x_regmap_field_alloc_optional(&pdev->dev, power->regmap,
976 axp_data->usb_bc_det_fld,
977 &power->usb_bc_det_fld);
978 if (ret)
979 return ret;
980
981 ret = axp20x_regmap_field_alloc_optional(&pdev->dev, power->regmap,
982 axp_data->vbus_disable_bit,
983 &power->vbus_disable_bit);
984 if (ret)
985 return ret;
986
987 ret = devm_delayed_work_autocancel(&pdev->dev, &power->vbus_detect,
988 axp_data->axp20x_read_vbus);
989 if (ret)
990 return ret;
991
992 if (power->vbus_mon_bit) {
993 /* Enable vbus valid checking */
994 ret = regmap_field_write(power->vbus_mon_bit, 1);
995 if (ret)
996 return ret;
997
998 if (IS_ENABLED(CONFIG_AXP20X_ADC))
999 ret = axp_data->axp20x_cfg_iio_chan(pdev, power);
1000 else
1001 ret = axp_data->axp20x_cfg_adc_reg(power);
1002
1003 if (ret)
1004 return ret;
1005 }
1006
1007 if (power->usb_bc_en_bit) {
1008 /* Enable USB Battery Charging specification detection */
1009 ret = regmap_field_write(power->usb_bc_en_bit, 1);
1010 if (ret)
1011 return ret;
1012 }
1013
1014 psy_cfg.of_node = pdev->dev.of_node;
1015 psy_cfg.drv_data = power;
1016
1017 power->supply = devm_power_supply_register(&pdev->dev,
1018 axp_data->power_desc,
1019 &psy_cfg);
1020 if (IS_ERR(power->supply))
1021 return PTR_ERR(power->supply);
1022
1023 /* Request irqs after registering, as irqs may trigger immediately */
1024 for (i = 0; i < axp_data->num_irq_names; i++) {
1025 irq = platform_get_irq_byname(pdev, axp_data->irq_names[i]);
1026 if (irq < 0)
1027 return irq;
1028
1029 power->irqs[i] = regmap_irq_get_virq(axp20x->regmap_irqc, irq);
1030 ret = devm_request_any_context_irq(&pdev->dev, power->irqs[i],
1031 axp20x_usb_power_irq, 0,
1032 DRVNAME, power);
1033 if (ret < 0) {
1034 dev_err(&pdev->dev, "Error requesting %s IRQ: %d\n",
1035 axp_data->irq_names[i], ret);
1036 return ret;
1037 }
1038 }
1039
1040 if (axp20x_usb_vbus_needs_polling(power))
1041 queue_delayed_work(system_power_efficient_wq, &power->vbus_detect, 0);
1042
1043 return 0;
1044 }
1045
1046 static const struct of_device_id axp20x_usb_power_match[] = {
1047 {
1048 .compatible = "x-powers,axp192-usb-power-supply",
1049 .data = &axp192_data,
1050 }, {
1051 .compatible = "x-powers,axp202-usb-power-supply",
1052 .data = &axp202_data,
1053 }, {
1054 .compatible = "x-powers,axp221-usb-power-supply",
1055 .data = &axp221_data,
1056 }, {
1057 .compatible = "x-powers,axp223-usb-power-supply",
1058 .data = &axp223_data,
1059 }, {
1060 .compatible = "x-powers,axp717-usb-power-supply",
1061 .data = &axp717_data,
1062 }, {
1063 .compatible = "x-powers,axp813-usb-power-supply",
1064 .data = &axp813_data,
1065 }, { /* sentinel */ }
1066 };
1067 MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
1068
1069 static struct platform_driver axp20x_usb_power_driver = {
1070 .probe = axp20x_usb_power_probe,
1071 .driver = {
1072 .name = DRVNAME,
1073 .of_match_table = axp20x_usb_power_match,
1074 .pm = &axp20x_usb_power_pm_ops,
1075 },
1076 };
1077
1078 module_platform_driver(axp20x_usb_power_driver);
1079
1080 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
1081 MODULE_DESCRIPTION("AXP20x PMIC USB power supply status driver");
1082 MODULE_LICENSE("GPL");
1083