summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/atmel/atngw100/atngw100.c25
-rw-r--r--cpu/at32ap/at32ap700x/gpio.c56
-rw-r--r--cpu/at32ap/pio.c56
-rw-r--r--include/asm-avr32/arch-at32ap700x/gpio.h8
-rw-r--r--include/configs/atngw100.h6
5 files changed, 129 insertions, 22 deletions
diff --git a/board/atmel/atngw100/atngw100.c b/board/atmel/atngw100/atngw100.c
index 375f0e7e1..f2c3e7979 100644
--- a/board/atmel/atngw100/atngw100.c
+++ b/board/atmel/atngw100/atngw100.c
@@ -60,6 +60,9 @@ int board_early_init_f(void)
#if defined(CONFIG_MMC)
gpio_enable_mmci();
#endif
+#if defined(CONFIG_ATMEL_SPI)
+ gpio_enable_spi0(1 << 0);
+#endif
return 0;
}
@@ -89,3 +92,25 @@ void board_init_info(void)
gd->bd->bi_phy_id[0] = 0x01;
gd->bd->bi_phy_id[1] = 0x03;
}
+
+/* SPI chip select control */
+#ifdef CONFIG_ATMEL_SPI
+#include <spi.h>
+
+#define ATNGW100_DATAFLASH_CS_PIN GPIO_PIN_PA3
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+ return bus == 0 && cs == 0;
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+ gpio_set_value(ATNGW100_DATAFLASH_CS_PIN, 0);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+ gpio_set_value(ATNGW100_DATAFLASH_CS_PIN, 1);
+}
+#endif /* CONFIG_ATMEL_SPI */
diff --git a/cpu/at32ap/at32ap700x/gpio.c b/cpu/at32ap/at32ap700x/gpio.c
index 3da35d4fe..56ba2f90c 100644
--- a/cpu/at32ap/at32ap700x/gpio.c
+++ b/cpu/at32ap/at32ap700x/gpio.c
@@ -149,24 +149,27 @@ void gpio_enable_mmci(void)
#ifdef AT32AP700x_CHIP_HAS_SPI
void gpio_enable_spi0(unsigned long cs_mask)
{
- u32 pa_mask = 0;
-
gpio_select_periph_A(GPIO_PIN_PA0, 0); /* MISO */
gpio_select_periph_A(GPIO_PIN_PA1, 0); /* MOSI */
gpio_select_periph_A(GPIO_PIN_PA2, 0); /* SCK */
- if (cs_mask & (1 << 0))
- pa_mask |= 1 << 3; /* NPCS0 */
- if (cs_mask & (1 << 1))
- pa_mask |= 1 << 4; /* NPCS1 */
- if (cs_mask & (1 << 2))
- pa_mask |= 1 << 5; /* NPCS2 */
- if (cs_mask & (1 << 3))
- pa_mask |= 1 << 20; /* NPCS3 */
-
- __raw_writel(pa_mask, PIOA_BASE + 0x00);
- __raw_writel(pa_mask, PIOA_BASE + 0x30);
- __raw_writel(pa_mask, PIOA_BASE + 0x10);
+ /* Set up NPCSx as GPIO outputs, initially high */
+ if (cs_mask & (1 << 0)) {
+ gpio_set_value(GPIO_PIN_PA3, 1);
+ gpio_select_pio(GPIO_PIN_PA3, GPIOF_OUTPUT);
+ }
+ if (cs_mask & (1 << 1)) {
+ gpio_set_value(GPIO_PIN_PA4, 1);
+ gpio_select_pio(GPIO_PIN_PA4, GPIOF_OUTPUT);
+ }
+ if (cs_mask & (1 << 2)) {
+ gpio_set_value(GPIO_PIN_PA5, 1);
+ gpio_select_pio(GPIO_PIN_PA5, GPIOF_OUTPUT);
+ }
+ if (cs_mask & (1 << 3)) {
+ gpio_set_value(GPIO_PIN_PA20, 1);
+ gpio_select_pio(GPIO_PIN_PA20, GPIOF_OUTPUT);
+ }
}
void gpio_enable_spi1(unsigned long cs_mask)
@@ -175,13 +178,22 @@ void gpio_enable_spi1(unsigned long cs_mask)
gpio_select_periph_B(GPIO_PIN_PB1, 0); /* MOSI */
gpio_select_periph_B(GPIO_PIN_PB5, 0); /* SCK */
- if (cs_mask & (1 << 0))
- gpio_select_periph_B(GPIO_PIN_PB2, 0); /* NPCS0 */
- if (cs_mask & (1 << 1))
- gpio_select_periph_B(GPIO_PIN_PB3, 0); /* NPCS1 */
- if (cs_mask & (1 << 2))
- gpio_select_periph_B(GPIO_PIN_PB4, 0); /* NPCS2 */
- if (cs_mask & (1 << 3))
- gpio_select_periph_A(GPIO_PIN_PA27, 0); /* NPCS3 */
+ /* Set up NPCSx as GPIO outputs, initially high */
+ if (cs_mask & (1 << 0)) {
+ gpio_set_value(GPIO_PIN_PB2, 1);
+ gpio_select_pio(GPIO_PIN_PB2, GPIOF_OUTPUT);
+ }
+ if (cs_mask & (1 << 1)) {
+ gpio_set_value(GPIO_PIN_PB3, 1);
+ gpio_select_pio(GPIO_PIN_PB3, GPIOF_OUTPUT);
+ }
+ if (cs_mask & (1 << 2)) {
+ gpio_set_value(GPIO_PIN_PB4, 1);
+ gpio_select_pio(GPIO_PIN_PB4, GPIOF_OUTPUT);
+ }
+ if (cs_mask & (1 << 3)) {
+ gpio_set_value(GPIO_PIN_PA27, 1);
+ gpio_select_pio(GPIO_PIN_PA27, GPIOF_OUTPUT);
+ }
}
#endif
diff --git a/cpu/at32ap/pio.c b/cpu/at32ap/pio.c
index 9ba0b8ea8..f64004b65 100644
--- a/cpu/at32ap/pio.c
+++ b/cpu/at32ap/pio.c
@@ -58,3 +58,59 @@ void gpio_select_periph_B(unsigned int pin, int use_pullup)
else
pio2_writel(base, PUDR, mask);
}
+
+void gpio_select_pio(unsigned int pin, unsigned long gpiof_flags)
+{
+ void *base = gpio_pin_to_addr(pin);
+ uint32_t mask = 1 << (pin & 0x1f);
+
+ if (!base)
+ panic("Invalid GPIO pin %u\n", pin);
+
+ if (gpiof_flags & GPIOF_OUTPUT) {
+ if (gpiof_flags & GPIOF_MULTIDRV)
+ pio2_writel(base, MDER, mask);
+ else
+ pio2_writel(base, MDDR, mask);
+ pio2_writel(base, PUDR, mask);
+ pio2_writel(base, OER, mask);
+ } else {
+ if (gpiof_flags & GPIOF_PULLUP)
+ pio2_writel(base, PUER, mask);
+ else
+ pio2_writel(base, PUDR, mask);
+ if (gpiof_flags & GPIOF_DEGLITCH)
+ pio2_writel(base, IFER, mask);
+ else
+ pio2_writel(base, IFDR, mask);
+ pio2_writel(base, ODR, mask);
+ }
+
+ pio2_writel(base, PER, mask);
+}
+
+void gpio_set_value(unsigned int pin, int value)
+{
+ void *base = gpio_pin_to_addr(pin);
+ uint32_t mask = 1 << (pin & 0x1f);
+
+ if (!base)
+ panic("Invalid GPIO pin %u\n", pin);
+
+ if (value)
+ pio2_writel(base, SODR, mask);
+ else
+ pio2_writel(base, CODR, mask);
+}
+
+int gpio_get_value(unsigned int pin)
+{
+ void *base = gpio_pin_to_addr(pin);
+ int value;
+
+ if (!base)
+ panic("Invalid GPIO pin %u\n", pin);
+
+ value = pio2_readl(base, PDSR);
+ return (value >> (pin & 0x1f)) & 1;
+}
diff --git a/include/asm-avr32/arch-at32ap700x/gpio.h b/include/asm-avr32/arch-at32ap700x/gpio.h
index ef20ceaab..8c922c7c6 100644
--- a/include/asm-avr32/arch-at32ap700x/gpio.h
+++ b/include/asm-avr32/arch-at32ap700x/gpio.h
@@ -180,6 +180,11 @@
#define GPIO_PIN_PE25 (GPIO_PIOE_BASE + 25)
#define GPIO_PIN_PE26 (GPIO_PIOE_BASE + 26)
+#define GPIOF_PULLUP 0x00000001 /* (not-OUT) Enable pull-up */
+#define GPIOF_OUTPUT 0x00000002 /* (OUT) Enable output driver */
+#define GPIOF_DEGLITCH 0x00000004 /* (IN) Filter glitches */
+#define GPIOF_MULTIDRV 0x00000008 /* Enable multidriver option */
+
static inline void *gpio_pin_to_addr(unsigned int pin)
{
switch (pin >> 5) {
@@ -200,6 +205,9 @@ static inline void *gpio_pin_to_addr(unsigned int pin)
void gpio_select_periph_A(unsigned int pin, int use_pullup);
void gpio_select_periph_B(unsigned int pin, int use_pullup);
+void gpio_select_pio(unsigned int pin, unsigned long gpiof_flags);
+void gpio_set_value(unsigned int pin, int value);
+int gpio_get_value(unsigned int pin);
void gpio_enable_ebi(void);
diff --git a/include/configs/atngw100.h b/include/configs/atngw100.h
index 3fc997563..7ac51b543 100644
--- a/include/configs/atngw100.h
+++ b/include/configs/atngw100.h
@@ -114,6 +114,8 @@
#define CONFIG_CMD_FAT
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_MMC
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SPI
#undef CONFIG_CMD_AUTOSCRIPT
#undef CONFIG_CMD_FPGA
@@ -126,6 +128,10 @@
#define CFG_NR_PIOS 5
#define CFG_HSDRAMC 1
#define CONFIG_MMC 1
+#define CONFIG_ATMEL_SPI 1
+
+#define CONFIG_SPI_FLASH 1
+#define CONFIG_SPI_FLASH_ATMEL 1
#define CFG_DCACHE_LINESZ 32
#define CFG_ICACHE_LINESZ 32