[PATCH v2] ALSA: usb-audio: add quirk for Novation UltraNova (1235:0011)

From: rainey . shawn+kaudio

Date: Fri Oct 23 2026 - 08:27:58 EST


From: Shawn Rainey <rainey.shawn+kaudio@xxxxxxxxx>

The device reports vendor-specific class on all interfaces, so the
standard parser rejects it and no card is created. Add a composite
quirk with fixed audio and raw-MIDI layouts. The id table entry
matches interface 0 only so that the vendor control interfaces (2/3)
are left unbound for userspace access.

The endpoints advertise no synchronization and the device provides no
feedback; both streams are locked to the USB SOF. The playback entry
is marked USB_ENDPOINT_SYNC_SYNC so that generic sync-EP detection
does not pair the capture data endpoint (0x82) as implicit feedback
for the output stream; the capture entry needs no override, as its
.ep_idx = 1 already keeps it out of sync-EP detection.

Verified on hardware: audio duplex at both supported rates, raw MIDI
in/out, and complete patch dumps as SysEx on the MIDI endpoints.

Signed-off-by: Shawn Rainey <rainey.shawn+kaudio@xxxxxxxxx>
---
v2:
- set .ep_idx = 1 on the capture entry: endpoint 0x82 is the second
endpoint descriptor of altsetting 1, and leaving ep_idx at 0 made
snd_usb_audioformat_set_sync_ep() treat the capture format as
playback (is_playback is derived from get_endpoint(alts, 0)).
- drop USB_ENDPOINT_SYNC_SYNC from the capture entry: with ep_idx = 1
it is no longer needed, as the capture format exits sync-EP
detection before the synctype is examined. The playback entry
keeps the flag, as without it the generic detection pairs capture
endpoint 0x82 as implicit feedback for the output stream.
(Both points from review feedback; re-verified duplex and MIDI
on hardware.)
v1: https://lore.kernel.org/r/20261022164340.78664-1-rainey.shawn+kaudio@xxxxxxxxx
sound/usb/quirks-table.h | 63 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)

diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 6343a50fb..2e4f21890 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2359,6 +2359,69 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
+{
+ /*
+ * Novation UltraNova: vendor-specific class descriptors, fixed
+ * audio and MIDI layouts. Only the audio and MIDI interfaces
+ * (0 and 1) are grabbed; the vendor control interfaces (2/3)
+ * are left unbound for userspace access.
+ */
+ USB_DEVICE_INTERFACE_NUMBER(0x1235, 0x0011, 0),
+ QUIRK_DRIVER_INFO {
+ .vendor_name = "Novation",
+ .product_name = "UltraNova",
+ QUIRK_DATA_COMPOSITE {
+ {
+ QUIRK_DATA_AUDIOFORMAT(0) {
+ /* playback */
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels = 4,
+ .iface = 0,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+ .endpoint = 0x01,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
+ USB_ENDPOINT_SYNC_SYNC,
+ .maxpacksize = 392,
+ .rates = SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000,
+ .rate_min = 44100,
+ .rate_max = 48000,
+ .nr_rates = 2,
+ .rate_table = (unsigned int[]) {
+ 44100, 48000
+ }
+ }
+ },
+ {
+ QUIRK_DATA_AUDIOFORMAT(0) {
+ /* capture */
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .channels = 2,
+ .iface = 0,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+ .endpoint = 0x82,
+ .ep_idx = 1,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC,
+ .maxpacksize = 294,
+ .rates = SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000,
+ .rate_min = 44100,
+ .rate_max = 48000,
+ .nr_rates = 2,
+ .rate_table = (unsigned int[]) {
+ 44100, 48000
+ }
+ }
+ },
+ { QUIRK_DATA_RAW_BYTES(1) },
+ QUIRK_COMPOSITE_END
+ }
+ }
+},
{
USB_DEVICE(0x1235, 0x001e),
QUIRK_DRIVER_INFO {
--
2.56.0