[ARM] 4910/1: [AT91] AT73C213 audio on SAM9260-EK and SAM9261-EK boards

Add support for AT73C213 audio DAC on the Atmel SAM9260-EK and
SAM9261-EK boards.

Signed-off-by: Sedji Gaouaou <sedji.gaouaou@atmel.com>
Signed-off-by: Andrew Victor <linux@maxim.org.za>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index 4405536..40c3e95 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -25,6 +25,8 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
@@ -37,7 +39,6 @@
 
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
-#include <asm/arch/at91sam9_smc.h>
 
 #include "generic.h"
 
@@ -85,6 +86,35 @@
 
 
 /*
+ * Audio
+ */
+static struct at73c213_board_info at73c213_data = {
+	.ssc_id		= 0,
+	.shortname	= "AT91SAM9260-EK external DAC",
+};
+
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+static void __init at73c213_set_clk(struct at73c213_board_info *info)
+{
+	struct clk *pck0;
+	struct clk *plla;
+
+	pck0 = clk_get(NULL, "pck0");
+	plla = clk_get(NULL, "plla");
+
+	/* AT73C213 MCK Clock */
+	at91_set_B_periph(AT91_PIN_PC1, 0);	/* PCK0 */
+
+	clk_set_parent(pck0, plla);
+	clk_put(plla);
+
+	info->dac_clk = pck0;
+}
+#else
+static void __init at73c213_set_clk(struct at73c213_board_info *info) {}
+#endif
+
+/*
  * SPI devices.
  */
 static struct spi_board_info ek_spi_devices[] = {
@@ -110,6 +140,8 @@
 		.chip_select	= 0,
 		.max_speed_hz	= 10 * 1000 * 1000,
 		.bus_num	= 1,
+		.mode		= SPI_MODE_1,
+		.platform_data	= &at73c213_data,
 	},
 #endif
 };
@@ -190,6 +222,9 @@
 	at91_add_device_mmc(0, &ek_mmc_data);
 	/* I2C */
 	at91_add_device_i2c(NULL, 0);
+	/* SSC (to AT73C213) */
+	at73c213_set_clk(&at73c213_data);
+	at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
 }
 
 MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 3c73825..ce512d7 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -26,6 +26,8 @@
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
+#include <linux/spi/at73c213.h>
+#include <linux/clk.h>
 #include <linux/dm9000.h>
 #include <linux/fb.h>
 #include <linux/gpio_keys.h>
@@ -231,6 +233,35 @@
 #endif
 
 /*
+ * Audio
+ */
+static struct at73c213_board_info at73c213_data = {
+	.ssc_id		= 1,
+	.shortname	= "AT91SAM9261-EK external DAC",
+};
+
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+static void __init at73c213_set_clk(struct at73c213_board_info *info)
+{
+	struct clk *pck2;
+	struct clk *plla;
+
+	pck2 = clk_get(NULL, "pck2");
+	plla = clk_get(NULL, "plla");
+
+	/* AT73C213 MCK Clock */
+	at91_set_B_periph(AT91_PIN_PB31, 0);	/* PCK2 */
+
+	clk_set_parent(pck2, plla);
+	clk_put(plla);
+
+	info->dac_clk = pck2;
+}
+#else
+static void __init at73c213_set_clk(struct at73c213_board_info *info) {}
+#endif
+
+/*
  * SPI devices
  */
 static struct spi_board_info ek_spi_devices[] = {
@@ -248,6 +279,7 @@
 		.bus_num	= 0,
 		.platform_data	= &ads_info,
 		.irq		= AT91SAM9261_ID_IRQ0,
+		.controller_data = (void *) AT91_PIN_PA28,	/* CS pin */
 	},
 #endif
 #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
@@ -263,6 +295,9 @@
 		.chip_select	= 3,
 		.max_speed_hz	= 10 * 1000 * 1000,
 		.bus_num	= 0,
+		.mode		= SPI_MODE_1,
+		.platform_data	= &at73c213_data,
+		.controller_data = (void*) AT91_PIN_PA29,	/* default for CS3 is PA6, but it must be PA29 */
 	},
 #endif
 };
@@ -473,6 +508,9 @@
 	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
 	/* Touchscreen */
 	ek_add_device_ts();
+	/* SSC (to AT73C213) */
+	at73c213_set_clk(&at73c213_data);
+	at91_add_device_ssc(AT91SAM9261_ID_SSC1, ATMEL_SSC_TX);
 #else
 	/* MMC */
 	at91_add_device_mmc(0, &ek_mmc_data);