diff options
author | Wu Fengguang <fengguang.wu@intel.com> | 2009-11-17 23:38:05 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-11-18 01:45:42 -0500 |
commit | 848de598eef9603d6f2c174f90fded4e63ac5e23 (patch) | |
tree | 9272ba0cc9dcf0c0e09286052abe29730148b503 /sound | |
parent | 978be6d711be237e0344eca21c3922ae88a240bc (diff) |
ALSA: intelhdmi - sticky infoframe
Remember the active infoframe, so as to avoid stop/restart infoframe
transmission when switching between audio clips of the same format.
Proposed by Shang and David.
CC: Shane W <shane-alsa@csy.ca>
CC: David Härdeman <david@hardeman.nu>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_intelhdmi.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index d68dba9ac113..abb056fde67a 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -646,6 +646,27 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec, hda_nid_t nid, | |||
646 | hdmi_debug_channel_mapping(codec, nid); | 646 | hdmi_debug_channel_mapping(codec, nid); |
647 | } | 647 | } |
648 | 648 | ||
649 | static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, | ||
650 | struct hdmi_audio_infoframe *ai) | ||
651 | { | ||
652 | u8 *bytes = (u8 *)ai; | ||
653 | u8 val; | ||
654 | int i; | ||
655 | |||
656 | if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0) | ||
657 | != AC_DIPXMIT_BEST) | ||
658 | return false; | ||
659 | |||
660 | hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); | ||
661 | for (i = 0; i < sizeof(*ai); i++) { | ||
662 | val = snd_hda_codec_read(codec, pin_nid, 0, | ||
663 | AC_VERB_GET_HDMI_DIP_DATA, 0); | ||
664 | if (val != bytes[i]) | ||
665 | return false; | ||
666 | } | ||
667 | |||
668 | return true; | ||
669 | } | ||
649 | 670 | ||
650 | static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | 671 | static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, |
651 | struct snd_pcm_substream *substream) | 672 | struct snd_pcm_substream *substream) |
@@ -670,8 +691,11 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, | |||
670 | continue; | 691 | continue; |
671 | 692 | ||
672 | pin_nid = spec->pin[i]; | 693 | pin_nid = spec->pin[i]; |
673 | hdmi_fill_audio_infoframe(codec, pin_nid, &ai); | 694 | if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) { |
674 | hdmi_start_infoframe_trans(codec, pin_nid); | 695 | hdmi_stop_infoframe_trans(codec, pin_nid); |
696 | hdmi_fill_audio_infoframe(codec, pin_nid, &ai); | ||
697 | hdmi_start_infoframe_trans(codec, pin_nid); | ||
698 | } | ||
675 | } | 699 | } |
676 | } | 700 | } |
677 | 701 | ||
@@ -767,16 +791,6 @@ static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
767 | struct hda_codec *codec, | 791 | struct hda_codec *codec, |
768 | struct snd_pcm_substream *substream) | 792 | struct snd_pcm_substream *substream) |
769 | { | 793 | { |
770 | struct intel_hdmi_spec *spec = codec->spec; | ||
771 | int i; | ||
772 | |||
773 | for (i = 0; i < spec->num_pins; i++) { | ||
774 | if (spec->pin_cvt[i] != hinfo->nid) | ||
775 | continue; | ||
776 | |||
777 | hdmi_stop_infoframe_trans(codec, spec->pin[i]); | ||
778 | } | ||
779 | |||
780 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); | 794 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); |
781 | return 0; | 795 | return 0; |
782 | } | 796 | } |