163 lines
5.1 KiB
Diff
163 lines
5.1 KiB
Diff
From e8fb34342dfb79cd2059431dd1a0f03202a244ca Mon Sep 17 00:00:00 2001
|
|
From: Samuel Holland <samuel@sholland.org>
|
|
Date: Thu, 26 Aug 2021 22:11:37 -0500
|
|
Subject: [PATCH 09/90] phy: sun4i-usb: Control USB supplies via regulator
|
|
uclass
|
|
|
|
The device tree binding for the PHY provides VBUS supplies as regulator
|
|
references. Now that all boards have the appropriate regulator uclass
|
|
drivers enabled, the PHY driver can switch to using them. This replaces
|
|
direct GPIO usage, which in some cases needed a special DM-incompatible
|
|
"virtual" GPIO from the PMIC.
|
|
|
|
The following boards provided a value for CONFIG_USB0_VBUS_PIN, but are
|
|
missing the "usb0_vbus-supply" property in their device tree. None of
|
|
them have the MUSB controller enabled in host or OTG mode, so they
|
|
should see no impact:
|
|
- Ainol_AW1_defconfig / sun7i-a20-ainol-aw1
|
|
- Ampe_A76_defconfig / sun5i-a13-ampe-a76
|
|
- CHIP_pro_defconfig / sun5i-gr8-chip-pro
|
|
- Cubieboard4_defconfig / sun9i-a80-cubieboard4
|
|
- Merrii_A80_Optimus_defconfig / sun9i-a80-optimus
|
|
- Sunchip_CX-A99_defconfig / sun9i-a80-cx-a99
|
|
- Yones_Toptech_BD1078_defconfig / sun7i-a20-yones-toptech-bd1078
|
|
- Yones_Toptech_BS1078_V2_defconfig /
|
|
sun6i-a31s-yones-toptech-bs1078-v2
|
|
- iNet_3F_defconfig / sun4i-a10-inet-3f
|
|
- iNet_3W_defconfig / sun4i-a10-inet-3w
|
|
- iNet_86VS_defconfig / sun5i-a13-inet-86vs
|
|
- iNet_D978_rev2_defconfig / sun8i-a33-inet-d978-rev2
|
|
- icnova-a20-swac_defconfig / sun7i-a20-icnova-swac
|
|
- sun8i_a23_evb_defconfig / sun8i-a23-evb
|
|
|
|
Similarly, the following boards set CONFIG_USB1_VBUS_PIN, but do not
|
|
have "usb1_vbus-supply" in their device tree. Neither of them have USB
|
|
enabled at all, so again there should be no impact:
|
|
- Cubieboard4_defconfig / sun9i-a80-cubieboard4 (also for USB3)
|
|
- sun8i_a23_evb_defconfig / sun8i-a23-evb
|
|
|
|
The following boards use a different pin for USB1 VBUS between their
|
|
defconfig and their device tree. Depending on which is correct, they
|
|
may be broken:
|
|
- Linksprite_pcDuino3_Nano_defconfig (PH11) /
|
|
sun7i-a20-pcduino3-nano (PD2)
|
|
- icnova-a20-swac_defconfig (PG10) / sun7i-a20-icnova-swac (PH6)
|
|
|
|
Finally, this board has conflicting pins given for its USB2 VBUS:
|
|
- Lamobo_R1_defconfig (PH3) / sun7i-a20-lamobo-r1 (PH12)
|
|
|
|
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
|
---
|
|
drivers/phy/allwinner/phy-sun4i-usb.c | 41 +++++++++++++--------------
|
|
1 file changed, 19 insertions(+), 22 deletions(-)
|
|
|
|
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
|
|
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
|
|
@@ -97,27 +97,22 @@ struct sun4i_usb_phy_cfg {
|
|
};
|
|
|
|
struct sun4i_usb_phy_info {
|
|
- const char *gpio_vbus;
|
|
const char *gpio_vbus_det;
|
|
const char *gpio_id_det;
|
|
} phy_info[] = {
|
|
{
|
|
- .gpio_vbus = CONFIG_USB0_VBUS_PIN,
|
|
.gpio_vbus_det = CONFIG_USB0_VBUS_DET,
|
|
.gpio_id_det = CONFIG_USB0_ID_DET,
|
|
},
|
|
{
|
|
- .gpio_vbus = CONFIG_USB1_VBUS_PIN,
|
|
.gpio_vbus_det = NULL,
|
|
.gpio_id_det = NULL,
|
|
},
|
|
{
|
|
- .gpio_vbus = CONFIG_USB2_VBUS_PIN,
|
|
.gpio_vbus_det = NULL,
|
|
.gpio_id_det = NULL,
|
|
},
|
|
{
|
|
- .gpio_vbus = CONFIG_USB3_VBUS_PIN,
|
|
.gpio_vbus_det = NULL,
|
|
.gpio_id_det = NULL,
|
|
},
|
|
@@ -125,11 +120,11 @@ struct sun4i_usb_phy_info {
|
|
|
|
struct sun4i_usb_phy_plat {
|
|
void __iomem *pmu;
|
|
- struct gpio_desc gpio_vbus;
|
|
struct gpio_desc gpio_vbus_det;
|
|
struct gpio_desc gpio_id_det;
|
|
struct clk clocks;
|
|
struct reset_ctl resets;
|
|
+ struct udevice *vbus;
|
|
int id;
|
|
};
|
|
|
|
@@ -218,14 +213,18 @@ static int sun4i_usb_phy_power_on(struct
|
|
{
|
|
struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
|
|
struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
|
|
+ int ret;
|
|
|
|
if (initial_usb_scan_delay) {
|
|
mdelay(initial_usb_scan_delay);
|
|
initial_usb_scan_delay = 0;
|
|
}
|
|
|
|
- if (dm_gpio_is_valid(&usb_phy->gpio_vbus))
|
|
- dm_gpio_set_value(&usb_phy->gpio_vbus, 1);
|
|
+ if (usb_phy->vbus) {
|
|
+ ret = regulator_set_enable(usb_phy->vbus, true);
|
|
+ if (ret && ret != -ENOSYS)
|
|
+ return ret;
|
|
+ }
|
|
|
|
return 0;
|
|
}
|
|
@@ -234,9 +233,13 @@ static int sun4i_usb_phy_power_off(struc
|
|
{
|
|
struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
|
|
struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
|
|
+ int ret;
|
|
|
|
- if (dm_gpio_is_valid(&usb_phy->gpio_vbus))
|
|
- dm_gpio_set_value(&usb_phy->gpio_vbus, 0);
|
|
+ if (usb_phy->vbus) {
|
|
+ ret = regulator_set_enable(usb_phy->vbus, false);
|
|
+ if (ret && ret != -ENOSYS)
|
|
+ return ret;
|
|
+ }
|
|
|
|
return 0;
|
|
}
|
|
@@ -450,22 +453,16 @@ static int sun4i_usb_phy_probe(struct ud
|
|
for (i = 0; i < data->cfg->num_phys; i++) {
|
|
struct sun4i_usb_phy_plat *phy = &plat[i];
|
|
struct sun4i_usb_phy_info *info = &phy_info[i];
|
|
- char name[16];
|
|
+ char name[20];
|
|
|
|
if (data->cfg->missing_phys & BIT(i))
|
|
continue;
|
|
|
|
- ret = dm_gpio_lookup_name(info->gpio_vbus, &phy->gpio_vbus);
|
|
- if (ret == 0) {
|
|
- ret = dm_gpio_request(&phy->gpio_vbus, "usb_vbus");
|
|
- if (ret)
|
|
- return ret;
|
|
- ret = dm_gpio_set_dir_flags(&phy->gpio_vbus,
|
|
- GPIOD_IS_OUT);
|
|
- if (ret)
|
|
- return ret;
|
|
- ret = dm_gpio_set_value(&phy->gpio_vbus, 0);
|
|
- if (ret)
|
|
+ snprintf(name, sizeof(name), "usb%d_vbus-supply", i);
|
|
+ ret = device_get_supply_regulator(dev, name, &phy->vbus);
|
|
+ if (phy->vbus) {
|
|
+ ret = regulator_set_enable(phy->vbus, false);
|
|
+ if (ret && ret != -ENOSYS)
|
|
return ret;
|
|
}
|
|
|