]>
Commit | Line | Data |
---|---|---|
6b39e30d TI |
1 | ================= |
2 | MIDI 2.0 on Linux | |
3 | ================= | |
4 | ||
5 | General | |
6 | ======= | |
7 | ||
8 | MIDI 2.0 is an extended protocol for providing higher resolutions and | |
9 | more fine controls over the legacy MIDI 1.0. The fundamental changes | |
10 | introduced for supporting MIDI 2.0 are: | |
11 | ||
12 | - Support of Universal MIDI Packet (UMP) | |
13 | - Support of MIDI 2.0 protocol messages | |
14 | - Transparent conversions between UMP and legacy MIDI 1.0 byte stream | |
15 | - MIDI-CI for property and profile configurations | |
16 | ||
17 | UMP is a new container format to hold all MIDI protocol 1.0 and MIDI | |
18 | 2.0 protocol messages. Unlike the former byte stream, it's 32bit | |
19 | aligned, and each message can be put in a single packet. UMP can send | |
20 | the events up to 16 "UMP Groups", where each UMP Group contain up to | |
21 | 16 MIDI channels. | |
22 | ||
23 | MIDI 2.0 protocol is an extended protocol to achieve the higher | |
24 | resolution and more controls over the old MIDI 1.0 protocol. | |
25 | ||
26 | MIDI-CI is a high-level protocol that can talk with the MIDI device | |
27 | for the flexible profiles and configurations. It's represented in the | |
28 | form of special SysEx. | |
29 | ||
30 | For Linux implementations, the kernel supports the UMP transport and | |
31 | the encoding/decoding of MIDI protocols on UMP, while MIDI-CI is | |
32 | supported in user-space over the standard SysEx. | |
33 | ||
34 | As of this writing, only USB MIDI device supports the UMP and Linux | |
35 | 2.0 natively. The UMP support itself is pretty generic, hence it | |
36 | could be used by other transport layers, although it could be | |
37 | implemented differently (e.g. as a ALSA sequencer client), too. | |
38 | ||
39 | The access to UMP devices are provided in two ways: the access via | |
40 | rawmidi device and the access via ALSA sequencer API. | |
41 | ||
42 | ALSA sequencer API was extended to allow the payload of UMP packets. | |
43 | It's allowed to connect freely between MIDI 1.0 and MIDI 2.0 sequencer | |
44 | clients, and the events are converted transparently. | |
45 | ||
46 | ||
47 | Kernel Configuration | |
48 | ==================== | |
49 | ||
50 | The following new configs are added for supporting MIDI 2.0: | |
51 | `CONFIG_SND_UMP`, `CONFIG_SND_UMP_LEGACY_RAWMIDI`, | |
52 | `CONFIG_SND_SEQ_UMP`, `CONFIG_SND_SEQ_UMP_CLIENT`, and | |
53 | `CONFIG_SND_USB_AUDIO_MIDI_V2`. The first visible one is | |
54 | `CONFIG_SND_USB_AUDIO_MIDI_V2`, and when you choose it (to set `=y`), | |
55 | the core support for UMP (`CONFIG_SND_UMP`) and the sequencer binding | |
56 | (`CONFIG_SND_SEQ_UMP_CLIENT`) will be automatically selected. | |
57 | ||
58 | Additionally, `CONFIG_SND_UMP_LEGACY_RAWMIDI=y` will enable the | |
59 | support for the legacy raw MIDI device for UMP Endpoints. | |
60 | ||
61 | ||
62 | Rawmidi Device with USB MIDI 2.0 | |
63 | ================================ | |
64 | ||
65 | When a device supports MIDI 2.0, the USB-audio driver probes and uses | |
66 | the MIDI 2.0 interface (that is found always at the altset 1) as | |
67 | default instead of the MIDI 1.0 interface (at altset 0). You can | |
68 | switch back to the binding with the old MIDI 1.0 interface by passing | |
69 | `midi2_enable=0` option to snd-usb-audio driver module, too. | |
70 | ||
febdfa0e TI |
71 | The USB audio driver tries to query the UMP Endpoint and UMP Function |
72 | Block information that are provided since UMP v1.1, and builds up the | |
73 | topology based on those information. When the device is older and | |
74 | doesn't respond to the new UMP inquiries, the driver falls back and | |
75 | builds the topology based on Group Terminal Block (GTB) information | |
76 | from the USB descriptor. Some device might be screwed up by the | |
60edec9b TI |
77 | unexpected UMP command; in such a case, pass `midi2_ump_probe=0` |
78 | option to snd-usb-audio driver for skipping the UMP v1.1 inquiries. | |
febdfa0e | 79 | |
6b39e30d TI |
80 | When the MIDI 2.0 device is probed, the kernel creates a rawmidi |
81 | device for each UMP Endpoint of the device. Its device name is | |
82 | `/dev/snd/umpC*D*` and different from the standard rawmidi device name | |
83 | `/dev/snd/midiC*D*` for MIDI 1.0, in order to avoid confusing the | |
84 | legacy applications accessing mistakenly to UMP devices. | |
85 | ||
86 | You can read and write UMP packet data directly from/to this UMP | |
87 | rawmidi device. For example, reading via `hexdump` like below will | |
88 | show the incoming UMP packets of the card 0 device 0 in the hex | |
89 | format:: | |
90 | ||
91 | % hexdump -C /dev/snd/umpC0D0 | |
92 | 00000000 01 07 b0 20 00 07 b0 20 64 3c 90 20 64 3c 80 20 |... ... d<. d<. | | |
93 | ||
94 | Unlike the MIDI 1.0 byte stream, UMP is a 32bit packet, and the size | |
95 | for reading or writing the device is also aligned to 32bit (which is 4 | |
96 | bytes). | |
97 | ||
98 | The 32-bit words in the UMP packet payload are always in CPU native | |
99 | endianness. Transport drivers are responsible to convert UMP words | |
100 | from / to system endianness to required transport endianness / byte | |
101 | order. | |
102 | ||
103 | When `CONFIG_SND_UMP_LEGACY_RAWMIDI` is set, the driver creates | |
104 | another standard raw MIDI device additionally as `/dev/snd/midiC*D*`. | |
105 | This contains 16 substreams, and each substream corresponds to a | |
106 | (0-based) UMP Group. Legacy applications can access to the specified | |
107 | group via each substream in MIDI 1.0 byte stream format. With the | |
108 | ALSA rawmidi API, you can open the arbitrary substream, while just | |
109 | opening `/dev/snd/midiC*D*` will end up with opening the first | |
110 | substream. | |
111 | ||
112 | Each UMP Endpoint can provide the additional information, constructed | |
febdfa0e TI |
113 | from the information inquired via UMP 1.1 Stream messages or USB MIDI |
114 | 2.0 descriptors. And a UMP Endpoint may contain one or more UMP | |
115 | Blocks, where UMP Block is an abstraction introduced in the ALSA UMP | |
116 | implementations to represent the associations among UMP Groups. UMP | |
117 | Block corresponds to Function Block in UMP 1.1 specification. When | |
118 | UMP 1.1 Function Block information isn't available, it's filled | |
119 | partially from Group Terminal Block (GTB) as defined in USB MIDI 2.0 | |
120 | specifications. | |
121 | ||
6b39e30d TI |
122 | The information of UMP Endpoints and UMP Blocks are found in the proc |
123 | file `/proc/asound/card*/midi*`. For example:: | |
124 | ||
125 | % cat /proc/asound/card1/midi0 | |
126 | ProtoZOA MIDI | |
127 | ||
128 | Type: UMP | |
129 | EP Name: ProtoZOA | |
130 | EP Product ID: ABCD12345678 | |
131 | UMP Version: 0x0000 | |
132 | Protocol Caps: 0x00000100 | |
133 | Protocol: 0x00000100 | |
134 | Num Blocks: 3 | |
135 | ||
136 | Block 0 (ProtoZOA Main) | |
137 | Direction: bidirection | |
138 | Active: Yes | |
139 | Groups: 1-1 | |
140 | Is MIDI1: No | |
141 | ||
142 | Block 1 (ProtoZOA Ext IN) | |
143 | Direction: output | |
144 | Active: Yes | |
145 | Groups: 2-2 | |
146 | Is MIDI1: Yes (Low Speed) | |
147 | .... | |
148 | ||
149 | Note that `Groups` field shown in the proc file above indicates the | |
150 | 1-based UMP Group numbers (from-to). | |
151 | ||
152 | Those additional UMP Endpoint and UMP Block information can be | |
153 | obtained via the new ioctls `SNDRV_UMP_IOCTL_ENDPOINT_INFO` and | |
154 | `SNDRV_UMP_IOCTL_BLOCK_INFO`, respectively. | |
155 | ||
156 | The rawmidi name and the UMP Endpoint name are usually identical, and | |
157 | in the case of USB MIDI, it's taken from `iInterface` of the | |
158 | corresponding USB MIDI interface descriptor. If it's not provided, | |
159 | it's copied from `iProduct` of the USB device descriptor as a | |
160 | fallback. | |
161 | ||
162 | The Endpoint Product ID is a string field and supposed to be unique. | |
163 | It's copied from `iSerialNumber` of the device for USB MIDI. | |
164 | ||
165 | The protocol capabilities and the actual protocol bits are defined in | |
166 | `asound.h`. | |
167 | ||
168 | ||
169 | ALSA Sequencer with USB MIDI 2.0 | |
170 | ================================ | |
171 | ||
172 | In addition to the rawmidi interfaces, ALSA sequencer interface | |
173 | supports the new UMP MIDI 2.0 device, too. Now, each ALSA sequencer | |
174 | client may set its MIDI version (0, 1 or 2) to declare itself being | |
175 | either the legacy, UMP MIDI 1.0 or UMP MIDI 2.0 device, respectively. | |
176 | The first, legacy client is the one that sends/receives the old | |
177 | sequencer event as was. Meanwhile, UMP MIDI 1.0 and 2.0 clients send | |
178 | and receive in the extended event record for UMP. The MIDI version is | |
179 | seen in the new `midi_version` field of `snd_seq_client_info`. | |
180 | ||
181 | A UMP packet can be sent/received in a sequencer event embedded by | |
182 | specifying the new event flag bit `SNDRV_SEQ_EVENT_UMP`. When this | |
183 | flag is set, the event has 16 byte (128 bit) data payload for holding | |
184 | the UMP packet. Without the `SNDRV_SEQ_EVENT_UMP` bit flag, the event | |
185 | is treated as a legacy event as it was (with max 12 byte data | |
186 | payload). | |
187 | ||
188 | With `SNDRV_SEQ_EVENT_UMP` flag set, the type field of a UMP sequencer | |
189 | event is ignored (but it should be set to 0 as default). | |
190 | ||
191 | The type of each client can be seen in `/proc/asound/seq/clients`. | |
192 | For example:: | |
193 | ||
194 | % cat /proc/asound/seq/clients | |
195 | Client info | |
196 | cur clients : 3 | |
197 | .... | |
198 | Client 14 : "Midi Through" [Kernel Legacy] | |
199 | Port 0 : "Midi Through Port-0" (RWe-) | |
200 | Client 20 : "ProtoZOA" [Kernel UMP MIDI1] | |
201 | UMP Endpoint: ProtoZOA | |
202 | UMP Block 0: ProtoZOA Main [Active] | |
203 | Groups: 1-1 | |
204 | UMP Block 1: ProtoZOA Ext IN [Active] | |
205 | Groups: 2-2 | |
206 | UMP Block 2: ProtoZOA Ext OUT [Active] | |
207 | Groups: 3-3 | |
208 | Port 0 : "MIDI 2.0" (RWeX) [In/Out] | |
209 | Port 1 : "ProtoZOA Main" (RWeX) [In/Out] | |
210 | Port 2 : "ProtoZOA Ext IN" (-We-) [Out] | |
211 | Port 3 : "ProtoZOA Ext OUT" (R-e-) [In] | |
212 | ||
213 | Here you can find two types of kernel clients, "Legacy" for client 14, | |
214 | and "UMP MIDI1" for client 20, which is a USB MIDI 2.0 device. | |
215 | A USB MIDI 2.0 client gives always the port 0 as "MIDI 2.0" and the | |
216 | rest ports from 1 for each UMP Group (e.g. port 1 for Group 1). | |
217 | In this example, the device has three active groups (Main, Ext IN and | |
218 | Ext OUT), and those are exposed as sequencer ports from 1 to 3. | |
219 | The "MIDI 2.0" port is for a UMP Endpoint, and its difference from | |
220 | other UMP Group ports is that UMP Endpoint port sends the events from | |
221 | the all ports on the device ("catch-all"), while each UMP Group port | |
222 | sends only the events from the given UMP Group. | |
febdfa0e TI |
223 | Also, UMP groupless messages (such as the UMP message type 0x0f) are |
224 | sent only to the UMP Endpoint port. | |
6b39e30d TI |
225 | |
226 | Note that, although each UMP sequencer client usually creates 16 | |
227 | ports, those ports that don't belong to any UMP Blocks (or belonging | |
228 | to inactive UMP Blocks) are marked as inactive, and they don't appear | |
229 | in the proc outputs. In the example above, the sequencer ports from 4 | |
230 | to 16 are present but not shown there. | |
231 | ||
232 | The proc file above shows the UMP Block information, too. The same | |
233 | entry (but with more detailed information) is found in the rawmidi | |
234 | proc output. | |
235 | ||
236 | When clients are connected between different MIDI versions, the events | |
237 | are translated automatically depending on the client's version, not | |
238 | only between the legacy and the UMP MIDI 1.0/2.0 types, but also | |
239 | between UMP MIDI 1.0 and 2.0 types, too. For example, running | |
240 | `aseqdump` program on the ProtoZOA Main port in the legacy mode will | |
241 | give you the output like:: | |
242 | ||
243 | % aseqdump -p 20:1 | |
244 | Waiting for data. Press Ctrl+C to end. | |
245 | Source Event Ch Data | |
246 | 20:1 Note on 0, note 60, velocity 100 | |
247 | 20:1 Note off 0, note 60, velocity 100 | |
248 | 20:1 Control change 0, controller 11, value 4 | |
249 | ||
250 | When you run `aseqdump` in MIDI 2.0 mode, it'll receive the high | |
251 | precision data like:: | |
252 | ||
253 | % aseqdump -u 2 -p 20:1 | |
254 | Waiting for data. Press Ctrl+C to end. | |
255 | Source Event Ch Data | |
256 | 20:1 Note on 0, note 60, velocity 0xc924, attr type = 0, data = 0x0 | |
257 | 20:1 Note off 0, note 60, velocity 0xc924, attr type = 0, data = 0x0 | |
258 | 20:1 Control change 0, controller 11, value 0x2000000 | |
259 | ||
260 | while the data is automatically converted by ALSA sequencer core. | |
261 | ||
262 | ||
263 | Rawmidi API Extensions | |
264 | ====================== | |
265 | ||
266 | * The additional UMP Endpoint information can be obtained via the new | |
267 | ioctl `SNDRV_UMP_IOCTL_ENDPOINT_INFO`. It contains the associated | |
268 | card and device numbers, the bit flags, the protocols, the number of | |
269 | UMP Blocks, the name string of the endpoint, etc. | |
270 | ||
271 | The protocols are specified in two field, the protocol capabilities | |
272 | and the current protocol. Both contain the bit flags specifying the | |
273 | MIDI protocol version (`SNDRV_UMP_EP_INFO_PROTO_MIDI1` or | |
274 | `SNDRV_UMP_EP_INFO_PROTO_MIDI2`) in the upper byte and the jitter | |
275 | reduction timestamp (`SNDRV_UMP_EP_INFO_PROTO_JRTS_TX` and | |
276 | `SNDRV_UMP_EP_INFO_PROTO_JRTS_RX`) in the lower byte. | |
277 | ||
278 | A UMP Endpoint may contain up to 32 UMP Blocks, and the number of | |
279 | the currently assigned blocks are shown in the Endpoint information. | |
280 | ||
281 | * Each UMP Block information can be obtained via another new ioctl | |
282 | `SNDRV_UMP_IOCTL_BLOCK_INFO`. The block ID number (0-based) has to | |
283 | be passed for the block to query. The received data contains the | |
284 | associated the direction of the block, the first associated group ID | |
285 | (0-based) and the number of groups, the name string of the block, | |
286 | etc. | |
287 | ||
288 | The direction is either `SNDRV_UMP_DIR_INPUT`, | |
289 | `SNDRV_UMP_DIR_OUTPUT` or `SNDRV_UMP_DIR_BIDIRECTION`. | |
290 | ||
febdfa0e TI |
291 | * For the device supports UMP v1.1, the UMP MIDI protocol can be |
292 | switched via "Stream Configuration Request" message (UMP type 0x0f, | |
293 | status 0x05). When UMP core receives such a message, it updates the | |
294 | UMP EP info and the corresponding sequencer clients as well. | |
295 | ||
6b39e30d TI |
296 | |
297 | Control API Extensions | |
298 | ====================== | |
299 | ||
300 | * The new ioctl `SNDRV_CTL_IOCTL_UMP_NEXT_DEVICE` is introduced for | |
301 | querying the next UMP rawmidi device, while the existing ioctl | |
302 | `SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE` queries only the legacy | |
303 | rawmidi devices. | |
304 | ||
305 | For setting the subdevice (substream number) to be opened, use the | |
306 | ioctl `SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE` like the normal | |
307 | rawmidi. | |
308 | ||
309 | * Two new ioctls `SNDRV_CTL_IOCTL_UMP_ENDPOINT_INFO` and | |
310 | `SNDRV_CTL_IOCTL_UMP_BLOCK_INFO` provide the UMP Endpoint and UMP | |
311 | Block information of the specified UMP device via ALSA control API | |
312 | without opening the actual (UMP) rawmidi device. | |
313 | The `card` field is ignored upon inquiry, always tied with the card | |
314 | of the control interface. | |
315 | ||
316 | ||
317 | Sequencer API Extensions | |
318 | ======================== | |
319 | ||
320 | * `midi_version` field is added to `snd_seq_client_info` to indicate | |
321 | the current MIDI version (either 0, 1 or 2) of each client. | |
322 | When `midi_version` is 1 or 2, the alignment of read from a UMP | |
323 | sequencer client is also changed from the former 28 bytes to 32 | |
324 | bytes for the extended payload. The alignment size for the write | |
325 | isn't changed, but each event size may differ depending on the new | |
326 | bit flag below. | |
327 | ||
328 | * `SNDRV_SEQ_EVENT_UMP` flag bit is added for each sequencer event | |
329 | flags. When this bit flag is set, the sequencer event is extended | |
330 | to have a larger payload of 16 bytes instead of the legacy 12 | |
331 | bytes, and the event contains the UMP packet in the payload. | |
332 | ||
333 | * The new sequencer port type bit (`SNDRV_SEQ_PORT_TYPE_MIDI_UMP`) | |
334 | indicates the port being UMP-capable. | |
335 | ||
336 | * The sequencer ports have new capability bits to indicate the | |
337 | inactive ports (`SNDRV_SEQ_PORT_CAP_INACTIVE`) and the UMP Endpoint | |
338 | port (`SNDRV_SEQ_PORT_CAP_UMP_ENDPOINT`). | |
339 | ||
340 | * The event conversion of ALSA sequencer clients can be suppressed the | |
341 | new filter bit `SNDRV_SEQ_FILTER_NO_CONVERT` set to the client info. | |
342 | For example, the kernel pass-through client (`snd-seq-dummy`) sets | |
343 | this flag internally. | |
344 | ||
345 | * The port information gained the new field `direction` to indicate | |
346 | the direction of the port (either `SNDRV_SEQ_PORT_DIR_INPUT`, | |
347 | `SNDRV_SEQ_PORT_DIR_OUTPUT` or `SNDRV_SEQ_PORT_DIR_BIDIRECTION`). | |
348 | ||
349 | * Another additional field for the port information is `ump_group` | |
350 | which specifies the associated UMP Group Number (1-based). | |
351 | When it's non-zero, the UMP group field in the UMP packet updated | |
352 | upon delivery to the specified group (corrected to be 0-based). | |
353 | Each sequencer port is supposed to set this field if it's a port to | |
354 | specific to a certain UMP group. | |
355 | ||
356 | * Each client may set the additional event filter for UMP Groups in | |
357 | `group_filter` bitmap. The filter consists of bitmap from 1-based | |
358 | Group numbers. For example, when the bit 1 is set, messages from | |
359 | Group 1 (i.e. the very first group) are filtered and not delivered. | |
febdfa0e | 360 | The bit 0 is used for filtering UMP groupless messages. |
6b39e30d TI |
361 | |
362 | * Two new ioctls are added for UMP-capable clients: | |
363 | `SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO` and | |
364 | `SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO`. They are used to get and set | |
365 | either `snd_ump_endpoint_info` or `snd_ump_block_info` data | |
366 | associated with the sequencer client. The USB MIDI driver provides | |
367 | those information from the underlying UMP rawmidi, while a | |
368 | user-space client may provide its own data via `*_SET` ioctl. | |
369 | For an Endpoint data, pass 0 to the `type` field, while for a Block | |
370 | data, pass the block number + 1 to the `type` field. | |
371 | Setting the data for a kernel client shall result in an error. | |
febdfa0e TI |
372 | |
373 | * With UMP 1.1, Function Block information may be changed | |
374 | dynamically. When the update of Function Block is received from the | |
375 | device, ALSA sequencer core changes the corresponding sequencer port | |
376 | name and attributes accordingly, and notifies the changes via the | |
377 | announcement to the ALSA sequencer system port, similarly like the | |
378 | normal port change notification. | |
e240cff9 TI |
379 | |
380 | ||
381 | MIDI2 USB Gadget Function Driver | |
382 | ================================ | |
383 | ||
384 | The latest kernel contains the support for USB MIDI 2.0 gadget | |
385 | function driver, which can be used for prototyping and debugging MIDI | |
386 | 2.0 features. | |
387 | ||
388 | `CONFIG_USB_GADGET`, `CONFIG_USB_CONFIGFS` and | |
389 | `CONFIG_USB_CONFIGFS_F_MIDI2` need to be enabled for the MIDI2 gadget | |
390 | driver. | |
391 | ||
392 | In addition, for using a gadget driver, you need a working UDC driver. | |
393 | In the example below, we use `dummy_hcd` driver (enabled via | |
394 | `CONFIG_USB_DUMMY_HCD`) that is available on PC and VM for debugging | |
395 | purpose. There are other UDC drivers depending on the platform, and | |
396 | those can be used for a real device, instead, too. | |
397 | ||
398 | At first, on a system to run the gadget, load `libcomposite` module:: | |
399 | ||
400 | % modprobe libcomposite | |
401 | ||
402 | and you'll have `usb_gadget` subdirectory under configfs space | |
403 | (typically `/sys/kernel/config` on modern OS). Then create a gadget | |
404 | instance and add configurations there, for example:: | |
405 | ||
406 | % cd /sys/kernel/config | |
407 | % mkdir usb_gadget/g1 | |
408 | ||
409 | % cd usb_gadget/g1 | |
410 | % mkdir configs/c.1 | |
411 | % mkdir functions/midi2.usb0 | |
412 | ||
413 | % echo 0x0004 > idProduct | |
414 | % echo 0x17b3 > idVendor | |
415 | % mkdir strings/0x409 | |
416 | % echo "ACME Enterprises" > strings/0x409/manufacturer | |
417 | % echo "ACMESynth" > strings/0x409/product | |
418 | % echo "ABCD12345" > strings/0x409/serialnumber | |
419 | ||
420 | % mkdir configs/c.1/strings/0x409 | |
421 | % echo "Monosynth" > configs/c.1/strings/0x409/configuration | |
422 | % echo 120 > configs/c.1/MaxPower | |
423 | ||
424 | At this point, there must be a subdirectory `ep.0`, and that is the | |
425 | configuration for a UMP Endpoint. You can fill the Endpoint | |
426 | information like:: | |
427 | ||
428 | % echo "ACMESynth" > functions/midi2.usb0/iface_name | |
429 | % echo "ACMESynth" > functions/midi2.usb0/ep.0/ep_name | |
430 | % echo "ABCD12345" > functions/midi2.usb0/ep.0/product_id | |
431 | % echo 0x0123 > functions/midi2.usb0/ep.0/family | |
432 | % echo 0x4567 > functions/midi2.usb0/ep.0/model | |
433 | % echo 0x123456 > functions/midi2.usb0/ep.0/manufacturer | |
434 | % echo 0x12345678 > functions/midi2.usb0/ep.0/sw_revision | |
435 | ||
436 | The default MIDI protocol can be set either 1 or 2:: | |
437 | ||
438 | % echo 2 > functions/midi2.usb0/ep.0/protocol | |
439 | ||
440 | And, you can find a subdirectory `block.0` under this Endpoint | |
441 | subdirectory. This defines the Function Block information:: | |
442 | ||
443 | % echo "Monosynth" > functions/midi2.usb0/ep.0/block.0/name | |
444 | % echo 0 > functions/midi2.usb0/ep.0/block.0/first_group | |
445 | % echo 1 > functions/midi2.usb0/ep.0/block.0/num_groups | |
446 | ||
447 | Finally, link the configuration and enable it:: | |
448 | ||
449 | % ln -s functions/midi2.usb0 configs/c.1 | |
450 | % echo dummy_udc.0 > UDC | |
451 | ||
452 | where `dummy_udc.0` is an example case and it differs depending on the | |
453 | system. You can find the UDC instances in `/sys/class/udc` and pass | |
454 | the found name instead:: | |
455 | ||
456 | % ls /sys/class/udc | |
457 | dummy_udc.0 | |
458 | ||
459 | Now, the MIDI 2.0 gadget device is enabled, and the gadget host | |
460 | creates a new sound card instance containing a UMP rawmidi device by | |
461 | `f_midi2` driver:: | |
462 | ||
463 | % cat /proc/asound/cards | |
464 | .... | |
465 | 1 [Gadget ]: f_midi2 - MIDI 2.0 Gadget | |
466 | MIDI 2.0 Gadget | |
467 | ||
468 | And on the connected host, a similar card should appear, too, but with | |
469 | the card and device names given in the configfs above:: | |
470 | ||
471 | % cat /proc/asound/cards | |
472 | .... | |
473 | 2 [ACMESynth ]: USB-Audio - ACMESynth | |
474 | ACME Enterprises ACMESynth at usb-dummy_hcd.0-1, high speed | |
475 | ||
476 | You can play a MIDI file on the gadget side:: | |
477 | ||
478 | % aplaymidi -p 20:1 to_host.mid | |
479 | ||
480 | and this will appear as an input from a MIDI device on the connected | |
481 | host:: | |
482 | ||
483 | % aseqdump -p 20:0 -u 2 | |
484 | ||
485 | Vice versa, a playback on the connected host will work as an input on | |
486 | the gadget, too. | |
487 | ||
488 | Each Function Block may have different direction and UI-hint, | |
489 | specified via `direction` and `ui_hint` attributes. | |
490 | Passing `1` is for input-only, `2` for out-only and `3` for | |
491 | bidirectional (the default value). For example:: | |
492 | ||
493 | % echo 2 > functions/midi2.usb0/ep.0/block.0/direction | |
494 | % echo 2 > functions/midi2.usb0/ep.0/block.0/ui_hint | |
495 | ||
496 | When you need more than one Function Blocks, you can create | |
497 | subdirectories `block.1`, `block.2`, etc dynamically, and configure | |
498 | them in the configuration procedure above before linking. | |
499 | For example, to create a second Function Block for a keyboard:: | |
500 | ||
501 | % mkdir functions/midi2.usb0/ep.0/block.1 | |
502 | % echo "Keyboard" > functions/midi2.usb0/ep.0/block.1/name | |
503 | % echo 1 > functions/midi2.usb0/ep.0/block.1/first_group | |
504 | % echo 1 > functions/midi2.usb0/ep.0/block.1/num_groups | |
505 | % echo 1 > functions/midi2.usb0/ep.0/block.1/direction | |
506 | % echo 1 > functions/midi2.usb0/ep.0/block.1/ui_hint | |
507 | ||
508 | The `block.*` subdirectories can be removed dynamically, too (except | |
509 | for `block.0` which is persistent). | |
510 | ||
511 | For assigning a Function Block for MIDI 1.0 I/O, set up in `is_midi1` | |
512 | attribute. 1 is for MIDI 1.0, and 2 is for MIDI 1.0 with low speed | |
513 | connection:: | |
514 | ||
515 | % echo 2 > functions/midi2.usb0/ep.0/block.1/is_midi1 | |
516 | ||
517 | For disabling the processing of UMP Stream messages in the gadget | |
a3ca016a | 518 | driver, pass `0` to `process_ump` attribute in the top-level config:: |
e240cff9 TI |
519 | |
520 | % echo 0 > functions/midi2.usb0/process_ump | |
521 | ||
522 | The MIDI 1.0 interface at altset 0 is supported by the gadget driver, | |
523 | too. When MIDI 1.0 interface is selected by the connected host, the | |
524 | UMP I/O on the gadget is translated from/to USB MIDI 1.0 packets | |
525 | accordingly while the gadget driver keeps communicating with the | |
526 | user-space over UMP rawmidi. | |
527 | ||
528 | MIDI 1.0 ports are set up from the config in each Function Block. | |
529 | For example:: | |
530 | ||
531 | % echo 0 > functions/midi2.usb0/ep.0/block.0/midi1_first_group | |
532 | % echo 1 > functions/midi2.usb0/ep.0/block.0/midi1_num_groups | |
533 | ||
534 | The configuration above will enable the Group 1 (the index 0) for MIDI | |
535 | 1.0 interface. Note that those groups must be in the groups defined | |
536 | for the Function Block itself. | |
537 | ||
538 | The gadget driver supports more than one UMP Endpoints, too. | |
539 | Similarly like the Function Blocks, you can create a new subdirectory | |
540 | `ep.1` (but under the card top-level config) to enable a new Endpoint:: | |
541 | ||
542 | % mkdir functions/midi2.usb0/ep.1 | |
543 | ||
544 | and create a new Function Block there. For example, to create 4 | |
545 | Groups for the Function Block of this new Endpoint:: | |
546 | ||
547 | % mkdir functions/midi2.usb0/ep.1/block.0 | |
548 | % echo 4 > functions/midi2.usb0/ep.1/block.0/num_groups | |
549 | ||
550 | Now, you'll have 4 rawmidi devices in total: the first two are UMP | |
551 | rawmidi devices for Endpoint 0 and Endpoint 1, and other two for the | |
552 | legacy MIDI 1.0 rawmidi devices corresponding to both EP 0 and EP 1. | |
553 | ||
554 | The current altsetting on the gadget can be informed via a control | |
555 | element "Operation Mode" with `RAWMIDI` iface. e.g. you can read it | |
556 | via `amixer` program running on the gadget host like:: | |
557 | ||
558 | % amixer -c1 cget iface=RAWMIDI,name='Operation Mode' | |
559 | ; type=INTEGER,access=r--v----,values=1,min=0,max=2,step=0 | |
560 | : values=2 | |
561 | ||
562 | The value (shown in the second returned line with `: values=`) | |
563 | indicates 1 for MIDI 1.0 (altset 0), 2 for MIDI 2.0 (altset 1) and 0 | |
564 | for unset. | |
565 | ||
566 | As of now, the configurations can't be changed after binding. |