|
@@ -75,3 +75,109 @@ omap_otg_init(struct omap_usb_config *config)
|
|
|
/* pin muxing and transceiver pinouts */
|
|
|
if (config->pins[0] > 2) /* alt pingroup 2 */
|
|
|
alt_pingroup = 1;
|
|
|
+ syscon |= config->usb0_init(config->pins[0], is_usb0_device(config));
|
|
|
+ syscon |= config->usb1_init(config->pins[1]);
|
|
|
+ syscon |= config->usb2_init(config->pins[2], alt_pingroup);
|
|
|
+ pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1));
|
|
|
+ omap_writel(syscon, OTG_SYSCON_1);
|
|
|
+
|
|
|
+ syscon = config->hmc_mode;
|
|
|
+ syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */;
|
|
|
+#ifdef CONFIG_USB_OTG
|
|
|
+ if (config->otg)
|
|
|
+ syscon |= OTG_EN;
|
|
|
+#endif
|
|
|
+ if (cpu_class_is_omap1())
|
|
|
+ pr_debug("USB_TRANSCEIVER_CTRL = %03x\n",
|
|
|
+ omap_readl(USB_TRANSCEIVER_CTRL));
|
|
|
+ pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2));
|
|
|
+ omap_writel(syscon, OTG_SYSCON_2);
|
|
|
+
|
|
|
+ printk("USB: hmc %d", config->hmc_mode);
|
|
|
+ if (!alt_pingroup)
|
|
|
+ printk(", usb2 alt %d wires", config->pins[2]);
|
|
|
+ else if (config->pins[0])
|
|
|
+ printk(", usb0 %d wires%s", config->pins[0],
|
|
|
+ is_usb0_device(config) ? " (dev)" : "");
|
|
|
+ if (config->pins[1])
|
|
|
+ printk(", usb1 %d wires", config->pins[1]);
|
|
|
+ if (!alt_pingroup && config->pins[2])
|
|
|
+ printk(", usb2 %d wires", config->pins[2]);
|
|
|
+ if (config->otg)
|
|
|
+ printk(", Mini-AB on usb%d", config->otg - 1);
|
|
|
+ printk("\n");
|
|
|
+
|
|
|
+ if (cpu_class_is_omap1()) {
|
|
|
+ u16 w;
|
|
|
+
|
|
|
+ /* leave USB clocks/controllers off until needed */
|
|
|
+ w = omap_readw(ULPD_SOFT_REQ);
|
|
|
+ w &= ~SOFT_USB_CLK_REQ;
|
|
|
+ omap_writew(w, ULPD_SOFT_REQ);
|
|
|
+
|
|
|
+ w = omap_readw(ULPD_CLOCK_CTRL);
|
|
|
+ w &= ~USB_MCLK_EN;
|
|
|
+ w |= DIS_USB_PVCI_CLK;
|
|
|
+ omap_writew(w, ULPD_CLOCK_CTRL);
|
|
|
+ }
|
|
|
+ syscon = omap_readl(OTG_SYSCON_1);
|
|
|
+ syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
|
|
|
+
|
|
|
+#ifdef CONFIG_USB_GADGET_OMAP
|
|
|
+ if (config->otg || config->register_dev) {
|
|
|
+ struct platform_device *udc_device = config->udc_device;
|
|
|
+ int status;
|
|
|
+
|
|
|
+ syscon &= ~DEV_IDLE_EN;
|
|
|
+ udc_device->dev.platform_data = config;
|
|
|
+ status = platform_device_register(udc_device);
|
|
|
+ if (status)
|
|
|
+ pr_debug("can't register UDC device, %d\n", status);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
|
|
|
+ if (config->otg || config->register_host) {
|
|
|
+ struct platform_device *ohci_device = config->ohci_device;
|
|
|
+ int status;
|
|
|
+
|
|
|
+ syscon &= ~HST_IDLE_EN;
|
|
|
+ ohci_device->dev.platform_data = config;
|
|
|
+ status = platform_device_register(ohci_device);
|
|
|
+ if (status)
|
|
|
+ pr_debug("can't register OHCI device, %d\n", status);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef CONFIG_USB_OTG
|
|
|
+ if (config->otg) {
|
|
|
+ struct platform_device *otg_device = config->otg_device;
|
|
|
+ int status;
|
|
|
+
|
|
|
+ syscon &= ~OTG_IDLE_EN;
|
|
|
+ otg_device->dev.platform_data = config;
|
|
|
+ status = platform_device_register(otg_device);
|
|
|
+ if (status)
|
|
|
+ pr_debug("can't register OTG device, %d\n", status);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1));
|
|
|
+ omap_writel(syscon, OTG_SYSCON_1);
|
|
|
+}
|
|
|
+
|
|
|
+#else
|
|
|
+void omap_otg_init(struct omap_usb_config *config) {}
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef CONFIG_USB_GADGET_OMAP
|
|
|
+
|
|
|
+static struct resource udc_resources[] = {
|
|
|
+ /* order is significant! */
|
|
|
+ { /* registers */
|
|
|
+ .start = UDC_BASE,
|
|
|
+ .end = UDC_BASE + 0xff,
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
+ }, { /* general IRQ */
|
|
|
+ .start = INT_USB_IRQ_GEN,
|
|
|
+ .flags = IORESOURCE_IRQ,
|
|
|
+ }, { /* PIO IRQ */
|