diff options
Diffstat (limited to 'sound/usb/midi.c')
-rw-r--r-- | sound/usb/midi.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index f9289102886a..c83f6143c0eb 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -47,6 +47,7 @@ #include <linux/usb.h> #include <linux/wait.h> #include <linux/usb/audio.h> +#include <linux/module.h> #include <sound/core.h> #include <sound/control.h> @@ -816,6 +817,22 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = { .output = snd_usbmidi_raw_output, }; +/* + * FTDI protocol: raw MIDI bytes, but input packets have two modem status bytes. + */ + +static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep, + uint8_t* buffer, int buffer_length) +{ + if (buffer_length > 2) + snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2); +} + +static struct usb_protocol_ops snd_usbmidi_ftdi_ops = { + .input = snd_usbmidi_ftdi_input, + .output = snd_usbmidi_raw_output, +}; + static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep, uint8_t *buffer, int buffer_length) { @@ -2163,6 +2180,17 @@ int snd_usbmidi_create(struct snd_card *card, /* endpoint 1 is input-only */ endpoints[1].out_cables = 0; break; + case QUIRK_MIDI_FTDI: + umidi->usb_protocol_ops = &snd_usbmidi_ftdi_ops; + + /* set baud rate to 31250 (48 MHz / 16 / 96) */ + err = usb_control_msg(umidi->dev, usb_sndctrlpipe(umidi->dev, 0), + 3, 0x40, 0x60, 0, NULL, 0, 1000); + if (err < 0) + break; + + err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); + break; default: snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); err = -ENXIO; |