diff options
author | Wu Fengguang <fengguang.wu@intel.com> | 2009-11-17 23:38:06 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-11-18 01:46:19 -0500 |
commit | 5779191e0efd851fb0d54698c13cb4f5325caca6 (patch) | |
tree | f7bfcf5a1f8a4930ad148f6c5f076098743ea594 | |
parent | 848de598eef9603d6f2c174f90fded4e63ac5e23 (diff) |
ALSA: intelhdmi - sticky stream id and format
We tracked down the first-0.5s-hdmi-audio-samples-lost problem to the
AC_VERB_SET_CHANNEL_STREAMID command. It is suspected that many HDMI
sinks need some time to adapt to the new state.
The workaround is to avoid changing stream id/format whenever possible.
Proposed by David.
Signed-off-by: David Härdeman <david@hardeman.nu>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index abb056fde67a..8a1cf9d7e5ce 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -772,6 +772,31 @@ static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res) | |||
772 | * Callbacks | 772 | * Callbacks |
773 | */ | 773 | */ |
774 | 774 | ||
775 | static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | ||
776 | u32 stream_tag, int format) | ||
777 | { | ||
778 | int tag; | ||
779 | int fmt; | ||
780 | |||
781 | tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; | ||
782 | fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); | ||
783 | |||
784 | snd_printdd("hdmi_setup_stream: " | ||
785 | "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n", | ||
786 | nid, | ||
787 | tag == stream_tag ? "" : "new-", | ||
788 | stream_tag, | ||
789 | fmt == format ? "" : "new-", | ||
790 | format); | ||
791 | |||
792 | if (tag != stream_tag) | ||
793 | snd_hda_codec_write(codec, nid, 0, | ||
794 | AC_VERB_SET_CHANNEL_STREAMID, stream_tag << 4); | ||
795 | if (fmt != format) | ||
796 | snd_hda_codec_write(codec, nid, 0, | ||
797 | AC_VERB_SET_STREAM_FORMAT, format); | ||
798 | } | ||
799 | |||
775 | static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 800 | static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
776 | struct hda_codec *codec, | 801 | struct hda_codec *codec, |
777 | unsigned int stream_tag, | 802 | unsigned int stream_tag, |
@@ -783,7 +808,7 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
783 | 808 | ||
784 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); | 809 | hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); |
785 | 810 | ||
786 | snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format); | 811 | hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); |
787 | return 0; | 812 | return 0; |
788 | } | 813 | } |
789 | 814 | ||
@@ -791,7 +816,6 @@ static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
791 | struct hda_codec *codec, | 816 | struct hda_codec *codec, |
792 | struct snd_pcm_substream *substream) | 817 | struct snd_pcm_substream *substream) |
793 | { | 818 | { |
794 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); | ||
795 | return 0; | 819 | return 0; |
796 | } | 820 | } |
797 | 821 | ||