1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * AXP20x PMIC USB power supply status driver
5 * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
6 * Copyright (C) 2014 Bruno Prémont <bonbons@linux-vserver.org>
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>
18 #include <linux/platform_device.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>
26 #define DRVNAME "axp20x-usb-power-supply"
28 #define AXP192_USB_OTG_STATUS 0x04
30 #define AXP20X_PWR_STATUS_VBUS_PRESENT BIT(5)
31 #define AXP20X_PWR_STATUS_VBUS_USED BIT(4)
33 #define AXP717_PWR_STATUS_VBUS_GOOD BIT(5)
35 #define AXP20X_USB_STATUS_VBUS_VALID BIT(2)
37 #define AXP717_PMU_FAULT_VBUS BIT(5)
38 #define AXP717_PMU_FAULT_VSYS BIT(3)
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
44 #define AXP20X_ADC_EN1_VBUS_CURR BIT(2)
45 #define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
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)
51 #define AXP717_ADC_EN_VBUS_VOLT BIT(2)
54 * Note do not raise the debounce time, we must report Vusb high within
55 * 100ms otherwise we get Vbus errors in musb.
57 #define DEBOUNCE_TIME msecs_to_jiffies(50)
59 struct axp20x_usb_power
;
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
);
80 struct axp20x_usb_power
{
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
;
95 unsigned int old_status
;
97 unsigned int num_irqs
;
98 unsigned int irqs
[] __counted_by(num_irqs
);
101 static bool axp20x_usb_vbus_needs_polling(struct axp20x_usb_power
*power
)
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.
108 if (power
->axp_data
->vbus_needs_polling
&& !power
->online
)
114 static irqreturn_t
axp20x_usb_power_irq(int irq
, void *devid
)
116 struct axp20x_usb_power
*power
= devid
;
118 power_supply_changed(power
->supply
);
120 mod_delayed_work(system_power_efficient_wq
, &power
->vbus_detect
, DEBOUNCE_TIME
);
125 static void axp20x_usb_power_poll_vbus(struct work_struct
*work
)
127 struct axp20x_usb_power
*power
=
128 container_of(work
, struct axp20x_usb_power
, vbus_detect
.work
);
132 ret
= regmap_read(power
->regmap
, AXP20X_PWR_INPUT_STATUS
, &val
);
136 val
&= (AXP20X_PWR_STATUS_VBUS_PRESENT
| AXP20X_PWR_STATUS_VBUS_USED
);
137 if (val
!= power
->old_status
)
138 power_supply_changed(power
->supply
);
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);
145 dev_err(power
->dev
, "failed to enable USB BC: errno %d",
149 power
->old_status
= val
;
150 power
->online
= val
& AXP20X_PWR_STATUS_VBUS_USED
;
153 if (axp20x_usb_vbus_needs_polling(power
))
154 mod_delayed_work(system_power_efficient_wq
, &power
->vbus_detect
, DEBOUNCE_TIME
);
157 static void axp717_usb_power_poll_vbus(struct work_struct
*work
)
159 struct axp20x_usb_power
*power
=
160 container_of(work
, struct axp20x_usb_power
, vbus_detect
.work
);
164 ret
= regmap_read(power
->regmap
, AXP717_ON_INDICATE
, &val
);
168 val
&= AXP717_PWR_STATUS_VBUS_GOOD
;
169 if (val
!= power
->old_status
)
170 power_supply_changed(power
->supply
);
172 power
->old_status
= val
;
175 static int axp20x_get_usb_type(struct axp20x_usb_power
*power
,
176 union power_supply_propval
*val
)
181 if (!power
->usb_bc_det_fld
)
184 ret
= regmap_field_read(power
->usb_bc_det_fld
, ®
);
190 val
->intval
= POWER_SUPPLY_USB_TYPE_SDP
;
193 val
->intval
= POWER_SUPPLY_USB_TYPE_CDP
;
196 val
->intval
= POWER_SUPPLY_USB_TYPE_DCP
;
199 val
->intval
= POWER_SUPPLY_USB_TYPE_UNKNOWN
;
206 static int axp20x_usb_power_get_property(struct power_supply
*psy
,
207 enum power_supply_property psp
, union power_supply_propval
*val
)
209 struct axp20x_usb_power
*power
= power_supply_get_drvdata(psy
);
210 unsigned int input
, v
;
214 case POWER_SUPPLY_PROP_VOLTAGE_MIN
:
215 ret
= regmap_read(power
->regmap
, AXP20X_VBUS_IPSOUT_MGMT
, &v
);
219 val
->intval
= AXP20X_VBUS_VHOLD_uV(v
);
221 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
222 if (IS_ENABLED(CONFIG_AXP20X_ADC
)) {
224 * IIO framework gives mV but Power Supply framework
227 ret
= iio_read_channel_processed_scale(power
->vbus_v
,
235 ret
= axp20x_read_variable_width(power
->regmap
,
236 AXP20X_VBUS_V_ADC_H
, 12);
240 val
->intval
= ret
* 1700; /* 1 step = 1.7 mV */
242 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
243 ret
= regmap_field_read(power
->curr_lim_fld
, &v
);
247 if (v
< power
->axp_data
->curr_lim_table_size
)
248 val
->intval
= power
->axp_data
->curr_lim_table
[v
];
250 val
->intval
= power
->axp_data
->curr_lim_table
[
251 power
->axp_data
->curr_lim_table_size
- 1];
253 case POWER_SUPPLY_PROP_CURRENT_NOW
:
254 if (IS_ENABLED(CONFIG_AXP20X_ADC
)) {
256 * IIO framework gives mA but Power Supply framework
259 ret
= iio_read_channel_processed_scale(power
->vbus_i
,
267 ret
= axp20x_read_variable_width(power
->regmap
,
268 AXP20X_VBUS_I_ADC_H
, 12);
272 val
->intval
= ret
* 375; /* 1 step = 0.375 mA */
275 case POWER_SUPPLY_PROP_USB_TYPE
:
276 return axp20x_get_usb_type(power
, val
);
281 /* All the properties below need the input-status reg value */
282 ret
= regmap_read(power
->regmap
, AXP20X_PWR_INPUT_STATUS
, &input
);
287 case POWER_SUPPLY_PROP_HEALTH
:
288 if (!(input
& AXP20X_PWR_STATUS_VBUS_PRESENT
)) {
289 val
->intval
= POWER_SUPPLY_HEALTH_UNKNOWN
;
293 val
->intval
= POWER_SUPPLY_HEALTH_GOOD
;
295 if (power
->vbus_valid_bit
) {
296 ret
= regmap_field_read(power
->vbus_valid_bit
, &v
);
301 val
->intval
= POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
;
305 case POWER_SUPPLY_PROP_PRESENT
:
306 val
->intval
= !!(input
& AXP20X_PWR_STATUS_VBUS_PRESENT
);
308 case POWER_SUPPLY_PROP_ONLINE
:
309 val
->intval
= !!(input
& AXP20X_PWR_STATUS_VBUS_USED
);
318 static int axp717_usb_power_get_property(struct power_supply
*psy
,
319 enum power_supply_property psp
, union power_supply_propval
*val
)
321 struct axp20x_usb_power
*power
= power_supply_get_drvdata(psy
);
326 case POWER_SUPPLY_PROP_HEALTH
:
327 val
->intval
= POWER_SUPPLY_HEALTH_GOOD
;
328 ret
= regmap_read(power
->regmap
, AXP717_ON_INDICATE
, &v
);
332 if (!(v
& AXP717_PWR_STATUS_VBUS_GOOD
))
333 val
->intval
= POWER_SUPPLY_HEALTH_UNKNOWN
;
335 ret
= regmap_read(power
->regmap
, AXP717_PMU_FAULT_VBUS
, &v
);
339 v
&= (AXP717_PMU_FAULT_VBUS
| AXP717_PMU_FAULT_VSYS
);
341 val
->intval
= POWER_SUPPLY_HEALTH_OVERVOLTAGE
;
342 regmap_write(power
->regmap
, AXP717_PMU_FAULT_VBUS
, v
);
346 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
347 ret
= regmap_read(power
->regmap
, AXP717_INPUT_CUR_LIMIT_CTRL
, &v
);
351 /* 50ma step size with 100ma offset. */
352 v
&= AXP717_INPUT_CUR_LIMIT_MASK
;
353 val
->intval
= (v
* 50000) + 100000;
355 case POWER_SUPPLY_PROP_ONLINE
:
356 case POWER_SUPPLY_PROP_PRESENT
:
357 ret
= regmap_read(power
->regmap
, AXP717_ON_INDICATE
, &v
);
360 val
->intval
= !!(v
& AXP717_PWR_STATUS_VBUS_GOOD
);
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
);
369 /* 80mv step size with 3.88v offset. */
370 v
&= AXP717_INPUT_VOL_LIMIT_MASK
;
371 val
->intval
= (v
* 80000) + 3880000;
373 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
374 if (IS_ENABLED(CONFIG_AXP20X_ADC
)) {
376 * IIO framework gives mV but Power Supply framework
379 ret
= iio_read_channel_processed_scale(power
->vbus_v
,
387 ret
= axp20x_read_variable_width(power
->regmap
,
388 AXP717_VBUS_V_H
, 16);
392 val
->intval
= (ret
% AXP717_ADC_DATA_MASK
) * 1000;
402 static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power
*power
,
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
);
428 static int axp717_usb_power_set_voltage_min(struct axp20x_usb_power
*power
,
433 /* Minimum value of 3.88v and maximum of 5.08v. */
434 if (intval
< 3880000 || intval
> 5080000)
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
);
444 static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power
*power
,
449 const unsigned int max
= power
->axp_data
->curr_lim_table_size
;
454 if (power
->max_input_cur
&& (intval
> power
->max_input_cur
)) {
456 "requested current %d clamped to max current %d\n",
457 intval
, power
->max_input_cur
);
458 intval
= power
->max_input_cur
;
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.
466 if (power
->usb_bc_en_bit
) {
468 "disabling BC1.2 detection because current limit was set");
469 ret
= regmap_field_write(power
->usb_bc_en_bit
, 0);
474 for (reg
= max
- 1; reg
> 0; reg
--)
475 if (power
->axp_data
->curr_lim_table
[reg
] <= intval
)
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
);
481 return regmap_field_write(power
->curr_lim_fld
, reg
);
484 static int axp717_usb_power_set_input_current_limit(struct axp20x_usb_power
*power
,
489 /* Minimum value of 100mA and maximum value of 3.25A*/
490 if (intval
< 100000 || intval
> 3250000)
493 if (power
->max_input_cur
&& (intval
> power
->max_input_cur
)) {
495 "reqested current %d clamped to max current %d\n",
496 intval
, power
->max_input_cur
);
497 intval
= power
->max_input_cur
;
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
);
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
)
511 struct axp20x_usb_power
*power
= power_supply_get_drvdata(psy
);
514 case POWER_SUPPLY_PROP_ONLINE
:
515 if (!power
->vbus_disable_bit
)
518 return regmap_field_write(power
->vbus_disable_bit
, !val
->intval
);
520 case POWER_SUPPLY_PROP_VOLTAGE_MIN
:
521 return axp20x_usb_power_set_voltage_min(power
, val
->intval
);
523 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
524 return axp20x_usb_power_set_input_current_limit(power
, val
->intval
);
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
)
535 struct axp20x_usb_power
*power
= power_supply_get_drvdata(psy
);
538 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
539 return axp717_usb_power_set_input_current_limit(power
, val
->intval
);
541 case POWER_SUPPLY_PROP_VOLTAGE_MIN
:
542 return axp717_usb_power_set_voltage_min(power
, val
->intval
);
551 static int axp20x_usb_power_prop_writeable(struct power_supply
*psy
,
552 enum power_supply_property psp
)
554 struct axp20x_usb_power
*power
= power_supply_get_drvdata(psy
);
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.
563 if (psp
== POWER_SUPPLY_PROP_ONLINE
)
564 return power
->vbus_disable_bit
!= NULL
;
566 return psp
== POWER_SUPPLY_PROP_VOLTAGE_MIN
||
567 psp
== POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
;
570 static int axp717_usb_power_prop_writeable(struct power_supply
*psy
,
571 enum power_supply_property psp
)
573 return psp
== POWER_SUPPLY_PROP_VOLTAGE_MIN
||
574 psp
== POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
;
577 static int axp20x_configure_iio_channels(struct platform_device
*pdev
,
578 struct axp20x_usb_power
*power
)
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
);
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
);
597 static int axp717_configure_iio_channels(struct platform_device
*pdev
,
598 struct axp20x_usb_power
*power
)
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
);
610 static int axp20x_configure_adc_registers(struct axp20x_usb_power
*power
)
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
);
620 static int axp717_configure_adc_registers(struct axp20x_usb_power
*power
)
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
);
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
,
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
,
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
,
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
,
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
,
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
,
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
),
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
),
713 static const char * const axp20x_irq_names
[] = {
720 static const char * const axp22x_irq_names
[] = {
725 static const char * const axp717_irq_names
[] = {
731 static int axp192_usb_curr_lim_table
[] = {
738 static int axp20x_usb_curr_lim_table
[] = {
745 static int axp221_usb_curr_lim_table
[] = {
752 static int axp813_usb_curr_lim_table
[] = {
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
,
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
,
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
,
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
,
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
,
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
,
848 #ifdef CONFIG_PM_SLEEP
849 static int axp20x_usb_power_suspend(struct device
*dev
)
851 struct axp20x_usb_power
*power
= dev_get_drvdata(dev
);
855 * Allow wake via VBUS_PLUGIN only.
857 * As nested threaded IRQs are not automatically disabled during
858 * suspend, we must explicitly disable the remainder of the IRQs.
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
++]);
868 static int axp20x_usb_power_resume(struct device
*dev
)
870 struct axp20x_usb_power
*power
= dev_get_drvdata(dev
);
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
++]);
878 mod_delayed_work(system_power_efficient_wq
, &power
->vbus_detect
, DEBOUNCE_TIME
);
884 static SIMPLE_DEV_PM_OPS(axp20x_usb_power_pm_ops
, axp20x_usb_power_suspend
,
885 axp20x_usb_power_resume
);
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
)
892 struct regmap_field
*field
;
894 if (fdesc
.reg
== 0) {
899 field
= devm_regmap_field_alloc(dev
, regmap
, fdesc
);
901 return PTR_ERR(field
);
907 /* Optionally allow users to specify a maximum charging current. */
908 static void axp20x_usb_power_parse_dt(struct device
*dev
,
909 struct axp20x_usb_power
*power
)
913 ret
= device_property_read_u32(dev
, "input-current-limit-microamp",
914 &power
->max_input_cur
);
916 dev_dbg(dev
, "%s() no input-current-limit specified\n", __func__
);
919 static int axp20x_usb_power_probe(struct platform_device
*pdev
)
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
;
927 if (!of_device_is_available(pdev
->dev
.of_node
))
931 dev_err(&pdev
->dev
, "Parent drvdata not set\n");
935 axp_data
= of_device_get_match_data(&pdev
->dev
);
937 power
= devm_kzalloc(&pdev
->dev
,
938 struct_size(power
, irqs
, axp_data
->num_irq_names
),
943 platform_set_drvdata(pdev
, power
);
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
;
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
);
955 axp20x_usb_power_parse_dt(&pdev
->dev
, power
);
957 ret
= axp20x_regmap_field_alloc_optional(&pdev
->dev
, power
->regmap
,
958 axp_data
->vbus_valid_bit
,
959 &power
->vbus_valid_bit
);
963 ret
= axp20x_regmap_field_alloc_optional(&pdev
->dev
, power
->regmap
,
964 axp_data
->vbus_mon_bit
,
965 &power
->vbus_mon_bit
);
969 ret
= axp20x_regmap_field_alloc_optional(&pdev
->dev
, power
->regmap
,
970 axp_data
->usb_bc_en_bit
,
971 &power
->usb_bc_en_bit
);
975 ret
= axp20x_regmap_field_alloc_optional(&pdev
->dev
, power
->regmap
,
976 axp_data
->usb_bc_det_fld
,
977 &power
->usb_bc_det_fld
);
981 ret
= axp20x_regmap_field_alloc_optional(&pdev
->dev
, power
->regmap
,
982 axp_data
->vbus_disable_bit
,
983 &power
->vbus_disable_bit
);
987 ret
= devm_delayed_work_autocancel(&pdev
->dev
, &power
->vbus_detect
,
988 axp_data
->axp20x_read_vbus
);
992 if (power
->vbus_mon_bit
) {
993 /* Enable vbus valid checking */
994 ret
= regmap_field_write(power
->vbus_mon_bit
, 1);
998 if (IS_ENABLED(CONFIG_AXP20X_ADC
))
999 ret
= axp_data
->axp20x_cfg_iio_chan(pdev
, power
);
1001 ret
= axp_data
->axp20x_cfg_adc_reg(power
);
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);
1014 psy_cfg
.of_node
= pdev
->dev
.of_node
;
1015 psy_cfg
.drv_data
= power
;
1017 power
->supply
= devm_power_supply_register(&pdev
->dev
,
1018 axp_data
->power_desc
,
1020 if (IS_ERR(power
->supply
))
1021 return PTR_ERR(power
->supply
);
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
]);
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,
1034 dev_err(&pdev
->dev
, "Error requesting %s IRQ: %d\n",
1035 axp_data
->irq_names
[i
], ret
);
1040 if (axp20x_usb_vbus_needs_polling(power
))
1041 queue_delayed_work(system_power_efficient_wq
, &power
->vbus_detect
, 0);
1046 static const struct of_device_id axp20x_usb_power_match
[] = {
1048 .compatible
= "x-powers,axp192-usb-power-supply",
1049 .data
= &axp192_data
,
1051 .compatible
= "x-powers,axp202-usb-power-supply",
1052 .data
= &axp202_data
,
1054 .compatible
= "x-powers,axp221-usb-power-supply",
1055 .data
= &axp221_data
,
1057 .compatible
= "x-powers,axp223-usb-power-supply",
1058 .data
= &axp223_data
,
1060 .compatible
= "x-powers,axp717-usb-power-supply",
1061 .data
= &axp717_data
,
1063 .compatible
= "x-powers,axp813-usb-power-supply",
1064 .data
= &axp813_data
,
1065 }, { /* sentinel */ }
1067 MODULE_DEVICE_TABLE(of
, axp20x_usb_power_match
);
1069 static struct platform_driver axp20x_usb_power_driver
= {
1070 .probe
= axp20x_usb_power_probe
,
1073 .of_match_table
= axp20x_usb_power_match
,
1074 .pm
= &axp20x_usb_power_pm_ops
,
1078 module_platform_driver(axp20x_usb_power_driver
);
1080 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
1081 MODULE_DESCRIPTION("AXP20x PMIC USB power supply status driver");
1082 MODULE_LICENSE("GPL");