return 0;
}
#else
+#define USB_INIT_UNKNOWN (USB_INIT_DEVICE + 1)
+
struct ehci_mx6_priv_data {
struct ehci_ctrl ctrl;
struct usb_ehci *ehci;
static int ehci_usb_phy_mode(struct udevice *dev)
{
- struct usb_platdata *plat = dev_get_platdata(dev);
+ struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
void *__iomem addr = (void *__iomem)devfdt_get_addr(dev);
void *__iomem phy_ctrl, *__iomem phy_status;
const void *blob = gd->fdt_blob;
val = readl(phy_ctrl);
if (val & USBPHY_CTRL_OTG_ID)
- plat->init_type = USB_INIT_DEVICE;
+ priv->init_type = USB_INIT_DEVICE;
else
- plat->init_type = USB_INIT_HOST;
+ priv->init_type = USB_INIT_HOST;
} else if (is_mx7() || is_imx8mm()) {
phy_status = (void __iomem *)(addr +
USBNC_PHY_STATUS_OFFSET);
val = readl(phy_status);
if (val & USBNC_PHYSTATUS_ID_DIG)
- plat->init_type = USB_INIT_DEVICE;
+ priv->init_type = USB_INIT_DEVICE;
else
- plat->init_type = USB_INIT_HOST;
+ priv->init_type = USB_INIT_HOST;
} else {
return -EINVAL;
}
static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
{
struct usb_platdata *plat = dev_get_platdata(dev);
+ struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
const char *mode;
const struct fdt_property *extcon;
mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "dr_mode", NULL);
if (mode) {
if (strcmp(mode, "peripheral") == 0)
- plat->init_type = USB_INIT_DEVICE;
+ priv->init_type = USB_INIT_DEVICE;
else if (strcmp(mode, "host") == 0)
- plat->init_type = USB_INIT_HOST;
+ priv->init_type = USB_INIT_HOST;
else if (strcmp(mode, "otg") == 0)
- return ehci_usb_phy_mode(dev);
+ priv->init_type = USB_INIT_UNKNOWN;
else
return -EINVAL;
-
- return 0;
} else {
extcon = fdt_get_property(gd->fdt_blob, dev_of_offset(dev),
"extcon", NULL);
- if (extcon) {
- plat->init_type = board_ehci_usb_phy_mode(dev);
- return 0;
- }
+ if (extcon)
+ priv->init_type = board_ehci_usb_phy_mode(dev);
+ else
+ priv->init_type = USB_INIT_UNKNOWN;
}
- return ehci_usb_phy_mode(dev);
+ if (priv->init_type != USB_INIT_UNKNOWN && priv->init_type != plat->init_type) {
+ debug("Request USB type is %u, board forced type is %u\n",
+ plat->init_type, priv->init_type);
+ return -ENODEV;
+ }
+
+ return 0;
}
static int ehci_usb_probe(struct udevice *dev)
priv->ehci = ehci;
priv->portnr = dev->seq;
- priv->init_type = type;
- ret = board_usb_init(priv->portnr, priv->init_type);
+ /* Init usb board level according to the requested init type */
+ ret = board_usb_init(priv->portnr, type);
if (ret) {
printf("Failed to initialize board for USB\n");
return ret;
if (ret)
return ret;
+ /* If the init_type is unknown due to it is not forced in DTB, we use USB ID to detect */
+ if (priv->init_type == USB_INIT_UNKNOWN) {
+ ret = ehci_usb_phy_mode(dev);
+ if (ret)
+ return ret;
+ if (priv->init_type != type)
+ return -ENODEV;
+ }
+
#if CONFIG_IS_ENABLED(DM_REGULATOR)
if (priv->vbus_supply) {
ret = regulator_set_enable(priv->vbus_supply,
- (type == USB_INIT_DEVICE) ?
+ (priv->init_type == USB_INIT_DEVICE) ?
false : true);
if (ret) {
puts("Error enabling VBUS supply\n");
int ehci_usb_remove(struct udevice *dev)
{
struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
+ struct usb_platdata *plat = dev_get_platdata(dev);
ehci_deregister(dev);
+ plat->init_type = 0; /* Clean the requested usb type to host mode */
+
return board_usb_cleanup(dev->seq, priv->init_type);
}