[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