Re: [PATCH] ALSA: usb-audio: Set the value of potential sticky mixers to maximum
From: Takashi Iwai
Date: Sun May 31 2026 - 09:27:18 EST
On Sat, 30 May 2026 21:52:49 +0200,
Rong Zhang wrote:
>
> 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@xxxxxxxx>
> ---
> 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;
This change is supposed to be applied only to 7.1, and 7.2 should take
another your series ("ALSA: usb-audio: MIXER_GET_CUR_BROKEN related
changes for 7.2") instead, right? If so, at merging the latter, I'll
revert this one as a preliminary.
thanks,
Takashi