aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_hdmi.c
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@iki.fi>2010-08-03 06:28:58 -0400
committerTakashi Iwai <tiwai@suse.de>2010-08-03 06:53:36 -0400
commitea87d1c493aba9cf3f645eae0d6d9c0fd44d3189 (patch)
treeaade327fe17501e0bd52bf4ae1dc02f84ccbe26f /sound/pci/hda/patch_hdmi.c
parent32c168c892e2c6936c714d1653ba5e19e07d5c26 (diff)
ALSA: hda - Add support for HDMI HBR passthrough
Passing IEC 61937 encapsulated compressed audio at bitrates over 6.144 Mbps (i.e. more than a single 2-channel 16-bit 192kHz IEC 60958 link) over HDMI requires the use of HBR Audio Stream Packets instead of Audio Sample Packets. Enable HBR mode when the stream has 8 channels and the Non-PCM bit is set. If the audio converter is not connected to any HBR-capable pins, return -EINVAL in prepare(). Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_hdmi.c')
-rw-r--r--sound/pci/hda/patch_hdmi.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 2fc53961054e..8534792591fc 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -698,11 +698,48 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
698 * Callbacks 698 * Callbacks
699 */ 699 */
700 700
701static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, 701static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
702 u32 stream_tag, int format) 702 u32 stream_tag, int format)
703{ 703{
704 struct hdmi_spec *spec = codec->spec;
704 int tag; 705 int tag;
705 int fmt; 706 int fmt;
707 int pinctl;
708 int new_pinctl = 0;
709 int i;
710
711 for (i = 0; i < spec->num_pins; i++) {
712 if (spec->pin_cvt[i] != nid)
713 continue;
714 if (!(snd_hda_query_pin_caps(codec, spec->pin[i]) & AC_PINCAP_HBR))
715 continue;
716
717 pinctl = snd_hda_codec_read(codec, spec->pin[i], 0,
718 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
719
720 new_pinctl = pinctl & ~AC_PINCTL_EPT;
721 /* Non-PCM, 8 channels */
722 if ((format & 0x8000) && (format & 0x0f) == 7)
723 new_pinctl |= AC_PINCTL_EPT_HBR;
724 else
725 new_pinctl |= AC_PINCTL_EPT_NATIVE;
726
727 snd_printdd("hdmi_setup_stream: "
728 "NID=0x%x, %spinctl=0x%x\n",
729 spec->pin[i],
730 pinctl == new_pinctl ? "" : "new-",
731 new_pinctl);
732
733 if (pinctl != new_pinctl)
734 snd_hda_codec_write(codec, spec->pin[i], 0,
735 AC_VERB_SET_PIN_WIDGET_CONTROL,
736 new_pinctl);
737 }
738
739 if ((format & 0x8000) && (format & 0x0f) == 7 && !new_pinctl) {
740 snd_printdd("hdmi_setup_stream: HBR is not supported\n");
741 return -EINVAL;
742 }
706 743
707 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; 744 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
708 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); 745 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
@@ -722,6 +759,7 @@ static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
722 if (fmt != format) 759 if (fmt != format)
723 snd_hda_codec_write(codec, nid, 0, 760 snd_hda_codec_write(codec, nid, 0,
724 AC_VERB_SET_STREAM_FORMAT, format); 761 AC_VERB_SET_STREAM_FORMAT, format);
762 return 0;
725} 763}
726 764
727/* 765/*