@@ -33,6 +33,11 @@ struct audioformat {
bool dsd_bitrev; /* reverse the bits of each DSD sample */
};
+struct audioformats {
+ unsigned int n_formats;
+ const struct audioformat *format;
+};
+
struct snd_usb_substream;
struct snd_usb_endpoint;
@@ -2937,43 +2937,68 @@ YAMAHA_DEVICE(0x7010, "UB99"),
/* Thanks to Clemens Ladisch <clemens@ladisch.de> */
USB_DEVICE(0x0dba, 0x1000),
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Digidesign",
- .product_name = "MBox",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]){
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE,
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = &(const struct audioformat) {
+ .vendor_name = "Digidesign",
+ .product_name = "MBox",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = (const struct snd_usb_audio_quirk[]) {
+ {
+ .ifnum = 0,
+ .type = QUIRK_AUDIO_STANDARD_MIXER,
+ },
+ {
+ .ifnum = 1,
+ .type = QUIRK_AUDIO_FIXED_MULTI_ENDPOINT,
+ .data = &(const struct audioformats)
+ {
+ .n_formats = 2,
+ .format = (const struct audioformat[]) {
+ {
.formats = SNDRV_PCM_FMTBIT_S24_3BE,
.channels = 2,
.iface = 1,
.altsetting = 1,
.altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+ .attributes = 0x4,
.endpoint = 0x02,
- .ep_attr = 0x01,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
+ USB_ENDPOINT_SYNC_SYNC,
+ .maxpacksize = 0x130,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
.rate_max = 48000,
- .nr_rates = 2,
+ .nr_rates = 1,
.rate_table = (unsigned int[]) {
- 44100, 48000
+ 48000
+ }
+ },
+ {
+ .formats = SNDRV_PCM_FMTBIT_S24_3BE,
+ .channels = 2,
+ .iface = 1,
+ .altsetting = 1,
+ .altset_idx = 1,
+ .attributes = 0x4,
+ .endpoint = 0x81,
+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
+ USB_ENDPOINT_SYNC_ASYNC,
+ .maxpacksize = 0x130,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .nr_rates = 1,
+ .rate_table = (unsigned int[]) {
+ 48000
+ }
}
}
- },
- {
- .ifnum = -1
}
+ },
+ {
+ .ifnum = -1
}
-
}
+}
},
/* DIGIDESIGN MBOX 2 */
@@ -180,6 +180,34 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
return 0;
}
+/*
+ * create N streams for an interface without proper descriptors but with
+ * multiple endpoints
+ */
+static int create_fixed_multi_stream_quirk(struct snd_usb_audio *chip,
+ struct usb_interface *iface,
+ struct usb_driver *driver,
+ const struct snd_usb_audio_quirk *quirk)
+{
+ struct audioformats *fp;
+ int i;
+
+ fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
+ if (!fp) {
+ usb_audio_err(chip, "cannot memdup\n");
+ return -ENOMEM;
+ }
+ for (i = 0; i < fp->n_formats; i++) {
+ struct snd_usb_audio_quirk nquirk = {
+ .ifnum = quirk->ifnum,
+ .type = QUIRK_AUDIO_FIXED_MULTI_ENDPOINT,
+ .data = (const struct audioformat *) &fp->format[i]
+ };
+ create_fixed_stream_quirk(chip, iface, driver, &nquirk);
+ }
+ return 0;
+}
+
static int create_auto_pcm_quirk(struct snd_usb_audio *chip,
struct usb_interface *iface,
struct usb_driver *driver)
@@ -528,6 +556,8 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
[QUIRK_MIDI_FTDI] = create_any_midi_quirk,
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
+ [QUIRK_AUDIO_FIXED_MULTI_ENDPOINT] =
+ create_fixed_multi_stream_quirk,
[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
[QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
[QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
@@ -96,6 +96,7 @@ enum quirk_type {
QUIRK_MIDI_FTDI,
QUIRK_AUDIO_STANDARD_INTERFACE,
QUIRK_AUDIO_FIXED_ENDPOINT,
+ QUIRK_AUDIO_FIXED_MULTI_ENDPOINT,
QUIRK_AUDIO_EDIROL_UAXX,
QUIRK_AUDIO_ALIGN_TRANSFER,
QUIRK_AUDIO_STANDARD_MIXER,