* [PATCH] ALSA: usb-audio: add quirk for Novation UltraNova (1235:0011)
@ 2026-10-22 16:43 rainey.shawn+kaudio
2026-10-22 16:57 ` sashiko-bot
0 siblings, 1 reply; 3+ messages in thread
From: rainey.shawn+kaudio @ 2026-10-22 16:43 UTC (permalink / raw)
To: Ajanesh Lal, Takashi Iwai, Shawn Rainey
Cc: Shawn Rainey, linux-sound, linux-kernel
From: Shawn Rainey <rainey.shawn+kaudio@gmail.com>
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, mirroring the RME Digiface
entries.
Both isochronous endpoints are marked USB_ENDPOINT_SYNC_SYNC: the
device implements no explicit or implicit feedback, and without the
flag the generic sync-EP detection pairs the capture data endpoint
(0x82) as a feedback endpoint for both directions, stalling capture.
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@gmail.com>
---
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..0b8bea76e 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_attr = USB_ENDPOINT_XFER_ISOC |
+ USB_ENDPOINT_SYNC_SYNC,
+ .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
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] ALSA: usb-audio: add quirk for Novation UltraNova (1235:0011)
2026-10-22 16:43 [PATCH] ALSA: usb-audio: add quirk for Novation UltraNova (1235:0011) rainey.shawn+kaudio
@ 2026-10-22 16:57 ` sashiko-bot
2026-10-23 12:27 ` Shawn
0 siblings, 1 reply; 3+ messages in thread
From: sashiko-bot @ 2026-10-22 16:57 UTC (permalink / raw)
To: rainey.shawn+kaudio; +Cc: linux-sound
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] ALSA: usb-audio: missing .ep_idx = 1 in UltraNova capture audioformat
--
commit aa83c7ced6942ef370a66b06613c33f74107f796
Author: Shawn Rainey <rainey.shawn+kaudio@gmail.com>
ALSA: usb-audio: add quirk for Novation UltraNova (1235:0011)
This commit adds a composite USB audio quirk for the Novation UltraNova
(1235:0011) with fixed playback and capture audio formats on interface 0
and a raw MIDI quirk on interface 1, while leaving the vendor control
interfaces unbound.
> diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
> index 6343a50fb2732..0b8bea76eca5b 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_attr = USB_ENDPOINT_XFER_ISOC |
> + USB_ENDPOINT_SYNC_SYNC,
[Severity: Medium]
Should the capture QUIRK_DATA_AUDIOFORMAT(0) entry in usb_audio_ids in
sound/usb/quirks-table.h also set .ep_idx = 1?
Since capture endpoint 0x82 shares interface 0 altsetting 1 with playback
endpoint 0x01, endpoint 0x82 is the second endpoint descriptor on that
altsetting. Leaving .ep_idx unset defaults fp->ep_idx to 0.
When usb_audio_probe() -> snd_usb_create_quirk() ->
create_composite_quirk() -> create_fixed_stream_quirk() runs in
sound/usb/quirks.c:
alts = &iface->altsetting[fp->altset_idx];
altsd = get_iface_desc(alts);
if (altsd->bNumEndpoints <= fp->ep_idx) {
err = -EINVAL;
goto error;
}
having fp->ep_idx == 0 only checks altsd->bNumEndpoints <= 0 and does not
verify that a second endpoint descriptor exists on altsetting 1.
Next, in create_fixed_stream_quirk() -> add_audio_stream_from_fixed_fmt() ->
snd_usb_audioformat_set_sync_ep() in sound/usb/pcm.c:
if (fmt->ep_idx > 0 || altsd->bNumEndpoints < 2)
return 0;
is_playback = !(get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN);
attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
if ((is_playback && (attr == USB_ENDPOINT_SYNC_SYNC ||
attr == USB_ENDPOINT_SYNC_ADAPTIVE)) ||
(!is_playback && attr != USB_ENDPOINT_SYNC_ADAPTIVE))
return 0;
because fmt->ep_idx is 0 rather than 1, snd_usb_audioformat_set_sync_ep()
does not return early at fmt->ep_idx > 0 and instead checks
get_endpoint(alts, 0) (playback endpoint 0x01), treating the capture
audioformat as is_playback = true. That also appears to be why omitting
USB_ENDPOINT_SYNC_SYNC caused generic sync-EP detection to pair 0x82 as a
sync endpoint for the capture direction as described in the commit message.
Additionally, when opening the capture endpoint via snd_usb_hw_params() ->
snd_usb_endpoint_open() in sound/usb/endpoint.c:
} else {
ep->iface = fp->iface;
ep->altsetting = fp->altsetting;
ep->ep_idx = fp->ep_idx;
}
ep->ep_idx for endpoint 0x82 is recorded as 0 instead of 1.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261022164340.78664-1-rainey.shawn+kaudio@gmail.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] ALSA: usb-audio: add quirk for Novation UltraNova (1235:0011)
2026-10-22 16:57 ` sashiko-bot
@ 2026-10-23 12:27 ` Shawn
0 siblings, 0 replies; 3+ messages in thread
From: Shawn @ 2026-10-23 12:27 UTC (permalink / raw)
To: sashiko-reviews; +Cc: linux-sound
Good catch. v2 incoming with .ep_idx = 1 to the capture entry
Best,
Shawn
On Thu, Oct 22, 2026 at 12:57 PM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] ALSA: usb-audio: missing .ep_idx = 1 in UltraNova capture audioformat
> --
>
> commit aa83c7ced6942ef370a66b06613c33f74107f796
> Author: Shawn Rainey <rainey.shawn+kaudio@gmail.com>
>
> ALSA: usb-audio: add quirk for Novation UltraNova (1235:0011)
>
> This commit adds a composite USB audio quirk for the Novation UltraNova
> (1235:0011) with fixed playback and capture audio formats on interface 0
> and a raw MIDI quirk on interface 1, while leaving the vendor control
> interfaces unbound.
>
> > diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
> > index 6343a50fb2732..0b8bea76eca5b 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_attr = USB_ENDPOINT_XFER_ISOC |
> > + USB_ENDPOINT_SYNC_SYNC,
>
> [Severity: Medium]
> Should the capture QUIRK_DATA_AUDIOFORMAT(0) entry in usb_audio_ids in
> sound/usb/quirks-table.h also set .ep_idx = 1?
>
> Since capture endpoint 0x82 shares interface 0 altsetting 1 with playback
> endpoint 0x01, endpoint 0x82 is the second endpoint descriptor on that
> altsetting. Leaving .ep_idx unset defaults fp->ep_idx to 0.
>
> When usb_audio_probe() -> snd_usb_create_quirk() ->
> create_composite_quirk() -> create_fixed_stream_quirk() runs in
> sound/usb/quirks.c:
>
> alts = &iface->altsetting[fp->altset_idx];
> altsd = get_iface_desc(alts);
> if (altsd->bNumEndpoints <= fp->ep_idx) {
> err = -EINVAL;
> goto error;
> }
>
> having fp->ep_idx == 0 only checks altsd->bNumEndpoints <= 0 and does not
> verify that a second endpoint descriptor exists on altsetting 1.
>
> Next, in create_fixed_stream_quirk() -> add_audio_stream_from_fixed_fmt() ->
> snd_usb_audioformat_set_sync_ep() in sound/usb/pcm.c:
>
> if (fmt->ep_idx > 0 || altsd->bNumEndpoints < 2)
> return 0;
>
> is_playback = !(get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN);
> attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
> if ((is_playback && (attr == USB_ENDPOINT_SYNC_SYNC ||
> attr == USB_ENDPOINT_SYNC_ADAPTIVE)) ||
> (!is_playback && attr != USB_ENDPOINT_SYNC_ADAPTIVE))
> return 0;
>
> because fmt->ep_idx is 0 rather than 1, snd_usb_audioformat_set_sync_ep()
> does not return early at fmt->ep_idx > 0 and instead checks
> get_endpoint(alts, 0) (playback endpoint 0x01), treating the capture
> audioformat as is_playback = true. That also appears to be why omitting
> USB_ENDPOINT_SYNC_SYNC caused generic sync-EP detection to pair 0x82 as a
> sync endpoint for the capture direction as described in the commit message.
>
> Additionally, when opening the capture endpoint via snd_usb_hw_params() ->
> snd_usb_endpoint_open() in sound/usb/endpoint.c:
>
> } else {
> ep->iface = fp->iface;
> ep->altsetting = fp->altsetting;
> ep->ep_idx = fp->ep_idx;
> }
>
> ep->ep_idx for endpoint 0x82 is recorded as 0 instead of 1.
>
> [ ... ]
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20261022164340.78664-1-rainey.shawn+kaudio@gmail.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-23 12:27 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-22 16:43 [PATCH] ALSA: usb-audio: add quirk for Novation UltraNova (1235:0011) rainey.shawn+kaudio
2026-10-22 16:57 ` sashiko-bot
2026-10-23 12:27 ` Shawn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox