diff options
author | Sebastien Alaiwan <sebastien.alaiwan@gmail.com> | 2010-02-16 02:55:08 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2010-02-16 03:34:56 -0500 |
commit | d39e82db73eb876c60d00f00219d767b3be30307 (patch) | |
tree | 6a6d0fdaae86bd4089e66578dd2bed19a6987d87 /sound/usb | |
parent | c3a3e040f01457d2ea4f199f75ca205401001a3b (diff) |
ALSA: USB MIDI support for Access Music VirusTI
Here's a patch that adds MIDI support through USB for one of the Access
Music synths, the VirusTI.
The synth uses standard USBMIDI protocol on its USB interface 3, although
it does signal "vendor specific" class. A magic string has to be sent on
interface 3 to enable the sending of MIDI from the synth (this string was
found by sniffing usb communication of the Windows driver). This is all
my patch does, and it works on my computer.
Please note that the synth can also do standard usb audio I/O on its
interfaces 2&3, which already works with the current snd-usb-audio driver,
except for the audio input from the synth. I'm going to work on it when I
have some time.
Signed-off-by: Sebastien Alaiwan <sebastien.alaiwan@gmail.com>
Signed-off-by: Clemens Ladisch <clemens@ladisch.de> (cosmetics, list terminator)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/usbaudio.c | 32 | ||||
-rw-r--r-- | sound/usb/usbmidi.c | 6 | ||||
-rw-r--r-- | sound/usb/usbquirks.h | 27 |
3 files changed, 65 insertions, 0 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 4963defee18a..d01ec188b602 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -3327,6 +3327,32 @@ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) | |||
3327 | } | 3327 | } |
3328 | 3328 | ||
3329 | /* | 3329 | /* |
3330 | * This call will put the synth in "USB send" mode, i.e it will send MIDI | ||
3331 | * messages through USB (this is disabled at startup). The synth will | ||
3332 | * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB | ||
3333 | * sign on its LCD. Values here are chosen based on sniffing USB traffic | ||
3334 | * under Windows. | ||
3335 | */ | ||
3336 | static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev) | ||
3337 | { | ||
3338 | int err, actual_length; | ||
3339 | |||
3340 | /* "midi send" enable */ | ||
3341 | static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 }; | ||
3342 | |||
3343 | void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL); | ||
3344 | if (!buf) | ||
3345 | return -ENOMEM; | ||
3346 | err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf, | ||
3347 | ARRAY_SIZE(seq), &actual_length, 1000); | ||
3348 | kfree(buf); | ||
3349 | if (err < 0) | ||
3350 | return err; | ||
3351 | |||
3352 | return 0; | ||
3353 | } | ||
3354 | |||
3355 | /* | ||
3330 | * Setup quirks | 3356 | * Setup quirks |
3331 | */ | 3357 | */ |
3332 | #define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ | 3358 | #define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ |
@@ -3624,6 +3650,12 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
3624 | goto __err_val; | 3650 | goto __err_val; |
3625 | } | 3651 | } |
3626 | 3652 | ||
3653 | /* Access Music VirusTI Desktop */ | ||
3654 | if (id == USB_ID(0x133e, 0x0815)) { | ||
3655 | if (snd_usb_accessmusic_boot_quirk(dev) < 0) | ||
3656 | goto __err_val; | ||
3657 | } | ||
3658 | |||
3627 | /* | 3659 | /* |
3628 | * found a config. now register to ALSA | 3660 | * found a config. now register to ALSA |
3629 | */ | 3661 | */ |
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 6e89b8368d9a..8f5bc1e8dabc 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -1407,6 +1407,12 @@ static struct port_info { | |||
1407 | EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), | 1407 | EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), |
1408 | EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), | 1408 | EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), |
1409 | EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), | 1409 | EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), |
1410 | /* Access Music Virus TI */ | ||
1411 | EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"), | ||
1412 | PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0, | ||
1413 | SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | | ||
1414 | SNDRV_SEQ_PORT_TYPE_HARDWARE | | ||
1415 | SNDRV_SEQ_PORT_TYPE_SYNTHESIZER), | ||
1410 | }; | 1416 | }; |
1411 | 1417 | ||
1412 | static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) | 1418 | static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) |
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index a892bda03df9..406b74b65ffb 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h | |||
@@ -2073,6 +2073,33 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2073 | } | 2073 | } |
2074 | }, | 2074 | }, |
2075 | 2075 | ||
2076 | /* Access Music devices */ | ||
2077 | { | ||
2078 | /* VirusTI Desktop */ | ||
2079 | USB_DEVICE_VENDOR_SPEC(0x133e, 0x0815), | ||
2080 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
2081 | .ifnum = QUIRK_ANY_INTERFACE, | ||
2082 | .type = QUIRK_COMPOSITE, | ||
2083 | .data = &(const struct snd_usb_audio_quirk[]) { | ||
2084 | { | ||
2085 | .ifnum = 3, | ||
2086 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
2087 | .data = &(const struct snd_usb_midi_endpoint_info) { | ||
2088 | .out_cables = 0x0003, | ||
2089 | .in_cables = 0x0003 | ||
2090 | } | ||
2091 | }, | ||
2092 | { | ||
2093 | .ifnum = 4, | ||
2094 | .type = QUIRK_IGNORE_INTERFACE | ||
2095 | }, | ||
2096 | { | ||
2097 | .ifnum = -1 | ||
2098 | } | ||
2099 | } | ||
2100 | } | ||
2101 | }, | ||
2102 | |||
2076 | /* */ | 2103 | /* */ |
2077 | { | 2104 | { |
2078 | /* aka. Serato Scratch Live DJ Box */ | 2105 | /* aka. Serato Scratch Live DJ Box */ |