diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /sound/usb/midi.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'sound/usb/midi.c')
-rw-r--r-- | sound/usb/midi.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index b9c2bc65f51a..f9289102886a 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <sound/asequencer.h> | 54 | #include <sound/asequencer.h> |
55 | #include "usbaudio.h" | 55 | #include "usbaudio.h" |
56 | #include "midi.h" | 56 | #include "midi.h" |
57 | #include "power.h" | ||
57 | #include "helper.h" | 58 | #include "helper.h" |
58 | 59 | ||
59 | /* | 60 | /* |
@@ -784,7 +785,7 @@ static struct usb_protocol_ops snd_usbmidi_novation_ops = { | |||
784 | }; | 785 | }; |
785 | 786 | ||
786 | /* | 787 | /* |
787 | * "raw" protocol: used by the MOTU FastLane. | 788 | * "raw" protocol: just move raw MIDI bytes from/to the endpoint |
788 | */ | 789 | */ |
789 | 790 | ||
790 | static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep, | 791 | static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep, |
@@ -834,7 +835,14 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep, | |||
834 | 835 | ||
835 | if (!ep->ports[0].active) | 836 | if (!ep->ports[0].active) |
836 | return; | 837 | return; |
837 | count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2; | 838 | switch (snd_usb_get_speed(ep->umidi->dev)) { |
839 | case USB_SPEED_HIGH: | ||
840 | case USB_SPEED_SUPER: | ||
841 | count = 1; | ||
842 | break; | ||
843 | default: | ||
844 | count = 2; | ||
845 | } | ||
838 | count = snd_rawmidi_transmit(ep->ports[0].substream, | 846 | count = snd_rawmidi_transmit(ep->ports[0].substream, |
839 | urb->transfer_buffer, | 847 | urb->transfer_buffer, |
840 | count); | 848 | count); |
@@ -843,8 +851,8 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep, | |||
843 | return; | 851 | return; |
844 | } | 852 | } |
845 | 853 | ||
846 | memset(urb->transfer_buffer + count, 0xFD, 9 - count); | 854 | memset(urb->transfer_buffer + count, 0xFD, ep->max_transfer - count); |
847 | urb->transfer_buffer_length = count; | 855 | urb->transfer_buffer_length = ep->max_transfer; |
848 | } | 856 | } |
849 | 857 | ||
850 | static struct usb_protocol_ops snd_usbmidi_122l_ops = { | 858 | static struct usb_protocol_ops snd_usbmidi_122l_ops = { |
@@ -1037,6 +1045,7 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | |||
1037 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | 1045 | struct snd_usb_midi* umidi = substream->rmidi->private_data; |
1038 | struct usbmidi_out_port* port = NULL; | 1046 | struct usbmidi_out_port* port = NULL; |
1039 | int i, j; | 1047 | int i, j; |
1048 | int err; | ||
1040 | 1049 | ||
1041 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | 1050 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) |
1042 | if (umidi->endpoints[i].out) | 1051 | if (umidi->endpoints[i].out) |
@@ -1049,6 +1058,9 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | |||
1049 | snd_BUG(); | 1058 | snd_BUG(); |
1050 | return -ENXIO; | 1059 | return -ENXIO; |
1051 | } | 1060 | } |
1061 | err = usb_autopm_get_interface(umidi->iface); | ||
1062 | if (err < 0) | ||
1063 | return -EIO; | ||
1052 | substream->runtime->private_data = port; | 1064 | substream->runtime->private_data = port; |
1053 | port->state = STATE_UNKNOWN; | 1065 | port->state = STATE_UNKNOWN; |
1054 | substream_open(substream, 1); | 1066 | substream_open(substream, 1); |
@@ -1057,7 +1069,10 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | |||
1057 | 1069 | ||
1058 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) | 1070 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) |
1059 | { | 1071 | { |
1072 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | ||
1073 | |||
1060 | substream_open(substream, 0); | 1074 | substream_open(substream, 0); |
1075 | usb_autopm_put_interface(umidi->iface); | ||
1061 | return 0; | 1076 | return 0; |
1062 | } | 1077 | } |
1063 | 1078 | ||
@@ -1286,8 +1301,16 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, | |||
1286 | case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */ | 1301 | case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */ |
1287 | case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */ | 1302 | case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */ |
1288 | case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */ | 1303 | case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */ |
1304 | case USB_ID(0xfc08, 0x0101): /* Unknown vendor Cable */ | ||
1289 | ep->max_transfer = 4; | 1305 | ep->max_transfer = 4; |
1290 | break; | 1306 | break; |
1307 | /* | ||
1308 | * Some devices only work with 9 bytes packet size: | ||
1309 | */ | ||
1310 | case USB_ID(0x0644, 0x800E): /* Tascam US-122L */ | ||
1311 | case USB_ID(0x0644, 0x800F): /* Tascam US-144 */ | ||
1312 | ep->max_transfer = 9; | ||
1313 | break; | ||
1291 | } | 1314 | } |
1292 | for (i = 0; i < OUTPUT_URBS; ++i) { | 1315 | for (i = 0; i < OUTPUT_URBS; ++i) { |
1293 | buffer = usb_alloc_coherent(umidi->dev, | 1316 | buffer = usb_alloc_coherent(umidi->dev, |
@@ -1722,13 +1745,7 @@ static int roland_load_info(struct snd_kcontrol *kcontrol, | |||
1722 | { | 1745 | { |
1723 | static const char *const names[] = { "High Load", "Light Load" }; | 1746 | static const char *const names[] = { "High Load", "Light Load" }; |
1724 | 1747 | ||
1725 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1748 | return snd_ctl_enum_info(info, 1, 2, names); |
1726 | info->count = 1; | ||
1727 | info->value.enumerated.items = 2; | ||
1728 | if (info->value.enumerated.item > 1) | ||
1729 | info->value.enumerated.item = 1; | ||
1730 | strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); | ||
1731 | return 0; | ||
1732 | } | 1749 | } |
1733 | 1750 | ||
1734 | static int roland_load_get(struct snd_kcontrol *kcontrol, | 1751 | static int roland_load_get(struct snd_kcontrol *kcontrol, |
@@ -2115,7 +2132,7 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2115 | umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; | 2132 | umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; |
2116 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 2133 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
2117 | break; | 2134 | break; |
2118 | case QUIRK_MIDI_FASTLANE: | 2135 | case QUIRK_MIDI_RAW_BYTES: |
2119 | umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; | 2136 | umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; |
2120 | /* | 2137 | /* |
2121 | * Interface 1 contains isochronous endpoints, but with the same | 2138 | * Interface 1 contains isochronous endpoints, but with the same |
@@ -2126,7 +2143,8 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2126 | * interface 0, so we have to make sure that the USB core looks | 2143 | * interface 0, so we have to make sure that the USB core looks |
2127 | * again at interface 0 by calling usb_set_interface() on it. | 2144 | * again at interface 0 by calling usb_set_interface() on it. |
2128 | */ | 2145 | */ |
2129 | usb_set_interface(umidi->dev, 0, 0); | 2146 | if (umidi->usb_id == USB_ID(0x07fd, 0x0001)) /* MOTU Fastlane */ |
2147 | usb_set_interface(umidi->dev, 0, 0); | ||
2130 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 2148 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
2131 | break; | 2149 | break; |
2132 | case QUIRK_MIDI_EMAGIC: | 2150 | case QUIRK_MIDI_EMAGIC: |