sorry for this mess. Please ignore this one. My script made some mistake. -Bryan On Sat, Sep 27, 2008 at 9:49 PM, Bryan Wu <cooloney@xxxxxxxxxx> wrote: > From: Cliff Cai <cliff.cai@xxxxxxxxxx> > > With MMAP enabled (DMA mode) on the AD1981, there is +/- 250ms of delay between > writing data to alsa and audio starts coming out of the AD1981. > > Copy more data to local buffer before starting DMA > > Signed-off-by: Cliff Cai <cliff.cai@xxxxxxxxxx> > Signed-off-by: Bryan Wu <cooloney@xxxxxxxxxx> > --- > sound/soc/blackfin/bf5xx-ac97-pcm.c | 42 +++++++++++++++++++++++++++++----- > sound/soc/blackfin/bf5xx-ac97.c | 1 - > sound/soc/blackfin/bf5xx-sport.h | 2 + > 3 files changed, 37 insertions(+), 8 deletions(-) > > diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c > index 51f4907..25e50d2 100644 > --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c > +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c > @@ -56,6 +56,7 @@ static void bf5xx_mmap_copy(struct snd_pcm_substream *substream, > sport->tx_pos += runtime->period_size; > if (sport->tx_pos >= runtime->buffer_size) > sport->tx_pos %= runtime->buffer_size; > + sport->tx_delay_pos = sport->tx_pos; > } else { > bf5xx_ac97_to_pcm( > (struct ac97_frame *)sport->rx_dma_buf + sport->rx_pos, > @@ -72,7 +73,15 @@ static void bf5xx_dma_irq(void *data) > struct snd_pcm_substream *pcm = data; > #if defined(CONFIG_SND_MMAP_SUPPORT) > struct snd_pcm_runtime *runtime = pcm->runtime; > + struct sport_device *sport = runtime->private_data; > bf5xx_mmap_copy(pcm, runtime->period_size); > + if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK) { > + if (sport->once == 0) { > + snd_pcm_period_elapsed(pcm); > + bf5xx_mmap_copy(pcm, runtime->period_size); > + sport->once = 1; > + } > + } > #endif > snd_pcm_period_elapsed(pcm); > } > @@ -114,6 +123,10 @@ static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream, > > static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream) > { > + struct snd_pcm_runtime *runtime = substream->runtime; > + > + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) > + memset(runtime->dma_area, 0, runtime->buffer_size); > snd_pcm_lib_free_pages(substream); > return 0; > } > @@ -127,16 +140,11 @@ static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream) > * SPORT working in TMD mode(include AC97). > */ > #if defined(CONFIG_SND_MMAP_SUPPORT) > - size_t size = bf5xx_pcm_hardware.buffer_bytes_max > - * sizeof(struct ac97_frame) / 4; > - /*clean up intermediate buffer*/ > if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { > - memset(sport->tx_dma_buf, 0, size); > sport_set_tx_callback(sport, bf5xx_dma_irq, substream); > sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods, > runtime->period_size * sizeof(struct ac97_frame)); > } else { > - memset(sport->rx_dma_buf, 0, size); > sport_set_rx_callback(sport, bf5xx_dma_irq, substream); > sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods, > runtime->period_size * sizeof(struct ac97_frame)); > @@ -164,8 +172,12 @@ static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) > pr_debug("%s enter\n", __func__); > switch (cmd) { > case SNDRV_PCM_TRIGGER_START: > - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) > + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { > + bf5xx_mmap_copy(substream, runtime->period_size); > + snd_pcm_period_elapsed(substream); > + sport->tx_delay_pos = 0; > sport_tx_start(sport); > + } > else > sport_rx_start(sport); > break; > @@ -198,7 +210,7 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream) > > #if defined(CONFIG_SND_MMAP_SUPPORT) > if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) > - curr = sport->tx_pos; > + curr = sport->tx_delay_pos; > else > curr = sport->rx_pos; > #else > @@ -237,6 +249,21 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream) > return ret; > } > > +static int bf5xx_pcm_close(struct snd_pcm_substream *substream) > +{ > + struct snd_pcm_runtime *runtime = substream->runtime; > + struct sport_device *sport = runtime->private_data; > + > + pr_debug("%s enter\n", __func__); > + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { > + sport->once = 0; > + memset(sport->tx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame)); > + } else > + memset(sport->rx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame)); > + > + return 0; > +} > + > #ifdef CONFIG_SND_MMAP_SUPPORT > static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream, > struct vm_area_struct *vma) > @@ -272,6 +299,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, > > struct snd_pcm_ops bf5xx_pcm_ac97_ops = { > .open = bf5xx_pcm_open, > + .close = bf5xx_pcm_close, > .ioctl = snd_pcm_lib_ioctl, > .hw_params = bf5xx_pcm_hw_params, > .hw_free = bf5xx_pcm_hw_free, > diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c > index c782e31..5e5aafb 100644 > --- a/sound/soc/blackfin/bf5xx-ac97.c > +++ b/sound/soc/blackfin/bf5xx-ac97.c > @@ -129,7 +129,6 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data) > struct ac97_frame *nextwrite; > > sport_incfrag(sport, &nextfrag, 1); > - sport_incfrag(sport, &nextfrag, 1); > > nextwrite = (struct ac97_frame *)(sport->tx_buf + \ > nextfrag * sport->tx_fragsize); > diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h > index 4c16345..fcadcc0 100644 > --- a/sound/soc/blackfin/bf5xx-sport.h > +++ b/sound/soc/blackfin/bf5xx-sport.h > @@ -123,6 +123,8 @@ struct sport_device { > int rx_pos; > unsigned int tx_buffer_size; > unsigned int rx_buffer_size; > + int tx_delay_pos; > + int once; > #endif > void *private_data; > }; > -- > 1.5.6 > > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel