Skip to content

Commit e240cff

Browse files
committed
ALSA: documentation: Add description for USB MIDI 2.0 gadget driver
The USB MIDI 2.0 gadget driver is now supported for 6.6 kernel, and here we show a brief instruction how to enable and use it. Link: https://lore.kernel.org/r/20230824075108.29958-5-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent b2bcbd0 commit e240cff

1 file changed

Lines changed: 188 additions & 0 deletions

File tree

Documentation/sound/designs/midi-2.0.rst

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,191 @@ Sequencer API Extensions
376376
name and attributes accordingly, and notifies the changes via the
377377
announcement to the ALSA sequencer system port, similarly like the
378378
normal port change notification.
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
518+
driver, pass `0` to `process_ump attribute in the top-level config::
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.

0 commit comments

Comments
 (0)