usb: imx-us-phy: implement notify_(dis)concect
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@pengutronix.de>
This commit is contained in:
parent
a44f222e09
commit
e21ddc6ec0
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue