From be0c223671c49c7dc05eabab709dc7c4e27cfa69 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Sun, 17 Apr 2022 04:37:48 +0000 Subject: [PATCH] HACK: ALSA: Assign internal PCM chmap/ELD/IEC958 kctls to device 0 On SoC sound devices utilizing codec2codec DAI links with a HDMI codec the kctls for chmap, ELD, IEC958 are currently created using the internal PCM device numbers. This causes userspace to not see the actual channel mapping. Affected devices include LibreTech LePotato and Wetek Play 2. The proper fix would be not create these kctls for internal PCMs and instead create them for the real userspace-visible PCMs, somehow forwarding the controls between the HDMI codec and the real PCM. As a workaround, simply use device=0 for all channel map controls and SoC HDMI codec controls for internal PCM devices. Signed-off-by: Anssi Hannula --- sound/core/pcm_lib.c | 5 ++++- sound/soc/codecs/hdmi-codec.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 1fc7c50ffa625b..9b40289c1fd197 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -2514,7 +2514,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, knew.name = "Playback Channel Map"; else knew.name = "Capture Channel Map"; - knew.device = pcm->device; + if (pcm->internal && pcm->device) + dev_info(pcm->card->dev, "workaround active: internal PCM chmap controls mapped to device 0\n"); + else + knew.device = pcm->device; knew.count = pcm->streams[stream].substream_count; knew.private_value = private_value; info->kctl = snd_ctl_new1(&knew, info); diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index b07607a9ecea4e..bcb018ea690b69 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -802,7 +802,8 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, if (!kctl) return -ENOMEM; - kctl->id.device = rtd->pcm->device; + if (!rtd->pcm->internal) + kctl->id.device = rtd->pcm->device; ret = snd_ctl_add(rtd->card->snd_card, kctl); if (ret < 0) return ret;