]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ALSA: usb-audio: add the initial mix for Presonus Studio 1824c
authorRoy Vegard Ovesen <roy.vegard.ovesen@gmail.com>
Sun, 28 Sep 2025 11:38:07 +0000 (13:38 +0200)
committerTakashi Iwai <tiwai@suse.de>
Sun, 28 Sep 2025 16:46:10 +0000 (18:46 +0200)
A reasonable initial mix for the 1824c is the one that
Presonus Universal Control calls bypass.
It mutes all the physical inputs, and connects
Daw channel 1 to Line out channel 1 (left)
Daw channel 2 to Line out channel 2 (right)
Daw channel 3 to Line out channel 3 (left)
etc.

To get the most out of the 1824c a mixer application like
Universal Control is needed. One is available for linux
Link: https://github.com/royvegard/baton
Signed-off-by: Roy Vegard Ovesen <roy.vegard.ovesen@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/mixer_s1810c.c

index 656f0b4bfdf0e81747c5f1e238b338efc3dbcdc3..b2658f922d071758b1d7db5c166ad95549e56fb8 100644 (file)
@@ -215,115 +215,164 @@ snd_sc1810c_get_status_field(struct usb_device *dev,
  */
 static int snd_s1810c_init_mixer_maps(struct snd_usb_audio *chip)
 {
-       u32 a, b, c, e, n, off;
+       u32 a, b, c, e, n, off, left, right;
        struct usb_device *dev = chip->dev;
 
-       /* Set initial volume levels ? */
-       a = 0x64;
-       e = 0xbc;
-       for (n = 0; n < 2; n++) {
-               off = n * 18;
-               for (b = off; b < 18 + off; b++) {
-                       /* This channel to all outputs ? */
-                       for (c = 0; c <= 8; c++) {
+       switch (chip->usb_id) {
+       case USB_ID(0x194f, 0x010c): /* 1810c */
+               /* Set initial volume levels ? */
+               a = 0x64;
+               e = 0xbc;
+               for (n = 0; n < 2; n++) {
+                       off = n * 18;
+                       for (b = off; b < 18 + off; b++) {
+                               /* This channel to all outputs ? */
+                               for (c = 0; c <= 8; c++) {
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
+                               }
+                               /* This channel to main output (again) */
+                               snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
+                               snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
+                       }
+                       /*
+                        * I noticed on UC that DAW channels have different
+                        * initial volumes, so this makes sense.
+                        */
+                       e = 0xb53bf0;
+               }
+
+               /* Connect analog outputs ? */
+               a = 0x65;
+               e = 0x01000000;
+               for (b = 1; b < 3; b++) {
+                       snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
+                       snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
+               }
+               snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, e);
+               snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, e);
+
+               /* Set initial volume levels for S/PDIF mappings ? */
+               a = 0x64;
+               e = 0xbc;
+               c = 3;
+               for (n = 0; n < 2; n++) {
+                       off = n * 18;
+                       for (b = off; b < 18 + off; b++) {
                                snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
                                snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
                        }
-                       /* This channel to main output (again) */
+                       e = 0xb53bf0;
+               }
+
+               /* Connect S/PDIF output ? */
+               a = 0x65;
+               e = 0x01000000;
+               snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
+               snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
+
+               /* Connect all outputs (again) ? */
+               a = 0x65;
+               e = 0x01000000;
+               for (b = 0; b < 4; b++) {
                        snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
                        snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
                }
-               /*
-                * I noticed on UC that DAW channels have different
-                * initial volumes, so this makes sense.
-                */
-               e = 0xb53bf0;
-       }
 
-       /* Connect analog outputs ? */
-       a = 0x65;
-       e = 0x01000000;
-       for (b = 1; b < 3; b++) {
-               snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
-               snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
-       }
-       snd_s1810c_send_ctl_packet(dev, a, 0, 0, 0, e);
-       snd_s1810c_send_ctl_packet(dev, a, 0, 0, 1, e);
-
-       /* Set initial volume levels for S/PDIF mappings ? */
-       a = 0x64;
-       e = 0xbc;
-       c = 3;
-       for (n = 0; n < 2; n++) {
-               off = n * 18;
-               for (b = off; b < 18 + off; b++) {
-                       snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
-                       snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
+               /* Basic routing to get sound out of the device */
+               a = 0x64;
+               e = 0x01000000;
+               for (c = 0; c < 4; c++) {
+                       for (b = 0; b < 36; b++) {
+                               if ((c == 0 && b == 18) ||      /* DAW1/2 -> Main */
+                                       (c == 1 && b == 20) ||  /* DAW3/4 -> Line3/4 */
+                                       (c == 2 && b == 22) ||  /* DAW4/5 -> Line5/6 */
+                                       (c == 3 && b == 24)) {  /* DAW5/6 -> S/PDIF */
+                                       /* Left */
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
+                                       b++;
+                                       /* Right */
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
+                               } else {
+                                       /* Leave the rest disconnected */
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
+                               }
+                       }
                }
-               e = 0xb53bf0;
-       }
 
-       /* Connect S/PDIF output ? */
-       a = 0x65;
-       e = 0x01000000;
-       snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
-       snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
-
-       /* Connect all outputs (again) ? */
-       a = 0x65;
-       e = 0x01000000;
-       for (b = 0; b < 4; b++) {
-               snd_s1810c_send_ctl_packet(dev, a, b, 0, 0, e);
-               snd_s1810c_send_ctl_packet(dev, a, b, 0, 1, e);
-       }
-
-       /* Basic routing to get sound out of the device */
-       a = 0x64;
-       e = 0x01000000;
-       for (c = 0; c < 4; c++) {
-               for (b = 0; b < 36; b++) {
-                       if ((c == 0 && b == 18) ||      /* DAW1/2 -> Main */
-                           (c == 1 && b == 20) ||      /* DAW3/4 -> Line3/4 */
-                           (c == 2 && b == 22) ||      /* DAW4/5 -> Line5/6 */
-                           (c == 3 && b == 24)) {      /* DAW5/6 -> S/PDIF */
-                               /* Left */
+               /* Set initial volume levels for S/PDIF (again) ? */
+               a = 0x64;
+               e = 0xbc;
+               c = 3;
+               for (n = 0; n < 2; n++) {
+                       off = n * 18;
+                       for (b = off; b < 18 + off; b++) {
                                snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
-                               snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
-                               b++;
-                               /* Right */
-                               snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
                                snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
-                       } else {
-                               /* Leave the rest disconnected */
-                               snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0);
-                               snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0);
                        }
+                       e = 0xb53bf0;
                }
-       }
 
-       /* Set initial volume levels for S/PDIF (again) ? */
-       a = 0x64;
-       e = 0xbc;
-       c = 3;
-       for (n = 0; n < 2; n++) {
-               off = n * 18;
-               for (b = off; b < 18 + off; b++) {
+               /* Connect S/PDIF outputs (again) ? */
+               a = 0x65;
+               e = 0x01000000;
+               snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
+               snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
+
+               /* Again ? */
+               snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
+               snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
+               break;
+
+       case USB_ID(0x194f, 0x010d): /* 1824c */
+               /* Set all output faders to unity gain */
+               a = 0x65;
+               c = 0x00;
+               e = 0x01000000;
+
+               for (b = 0; b < 9; b++) {
                        snd_s1810c_send_ctl_packet(dev, a, b, c, 0, e);
                        snd_s1810c_send_ctl_packet(dev, a, b, c, 1, e);
                }
-               e = 0xb53bf0;
-       }
-
-       /* Connect S/PDIF outputs (again) ? */
-       a = 0x65;
-       e = 0x01000000;
-       snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
-       snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
-
-       /* Again ? */
-       snd_s1810c_send_ctl_packet(dev, a, 3, 0, 0, e);
-       snd_s1810c_send_ctl_packet(dev, a, 3, 0, 1, e);
 
+               /* Set
+                * Daw 1 -> Line out 1 (left), Daw 2 -> Line out 2 (right)
+                * Daw 3 -> Line out 3, (left) Daw 4 -> Line out 4 (right)
+                * Daw 5 -> Line out 5, (left) Daw 6 -> Line out 6 (right)
+                * Daw 7 -> Line out 7, (left) Daw 8 -> Line out 8 (right)
+                * Daw 9 -> SPDIF out 1, (left) Daw 10 -> SPDIF out 2 (right)
+                * Daw 11 -> ADAT out 1, (left) Daw 12 -> ADAT out 2 (right)
+                * Daw 13 -> ADAT out 3, (left) Daw 14 -> ADAT out 4 (right)
+                * Daw 15 -> ADAT out 5, (left) Daw 16 -> ADAT out 6 (right)
+                * Daw 17 -> ADAT out 7, (left) Daw 18 -> ADAT out 8 (right)
+                * Everything else muted
+                */
+               a = 0x64;
+               /* The first Daw channel is channel 18 */
+               left = 18;
+
+               for (c = 0; c < 9; c++) {
+                       right = left + 1;
+
+                       for (b = 0; b < 36; b++) {
+                               if (b == left) {
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x01000000);
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x00);
+                               } else if (b == right) {
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x00);
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x01000000);
+                               } else {
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 0, 0x00);
+                                       snd_s1810c_send_ctl_packet(dev, a, b, c, 1, 0x00);
+                               }
+                       }
+                       left += 2;
+               }
+               break;
+       }
        return 0;
 }