From 48021bd93ca339fcafe9b043d05f5d3a58be7c0a Mon Sep 17 00:00:00 2001 From: Kristoffer Nyborg Gregertsen Date: Thu, 16 Aug 2007 13:45:00 +0200 Subject: [AVR32] Platform code for pata_at32 This patch adds platform code for PATA devices on the AP7000. [hskinnemoen@atmel.com: board code left out for now since stk1000 doesn't support IDE out of the box] Signed-off-by: Kristoffer Nyborg Gregertsen Signed-off-by: Haavard Skinnemoen --- include/asm-avr32/arch-at32ap/board.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/asm-avr32') diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h index 7dbd603c38c..c18160f29cb 100644 --- a/include/asm-avr32/arch-at32ap/board.h +++ b/include/asm-avr32/arch-at32ap/board.h @@ -44,6 +44,13 @@ struct usba_platform_data { struct platform_device * at32_add_device_usba(unsigned int id, struct usba_platform_data *data); +struct ide_platform_data { + u8 cs; +}; +struct platform_device * +at32_add_device_ide(unsigned int id, unsigned int extint, + struct ide_platform_data *data); + /* depending on what's hooked up, not all SSC pins will be used */ #define ATMEL_SSC_TK 0x01 #define ATMEL_SSC_TF 0x02 -- cgit v1.2.3-70-g09d2 From 2042c1c4e7a5e3b69ff3c3c5db6bf6416abd8b24 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 22 Oct 2007 17:42:35 +0200 Subject: [AVR32] Implement more at32_add_device_foo() functions Implement functions for adding platform devices for TWI, MCI, AC97C and ABDAC. They may need to be modified to cope with platform data, etc. when the corresponding drivers are ready to be merged, but such changes are much less likely to conflict than adding support for a whole new type of device. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/at32ap7000.c | 208 ++++++++++++++++++++++++++++++++++ include/asm-avr32/arch-at32ap/board.h | 5 + 2 files changed, 213 insertions(+) (limited to 'include/asm-avr32') diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 30aedc9473f..d152504f12b 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -556,6 +556,17 @@ static struct clk pico_clk = { .users = 1, }; +static struct resource dmaca0_resource[] = { + { + .start = 0xff200000, + .end = 0xff20ffff, + .flags = IORESOURCE_MEM, + }, + IRQ(2), +}; +DEFINE_DEV(dmaca, 0); +DEV_CLK(hclk, dmaca0, hsb, 10); + /* -------------------------------------------------------------------- * HMATRIX * -------------------------------------------------------------------- */ @@ -655,6 +666,7 @@ void __init at32_add_system_devices(void) platform_device_register(&at32_eic0_device); platform_device_register(&smc0_device); platform_device_register(&pdc_device); + platform_device_register(&dmaca0_device); platform_device_register(&at32_systc0_device); @@ -959,6 +971,96 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) return pdev; } +/* -------------------------------------------------------------------- + * TWI + * -------------------------------------------------------------------- */ +static struct resource atmel_twi0_resource[] __initdata = { + PBMEM(0xffe00800), + IRQ(5), +}; +static struct clk atmel_twi0_pclk = { + .name = "twi_pclk", + .parent = &pba_clk, + .mode = pba_clk_mode, + .get_rate = pba_clk_get_rate, + .index = 2, +}; + +struct platform_device *__init at32_add_device_twi(unsigned int id) +{ + struct platform_device *pdev; + + if (id != 0) + return NULL; + + pdev = platform_device_alloc("atmel_twi", id); + if (!pdev) + return NULL; + + if (platform_device_add_resources(pdev, atmel_twi0_resource, + ARRAY_SIZE(atmel_twi0_resource))) + goto err_add_resources; + + select_peripheral(PA(6), PERIPH_A, 0); /* SDA */ + select_peripheral(PA(7), PERIPH_A, 0); /* SDL */ + + atmel_twi0_pclk.dev = &pdev->dev; + + platform_device_add(pdev); + return pdev; + +err_add_resources: + platform_device_put(pdev); + return NULL; +} + +/* -------------------------------------------------------------------- + * MMC + * -------------------------------------------------------------------- */ +static struct resource atmel_mci0_resource[] __initdata = { + PBMEM(0xfff02400), + IRQ(28), +}; +static struct clk atmel_mci0_pclk = { + .name = "mci_clk", + .parent = &pbb_clk, + .mode = pbb_clk_mode, + .get_rate = pbb_clk_get_rate, + .index = 9, +}; + +struct platform_device *__init at32_add_device_mci(unsigned int id) +{ + struct platform_device *pdev; + + if (id != 0) + return NULL; + + pdev = platform_device_alloc("atmel_mci", id); + if (!pdev) + return NULL; + + if (platform_device_add_resources(pdev, atmel_mci0_resource, + ARRAY_SIZE(atmel_mci0_resource))) + goto err_add_resources; + + select_peripheral(PA(10), PERIPH_A, 0); /* CLK */ + select_peripheral(PA(11), PERIPH_A, 0); /* CMD */ + select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */ + select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */ + select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */ + select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */ + + atmel_mci0_pclk.dev = &pdev->dev; + + platform_device_add(pdev); + return pdev; + +err_add_resources: + platform_device_put(pdev); + return NULL; +} + /* -------------------------------------------------------------------- * LCDC * -------------------------------------------------------------------- */ @@ -1292,6 +1394,105 @@ at32_add_device_ide(unsigned int id, unsigned int extint, return pdev; } +/* -------------------------------------------------------------------- + * AC97C + * -------------------------------------------------------------------- */ +static struct resource atmel_ac97c0_resource[] __initdata = { + PBMEM(0xfff02800), + IRQ(29), +}; +static struct clk atmel_ac97c0_pclk = { + .name = "pclk", + .parent = &pbb_clk, + .mode = pbb_clk_mode, + .get_rate = pbb_clk_get_rate, + .index = 10, +}; + +struct platform_device *__init at32_add_device_ac97c(unsigned int id) +{ + struct platform_device *pdev; + + if (id != 0) + return NULL; + + pdev = platform_device_alloc("atmel_ac97c", id); + if (!pdev) + return NULL; + + if (platform_device_add_resources(pdev, atmel_ac97c0_resource, + ARRAY_SIZE(atmel_ac97c0_resource))) + goto err_add_resources; + + select_peripheral(PB(20), PERIPH_B, 0); /* SYNC */ + select_peripheral(PB(21), PERIPH_B, 0); /* SDO */ + select_peripheral(PB(22), PERIPH_B, 0); /* SDI */ + select_peripheral(PB(23), PERIPH_B, 0); /* SCLK */ + + atmel_ac97c0_pclk.dev = &pdev->dev; + + platform_device_add(pdev); + return pdev; + +err_add_resources: + platform_device_put(pdev); + return NULL; +} + +/* -------------------------------------------------------------------- + * ABDAC + * -------------------------------------------------------------------- */ +static struct resource abdac0_resource[] __initdata = { + PBMEM(0xfff02000), + IRQ(27), +}; +static struct clk abdac0_pclk = { + .name = "pclk", + .parent = &pbb_clk, + .mode = pbb_clk_mode, + .get_rate = pbb_clk_get_rate, + .index = 8, +}; +static struct clk abdac0_sample_clk = { + .name = "sample_clk", + .mode = genclk_mode, + .get_rate = genclk_get_rate, + .set_rate = genclk_set_rate, + .set_parent = genclk_set_parent, + .index = 6, +}; + +struct platform_device *__init at32_add_device_abdac(unsigned int id) +{ + struct platform_device *pdev; + + if (id != 0) + return NULL; + + pdev = platform_device_alloc("abdac", id); + if (!pdev) + return NULL; + + if (platform_device_add_resources(pdev, abdac0_resource, + ARRAY_SIZE(abdac0_resource))) + goto err_add_resources; + + select_peripheral(PB(20), PERIPH_A, 0); /* DATA1 */ + select_peripheral(PB(21), PERIPH_A, 0); /* DATA0 */ + select_peripheral(PB(22), PERIPH_A, 0); /* DATAN1 */ + select_peripheral(PB(23), PERIPH_A, 0); /* DATAN0 */ + + abdac0_pclk.dev = &pdev->dev; + abdac0_sample_clk.dev = &pdev->dev; + + platform_device_add(pdev); + return pdev; + +err_add_resources: + platform_device_put(pdev); + return NULL; +} + /* -------------------------------------------------------------------- * GCLK * -------------------------------------------------------------------- */ @@ -1355,6 +1556,7 @@ struct clk *at32_clock_list[] = { &smc0_mck, &pdc_hclk, &pdc_pclk, + &dmaca0_hclk, &pico_clk, &pio0_mck, &pio1_mck, @@ -1372,6 +1574,8 @@ struct clk *at32_clock_list[] = { &macb1_pclk, &atmel_spi0_spi_clk, &atmel_spi1_spi_clk, + &atmel_twi0_pclk, + &atmel_mci0_pclk, &atmel_lcdfb0_hck1, &atmel_lcdfb0_pixclk, &ssc0_pclk, @@ -1379,6 +1583,9 @@ struct clk *at32_clock_list[] = { &ssc2_pclk, &usba0_hclk, &usba0_pclk, + &atmel_ac97c0_pclk, + &abdac0_pclk, + &abdac0_sample_clk, &gclk0, &gclk1, &gclk2, @@ -1420,6 +1627,7 @@ void __init at32_clock_init(void) genclk_init_parent(&gclk3); genclk_init_parent(&gclk4); genclk_init_parent(&atmel_lcdfb0_pixclk); + genclk_init_parent(&abdac0_sample_clk); /* * Turn on all clocks that have at least one user already, and diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h index c18160f29cb..946378a1b6b 100644 --- a/include/asm-avr32/arch-at32ap/board.h +++ b/include/asm-avr32/arch-at32ap/board.h @@ -65,4 +65,9 @@ at32_add_device_ide(unsigned int id, unsigned int extint, struct platform_device * at32_add_device_ssc(unsigned int id, unsigned int flags); +struct platform_device *at32_add_device_twi(unsigned int id); +struct platform_device *at32_add_device_mci(unsigned int id); +struct platform_device *at32_add_device_ac97c(unsigned int id); +struct platform_device *at32_add_device_abdac(unsigned int id); + #endif /* __ASM_ARCH_BOARD_H */ -- cgit v1.2.3-70-g09d2 From eaf5f925a31973e2fdc50c785665b90ff444eceb Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 22 Oct 2007 18:32:14 +0200 Subject: [AVR32] Implement at32_add_device_cf() Implement at32_add_device_cf() which will add a platform_device for the at32_cf driver (not merged yet). Separate out most of the at32_add_device_ide() code and use it to implement at32_add_device_cf() as well. This changes the API in the following ways: * The board code must initialize data->cs to the chipselect ID to use before calling any of these functions. * The board code must use GPIO_PIN_NONE to indicate unused CF pins. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/at32ap7000.c | 133 ++++++++++++++++++++++++++-------- include/asm-avr32/arch-at32ap/board.h | 11 +++ 2 files changed, 113 insertions(+), 31 deletions(-) (limited to 'include/asm-avr32') diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index d152504f12b..a9d9ec081e3 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -1330,10 +1330,9 @@ out_free_pdev: } /* -------------------------------------------------------------------- - * IDE + * IDE / CompactFlash * -------------------------------------------------------------------- */ -static struct ide_platform_data at32_ide0_data; -static struct resource at32_ide0_resource[] = { +static struct resource at32_smc_cs4_resource[] __initdata = { { .start = 0x04000000, .end = 0x07ffffff, @@ -1341,45 +1340,63 @@ static struct resource at32_ide0_resource[] = { }, IRQ(~0UL), /* Magic IRQ will be overridden */ }; -DEFINE_DEV_DATA(at32_ide, 0); +static struct resource at32_smc_cs5_resource[] __initdata = { + { + .start = 0x20000000, + .end = 0x23ffffff, + .flags = IORESOURCE_MEM, + }, + IRQ(~0UL), /* Magic IRQ will be overridden */ +}; -struct platform_device *__init -at32_add_device_ide(unsigned int id, unsigned int extint, - struct ide_platform_data *data) +static int __init at32_init_ide_or_cf(struct platform_device *pdev, + unsigned int cs, unsigned int extint) { - struct platform_device *pdev; + static unsigned int extint_pin_map[4] __initdata = { + GPIO_PIN_PB(25), + GPIO_PIN_PB(26), + GPIO_PIN_PB(27), + GPIO_PIN_PB(28), + }; + static bool common_pins_initialized __initdata = false; unsigned int extint_pin; + int ret; - switch (extint) { - case 0: - extint_pin = GPIO_PIN_PB(25); - break; - case 1: - extint_pin = GPIO_PIN_PB(26); - break; - case 2: - extint_pin = GPIO_PIN_PB(27); + if (extint >= ARRAY_SIZE(extint_pin_map)) + return -EINVAL; + extint_pin = extint_pin_map[extint]; + + switch (cs) { + case 4: + ret = platform_device_add_resources(pdev, + at32_smc_cs4_resource, + ARRAY_SIZE(at32_smc_cs4_resource)); + if (ret) + return ret; + + select_peripheral(PE(21), PERIPH_A, 0); /* NCS4 -> OE_N */ + set_ebi_sfr_bits(HMATRIX_BIT(CS4A)); break; - case 3: - extint_pin = GPIO_PIN_PB(28); + case 5: + ret = platform_device_add_resources(pdev, + at32_smc_cs5_resource, + ARRAY_SIZE(at32_smc_cs5_resource)); + if (ret) + return ret; + + select_peripheral(PE(22), PERIPH_A, 0); /* NCS5 -> OE_N */ + set_ebi_sfr_bits(HMATRIX_BIT(CS5A)); break; default: - return NULL; + return -EINVAL; } - switch (id) { - case 0: - pdev = &at32_ide0_device; + if (!common_pins_initialized) { select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1 -> CS0_N */ select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2 -> CS1_N */ - select_peripheral(PE(21), PERIPH_A, 0); /* NCS4 -> OE_N */ select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW -> DIR */ select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT <- IORDY */ - set_ebi_sfr_bits(HMATRIX_BIT(CS4A)); - data->cs = 4; - break; - default: - return NULL; + common_pins_initialized = true; } at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); @@ -1387,11 +1404,65 @@ at32_add_device_ide(unsigned int id, unsigned int extint, pdev->resource[1].start = EIM_IRQ_BASE + extint; pdev->resource[1].end = pdev->resource[1].start; - memcpy(pdev->dev.platform_data, data, sizeof(struct ide_platform_data)); + return 0; +} - platform_device_register(pdev); +struct platform_device *__init +at32_add_device_ide(unsigned int id, unsigned int extint, + struct ide_platform_data *data) +{ + struct platform_device *pdev; + + pdev = platform_device_alloc("at32_ide", id); + if (!pdev) + goto fail; + + if (platform_device_add_data(pdev, data, + sizeof(struct ide_platform_data))) + goto fail; + + if (at32_init_ide_or_cf(pdev, data->cs, extint)) + goto fail; + + platform_device_add(pdev); + return pdev; + +fail: + platform_device_put(pdev); + return NULL; +} + +struct platform_device *__init +at32_add_device_cf(unsigned int id, unsigned int extint, + struct cf_platform_data *data) +{ + struct platform_device *pdev; + + pdev = platform_device_alloc("at32_cf", id); + if (!pdev) + goto fail; + if (platform_device_add_data(pdev, data, + sizeof(struct cf_platform_data))) + goto fail; + + if (at32_init_ide_or_cf(pdev, data->cs, extint)) + goto fail; + + if (data->detect_pin != GPIO_PIN_NONE) + at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH); + if (data->reset_pin != GPIO_PIN_NONE) + at32_select_gpio(data->reset_pin, 0); + if (data->vcc_pin != GPIO_PIN_NONE) + at32_select_gpio(data->vcc_pin, 0); + /* READY is used as extint, so we can't select it as gpio */ + + platform_device_add(pdev); return pdev; + +fail: + platform_device_put(pdev); + return NULL; } /* -------------------------------------------------------------------- diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h index 946378a1b6b..d6993a6b647 100644 --- a/include/asm-avr32/arch-at32ap/board.h +++ b/include/asm-avr32/arch-at32ap/board.h @@ -70,4 +70,15 @@ struct platform_device *at32_add_device_mci(unsigned int id); struct platform_device *at32_add_device_ac97c(unsigned int id); struct platform_device *at32_add_device_abdac(unsigned int id); +struct cf_platform_data { + int detect_pin; + int reset_pin; + int vcc_pin; + int ready_pin; + u8 cs; +}; +struct platform_device * +at32_add_device_cf(unsigned int id, unsigned int extint, + struct cf_platform_data *data); + #endif /* __ASM_ARCH_BOARD_H */ -- cgit v1.2.3-70-g09d2