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

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


Part 5: S3C ASoC 24XX-AC97 drivers. Add the callback functions for the
DMA drivers. These callback functions are determined in the compile time
(no need to be registered in the probe phase).  



--- a/sound/soc/s3c24xx/s3c2443-ac97.c	2009-08-24 13:28:58.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c	2009-08-24 15:13:42.000000000 +0800
@@ -154,6 +154,39 @@
 	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 }
 
+static int s3c2443_ac97_snd_ctrl_on(int stream_direction)
+{
+	u32 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
+	if (stream_direction == SNDRV_PCM_STREAM_CAPTURE)
+		ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
+	else
+		ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
+	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
+	return 0;
+}
+
+static int s3c2443_ac97_snd_ctrl_off(int stream_direction)
+{
+	u32 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
+	if (stream_direction == SNDRV_PCM_STREAM_CAPTURE)
+		ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
+	else
+		ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
+	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
+	return 0;
+}
+
+static int s3c2443_ac97_mic_ctrl(int cmd)
+{
+	u32 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
+	if(cmd == 1)
+		ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
+	else
+		ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
+	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
+	return 0;
+}
+
 static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id)
 {
 	int status;
@@ -178,15 +211,24 @@
 };
 
 static struct s3c2410_dma_client s3c2443_dma_client_out = {
-	.name = "AC97 PCM Stereo out"
+	.name = "AC97 PCM Stereo out",
+	.channel	= DMACH_PCM_OUT,
+	.gen_request	= (void *)s3c2443_ac97_snd_ctrl_on,
+	.end_request	= (void *)s3c2443_ac97_snd_ctrl_off,
 };
 
 static struct s3c2410_dma_client s3c2443_dma_client_in = {
-	.name = "AC97 PCM Stereo in"
+	.name = "AC97 PCM Stereo in",
+	.channel	= DMACH_PCM_IN,
+	.gen_request	= (void *)s3c2443_ac97_snd_ctrl_on,
+	.end_request	= (void *)s3c2443_ac97_snd_ctrl_off,
 };
 
 static struct s3c2410_dma_client s3c2443_dma_client_micin = {
-	.name = "AC97 Mic Mono in"
+	.name = "AC97 Mic Mono in",
+	.channel	= DMACH_MIC_IN,
+	.gen_request	= (void *)s3c2443_ac97_mic_ctrl,
+	.end_request	= (void *)s3c2443_ac97_mic_ctrl,
 };
 
 static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_out = {
@@ -289,30 +331,25 @@
 static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
 				struct snd_soc_dai *dai)
 {
-	u32 ac_glbctrl;
+	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;
 
-	ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
+	client->private_data = (void *)substream->stream;
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-			ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
-		else
-			ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
+		client->event = S3C2410_DMA_TRIGGER_START;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-			ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
-		else
-			ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
+		client->event = S3C2410_DMA_TRIGGER_STOP;
 		break;
 	}
-	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 
-	return 0;
+	return s3c2410_dma_trigger(client);
 }
 
 static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
@@ -333,23 +370,25 @@
 static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
 				    int cmd, struct snd_soc_dai *dai)
 {
-	u32 ac_glbctrl;
+	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;
 
-	ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
+		client->private_data = (void *)1;
+		client->event = S3C2410_DMA_TRIGGER_START;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
+		client->private_data = (void *)0;
+		client->event = S3C2410_DMA_TRIGGER_STOP;
 	}
-	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 
-	return 0;
+	return s3c2410_dma_trigger(client);
 }
 
 #define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\





More information about the Alsa-devel mailing list