diff options
| author | Rong Zhang <i@rong.moe> | 2026-04-11 01:49:03 +0800 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2026-04-11 10:02:53 +0200 |
| commit | e3ad86a82868fcde16f213240a60891c2d7bbec4 (patch) | |
| tree | 0497816263c2b6b416d058cfb8b334b7543efd33 | |
| parent | 4f55a85cd4fc988712965f710ba1475e7ba3292a (diff) | |
ALSA: usb-audio: Move volume control resolution check into a function
get_min_max_with_quirks() is too lengthy and hard to read.
Move the volume control resolution check code into a function as it's
relatively self-contained.
Suggested-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/87o6jsk3vs.wl-tiwai@suse.de
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260411-uac-sticky-mixer-v1-2-29d62717befd@rong.moe
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/usb/mixer.c | 65 |
1 files changed, 39 insertions, 26 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index e5993364c825..e77c2d78a782 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1233,6 +1233,38 @@ static void init_cur_mix_raw(struct usb_mixer_elem_info *cval, int ch, int idx) } /* + * Additional checks for the proper resolution + * + * Some devices report smaller resolutions than actually reacting. + * They don't return errors but simply clip to the lower aligned value. + */ +static void check_volume_control_res(struct usb_mixer_elem_info *cval, + int channel, int saved) +{ + int last_valid_res = cval->res; + int test, check; + + for (;;) { + test = saved; + if (test < cval->max) + test += cval->res; + else + test -= cval->res; + + if (test < cval->min || test > cval->max || + snd_usb_set_cur_mix_value(cval, channel, 0, test) || + get_cur_mix_raw(cval, channel, &check)) { + cval->res = last_valid_res; + break; + } + if (test == check) + break; + + cval->res *= 2; + } +} + +/* * retrieve the minimum and maximum values for the specified control */ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, @@ -1287,37 +1319,18 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, if (cval->res == 0) cval->res = 1; - /* Additional checks for the proper resolution - * - * Some devices report smaller resolutions than actually - * reacting. They don't return errors but simply clip - * to the lower aligned value. - */ if (cval->min + cval->res < cval->max) { - int last_valid_res = cval->res; - int saved, test, check; + int saved; + if (get_cur_mix_raw(cval, minchn, &saved) < 0) - goto no_res_check; - for (;;) { - test = saved; - if (test < cval->max) - test += cval->res; - else - test -= cval->res; - if (test < cval->min || test > cval->max || - snd_usb_set_cur_mix_value(cval, minchn, 0, test) || - get_cur_mix_raw(cval, minchn, &check)) { - cval->res = last_valid_res; - break; - } - if (test == check) - break; - cval->res *= 2; - } + goto no_checks; + + check_volume_control_res(cval, minchn, saved); + snd_usb_set_cur_mix_value(cval, minchn, 0, saved); } -no_res_check: +no_checks: cval->initialized = 1; } |
