aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2012-12-19 05:27:22 -0500
committerTakashi Iwai <tiwai@suse.de>2012-12-19 05:27:22 -0500
commitcb99864d40e46dea9c2aa3eaa97517b776f91024 (patch)
treec3684fe904dd058a0a01a51cda460f3575a5ec38 /sound
parent44728e97c35ef31d649dafbbada665e37176f5da (diff)
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>
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/midi.c4
-rw-r--r--sound/usb/quirks-table.h87
-rw-r--r--sound/usb/quirks.c91
-rw-r--r--sound/usb/usbaudio.h1
4 files changed, 183 insertions, 0 deletions
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 34b9bb7fe87c..c183d34842ac 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -2181,6 +2181,10 @@ int snd_usbmidi_create(struct snd_card *card,
2181 umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; 2181 umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
2182 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); 2182 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
2183 break; 2183 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;
2184 case QUIRK_MIDI_RAW_BYTES: 2188 case QUIRK_MIDI_RAW_BYTES:
2185 umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; 2189 umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
2186 /* 2190 /*
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 579cf6f6901c..cdcf6b45e8a8 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2921,6 +2921,93 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2921 2921
2922 } 2922 }
2923}, 2923},
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},
2924{ 3011{
2925 /* Tascam US122 MKII - playback-only support */ 3012 /* Tascam US122 MKII - playback-only support */
2926 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, 3013 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 0f58b4b6d702..203d72b8a037 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -306,6 +306,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
306 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk, 306 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
307 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk, 307 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
308 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk, 308 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
309 [QUIRK_MIDI_MBOX2] = create_any_midi_quirk,
309 [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk, 310 [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
310 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, 311 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
311 [QUIRK_MIDI_CME] = create_any_midi_quirk, 312 [QUIRK_MIDI_CME] = create_any_midi_quirk,
@@ -497,6 +498,92 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
497 return -EAGAIN; 498 return -EAGAIN;
498} 499}
499 500
501static 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
531int 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
500/* 587/*
501 * Setup quirks 588 * Setup quirks
502 */ 589 */
@@ -655,6 +742,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
655 case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */ 742 case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
656 return snd_usb_cm6206_boot_quirk(dev); 743 return snd_usb_cm6206_boot_quirk(dev);
657 744
745 case USB_ID(0x0dba, 0x3000):
746 /* Digidesign Mbox 2 */
747 return snd_usb_mbox2_boot_quirk(dev);
748
658 case USB_ID(0x133e, 0x0815): 749 case USB_ID(0x133e, 0x0815):
659 /* Access Music VirusTI Desktop */ 750 /* Access Music VirusTI Desktop */
660 return snd_usb_accessmusic_boot_quirk(dev); 751 return snd_usb_accessmusic_boot_quirk(dev);
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 1ac3fd9cc5a6..a8172c119796 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -76,6 +76,7 @@ enum quirk_type {
76 QUIRK_MIDI_YAMAHA, 76 QUIRK_MIDI_YAMAHA,
77 QUIRK_MIDI_MIDIMAN, 77 QUIRK_MIDI_MIDIMAN,
78 QUIRK_MIDI_NOVATION, 78 QUIRK_MIDI_NOVATION,
79 QUIRK_MIDI_MBOX2,
79 QUIRK_MIDI_RAW_BYTES, 80 QUIRK_MIDI_RAW_BYTES,
80 QUIRK_MIDI_EMAGIC, 81 QUIRK_MIDI_EMAGIC,
81 QUIRK_MIDI_CME, 82 QUIRK_MIDI_CME,