]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ALSA: usb-audio: Extend max number of channels to 64
authorTakashi Iwai <tiwai@suse.de>
Fri, 27 Mar 2026 15:30:54 +0000 (16:30 +0100)
committerTakashi Iwai <tiwai@suse.de>
Fri, 27 Mar 2026 15:32:19 +0000 (16:32 +0100)
The current limitation of 16 as MAX_CHANNELS is rather historical at
the time of UAC1 definition.  As there seem already devices with a
higher number of mixer channels, we should extend it too.  As an ad
hoc update, let's raise it to 64 so that it can still fit in a single
long-long integer.

Link: https://lore.kernel.org/F1B104A5-CD6A-4A26-AB46-14BF233C0579@getmailspring.com
Tested-by: Phil Willoughby <willerz@gmail.com>
Link: https://patch.msgid.link/20260327153056.691575-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/mixer.c
sound/usb/mixer.h

index e764757979e009ac1a4dd26cbab62e24b266c19b..69026cf54979a8a04584e6a6eb5da8bfcbcbd410 100644 (file)
@@ -1725,7 +1725,7 @@ static bool check_insane_volume_range(struct usb_mixer_interface *mixer,
 
 static void __build_feature_ctl(struct usb_mixer_interface *mixer,
                                const struct usbmix_name_map *imap,
-                               unsigned int ctl_mask, int control,
+                               u64 ctl_mask, int control,
                                struct usb_audio_term *iterm,
                                struct usb_audio_term *oterm,
                                int unitid, int nameid, int readonly_mask)
@@ -1887,7 +1887,7 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer,
 }
 
 static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
-                             unsigned int ctl_mask, int control,
+                             u64 ctl_mask, int control,
                              struct usb_audio_term *iterm, int unitid,
                              int readonly_mask)
 {
@@ -1899,7 +1899,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
 }
 
 static void build_feature_ctl_badd(struct usb_mixer_interface *mixer,
-                             unsigned int ctl_mask, int control, int unitid,
+                             u64 ctl_mask, int control, int unitid,
                              const struct usbmix_name_map *badd_map)
 {
        __build_feature_ctl(mixer, badd_map, ctl_mask, control,
@@ -2075,7 +2075,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
                bmaControls = ftr->bmaControls;
        }
 
-       if (channels > 32) {
+       if (channels > MAX_CHANNELS) {
                usb_audio_info(state->chip,
                               "usbmixer: too many channels (%d) in unit %d\n",
                               channels, unitid);
@@ -2113,7 +2113,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
        if (state->mixer->protocol == UAC_VERSION_1) {
                /* check all control types */
                for (i = 0; i < 10; i++) {
-                       unsigned int ch_bits = 0;
+                       u64 ch_bits = 0;
                        int control = audio_feature_info[i].control;
 
                        for (j = 0; j < channels; j++) {
@@ -2139,7 +2139,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
                }
        } else { /* UAC_VERSION_2/3 */
                for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
-                       unsigned int ch_bits = 0;
+                       u64 ch_bits = 0;
                        unsigned int ch_read_only = 0;
                        int control = audio_feature_info[i].control;
 
@@ -3452,7 +3452,7 @@ static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
                [USB_MIXER_U32] = "U32",
                [USB_MIXER_BESPOKEN] = "BESPOKEN",
        };
-       snd_iprintf(buffer, "    Info: id=%i, control=%i, cmask=0x%x, "
+       snd_iprintf(buffer, "    Info: id=%i, control=%i, cmask=0x%llx, "
                            "channels=%i, type=\"%s\"\n", cval->head.id,
                            cval->control, cval->cmask, cval->channels,
                            val_types[cval->val_type]);
index 167fbfcf01ace9b67b8502adbd3f694975f6d202..afbb3dd9f177bf4dd5884bbd57c842bce3444e23 100644 (file)
@@ -44,7 +44,7 @@ struct usb_mixer_interface {
        void (*private_suspend)(struct usb_mixer_interface *mixer);
 };
 
-#define MAX_CHANNELS   16      /* max logical channels */
+#define MAX_CHANNELS   64      /* max logical channels */
 
 enum {
        USB_MIXER_BOOLEAN,
@@ -81,7 +81,7 @@ struct usb_mixer_elem_list {
 struct usb_mixer_elem_info {
        struct usb_mixer_elem_list head;
        unsigned int control;   /* CS or ICN (high byte) */
-       unsigned int cmask; /* channel mask bitmap: 0 = master */
+       u64 cmask; /* channel mask bitmap: 0 = master */
        unsigned int idx_off; /* Control index offset */
        unsigned int ch_readonly;
        unsigned int master_readonly;