aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Anand <[email protected]>2017-01-25 04:27:53 +0530
committerTakashi Iwai <[email protected]>2017-01-25 14:24:19 +0100
commit232892fb14265b07b7a50061f36aaa5a6b81fb9d (patch)
tree263b59748121fd3c80ed237a00ced6c87185b1ca
parent5dab11d89777230b3ff38f19ee1b6fbba9688b23 (diff)
ALSA: x86: hdmi: continue playback even when display resolution changes
When the display resolution changes, the drm disables the display pipes due to which audio rendering stops. At this time, we need to ensure the existing audio pointers and buffers are cleared out so that the playback can restarted once the display pipe is enabled with a different N/CTS values Signed-off-by: Pierre-Louis Bossart <[email protected]> Signed-off-by: Jerome Anand <[email protected]> Signed-off-by: Takashi Iwai <[email protected]>
-rw-r--r--sound/x86/intel_hdmi_audio.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
index b69521aa2ed1..f30155446117 100644
--- a/sound/x86/intel_hdmi_audio.c
+++ b/sound/x86/intel_hdmi_audio.c
@@ -43,6 +43,7 @@ static DEFINE_MUTEX(had_mutex);
static int hdmi_card_index = SNDRV_DEFAULT_IDX1;
static char *hdmi_card_id = SNDRV_DEFAULT_STR1;
static struct snd_intelhad *had_data;
+static int underrun_count;
module_param_named(index, hdmi_card_index, int, 0444);
MODULE_PARM_DESC(index,
@@ -1052,6 +1053,7 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream)
intelhaddata = snd_pcm_substream_chip(substream);
had_stream = intelhaddata->private_data;
runtime = substream->runtime;
+ underrun_count = 0;
pm_runtime_get(intelhaddata->dev);
@@ -1445,10 +1447,23 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer(
buf_id = intelhaddata->curr_buf % 4;
had_read_register(AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), &t);
- if (t == 0) {
- pr_debug("discovered buffer done for buf %d\n", buf_id);
- /* had_process_buffer_done(intelhaddata); */
+
+ if ((t == 0) || (t == ((u32)-1L))) {
+ underrun_count++;
+ pr_debug("discovered buffer done for buf %d, count = %d\n",
+ buf_id, underrun_count);
+
+ if (underrun_count > (HAD_MIN_PERIODS/2)) {
+ pr_debug("assume audio_codec_reset, underrun = %d - do xrun\n",
+ underrun_count);
+ underrun_count = 0;
+ return SNDRV_PCM_POS_XRUN;
+ }
+ } else {
+ /* Reset Counter */
+ underrun_count = 0;
}
+
t = intelhaddata->buf_info[buf_id].buf_size - t;
if (intelhaddata->stream_info.buffer_rendered)