[PATCH 10/28] ASoC: ops: Accept patterns in snd_soc_limit_volume
From: James Calligeros
Date: Sun Sep 20 2026 - 00:58:58 EST
From: Martin Povišer <povik+lin@xxxxxxxxxxx>
In snd_soc_limit_volume, instead of looking up a single control by name,
also understand wildcard-starting patterns like '* Amp Gain Volume' to
touch many controls at one.
Signed-off-by: Martin Povišer <povik+lin@xxxxxxxxxxx>
Signed-off-by: James Calligeros <jcalligeros99@xxxxxxxxx>
---
sound/soc/soc-ops.c | 51 ++++++++++++++++++++++---
1 file changed, 45 insertions(+), 6 deletions(-)
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index e572b05840b4..2f91ee7946bb 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -403,6 +403,29 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx);
+static bool soc_control_matches(struct snd_kcontrol *kctl,
+ const char *pattern)
+{
+ const char *name = kctl->id.name;
+
+ if (pattern[0] == '*') {
+ int namelen;
+ int patternlen;
+
+ pattern++;
+ if (pattern[0] == ' ')
+ pattern++;
+
+ namelen = strlen(name);
+ patternlen = strlen(pattern);
+
+ if (namelen > patternlen)
+ name += namelen - patternlen;
+ }
+
+ return !strcmp(name, pattern);
+}
+
static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl)
{
struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value;
@@ -445,31 +468,47 @@ static int soc_limit_volume(struct snd_kcontrol *kctl, int max)
}
/**
- * snd_soc_limit_volume - Set new limit to an existing volume control.
+ * snd_soc_limit_volume - Set new limit to existing volume controls.
*
* @card: where to look for the control
- * @name: Name of the control
+ * @name: name pattern
* @max: new maximum limit
*
- * Return 0 for success, else error.
+ * Finds controls matching the given name (which can be either a name
+ * verbatim, or a pattern starting with the wildcard '*') and sets
+ * a platform volume limit on them.
+ *
+ * Return number of matching controls on success, else error. At least
+ * one control needs to match the pattern.
*/
int snd_soc_limit_volume(struct snd_soc_card *card, const char *name, int max)
{
struct snd_kcontrol *kctl;
+ int hits = 0;
+ int ret;
/* Sanity check for name */
if (unlikely(!name))
return -EINVAL;
- kctl = snd_soc_card_get_kcontrol(card, name);
- if (!kctl) {
+ list_for_each_entry(kctl, &card->snd_card->controls, list) {
+ if (!soc_control_matches(kctl, name))
+ continue;
+
+ ret = soc_limit_volume(kctl, max);
+ if (ret < 0)
+ return ret;
+ hits++;
+ }
+
+ if (!hits) {
/* Some cards blindly add limits for multiple variants. */
dev_dbg(card->dev, "Volume limit for unknown control '%s'\n",
name);
return -EINVAL;
}
- return soc_limit_volume(kctl, max);
+ return hits;
}
EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
--
2.55.0