ALSA: ca0106 - clean up playback pointer callback
Clean up the playback pointer callback function a bit, and make the pointer check more strictly to avoid bogus pointers. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Родитель
9fe856e47e
Коммит
add7c0a6a4
|
@ -1002,29 +1002,27 @@ snd_ca0106_pcm_pointer_playback(struct snd_pcm_substream *substream)
|
|||
struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_ca0106_pcm *epcm = runtime->private_data;
|
||||
snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
|
||||
unsigned int ptr, prev_ptr;
|
||||
int channel = epcm->channel_id;
|
||||
int timeout = 10;
|
||||
|
||||
if (!epcm->running)
|
||||
return 0;
|
||||
|
||||
ptr3 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
|
||||
ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel);
|
||||
ptr4 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
|
||||
if (ptr3 != ptr4) ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel);
|
||||
ptr2 = bytes_to_frames(runtime, ptr1);
|
||||
ptr2+= (ptr4 >> 3) * runtime->period_size;
|
||||
ptr=ptr2;
|
||||
if (ptr >= runtime->buffer_size)
|
||||
ptr -= runtime->buffer_size;
|
||||
/*
|
||||
printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, "
|
||||
"buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n",
|
||||
ptr1, ptr2, ptr, (int)runtime->buffer_size,
|
||||
(int)runtime->period_size, (int)runtime->frame_bits,
|
||||
(int)runtime->rate);
|
||||
*/
|
||||
return ptr;
|
||||
prev_ptr = -1;
|
||||
do {
|
||||
ptr = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
|
||||
ptr = (ptr >> 3) * runtime->period_size;
|
||||
ptr += bytes_to_frames(runtime,
|
||||
snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel));
|
||||
if (ptr >= runtime->buffer_size)
|
||||
ptr -= runtime->buffer_size;
|
||||
if (prev_ptr == ptr)
|
||||
return ptr;
|
||||
prev_ptr = ptr;
|
||||
} while (--timeout);
|
||||
snd_printk(KERN_WARNING "ca0106: unstable DMA pointer!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pointer_capture callback */
|
||||
|
|
Загрузка…
Ссылка в новой задаче