]> git.sur5r.net Git - u-boot/blobdiff - drivers/phy/allwinner/phy-sun4i-usb.c
phy: sun4i-usb: Add id_detect and vbus_detect ops
[u-boot] / drivers / phy / allwinner / phy-sun4i-usb.c
index 78304c1f228134d8486b44a0fb42b95ab49b13aa..7f2970b96bda291f23d65ec333e4f321645f0dff 100644 (file)
@@ -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,