aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_hdmi.c
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@iki.fi>2013-11-03 10:15:00 -0500
committerTakashi Iwai <tiwai@suse.de>2013-11-04 04:10:28 -0500
commit611885bc963a2fa6fbd6141d149abbcce4dd8923 (patch)
treede9234e0003bd30e8848bee9a6e65172ba4f39b7 /sound/pci/hda/patch_hdmi.c
parentfce762ed9ffa0192d8f77f60d98f84b4cfbe4517 (diff)
ALSA: hda - hdmi: Disallow unsupported 2ch remapping on NVIDIA codecs
NVIDIA HDMI codecs do not seem to follow the Audio Sample Packet (ASP) channel mapping (as set by verb F32h per HDA specification 7.3.3.41) when playing back 2-channel audio (CEA CA 0x00). Basically this means that specifying swapped channels for stereo audio (FR,FL) does not take effect, and e.g. this command plays back on the wrong channel: speaker-test -c2 -Dhdmi:CARD=NVidia,DEV=0 -m FR,FL -s1 Multichannel audio is not affected. This issue has been confirmed to exist on codec 0x10de0015 by me and on 0x10de0040 by Juho Teperi. Disable 2ch FL/FR channel swapping on all NVIDIA HDMI codecs that use the standard HDA channel mapping system. Since this is a very minor functionality loss, we err on the side of disabling it for newer codecs as well until any future testing confirms that this issue has been fixed. Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi> Helped-by: Juho Teperi <juho.teperi@iki.fi> Cc: Aaron Plattner <aplattner@nvidia.com> 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.c86
1 files changed, 63 insertions, 23 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index d61cc2ab52af..c3e3537b3196 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2787,6 +2787,46 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
2787} 2787}
2788 2788
2789/* 2789/*
2790 * NVIDIA codecs ignore ASP mapping for 2ch - confirmed on:
2791 * - 0x10de0015
2792 * - 0x10de0040
2793 */
2794static int nvhdmi_chmap_cea_alloc_validate_get_type(struct cea_channel_speaker_allocation *cap,
2795 int channels)
2796{
2797 if (cap->ca_index == 0x00 && channels == 2)
2798 return SNDRV_CTL_TLVT_CHMAP_FIXED;
2799
2800 return hdmi_chmap_cea_alloc_validate_get_type(cap, channels);
2801}
2802
2803static int nvhdmi_chmap_validate(int ca, int chs, unsigned char *map)
2804{
2805 if (ca == 0x00 && (map[0] != SNDRV_CHMAP_FL || map[1] != SNDRV_CHMAP_FR))
2806 return -EINVAL;
2807
2808 return 0;
2809}
2810
2811static int patch_nvhdmi(struct hda_codec *codec)
2812{
2813 struct hdmi_spec *spec;
2814 int err;
2815
2816 err = patch_generic_hdmi(codec);
2817 if (err)
2818 return err;
2819
2820 spec = codec->spec;
2821
2822 spec->ops.chmap_cea_alloc_validate_get_type =
2823 nvhdmi_chmap_cea_alloc_validate_get_type;
2824 spec->ops.chmap_validate = nvhdmi_chmap_validate;
2825
2826 return 0;
2827}
2828
2829/*
2790 * ATI/AMD-specific implementations 2830 * ATI/AMD-specific implementations
2791 */ 2831 */
2792 2832
@@ -3167,30 +3207,30 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
3167{ .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, 3207{ .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
3168{ .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, 3208{ .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
3169{ .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x }, 3209{ .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x },
3170{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_generic_hdmi }, 3210{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi },
3171{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_generic_hdmi }, 3211{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi },
3172{ .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_generic_hdmi }, 3212{ .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi },
3173{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_generic_hdmi }, 3213{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi },
3174{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_generic_hdmi }, 3214{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi },
3175{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_generic_hdmi }, 3215{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi },
3176{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_generic_hdmi }, 3216{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi },
3177{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_generic_hdmi }, 3217{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi },
3178{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_generic_hdmi }, 3218{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi },
3179{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_generic_hdmi }, 3219{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_nvhdmi },
3180{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_generic_hdmi }, 3220{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_nvhdmi },
3181/* 17 is known to be absent */ 3221/* 17 is known to be absent */
3182{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_generic_hdmi }, 3222{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi },
3183{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_generic_hdmi }, 3223{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi },
3184{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_generic_hdmi }, 3224{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi },
3185{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_generic_hdmi }, 3225{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi },
3186{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_generic_hdmi }, 3226{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi },
3187{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_generic_hdmi }, 3227{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi },
3188{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_generic_hdmi }, 3228{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi },
3189{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, 3229{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi },
3190{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, 3230{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi },
3191{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, 3231{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi },
3192{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_generic_hdmi }, 3232{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_nvhdmi },
3193{ .id = 0x10de0060, .name = "GPU 60 HDMI/DP", .patch = patch_generic_hdmi }, 3233{ .id = 0x10de0060, .name = "GPU 60 HDMI/DP", .patch = patch_nvhdmi },
3194{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 3234{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
3195{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, 3235{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
3196{ .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, 3236{ .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi },