diff options
author | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2007-02-16 07:56:11 -0500 |
---|---|---|
committer | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2007-02-16 08:01:40 -0500 |
commit | 41d8ca452f523b9245704c7dd8ef290fa7b78e6b (patch) | |
tree | 41d84a6d1a1f20e7e74893eb76bf9a2c4de5c709 | |
parent | 23cebe2287474720c2eb0673581056cfb285a69f (diff) |
[AVR32] Use per-controller spi_board_info structures
Set up one spi_board_info array per controller and pass this to
at32_add_device_spi so that it can set up any GPIO pins for chip
selects based on this information.
Extracted from a patch by David Brownell and adapted slightly.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
-rw-r--r-- | arch/avr32/boards/atstk1000/atstk1002.c | 9 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/at32ap7000.c | 55 | ||||
-rw-r--r-- | include/asm-avr32/arch-at32ap/board.h | 4 |
3 files changed, 44 insertions, 24 deletions
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index d47e39f0e971..5974768a59e5 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c | |||
@@ -8,7 +8,6 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/device.h> | ||
12 | #include <linux/etherdevice.h> | 11 | #include <linux/etherdevice.h> |
13 | #include <linux/init.h> | 12 | #include <linux/init.h> |
14 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
@@ -36,12 +35,11 @@ static struct eth_addr __initdata hw_addr[2]; | |||
36 | static struct eth_platform_data __initdata eth_data[2]; | 35 | static struct eth_platform_data __initdata eth_data[2]; |
37 | extern struct lcdc_platform_data atstk1000_fb0_data; | 36 | extern struct lcdc_platform_data atstk1000_fb0_data; |
38 | 37 | ||
39 | static struct spi_board_info spi_board_info[] __initdata = { | 38 | static struct spi_board_info spi0_board_info[] __initdata = { |
40 | { | 39 | { |
40 | /* QVGA display */ | ||
41 | .modalias = "ltv350qv", | 41 | .modalias = "ltv350qv", |
42 | .controller_data = (void *)GPIO_PIN_PA(4), | ||
43 | .max_speed_hz = 16000000, | 42 | .max_speed_hz = 16000000, |
44 | .bus_num = 0, | ||
45 | .chip_select = 1, | 43 | .chip_select = 1, |
46 | }, | 44 | }, |
47 | }; | 45 | }; |
@@ -149,8 +147,7 @@ static int __init atstk1002_init(void) | |||
149 | 147 | ||
150 | set_hw_addr(at32_add_device_eth(0, ð_data[0])); | 148 | set_hw_addr(at32_add_device_eth(0, ð_data[0])); |
151 | 149 | ||
152 | spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); | 150 | at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); |
153 | at32_add_device_spi(0); | ||
154 | at32_add_device_lcdc(0, &atstk1000_fb0_data); | 151 | at32_add_device_lcdc(0, &atstk1000_fb0_data); |
155 | 152 | ||
156 | return 0; | 153 | return 0; |
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index a5037aa102fb..bc235507c5c7 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/clk.h> | 8 | #include <linux/clk.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | #include <linux/spi/spi.h> | ||
11 | 12 | ||
12 | #include <asm/io.h> | 13 | #include <asm/io.h> |
13 | 14 | ||
@@ -751,8 +752,41 @@ static struct resource atmel_spi1_resource[] = { | |||
751 | DEFINE_DEV(atmel_spi, 1); | 752 | DEFINE_DEV(atmel_spi, 1); |
752 | DEV_CLK(spi_clk, atmel_spi1, pba, 1); | 753 | DEV_CLK(spi_clk, atmel_spi1, pba, 1); |
753 | 754 | ||
754 | struct platform_device *__init at32_add_device_spi(unsigned int id) | 755 | static void |
756 | at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, | ||
757 | unsigned int n, const u8 *pins) | ||
755 | { | 758 | { |
759 | unsigned int pin, mode; | ||
760 | |||
761 | for (; n; n--, b++) { | ||
762 | b->bus_num = bus_num; | ||
763 | if (b->chip_select >= 4) | ||
764 | continue; | ||
765 | pin = (unsigned)b->controller_data; | ||
766 | if (!pin) { | ||
767 | pin = pins[b->chip_select]; | ||
768 | b->controller_data = (void *)pin; | ||
769 | } | ||
770 | mode = AT32_GPIOF_OUTPUT; | ||
771 | if (!(b->mode & SPI_CS_HIGH)) | ||
772 | mode |= AT32_GPIOF_HIGH; | ||
773 | at32_select_gpio(pin, mode); | ||
774 | } | ||
775 | } | ||
776 | |||
777 | struct platform_device *__init | ||
778 | at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) | ||
779 | { | ||
780 | /* | ||
781 | * Manage the chipselects as GPIOs, normally using the same pins | ||
782 | * the SPI controller expects; but boards can use other pins. | ||
783 | */ | ||
784 | static u8 __initdata spi0_pins[] = | ||
785 | { GPIO_PIN_PA(3), GPIO_PIN_PA(4), | ||
786 | GPIO_PIN_PA(5), GPIO_PIN_PA(20), }; | ||
787 | static u8 __initdata spi1_pins[] = | ||
788 | { GPIO_PIN_PB(2), GPIO_PIN_PB(3), | ||
789 | GPIO_PIN_PB(4), GPIO_PIN_PA(27), }; | ||
756 | struct platform_device *pdev; | 790 | struct platform_device *pdev; |
757 | 791 | ||
758 | switch (id) { | 792 | switch (id) { |
@@ -761,14 +795,7 @@ struct platform_device *__init at32_add_device_spi(unsigned int id) | |||
761 | select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ | 795 | select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ |
762 | select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ | 796 | select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ |
763 | select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ | 797 | select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ |
764 | 798 | at32_spi_setup_slaves(0, b, n, spi0_pins); | |
765 | /* NPCS[2:0] */ | ||
766 | at32_select_gpio(GPIO_PIN_PA(3), | ||
767 | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); | ||
768 | at32_select_gpio(GPIO_PIN_PA(4), | ||
769 | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); | ||
770 | at32_select_gpio(GPIO_PIN_PA(5), | ||
771 | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); | ||
772 | break; | 799 | break; |
773 | 800 | ||
774 | case 1: | 801 | case 1: |
@@ -776,20 +803,14 @@ struct platform_device *__init at32_add_device_spi(unsigned int id) | |||
776 | select_peripheral(PB(0), PERIPH_B, 0); /* MISO */ | 803 | select_peripheral(PB(0), PERIPH_B, 0); /* MISO */ |
777 | select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */ | 804 | select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */ |
778 | select_peripheral(PB(5), PERIPH_B, 0); /* SCK */ | 805 | select_peripheral(PB(5), PERIPH_B, 0); /* SCK */ |
779 | 806 | at32_spi_setup_slaves(1, b, n, spi1_pins); | |
780 | /* NPCS[2:0] */ | ||
781 | at32_select_gpio(GPIO_PIN_PB(2), | ||
782 | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); | ||
783 | at32_select_gpio(GPIO_PIN_PB(3), | ||
784 | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); | ||
785 | at32_select_gpio(GPIO_PIN_PB(4), | ||
786 | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); | ||
787 | break; | 807 | break; |
788 | 808 | ||
789 | default: | 809 | default: |
790 | return NULL; | 810 | return NULL; |
791 | } | 811 | } |
792 | 812 | ||
813 | spi_register_board_info(b, n); | ||
793 | platform_device_register(pdev); | 814 | platform_device_register(pdev); |
794 | return pdev; | 815 | return pdev; |
795 | } | 816 | } |
diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h index b120ee030c86..1a7b07d436ff 100644 --- a/include/asm-avr32/arch-at32ap/board.h +++ b/include/asm-avr32/arch-at32ap/board.h | |||
@@ -26,7 +26,9 @@ struct eth_platform_data { | |||
26 | struct platform_device * | 26 | struct platform_device * |
27 | at32_add_device_eth(unsigned int id, struct eth_platform_data *data); | 27 | at32_add_device_eth(unsigned int id, struct eth_platform_data *data); |
28 | 28 | ||
29 | struct platform_device *at32_add_device_spi(unsigned int id); | 29 | struct spi_board_info; |
30 | struct platform_device * | ||
31 | at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n); | ||
30 | 32 | ||
31 | struct lcdc_platform_data { | 33 | struct lcdc_platform_data { |
32 | unsigned long fbmem_start; | 34 | unsigned long fbmem_start; |