[alsa-devel] [PATCH 3/5 v2] ASoC: S3C platform: Fix s3c2410_dma_started called at wrong time

Shine Liu shinel at foxmail.com
Mon Aug 24 11:22:32 CEST 2009


Part 3: S3C ASoC I2S-V2 drivers, used by S3C2412-I2S and S3C64XX-I2S.
Add the callback functions for the DMA drivers. These callback functions
are registered in the probe phase.  



--- a/sound/soc/s3c24xx/s3c-i2s-v2.c	2009-08-24 13:28:58.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c	2009-08-24 15:17:02.000000000 +0800
@@ -53,6 +53,12 @@
 
 #define S3C2412_I2S_DEBUG_CON 0
 
+struct s3c2412_i2s_trigger_internal_data {
+	struct snd_pcm_substream *substream;
+	int cmd;
+	struct snd_soc_dai *dai;
+};
+
 static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
 {
 	return cpu_dai->private_data;
@@ -383,14 +389,45 @@
 			       struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct s3c24xx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+	struct s3c2410_dma_client *client  = dma_params->client;
+	struct s3c2412_i2s_trigger_internal_data callback_params;
+	int ret = 0;
+
+	callback_params.substream = substream;
+	callback_params.cmd = cmd;
+	callback_params.dai = dai;
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START;
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		client->event = S3C2410_DMA_TRIGGER_START;;
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		client->event = S3C2410_DMA_TRIGGER_STOP;
+		break;
+	default:
+		return -EINVAL;		
+	}
+
+	client->private_data = &callback_params;
+	return s3c2410_dma_trigger(client);
+}
+
+static int s3c2412_i2s_trigger_internal(struct s3c2412_i2s_trigger_internal_data *data)
+{
+	struct snd_soc_pcm_runtime *rtd = data->substream->private_data;
 	struct s3c_i2sv2_info *i2s = to_info(rtd->dai->cpu_dai);
-	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+	int capture = (data->substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 	unsigned long irqs;
 	int ret = 0;
 
 	pr_debug("Entered %s\n", __func__);
 
-	switch (cmd) {
+	switch (data->cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		/* On start, ensure that the FIFOs are cleared and reset. */
 
@@ -627,6 +664,14 @@
 	s3c2412_snd_txctrl(i2s, 0);
 	s3c2412_snd_rxctrl(i2s, 0);
 
+	if(i2s->dma_playback && i2s->dma_playback->client) {
+		i2s->dma_playback->client->gen_request = (void*)s3c2412_i2s_trigger_internal;
+		i2s->dma_playback->client->end_request = (void*)s3c2412_i2s_trigger_internal;
+	}
+	if(i2s->dma_capture && i2s->dma_capture->client) {
+		i2s->dma_capture->client->gen_request = (void*)s3c2412_i2s_trigger_internal;
+		i2s->dma_capture->client->end_request = (void*)s3c2412_i2s_trigger_internal;
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(s3c_i2sv2_probe);
--- a/sound/soc/s3c24xx/s3c2412-i2s.c	2009-08-24 13:28:58.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c	2009-08-24 15:02:32.000000000 +0800
@@ -44,11 +44,16 @@
 #define S3C2412_I2S_DEBUG 0
 
 static struct s3c2410_dma_client s3c2412_dma_client_out = {
-	.name		= "I2S PCM Stereo out"
+	.name		= "I2S PCM Stereo out",
+	.channel	= DMACH_I2S_OUT,
+	/* callback functions will be set in s3c_i2sv2_probe */
+
 };
 
 static struct s3c2410_dma_client s3c2412_dma_client_in = {
-	.name		= "I2S PCM Stereo in"
+	.name		= "I2S PCM Stereo in",
+	.channel	= DMACH_I2S_IN,
+	/* callback functions will be set in s3c_i2sv2_probe */	
 };
 
 static struct s3c24xx_pcm_dma_params s3c2412_i2s_pcm_stereo_out = {
@@ -112,13 +117,14 @@
 
 	pr_debug("Entered %s\n", __func__);
 
+	/* s3c_i2sv2_probe will setup dma callback functions for them  */
+	s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in;
+	s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
+
 	ret = s3c_i2sv2_probe(pdev, dai, &s3c2412_i2s, S3C2410_PA_IIS);
 	if (ret)
 		return ret;
 
-	s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in;
-	s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
-
 	s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk");
 	if (s3c2412_i2s.iis_cclk == NULL) {
 		pr_err("failed to get i2sclk clock\n");
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c	2009-08-24 13:28:58.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c	2009-08-24 15:00:24.000000000 +0800
@@ -39,24 +39,42 @@
 #include "s3c24xx-pcm.h"
 #include "s3c64xx-i2s.h"
 
-static struct s3c2410_dma_client s3c64xx_dma_client_out = {
-	.name		= "I2S PCM Stereo out"
+static struct s3c2410_dma_client s3c64xx_dma_client_out_0 = {
+	.name		= "I2S PCM Stereo out #0",
+	.channel	= DMACH_I2S0_OUT,
+	/* callback functions will be set in s3c_i2sv2_probe */
 };
 
-static struct s3c2410_dma_client s3c64xx_dma_client_in = {
-	.name		= "I2S PCM Stereo in"
+static struct s3c2410_dma_client s3c64xx_dma_client_out_1 = {
+	.name		= "I2S PCM Stereo out #1",
+	.channel	= DMACH_I2S1_OUT,
+	/* callback functions will be set in s3c_i2sv2_probe */
+};
+
+static struct s3c2410_dma_client s3c64xx_dma_client_in_0 = {
+	.name		= "I2S PCM Stereo in #0",
+	.channel	= DMACH_I2S0_IN,
+	/* callback functions will be set in s3c_i2sv2_probe */
+
+};
+
+static struct s3c2410_dma_client s3c64xx_dma_client_in_1 = {
+	.name		= "I2S PCM Stereo in #1",
+	.channel	= DMACH_I2S1_IN,
+	/* callback functions will be set in s3c_i2sv2_probe */
+
 };
 
 static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_out[2] = {
 	[0] = {
 		.channel	= DMACH_I2S0_OUT,
-		.client		= &s3c64xx_dma_client_out,
+		.client		= &s3c64xx_dma_client_out_0,
 		.dma_addr	= S3C64XX_PA_IIS0 + S3C2412_IISTXD,
 		.dma_size	= 4,
 	},
 	[1] = {
 		.channel	= DMACH_I2S1_OUT,
-		.client		= &s3c64xx_dma_client_out,
+		.client		= &s3c64xx_dma_client_out_1,
 		.dma_addr	= S3C64XX_PA_IIS1 + S3C2412_IISTXD,
 		.dma_size	= 4,
 	},
@@ -65,13 +83,13 @@
 static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_in[2] = {
 	[0] = {
 		.channel	= DMACH_I2S0_IN,
-		.client		= &s3c64xx_dma_client_in,
+		.client		= &s3c64xx_dma_client_in_0,
 		.dma_addr	= S3C64XX_PA_IIS0 + S3C2412_IISRXD,
 		.dma_size	= 4,
 	},
 	[1] = {
 		.channel	= DMACH_I2S1_IN,
-		.client		= &s3c64xx_dma_client_in,
+		.client		= &s3c64xx_dma_client_in_1,
 		.dma_addr	= S3C64XX_PA_IIS1 + S3C2412_IISRXD,
 		.dma_size	= 4,
 	},





More information about the Alsa-devel mailing list