diff options
author | Anssi Hannula <anssi.hannula@iki.fi> | 2013-10-24 14:10:37 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-10-24 16:54:56 -0400 |
commit | 461cf6b39dded3ddb15a2300a534aba039870e5f (patch) | |
tree | 1263b6835a441f8ff53016eb91ecc2b01b418781 /sound/pci/hda/patch_hdmi.c | |
parent | 89250f84644676c1ed6a09acef1033e14596a402 (diff) |
ALSA: hda - hdmi: Add HBR bitstreaming support for ATI/AMD HDMI codecs
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
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.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 0307ae87bef3..f6a97607e522 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -2799,6 +2799,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) | |||
2799 | #define ATI_VERB_SET_MULTICHANNEL_23 0x778 | 2799 | #define ATI_VERB_SET_MULTICHANNEL_23 0x778 |
2800 | #define ATI_VERB_SET_MULTICHANNEL_45 0x779 | 2800 | #define ATI_VERB_SET_MULTICHANNEL_45 0x779 |
2801 | #define ATI_VERB_SET_MULTICHANNEL_67 0x77a | 2801 | #define ATI_VERB_SET_MULTICHANNEL_67 0x77a |
2802 | #define ATI_VERB_SET_HBR_CONTROL 0x77c | ||
2802 | #define ATI_VERB_SET_MULTICHANNEL_1 0x785 | 2803 | #define ATI_VERB_SET_MULTICHANNEL_1 0x785 |
2803 | #define ATI_VERB_SET_MULTICHANNEL_3 0x786 | 2804 | #define ATI_VERB_SET_MULTICHANNEL_3 0x786 |
2804 | #define ATI_VERB_SET_MULTICHANNEL_5 0x787 | 2805 | #define ATI_VERB_SET_MULTICHANNEL_5 0x787 |
@@ -2810,6 +2811,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) | |||
2810 | #define ATI_VERB_GET_MULTICHANNEL_23 0xf78 | 2811 | #define ATI_VERB_GET_MULTICHANNEL_23 0xf78 |
2811 | #define ATI_VERB_GET_MULTICHANNEL_45 0xf79 | 2812 | #define ATI_VERB_GET_MULTICHANNEL_45 0xf79 |
2812 | #define ATI_VERB_GET_MULTICHANNEL_67 0xf7a | 2813 | #define ATI_VERB_GET_MULTICHANNEL_67 0xf7a |
2814 | #define ATI_VERB_GET_HBR_CONTROL 0xf7c | ||
2813 | #define ATI_VERB_GET_MULTICHANNEL_1 0xf85 | 2815 | #define ATI_VERB_GET_MULTICHANNEL_1 0xf85 |
2814 | #define ATI_VERB_GET_MULTICHANNEL_3 0xf86 | 2816 | #define ATI_VERB_GET_MULTICHANNEL_3 0xf86 |
2815 | #define ATI_VERB_GET_MULTICHANNEL_5 0xf87 | 2817 | #define ATI_VERB_GET_MULTICHANNEL_5 0xf87 |
@@ -2821,6 +2823,9 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) | |||
2821 | #define ATI_MULTICHANNEL_MODE_PAIRED 0 | 2823 | #define ATI_MULTICHANNEL_MODE_PAIRED 0 |
2822 | #define ATI_MULTICHANNEL_MODE_SINGLE 1 | 2824 | #define ATI_MULTICHANNEL_MODE_SINGLE 1 |
2823 | 2825 | ||
2826 | #define ATI_HBR_CAPABLE 0x01 | ||
2827 | #define ATI_HBR_ENABLE 0x10 | ||
2828 | |||
2824 | static int atihdmi_pin_get_eld(struct hda_codec *codec, hda_nid_t nid, | 2829 | static int atihdmi_pin_get_eld(struct hda_codec *codec, hda_nid_t nid, |
2825 | unsigned char *buf, int *eld_size) | 2830 | unsigned char *buf, int *eld_size) |
2826 | { | 2831 | { |
@@ -3015,6 +3020,35 @@ static void atihdmi_paired_cea_alloc_to_tlv_chmap(struct cea_channel_speaker_all | |||
3015 | WARN_ON(count != channels); | 3020 | WARN_ON(count != channels); |
3016 | } | 3021 | } |
3017 | 3022 | ||
3023 | static int atihdmi_pin_hbr_setup(struct hda_codec *codec, hda_nid_t pin_nid, | ||
3024 | bool hbr) | ||
3025 | { | ||
3026 | int hbr_ctl, hbr_ctl_new; | ||
3027 | |||
3028 | hbr_ctl = snd_hda_codec_read(codec, pin_nid, 0, ATI_VERB_GET_HBR_CONTROL, 0); | ||
3029 | if (hbr_ctl & ATI_HBR_CAPABLE) { | ||
3030 | if (hbr) | ||
3031 | hbr_ctl_new = hbr_ctl | ATI_HBR_ENABLE; | ||
3032 | else | ||
3033 | hbr_ctl_new = hbr_ctl & ~ATI_HBR_ENABLE; | ||
3034 | |||
3035 | snd_printdd("atihdmi_pin_hbr_setup: " | ||
3036 | "NID=0x%x, %shbr-ctl=0x%x\n", | ||
3037 | pin_nid, | ||
3038 | hbr_ctl == hbr_ctl_new ? "" : "new-", | ||
3039 | hbr_ctl_new); | ||
3040 | |||
3041 | if (hbr_ctl != hbr_ctl_new) | ||
3042 | snd_hda_codec_write(codec, pin_nid, 0, | ||
3043 | ATI_VERB_SET_HBR_CONTROL, | ||
3044 | hbr_ctl_new); | ||
3045 | |||
3046 | } else if (hbr) | ||
3047 | return -EINVAL; | ||
3048 | |||
3049 | return 0; | ||
3050 | } | ||
3051 | |||
3018 | static int atihdmi_init(struct hda_codec *codec) | 3052 | static int atihdmi_init(struct hda_codec *codec) |
3019 | { | 3053 | { |
3020 | struct hdmi_spec *spec = codec->spec; | 3054 | struct hdmi_spec *spec = codec->spec; |
@@ -3060,6 +3094,7 @@ static int patch_atihdmi(struct hda_codec *codec) | |||
3060 | spec->ops.pin_get_slot_channel = atihdmi_pin_get_slot_channel; | 3094 | spec->ops.pin_get_slot_channel = atihdmi_pin_get_slot_channel; |
3061 | spec->ops.pin_set_slot_channel = atihdmi_pin_set_slot_channel; | 3095 | spec->ops.pin_set_slot_channel = atihdmi_pin_set_slot_channel; |
3062 | spec->ops.pin_setup_infoframe = atihdmi_pin_setup_infoframe; | 3096 | spec->ops.pin_setup_infoframe = atihdmi_pin_setup_infoframe; |
3097 | spec->ops.pin_hbr_setup = atihdmi_pin_hbr_setup; | ||
3063 | 3098 | ||
3064 | if (!has_amd_full_remap_support(codec)) { | 3099 | if (!has_amd_full_remap_support(codec)) { |
3065 | /* override to ATI/AMD-specific versions with pairwise mapping */ | 3100 | /* override to ATI/AMD-specific versions with pairwise mapping */ |