[PATCH 2/3] ALSA: usb-audio: Move volume control resolution check into a function
From: Rong Zhang
Date: Fri Apr 10 2026 - 13:49:57 EST
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@xxxxxxx>
Link: https://lore.kernel.org/r/87o6jsk3vs.wl-tiwai@xxxxxxx
Signed-off-by: Rong Zhang <i@xxxxxxxx>
---
sound/usb/mixer.c | 65 +++++++++++++++++++++++++++++++++----------------------
1 file 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
@@ -1232,6 +1232,38 @@ static void init_cur_mix_raw(struct usb_mixer_elem_info *cval, int ch, int idx)
snd_usb_set_cur_mix_value(cval, ch, idx, cval->min);
}
+/*
+ * 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
*/
@@ -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;
}
--
2.53.0