Commit 3a3d5fd1 authored by David Dillow's avatar David Dillow Committed by Jaroslav Kysela

sis7019: fix capture issues with multiple periods per buffer

When using a timing voice to clock out periods during capture, the
driver would slowly loose synchronization and never catch up, eventually
reaching a point where it no longer generated interrupts. To avoid
this situation, the virtual period clocking was changed to shorten the
next timing period when our timing voice falls too far behind the
capture voice. In addition, the first virtual period for the timing
voice was slightly too short, causing the timing voice to initially be
ahead of the capture voice.

While tracking down this problem, I noticed that the expected sample
offset was being incorrectly initialized, causing an overrun to be
incorrectly reported when the timing voice happened to be perfectly
synchronized.
Reported-by: default avatarHans Schou <linux@schou.dk>
Signed-off-by: default avatarDave Dillow <dave@thedillows.org>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 5daeba34
......@@ -264,11 +264,13 @@ static void sis_update_voice(struct voice *voice)
* if using small periods.
*
* If we're less than 9 samples behind, we're on target.
* Otherwise, shorten the next vperiod by the amount we've
* been delayed.
*/
if (sync > -9)
voice->vperiod = voice->sync_period_size + 1;
else
voice->vperiod = voice->sync_period_size - 4;
voice->vperiod = voice->sync_period_size + sync + 10;
if (voice->vperiod < voice->buffer_size) {
sis_update_sso(voice, voice->vperiod);
......@@ -736,7 +738,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
period_size = buffer_size;
/* Initially, we want to interrupt just a bit behind the end of
* the period we're clocking out. 10 samples seems to give a good
* the period we're clocking out. 12 samples seems to give a good
* delay.
*
* We want to spread our interrupts throughout the virtual period,
......@@ -747,7 +749,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
*
* This is all moot if we don't need to use virtual periods.
*/
vperiod = runtime->period_size + 10;
vperiod = runtime->period_size + 12;
if (vperiod > period_size) {
u16 tail = vperiod % period_size;
u16 quarter_period = period_size / 4;
......@@ -776,7 +778,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
*/
timing->flags |= VOICE_SYNC_TIMING;
timing->sync_base = voice->ctrl_base;
timing->sync_cso = runtime->period_size - 1;
timing->sync_cso = runtime->period_size;
timing->sync_period_size = runtime->period_size;
timing->sync_buffer_size = runtime->buffer_size;
timing->period_size = period_size;
......
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