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 450db304936f..8507dd02fe90 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c | |||
| @@ -26,6 +26,101 @@ | |||
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | /* -------------------------------------------------------------------- | 28 | /* -------------------------------------------------------------------- |
| 29 | * USB HS Device (Gadget) | ||
| 30 | * -------------------------------------------------------------------- */ | ||
| 31 | |||
| 32 | #if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE) | ||
| 33 | |||
| 34 | static struct resource usba_udc_resources[] = { | ||
| 35 | [0] = { | ||
| 36 | .start = AT91SAM9RL_UDPHS_FIFO, | ||
| 37 | .end = AT91SAM9RL_UDPHS_FIFO + SZ_512K - 1, | ||
| 38 | .flags = IORESOURCE_MEM, | ||
| 39 | }, | ||
| 40 | [1] = { | ||
| 41 | .start = AT91SAM9RL_BASE_UDPHS, | ||
| 42 | .end = AT91SAM9RL_BASE_UDPHS + SZ_1K - 1, | ||
| 43 | .flags = IORESOURCE_MEM, | ||
| 44 | }, | ||
| 45 | [2] = { | ||
| 46 | .start = AT91SAM9RL_ID_UDPHS, | ||
| 47 | .end = AT91SAM9RL_ID_UDPHS, | ||
| 48 | .flags = IORESOURCE_IRQ, | ||
| 49 | }, | ||
| 50 | }; | ||
| 51 | |||
| 52 | #define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ | ||
| 53 | [idx] = { \ | ||
| 54 | .name = nam, \ | ||
| 55 | .index = idx, \ | ||
| 56 | .fifo_size = maxpkt, \ | ||
| 57 | .nr_banks = maxbk, \ | ||
| 58 | .can_dma = dma, \ | ||
| 59 | .can_isoc = isoc, \ | ||
| 60 | } | ||
| 61 | |||
| 62 | static struct usba_ep_data usba_udc_ep[] __initdata = { | ||
| 63 | EP("ep0", 0, 64, 1, 0, 0), | ||
| 64 | EP("ep1", 1, 1024, 2, 1, 1), | ||
| 65 | EP("ep2", 2, 1024, 2, 1, 1), | ||
| 66 | EP("ep3", 3, 1024, 3, 1, 0), | ||
| 67 | EP("ep4", 4, 1024, 3, 1, 0), | ||
| 68 | EP("ep5", 5, 1024, 3, 1, 1), | ||
| 69 | EP("ep6", 6, 1024, 3, 1, 1), | ||
| 70 | }; | ||
| 71 | |||
| 72 | #undef EP | ||
| 73 | |||
| 74 | /* | ||
| 75 | * pdata doesn't have room for any endpoints, so we need to | ||
| 76 | * append room for the ones we need right after it. | ||
| 77 | */ | ||
| 78 | static struct { | ||
| 79 | struct usba_platform_data pdata; | ||
| 80 | struct usba_ep_data ep[7]; | ||
| 81 | } usba_udc_data; | ||
| 82 | |||
| 83 | static struct platform_device at91_usba_udc_device = { | ||
| 84 | .name = "atmel_usba_udc", | ||
| 85 | .id = -1, | ||
| 86 | .dev = { | ||
| 87 | .platform_data = &usba_udc_data.pdata, | ||
| 88 | }, | ||
| 89 | .resource = usba_udc_resources, | ||
| 90 | .num_resources = ARRAY_SIZE(usba_udc_resources), | ||
| 91 | }; | ||
| 92 | |||
| 93 | void __init at91_add_device_usba(struct usba_platform_data *data) | ||
| 94 | { | ||
| 95 | /* | ||
| 96 | * Invalid pins are 0 on AT91, but the usba driver is shared | ||
| 97 | * with AVR32, which use negative values instead. Once/if | ||
| 98 | * gpio_is_valid() is ported to AT91, revisit this code. | ||
| 99 | */ | ||
| 100 | usba_udc_data.pdata.vbus_pin = -EINVAL; | ||
| 101 | usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); | ||
| 102 | memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));; | ||
| 103 | |||
| 104 | if (data && data->vbus_pin > 0) { | ||
| 105 | at91_set_gpio_input(data->vbus_pin, 0); | ||
| 106 | at91_set_deglitch(data->vbus_pin, 1); | ||
| 107 | usba_udc_data.pdata.vbus_pin = data->vbus_pin; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* Pullup pin is handled internally by USB device peripheral */ | ||
| 111 | |||
| 112 | /* Clocks */ | ||
| 113 | at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk"); | ||
| 114 | at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk"); | ||
| 115 | |||
| 116 | platform_device_register(&at91_usba_udc_device); | ||
| 117 | } | ||
| 118 | #else | ||
| 119 | void __init at91_add_device_usba(struct usba_platform_data *data) {} | ||
| 120 | #endif | ||
| 121 | |||
| 122 | |||
| 123 | /* -------------------------------------------------------------------- | ||
| 29 | * MMC / SD | 124 | * MMC / SD |
| 30 | * -------------------------------------------------------------------- */ | 125 | * -------------------------------------------------------------------- */ |
| 31 | 126 | ||
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index ffc0597aee8d..b6a70fc735c3 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) | |||
| 56 | 56 | ||
| 57 | 57 | ||
| 58 | /* | 58 | /* |
| 59 | * USB HS Device port | ||
| 60 | */ | ||
| 61 | static struct usba_platform_data __initdata ek_usba_udc_data = { | ||
| 62 | .vbus_pin = AT91_PIN_PA8, | ||
| 63 | }; | ||
| 64 | |||
| 65 | |||
| 66 | /* | ||
| 59 | * MCI (SD/MMC) | 67 | * MCI (SD/MMC) |
| 60 | */ | 68 | */ |
| 61 | static struct at91_mmc_data __initdata ek_mmc_data = { | 69 | static struct at91_mmc_data __initdata ek_mmc_data = { |
| @@ -175,6 +183,8 @@ static void __init ek_board_init(void) | |||
| 175 | { | 183 | { |
| 176 | /* Serial */ | 184 | /* Serial */ |
| 177 | at91_add_device_serial(); | 185 | at91_add_device_serial(); |
| 186 | /* USB HS */ | ||
| 187 | at91_add_device_usba(&ek_usba_udc_data); | ||
| 178 | /* I2C */ | 188 | /* I2C */ |
| 179 | at91_add_device_i2c(NULL, 0); | 189 | at91_add_device_i2c(NULL, 0); |
| 180 | /* NAND */ | 190 | /* NAND */ |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index b87772cd3d32..e8ce8f0f3eda 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) | |||
| 391 | seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); | 391 | seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); |
| 392 | seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); | 392 | seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); |
| 393 | seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); | 393 | seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); |
| 394 | seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); | 394 | if (!cpu_is_at91sam9rl()) |
| 395 | if (cpu_is_at91cap9()) | 395 | seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); |
| 396 | if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) | ||
| 396 | seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR)); | 397 | seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR)); |
| 397 | seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); | 398 | seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); |
| 398 | seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); | 399 | 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) | |||
| 610 | /* | 611 | /* |
| 611 | * USB HS clock init | 612 | * USB HS clock init |
| 612 | */ | 613 | */ |
| 613 | if (cpu_is_at91cap9()) { | 614 | if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) { |
| 614 | /* | 615 | /* |
| 615 | * multiplier is hard-wired to 40 | 616 | * multiplier is hard-wired to 40 |
| 616 | * (obtain the USB High Speed 480 MHz when input is 12 MHz) | 617 | * (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) | |||
| 635 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) | 636 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) |
| 636 | list_add_tail(&standard_pmc_clocks[i]->node, &clocks); | 637 | list_add_tail(&standard_pmc_clocks[i]->node, &clocks); |
| 637 | 638 | ||
| 638 | if (cpu_is_at91cap9()) | 639 | if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) |
| 639 | list_add_tail(&utmi_clk.node, &clocks); | 640 | list_add_tail(&utmi_clk.node, &clocks); |
| 640 | 641 | ||
| 641 | /* MCK and CPU clock are "always on" */ | 642 | /* MCK and CPU clock are "always on" */ |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 6e784d2db423..3565d4352826 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -118,10 +118,10 @@ config USB_AMD5536UDC | |||
| 118 | config USB_GADGET_ATMEL_USBA | 118 | config USB_GADGET_ATMEL_USBA |
| 119 | boolean "Atmel USBA" | 119 | boolean "Atmel USBA" |
| 120 | select USB_GADGET_DUALSPEED | 120 | select USB_GADGET_DUALSPEED |
| 121 | depends on AVR32 || ARCH_AT91CAP9 | 121 | depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL |
| 122 | help | 122 | help |
| 123 | USBA is the integrated high-speed USB Device controller on | 123 | USBA is the integrated high-speed USB Device controller on |
| 124 | the AT32AP700x and AT91CAP9 processors from Atmel. | 124 | the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. |
| 125 | 125 | ||
| 126 | config USB_ATMEL_USBA | 126 | config USB_ATMEL_USBA |
| 127 | tristate | 127 | tristate |
diff --git a/include/asm-arm/arch-at91/at91sam9rl.h b/include/asm-arm/arch-at91/at91sam9rl.h index 16d2832f6c0a..622e56f81d42 100644 --- a/include/asm-arm/arch-at91/at91sam9rl.h +++ b/include/asm-arm/arch-at91/at91sam9rl.h | |||
| @@ -110,6 +110,6 @@ | |||
| 110 | #define AT91SAM9RL_ROM_SIZE (2 * SZ_16K) /* Internal ROM size (32Kb) */ | 110 | #define AT91SAM9RL_ROM_SIZE (2 * SZ_16K) /* Internal ROM size (32Kb) */ |
| 111 | 111 | ||
| 112 | #define AT91SAM9RL_LCDC_BASE 0x00500000 /* LCD Controller */ | 112 | #define AT91SAM9RL_LCDC_BASE 0x00500000 /* LCD Controller */ |
| 113 | #define AT91SAM9RL_UDPHS_BASE 0x00600000 /* USB Device HS controller */ | 113 | #define AT91SAM9RL_UDPHS_FIFO 0x00600000 /* USB Device HS controller */ |
| 114 | 114 | ||
| 115 | #endif | 115 | #endif |
