aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@iki.fi>2013-11-10 13:56:11 -0500
committerTakashi Iwai <tiwai@suse.de>2013-11-11 11:08:04 -0500
commita5666824ce79f4e63e017c25f6e1d9b6e6f267b2 (patch)
treee99df9cb2045eba760369eed35ed86098bd310d8
parent13122e6ebf24d9f676d8a40edc2e9a265e89b628 (diff)
ALSA: hda - hdmi: Skip out-of-range latency values in AMD ELD generator
The ATI/AMD video/audio latencies are specified in apparent HDMI VSDB format. In this format values above 251 are not valid (or stream component is not supported - 255), but no checking is performed since this was not mentioned in the AMD HDA verbs specification. Check that the latencies are valid before using them, and add a comment describing the formats. Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_eld.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index e8c55f5a34ff..9b697a28cf53 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -768,13 +768,28 @@ int snd_hdmi_get_eld_ati(struct hda_codec *codec, hda_nid_t nid,
768 return -EINVAL; 768 return -EINVAL;
769 } 769 }
770 770
771 /*
772 * HDMI VSDB latency format:
773 * separately for both audio and video:
774 * 0 field not valid or unknown latency
775 * [1..251] msecs = (x-1)*2 (max 500ms with x = 251 = 0xfb)
776 * 255 audio/video not supported
777 *
778 * HDA latency format:
779 * single value indicating video latency relative to audio:
780 * 0 unknown or 0ms
781 * [1..250] msecs = x*2 (max 500ms with x = 250 = 0xfa)
782 * [251..255] reserved
783 */
771 aud_synch = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_AUDIO_VIDEO_DELAY, 0); 784 aud_synch = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_AUDIO_VIDEO_DELAY, 0);
772 if ((aud_synch & ATI_DELAY_VIDEO_LATENCY) && (aud_synch & ATI_DELAY_AUDIO_LATENCY)) { 785 if ((aud_synch & ATI_DELAY_VIDEO_LATENCY) && (aud_synch & ATI_DELAY_AUDIO_LATENCY)) {
773 int video_latency = (aud_synch & ATI_DELAY_VIDEO_LATENCY) - 1; 786 int video_latency_hdmi = (aud_synch & ATI_DELAY_VIDEO_LATENCY);
774 int audio_latency = ((aud_synch & ATI_DELAY_AUDIO_LATENCY) >> 8) - 1; 787 int audio_latency_hdmi = (aud_synch & ATI_DELAY_AUDIO_LATENCY) >> 8;
775 788
776 if (video_latency > audio_latency) 789 if (video_latency_hdmi <= 0xfb && audio_latency_hdmi <= 0xfb &&
777 buf[6] = min(video_latency - audio_latency, 0xfa); 790 video_latency_hdmi > audio_latency_hdmi)
791 buf[6] = video_latency_hdmi - audio_latency_hdmi;
792 /* else unknown/invalid or 0ms or video ahead of audio, so use zero */
778 } 793 }
779 794
780 /* Baseline length */ 795 /* Baseline length */