[PATCH v2] ALSA: usb-audio: Add support for Pioneer DJ DJM-S11
From: Federico Beffa
Date: Thu Jun 25 2026 - 07:54:07 EST
The Pioneer DJ DJM-S11, a professional 2-port DJ mixer, is currently not
recognized as an audio interface and therefore not usable on Linux. This
patch enables its full audio functionality.
Like other mixers in the Pioneer DJ DJM family, the DJM-S11 uses
vendor-specific USB class descriptors (0xff) and requires custom mixer
quirks to expose the hardware's input capture routing and volume
controls.
Add the USB vendor and product ID (2b73:0037) to quirks-table.h, mapping
the control interface (Interface 0) to trigger the standard mixer quirks,
and establishing the audio formats for the playback and capture streams.
Control interface 3 is likely related to the touchscreen which is
capable to display waveforms, etc. This functionality is not supported.
In mixer_quirks.c, add the DSP routing options for the DJM-S11. This
creates the ALSA kcontrols for selecting the capture sources (Phono,
Line, Post-fader, etc.) and initializes the default DSP state during
the device probe.
Note that the DJM-S11's capture endpoint clock is strictly slaved to
its playback endpoint. Capturing audio (e.g., timecode vinyl DVS input)
physically requires an active playback stream on the output channels
to feed the master word clock back to the capture stage. Userspace
audio servers (such as PipeWire or JACK) should be configured in
full-duplex mode or have automatic node suspension disabled to maintain
the clock line and prevent I/O errors during capture.
Signed-off-by: Federico Beffa <beffa@xxxxxxxxxxxxxxxx>
---
We reinserted the inadvertenly deleted 'break;' line in mixer_quirks.c.
sound/usb/mixer_quirks.c | 20 ++++++++++++
sound/usb/quirks-table.h | 67 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 87 insertions(+)
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index f6f2bc8e97a7..989157a8baaf 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -3936,6 +3936,7 @@ static int snd_rme_digiface_controls_create(struct usb_mixer_interface *mixer)
#define SND_DJM_450_IDX 0x5
#define SND_DJM_A9_IDX 0x6
#define SND_DJM_V10_IDX 0x7
+#define SND_DJM_S11_IDX 0x8
#define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \
.name = _name, \
@@ -4276,6 +4277,21 @@ static const struct snd_djm_ctl snd_djm_ctls_v10[] = {
// playback channels are fixed and controlled by hardware knobs on the mixer
};
+// DJM-S11
+static const u16 snd_djm_opts_s11_cap1[] = {
+ 0x0100, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010d };
+static const u16 snd_djm_opts_s11_cap2[] = {
+ 0x0200, 0x0203, 0x0206, 0x0207, 0x0208, 0x0209, 0x020d };
+static const u16 snd_djm_opts_s11_cap3[] = {
+ 0x0307, 0x0308, 0x0309, 0x030a, 0x030d, 0x0311, 0x0312 };
+
+static const struct snd_djm_ctl snd_djm_ctls_s11[] = {
+ SND_DJM_CTL("Master Input Level Capture Switch", cap_level, 0, SND_DJM_WINDEX_CAPLVL),
+ SND_DJM_CTL("Input 1 Capture Switch", s11_cap1, 1, SND_DJM_WINDEX_CAP),
+ SND_DJM_CTL("Input 2 Capture Switch", s11_cap2, 1, SND_DJM_WINDEX_CAP),
+ SND_DJM_CTL("Input 3 Capture Switch", s11_cap3, 3, SND_DJM_WINDEX_CAP)
+};
+
static const struct snd_djm_device snd_djm_devices[] = {
[SND_DJM_250MK2_IDX] = SND_DJM_DEVICE(250mk2),
[SND_DJM_750_IDX] = SND_DJM_DEVICE(750),
@@ -4285,6 +4301,7 @@ static const struct snd_djm_device snd_djm_devices[] = {
[SND_DJM_450_IDX] = SND_DJM_DEVICE(450),
[SND_DJM_A9_IDX] = SND_DJM_DEVICE(a9),
[SND_DJM_V10_IDX] = SND_DJM_DEVICE(v10),
+ [SND_DJM_S11_IDX] = SND_DJM_DEVICE(s11),
};
static int snd_djm_controls_info(struct snd_kcontrol *kctl,
@@ -4589,6 +4606,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
case USB_ID(0x2b73, 0x0034): /* Pioneer DJ DJM-V10 */
err = snd_djm_controls_create(mixer, SND_DJM_V10_IDX);
break;
+ case USB_ID(0x2b73, 0x0037): /* Pioneer DJ DJM-S11 */
+ err = snd_djm_controls_create(mixer, SND_DJM_S11_IDX);
+ break;
case USB_ID(0x03f0, 0x0269): /* HP TB Dock G2 */
err = hp_dock_mixer_create(mixer);
break;
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 71444c2898b4..938908671d93 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -3310,6 +3310,73 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
+{
+ /*
+ * Pioneer DJ / AlphaTheta DJM-S11
+ */
+ USB_DEVICE(0x2b73, 0x0037),
+ QUIRK_DRIVER_INFO {
+ QUIRK_DATA_COMPOSITE {
+ {
+ QUIRK_DATA_STANDARD_MIXER(0)
+ },
+ {
+ QUIRK_DATA_AUDIOFORMAT(1) {
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .channels = 14,
+ .iface = 1,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .endpoint = 0x01,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
+ USB_ENDPOINT_SYNC_ASYNC,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .nr_rates = 1,
+ .rate_table = (unsigned int[]) { 48000 },
+ .clock = 1,
+ .fmt_type = UAC_FORMAT_TYPE_I
+ }
+ },
+ {
+ QUIRK_DATA_AUDIOFORMAT(2) {
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .channels = 10,
+ .iface = 2,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .endpoint = 0x82,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
+ USB_ENDPOINT_SYNC_ASYNC |
+ USB_ENDPOINT_USAGE_IMPLICIT_FB,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .nr_rates = 1,
+ .rate_table = (unsigned int[]) { 48000 },
+ .clock = 1,
+ .fmt_type = UAC_FORMAT_TYPE_I
+ }
+ },
+ {
+ /* Audio Control (unknown purpose) */
+ .ifnum = 3,
+ .type = QUIRK_IGNORE_INTERFACE
+ },
+ {
+ .ifnum = 4,
+ .type = QUIRK_MIDI_STANDARD_INTERFACE
+ },
+ {
+ /* HID */
+ .ifnum = 5,
+ .type = QUIRK_IGNORE_INTERFACE
+ },
+ QUIRK_COMPOSITE_END
+ }
+ }
+},
/*
* MacroSilicon MS2100/MS2106 based AV capture cards
--
2.54.0