[PATCH 2/4] ALSA: usb-audio: Use fixed control index for us16x08 mixer elements
From: Takashi Iwai
Date: Tue Oct 13 2026 - 08:54:32 EST
The callbacks for us16x08 mixer elements assume that id.index points
to the channel to be operated, and the assumption is correct for now.
However, since the kctls are added via snd_usb_mixer_add_control() and
it looks for the empty slot if the same control name is already
present, in theory, the index can become more than the channel numbers
(if a conflicting name really happens).
Since the mixer code in us16x08 doesn't need the search for an empty
slot but requires the fixed index, this patch changes slightly how to
assign the kcontrols. Now, a new argument is added to
snd_usb_mixer_add_list() in order to disable the empty slot search,
and use it in us16x08's add_new_ctl() helper function, instead.
Fixes: d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
---
sound/usb/mixer.c | 6 ++++--
sound/usb/mixer.h | 5 +++--
sound/usb/mixer_quirks.c | 2 +-
sound/usb/mixer_us16x08.c | 3 ++-
4 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 49a8a26f1a96..c2c24461c5a8 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -649,14 +649,16 @@ static int check_matrix_bitmap(unsigned char *bmap,
/*
* add an alsa control element
- * search and increment the index until an empty slot is found.
+ * when @look_for_empty is set, search and increment the index until an empty
+ * slot is found.
*
* if failed, give up and free the control instance.
*/
int snd_usb_mixer_add_list(struct usb_mixer_elem_list *list,
struct snd_kcontrol *kctl,
- bool is_std_info)
+ bool is_std_info,
+ bool look_for_empty)
{
struct usb_mixer_interface *mixer = list->mixer;
int err;
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 0d0a8b343756..c40f832852be 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -113,10 +113,11 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
int snd_usb_mixer_add_list(struct usb_mixer_elem_list *list,
struct snd_kcontrol *kctl,
- bool is_std_info);
+ bool is_std_info,
+ bool look_for_empty);
#define snd_usb_mixer_add_control(list, kctl) \
- snd_usb_mixer_add_list(list, kctl, true)
+ snd_usb_mixer_add_list(list, kctl, true, true)
void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
struct usb_mixer_interface *mixer,
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 1e266fdbbb8e..01210cc3fae7 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -167,7 +167,7 @@ static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer,
}
kctl->private_free = snd_usb_mixer_elem_free;
/* don't use snd_usb_mixer_add_control() here, this is a special list element */
- return snd_usb_mixer_add_list(list, kctl, false);
+ return snd_usb_mixer_add_list(list, kctl, false, true);
}
/*
diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c
index b447c4f7a161..18e8c2bd2678 100644
--- a/sound/usb/mixer_us16x08.c
+++ b/sound/usb/mixer_us16x08.c
@@ -1134,7 +1134,8 @@ static int add_new_ctl(struct usb_mixer_interface *mixer,
strscpy(kctl->id.name, name, sizeof(kctl->id.name));
- err = snd_usb_mixer_add_control(&elem->head, kctl);
+ /* look_for_empty=false, as we want the fixed id.index as channel */
+ err = snd_usb_mixer_add_list(&elem->head, kctl, true, false);
if (err < 0)
return err;
--
2.55.0