Linux Sound subsystem development
 help / color / mirror / Atom feed
* [PATCH] ALSA: usb-audio: Set the value of potential sticky mixers to maximum
@ 2026-05-30 19:52 Rong Zhang
  2026-05-31  5:12 ` Steve Smith
  2026-05-31 13:23 ` Takashi Iwai
  0 siblings, 2 replies; 7+ messages in thread
From: Rong Zhang @ 2026-05-30 19:52 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai
  Cc: Takashi Iwai, Steve Smith, linux-sound, linux-kernel, Rong Zhang

It makes no sense to restore the saved value for a sticky mixer, since
setting any value is a no-op.

However, in some rare cases, SET_CUR is effective despite GET_CUR always
returns a constant value. These mixers are not sticky, but there's no
way to distinguish them. Without any additional information, the best
thing we can do is to set the mixer value to the maximum before bailing
out, so that a soft mixer can still reach the maximum hardware volume if
the mixer turns out to be non-sticky. Meanwhile, all channels must be
synchronized to prevent imbalance volume.

Fixes: 86aa1ea1f15c ("ALSA: usb-audio: Do not expose sticky mixers")
Signed-off-by: Rong Zhang <i@rong.moe>
---
 sound/usb/mixer.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 5fba456eb4a9..fb37bb8ad9a9 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1371,10 +1371,8 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
 				goto no_checks;
 
 			ret = check_sticky_volume_control(cval, minchn, saved);
-			if (ret < 0) {
-				snd_usb_set_cur_mix_value(cval, minchn, 0, saved);
-				return ret;
-			}
+			if (ret < 0)
+				goto sticky;
 
 			if (cval->min + cval->res < cval->max)
 				check_volume_control_res(cval, minchn, saved);
@@ -1431,6 +1429,33 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
 	}
 
 	return 0;
+
+sticky:
+	/*
+	 * It makes no sense to restore the saved value for a sticky mixer,
+	 * since setting any value is a no-op.
+	 *
+	 * However, in some rare cases, SET_CUR is effective despite GET_CUR
+	 * always returns a constant value. These mixers are not sticky, but
+	 * there's no way to distinguish them. Without any additional
+	 * information, the best thing we can do is to set the mixer value to
+	 * the maximum before bailing out, so that a soft mixer can still reach
+	 * the maximum hardware volume if the mixer turns out to be non-sticky.
+	 * Meanwhile, all channels must be synchronized to prevent imbalance
+	 * volume.
+	 */
+	if (!cval->cmask) {
+		snd_usb_set_cur_mix_value(cval, 0, 0, cval->max);
+	} else {
+		for (i = 0; i < MAX_CHANNELS; i++) {
+			idx = 0;
+			if (cval->cmask & BIT(i)) {
+				snd_usb_set_cur_mix_value(cval, i + 1, idx, cval->max);
+				idx++;
+			}
+		}
+	}
+	return ret;
 }
 
 #define get_min_max(cval, def)	get_min_max_with_quirks(cval, def, NULL)

---
base-commit: 2c142b63c8ee982cdfdba49a616027c266294838
change-id: 2ae46b0d-uac-sticky-error-path-496e4f0caa0f

Thanks,
Rong


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-05-31 14:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-30 19:52 [PATCH] ALSA: usb-audio: Set the value of potential sticky mixers to maximum Rong Zhang
2026-05-31  5:12 ` Steve Smith
2026-05-31 13:23 ` Takashi Iwai
2026-05-31 13:55   ` Rong Zhang
2026-05-31 14:07     ` Takashi Iwai
2026-05-31 14:19       ` Rong Zhang
2026-05-31 14:50         ` Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox