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 /arch/avr32/mach-at32ap | |
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>
Diffstat (limited to 'arch/avr32/mach-at32ap')
-rw-r--r-- | arch/avr32/mach-at32ap/at32ap7000.c | 55 |
1 files changed, 38 insertions, 17 deletions
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 | } |