summaryrefslogtreecommitdiffstats
path: root/drivers/phy/allwinner
diff options
context:
space:
mode:
authorJagan Teki <jagan@amarulasolutions.com>2018-05-07 13:03:27 +0530
committerJagan Teki <jagan@amarulasolutions.com>2018-05-28 16:40:43 +0530
commit129c45c72872cf82dde44024864a517267aed68a (patch)
tree99722441279923eea438099c0a5e8d6d67c076d9 /drivers/phy/allwinner
parent6768594326eb358de06772febc06f87fea0a9483 (diff)
downloadu-boot-129c45c72872cf82dde44024864a517267aed68a.tar.gz
u-boot-129c45c72872cf82dde44024864a517267aed68a.tar.xz
u-boot-129c45c72872cf82dde44024864a517267aed68a.zip
phy: sun4i-usb: Add id_detect and vbus_detect ops
ID and VBUS detection code require when musb changing between Host and/or Peripheral modes. Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> Acked-by: Jun Nie <jun.nie@linaro.org>
Diffstat (limited to 'drivers/phy/allwinner')
-rw-r--r--drivers/phy/allwinner/phy-sun4i-usb.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 78304c1f22..7f2970b96b 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -14,6 +14,7 @@
#include <dm.h>
#include <dm/device.h>
#include <generic-phy.h>
+#include <phy-sun4i-usb.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
@@ -295,6 +296,44 @@ static int sun4i_usb_phy_xlate(struct phy *phy,
return 0;
}
+int sun4i_usb_phy_vbus_detect(struct phy *phy)
+{
+ struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
+ struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
+ int err, retries = 3;
+
+ debug("%s: id_det = %d\n", __func__, usb_phy->gpio_id_det);
+
+ if (usb_phy->gpio_vbus_det < 0)
+ return usb_phy->gpio_vbus_det;
+
+ err = gpio_get_value(usb_phy->gpio_vbus_det);
+ /*
+ * Vbus may have been provided by the board and just been turned of
+ * some milliseconds ago on reset, what we're measuring then is a
+ * residual charge on Vbus, sleep a bit and try again.
+ */
+ while (err > 0 && retries--) {
+ mdelay(100);
+ err = gpio_get_value(usb_phy->gpio_vbus_det);
+ }
+
+ return err;
+}
+
+int sun4i_usb_phy_id_detect(struct phy *phy)
+{
+ struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev);
+ struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id];
+
+ debug("%s: id_det = %d\n", __func__, usb_phy->gpio_id_det);
+
+ if (usb_phy->gpio_id_det < 0)
+ return usb_phy->gpio_id_det;
+
+ return gpio_get_value(usb_phy->gpio_id_det);
+}
+
static struct phy_ops sun4i_usb_phy_ops = {
.of_xlate = sun4i_usb_phy_xlate,
.init = sun4i_usb_phy_init,