aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/usbmidi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usbmidi.c')
-rw-r--r--sound/usb/usbmidi.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 6676a177c99e..5962e4b84423 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -669,6 +669,42 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = {
669 .output = snd_usbmidi_raw_output, 669 .output = snd_usbmidi_raw_output,
670}; 670};
671 671
672static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep,
673 uint8_t *buffer, int buffer_length)
674{
675 if (buffer_length != 9)
676 return;
677 buffer_length = 8;
678 while (buffer_length && buffer[buffer_length - 1] == 0xFD)
679 buffer_length--;
680 if (buffer_length)
681 snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
682}
683
684static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep)
685{
686 int count;
687
688 if (!ep->ports[0].active)
689 return;
690 count = ep->urb->dev->speed == USB_SPEED_HIGH ? 1 : 2;
691 count = snd_rawmidi_transmit(ep->ports[0].substream,
692 ep->urb->transfer_buffer,
693 count);
694 if (count < 1) {
695 ep->ports[0].active = 0;
696 return;
697 }
698
699 memset(ep->urb->transfer_buffer + count, 0xFD, 9 - count);
700 ep->urb->transfer_buffer_length = count;
701}
702
703static struct usb_protocol_ops snd_usbmidi_122l_ops = {
704 .input = snd_usbmidi_us122l_input,
705 .output = snd_usbmidi_us122l_output,
706};
707
672/* 708/*
673 * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching. 709 * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching.
674 */ 710 */
@@ -1076,6 +1112,15 @@ void snd_usbmidi_disconnect(struct list_head* p)
1076 } 1112 }
1077 if (ep->in) 1113 if (ep->in)
1078 usb_kill_urb(ep->in->urb); 1114 usb_kill_urb(ep->in->urb);
1115 /* free endpoints here; later call can result in Oops */
1116 if (ep->out) {
1117 snd_usbmidi_out_endpoint_delete(ep->out);
1118 ep->out = NULL;
1119 }
1120 if (ep->in) {
1121 snd_usbmidi_in_endpoint_delete(ep->in);
1122 ep->in = NULL;
1123 }
1079 } 1124 }
1080 del_timer_sync(&umidi->error_timer); 1125 del_timer_sync(&umidi->error_timer);
1081} 1126}
@@ -1714,6 +1759,9 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1714 umidi->usb_protocol_ops = 1759 umidi->usb_protocol_ops =
1715 &snd_usbmidi_maudio_broken_running_status_ops; 1760 &snd_usbmidi_maudio_broken_running_status_ops;
1716 break; 1761 break;
1762 case QUIRK_MIDI_US122L:
1763 umidi->usb_protocol_ops = &snd_usbmidi_122l_ops;
1764 /* fall through */
1717 case QUIRK_MIDI_FIXED_ENDPOINT: 1765 case QUIRK_MIDI_FIXED_ENDPOINT:
1718 memcpy(&endpoints[0], quirk->data, 1766 memcpy(&endpoints[0], quirk->data,
1719 sizeof(struct snd_usb_midi_endpoint_info)); 1767 sizeof(struct snd_usb_midi_endpoint_info));