diff options
-rw-r--r-- | arch/arm/mach-at91/at91sam9rl_devices.c | 95 | ||||
-rw-r--r-- | arch/arm/mach-at91/board-sam9rlek.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-at91/clock.c | 9 | ||||
-rw-r--r-- | drivers/usb/gadget/Kconfig | 4 | ||||
-rw-r--r-- | include/asm-arm/arch-at91/at91sam9rl.h | 2 |
5 files changed, 113 insertions, 7 deletions
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 450db304936..8507dd02fe9 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -26,6 +26,101 @@ /* -------------------------------------------------------------------- + * 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 = AT91SAM9RL_UDPHS_FIFO, + .end = AT91SAM9RL_UDPHS_FIFO + SZ_512K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9RL_BASE_UDPHS, + .end = AT91SAM9RL_BASE_UDPHS + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = AT91SAM9RL_ID_UDPHS, + .end = AT91SAM9RL_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[] __initdata = { + EP("ep0", 0, 64, 1, 0, 0), + EP("ep1", 1, 1024, 2, 1, 1), + EP("ep2", 2, 1024, 2, 1, 1), + EP("ep3", 3, 1024, 3, 1, 0), + EP("ep4", 4, 1024, 3, 1, 0), + EP("ep5", 5, 1024, 3, 1, 1), + EP("ep6", 6, 1024, 3, 1, 1), +}; + +#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[7]; +} 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) +{ + /* + * 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 + + +/* -------------------------------------------------------------------- * MMC / SD * -------------------------------------------------------------------- */ diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index ffc0597aee8..b6a70fc735c 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c @@ -56,6 +56,14 @@ static void __init ek_init_irq(void) /* + * USB HS Device port + */ +static struct usba_platform_data __initdata ek_usba_udc_data = { + .vbus_pin = AT91_PIN_PA8, +}; + + +/* * MCI (SD/MMC) */ static struct at91_mmc_data __initdata ek_mmc_data = { @@ -175,6 +183,8 @@ static void __init ek_board_init(void) { /* Serial */ at91_add_device_serial(); + /* USB HS */ + at91_add_device_usba(&ek_usba_udc_data); /* I2C */ at91_add_device_i2c(NULL, 0); /* NAND */ diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index b87772cd3d3..e8ce8f0f3ed 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -391,8 +391,9 @@ static int at91_clk_show(struct seq_file *s, void *unused) seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); - seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); - if (cpu_is_at91cap9()) + if (!cpu_is_at91sam9rl()) + seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); + if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR)); seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); @@ -610,7 +611,7 @@ int __init at91_clock_init(unsigned long main_clock) /* * USB HS clock init */ - if (cpu_is_at91cap9()) { + if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) { /* * multiplier is hard-wired to 40 * (obtain the USB High Speed 480 MHz when input is 12 MHz) @@ -635,7 +636,7 @@ int __init at91_clock_init(unsigned long main_clock) for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) list_add_tail(&standard_pmc_clocks[i]->node, &clocks); - if (cpu_is_at91cap9()) + if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) list_add_tail(&utmi_clk.node, &clocks); /* MCK and CPU clock are "always on" */ diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 6e784d2db42..3565d435282 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -118,10 +118,10 @@ config USB_AMD5536UDC config USB_GADGET_ATMEL_USBA boolean "Atmel USBA" select USB_GADGET_DUALSPEED - depends on AVR32 || ARCH_AT91CAP9 + depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL help USBA is the integrated high-speed USB Device controller on - the AT32AP700x and AT91CAP9 processors from Atmel. + the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. config USB_ATMEL_USBA tristate diff --git a/include/asm-arm/arch-at91/at91sam9rl.h b/include/asm-arm/arch-at91/at91sam9rl.h index 16d2832f6c0..622e56f81d4 100644 --- a/include/asm-arm/arch-at91/at91sam9rl.h +++ b/include/asm-arm/arch-at91/at91sam9rl.h @@ -110,6 +110,6 @@ #define AT91SAM9RL_ROM_SIZE (2 * SZ_16K) /* Internal ROM size (32Kb) */ #define AT91SAM9RL_LCDC_BASE 0x00500000 /* LCD Controller */ -#define AT91SAM9RL_UDPHS_BASE 0x00600000 /* USB Device HS controller */ +#define AT91SAM9RL_UDPHS_FIFO 0x00600000 /* USB Device HS controller */ #endif |