mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Zipdox <zipdox@zipdox.net>
Cc: linux-sound@vger.kernel.org, perex@perex.cz,
	linux-kernel@vger.kernel.org, tiwai@suse.com
Subject: Re: [PATCH] USB Audio Class 2 Mixer unit support for GET_CUR, SET_CUR and RANGE
Date: Wed, 16 Sep 2026 20:22:01 +0200	[thread overview]
Message-ID: <87y0d1hx9y.wl-tiwai@suse.de> (raw)
In-Reply-To: <8733v9jfp1.wl-tiwai@suse.de>

On Wed, 16 Sep 2026 18:58:50 +0200,
Takashi Iwai wrote:
> 
> On Wed, 16 Sep 2026 17:40:53 +0200,
> Takashi Iwai wrote:
> > 
> > On Wed, 16 Sep 2026 09:43:14 +0200,
> > Zipdox wrote:
> > > 
> > > On 9/15/26 4:19 PM, Takashi Iwai wrote:
> > > > But your code also blindly assumes the MU_MIXER_CONTROL that doesn't
> > > > fit with other units like feature unit?  I guess we have to set the
> > > > proper Control Selector value depending on the unit type.
> > > > 
> > > > After all, this is about the correct setup of wValue.  Let's try to be
> > > > minimalistic at first -- just tweak wValue in get_ctl_value_v2() and
> > > > snd_usb_mixer_set_ctl_value() at first.  If this becomes too ugly, we
> > > > can think of redesigning.
> > > I assumed that mixer.c was just for the mixer unit, and I seem to have
> > > completely overlooked the fact that that it also controls feature
> > > units. I'm not sure how to proceed from here. Do you have any
> > > suggestions for how we can store the control selector in the
> > > usb_mixer_elem_info struct? The control field is presently used as the
> > > input channel number, so maybe we should add a separate field for the
> > > input channel? I think maybe it's better that someone else fixes this,
> > > I'm kind of out of my element here.
> > 
> > I took a look back at the current code, and at least, the parse of
> > UAC2 mixer unit itself is OK -- it handles the bitmap properly.
> > The problem is the exceptional way to set up wValue for the mixer
> > unit, and I guess something like below could work.  It just stores the
> > part of wValue in an additional field, and use it for calculating the
> > correct wValue with MCN + UAC2_MU_MIXER in high byte.
> > 
> > Just compile tested, so not 100% sure whether it's correct.
> 
> ... and this version was obviously half-baked, forgotten the
> counterpart.  A revised patch is below.

... or maybe a less cryptic version like below.


Takashi

-- 8< --
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 33a6a1281410..c6639a45fb24 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -335,6 +335,16 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
 	return -EINVAL;
 }
 
+/* convert the given UAC1 wValue (ICN+1|OCN+1) to UAC2 MCN */
+static unsigned int to_mcn(const struct usb_mixer_elem_info *cval,
+			   unsigned int validx)
+{
+	unsigned char m = (validx >> 8) & 0xff;
+	unsigned char v = validx & 0xff;
+
+	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 +357,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 +492,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 +2363,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;
 };
 

      reply	other threads:[~2026-09-16 18:22 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-15  8:54 Zipdox
2026-09-15 11:08 ` Takashi Iwai
2026-09-15 12:54   ` Zipdox
2026-09-15 14:19     ` Takashi Iwai
2026-09-16  7:43       ` Zipdox
2026-09-16 15:40         ` Takashi Iwai
2026-09-16 16:58           ` Takashi Iwai
2026-09-16 18:22             ` Takashi Iwai [this message]

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=87y0d1hx9y.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    --cc=zipdox@zipdox.net \
    /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®