[PATCH v3 1/3] ALSA: pcm: Add snd_pcm_add_named_chmap_ctls() for custom control names

From: Abel Vesa

Date: Thu Nov 05 2026 - 11:28:16 EST


From: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxxxxxxxx>

Add snd_pcm_add_named_chmap_ctls() to allow drivers to register channel
map controls with names other than the default "Playback Channel Map"
and "Capture Channel Map".

This is useful for cards exposing several channel map controls, such as
Qualcomm machine drivers with both HDMI/DP and WSA speaker backends,
where a distinct name makes it clear to userspace which backend the
control belongs to.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxxxxxxxx>
Signed-off-by: Abel Vesa <abel.vesa@xxxxxxxxxxxxxxxx>
---
include/sound/pcm.h | 6 ++++++
sound/core/pcm_lib.c | 48 ++++++++++++++++++++++++++++++++++++++----------
2 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 1cf511f8d880..58f5533a0315 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -1501,6 +1501,12 @@ extern const struct snd_pcm_chmap_elem snd_pcm_alt_chmaps[];
#define SND_PCM_CHMAP_MASK_246 (SND_PCM_CHMAP_MASK_24 | (1U << 6))
#define SND_PCM_CHMAP_MASK_2468 (SND_PCM_CHMAP_MASK_246 | (1U << 8))

+int snd_pcm_add_named_chmap_ctls(struct snd_pcm *pcm, int stream,
+ const char *name,
+ const struct snd_pcm_chmap_elem *chmap,
+ int max_channels,
+ unsigned long private_value,
+ struct snd_pcm_chmap **info_ret);
int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
const struct snd_pcm_chmap_elem *chmap,
int max_channels,
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index bb16738bb591..d7d63f5109f4 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -2586,9 +2586,11 @@ static void pcm_chmap_ctl_private_free(struct snd_kcontrol *kcontrol)
}

/**
- * snd_pcm_add_chmap_ctls - create channel-mapping control elements
+ * snd_pcm_add_named_chmap_ctls - create channel-mapping control elements
+ * with a custom name
* @pcm: the assigned PCM instance
* @stream: stream direction
+ * @name: the control element name
* @chmap: channel map elements (for query)
* @max_channels: the max number of channels for the stream
* @private_value: the value passed to each kcontrol's private_value field
@@ -2597,11 +2599,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,
- const struct snd_pcm_chmap_elem *chmap,
- int max_channels,
- unsigned long private_value,
- struct snd_pcm_chmap **info_ret)
+int snd_pcm_add_named_chmap_ctls(struct snd_pcm *pcm, int stream,
+ const char *name,
+ 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;
struct snd_kcontrol_new knew = {
@@ -2625,10 +2628,7 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
info->stream = stream;
info->chmap = chmap;
info->max_channels = max_channels;
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- knew.name = "Playback Channel Map";
- else
- knew.name = "Capture Channel Map";
+ knew.name = name;
knew.device = pcm->device;
knew.count = pcm->streams[stream].substream_count;
knew.private_value = private_value;
@@ -2646,4 +2646,32 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
*info_ret = info;
return 0;
}
+EXPORT_SYMBOL_GPL(snd_pcm_add_named_chmap_ctls);
+
+/**
+ * snd_pcm_add_chmap_ctls - create channel-mapping control elements
+ * @pcm: the assigned PCM instance
+ * @stream: stream direction
+ * @chmap: channel map elements (for query)
+ * @max_channels: the max number of channels for the stream
+ * @private_value: the value passed to each kcontrol's private_value field
+ * @info_ret: store struct snd_pcm_chmap instance if non-NULL
+ *
+ * Create channel-mapping control elements assigned to the given PCM stream(s),
+ * using the default "Playback Channel Map" / "Capture Channel Map" names.
+ * Return: Zero if successful, or a negative error value.
+ */
+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)
+{
+ const char *name = stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ "Playback Channel Map" : "Capture Channel Map";
+
+ return snd_pcm_add_named_chmap_ctls(pcm, stream, name, chmap,
+ max_channels, private_value,
+ info_ret);
+}
EXPORT_SYMBOL_GPL(snd_pcm_add_chmap_ctls);

--
2.54.0