Skip to content

Commit

Permalink
ASoC: OMAP: Fix capture pointer handling for OMAP1510 to work correct…
Browse files Browse the repository at this point in the history
…ly with recent ALSA PCM code

With recent (2.6.34) chnages in PCM handling, capture stopped working on my
OMAP1510 based Amstrad Delta videophone.

Using 2.6.34-rc2, I was able to correct the problem in 3 different ways:

1. reverting commit 7b3a177,
2. enabling additional jiffies check with
	echo 4 >/proc/asound/card0/pcm0c0/xrun_debug
3. applying the patch below.

Since I wasn't able to reproduce the problem on my i686 PC, I guess the
problem is probably machine specific.

The patch reuses the method for software emulation of missing hardware
pointer, already implemented for playback on OMAP1510. It's possible that
event if a hardware pointer is available for capture on this machine, its
behaviour may be not compatible with what upper layer expects.

If you think the problem may be more general and should be solved differently,
on a higher level, I can try to work more on it if you give me a hint.

If the patch gets accepted, I suggest it goes as a fix in the current release
cycle.

Created and tested against linux-2.6.34-rc2.

Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
Acked-by: Jarkko Nikula <jhnikula@gmail.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Janusz Krzysztofik authored and Mark Brown committed Apr 2, 2010
1 parent fb48e3c commit b5442a7
Showing 1 changed file with 8 additions and 9 deletions.
17 changes: 8 additions & 9 deletions sound/soc/omap/omap-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
struct omap_runtime_data *prtd = runtime->private_data;
unsigned long flags;

if ((cpu_is_omap1510()) &&
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
if ((cpu_is_omap1510())) {
/*
* OMAP1510 doesn't fully support DMA progress counter
* and there is no software emulation implemented yet,
* so have to maintain our own playback progress counter
* so have to maintain our own progress counters
* that can be used by omap_pcm_pointer() instead.
*/
spin_lock_irqsave(&prtd->lock, flags);
Expand Down Expand Up @@ -189,8 +188,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
dma_params.frame_count = runtime->periods;
omap_set_dma_params(prtd->dma_ch, &dma_params);

if ((cpu_is_omap1510()) &&
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
if ((cpu_is_omap1510()))
omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
else
Expand Down Expand Up @@ -248,14 +246,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
dma_addr_t ptr;
snd_pcm_uframes_t offset;

if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
if (cpu_is_omap1510()) {
offset = prtd->period_index * runtime->period_size;
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
ptr = omap_get_dma_dst_pos(prtd->dma_ch);
offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
} else if (!(cpu_is_omap1510())) {
} else {
ptr = omap_get_dma_src_pos(prtd->dma_ch);
offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
} else
offset = prtd->period_index * runtime->period_size;
}

if (offset >= runtime->buffer_size)
offset = 0;
Expand Down

0 comments on commit b5442a7

Please sign in to comment.