Commit ef7eeb69 authored by Jaroslav Kysela's avatar Jaroslav Kysela

[ALSA] Add workaround for buggy ATI IXP hardwares

ATIIXP-modem driver
Added a workaround for buggy ATI IXP hardwares which returns
bogus DMA pointer register value.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 86f4e0e4
...@@ -606,21 +606,20 @@ static snd_pcm_uframes_t snd_atiixp_pcm_pointer(snd_pcm_substream_t *substream) ...@@ -606,21 +606,20 @@ static snd_pcm_uframes_t snd_atiixp_pcm_pointer(snd_pcm_substream_t *substream)
snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_runtime_t *runtime = substream->runtime;
atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data; atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data;
unsigned int curptr; unsigned int curptr;
int timeout = 1000;
spin_lock(&chip->reg_lock); while (timeout--) {
curptr = readl(chip->remap_addr + dma->ops->dt_cur); curptr = readl(chip->remap_addr + dma->ops->dt_cur);
if (curptr < dma->buf_addr) { if (curptr < dma->buf_addr)
snd_printdd("curptr = %x, base = %x\n", curptr, dma->buf_addr); continue;
curptr = 0;
} else {
curptr -= dma->buf_addr; curptr -= dma->buf_addr;
if (curptr >= dma->buf_bytes) { if (curptr >= dma->buf_bytes)
snd_printdd("curptr = %x, size = %x\n", curptr, dma->buf_bytes); continue;
curptr = 0;
}
}
spin_unlock(&chip->reg_lock);
return bytes_to_frames(runtime, curptr); return bytes_to_frames(runtime, curptr);
}
snd_printd("atiixp-modem: invalid DMA pointer read 0x%x (buf=%x)\n",
readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
return 0;
} }
/* /*
......
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