summaryrefslogtreecommitdiffstats
path: root/sound/usb/midi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/midi.c')
-rw-r--r--sound/usb/midi.c28
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;