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 |\ _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel