ALSA: usb-audio: add Yamaha MOX6/MOX8 support
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / sound / usb / midi.c
index f9289102886ad890987a0d27739a19f1e48afdd4..c83f6143c0eb34d8f77f969e1928427458b4268a 100644 (file)
@@ -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;