diff options
Diffstat (limited to 'arch/avr32/mach-at32ap/at32ap700x.c')
| -rw-r--r-- | arch/avr32/mach-at32ap/at32ap700x.c | 227 |
1 files changed, 152 insertions, 75 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index 3fbfd1e32a9..a1f4d1e91b5 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -12,9 +12,12 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> +#include <linux/slab.h> #include <linux/gpio.h> #include <linux/spi/spi.h> #include <linux/usb/atmel_usba_udc.h> + +#include <mach/atmel-mci.h> #include <linux/atmel-mci.h> #include <asm/io.h> @@ -26,6 +29,9 @@ #include <mach/portmux.h> #include <mach/sram.h> +#include <sound/atmel-abdac.h> +#include <sound/atmel-ac97c.h> + #include <video/atmel_lcdc.h> #include "clock.h" @@ -57,26 +63,26 @@ * don't ... tc, smc, pio, rtc, watchdog, pwm, ps2, and more. */ #define DEFINE_DEV(_name, _id) \ -static u64 _name##_id##_dma_mask = DMA_32BIT_MASK; \ +static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32); \ static struct platform_device _name##_id##_device = { \ .name = #_name, \ .id = _id, \ .dev = { \ .dma_mask = &_name##_id##_dma_mask, \ - .coherent_dma_mask = DMA_32BIT_MASK, \ + .coherent_dma_mask = DMA_BIT_MASK(32), \ }, \ .resource = _name##_id##_resource, \ .num_resources = ARRAY_SIZE(_name##_id##_resource), \ } #define DEFINE_DEV_DATA(_name, _id) \ -static u64 _name##_id##_dma_mask = DMA_32BIT_MASK; \ +static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32); \ static struct platform_device _name##_id##_device = { \ .name = #_name, \ .id = _id, \ .dev = { \ .dma_mask = &_name##_id##_dma_mask, \ .platform_data = &_name##_id##_data, \ - .coherent_dma_mask = DMA_32BIT_MASK, \ + .coherent_dma_mask = DMA_BIT_MASK(32), \ }, \ .resource = _name##_id##_resource, \ .num_resources = ARRAY_SIZE(_name##_id##_resource), \ @@ -599,6 +605,9 @@ static void __init genclk_init_parent(struct clk *clk) static struct dw_dma_platform_data dw_dmac0_data = { .nr_channels = 3, + .block_size = 4095U, + .nr_masters = 2, + .data_width = { 2, 2, 0, 0 }, }; static struct resource dw_dmac0_resource[] = { @@ -963,56 +972,69 @@ static struct resource atmel_usart3_resource[] = { DEFINE_DEV_DATA(atmel_usart, 3); DEV_CLK(usart, atmel_usart3, pba, 6); -static inline void configure_usart0_pins(void) +static inline void configure_usart0_pins(int flags) { u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */ + if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 6); + if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 7); + if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 10); select_peripheral(PIOA, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP); } -static inline void configure_usart1_pins(void) +static inline void configure_usart1_pins(int flags) { u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */ + if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 19); + if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 20); + if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 16); select_peripheral(PIOA, pin_mask, PERIPH_A, AT32_GPIOF_PULLUP); } -static inline void configure_usart2_pins(void) +static inline void configure_usart2_pins(int flags) { u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */ + if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 30); + if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 29); + if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 28); select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP); } -static inline void configure_usart3_pins(void) +static inline void configure_usart3_pins(int flags) { u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */ + if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 16); + if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 15); + if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 19); select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP); } static struct platform_device *__initdata at32_usarts[4]; -void __init at32_map_usart(unsigned int hw_id, unsigned int line) +void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags) { struct platform_device *pdev; + struct atmel_uart_data *pdata; switch (hw_id) { case 0: pdev = &atmel_usart0_device; - configure_usart0_pins(); + configure_usart0_pins(flags); break; case 1: pdev = &atmel_usart1_device; - configure_usart1_pins(); + configure_usart1_pins(flags); break; case 2: pdev = &atmel_usart2_device; - configure_usart2_pins(); + configure_usart2_pins(flags); break; case 3: pdev = &atmel_usart3_device; - configure_usart3_pins(); + configure_usart3_pins(flags); break; default: return; @@ -1025,6 +1047,8 @@ void __init at32_map_usart(unsigned int hw_id, unsigned int line) } pdev->id = line; + pdata = pdev->dev.platform_data; + pdata->num = line; at32_usarts[line] = pdev; } @@ -1034,11 +1058,11 @@ struct platform_device *__init at32_add_device_usart(unsigned int id) return at32_usarts[id]; } -struct platform_device *atmel_default_console_device; - void __init at32_setup_serial_console(unsigned int usart_id) { +#ifdef CONFIG_SERIAL_ATMEL atmel_default_console_device = at32_usarts[usart_id]; +#endif } /* -------------------------------------------------------------------- @@ -1046,7 +1070,7 @@ void __init at32_setup_serial_console(unsigned int usart_id) * -------------------------------------------------------------------- */ #ifdef CONFIG_CPU_AT32AP7000 -static struct eth_platform_data macb0_data; +static struct macb_platform_data macb0_data; static struct resource macb0_resource[] = { PBMEM(0xfff01800), IRQ(25), @@ -1055,7 +1079,7 @@ DEFINE_DEV_DATA(macb, 0); DEV_CLK(hclk, macb0, hsb, 8); DEV_CLK(pclk, macb0, pbb, 6); -static struct eth_platform_data macb1_data; +static struct macb_platform_data macb1_data; static struct resource macb1_resource[] = { PBMEM(0xfff01c00), IRQ(26), @@ -1065,7 +1089,7 @@ DEV_CLK(hclk, macb1, hsb, 9); DEV_CLK(pclk, macb1, pbb, 7); struct platform_device *__init -at32_add_device_eth(unsigned int id, struct eth_platform_data *data) +at32_add_device_eth(unsigned int id, struct macb_platform_data *data) { struct platform_device *pdev; u32 pin_mask; @@ -1142,7 +1166,7 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) return NULL; } - memcpy(pdev->dev.platform_data, data, sizeof(struct eth_platform_data)); + memcpy(pdev->dev.platform_data, data, sizeof(struct macb_platform_data)); platform_device_register(pdev); return pdev; @@ -1166,19 +1190,32 @@ static struct resource atmel_spi1_resource[] = { DEFINE_DEV(atmel_spi, 1); DEV_CLK(spi_clk, atmel_spi1, pba, 1); -static void __init -at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, - unsigned int n, const u8 *pins) +void __init +at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, unsigned int n) { + /* + * Manage the chipselects as GPIOs, normally using the same pins + * the SPI controller expects; but boards can use other pins. + */ + static u8 __initdata spi_pins[][4] = { + { GPIO_PIN_PA(3), GPIO_PIN_PA(4), + GPIO_PIN_PA(5), GPIO_PIN_PA(20) }, + { GPIO_PIN_PB(2), GPIO_PIN_PB(3), + GPIO_PIN_PB(4), GPIO_PIN_PA(27) }, + }; unsigned int pin, mode; + /* There are only 2 SPI controllers */ + if (bus_num > 1) + return; + for (; n; n--, b++) { b->bus_num = bus_num; if (b->chip_select >= 4) continue; pin = (unsigned)b->controller_data; if (!pin) { - pin = pins[b->chip_select]; + pin = spi_pins[bus_num][b->chip_select]; b->controller_data = (void *)pin; } mode = AT32_GPIOF_OUTPUT; @@ -1191,16 +1228,6 @@ at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, struct platform_device *__init at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) { - /* - * Manage the chipselects as GPIOs, normally using the same pins - * the SPI controller expects; but boards can use other pins. - */ - static u8 __initdata spi0_pins[] = - { GPIO_PIN_PA(3), GPIO_PIN_PA(4), - GPIO_PIN_PA(5), GPIO_PIN_PA(20), }; - static u8 __initdata spi1_pins[] = - { GPIO_PIN_PB(2), GPIO_PIN_PB(3), - GPIO_PIN_PB(4), GPIO_PIN_PA(27), }; struct platform_device *pdev; u32 pin_mask; @@ -1213,7 +1240,7 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) select_peripheral(PIOA, (1 << 0), PERIPH_A, AT32_GPIOF_PULLUP); select_peripheral(PIOA, pin_mask, PERIPH_A, 0); - at32_spi_setup_slaves(0, b, n, spi0_pins); + at32_spi_setup_slaves(0, b, n); break; case 1: @@ -1224,7 +1251,7 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) select_peripheral(PIOB, (1 << 0), PERIPH_B, AT32_GPIOF_PULLUP); select_peripheral(PIOB, pin_mask, PERIPH_B, 0); - at32_spi_setup_slaves(1, b, n, spi1_pins); + at32_spi_setup_slaves(1, b, n); break; default: @@ -1305,7 +1332,7 @@ struct platform_device *__init at32_add_device_mci(unsigned int id, struct mci_platform_data *data) { struct platform_device *pdev; - struct dw_dma_slave *dws = &data->dma_slave; + struct mci_dma_data *slave; u32 pioa_mask; u32 piob_mask; @@ -1324,16 +1351,21 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) ARRAY_SIZE(atmel_mci0_resource))) goto fail; - dws->dma_dev = &dw_dmac0_device.dev; - dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT; - dws->cfg_hi = (DWC_CFGH_SRC_PER(0) + slave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL); + if (!slave) + goto fail; + + slave->sdata.dma_dev = &dw_dmac0_device.dev; + slave->sdata.cfg_hi = (DWC_CFGH_SRC_PER(0) | DWC_CFGH_DST_PER(1)); - dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL + slave->sdata.cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + data->dma_slave = slave; + if (platform_device_add_data(pdev, data, sizeof(struct mci_platform_data))) - goto fail; + goto fail_free; /* CLK line is common to both slots */ pioa_mask = 1 << 10; @@ -1357,7 +1389,7 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) /* Slot is unused */ break; default: - goto fail; + goto fail_free; } select_peripheral(PIOA, pioa_mask, PERIPH_A, 0); @@ -1384,7 +1416,7 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) break; default: if (!data->slot[0].bus_width) - goto fail; + goto fail_free; data->slot[1].bus_width = 0; break; @@ -1395,7 +1427,10 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) platform_device_add(pdev); return pdev; +fail_free: + kfree(slave); fail: + data->dma_slave = NULL; platform_device_put(pdev); return NULL; } @@ -1404,7 +1439,7 @@ fail: * LCDC * -------------------------------------------------------------------- */ #if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002) -static struct atmel_lcdfb_info atmel_lcdfb0_data; +static struct atmel_lcdfb_pdata atmel_lcdfb0_data; static struct resource atmel_lcdfb0_resource[] = { { .start = 0xff000000, @@ -1420,7 +1455,7 @@ static struct resource atmel_lcdfb0_resource[] = { }, }; DEFINE_DEV_DATA(atmel_lcdfb, 0); -DEV_CLK(hck1, atmel_lcdfb0, hsb, 7); +DEV_CLK(hclk, atmel_lcdfb0, hsb, 7); static struct clk atmel_lcdfb0_pixclk = { .name = "lcdc_clk", .dev = &atmel_lcdfb0_device.dev, @@ -1432,12 +1467,12 @@ static struct clk atmel_lcdfb0_pixclk = { }; struct platform_device *__init -at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, +at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_pdata *data, unsigned long fbmem_start, unsigned long fbmem_len, u64 pin_mask) { struct platform_device *pdev; - struct atmel_lcdfb_info *info; + struct atmel_lcdfb_pdata *info; struct fb_monspecs *monspecs; struct fb_videomode *modedb; unsigned int modedb_size; @@ -1494,9 +1529,11 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, } info = pdev->dev.platform_data; - memcpy(info, data, sizeof(struct atmel_lcdfb_info)); + memcpy(info, data, sizeof(struct atmel_lcdfb_pdata)); info->default_monspecs = monspecs; + pdev->name = "at32ap-lcdfb"; + platform_device_register(pdev); return pdev; @@ -1741,10 +1778,13 @@ at32_add_device_usba(unsigned int id, struct usba_platform_data *data) ARRAY_SIZE(usba0_resource))) goto out_free_pdev; - if (data) + if (data) { usba_data.pdata.vbus_pin = data->vbus_pin; - else + usba_data.pdata.vbus_pin_inverted = data->vbus_pin_inverted; + } else { usba_data.pdata.vbus_pin = -EINVAL; + usba_data.pdata.vbus_pin_inverted = -EINVAL; + } data = &usba_data.pdata; data->num_ep = ARRAY_SIZE(at32_usba_ep); @@ -1753,7 +1793,7 @@ at32_add_device_usba(unsigned int id, struct usba_platform_data *data) if (platform_device_add_data(pdev, data, sizeof(usba_data))) goto out_free_pdev; - if (data->vbus_pin >= 0) + if (gpio_is_valid(data->vbus_pin)) at32_select_gpio(data->vbus_pin, 0); usba0_pclk.dev = &pdev->dev; @@ -1943,6 +1983,9 @@ at32_add_device_nand(unsigned int id, struct atmel_nand_data *data) ARRAY_SIZE(smc_cs3_resource))) goto fail; + /* For at32ap7000, we use the reset workaround for nand driver */ + data->need_reset_workaround = true; + if (platform_device_add_data(pdev, data, sizeof(struct atmel_nand_data))) goto fail; @@ -1980,11 +2023,14 @@ static struct clk atmel_ac97c0_pclk = { }; struct platform_device *__init -at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data) +at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, + unsigned int flags) { - struct platform_device *pdev; - struct ac97c_platform_data _data; - u32 pin_mask; + struct platform_device *pdev; + struct dw_dma_slave *rx_dws; + struct dw_dma_slave *tx_dws; + struct ac97c_platform_data _data; + u32 pin_mask; if (id != 0) return NULL; @@ -1995,37 +2041,54 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data) if (platform_device_add_resources(pdev, atmel_ac97c0_resource, ARRAY_SIZE(atmel_ac97c0_resource))) - goto fail; + goto out_free_resources; if (!data) { data = &_data; memset(data, 0, sizeof(struct ac97c_platform_data)); - data->reset_pin = GPIO_PIN_NONE; + data->reset_pin = -ENODEV; } - data->dma_rx_periph_id = 3; - data->dma_tx_periph_id = 4; - data->dma_controller_id = 0; + rx_dws = &data->rx_dws; + tx_dws = &data->tx_dws; + + /* Check if DMA slave interface for capture should be configured. */ + if (flags & AC97C_CAPTURE) { + rx_dws->dma_dev = &dw_dmac0_device.dev; + rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3); + rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + rx_dws->src_master = 0; + rx_dws->dst_master = 1; + } + + /* Check if DMA slave interface for playback should be configured. */ + if (flags & AC97C_PLAYBACK) { + tx_dws->dma_dev = &dw_dmac0_device.dev; + tx_dws->cfg_hi = DWC_CFGH_DST_PER(4); + tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + tx_dws->src_master = 0; + tx_dws->dst_master = 1; + } if (platform_device_add_data(pdev, data, sizeof(struct ac97c_platform_data))) - goto fail; + goto out_free_resources; - pin_mask = (1 << 20) | (1 << 21); /* SDO & SYNC */ - pin_mask |= (1 << 22) | (1 << 23); /* SCLK & SDI */ + /* SDO | SYNC | SCLK | SDI */ + pin_mask = (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23); select_peripheral(PIOB, pin_mask, PERIPH_B, 0); - /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ - if (data->reset_pin != GPIO_PIN_NONE) - at32_select_gpio(data->reset_pin, 0); + if (gpio_is_valid(data->reset_pin)) + at32_select_gpio(data->reset_pin, AT32_GPIOF_OUTPUT + | AT32_GPIOF_HIGH); atmel_ac97c0_pclk.dev = &pdev->dev; platform_device_add(pdev); return pdev; -fail: +out_free_resources: platform_device_put(pdev); return NULL; } @@ -2053,21 +2116,35 @@ static struct clk abdac0_sample_clk = { .index = 6, }; -struct platform_device *__init at32_add_device_abdac(unsigned int id) +struct platform_device *__init +at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data) { - struct platform_device *pdev; - u32 pin_mask; + struct platform_device *pdev; + struct dw_dma_slave *dws; + u32 pin_mask; - if (id != 0) + if (id != 0 || !data) return NULL; - pdev = platform_device_alloc("abdac", id); + pdev = platform_device_alloc("atmel_abdac", id); if (!pdev) return NULL; if (platform_device_add_resources(pdev, abdac0_resource, ARRAY_SIZE(abdac0_resource))) - goto err_add_resources; + goto out_free_resources; + + dws = &data->dws; + + dws->dma_dev = &dw_dmac0_device.dev; + dws->cfg_hi = DWC_CFGH_DST_PER(2); + dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); + dws->src_master = 0; + dws->dst_master = 1; + + if (platform_device_add_data(pdev, data, + sizeof(struct atmel_abdac_pdata))) + goto out_free_resources; pin_mask = (1 << 20) | (1 << 22); /* DATA1 & DATAN1 */ pin_mask |= (1 << 21) | (1 << 23); /* DATA0 & DATAN0 */ @@ -2080,7 +2157,7 @@ struct platform_device *__init at32_add_device_abdac(unsigned int id) platform_device_add(pdev); return pdev; -err_add_resources: +out_free_resources: platform_device_put(pdev); return NULL; } @@ -2176,7 +2253,7 @@ static __initdata struct clk *init_clocks[] = { &atmel_twi0_pclk, &atmel_mci0_pclk, #if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002) - &atmel_lcdfb0_hck1, + &atmel_lcdfb0_hclk, &atmel_lcdfb0_pixclk, #endif &ssc0_pclk, |
