Commit 64844a6a authored by Janusz Krzysztofik's avatar Janusz Krzysztofik Committed by Mark Brown

ASoC: OMAP: Make use of DMA channel self linking on OMAP1510

Use newly implemented DMA channel self linking on OMAP1510 like on other OMAP
models. Remove unnecessary DMA transfer restart from interrupt handler
routine.

The interrupt routine used to maintain a period index, originally needed for
counting up periods up to a full buffer in order to restart the DMA transfer.
For some time, this counter is also used as a replacement for hardware DMA
progress counter that has been found unusable on OMAP1510 in case of playback.
Thus, the period index calculation cannot be omitted completely. However, the
accuracy of this counter can still suffer from missing DMA interrupts.

In order to work correctly, it requires patch 1 from this series also applied:
[RFC][PATCH 1/3] ARM: OMAP: DMA: Add support for DMA channel self linking on OMAP1510

Created against linux-2.6.31-rc5.

Tested on Amstrad Delta.
Signed-off-by: default avatarJanusz Krzysztofik <jkrzyszt@tis.icnet.pl>
Acked-by: default avatarJarkko Nikula <jhnikula@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 1e97f50b
...@@ -59,16 +59,18 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) ...@@ -59,16 +59,18 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
struct omap_runtime_data *prtd = runtime->private_data; struct omap_runtime_data *prtd = runtime->private_data;
unsigned long flags; unsigned long flags;
if (cpu_is_omap1510()) { if ((cpu_is_omap1510()) &&
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
/* /*
* OMAP1510 doesn't support DMA chaining so have to restart * OMAP1510 doesn't fully support DMA progress counter
* the transfer after all periods are transferred * and there is no software emulation implemented yet,
* so have to maintain our own playback progress counter
* that can be used by omap_pcm_pointer() instead.
*/ */
spin_lock_irqsave(&prtd->lock, flags); spin_lock_irqsave(&prtd->lock, flags);
if (prtd->period_index >= 0) { if (prtd->period_index >= 0) {
if (++prtd->period_index == runtime->periods) { if (++prtd->period_index == runtime->periods) {
prtd->period_index = 0; prtd->period_index = 0;
omap_start_dma(prtd->dma_ch);
} }
} }
spin_unlock_irqrestore(&prtd->lock, flags); spin_unlock_irqrestore(&prtd->lock, flags);
...@@ -100,7 +102,7 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -100,7 +102,7 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
prtd->dma_data = dma_data; prtd->dma_data = dma_data;
err = omap_request_dma(dma_data->dma_req, dma_data->name, err = omap_request_dma(dma_data->dma_req, dma_data->name,
omap_pcm_dma_irq, substream, &prtd->dma_ch); omap_pcm_dma_irq, substream, &prtd->dma_ch);
if (!err && !cpu_is_omap1510()) { if (!err) {
/* /*
* Link channel with itself so DMA doesn't need any * Link channel with itself so DMA doesn't need any
* reprogramming while looping the buffer * reprogramming while looping the buffer
...@@ -119,8 +121,7 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream) ...@@ -119,8 +121,7 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
if (prtd->dma_data == NULL) if (prtd->dma_data == NULL)
return 0; return 0;
if (!cpu_is_omap1510()) omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch);
omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch);
omap_free_dma(prtd->dma_ch); omap_free_dma(prtd->dma_ch);
prtd->dma_data = NULL; prtd->dma_data = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment