[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