From: Chen-Yu Tsai <[email protected]>
Hi everyone,
This is v3 of my A83T USB power supply / OTG series. Changes since v2:
- Added Rob's ack for dt bindings patch
- Rebased onto v5.1-rc1
Changes since v1:
- Added Lee's ack for mfd patch
- Make axp803_usb_power_supply_resources[] const
This series has since been tested. Both host mode and gadget mode work
well. However this SoC seems to have a glitch in hardware. After host
mode is used by plugging in a host mode cable, the hardware will not
revert back to gadget mode if a standard USB cable is plugged in. Host
mode continues to work however. This will likely have to be addressed
with some workaround in either the musb driver or our USB PHY driver.
The patches have no cross-tree dependencies, so each part can go through
their respective trees (power-supply / mfd / arm-soc).
I also have some follow-up patches to enable the USB power supply on
AXP803 / A64. It's the boiler-plate mfd cell and device node addition.
Original cover letter follows:
This series enables USB OTG on the A83T boards. The AXP813/AXP818 PMICs
used with the A83T have the same behavior as the AXP221 and AXP223,
where if the N_VBUSEN pin is driven high, the VBUS sensing interrupts
stop working. In the past Hans made a polling workaround in the USB PHY
driver. In this series polling is added to the power supply driver.
The power supply driver work was started by Quentin, and shared with me
when I expressed interest in getting USB OTG to work some time ago.
Neither of us got around to finishing it, until now that is.
Patch 1 adds a new compatible string for the AXP813 VBUS power supply
part.
Patch 2 is a bit of cleanup work for the driver.
Patch 3 allows disabling VBUS input current limiting on the AXP20x /
AXP22x PMICs. While not strictly related to this series, I found it
easier to just send everything together. This patch depends on the
previous one.
Patch 4 adds the VBUS status polling feature. This is enabled on AXP221
and all later PMICs.
Patch 5 factors out code to read out the configured input current limit
for the AXP20x and AXP22x PMICs. As the AXP813 uses different values,
factoring out the code based on model will make the main function more
readable.
Patch 6 adds support for the AXP813 VBUS power supply. checkpatch.pl
reports a few warnings for this patch:
WARNING: Possible switch case/default not preceded by break or
fallthrough comment
#100: FILE: drivers/power/supply/axp20x_usb_power.c:306:
+ case 1500000:
WARNING: Possible switch case/default not preceded by break or
fallthrough comment
#101: FILE: drivers/power/supply/axp20x_usb_power.c:307:
+ case 2000000:
WARNING: Possible switch case/default not preceded by break or
fallthrough comment
#102: FILE: drivers/power/supply/axp20x_usb_power.c:308:
+ case 2500000:
However they seem to be a false positive. The preceding line of the
reported lines is a return statement, which is definitely not a
fallthrough.
Patch 7 adds an mfd cell for the newly supported VBUS power supply.
Patch 8 adds a device node for the VBUS power supply to the common
axp81x dtsi file.
Patch 9 enables USB OTG on the Cubietruck Plus and Bananapi M3.
Please have a look, and also test it on boards you have, and don't
limit it to just the A83T ones. As mentioned above, the polling feature
affects all boards that have an AXP221 or newer PMIC.
I haven't removed the polling workaround from the USB PHY driver yet.
That would be the next step after this series is merged, and preferrably
a release has passed.
Regards
ChenYu
Chen-Yu Tsai (5):
dt-bindings: power: supply: axp20x_usb_power: add axp813 compatible
power: supply: axp20x_usb_power: Fix typo in VBUS current limit macros
power: supply: axp20x_usb_power: allow disabling input current
limiting
power: supply: axp20x_usb_power: use polling to detect vbus status
change
ARM: dts: sun8i: a83t: Enable USB OTG controller on some boards
Quentin Schulz (4):
power: supply: axp20x_usb_power: add function to get max current
power: supply: axp20x_usb_power: add support for AXP813
mfd: axp20x: add USB power supply mfd cell to AXP813
ARM: dtsi: axp81x: add USB power supply node
.../power/supply/axp20x_usb_power.txt | 1 +
arch/arm/boot/dts/axp81x.dtsi | 4 +
arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts | 12 ++
.../boot/dts/sun8i-a83t-cubietruck-plus.dts | 12 ++
drivers/mfd/axp20x.c | 11 ++
drivers/power/supply/axp20x_usb_power.c | 184 +++++++++++++++---
6 files changed, 197 insertions(+), 27 deletions(-)
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
The AXP PMICs allow the user to disable current limiting on the VBUS
input. While read-out of this setting was already supported by the
driver, it did not allow the user to configure the PMIC to disable
current limiting.
Add support for this.
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
drivers/power/supply/axp20x_usb_power.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
index cd9b90d79839..e2f353906bb1 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -230,6 +230,11 @@ static int axp20x_usb_power_set_current_max(struct axp20x_usb_power *power,
return regmap_update_bits(power->regmap,
AXP20X_VBUS_IPSOUT_MGMT,
AXP20X_VBUS_CLIMIT_MASK, val);
+ case -1:
+ return regmap_update_bits(power->regmap,
+ AXP20X_VBUS_IPSOUT_MGMT,
+ AXP20X_VBUS_CLIMIT_MASK,
+ AXP20X_VBUS_CLIMIT_NONE);
default:
return -EINVAL;
}
--
2.20.1
From: Quentin Schulz <[email protected]>
This adds support for AXP813 PMIC. It is almost the same as AXP22X but
has a different current limit.
Signed-off-by: Quentin Schulz <[email protected]>
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
drivers/power/supply/axp20x_usb_power.c | 66 ++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
index 90d06027bf98..d39c450b14c6 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -42,6 +42,11 @@
#define AXP20X_VBUS_CLIMIT_100mA 2
#define AXP20X_VBUS_CLIMIT_NONE 3
+#define AXP813_VBUS_CLIMIT_900mA 0
+#define AXP813_VBUS_CLIMIT_1500mA 1
+#define AXP813_VBUS_CLIMIT_2000mA 2
+#define AXP813_VBUS_CLIMIT_2500mA 3
+
#define AXP20X_ADC_EN1_VBUS_CURR BIT(2)
#define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
@@ -131,6 +136,31 @@ static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val)
return 0;
}
+static int axp813_get_current_max(struct axp20x_usb_power *power, int *val)
+{
+ unsigned int v;
+ int ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
+
+ if (ret)
+ return ret;
+
+ switch (v & AXP20X_VBUS_CLIMIT_MASK) {
+ case AXP813_VBUS_CLIMIT_900mA:
+ *val = 900000;
+ break;
+ case AXP813_VBUS_CLIMIT_1500mA:
+ *val = 1500000;
+ break;
+ case AXP813_VBUS_CLIMIT_2000mA:
+ *val = 2000000;
+ break;
+ case AXP813_VBUS_CLIMIT_2500mA:
+ *val = 2500000;
+ break;
+ }
+ return 0;
+}
+
static int axp20x_usb_power_get_property(struct power_supply *psy,
enum power_supply_property psp, union power_supply_propval *val)
{
@@ -169,6 +199,8 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
val->intval = ret * 1700; /* 1 step = 1.7 mV */
return 0;
case POWER_SUPPLY_PROP_CURRENT_MAX:
+ if (power->axp20x_id == AXP813_ID)
+ return axp813_get_current_max(power, &val->intval);
return axp20x_get_current_max(power, &val->intval);
case POWER_SUPPLY_PROP_CURRENT_NOW:
if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
@@ -260,6 +292,31 @@ static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
return -EINVAL;
}
+static int axp813_usb_power_set_current_max(struct axp20x_usb_power *power,
+ int intval)
+{
+ int val;
+
+ switch (intval) {
+ case 900000:
+ return regmap_update_bits(power->regmap,
+ AXP20X_VBUS_IPSOUT_MGMT,
+ AXP20X_VBUS_CLIMIT_MASK,
+ AXP813_VBUS_CLIMIT_900mA);
+ case 1500000:
+ case 2000000:
+ case 2500000:
+ val = (intval - 1000000) / 500000;
+ return regmap_update_bits(power->regmap,
+ AXP20X_VBUS_IPSOUT_MGMT,
+ AXP20X_VBUS_CLIMIT_MASK, val);
+ default:
+ return -EINVAL;
+ }
+
+ return -EINVAL;
+}
+
static int axp20x_usb_power_set_current_max(struct axp20x_usb_power *power,
int intval)
{
@@ -299,6 +356,9 @@ static int axp20x_usb_power_set_property(struct power_supply *psy,
return axp20x_usb_power_set_voltage_min(power, val->intval);
case POWER_SUPPLY_PROP_CURRENT_MAX:
+ if (power->axp20x_id == AXP813_ID)
+ return axp813_usb_power_set_current_max(power,
+ val->intval);
return axp20x_usb_power_set_current_max(power, val->intval);
default:
@@ -434,7 +494,8 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
usb_power_desc = &axp20x_usb_power_desc;
irq_names = axp20x_irq_names;
} else if (power->axp20x_id == AXP221_ID ||
- power->axp20x_id == AXP223_ID) {
+ power->axp20x_id == AXP223_ID ||
+ power->axp20x_id == AXP813_ID) {
usb_power_desc = &axp22x_usb_power_desc;
irq_names = axp22x_irq_names;
} else {
@@ -493,6 +554,9 @@ static const struct of_device_id axp20x_usb_power_match[] = {
}, {
.compatible = "x-powers,axp223-usb-power-supply",
.data = (void *)AXP223_ID,
+ }, {
+ .compatible = "x-powers,axp813-usb-power-supply",
+ .data = (void *)AXP813_ID,
}, { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
--
2.20.1
From: Quentin Schulz <[email protected]>
The AXP813/818 has a VBUS power input. Add a device node for it, now
that we support it.
Signed-off-by: Quentin Schulz <[email protected]>
[[email protected]: Add commit message]
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
arch/arm/boot/dts/axp81x.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/axp81x.dtsi b/arch/arm/boot/dts/axp81x.dtsi
index bd83962d3627..1dfeeceabf4c 100644
--- a/arch/arm/boot/dts/axp81x.dtsi
+++ b/arch/arm/boot/dts/axp81x.dtsi
@@ -171,4 +171,8 @@
status = "disabled";
};
};
+
+ usb_power_supply: usb-power-supply {
+ compatible = "x-powers,axp813-usb-power-supply";
+ };
};
--
2.20.1
From: Quentin Schulz <[email protected]>
To prepare for a new PMIC, factor out the code responsible of returning
the maximum current to axp20x_get_current_max.
Signed-off-by: Quentin Schulz <[email protected]>
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
drivers/power/supply/axp20x_usb_power.c | 52 ++++++++++++++-----------
1 file changed, 30 insertions(+), 22 deletions(-)
diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
index ac061bcdc056..90d06027bf98 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -102,6 +102,35 @@ static bool axp20x_usb_vbus_needs_polling(struct axp20x_usb_power *power)
return false;
}
+static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val)
+{
+ unsigned int v;
+ int ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
+
+ if (ret)
+ return ret;
+
+ switch (v & AXP20X_VBUS_CLIMIT_MASK) {
+ case AXP20X_VBUS_CLIMIT_100mA:
+ if (power->axp20x_id == AXP221_ID)
+ *val = -1; /* No 100mA limit */
+ else
+ *val = 100000;
+ break;
+ case AXP20X_VBUS_CLIMIT_500mA:
+ *val = 500000;
+ break;
+ case AXP20X_VBUS_CLIMIT_900mA:
+ *val = 900000;
+ break;
+ case AXP20X_VBUS_CLIMIT_NONE:
+ *val = -1;
+ break;
+ }
+
+ return 0;
+}
+
static int axp20x_usb_power_get_property(struct power_supply *psy,
enum power_supply_property psp, union power_supply_propval *val)
{
@@ -140,28 +169,7 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
val->intval = ret * 1700; /* 1 step = 1.7 mV */
return 0;
case POWER_SUPPLY_PROP_CURRENT_MAX:
- ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
- if (ret)
- return ret;
-
- switch (v & AXP20X_VBUS_CLIMIT_MASK) {
- case AXP20X_VBUS_CLIMIT_100mA:
- if (power->axp20x_id == AXP221_ID)
- val->intval = -1; /* No 100mA limit */
- else
- val->intval = 100000;
- break;
- case AXP20X_VBUS_CLIMIT_500mA:
- val->intval = 500000;
- break;
- case AXP20X_VBUS_CLIMIT_900mA:
- val->intval = 900000;
- break;
- case AXP20X_VBUS_CLIMIT_NONE:
- val->intval = -1;
- break;
- }
- return 0;
+ return axp20x_get_current_max(power, &val->intval);
case POWER_SUPPLY_PROP_CURRENT_NOW:
if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
ret = iio_read_channel_processed(power->vbus_i,
--
2.20.1
From: Quentin Schulz <[email protected]>
The AXP813 has a VBUS power input. Now that the axp20x_usb_power driver
supports this variant, we can add an mfd cell for it to use it.
Signed-off-by: Quentin Schulz <[email protected]>
[[email protected]: add commit message]
Acked-for-MFD-by: Lee Jones <[email protected]>
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
Changes since v1:
- Made axp803_usb_power_supply_resources[] constant
- Added Lee's acked-by
---
drivers/mfd/axp20x.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 3c97f2c0fdfe..902f9f27e748 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -198,6 +198,12 @@ static const struct resource axp22x_usb_power_supply_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
};
+/* AXP803 and AXP813/AXP818 share the same interrupts */
+static const struct resource axp803_usb_power_supply_resources[] = {
+ DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
+ DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
+};
+
static const struct resource axp22x_pek_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
@@ -793,6 +799,11 @@ static const struct mfd_cell axp813_cells[] = {
.of_compatible = "x-powers,axp813-ac-power-supply",
.num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
.resources = axp20x_ac_power_supply_resources,
+ }, {
+ .name = "axp20x-usb-power-supply",
+ .num_resources = ARRAY_SIZE(axp803_usb_power_supply_resources),
+ .resources = axp803_usb_power_supply_resources,
+ .of_compatible = "x-powers,axp813-usb-power-supply",
},
};
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
The Bananapi M3 and Cubietruck Plus both have USB OTG ports wired to the
SoC and PMIC in the same way, with the N_VBUSEN pin on the PMIC
controlling VBUS output, the PMIC's VBUS input for sensing VBUS, and
PH11 on the SoC for sensing the ID pin.
Enable OTG on both boards.
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts | 12 ++++++++++++
arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts | 12 ++++++++++++
2 files changed, 24 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
index 838be7b3715f..9d34eabba121 100644
--- a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
@@ -389,7 +389,19 @@
};
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
&usbphy {
+ usb0_id_det-gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb0_vbus-supply = <®_drivevbus>;
usb1_vbus-supply = <®_usb1_vbus>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
index fcbec3d7ccd7..ea299d3d84d0 100644
--- a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
+++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
@@ -420,7 +420,19 @@
};
};
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb_power_supply {
+ status = "okay";
+};
+
&usbphy {
+ usb0_id_det-gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */
+ usb0_vbus_power-supply = <&usb_power_supply>;
+ usb0_vbus-supply = <®_drivevbus>;
usb1_vbus-supply = <®_usb1_vbus>;
usb2_vbus-supply = <®_usb2_vbus>;
status = "okay";
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
This adds the "x-powers,axp813-usb-power-supply" to the list of
compatibles for AXP20X VBUS power supply driver.
Reviewed-by: Rob Herring <[email protected]>
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
Changes since v2:
- Collected Rob's Reviewed-by
---
.../devicetree/bindings/power/supply/axp20x_usb_power.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt b/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt
index ba8d35f66cbe..b2d4968fde7d 100644
--- a/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt
+++ b/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt
@@ -4,6 +4,7 @@ Required Properties:
-compatible: One of: "x-powers,axp202-usb-power-supply"
"x-powers,axp221-usb-power-supply"
"x-powers,axp223-usb-power-supply"
+ "x-powers,axp813-usb-power-supply"
The AXP223 PMIC shares most of its behaviour with the AXP221 but has slight
variations such as the former being able to set the VBUS power supply max
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
On AXP221 and later AXP PMICs that have the N_VBUSEN pin, when this pin
is high, either due to the PMIC driving it high or as an input, the VBUS
detection related interrupt mechanisms are disabled.
Previously this was worked around in the phy-sun4i-usb driver, which
needed to sense VBUS changes and report them to the musb driver in a
timely matter. However this workaround was only for the A31 and A33 type
USB PHYs. To support newer platforms we would have to enable it for
almost all the post-A31 SoCs.
However, since this is actually the result of the PMIC's behavior, the
workaround would be better if done in the PMIC driver, in this case the
VBUS power supply driver.
Add the same workqueue-based polling to the VBUS power supply driver.
The polling interval is chosen to be the debounce interval from the USB
PHY driver, as this short interval is needed in some cases, but the
power supply driver would not know when.
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
drivers/power/supply/axp20x_usb_power.c | 53 +++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
index e2f353906bb1..ac061bcdc056 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -24,6 +24,7 @@
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/iio/consumer.h>
+#include <linux/workqueue.h>
#define DRVNAME "axp20x-usb-power-supply"
@@ -46,6 +47,12 @@
#define AXP20X_VBUS_MON_VBUS_VALID BIT(3)
+/*
+ * Note do not raise the debounce time, we must report Vusb high within
+ * 100ms otherwise we get Vbus errors in musb.
+ */
+#define DEBOUNCE_TIME msecs_to_jiffies(50)
+
struct axp20x_usb_power {
struct device_node *np;
struct regmap *regmap;
@@ -53,6 +60,8 @@ struct axp20x_usb_power {
enum axp20x_variants axp20x_id;
struct iio_channel *vbus_v;
struct iio_channel *vbus_i;
+ struct delayed_work vbus_detect;
+ unsigned int old_status;
};
static irqreturn_t axp20x_usb_power_irq(int irq, void *devid)
@@ -64,6 +73,35 @@ static irqreturn_t axp20x_usb_power_irq(int irq, void *devid)
return IRQ_HANDLED;
}
+static void axp20x_usb_power_poll_vbus(struct work_struct *work)
+{
+ struct axp20x_usb_power *power =
+ container_of(work, struct axp20x_usb_power, vbus_detect.work);
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &val);
+ if (ret)
+ goto out;
+
+ val &= (AXP20X_PWR_STATUS_VBUS_PRESENT | AXP20X_PWR_STATUS_VBUS_USED);
+ if (val != power->old_status)
+ power_supply_changed(power->supply);
+
+ power->old_status = val;
+
+out:
+ mod_delayed_work(system_wq, &power->vbus_detect, DEBOUNCE_TIME);
+}
+
+static bool axp20x_usb_vbus_needs_polling(struct axp20x_usb_power *power)
+{
+ if (power->axp20x_id >= AXP221_ID)
+ return true;
+
+ return false;
+}
+
static int axp20x_usb_power_get_property(struct power_supply *psy,
enum power_supply_property psp, union power_supply_propval *val)
{
@@ -362,6 +400,7 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
if (!power)
return -ENOMEM;
+ platform_set_drvdata(pdev, power);
power->axp20x_id = (enum axp20x_variants)of_device_get_match_data(
&pdev->dev);
@@ -420,6 +459,19 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
irq_names[i], ret);
}
+ INIT_DELAYED_WORK(&power->vbus_detect, axp20x_usb_power_poll_vbus);
+ if (axp20x_usb_vbus_needs_polling(power))
+ queue_delayed_work(system_wq, &power->vbus_detect, 0);
+
+ return 0;
+}
+
+static int axp20x_usb_power_remove(struct platform_device *pdev)
+{
+ struct axp20x_usb_power *power = platform_get_drvdata(pdev);
+
+ cancel_delayed_work_sync(&power->vbus_detect);
+
return 0;
}
@@ -439,6 +491,7 @@ MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
static struct platform_driver axp20x_usb_power_driver = {
.probe = axp20x_usb_power_probe,
+ .remove = axp20x_usb_power_remove,
.driver = {
.name = DRVNAME,
.of_match_table = axp20x_usb_power_match,
--
2.20.1
From: Chen-Yu Tsai <[email protected]>
The VBUS current limit value macros have VBUS typed as VBUC, while
the bitmask macro is named correctly. Fix it.
Fixes: 69fb4dcada77 ("power: Add an axp20x-usb-power driver")
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
drivers/power/supply/axp20x_usb_power.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
index f52fe77edb6f..cd9b90d79839 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -36,10 +36,10 @@
#define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3)
#define AXP20X_VBUS_VHOLD_OFFSET 3
#define AXP20X_VBUS_CLIMIT_MASK 3
-#define AXP20X_VBUC_CLIMIT_900mA 0
-#define AXP20X_VBUC_CLIMIT_500mA 1
-#define AXP20X_VBUC_CLIMIT_100mA 2
-#define AXP20X_VBUC_CLIMIT_NONE 3
+#define AXP20X_VBUS_CLIMIT_900mA 0
+#define AXP20X_VBUS_CLIMIT_500mA 1
+#define AXP20X_VBUS_CLIMIT_100mA 2
+#define AXP20X_VBUS_CLIMIT_NONE 3
#define AXP20X_ADC_EN1_VBUS_CURR BIT(2)
#define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
@@ -107,19 +107,19 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
return ret;
switch (v & AXP20X_VBUS_CLIMIT_MASK) {
- case AXP20X_VBUC_CLIMIT_100mA:
+ case AXP20X_VBUS_CLIMIT_100mA:
if (power->axp20x_id == AXP221_ID)
val->intval = -1; /* No 100mA limit */
else
val->intval = 100000;
break;
- case AXP20X_VBUC_CLIMIT_500mA:
+ case AXP20X_VBUS_CLIMIT_500mA:
val->intval = 500000;
break;
- case AXP20X_VBUC_CLIMIT_900mA:
+ case AXP20X_VBUS_CLIMIT_900mA:
val->intval = 900000;
break;
- case AXP20X_VBUC_CLIMIT_NONE:
+ case AXP20X_VBUS_CLIMIT_NONE:
val->intval = -1;
break;
}
--
2.20.1
Hi,
The rest of the series is
Acked-by: Maxime Ripard <[email protected]>
On Thu, Mar 21, 2019 at 04:48:44PM +0800, Chen-Yu Tsai wrote:
> From: Chen-Yu Tsai <[email protected]>
>
> The AXP PMICs allow the user to disable current limiting on the VBUS
> input. While read-out of this setting was already supported by the
> driver, it did not allow the user to configure the PMIC to disable
> current limiting.
>
> Add support for this.
>
> Signed-off-by: Chen-Yu Tsai <[email protected]>
Do we really want to do that though? That could have some pretty bad
consequences.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Thu, Mar 21, 2019 at 5:30 PM Maxime Ripard <[email protected]> wrote:
>
> Hi,
>
> The rest of the series is
> Acked-by: Maxime Ripard <[email protected]>
>
> On Thu, Mar 21, 2019 at 04:48:44PM +0800, Chen-Yu Tsai wrote:
> > From: Chen-Yu Tsai <[email protected]>
> >
> > The AXP PMICs allow the user to disable current limiting on the VBUS
> > input. While read-out of this setting was already supported by the
> > driver, it did not allow the user to configure the PMIC to disable
> > current limiting.
> >
> > Add support for this.
> >
> > Signed-off-by: Chen-Yu Tsai <[email protected]>
>
> Do we really want to do that though? That could have some pretty bad
> consequences.
If I understand the manual correctly, the PMIC has two mode of operation
with regards to VBUS. Normal operation means the PMIC will try to limit
the current draw to maintain VBUS above the set V_hold (defaults to 4.4V).
This is in addition to the current limit set in this patch.
The other mode of operation is bypass, where it ignores the voltage limit.
Not sure if it also ignores the current limit, but probably not. In any
case we don't support this mode in the driver.
So I can think of a few cases where this might be bad:
1. High current draw results in excessive voltage drop and heating over
line / traces due to insufficient conductor area. This should be covered
by the voltage holding mechanism.
2. Over taxing the external power supply. This should also result in some
voltage drop for simple power bricks. Advanced ones would either have
current limiting or over-current protection.
What bad consequences are you thinking of?
ChenYu
Hi,
On 25-03-19 03:45, Chen-Yu Tsai wrote:
> On Thu, Mar 21, 2019 at 5:30 PM Maxime Ripard <[email protected]> wrote:
>>
>> Hi,
>>
>> The rest of the series is
>> Acked-by: Maxime Ripard <[email protected]>
>>
>> On Thu, Mar 21, 2019 at 04:48:44PM +0800, Chen-Yu Tsai wrote:
>>> From: Chen-Yu Tsai <[email protected]>
>>>
>>> The AXP PMICs allow the user to disable current limiting on the VBUS
>>> input. While read-out of this setting was already supported by the
>>> driver, it did not allow the user to configure the PMIC to disable
>>> current limiting.
>>>
>>> Add support for this.
>>>
>>> Signed-off-by: Chen-Yu Tsai <[email protected]>
>>
>> Do we really want to do that though? That could have some pretty bad
>> consequences.
>
> If I understand the manual correctly, the PMIC has two mode of operation
> with regards to VBUS. Normal operation means the PMIC will try to limit
> the current draw to maintain VBUS above the set V_hold (defaults to 4.4V).
> This is in addition to the current limit set in this patch.
>
> The other mode of operation is bypass, where it ignores the voltage limit.
> Not sure if it also ignores the current limit, but probably not. In any
> case we don't support this mode in the driver.
>
> So I can think of a few cases where this might be bad:
>
> 1. High current draw results in excessive voltage drop and heating over
> line / traces due to insufficient conductor area. This should be covered
> by the voltage holding mechanism.
>
> 2. Over taxing the external power supply. This should also result in some
> voltage drop for simple power bricks. Advanced ones would either have
> current limiting or over-current protection.
>
> What bad consequences are you thinking of?
Lets say you use a typical 5v / 2A charger-plug, lets also say that at full
load this brick has an efficiency of 90%. At full load it delivers 10W of
power, while consuming 11.1W dissipating 1.1W of losses as heat.
Now lets say we disable current-limiting and rely only on the V_hold
mechanism, lets say that we end up with 4.5 volts at 2.4 amps because of
this and since we are now operating in overload conditions the
efficiency has fallen to 80% (approx. 4.5/5.0 * 90%) so now at full load
it delivers 10.8W of power, while consuming 13.5W dissipating 2.7W of
losses as heat. Chances are the the small plastic enclosure of your
typical charger-plug cannot dissipate this much and will start warming
up, until it bursts into flames.
Disabling current limit protection is a very bad idea because you will
end up in an equilibrium between the Vhold from the charger-ic and the
over-current protection from the power-brick where you are over the
design limit of the power-brick.
I actually like what the TI charger-ics are doing here a lot more then
what the AXP series is doing, with TI charger-ics if you set a current
limit > 500mA and the power-brick's voltages drops too much because of
this (or because of a bad cable) it automatically falls back to 500mA.
Where as at least with the AXP288, it simply starts drawing 1.5A at 4.5V
with a bad cable, but in this case the dissipation at least is happening
inside the cable rather then inside the charger-plug, which typically
already gets quite hot under normal operation conditions.
Disabling the current limit is basically the same as what bad USB-A
to USB-C cables which have a Rp-3.0 resistor in the C plug do, these tell
the device with the Type-C plug it can safely draw 3A from the A-port the
A plug is plugged into. The web is full of stories about this causing
damage to machines, e.g.:
"Bohn's Nexus 6P drew too much power from his MacBook Air while using a third-party cord, frying the machine and making the USB Type-C ports work only intermittently."
From: https://www.laptopmag.com/articles/how-to-find-safe-usb-type-c-cables
Another good link about the problems caused by these bad Rp resistor
values in Type-C to Type-A cables (which also effectively disable the
current-limit on the device charging on the C-end of the cable):
https://plus.google.com/102617628172847077584/posts/HakwCMmd346
Note this second link is going away in 6 days as google is retiring
google+.
Anyways TL;DR: Disabling the current-limit is a bad idea and really
nothing good can come from this.
Regards,
Hans
On Mon, Mar 25, 2019 at 4:58 PM Hans de Goede <[email protected]> wrote:
>
> Hi,
>
> On 25-03-19 03:45, Chen-Yu Tsai wrote:
> > On Thu, Mar 21, 2019 at 5:30 PM Maxime Ripard <[email protected]> wrote:
> >>
> >> Hi,
> >>
> >> The rest of the series is
> >> Acked-by: Maxime Ripard <[email protected]>
> >>
> >> On Thu, Mar 21, 2019 at 04:48:44PM +0800, Chen-Yu Tsai wrote:
> >>> From: Chen-Yu Tsai <[email protected]>
> >>>
> >>> The AXP PMICs allow the user to disable current limiting on the VBUS
> >>> input. While read-out of this setting was already supported by the
> >>> driver, it did not allow the user to configure the PMIC to disable
> >>> current limiting.
> >>>
> >>> Add support for this.
> >>>
> >>> Signed-off-by: Chen-Yu Tsai <[email protected]>
> >>
> >> Do we really want to do that though? That could have some pretty bad
> >> consequences.
> >
> > If I understand the manual correctly, the PMIC has two mode of operation
> > with regards to VBUS. Normal operation means the PMIC will try to limit
> > the current draw to maintain VBUS above the set V_hold (defaults to 4.4V).
> > This is in addition to the current limit set in this patch.
> >
> > The other mode of operation is bypass, where it ignores the voltage limit.
> > Not sure if it also ignores the current limit, but probably not. In any
> > case we don't support this mode in the driver.
> >
> > So I can think of a few cases where this might be bad:
> >
> > 1. High current draw results in excessive voltage drop and heating over
> > line / traces due to insufficient conductor area. This should be covered
> > by the voltage holding mechanism.
> >
> > 2. Over taxing the external power supply. This should also result in some
> > voltage drop for simple power bricks. Advanced ones would either have
> > current limiting or over-current protection.
> >
> > What bad consequences are you thinking of?
>
> Lets say you use a typical 5v / 2A charger-plug, lets also say that at full
> load this brick has an efficiency of 90%. At full load it delivers 10W of
> power, while consuming 11.1W dissipating 1.1W of losses as heat.
>
> Now lets say we disable current-limiting and rely only on the V_hold
> mechanism, lets say that we end up with 4.5 volts at 2.4 amps because of
> this and since we are now operating in overload conditions the
> efficiency has fallen to 80% (approx. 4.5/5.0 * 90%) so now at full load
> it delivers 10.8W of power, while consuming 13.5W dissipating 2.7W of
> losses as heat. Chances are the the small plastic enclosure of your
> typical charger-plug cannot dissipate this much and will start warming
> up, until it bursts into flames.
>
> Disabling current limit protection is a very bad idea because you will
> end up in an equilibrium between the Vhold from the charger-ic and the
> over-current protection from the power-brick where you are over the
> design limit of the power-brick.
>
> I actually like what the TI charger-ics are doing here a lot more then
> what the AXP series is doing, with TI charger-ics if you set a current
> limit > 500mA and the power-brick's voltages drops too much because of
> this (or because of a bad cable) it automatically falls back to 500mA.
> Where as at least with the AXP288, it simply starts drawing 1.5A at 4.5V
> with a bad cable, but in this case the dissipation at least is happening
> inside the cable rather then inside the charger-plug, which typically
> already gets quite hot under normal operation conditions.
>
> Disabling the current limit is basically the same as what bad USB-A
> to USB-C cables which have a Rp-3.0 resistor in the C plug do, these tell
> the device with the Type-C plug it can safely draw 3A from the A-port the
> A plug is plugged into. The web is full of stories about this causing
> damage to machines, e.g.:
>
> "Bohn's Nexus 6P drew too much power from his MacBook Air while using a third-party cord, frying the machine and making the USB Type-C ports work only intermittently."
>
> From: https://www.laptopmag.com/articles/how-to-find-safe-usb-type-c-cables
>
> Another good link about the problems caused by these bad Rp resistor
> values in Type-C to Type-A cables (which also effectively disable the
> current-limit on the device charging on the C-end of the cable):
> https://plus.google.com/102617628172847077584/posts/HakwCMmd346
>
> Note this second link is going away in 6 days as google is retiring
> google+.
>
> Anyways TL;DR: Disabling the current-limit is a bad idea and really
> nothing good can come from this.
OK. I'll respin the series without this.
ChenYu
On Thu, 21 Mar 2019, Chen-Yu Tsai wrote:
> From: Quentin Schulz <[email protected]>
>
> The AXP813 has a VBUS power input. Now that the axp20x_usb_power driver
> supports this variant, we can add an mfd cell for it to use it.
>
> Signed-off-by: Quentin Schulz <[email protected]>
> [[email protected]: add commit message]
> Acked-for-MFD-by: Lee Jones <[email protected]>
> Signed-off-by: Chen-Yu Tsai <[email protected]>
This patch looks orthogonal.
Unless anyone screams, I'm going to apply it.
> ---
>
> Changes since v1:
> - Made axp803_usb_power_supply_resources[] constant
> - Added Lee's acked-by
> ---
> drivers/mfd/axp20x.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 3c97f2c0fdfe..902f9f27e748 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -198,6 +198,12 @@ static const struct resource axp22x_usb_power_supply_resources[] = {
> DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
> };
>
> +/* AXP803 and AXP813/AXP818 share the same interrupts */
> +static const struct resource axp803_usb_power_supply_resources[] = {
> + DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
> + DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
> +};
> +
> static const struct resource axp22x_pek_resources[] = {
> DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
> DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
> @@ -793,6 +799,11 @@ static const struct mfd_cell axp813_cells[] = {
> .of_compatible = "x-powers,axp813-ac-power-supply",
> .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
> .resources = axp20x_ac_power_supply_resources,
> + }, {
> + .name = "axp20x-usb-power-supply",
> + .num_resources = ARRAY_SIZE(axp803_usb_power_supply_resources),
> + .resources = axp803_usb_power_supply_resources,
> + .of_compatible = "x-powers,axp813-usb-power-supply",
> },
> };
>
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog