aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2009-11-17 23:38:05 -0500
committerTakashi Iwai <tiwai@suse.de>2009-11-18 01:45:42 -0500
commit848de598eef9603d6f2c174f90fded4e63ac5e23 (patch)
tree9272ba0cc9dcf0c0e09286052abe29730148b503 /sound
parent978be6d711be237e0344eca21c3922ae88a240bc (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.c38
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
649static 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
650static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, 671static 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}