Skip to content

Commit cb99864

Browse files
zamaudiotiwai
authored andcommitted
ALSA: usb-audio: Support for Digidesign Mbox 2 USB sound card:
This patch is the result of a lot of trial and error, since there are no specs available for the device. Full duplex support is provided, i.e. playback and recording in stereo. The format is hardcoded at 48000Hz @ 24 bit, which is the maximum that the device supports. Also, MIDI in and MIDI out both work. Users will notice that the S/PDIF light also flashes when playback or recording is active. I believe this means that S/PDIF input/output is simultaneously activated with the analogue i/o during use. But this particular functionality remains untested. Note that this particular version of the patch is so far untested on the physical hardware because I have not compiled a full kernel with the changes. However, extensive testing has been done by many users of the hardware who believe other versions of my patch have worked since circa 2009. [Modified to make a function static by tiwai] Signed-off-by: Damien Zammit <damien@zamaudio.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 44728e9 commit cb99864

File tree

4 files changed

+183
-0
lines changed

4 files changed

+183
-0
lines changed

sound/usb/midi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2181,6 +2181,10 @@ int snd_usbmidi_create(struct snd_card *card,
21812181
umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
21822182
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
21832183
break;
2184+
case QUIRK_MIDI_MBOX2:
2185+
umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
2186+
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
2187+
break;
21842188
case QUIRK_MIDI_RAW_BYTES:
21852189
umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
21862190
/*

sound/usb/quirks-table.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,6 +2921,93 @@ YAMAHA_DEVICE(0x7010, "UB99"),
29212921

29222922
}
29232923
},
2924+
2925+
/* DIGIDESIGN MBOX 2 */
2926+
{
2927+
USB_DEVICE(0x0dba, 0x3000),
2928+
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
2929+
.vendor_name = "Digidesign",
2930+
.product_name = "Mbox 2",
2931+
.ifnum = QUIRK_ANY_INTERFACE,
2932+
.type = QUIRK_COMPOSITE,
2933+
.data = (const struct snd_usb_audio_quirk[]) {
2934+
{
2935+
.ifnum = 0,
2936+
.type = QUIRK_IGNORE_INTERFACE
2937+
},
2938+
{
2939+
.ifnum = 1,
2940+
.type = QUIRK_IGNORE_INTERFACE
2941+
},
2942+
{
2943+
.ifnum = 2,
2944+
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
2945+
.data = &(const struct audioformat) {
2946+
.formats = SNDRV_PCM_FMTBIT_S24_3BE,
2947+
.channels = 2,
2948+
.iface = 2,
2949+
.altsetting = 2,
2950+
.altset_idx = 1,
2951+
.attributes = 0x00,
2952+
.endpoint = 0x03,
2953+
.ep_attr = USB_ENDPOINT_SYNC_ASYNC,
2954+
.maxpacksize = 0x128,
2955+
.rates = SNDRV_PCM_RATE_48000,
2956+
.rate_min = 48000,
2957+
.rate_max = 48000,
2958+
.nr_rates = 1,
2959+
.rate_table = (unsigned int[]) {
2960+
48000
2961+
}
2962+
}
2963+
},
2964+
{
2965+
.ifnum = 3,
2966+
.type = QUIRK_IGNORE_INTERFACE
2967+
},
2968+
{
2969+
.ifnum = 4,
2970+
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
2971+
.data = &(const struct audioformat) {
2972+
.formats = SNDRV_PCM_FMTBIT_S24_3BE,
2973+
.channels = 2,
2974+
.iface = 4,
2975+
.altsetting = 2,
2976+
.altset_idx = 1,
2977+
.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
2978+
.endpoint = 0x85,
2979+
.ep_attr = USB_ENDPOINT_SYNC_SYNC,
2980+
.maxpacksize = 0x128,
2981+
.rates = SNDRV_PCM_RATE_48000,
2982+
.rate_min = 48000,
2983+
.rate_max = 48000,
2984+
.nr_rates = 1,
2985+
.rate_table = (unsigned int[]) {
2986+
48000
2987+
}
2988+
}
2989+
},
2990+
{
2991+
.ifnum = 5,
2992+
.type = QUIRK_IGNORE_INTERFACE
2993+
},
2994+
{
2995+
.ifnum = 6,
2996+
.type = QUIRK_MIDI_MBOX2,
2997+
.data = &(const struct snd_usb_midi_endpoint_info) {
2998+
.out_ep = 0x02,
2999+
.out_cables = 0x0001,
3000+
.in_ep = 0x81,
3001+
.in_interval = 0x01,
3002+
.in_cables = 0x0001
3003+
}
3004+
},
3005+
{
3006+
.ifnum = -1
3007+
}
3008+
}
3009+
}
3010+
},
29243011
{
29253012
/* Tascam US122 MKII - playback-only support */
29263013
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,

sound/usb/quirks.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
306306
[QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
307307
[QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
308308
[QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
309+
[QUIRK_MIDI_MBOX2] = create_any_midi_quirk,
309310
[QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
310311
[QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
311312
[QUIRK_MIDI_CME] = create_any_midi_quirk,
@@ -497,6 +498,92 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
497498
return -EAGAIN;
498499
}
499500

501+
static void mbox2_setup_48_24_magic(struct usb_device *dev)
502+
{
503+
u8 srate[3];
504+
u8 temp[12];
505+
506+
/* Choose 48000Hz permanently */
507+
srate[0] = 0x80;
508+
srate[1] = 0xbb;
509+
srate[2] = 0x00;
510+
511+
/* Send the magic! */
512+
snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
513+
0x01, 0x22, 0x0100, 0x0085, &temp, 0x0003);
514+
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
515+
0x81, 0xa2, 0x0100, 0x0085, &srate, 0x0003);
516+
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
517+
0x81, 0xa2, 0x0100, 0x0086, &srate, 0x0003);
518+
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
519+
0x81, 0xa2, 0x0100, 0x0003, &srate, 0x0003);
520+
return;
521+
}
522+
523+
/* Digidesign Mbox 2 needs to load firmware onboard
524+
* and driver must wait a few seconds for initialisation.
525+
*/
526+
527+
#define MBOX2_FIRMWARE_SIZE 646
528+
#define MBOX2_BOOT_LOADING 0x01 /* Hard coded into the device */
529+
#define MBOX2_BOOT_READY 0x02 /* Hard coded into the device */
530+
531+
int snd_usb_mbox2_boot_quirk(struct usb_device *dev)
532+
{
533+
struct usb_host_config *config = dev->actconfig;
534+
int err;
535+
u8 bootresponse;
536+
int fwsize;
537+
int count;
538+
539+
fwsize = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
540+
541+
if (fwsize != MBOX2_FIRMWARE_SIZE) {
542+
snd_printk(KERN_ERR "usb-audio: Invalid firmware size=%d.\n", fwsize);
543+
return -ENODEV;
544+
}
545+
546+
snd_printd("usb-audio: Sending Digidesign Mbox 2 boot sequence...\n");
547+
548+
count = 0;
549+
bootresponse = MBOX2_BOOT_LOADING;
550+
while ((bootresponse == MBOX2_BOOT_LOADING) && (count < 10)) {
551+
msleep(500); /* 0.5 second delay */
552+
snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
553+
/* Control magic - load onboard firmware */
554+
0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012);
555+
if (bootresponse == MBOX2_BOOT_READY)
556+
break;
557+
snd_printd("usb-audio: device not ready, resending boot sequence...\n");
558+
count++;
559+
}
560+
561+
if (bootresponse != MBOX2_BOOT_READY) {
562+
snd_printk(KERN_ERR "usb-audio: Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse);
563+
return -ENODEV;
564+
}
565+
566+
snd_printdd("usb-audio: device initialised!\n");
567+
568+
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
569+
&dev->descriptor, sizeof(dev->descriptor));
570+
config = dev->actconfig;
571+
if (err < 0)
572+
snd_printd("error usb_get_descriptor: %d\n", err);
573+
574+
err = usb_reset_configuration(dev);
575+
if (err < 0)
576+
snd_printd("error usb_reset_configuration: %d\n", err);
577+
snd_printdd("mbox2_boot: new boot length = %d\n",
578+
le16_to_cpu(get_cfg_desc(config)->wTotalLength));
579+
580+
mbox2_setup_48_24_magic(dev);
581+
582+
snd_printk(KERN_INFO "usb-audio: Digidesign Mbox 2: 24bit 48kHz");
583+
584+
return 0; /* Successful boot */
585+
}
586+
500587
/*
501588
* Setup quirks
502589
*/
@@ -655,6 +742,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
655742
case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
656743
return snd_usb_cm6206_boot_quirk(dev);
657744

745+
case USB_ID(0x0dba, 0x3000):
746+
/* Digidesign Mbox 2 */
747+
return snd_usb_mbox2_boot_quirk(dev);
748+
658749
case USB_ID(0x133e, 0x0815):
659750
/* Access Music VirusTI Desktop */
660751
return snd_usb_accessmusic_boot_quirk(dev);

sound/usb/usbaudio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ enum quirk_type {
7676
QUIRK_MIDI_YAMAHA,
7777
QUIRK_MIDI_MIDIMAN,
7878
QUIRK_MIDI_NOVATION,
79+
QUIRK_MIDI_MBOX2,
7980
QUIRK_MIDI_RAW_BYTES,
8081
QUIRK_MIDI_EMAGIC,
8182
QUIRK_MIDI_CME,

0 commit comments

Comments
 (0)