From: Takashi Iwai <tiwai@suse.de>
To: linux-sound@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH v3 2/3] ALSA: usb-audio: Fix UAC2 mixer unit request handling
Date: Wed, 30 Sep 2026 17:53:51 +0200 [thread overview]
Message-ID: <20260930155356.348608-3-tiwai@suse.de> (raw)
In-Reply-To: <20260930155356.348608-1-tiwai@suse.de>
For a request for a Mixer Unit on UAC2 (also UAC3), the wValue is
different from UAC1 and an incompatible value must be passed.
Namely, UAC1 takes a word consisting of 1-based input channel in the
high byte and 1-based output channel in the low byte.
Meanwhile, UAC2/3 takes UAC2_MU_MIXER in the high byte and a MCN
(0-based bit position of input/output channels) in the low byte.
The current driver implementation blindly assumes the UAC1 way, hence
it would cause a firmware error.
This patch attempts to implement the conversion to UAC2 MCN at
get_ctl_value_v2() and snd_usb_mixer_set_ctl_value() for mixer units.
At the points above, the old wValue containing ICN and OCN is
converted to the corresponding MCN, and it's used as the proper
wValue.
Reported-by: Zipdox <zipdox@zipdox.net>
Closes: https://lore.kernel.org/d46fcac6-bd7e-4fc4-95e1-4e8d39f92ad3@zipdox.net
Fixes: 23caaf19b11e ("ALSA: usb-mixer: Add support for Audio Class v2.0")
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
v2->v3: no change
sound/usb/mixer.c | 23 +++++++++++++++++++++++
sound/usb/mixer.h | 2 ++
2 files changed, 25 insertions(+)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index ddfd7e01a3ef..a8bdd1696a20 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -335,6 +335,17 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
return -EINVAL;
}
+/* convert the given UAC1 wValue (ICN|OCN) to UAC2 MCN */
+static unsigned char to_mcn(const struct usb_mixer_elem_info *cval,
+ unsigned int validx)
+{
+ unsigned char m = (validx >> 8) & 0xff; /* 1-based input channel */
+ unsigned char v = validx & 0xff; /* 1-based output channel */
+
+ /* num_inputs * num_outputs is guaranteed to be < 256 */
+ return (m - 1) * cval->num_outputs + (v - 1);
+}
+
static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
int validx, int *value_ret)
{
@@ -347,6 +358,10 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
val_size = uac2_ctl_value_size(cval->val_type);
+ /* correct wValue for UAC2 mixer control with MCN */
+ if (cval->v2_mixer)
+ validx = (UAC2_MU_MIXER << 8) | to_mcn(cval, validx);
+
if (request == UAC_GET_CUR) {
bRequest = UAC2_CS_CUR;
size = val_size;
@@ -478,6 +493,10 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
}
request = UAC2_CS_CUR;
+
+ /* correct wValue for UAC2 mixer control with MCN */
+ if (cval->v2_mixer)
+ validx = (UAC2_MU_MIXER << 8) | to_mcn(cval, validx);
}
value_set = convert_bytes_value(cval, value_set);
@@ -2345,6 +2364,10 @@ static void build_mixer_unit_ctl(struct mixer_build *state,
snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid);
cval->control = in_ch + 1; /* based on 1 */
+ if (state->mixer->protocol == UAC_VERSION_2 ||
+ state->mixer->protocol == UAC_VERSION_3)
+ cval->v2_mixer = true;
+ cval->num_outputs = num_outs;
cval->val_type = USB_MIXER_S16;
for (i = 0; i < num_outs; i++) {
__u8 *c = uac_mixer_unit_bmControls(desc, state->mixer->protocol);
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 037b446d8b6f..cf45c39cbccc 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -97,6 +97,8 @@ struct usb_mixer_elem_info {
u8 initialized;
u8 min_mute;
u8 get_cur_broken;
+ u8 num_outputs;
+ bool v2_mixer;
void *private_data;
};
--
2.55.0
next prev parent reply other threads:[~2026-09-30 15:54 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-30 15:53 [PATCH v3 0/3] ALSA: usb-audio: fix for UAC2 mixer unit handling Takashi Iwai
2026-09-30 15:53 ` [PATCH v3 1/3] ALSA: usb-audio: Check mixer matrix size for UAC2/3 at parsing Takashi Iwai
2026-09-30 15:53 ` Takashi Iwai [this message]
2026-09-30 15:53 ` [PATCH v3 3/3] ALSA: usb-audio: Optimize min/max/res parse for UAC2 Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260930155356.348608-3-tiwai@suse.de \
--to=tiwai@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®