]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: usb-audio: Move volume control resolution check into a function
authorRong Zhang <i@rong.moe>
Fri, 10 Apr 2026 17:49:03 +0000 (01:49 +0800)
committerTakashi Iwai <tiwai@suse.de>
Sat, 11 Apr 2026 08:02:53 +0000 (10:02 +0200)
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>
sound/usb/mixer.c

index e5993364c8250ace4fa29eb0d4217c701186f262..e77c2d78a782a3950cc20197b78aecf50b1958b4 100644 (file)
@@ -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;
        }