phy: sun4i-usb: Add id_detect and vbus_detect ops
authorJagan Teki <jagan@amarulasolutions.com>
Mon, 7 May 2018 07:33:27 +0000 (13:03 +0530)
committerJagan Teki <jagan@amarulasolutions.com>
Mon, 28 May 2018 11:10:43 +0000 (16:40 +0530)
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>
drivers/phy/allwinner/phy-sun4i-usb.c
include/phy-sun4i-usb.h [new file with mode: 0644]

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,
diff --git a/include/phy-sun4i-usb.h b/include/phy-sun4i-usb.h
new file mode 100644 (file)
index 0000000..040e9d3
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 Jagan Teki <jagan@amarulasolutions.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __GENERIC_PHY_SUN4I_USB_H
+#define __GENERIC_PHY_SUN4I_USB_H
+
+/**
+ * sun4i_usb_phy_id_detect - detect ID pin of USB PHY
+ *
+ * @phy:       USB PHY port to detect ID pin
+ * @return 0 if OK, or a negative error code
+ */
+int sun4i_usb_phy_id_detect(struct phy *phy);
+
+/**
+ * sun4i_usb_phy_vbus_detect - detect VBUS pin of USB PHY
+ *
+ * @phy:       USB PHY port to detect VBUS pin
+ * @return 0 if OK, or a negative error code
+ */
+int sun4i_usb_phy_vbus_detect(struct phy *phy);
+
+#endif /*__GENERIC_PHY_SUN4I_USB_H */