diff options
| -rw-r--r-- | sound/usb/midi.c | 4 | ||||
| -rw-r--r-- | sound/usb/quirks-table.h | 87 | ||||
| -rw-r--r-- | sound/usb/quirks.c | 91 | ||||
| -rw-r--r-- | sound/usb/usbaudio.h | 1 |
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 | ||
| 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 | |||
| 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, |
