Commit d7dc9e32 authored by Markus Bollinger's avatar Markus Bollinger Committed by Takashi Iwai

ALSA: pcxhr: Fix a counter wrap

fix a counter wrap to avoid resynchronization of stream positions every several
minutes. The resynchronization may create stream position jitter
Signed-off-by: default avatarMarkus Bollinger <bollinger@digigram.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent e0815f35
...@@ -1133,13 +1133,12 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr, ...@@ -1133,13 +1133,12 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24; hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24;
hw_sample_count += (u_int64_t)rmh.stat[1]; hw_sample_count += (u_int64_t)rmh.stat[1];
snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", snd_printdd("stream %c%d : abs samples real(%llu) timer(%llu)\n",
stream->pipe->is_capture ? 'C' : 'P', stream->pipe->is_capture ? 'C' : 'P',
stream->substream->number, stream->substream->number,
(long unsigned int)hw_sample_count, hw_sample_count,
(long unsigned int)(stream->timer_abs_periods + stream->timer_abs_periods + stream->timer_period_frag +
stream->timer_period_frag + mgr->granularity);
mgr->granularity));
return hw_sample_count; return hw_sample_count;
} }
...@@ -1243,11 +1242,19 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) ...@@ -1243,11 +1242,19 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
if ((dsp_time_diff < 0) && if ((dsp_time_diff < 0) &&
(mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) {
snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " /* handle dsp counter wraparound without resync */
"resynchronize all streams\n", int tmp_diff = dsp_time_diff + PCXHR_DSP_TIME_MASK + 1;
snd_printdd("WARNING DSP timestamp old(%d) new(%d)",
mgr->dsp_time_last, dsp_time_new); mgr->dsp_time_last, dsp_time_new);
if (tmp_diff > 0 && tmp_diff <= (2*mgr->granularity)) {
snd_printdd("-> timestamp wraparound OK: "
"diff=%d\n", tmp_diff);
dsp_time_diff = tmp_diff;
} else {
snd_printdd("-> resynchronize all streams\n");
mgr->dsp_time_err++; mgr->dsp_time_err++;
} }
}
#ifdef CONFIG_SND_DEBUG_VERBOSE #ifdef CONFIG_SND_DEBUG_VERBOSE
if (dsp_time_diff == 0) if (dsp_time_diff == 0)
snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n",
......
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