summaryrefslogtreecommitdiffstats
path: root/drivers/usb/imx/chipidea-imx.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-11-22 15:35:22 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2012-12-13 22:18:46 +0100
commita4076ddf6577a5163c4d36aa4dff2e674df37b2d (patch)
tree1a5e656f29a49f8f77411b77cd52fead9688046f /drivers/usb/imx/chipidea-imx.c
parent15fd89d0a49f015e2b6078a28cb61400f4028e39 (diff)
downloadbarebox-a4076ddf6577a5163c4d36aa4dff2e674df37b2d.tar.gz
barebox-a4076ddf6577a5163c4d36aa4dff2e674df37b2d.tar.xz
USB i.MX: Add chipidea driver support
For proper USB function the usbmisc registers have to be initialized. This patch adds a driver which matches for the usbmisc registers. This driver is called from a new driver which binds to the USB ports to configure the misc registers. After that the driver registers the EHCI driver and an ULPI transceiver if necessary. Currently only host mode is supported, but device support can be added later. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/usb/imx/chipidea-imx.c')
-rw-r--r--drivers/usb/imx/chipidea-imx.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c
new file mode 100644
index 0000000000..5b4c0812cf
--- /dev/null
+++ b/drivers/usb/imx/chipidea-imx.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <driver.h>
+#include <usb/ehci.h>
+#include <usb/chipidea-imx.h>
+#include <usb/ulpi.h>
+
+#define MXC_EHCI_PORTSC_MASK (0xf << 28)
+
+static int imx_chipidea_probe(struct device_d *dev)
+{
+ struct imxusb_platformdata *pdata = dev->platform_data;
+ int ret;
+ void __iomem *base;
+ struct ehci_data data;
+ uint32_t portsc;
+
+ if (!pdata) {
+ dev_err(dev, "no pdata!\n");
+ return -EINVAL;
+ }
+
+ base = dev_request_mem_region(dev, 0);
+ if (!base)
+ return -ENODEV;
+
+ portsc = readl(base + 0x184);
+ portsc &= ~MXC_EHCI_PORTSC_MASK;
+ portsc |= pdata->flags & MXC_EHCI_PORTSC_MASK;
+ writel(portsc, base + 0x184);
+
+ ret = imx_usbmisc_port_init(dev->id, pdata->flags);
+ if (ret) {
+ dev_err(dev, "failed to init misc regs: %s\n", strerror(-ret));
+ return ret;
+ }
+
+ if ((pdata->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_ULPI) {
+ dev_dbg(dev, "using ULPI phy\n");
+ if (IS_ENABLED(CONFIG_USB_ULPI)) {
+ ret = ulpi_setup(base + 0x170, 1);
+ } else {
+ dev_err(dev, "no ULPI support available\n");
+ ret = -ENODEV;
+ }
+
+ if (ret)
+ return ret;
+ }
+
+ data.hccr = base + 0x100;
+ data.hcor = base + 0x140;
+ data.flags = EHCI_HAS_TT;
+
+ if (pdata->mode == IMX_USB_MODE_HOST) {
+ ret = ehci_register(dev, &data);
+ } else {
+ /*
+ * Not yet implemented. Register USB gadget driver here.
+ */
+ ret = -ENOSYS;
+ }
+
+ return ret;
+};
+
+static struct driver_d imx_chipidea_driver = {
+ .name = "imx-usb",
+ .probe = imx_chipidea_probe,
+};
+
+static int imx_chipidea_init(void)
+{
+ return platform_driver_register(&imx_chipidea_driver);
+}
+device_initcall(imx_chipidea_init);