diff options
Diffstat (limited to 'sound/usb/usbmidi.c')
-rw-r--r-- | sound/usb/usbmidi.c | 48 |
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 | ||
672 | static 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 | |||
684 | static 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 | |||
703 | static 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)); |