ARM: 5726/1: at91/USB: at91sam9g45 series USB host integration
authorNicolas Ferre <nicolas.ferre@atmel.com>
Fri, 25 Sep 2009 11:11:32 +0000 (12:11 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 25 Oct 2009 16:00:33 +0000 (16:00 +0000)
This is the at91 specific part of USB host integration. The EHCI high speed
controller has a companion OHCI controller to manage USB full and low speed.
They are sharing the same IRQ line and vbus pin.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Andrew Victor <linux@maxim.org.za>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/board-sam9m10g45ek.c
arch/arm/mach-at91/include/mach/board.h

index d581cff80c4c673468e4d6dec2608d847f176c1b..003f4f91fa526f0df4e431092ffb51869619e3eb 100644 (file)
@@ -130,6 +130,62 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
 #endif
 
 
+/* --------------------------------------------------------------------
+ *  USB Host HS (EHCI)
+ *  Needs an OHCI host for low and full speed management
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_ehci_data;
+
+static struct resource usbh_ehci_resources[] = {
+       [0] = {
+               .start  = AT91SAM9G45_EHCI_BASE,
+               .end    = AT91SAM9G45_EHCI_BASE + SZ_1M - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91SAM9G45_ID_UHPHS,
+               .end    = AT91SAM9G45_ID_UHPHS,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at91_usbh_ehci_device = {
+       .name           = "atmel-ehci",
+       .id             = -1,
+       .dev            = {
+                               .dma_mask               = &ehci_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &usbh_ehci_data,
+       },
+       .resource       = usbh_ehci_resources,
+       .num_resources  = ARRAY_SIZE(usbh_ehci_resources),
+};
+
+void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data)
+{
+       int i;
+
+       if (!data)
+               return;
+
+       /* Enable VBus control for UHP ports */
+       for (i = 0; i < data->ports; i++) {
+               if (data->vbus_pin[i])
+                       at91_set_gpio_output(data->vbus_pin[i], 0);
+       }
+
+       usbh_ehci_data = *data;
+       at91_clock_associate("uhphs_clk", &at91_usbh_ehci_device.dev, "ehci_clk");
+       platform_device_register(&at91_usbh_ehci_device);
+}
+#else
+void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {}
+#endif
+
+
 /* --------------------------------------------------------------------
  *  USB HS Device (Gadget)
  * -------------------------------------------------------------------- */
index 64c3843f323df7e230ea5d1dfd080622998ea9e8..1cf4d868107826a735be0c5f858255ad3d5d6e30 100644 (file)
@@ -366,6 +366,7 @@ static void __init ek_board_init(void)
        at91_add_device_serial();
        /* USB HS Host */
        at91_add_device_usbh_ohci(&ek_usbh_hs_data);
+       at91_add_device_usbh_ehci(&ek_usbh_hs_data);
        /* USB HS Device */
        at91_add_device_usba(&ek_usba_udc_data);
        /* SPI */
index 2f4fcedc02ba6a55638f5b44c0e5234f8acd887b..2295d80dd893e2ab1b370f7ad44b1e8f64c5805f 100644 (file)
@@ -98,6 +98,7 @@ struct at91_usbh_data {
 };
 extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
 extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
+extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data);
 
  /* NAND / SmartMedia */
 struct atmel_nand_data {