diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/midi.c | 4 | ||||
-rw-r--r-- | sound/usb/quirks-table.h | 123 | ||||
-rw-r--r-- | sound/usb/quirks.c | 91 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 1 |
4 files changed, 219 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 49f9af995d7a..cdcf6b45e8a8 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -99,6 +99,42 @@ | |||
99 | }, | 99 | }, |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * HP Wireless Audio | ||
103 | * When not ignored, causes instability issues for some users, forcing them to | ||
104 | * blacklist the entire module. | ||
105 | */ | ||
106 | { | ||
107 | USB_DEVICE(0x0424, 0xb832), | ||
108 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
109 | .vendor_name = "Standard Microsystems Corp.", | ||
110 | .product_name = "HP Wireless Audio", | ||
111 | .ifnum = QUIRK_ANY_INTERFACE, | ||
112 | .type = QUIRK_COMPOSITE, | ||
113 | .data = (const struct snd_usb_audio_quirk[]) { | ||
114 | /* Mixer */ | ||
115 | { | ||
116 | .ifnum = 0, | ||
117 | .type = QUIRK_IGNORE_INTERFACE, | ||
118 | }, | ||
119 | /* Playback */ | ||
120 | { | ||
121 | .ifnum = 1, | ||
122 | .type = QUIRK_IGNORE_INTERFACE, | ||
123 | }, | ||
124 | /* Capture */ | ||
125 | { | ||
126 | .ifnum = 2, | ||
127 | .type = QUIRK_IGNORE_INTERFACE, | ||
128 | }, | ||
129 | /* HID Device, .ifnum = 3 */ | ||
130 | { | ||
131 | .ifnum = -1, | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | }, | ||
136 | |||
137 | /* | ||
102 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface | 138 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface |
103 | * class matches do not take effect without an explicit ID match. | 139 | * class matches do not take effect without an explicit ID match. |
104 | */ | 140 | */ |
@@ -2885,6 +2921,93 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2885 | 2921 | ||
2886 | } | 2922 | } |
2887 | }, | 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 | }, | ||
2888 | { | 3011 | { |
2889 | /* Tascam US122 MKII - playback-only support */ | 3012 | /* Tascam US122 MKII - playback-only support */ |
2890 | .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 007fcecdf5cd..f104c68fe1e0 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, |