From 20bc8665923a23ae2bbbae22218725540b6ae5df Mon Sep 17 00:00:00 2001
From: Liam Girdwood <lrg@slimlogic.co.uk>
Date: Sun, 25 Jul 2010 19:53:51 +0100
Subject: [PATCH 15/60] ASoC: sdp4430: Add all ABE backend DAIs

commit 5494e250cf59b59c1ff9344b89e8c060c5d830d8 upstream

SDP4430 implements the following DAI links:

- SDP4430 Media: Frontend connecting MM_UL and MM_DL
  Supported backends are PDM_DL1, PDM_DL2, PDM_UL,
  BT_VX, MM_EXT, DMIC0, DMIC1 and DMIC2
- SDP4430 Media Capture: Frontend for MM_UL2
  Supported backends are PDM_UL, BT_VX, MM_EXT,
  DMIC0, DMIC1 and DMIC2
- SDP4430 Voice: Frontend connecting VX_UL and VX_DL
  Supports all media backends
- SDP4430 Tones Playback: Frontend for TONES_DL
  Supported backends are PDM_DL1, PDM_DL2, BT_VX and
  MM_EXT
- SDP4430 Vibra Playback: Frontend for VIB_DL
  Only supported backend is PDM_VIB
- SDP4430 MODEM: Frontend connecting MODEM with McBSP2
  Supported backends are the same as in media links
- SDP4430 Media LP: Frontend for MM_DL with ping-pong
  buffer. Supported backends are PDM_DL1, PDM_DL2,
  BT_VX and MM_EXT
- HDMI: Frontend for HDMI
- Legacy McBSP: Direct link between processor and
  MM_EXT (McBSP2)
- Legacy McPDM: Direct link between processor and
  PDM_DL1
- Legacy DMIC: Direct link between DMIC0 and processor

Change-Id: Ib3a8c844be5c4fa6f6b6a6371086f8e4a0e1fe7b
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Margarita Olaya Cabrera <magi.olaya@ti.com>
Signed-off-by: Jorge Eduardo Candelaria <jorge.candelaria@ti.com>
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
Signed-off-by: Chris Kelly <c-kelly@ti.com>
Integrated-by: Jingdong Lu <jingdong.lu@windriver.com>
---
 sound/soc/omap/Kconfig   |    5 +
 sound/soc/omap/sdp4430.c |  526 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 516 insertions(+), 15 deletions(-)

diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index e28ca02..0ee3104 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -103,8 +103,13 @@ config SND_OMAP_SOC_SDP3430
 config SND_OMAP_SOC_SDP4430
 	tristate "SoC Audio support for Texas Instruments SDP4430"
 	depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP
+	select SND_OMAP_SOC_ABE
 	select SND_OMAP_SOC_MCPDM
 	select SND_SOC_TWL6040
+	select SND_OMAP_SOC_MCBSP
+	select SND_SOC_DMIC
+	select SND_OMAP_SOC_DMIC
+	select SND_OMAP_SOC_ABE_DSP
 	help
 	  Say Y if you want to add support for SoC audio on Texas Instruments
 	  SDP4430.
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index 189e039..badb680 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -30,13 +30,20 @@
 #include <plat/hardware.h>
 #include <plat/mux.h>
 
-#include "mcpdm.h"
+#include "omap-mcpdm.h"
+#include "omap-abe.h"
 #include "omap-pcm.h"
+#include "omap-mcbsp.h"
+#include "omap-dmic.h"
 #include "../codecs/twl6040.h"
 
+#ifdef CONFIG_SND_OMAP_SOC_HDMI
+#include "omap-hdmi.h"
+#endif
+
 static int twl6040_power_mode;
 
-static int sdp4430_hw_params(struct snd_pcm_substream *substream,
+static int sdp4430_mcpdm_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -62,8 +69,82 @@ static int sdp4430_hw_params(struct snd_pcm_substream *substream,
 	return ret;
 }
 
-static struct snd_soc_ops sdp4430_ops = {
-	.hw_params = sdp4430_hw_params,
+static struct snd_soc_ops sdp4430_mcpdm_ops = {
+	.hw_params = sdp4430_mcpdm_hw_params,
+};
+
+static int sdp4430_mcbsp_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	int ret = 0;
+	unsigned int be_id;
+
+        be_id = rtd->dai_link->be_id;
+
+	if (be_id == OMAP_ABE_DAI_MM_FM) {
+		/* Set cpu DAI configuration */
+		ret = snd_soc_dai_set_fmt(cpu_dai,
+				  SND_SOC_DAIFMT_I2S |
+				  SND_SOC_DAIFMT_NB_NF |
+				  SND_SOC_DAIFMT_CBM_CFM);
+	} else if (be_id == OMAP_ABE_DAI_BT_VX) {
+	        ret = snd_soc_dai_set_fmt(cpu_dai,
+                                  SND_SOC_DAIFMT_DSP_B |
+                                  SND_SOC_DAIFMT_NB_IF |
+                                  SND_SOC_DAIFMT_CBM_CFM);
+	}
+
+	if (ret < 0) {
+		printk(KERN_ERR "can't set cpu DAI configuration\n");
+		return ret;
+	}
+
+	/*
+	 * TODO: where does this clock come from (external source??) -
+	 * do we need to enable it.
+	 */
+	/* Set McBSP clock to external */
+	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_FCLK,
+				     64 * params_rate(params),
+				     SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set cpu system clock\n");
+		return ret;
+	}
+	return 0;
+}
+
+static struct snd_soc_ops sdp4430_mcbsp_ops = {
+	.hw_params = sdp4430_mcbsp_hw_params,
+};
+
+static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	int ret = 0;
+
+	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS,
+				     19200000, SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set DMIC cpu system clock\n");
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_DMIC_CLKDIV, 8);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set DMIC cpu clock divider\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct snd_soc_ops sdp4430_dmic_ops = {
+	.hw_params = sdp4430_dmic_hw_params,
 };
 
 /* Headset jack */
@@ -196,23 +277,436 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
 	return ret;
 }
 
+/* TODO: make this a separate BT CODEC driver or DUMMY */
+static struct snd_soc_dai_driver dai[] = {
+{
+	.name = "Bluetooth",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
+					SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
+					SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+},
+/* TODO: make this a separate FM CODEC driver or DUMMY */
+{
+	.name = "FM Digital",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+},
+{
+	.name = "HDMI",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 2,
+		.channels_max = 8,
+		.rates = SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
+	},
+},
+};
+
+static const char *mm1_be[] = {
+	OMAP_ABE_BE_PDM_DL1,
+	OMAP_ABE_BE_PDM_UL1,
+	OMAP_ABE_BE_PDM_DL2,
+	OMAP_ABE_BE_BT_VX,
+	OMAP_ABE_BE_MM_EXT0,
+	OMAP_ABE_BE_DMIC0,
+	OMAP_ABE_BE_DMIC1,
+	OMAP_ABE_BE_DMIC2,
+};
+
+static const char *mm2_be[] = {
+	OMAP_ABE_BE_PDM_UL1,
+	OMAP_ABE_BE_BT_VX,
+	OMAP_ABE_BE_MM_EXT0,
+	OMAP_ABE_BE_DMIC0,
+	OMAP_ABE_BE_DMIC1,
+	OMAP_ABE_BE_DMIC2,
+};
+
+static const char *tones_be[] = {
+	OMAP_ABE_BE_PDM_DL1,
+	OMAP_ABE_BE_PDM_DL2,
+	OMAP_ABE_BE_BT_VX,
+	OMAP_ABE_BE_MM_EXT0,
+};
+
+static const char *vib_be[] = {
+	OMAP_ABE_BE_PDM_VIB,
+};
+
+static const char *modem_be[] = {
+	OMAP_ABE_BE_PDM_DL1,
+	OMAP_ABE_BE_PDM_UL1,
+	OMAP_ABE_BE_PDM_DL2,
+	OMAP_ABE_BE_BT_VX,
+	OMAP_ABE_BE_DMIC0,
+	OMAP_ABE_BE_DMIC1,
+	OMAP_ABE_BE_DMIC2,
+};
+
+static const char *mm_lp_be[] = {
+	OMAP_ABE_BE_PDM_DL1,
+	OMAP_ABE_BE_PDM_DL2,
+	OMAP_ABE_BE_BT_VX,
+	OMAP_ABE_BE_MM_EXT0,
+};
+
 /* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link sdp4430_dai = {
-	.name = "TWL6040",
-	.stream_name = "TWL6040",
-	.cpu_dai_name ="omap-mcpdm-dai",
-	.codec_dai_name = "twl6040-hifi",
-	.platform_name = "omap-pcm-audio",
-	.codec_name = "twl6040-codec",
-	.init = sdp4430_twl6040_init,
-	.ops = &sdp4430_ops,
+static struct snd_soc_dai_link sdp4430_dai[] = {
+
+/*
+ * Frontend DAIs - i.e. userspace visible interfaces (ALSA PCMs)
+ */
+
+	{
+		.name = "SDP4430 Media",
+		.stream_name = "Multimedia",
+
+		/* ABE components - MM-UL & MM_DL */
+		.cpu_dai_name = "MultiMedia1",
+		.platform_name = "omap-pcm-audio",
+
+		.dynamic = 1, /* BE is dynamic */
+		.supported_be = mm1_be,
+		.num_be = ARRAY_SIZE(mm1_be),
+		.fe_playback_channels = 2,
+		.fe_capture_channels = 8,
+	},
+	{
+		.name = "SDP4430 Media Capture",
+		.stream_name = "Multimedia Capture",
+
+		/* ABE components - MM-UL2 */
+		.cpu_dai_name = "MultiMedia2",
+		.platform_name = "omap-pcm-audio",
+
+		.dynamic = 1, /* BE is dynamic */
+		.supported_be = mm2_be,
+		.num_be = ARRAY_SIZE(mm2_be),
+		.fe_capture_channels = 2,
+	},
+	{
+		.name = "SDP4430 Voice",
+		.stream_name = "Voice",
+
+		/* ABE components - VX-UL & VX-DL */
+		.cpu_dai_name = "Voice",
+		.platform_name = "omap-pcm-audio",
+
+		.dynamic = 1, /* BE is dynamic */
+		.supported_be = mm1_be,
+		.num_be = ARRAY_SIZE(mm1_be),
+		.fe_playback_channels = 2,
+		.fe_capture_channels = 2,
+	},
+	{
+		.name = "SDP4430 Tones Playback",
+		.stream_name = "Tone Playback",
+
+		/* ABE components - TONES_DL */
+		.cpu_dai_name = "Tones",
+		.platform_name = "omap-pcm-audio",
+
+		.dynamic = 1, /* BE is dynamic */
+		.supported_be = tones_be,
+		.num_be = ARRAY_SIZE(tones_be),
+		.fe_playback_channels = 2,
+	},
+	{
+		.name = "SDP4430 Vibra Playback",
+		.stream_name = "VIB-DL",
+
+		.cpu_dai_name = "Vibra",
+		.platform_name = "omap-pcm-audio",
+
+		.dynamic = 1, /* BE is dynamic */
+		.supported_be = vib_be,
+		.num_be = ARRAY_SIZE(vib_be),
+		.fe_playback_channels = 2,
+	},
+	{
+		.name = "SDP4430 MODEM",
+		.stream_name = "MODEM",
+
+		/* ABE components - MODEM <-> McBSP2 */
+		.cpu_dai_name = "MODEM",
+		.platform_name = "omap-aess-audio",
+
+		.dynamic = 1, /* BE is dynamic */
+		.supported_be = modem_be,
+		.num_be = ARRAY_SIZE(modem_be),
+		.fe_playback_channels = 2,
+		.fe_capture_channels = 2,
+	},
+	{
+		.name = "SDP4430 Media LP",
+		.stream_name = "Multimedia",
+
+		/* ABE components - MM-DL (mmap) */
+		.cpu_dai_name = "MultiMedia1 LP",
+		.platform_name = "omap-aess-audio",
+
+		.dynamic = 1, /* BE is dynamic */
+		.supported_be = mm_lp_be,
+		.num_be = ARRAY_SIZE(mm_lp_be),
+		.fe_playback_channels = 2,
+	},
+#ifdef CONFIG_SND_OMAP_SOC_HDMI
+	{
+		.name = "hdmi",
+		.stream_name = "HDMI",
+
+		.cpu_dai_name = "hdmi-dai",
+		.platform_name = "omap-pcm-audio",
+
+		/* HDMI*/
+		.codec_dai_name = "HDMI",
+
+		.no_codec = 1,
+	},
+#endif
+	{
+		.name = "Legacy McBSP",
+		.stream_name = "Multimedia",
+
+		/* ABE components - MCBSP2 - MM-EXT */
+		.cpu_dai_name = "omap-mcbsp-dai.1",
+		.platform_name = "omap-pcm-audio",
+
+		/* FM */
+		.codec_dai_name = "FM Digital",
+
+		.no_codec = 1, /* TODO: have a dummy CODEC */
+		.ops = &sdp4430_mcbsp_ops,
+	},
+	{
+		.name = "Legacy McPDM",
+		.stream_name = "Headset Playback",
+
+		/* ABE components - DL1 */
+		.cpu_dai_name = "mcpdm-dl",
+		.platform_name = "omap-pcm-audio",
+
+		/* Phoenix - DL1 DAC */
+		.codec_dai_name =  "twl6040-dl1",
+		.codec_name = "twl6040-codec",
+
+		.ops = &sdp4430_mcpdm_ops,
+	},
+	{
+		.name = "Legacy DMIC",
+		.stream_name = "DMIC Capture",
+
+		/* ABE components - DMIC0 */
+		.cpu_dai_name = "omap-dmic-dai-0",
+		.platform_name = "omap-pcm-audio",
+
+		/* DMIC codec */
+		.codec_dai_name = "dmic-hifi",
+		.codec_name = "dmic-codec.0",
+
+		.ops = &sdp4430_dmic_ops,
+	},
+
+/*
+ * Backend DAIs - i.e. dynamically matched interfaces, invisible to userspace.
+ * Matched to above interfaces at runtime, based upon use case.
+ */
+
+	{
+		.name = OMAP_ABE_BE_PDM_DL1,
+		.stream_name = "HS Playback",
+
+		/* ABE components - DL1 */
+		.cpu_dai_name = "mcpdm-dl1",
+		.platform_name = "omap-aess-audio",
+
+		/* Phoenix - DL1 DAC */
+		.codec_dai_name =  "twl6040-dl1",
+		.codec_name = "twl6040-codec",
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.init = sdp4430_twl6040_init,
+		.ops = &sdp4430_mcpdm_ops,
+		.be_id = OMAP_ABE_DAI_PDM_DL1,
+	},
+	{
+		.name = OMAP_ABE_BE_PDM_UL1,
+		.stream_name = "Analog Capture",
+
+		/* ABE components - UL1 */
+		.cpu_dai_name = "mcpdm-ul1",
+		.platform_name = "omap-aess-audio",
+
+		/* Phoenix - UL ADC */
+		.codec_dai_name =  "twl6040-ul",
+		.codec_name = "twl6040-codec",
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.ops = &sdp4430_mcpdm_ops,
+		.be_id = OMAP_ABE_DAI_PDM_UL,
+	},
+	{
+		.name = OMAP_ABE_BE_PDM_DL2,
+		.stream_name = "HF Playback",
+
+		/* ABE components - DL2 */
+		.cpu_dai_name = "mcpdm-dl2",
+		.platform_name = "omap-aess-audio",
+
+		/* Phoenix - DL2 DAC */
+		.codec_dai_name =  "twl6040-dl2",
+		.codec_name = "twl6040-codec",
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.ops = &sdp4430_mcpdm_ops,
+		.be_id = OMAP_ABE_DAI_PDM_DL2,
+	},
+	{
+		.name = OMAP_ABE_BE_PDM_VIB,
+		.stream_name = "Vibra",
+
+		/* ABE components - VIB1 DL */
+		.cpu_dai_name = "mcpdm-vib",
+		.platform_name = "omap-aess-audio",
+
+		/* Phoenix - PDM to PWM */
+		.codec_dai_name =  "twl6040-vib",
+		.codec_name = "twl6040-codec",
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.ops = &sdp4430_mcpdm_ops,
+		.be_id = OMAP_ABE_DAI_PDM_VIB,
+	},
+	{
+		.name = OMAP_ABE_BE_BT_VX,
+		.stream_name = "BT",
+
+		/* ABE components - MCBSP1 - BT-VX */
+		.cpu_dai_name = "omap-mcbsp-dai.0",
+		.platform_name = "omap-aess-audio",
+
+		/* Bluetooth */
+		.codec_dai_name = "Bluetooth",
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.no_codec = 1, /* TODO: have a dummy CODEC */
+		.ops = &sdp4430_mcbsp_ops,
+		.be_id = OMAP_ABE_DAI_BT_VX,
+	},
+	{
+		.name = OMAP_ABE_BE_MM_EXT0,
+		.stream_name = "FM",
+
+		/* ABE components - MCBSP2 - MM-EXT */
+		.cpu_dai_name = "omap-mcbsp-dai.1",
+		.platform_name = "omap-aess-audio",
+
+		/* FM */
+		.codec_dai_name = "FM Digital",
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.no_codec = 1, /* TODO: have a dummy CODEC */
+		.ops = &sdp4430_mcbsp_ops,
+		.be_id = OMAP_ABE_DAI_MM_FM,
+	},
+	{
+		.name = OMAP_ABE_BE_MM_EXT1,
+		.stream_name = "MODEM",
+
+		/* ABE components - MCBSP2 - MM-EXT */
+		.cpu_dai_name = "omap-mcbsp-dai.1",
+		.platform_name = "omap-aess-audio",
+
+		/* MODEM */
+		.codec_dai_name = "MODEM",
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.no_codec = 1, /* TODO: have a dummy CODEC */
+		.ops = &sdp4430_mcbsp_ops,
+		.be_id = OMAP_ABE_DAI_MODEM,
+	},
+	{
+		.name = OMAP_ABE_BE_DMIC0,
+		.stream_name = "DMIC0",
+
+		/* ABE components - DMIC UL 1 */
+		.cpu_dai_name = "omap-dmic-abe-dai-0",
+		.platform_name = "omap-aess-audio",
+
+		/* DMIC 0 */
+		.codec_dai_name = "dmic-hifi",
+		.codec_name = "dmic-codec.0",
+		.ops = &sdp4430_dmic_ops,
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.be_id = OMAP_ABE_DAI_DMIC0,
+	},
+	{
+		.name = OMAP_ABE_BE_DMIC1,
+		.stream_name = "DMIC1",
+
+		/* ABE components - DMIC UL 1 */
+		.cpu_dai_name = "omap-dmic-abe-dai-1",
+		.platform_name = "omap-aess-audio",
+
+		/* DMIC 1 */
+		.codec_dai_name = "dmic-hifi",
+		.codec_name = "dmic-codec.1",
+		.ops = &sdp4430_dmic_ops,
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.be_id = OMAP_ABE_DAI_DMIC1,
+	},
+	{
+		.name = OMAP_ABE_BE_DMIC2,
+		.stream_name = "DMIC2",
+
+		/* ABE components - DMIC UL 2 */
+		.cpu_dai_name = "omap-dmic-abe-dai-2",
+		.platform_name = "omap-aess-audio",
+
+		/* DMIC 2 */
+		.codec_dai_name = "dmic-hifi",
+		.codec_name = "dmic-codec.2",
+		.ops = &sdp4430_dmic_ops,
+
+		.no_pcm = 1, /* don't create ALSA pcm for this */
+		.be_id = OMAP_ABE_DAI_DMIC2,
+	},
 };
 
 /* Audio machine driver */
 static struct snd_soc_card snd_soc_sdp4430 = {
 	.name = "SDP4430",
-	.dai_link = &sdp4430_dai,
-	.num_links = 1,
+	.long_name = "TI OMAP4 SDP4430 Board",
+	.dai_link = sdp4430_dai,
+	.num_links = ARRAY_SIZE(sdp4430_dai),
 };
 
 static struct platform_device *sdp4430_snd_device;
@@ -231,6 +725,8 @@ static int __init sdp4430_soc_init(void)
 		return -ENOMEM;
 	}
 
+	snd_soc_register_dais(&sdp4430_snd_device->dev, dai, ARRAY_SIZE(dai));
+
 	platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430);
 
 	ret = platform_device_add(sdp4430_snd_device);
-- 
1.7.4.1

