[alsa-devel] [PATCH] ALSA: hda - hdmi: Disallow unsupported 2ch remapping on NVIDIA codecs

Takashi Iwai tiwai at suse.de
Mon Nov 4 10:12:33 CET 2013


At Sun,  3 Nov 2013 17:15:00 +0200,
Anssi Hannula wrote:
> 
> 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 at iki.fi>
> Helped-by: Juho Teperi <juho.teperi at iki.fi>
> Cc: Aaron Plattner <aplattner at nvidia.com>

Thanks, applied.


Takashi


> ---
>  sound/pci/hda/patch_hdmi.c | 86 +++++++++++++++++++++++++++++++++-------------
>  1 file 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)
>  }
>  
>  /*
> + * NVIDIA codecs ignore ASP mapping for 2ch - confirmed on:
> + * - 0x10de0015
> + * - 0x10de0040
> + */
> +static int nvhdmi_chmap_cea_alloc_validate_get_type(struct cea_channel_speaker_allocation *cap,
> +						    int channels)
> +{
> +	if (cap->ca_index == 0x00 && channels == 2)
> +		return SNDRV_CTL_TLVT_CHMAP_FIXED;
> +
> +	return hdmi_chmap_cea_alloc_validate_get_type(cap, channels);
> +}
> +
> +static int nvhdmi_chmap_validate(int ca, int chs, unsigned char *map)
> +{
> +	if (ca == 0x00 && (map[0] != SNDRV_CHMAP_FL || map[1] != SNDRV_CHMAP_FR))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int patch_nvhdmi(struct hda_codec *codec)
> +{
> +	struct hdmi_spec *spec;
> +	int err;
> +
> +	err = patch_generic_hdmi(codec);
> +	if (err)
> +		return err;
> +
> +	spec = codec->spec;
> +
> +	spec->ops.chmap_cea_alloc_validate_get_type =
> +		nvhdmi_chmap_cea_alloc_validate_get_type;
> +	spec->ops.chmap_validate = nvhdmi_chmap_validate;
> +
> +	return 0;
> +}
> +
> +/*
>   * ATI/AMD-specific implementations
>   */
>  
> @@ -3167,30 +3207,30 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
>  { .id = 0x10de0005, .name = "MCP77/78 HDMI",	.patch = patch_nvhdmi_8ch_7x },
>  { .id = 0x10de0006, .name = "MCP77/78 HDMI",	.patch = patch_nvhdmi_8ch_7x },
>  { .id = 0x10de0007, .name = "MCP79/7A HDMI",	.patch = patch_nvhdmi_8ch_7x },
> -{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de000c, .name = "MCP89 HDMI",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP",	.patch = patch_generic_hdmi },
> +{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de000c, .name = "MCP89 HDMI",	.patch = patch_nvhdmi },
> +{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP",	.patch = patch_nvhdmi },
>  /* 17 is known to be absent */
> -{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP",	.patch = patch_generic_hdmi },
> -{ .id = 0x10de0060, .name = "GPU 60 HDMI/DP",	.patch = patch_generic_hdmi },
> +{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP",	.patch = patch_nvhdmi },
> +{ .id = 0x10de0060, .name = "GPU 60 HDMI/DP",	.patch = patch_nvhdmi },
>  { .id = 0x10de0067, .name = "MCP67 HDMI",	.patch = patch_nvhdmi_2ch },
>  { .id = 0x10de8001, .name = "MCP73 HDMI",	.patch = patch_nvhdmi_2ch },
>  { .id = 0x11069f80, .name = "VX900 HDMI/DP",	.patch = patch_via_hdmi },
> -- 
> 1.8.1.5
> 


More information about the Alsa-devel mailing list