[ARM] 4934/1: AT91CAP9 UDPHS driver: board and cpu integration.
authorStelian Pop <stelian@popies.net>
Sat, 5 Apr 2008 20:15:25 +0000 (21:15 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 2 Jun 2008 14:08:09 +0000 (15:08 +0100)
This is patch 2 of 2 adding support for the USB High Speed Device Port
on the AT91CAP9 system on chip. The AT91CAP9 uses the same UDPHS IP
as the AVR32 and the AT91SAM9RL.

This patch declares the UDPHS ressources in the at91cap9 (cpu and
adk board) files, wires up the atmel_usba_udc driver to them,
and activates the driver in the defconfig.

Signed-off-by: Stelian Pop <stelian@popies.net>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Acked-by: Andrew Victor <linux@maxim.org.za>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/configs/at91cap9adk_defconfig
arch/arm/mach-at91/at91cap9_devices.c
arch/arm/mach-at91/board-cap9adk.c
include/asm-arm/arch-at91/at91cap9.h
include/asm-arm/arch-at91/at91cap9_matrix.h

index e32e736..39ca662 100644 (file)
@@ -907,7 +907,32 @@ CONFIG_USB_MON=y
 #
 # USB Gadget Support
 #
-# CONFIG_USB_GADGET is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
index be52674..747b9de 100644 (file)
@@ -83,6 +83,105 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
 #endif
 
 
+/* --------------------------------------------------------------------
+ *  USB HS Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+
+static struct resource usba_udc_resources[] = {
+       [0] = {
+               .start  = AT91CAP9_UDPHS_FIFO,
+               .end    = AT91CAP9_UDPHS_FIFO + SZ_512K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91CAP9_BASE_UDPHS,
+               .end    = AT91CAP9_BASE_UDPHS + SZ_1K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start  = AT91CAP9_ID_UDPHS,
+               .end    = AT91CAP9_ID_UDPHS,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc)                 \
+       [idx] = {                                               \
+               .name           = nam,                          \
+               .index          = idx,                          \
+               .fifo_size      = maxpkt,                       \
+               .nr_banks       = maxbk,                        \
+               .can_dma        = dma,                          \
+               .can_isoc       = isoc,                         \
+       }
+
+static struct usba_ep_data usba_udc_ep[] = {
+       EP("ep0", 0,   64, 1, 0, 0),
+       EP("ep1", 1, 1024, 3, 1, 1),
+       EP("ep2", 2, 1024, 3, 1, 1),
+       EP("ep3", 3, 1024, 2, 1, 1),
+       EP("ep4", 4, 1024, 2, 1, 1),
+       EP("ep5", 5, 1024, 2, 1, 0),
+       EP("ep6", 6, 1024, 2, 1, 0),
+       EP("ep7", 7, 1024, 2, 0, 0),
+};
+
+#undef EP
+
+/*
+ * pdata doesn't have room for any endpoints, so we need to
+ * append room for the ones we need right after it.
+ */
+static struct {
+       struct usba_platform_data pdata;
+       struct usba_ep_data ep[8];
+} usba_udc_data;
+
+static struct platform_device at91_usba_udc_device = {
+       .name           = "atmel_usba_udc",
+       .id             = -1,
+       .dev            = {
+                               .platform_data  = &usba_udc_data.pdata,
+       },
+       .resource       = usba_udc_resources,
+       .num_resources  = ARRAY_SIZE(usba_udc_resources),
+};
+
+void __init at91_add_device_usba(struct usba_platform_data *data)
+{
+       at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
+                                         AT91_MATRIX_UDPHS_BYPASS_LOCK);
+
+       /*
+        * Invalid pins are 0 on AT91, but the usba driver is shared
+        * with AVR32, which use negative values instead. Once/if
+        * gpio_is_valid() is ported to AT91, revisit this code.
+        */
+       usba_udc_data.pdata.vbus_pin = -EINVAL;
+       usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
+       memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
+
+       if (data && data->vbus_pin > 0) {
+               at91_set_gpio_input(data->vbus_pin, 0);
+               at91_set_deglitch(data->vbus_pin, 1);
+               usba_udc_data.pdata.vbus_pin = data->vbus_pin;
+       }
+
+       /* Pullup pin is handled internally by USB device peripheral */
+
+       /* Clocks */
+       at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
+       at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
+
+       platform_device_register(&at91_usba_udc_device);
+}
+#else
+void __init at91_add_device_usba(struct usba_platform_data *data) {}
+#endif
+
+
 /* --------------------------------------------------------------------
  *  Ethernet
  * -------------------------------------------------------------------- */
index e5512d1..8a2a958 100644 (file)
@@ -78,6 +78,12 @@ static struct at91_usbh_data __initdata cap9adk_usbh_data = {
        .ports          = 2,
 };
 
+/*
+ * USB HS Device port
+ */
+static struct usba_platform_data __initdata cap9adk_usba_udc_data = {
+       .vbus_pin       = AT91_PIN_PB31,
+};
 
 /*
  * ADS7846 Touchscreen
@@ -326,6 +332,9 @@ static void __init cap9adk_board_init(void)
        /* USB Host */
        set_irq_type(AT91CAP9_ID_UHP, IRQT_HIGH);
        at91_add_device_usbh(&cap9adk_usbh_data);
+       /* USB HS */
+       set_irq_type(AT91CAP9_ID_UDPHS, IRQT_HIGH);
+       at91_add_device_usba(&cap9adk_usba_udc_data);
        /* SPI */
        at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
        /* Touchscreen */
index bac83ad..6f14d90 100644 (file)
 #define AT91CAP9_ROM_SIZE      (32 * SZ_1K)    /* Internal ROM size (32Kb) */
 
 #define AT91CAP9_LCDC_BASE     0x00500000      /* LCD Controller */
-#define AT91CAP9_UDPHS_BASE    0x00600000      /* USB High Speed Device Port */
+#define AT91CAP9_UDPHS_FIFO    0x00600000      /* USB High Speed Device Port */
 #define AT91CAP9_UHP_BASE      0x00700000      /* USB Host controller */
 
 #define CONFIG_DRAM_BASE       AT91_CHIPSELECT_6
index a641686..ddbd487 100644 (file)
 #define AT91_MPBS0_SFR         (AT91_MATRIX + 0x114)   /* MPBlock Slave 0 Special Function Register */
 #define AT91_MPBS1_SFR         (AT91_MATRIX + 0x11C)   /* MPBlock Slave 1 Special Function Register */
 
+#define AT91_MATRIX_UDPHS      (AT91_MATRIX + 0x118)   /* USBHS Special Function Register [AT91CAP9 only] */
+#define                AT91_MATRIX_SELECT_UDPHS        (0 << 31)       /* select High Speed UDP */
+#define                AT91_MATRIX_SELECT_UDP          (1 << 31)       /* select standard UDP */
+#define                AT91_MATRIX_UDPHS_BYPASS_LOCK   (1 << 30)       /* bypass lock bit */
+
 #define AT91_MATRIX_EBICSA     (AT91_MATRIX + 0x120)   /* EBI Chip Select Assignment Register */
 #define                AT91_MATRIX_EBI_CS1A            (1 << 1)        /* Chip Select 1 Assignment */
 #define                        AT91_MATRIX_EBI_CS1A_SMC                (0 << 1)