[alsa-devel] [PATCH - BT and FM audio for zoom2 2/2] Change pcm to bluetooth for McBSP3. Add FM transmit for McBSP4

sean.mcneil at ti.com sean.mcneil at ti.com
Mon Aug 3 06:29:15 CEST 2009


From: Sean McNeil <sean.mcneil at ti.com>


Signed-off-by: Sean McNeil <sean.mcneil at ti.com>

diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index f90b45f..2fdefd5 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -35,10 +35,13 @@
 #include "omap-pcm.h"
 #include "../codecs/twl4030.h"
 
+#define OMAP_MCBSP_MASTER_MODE	0
+
+#define ZOOM2_BT_MCBSP_GPIO		164
 #define ZOOM2_HEADSET_MUX_GPIO		(OMAP_MAX_GPIO_LINES + 15)
 #define ZOOM2_HEADSET_EXTMUTE_GPIO	153
 
-static int zoom2_hw_params(struct snd_pcm_substream *substream,
+static int zoom2_i2s_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -77,33 +80,41 @@ static int zoom2_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static struct snd_soc_ops zoom2_ops = {
-	.hw_params = zoom2_hw_params,
+static struct snd_soc_ops zoom2_i2s_ops = {
+	.hw_params = zoom2_i2s_hw_params,
 };
 
-static int zoom2_hw_voice_params(struct snd_pcm_substream *substream,
-				struct snd_pcm_hw_params *params)
+static int zoom2_pcm_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 *codec_dai = rtd->dai->codec_dai;
 	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
 	int ret;
 
+	if (gpio_request(ZOOM2_BT_MCBSP_GPIO, "bt_mux") == 0) {
+		gpio_direction_output(ZOOM2_BT_MCBSP_GPIO, 1);
+		gpio_free(ZOOM2_BT_MCBSP_GPIO);
+	}
+
+#if OMAP_MCBSP_MASTER_MODE
+	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+	int divisor;
+
 	/* Set codec DAI configuration */
 	ret = snd_soc_dai_set_fmt(codec_dai,
-				SND_SOC_DAIFMT_DSP_A |
-				SND_SOC_DAIFMT_IB_NF |
-				SND_SOC_DAIFMT_CBM_CFM);
-	if (ret) {
+				  SND_SOC_DAIFMT_DSP_B |
+				  SND_SOC_DAIFMT_NB_NF |
+				  SND_SOC_DAIFMT_CBS_CFS);
+	if (ret < 0) {
 		printk(KERN_ERR "can't set codec DAI configuration\n");
 		return ret;
 	}
 
 	/* Set cpu DAI configuration */
 	ret = snd_soc_dai_set_fmt(cpu_dai,
-				SND_SOC_DAIFMT_DSP_A |
-				SND_SOC_DAIFMT_IB_NF |
-				SND_SOC_DAIFMT_CBM_CFM);
+				  SND_SOC_DAIFMT_DSP_B |
+				  SND_SOC_DAIFMT_NB_NF |
+				  SND_SOC_DAIFMT_CBS_CFS);
 	if (ret < 0) {
 		printk(KERN_ERR "can't set cpu DAI configuration\n");
 		return ret;
@@ -117,11 +128,121 @@ static int zoom2_hw_voice_params(struct snd_pcm_substream *substream,
 		return ret;
 	}
 
+	ret = twl4030_set_rate(codec_dai->codec, params);
+
+	/* Use external (CLK256FS) clock for mcBSP3 */
+	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT,
+			0, SND_SOC_CLOCK_OUT);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set mcBSP3 to external clock\n");
+		return ret;
+	}
+
+	divisor = twl4030_get_clock_divisor(codec_dai->codec, params);
+
+	ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, divisor);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set codec clock divisor\n");
+		return ret;
+	}
+#else
+	/* Set cpu DAI configuration */
+	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;
+	}
+#endif
+
+	return 0;
+}
+
+int zoom2_pcm_hw_free(struct snd_pcm_substream *substream)
+{
 	return 0;
 }
 
-static struct snd_soc_ops zoom2_voice_ops = {
-	.hw_params = zoom2_hw_voice_params,
+static struct snd_soc_ops zoom2_pcm_ops = {
+	.hw_params = zoom2_pcm_hw_params,
+	.hw_free = zoom2_pcm_hw_free,
+};
+
+static int zoom2_fm_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->dai->cpu_dai;
+	int ret;
+
+#if OMAP_MCBSP_MASTER_MODE
+	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+	int divisor;
+
+	/* Set codec DAI configuration */
+	ret = snd_soc_dai_set_fmt(codec_dai,
+				  SND_SOC_DAIFMT_I2S |
+				  SND_SOC_DAIFMT_NB_NF |
+				  SND_SOC_DAIFMT_CBS_CFS);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set codec DAI configuration\n");
+		return ret;
+	}
+
+	/* Set cpu DAI configuration */
+	ret = snd_soc_dai_set_fmt(cpu_dai,
+				  SND_SOC_DAIFMT_I2S |
+				  SND_SOC_DAIFMT_NB_NF |
+				  SND_SOC_DAIFMT_CBS_CFS);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set cpu DAI configuration\n");
+		return ret;
+	}
+
+	/* Set the codec system clock for DAC and ADC */
+	ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
+			SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set codec system clock\n");
+		return ret;
+	}
+
+	ret = twl4030_set_rate(codec_dai->codec, params);
+
+	/* Use external (CLK256FS) clock for mcBSP4 */
+	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT,
+			0, SND_SOC_CLOCK_OUT);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set mcBSP4 to external clock\n");
+		return ret;
+	}
+
+	divisor = twl4030_get_clock_divisor(codec_dai->codec, params);
+
+	ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, divisor);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set codec clock divisor\n");
+		return ret;
+	}
+#else
+	/* 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);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set cpu DAI configuration\n");
+		return ret;
+	}
+#endif
+
+	return 0;
+}
+
+static struct snd_soc_ops zoom2_fm_ops = {
+	.hw_params = zoom2_fm_hw_params,
 };
 
 /* Zoom2 machine DAPM */
@@ -207,24 +328,57 @@ static int zoom2_twl4030_voice_init(struct snd_soc_codec *codec)
 	return 0;
 }
 
+#if !OMAP_MCBSP_MASTER_MODE
+struct snd_soc_dai null_dai = {
+	.name = "null",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 4,
+		.rates = SNDRV_PCM_RATE_8000_96000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE,},
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 4,
+		.rates = SNDRV_PCM_RATE_8000_96000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE,},
+};
+#endif
+
 /* Digital audio interface glue - connects codec <--> CPU */
 static struct snd_soc_dai_link zoom2_dai[] = {
-	{
-		.name = "TWL4030 I2S",
-		.stream_name = "TWL4030 Audio",
-		.cpu_dai = &omap_mcbsp_dai[0],
-		.codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
-		.init = zoom2_twl4030_init,
-		.ops = &zoom2_ops,
-	},
-	{
-		.name = "TWL4030 PCM",
-		.stream_name = "TWL4030 Voice",
-		.cpu_dai = &omap_mcbsp_dai[1],
-		.codec_dai = &twl4030_dai[TWL4030_DAI_VOICE],
-		.init = zoom2_twl4030_voice_init,
-		.ops = &zoom2_voice_ops,
-	},
+{
+	.name = "TWL4030_I2S",
+	.stream_name = "TWL4030_I2S",
+	.cpu_dai = &omap_mcbsp_dai[0],
+	.codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
+	.init = zoom2_twl4030_init,
+	.ops = &zoom2_i2s_ops,
+},
+{
+	.name = "TWL4030_PCM",
+	.stream_name = "TWL4030_PCM",
+	.cpu_dai = &omap_mcbsp_dai[1],
+#if OMAP_MCBSP_MASTER_MODE
+	.codec_dai = &twl4030_dai[TWL4030_DAI_CLOCK],
+#else
+	.codec_dai = &null_dai,
+#endif
+	.init = zoom2_twl4030_voice_init,
+	.ops = &zoom2_pcm_ops,
+},
+{
+	.name = "TWL4030_FM",
+	.stream_name = "TWL4030_FM",
+	.cpu_dai = &omap_mcbsp_dai[2],
+#if OMAP_MCBSP_MASTER_MODE
+	.codec_dai = &twl4030_dai[TWL4030_DAI_CLOCK],
+#else
+	.codec_dai = &null_dai,
+#endif
+	.ops = &zoom2_fm_ops,
+},
 };
 
 /* Audio machine driver */
@@ -268,6 +422,10 @@ static int __init zoom2_soc_init(void)
 	}
 	printk(KERN_INFO "Zoom2 SoC init\n");
 
+#if !OMAP_MCBSP_MASTER_MODE
+	snd_soc_register_dais(&null_dai, 1);
+#endif
+
 	zoom2_snd_device = platform_device_alloc("soc-audio", -1);
 	if (!zoom2_snd_device) {
 		printk(KERN_ERR "Platform device allocation failed\n");
@@ -278,6 +436,7 @@ static int __init zoom2_soc_init(void)
 	zoom2_snd_devdata.dev = &zoom2_snd_device->dev;
 	*(unsigned int *)zoom2_dai[0].cpu_dai->private_data = 1; /* McBSP2 */
 	*(unsigned int *)zoom2_dai[1].cpu_dai->private_data = 2; /* McBSP3 */
+	*(unsigned int *)zoom2_dai[2].cpu_dai->private_data = 3; /* McBSP4 */
 
 	ret = platform_device_add(zoom2_snd_device);
 	if (ret)
-- 
1.6.0.4



More information about the Alsa-devel mailing list