ATI/AMD HDMI codecs do not include standard HDA HDMI HBR support (which is required for bitstreaming DTS-HD and Dolby TrueHD), instead they have custom verbs for checking and enabling it.
Add support for the ATI/AMD HDMI HBR verbs.
The specification is available at: http://www.x.org/docs/AMD/AMD_HDA_verbs_v2.pdf
v2: adapted to hdmi_ops infrastructure
Signed-off-by: Anssi Hannula anssi.hannula@iki.fi Tested-by: Peter Frühberger fritsch@xbmc.org # v1 --- sound/pci/hda/patch_hdmi.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 75ba933..2c45591 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -2800,6 +2800,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) #define ATI_VERB_SET_MULTICHANNEL_23 0x778 #define ATI_VERB_SET_MULTICHANNEL_45 0x779 #define ATI_VERB_SET_MULTICHANNEL_67 0x77a +#define ATI_VERB_SET_HBR_CONTROL 0x77c #define ATI_VERB_SET_MULTICHANNEL_1 0x785 #define ATI_VERB_SET_MULTICHANNEL_3 0x786 #define ATI_VERB_SET_MULTICHANNEL_5 0x787 @@ -2811,6 +2812,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) #define ATI_VERB_GET_MULTICHANNEL_23 0xf78 #define ATI_VERB_GET_MULTICHANNEL_45 0xf79 #define ATI_VERB_GET_MULTICHANNEL_67 0xf7a +#define ATI_VERB_GET_HBR_CONTROL 0xf7c #define ATI_VERB_GET_MULTICHANNEL_1 0xf85 #define ATI_VERB_GET_MULTICHANNEL_3 0xf86 #define ATI_VERB_GET_MULTICHANNEL_5 0xf87 @@ -2822,6 +2824,9 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) #define ATI_MULTICHANNEL_MODE_PAIRED 0 #define ATI_MULTICHANNEL_MODE_SINGLE 1
+#define ATI_HBR_CAPABLE 0x01 +#define ATI_HBR_ENABLE 0x10 + static int atihdmi_pin_get_eld(struct hda_codec *codec, hda_nid_t nid, unsigned char *buf, int *eld_size) { @@ -3016,6 +3021,35 @@ static void atihdmi_paired_cea_alloc_to_tlv_chmap(struct cea_channel_speaker_all WARN_ON(count != channels); }
+static int atihdmi_pin_hbr_setup(struct hda_codec *codec, hda_nid_t pin_nid, + bool hbr) +{ + int hbr_ctl, hbr_ctl_new; + + hbr_ctl = snd_hda_codec_read(codec, pin_nid, 0, ATI_VERB_GET_HBR_CONTROL, 0); + if (hbr_ctl & ATI_HBR_CAPABLE) { + if (hbr) + hbr_ctl_new = hbr_ctl | ATI_HBR_ENABLE; + else + hbr_ctl_new = hbr_ctl & ~ATI_HBR_ENABLE; + + snd_printdd("atihdmi_pin_hbr_setup: " + "NID=0x%x, %shbr-ctl=0x%x\n", + pin_nid, + hbr_ctl == hbr_ctl_new ? "" : "new-", + hbr_ctl_new); + + if (hbr_ctl != hbr_ctl_new) + snd_hda_codec_write(codec, pin_nid, 0, + ATI_VERB_SET_HBR_CONTROL, + hbr_ctl_new); + + } else if (hbr) + return -EINVAL; + + return 0; +} + static int atihdmi_init(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; @@ -3061,6 +3095,7 @@ static int patch_atihdmi(struct hda_codec *codec) spec->ops.pin_get_slot_channel = atihdmi_pin_get_slot_channel; spec->ops.pin_set_slot_channel = atihdmi_pin_set_slot_channel; spec->ops.pin_setup_infoframe = atihdmi_pin_setup_infoframe; + spec->ops.pin_hbr_setup = atihdmi_pin_hbr_setup;
if (!has_amd_full_remap_support(codec)) { /* override to ATI/AMD-specific versions with pairwise mapping */