Merge branch 'master' of git://www.denx.de/git/u-boot-avr32
diff --git a/board/atmel/atngw100/atngw100.c b/board/atmel/atngw100/atngw100.c
index 375f0e7..f2c3e79 100644
--- a/board/atmel/atngw100/atngw100.c
+++ b/board/atmel/atngw100/atngw100.c
@@ -60,6 +60,9 @@
 #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 @@
 	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 3da35d4..56ba2f9 100644
--- a/cpu/at32ap/at32ap700x/gpio.c
+++ b/cpu/at32ap/at32ap700x/gpio.c
@@ -149,24 +149,27 @@
 #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 @@
 	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 9ba0b8e..f64004b 100644
--- a/cpu/at32ap/pio.c
+++ b/cpu/at32ap/pio.c
@@ -58,3 +58,59 @@
 	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 ef20cea..8c922c7 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 @@
 
 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 3fc9975..7ac51b5 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