[PATCH 9/9] usb: imx-us-phy: implement notify_(dis)concect

Sascha Hauer s.hauer at pengutronix.de
Thu Sep 29 05:39:00 PDT 2016


The i.MX6 USB phy does not recognize disconnects of high speed
devices when the USBPHY_CTRL_ENHOSTDISCONDETECT is not set. The
phy does not work properly though when this bit is always set, so
implement the notify_(dis)concect() callbacks to set this bit
whenever a high speed device is connected and to clear it again
when the device is disconnected.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/usb/imx/imx-usb-phy.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/usb/imx/imx-usb-phy.c b/drivers/usb/imx/imx-usb-phy.c
index 2829ffc..9f46f8d 100644
--- a/drivers/usb/imx/imx-usb-phy.c
+++ b/drivers/usb/imx/imx-usb-phy.c
@@ -33,6 +33,7 @@
 #define USBPHY_CTRL_CLKGATE		(1 << 30)
 #define USBPHY_CTRL_ENUTMILEVEL3	(1 << 15)
 #define USBPHY_CTRL_ENUTMILEVEL2	(1 << 14)
+#define USBPHY_CTRL_ENHOSTDISCONDETECT	(1 << 1)
 
 struct imx_usbphy {
 	struct usb_phy usb_phy;
@@ -67,6 +68,30 @@ static int imx_usbphy_phy_init(struct phy *phy)
 	return 0;
 }
 
+static int imx_usbphy_notify_connect(struct usb_phy *phy,
+				     enum usb_device_speed speed)
+{
+	struct imx_usbphy *imxphy = container_of(phy, struct imx_usbphy, usb_phy);
+
+	if (speed == USB_SPEED_HIGH) {
+		writel(USBPHY_CTRL_ENHOSTDISCONDETECT,
+		       imxphy->base + USBPHY_CTRL + SET);
+	}
+
+	return 0;
+}
+
+static int imx_usbphy_notify_disconnect(struct usb_phy *phy,
+					enum usb_device_speed speed)
+{
+	struct imx_usbphy *imxphy = container_of(phy, struct imx_usbphy, usb_phy);
+
+	writel(USBPHY_CTRL_ENHOSTDISCONDETECT,
+	       imxphy->base + USBPHY_CTRL + CLR);
+
+	return 0;
+}
+
 static struct phy *imx_usbphy_xlate(struct device_d *dev,
 				    struct of_phandle_args *args)
 {
@@ -112,6 +137,8 @@ static int imx_usbphy_probe(struct device_d *dev)
 	dev->priv = imxphy;
 
 	imxphy->usb_phy.dev = dev;
+	imxphy->usb_phy.notify_connect = imx_usbphy_notify_connect;
+	imxphy->usb_phy.notify_disconnect = imx_usbphy_notify_disconnect;
 	imxphy->phy = phy_create(dev, NULL, &imx_phy_ops, NULL);
 	if (IS_ERR(imxphy->phy)) {
 		ret = PTR_ERR(imxphy->phy);
-- 
2.9.3




More information about the barebox mailing list