[PATCH 0/3] ASoC: hdmi-codec: add component name prefix to controls
While adding audio support to two instances of Display port on x13s, hdmi-codec failed to add controls as two codec instances were trying to add controls with same name.
snd-sc8280xp sound: control 3:16:0:IEC958 Playback Mask:0 is already present snd-sc8280xp sound: control 3:16:0:Playback Channel Map:0 is already present hdmi-audio-codec hdmi-audio-codec.4.auto: ASoC: error at snd_soc_pcm_dai_new on i2s-hifi: -16
To fix this issue, I have added a new api snd_pcm_add_chmap_ctls_with_prefix() to allow to pass asoc component name prefix, which should provide a unique control names. We can also make snd_pcm_add_chmap_ctls() take prefix argument to do the same this.
Srinivas Kandagatla (3): ALSA: pcm: add snd_pcm_add_chmap_ctls_with_prefix ASoC: hdmi-codec: use snd_pcm_add_chmap_ctls_with_prefix to add controls ASoC: hdmi-codec: use snd_soc_cnew to add controls
include/sound/pcm.h | 7 +++++++ sound/core/pcm_lib.c | 30 ++++++++++++++++++++++++++++-- sound/soc/codecs/hdmi-codec.c | 10 ++++++---- 3 files changed, 41 insertions(+), 6 deletions(-)
On Qualcomm SoC which has multiple Display Port controllers, using snd_pcm_add_chmap_ctls() to add chmap controls from every ASoC hdmi codec instance for a give card fails while adding second instance as the control with same name "Playback Channel Map" already exists from the first instance.
Fix this by adding a new api wrapper to pass ASoC component name prefix to avoid such duplicate control naming.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- We can also make snd_pcm_add_chmap_ctls to take prefix argument and avoid adding this new api, but that would touch lots of drivers.
include/sound/pcm.h | 7 +++++++ sound/core/pcm_lib.c | 30 ++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 27040b472a4f..39efd25b53e3 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -1528,6 +1528,13 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, unsigned long private_value, struct snd_pcm_chmap **info_ret);
+int snd_pcm_add_chmap_ctls_with_prefix(struct snd_pcm *pcm, int stream, + const struct snd_pcm_chmap_elem *chmap, + int max_channels, + unsigned long private_value, + struct snd_pcm_chmap **info_ret, + const char *prefix); + /** * pcm_format_to_bits - Strong-typed conversion of pcm_format to bitwise * @pcm_format: PCM format diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 8b6aeb8a78f7..ed75dd007425 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -2483,11 +2483,12 @@ static void pcm_chmap_ctl_private_free(struct snd_kcontrol *kcontrol) * Create channel-mapping control elements assigned to the given PCM stream(s). * Return: Zero if successful, or a negative error value. */ -int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, +int snd_pcm_add_chmap_ctls_with_prefix(struct snd_pcm *pcm, int stream, const struct snd_pcm_chmap_elem *chmap, int max_channels, unsigned long private_value, - struct snd_pcm_chmap **info_ret) + struct snd_pcm_chmap **info_ret, + const char *prefix) { struct snd_pcm_chmap *info; struct snd_kcontrol_new knew = { @@ -2499,6 +2500,7 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, .get = pcm_chmap_ctl_get, .tlv.c = pcm_chmap_ctl_tlv, }; + char *name = NULL; int err;
if (WARN_ON(pcm->streams[stream].chmap_kctl)) @@ -2514,10 +2516,21 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, knew.name = "Playback Channel Map"; else knew.name = "Capture Channel Map"; + + if (prefix) { + name = kasprintf(GFP_KERNEL, "%s %s", prefix, knew.name); + if (!name) { + kfree(info); + return -ENOMEM; + } + knew.name = name; + } + knew.device = pcm->device; knew.count = pcm->streams[stream].substream_count; knew.private_value = private_value; info->kctl = snd_ctl_new1(&knew, info); + kfree(name); if (!info->kctl) { kfree(info); return -ENOMEM; @@ -2530,5 +2543,18 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, if (info_ret) *info_ret = info; return 0; + +} +EXPORT_SYMBOL_GPL(snd_pcm_add_chmap_ctls_with_prefix); + +int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, + const struct snd_pcm_chmap_elem *chmap, + int max_channels, + unsigned long private_value, + struct snd_pcm_chmap **info_ret) +{ + return snd_pcm_add_chmap_ctls_with_prefix(pcm, stream, chmap, + max_channels, private_value, + info_ret, NULL); } EXPORT_SYMBOL_GPL(snd_pcm_add_chmap_ctls);
On Fri, 05 May 2023 18:55:12 +0200, Srinivas Kandagatla wrote:
On Qualcomm SoC which has multiple Display Port controllers, using snd_pcm_add_chmap_ctls() to add chmap controls from every ASoC hdmi codec instance for a give card fails while adding second instance as the control with same name "Playback Channel Map" already exists from the first instance.
Fix this by adding a new api wrapper to pass ASoC component name prefix to avoid such duplicate control naming.
It implies that you have conflicting PCM objects with the same PCM device number from the same card. How can it be?
Takashi
On 06/05/2023 06:57, Takashi Iwai wrote:
On Fri, 05 May 2023 18:55:12 +0200, Srinivas Kandagatla wrote:
On Qualcomm SoC which has multiple Display Port controllers, using snd_pcm_add_chmap_ctls() to add chmap controls from every ASoC hdmi codec instance for a give card fails while adding second instance as the control with same name "Playback Channel Map" already exists from the first instance.
Fix this by adding a new api wrapper to pass ASoC component name prefix to avoid such duplicate control naming.
It implies that you have conflicting PCM objects with the same PCM device number from the same card. How can it be?
Thanks for the inputs, this is only issue with my local changes, Sorry for the noise, Please ignore this series.
I had some local changes to debug an issue around pcm device numbering with backend dailinks from device tree and frontend dailinks from tplg. Will start a new thread to discuss this issue.
thanks, srini
Takashi
If there are multiple instances of this codec in a sound card snd_pcm_add_chmap_ctls() will fail with below error because of duplicate control names.
snd-sc8280xp sound: control 3:16:0:Playback Channel Map:0 is already present hdmi-audio-codec hdmi-audio-codec.4.auto: ASoC: error at snd_soc_pcm_dai_new on i2s-hifi: -16
Fix this by using snd_pcm_add_chmap_ctls_with_prefix along wth component name prefix.
This issue is noticed on x13s laptop which has multiple instances of Displayport.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/hdmi-codec.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 6d980fbc4207..8c54cddf86b6 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -782,9 +782,10 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, unsigned int i; int ret;
- ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK, - NULL, drv->playback.channels_max, 0, - &hcp->chmap_info); + ret = snd_pcm_add_chmap_ctls_with_prefix(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK, + NULL, drv->playback.channels_max, 0, + &hcp->chmap_info, + dai->component->name_prefix); if (ret < 0) return ret;
If there are multiple instances of this codec in a sound card using snd_ctl_new1 will fail with below error because of duplicate control names.
snd-sc8280xp sound: control 3:16:0:IEC958 Playback Mask:0 is already present hdmi-audio-codec hdmi-audio-codec.4.auto: ASoC: error at snd_soc_pcm_dai_new on i2s-hifi: -16
Fix this by using snd_soc_cnew along with component name prefix to avoid this duplication.
This issue is noticed on x13s laptop which has multiple instances of Displayport.
Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org --- sound/soc/codecs/hdmi-codec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 8c54cddf86b6..48d1eef9c806 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -801,7 +801,8 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, struct snd_kcontrol *kctl;
/* add ELD ctl with the device number corresponding to the PCM stream */ - kctl = snd_ctl_new1(&hdmi_codec_controls[i], dai->component); + kctl = snd_soc_cnew(&hdmi_codec_controls[i], dai->component, NULL, + dai->component->name_prefix); if (!kctl) return -ENOMEM;
participants (2)
-
Srinivas Kandagatla
-
Takashi Iwai