diff options
Diffstat (limited to 'sound/pci/pcxhr/pcxhr_core.c')
-rw-r--r-- | sound/pci/pcxhr/pcxhr_core.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 304411c1fe4b..b33db1e006e7 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -504,6 +504,8 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = { [CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, [CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, [CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, +[CMD_GET_TIME_CODE] = { 0x060000, 5, RMH_SSIZE_FIXED }, +[CMD_MANAGE_SIGNAL] = { 0x0f0000, 0, RMH_SSIZE_FIXED }, }; #ifdef CONFIG_SND_DEBUG_VERBOSE @@ -533,6 +535,8 @@ static char* cmd_names[] = { [CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN", [CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT", [CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST", +[CMD_GET_TIME_CODE] = "CMD_GET_TIME_CODE", +[CMD_MANAGE_SIGNAL] = "CMD_MANAGE_SIGNAL", }; #endif @@ -1133,13 +1137,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[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->substream->number, - (long unsigned int)hw_sample_count, - (long unsigned int)(stream->timer_abs_periods + - stream->timer_period_frag + - mgr->granularity)); + hw_sample_count, + stream->timer_abs_periods + stream->timer_period_frag + + mgr->granularity); return hw_sample_count; } @@ -1243,10 +1246,18 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) if ((dsp_time_diff < 0) && (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { - snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " - "resynchronize all streams\n", + /* handle dsp counter wraparound without resync */ + 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_err++; + 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++; + } } #ifdef CONFIG_SND_DEBUG_VERBOSE if (dsp_time_diff == 0) |