usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
/*
|
|
|
|
* f_midi2.c -- USB MIDI 2.0 class function driver
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/device.h>
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
|
|
|
|
#include <sound/core.h>
|
2023-07-25 08:22:05 +02:00
|
|
|
#include <sound/control.h>
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
#include <sound/ump.h>
|
|
|
|
#include <sound/ump_msg.h>
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
#include <sound/ump_convert.h>
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
|
|
|
#include <linux/usb/ch9.h>
|
2024-09-01 21:11:16 +02:00
|
|
|
#include <linux/usb/func_utils.h>
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
#include <linux/usb/gadget.h>
|
|
|
|
#include <linux/usb/audio.h>
|
|
|
|
#include <linux/usb/midi-v2.h>
|
|
|
|
|
|
|
|
#include "u_midi2.h"
|
|
|
|
|
|
|
|
struct f_midi2;
|
|
|
|
struct f_midi2_ep;
|
|
|
|
struct f_midi2_usb_ep;
|
|
|
|
|
|
|
|
/* Context for each USB request */
|
|
|
|
struct f_midi2_req_ctx {
|
|
|
|
struct f_midi2_usb_ep *usb_ep; /* belonging USB EP */
|
|
|
|
unsigned int index; /* array index: 0-31 */
|
|
|
|
struct usb_request *req; /* assigned request */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Resources for a USB Endpoint */
|
|
|
|
struct f_midi2_usb_ep {
|
|
|
|
struct f_midi2 *card; /* belonging card */
|
|
|
|
struct f_midi2_ep *ep; /* belonging UMP EP (optional) */
|
|
|
|
struct usb_ep *usb_ep; /* assigned USB EP */
|
|
|
|
void (*complete)(struct usb_ep *usb_ep, struct usb_request *req);
|
|
|
|
unsigned long free_reqs; /* bitmap for unused requests */
|
|
|
|
unsigned int num_reqs; /* number of allocated requests */
|
|
|
|
struct f_midi2_req_ctx *reqs; /* request context array */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Resources for UMP Function Block (and USB Group Terminal Block) */
|
|
|
|
struct f_midi2_block {
|
|
|
|
struct f_midi2_block_info info; /* FB info, copied from configfs */
|
|
|
|
struct snd_ump_block *fb; /* assigned FB */
|
|
|
|
unsigned int gtb_id; /* assigned GTB id */
|
|
|
|
unsigned int string_id; /* assigned string id */
|
|
|
|
};
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
/* Temporary buffer for altset 0 MIDI 1.0 handling */
|
|
|
|
struct f_midi2_midi1_port {
|
|
|
|
unsigned int pending; /* pending bytes on the input buffer */
|
|
|
|
u8 buf[32]; /* raw MIDI 1.0 byte input */
|
|
|
|
u8 state; /* running status */
|
|
|
|
u8 data[2]; /* rendered USB MIDI 1.0 packet data */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* MIDI 1.0 message states */
|
|
|
|
enum {
|
|
|
|
STATE_INITIAL = 0, /* pseudo state */
|
|
|
|
STATE_1PARAM,
|
|
|
|
STATE_2PARAM_1,
|
|
|
|
STATE_2PARAM_2,
|
|
|
|
STATE_SYSEX_0,
|
|
|
|
STATE_SYSEX_1,
|
|
|
|
STATE_SYSEX_2,
|
|
|
|
STATE_REAL_TIME,
|
|
|
|
STATE_FINISHED, /* pseudo state */
|
|
|
|
};
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/* Resources for UMP Endpoint */
|
|
|
|
struct f_midi2_ep {
|
|
|
|
struct snd_ump_endpoint *ump; /* assigned UMP EP */
|
|
|
|
struct f_midi2 *card; /* belonging MIDI 2.0 device */
|
|
|
|
|
|
|
|
struct f_midi2_ep_info info; /* UMP EP info, copied from configfs */
|
|
|
|
unsigned int num_blks; /* number of FBs */
|
|
|
|
struct f_midi2_block blks[SNDRV_UMP_MAX_BLOCKS]; /* UMP FBs */
|
|
|
|
|
|
|
|
struct f_midi2_usb_ep ep_in; /* USB MIDI EP-in */
|
|
|
|
struct f_midi2_usb_ep ep_out; /* USB MIDI EP-out */
|
2023-07-25 08:22:06 +02:00
|
|
|
|
|
|
|
u8 in_group_to_cable[SNDRV_UMP_MAX_GROUPS]; /* map to cable; 1-based! */
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* indices for USB strings */
|
|
|
|
enum {
|
|
|
|
STR_IFACE = 0,
|
|
|
|
STR_GTB1 = 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* 1-based GTB id to string id */
|
|
|
|
#define gtb_to_str_id(id) (STR_GTB1 + (id) - 1)
|
|
|
|
|
2023-07-25 08:22:06 +02:00
|
|
|
/* mapping from MIDI 1.0 cable to UMP group */
|
|
|
|
struct midi1_cable_mapping {
|
|
|
|
struct f_midi2_ep *ep;
|
|
|
|
unsigned char block;
|
|
|
|
unsigned char group;
|
|
|
|
};
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/* operation mode */
|
|
|
|
enum {
|
|
|
|
MIDI_OP_MODE_UNSET, /* no altset set yet */
|
|
|
|
MIDI_OP_MODE_MIDI1, /* MIDI 1.0 (altset 0) is used */
|
|
|
|
MIDI_OP_MODE_MIDI2, /* MIDI 2.0 (altset 1) is used */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Resources for MIDI 2.0 Device */
|
|
|
|
struct f_midi2 {
|
|
|
|
struct usb_function func;
|
|
|
|
struct usb_gadget *gadget;
|
|
|
|
struct snd_card *card;
|
|
|
|
|
|
|
|
/* MIDI 1.0 in/out USB EPs */
|
|
|
|
struct f_midi2_usb_ep midi1_ep_in;
|
|
|
|
struct f_midi2_usb_ep midi1_ep_out;
|
|
|
|
|
2023-07-25 08:22:06 +02:00
|
|
|
/* number of MIDI 1.0 I/O cables */
|
|
|
|
unsigned int num_midi1_in;
|
|
|
|
unsigned int num_midi1_out;
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
/* conversion for MIDI 1.0 EP-in */
|
|
|
|
struct f_midi2_midi1_port midi1_port[MAX_CABLES];
|
|
|
|
/* conversion for MIDI 1.0 EP-out */
|
|
|
|
struct ump_cvt_to_ump midi1_ump_cvt;
|
2023-07-25 08:22:06 +02:00
|
|
|
/* mapping between cables and UMP groups */
|
|
|
|
struct midi1_cable_mapping in_cable_mapping[MAX_CABLES];
|
|
|
|
struct midi1_cable_mapping out_cable_mapping[MAX_CABLES];
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
int midi_if; /* USB MIDI interface number */
|
|
|
|
int operation_mode; /* current operation mode */
|
|
|
|
|
|
|
|
spinlock_t queue_lock;
|
|
|
|
|
|
|
|
struct f_midi2_card_info info; /* card info, copied from configfs */
|
|
|
|
|
|
|
|
unsigned int num_eps;
|
|
|
|
struct f_midi2_ep midi2_eps[MAX_UMP_EPS];
|
|
|
|
|
|
|
|
unsigned int total_blocks; /* total number of blocks of all EPs */
|
|
|
|
struct usb_string *string_defs;
|
|
|
|
struct usb_string *strings;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define func_to_midi2(f) container_of(f, struct f_midi2, func)
|
|
|
|
|
2024-07-08 11:57:17 +02:00
|
|
|
/* convert from MIDI protocol number (1 or 2) to SNDRV_UMP_EP_INFO_PROTO_* */
|
|
|
|
#define to_ump_protocol(v) (((v) & 3) << 8)
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/* get EP name string */
|
|
|
|
static const char *ump_ep_name(const struct f_midi2_ep *ep)
|
|
|
|
{
|
|
|
|
return ep->info.ep_name ? ep->info.ep_name : "MIDI 2.0 Gadget";
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get EP product ID string */
|
|
|
|
static const char *ump_product_id(const struct f_midi2_ep *ep)
|
|
|
|
{
|
|
|
|
return ep->info.product_id ? ep->info.product_id : "Unique Product ID";
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get FB name string */
|
|
|
|
static const char *ump_fb_name(const struct f_midi2_block_info *info)
|
|
|
|
{
|
|
|
|
return info->name ? info->name : "MIDI 2.0 Gadget I/O";
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* USB Descriptor Definitions
|
|
|
|
*/
|
|
|
|
/* GTB header descriptor */
|
|
|
|
static struct usb_ms20_gr_trm_block_header_descriptor gtb_header_desc = {
|
|
|
|
.bLength = sizeof(gtb_header_desc),
|
|
|
|
.bDescriptorType = USB_DT_CS_GR_TRM_BLOCK,
|
|
|
|
.bDescriptorSubtype = USB_MS_GR_TRM_BLOCK_HEADER,
|
|
|
|
.wTotalLength = __cpu_to_le16(0x12), // to be filled
|
|
|
|
};
|
|
|
|
|
|
|
|
/* GTB descriptor template: most items are replaced dynamically */
|
|
|
|
static struct usb_ms20_gr_trm_block_descriptor gtb_desc = {
|
|
|
|
.bLength = sizeof(gtb_desc),
|
|
|
|
.bDescriptorType = USB_DT_CS_GR_TRM_BLOCK,
|
|
|
|
.bDescriptorSubtype = USB_MS_GR_TRM_BLOCK,
|
|
|
|
.bGrpTrmBlkID = 0x01,
|
|
|
|
.bGrpTrmBlkType = USB_MS_GR_TRM_BLOCK_TYPE_BIDIRECTIONAL,
|
|
|
|
.nGroupTrm = 0x00,
|
|
|
|
.nNumGroupTrm = 1,
|
|
|
|
.iBlockItem = 0,
|
|
|
|
.bMIDIProtocol = USB_MS_MIDI_PROTO_1_0_64,
|
|
|
|
.wMaxInputBandwidth = 0,
|
|
|
|
.wMaxOutputBandwidth = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
|
2023-07-25 08:22:02 +02:00
|
|
|
DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16);
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
|
|
|
|
DECLARE_USB_MS20_ENDPOINT_DESCRIPTOR(32);
|
|
|
|
|
|
|
|
#define EP_MAX_PACKET_INT 8
|
|
|
|
|
|
|
|
/* Audio Control Interface */
|
|
|
|
static struct usb_interface_descriptor midi2_audio_if_desc = {
|
|
|
|
.bLength = USB_DT_INTERFACE_SIZE,
|
|
|
|
.bDescriptorType = USB_DT_INTERFACE,
|
|
|
|
.bInterfaceNumber = 0, // to be filled
|
|
|
|
.bNumEndpoints = 0,
|
|
|
|
.bInterfaceClass = USB_CLASS_AUDIO,
|
|
|
|
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
|
|
|
|
.bInterfaceProtocol = 0,
|
|
|
|
.iInterface = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct uac1_ac_header_descriptor_1 midi2_audio_class_desc = {
|
|
|
|
.bLength = 0x09,
|
|
|
|
.bDescriptorType = USB_DT_CS_INTERFACE,
|
|
|
|
.bDescriptorSubtype = 0x01,
|
|
|
|
.bcdADC = __cpu_to_le16(0x0100),
|
|
|
|
.wTotalLength = __cpu_to_le16(0x0009),
|
|
|
|
.bInCollection = 0x01,
|
|
|
|
.baInterfaceNr = { 0x01 }, // to be filled
|
|
|
|
};
|
|
|
|
|
|
|
|
/* MIDI 1.0 Streaming Interface (altset 0) */
|
|
|
|
static struct usb_interface_descriptor midi2_midi1_if_desc = {
|
|
|
|
.bLength = USB_DT_INTERFACE_SIZE,
|
|
|
|
.bDescriptorType = USB_DT_INTERFACE,
|
|
|
|
.bInterfaceNumber = 0, // to be filled
|
|
|
|
.bAlternateSetting = 0,
|
2023-07-25 08:22:02 +02:00
|
|
|
.bNumEndpoints = 2, // to be filled
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
.bInterfaceClass = USB_CLASS_AUDIO,
|
|
|
|
.bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING,
|
|
|
|
.bInterfaceProtocol = 0,
|
|
|
|
.iInterface = 0, // to be filled
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct usb_ms_header_descriptor midi2_midi1_class_desc = {
|
|
|
|
.bLength = 0x07,
|
|
|
|
.bDescriptorType = USB_DT_CS_INTERFACE,
|
|
|
|
.bDescriptorSubtype = USB_MS_HEADER,
|
|
|
|
.bcdMSC = __cpu_to_le16(0x0100),
|
|
|
|
.wTotalLength = __cpu_to_le16(0x41), // to be calculated
|
|
|
|
};
|
|
|
|
|
|
|
|
/* MIDI 1.0 EP OUT */
|
|
|
|
static struct usb_endpoint_descriptor midi2_midi1_ep_out_desc = {
|
|
|
|
.bLength = USB_DT_ENDPOINT_AUDIO_SIZE,
|
|
|
|
.bDescriptorType = USB_DT_ENDPOINT,
|
|
|
|
.bEndpointAddress = USB_DIR_OUT | 0, // set up dynamically
|
|
|
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct usb_ss_ep_comp_descriptor midi2_midi1_ep_out_ss_comp_desc = {
|
|
|
|
.bLength = sizeof(midi2_midi1_ep_out_ss_comp_desc),
|
|
|
|
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
|
|
|
};
|
|
|
|
|
2023-07-25 08:22:02 +02:00
|
|
|
static struct usb_ms_endpoint_descriptor_16 midi2_midi1_ep_out_class_desc = {
|
|
|
|
.bLength = 0x05, // to be filled
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
.bDescriptorType = USB_DT_CS_ENDPOINT,
|
|
|
|
.bDescriptorSubtype = USB_MS_GENERAL,
|
|
|
|
.bNumEmbMIDIJack = 1,
|
|
|
|
.baAssocJackID = { 0x01 },
|
|
|
|
};
|
|
|
|
|
|
|
|
/* MIDI 1.0 EP IN */
|
|
|
|
static struct usb_endpoint_descriptor midi2_midi1_ep_in_desc = {
|
|
|
|
.bLength = USB_DT_ENDPOINT_AUDIO_SIZE,
|
|
|
|
.bDescriptorType = USB_DT_ENDPOINT,
|
|
|
|
.bEndpointAddress = USB_DIR_IN | 0, // set up dynamically
|
|
|
|
.bmAttributes = USB_ENDPOINT_XFER_BULK,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct usb_ss_ep_comp_descriptor midi2_midi1_ep_in_ss_comp_desc = {
|
|
|
|
.bLength = sizeof(midi2_midi1_ep_in_ss_comp_desc),
|
|
|
|
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
|
|
|
};
|
|
|
|
|
2023-07-25 08:22:02 +02:00
|
|
|
static struct usb_ms_endpoint_descriptor_16 midi2_midi1_ep_in_class_desc = {
|
|
|
|
.bLength = 0x05, // to be filled
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
.bDescriptorType = USB_DT_CS_ENDPOINT,
|
|
|
|
.bDescriptorSubtype = USB_MS_GENERAL,
|
|
|
|
.bNumEmbMIDIJack = 1,
|
|
|
|
.baAssocJackID = { 0x03 },
|
|
|
|
};
|
|
|
|
|
|
|
|
/* MIDI 2.0 Streaming Interface (altset 1) */
|
|
|
|
static struct usb_interface_descriptor midi2_midi2_if_desc = {
|
|
|
|
.bLength = USB_DT_INTERFACE_SIZE,
|
|
|
|
.bDescriptorType = USB_DT_INTERFACE,
|
|
|
|
.bInterfaceNumber = 0, // to be filled
|
|
|
|
.bAlternateSetting = 1,
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
.bNumEndpoints = 2, // to be filled
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
.bInterfaceClass = USB_CLASS_AUDIO,
|
|
|
|
.bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING,
|
|
|
|
.bInterfaceProtocol = 0,
|
|
|
|
.iInterface = 0, // to be filled
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct usb_ms_header_descriptor midi2_midi2_class_desc = {
|
|
|
|
.bLength = 0x07,
|
|
|
|
.bDescriptorType = USB_DT_CS_INTERFACE,
|
|
|
|
.bDescriptorSubtype = USB_MS_HEADER,
|
|
|
|
.bcdMSC = __cpu_to_le16(0x0200),
|
|
|
|
.wTotalLength = __cpu_to_le16(0x07),
|
|
|
|
};
|
|
|
|
|
|
|
|
/* MIDI 2.0 EP OUT */
|
|
|
|
static struct usb_endpoint_descriptor midi2_midi2_ep_out_desc[MAX_UMP_EPS];
|
|
|
|
|
|
|
|
static struct usb_ss_ep_comp_descriptor midi2_midi2_ep_out_ss_comp_desc = {
|
|
|
|
.bLength = sizeof(midi2_midi1_ep_out_ss_comp_desc),
|
|
|
|
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct usb_ms20_endpoint_descriptor_32 midi2_midi2_ep_out_class_desc[MAX_UMP_EPS];
|
|
|
|
|
|
|
|
/* MIDI 2.0 EP IN */
|
|
|
|
static struct usb_endpoint_descriptor midi2_midi2_ep_in_desc[MAX_UMP_EPS];
|
|
|
|
|
|
|
|
static struct usb_ss_ep_comp_descriptor midi2_midi2_ep_in_ss_comp_desc = {
|
|
|
|
.bLength = sizeof(midi2_midi2_ep_in_ss_comp_desc),
|
|
|
|
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct usb_ms20_endpoint_descriptor_32 midi2_midi2_ep_in_class_desc[MAX_UMP_EPS];
|
|
|
|
|
|
|
|
/* Arrays of descriptors to be created */
|
|
|
|
static void *midi2_audio_descs[] = {
|
|
|
|
&midi2_audio_if_desc,
|
|
|
|
&midi2_audio_class_desc,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static void *midi2_midi1_descs[] = {
|
|
|
|
&midi2_midi1_if_desc,
|
|
|
|
&midi2_midi1_class_desc,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2023-07-25 08:22:02 +02:00
|
|
|
static void *midi2_midi1_ep_out_descs[] = {
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
&midi2_midi1_ep_out_desc,
|
|
|
|
&midi2_midi1_ep_out_class_desc,
|
2023-07-25 08:22:02 +02:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static void *midi2_midi1_ep_in_descs[] = {
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
&midi2_midi1_ep_in_desc,
|
|
|
|
&midi2_midi1_ep_in_class_desc,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2023-07-25 08:22:02 +02:00
|
|
|
static void *midi2_midi1_ep_out_ss_descs[] = {
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
&midi2_midi1_ep_out_desc,
|
|
|
|
&midi2_midi1_ep_out_ss_comp_desc,
|
|
|
|
&midi2_midi1_ep_out_class_desc,
|
2023-07-25 08:22:02 +02:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static void *midi2_midi1_ep_in_ss_descs[] = {
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
&midi2_midi1_ep_in_desc,
|
|
|
|
&midi2_midi1_ep_in_ss_comp_desc,
|
|
|
|
&midi2_midi1_ep_in_class_desc,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static void *midi2_midi2_descs[] = {
|
|
|
|
&midi2_midi2_if_desc,
|
|
|
|
&midi2_midi2_class_desc,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* USB request handling
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* get an empty request for the given EP */
|
|
|
|
static struct usb_request *get_empty_request(struct f_midi2_usb_ep *usb_ep)
|
|
|
|
{
|
|
|
|
struct usb_request *req = NULL;
|
|
|
|
unsigned long flags;
|
|
|
|
int index;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&usb_ep->card->queue_lock, flags);
|
|
|
|
if (!usb_ep->free_reqs)
|
|
|
|
goto unlock;
|
|
|
|
index = find_first_bit(&usb_ep->free_reqs, usb_ep->num_reqs);
|
|
|
|
if (index >= usb_ep->num_reqs)
|
|
|
|
goto unlock;
|
|
|
|
req = usb_ep->reqs[index].req;
|
|
|
|
if (!req)
|
|
|
|
goto unlock;
|
|
|
|
clear_bit(index, &usb_ep->free_reqs);
|
|
|
|
req->length = 0;
|
|
|
|
unlock:
|
|
|
|
spin_unlock_irqrestore(&usb_ep->card->queue_lock, flags);
|
|
|
|
return req;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* put the empty request back */
|
|
|
|
static void put_empty_request(struct usb_request *req)
|
|
|
|
{
|
|
|
|
struct f_midi2_req_ctx *ctx = req->context;
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
spin_lock_irqsave(&ctx->usb_ep->card->queue_lock, flags);
|
|
|
|
set_bit(ctx->index, &ctx->usb_ep->free_reqs);
|
|
|
|
spin_unlock_irqrestore(&ctx->usb_ep->card->queue_lock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* UMP v1.1 Stream message handling
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* queue a request to UMP EP; request is either queued or freed after this */
|
|
|
|
static int queue_request_ep_raw(struct usb_request *req)
|
|
|
|
{
|
|
|
|
struct f_midi2_req_ctx *ctx = req->context;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
req->complete = ctx->usb_ep->complete;
|
|
|
|
err = usb_ep_queue(ctx->usb_ep->usb_ep, req, GFP_ATOMIC);
|
|
|
|
if (err) {
|
|
|
|
put_empty_request(req);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* queue a request with endianness conversion */
|
|
|
|
static int queue_request_ep_in(struct usb_request *req)
|
|
|
|
{
|
|
|
|
/* UMP packets have to be converted to little-endian */
|
|
|
|
cpu_to_le32_array((u32 *)req->buf, req->length >> 2);
|
|
|
|
return queue_request_ep_raw(req);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* reply a UMP packet via EP-in */
|
|
|
|
static int reply_ep_in(struct f_midi2_ep *ep, const void *buf, int len)
|
|
|
|
{
|
|
|
|
struct f_midi2_usb_ep *usb_ep = &ep->ep_in;
|
|
|
|
struct usb_request *req;
|
|
|
|
|
|
|
|
req = get_empty_request(usb_ep);
|
|
|
|
if (!req)
|
|
|
|
return -ENOSPC;
|
|
|
|
|
|
|
|
req->length = len;
|
|
|
|
memcpy(req->buf, buf, len);
|
|
|
|
return queue_request_ep_in(req);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* reply a UMP stream EP info */
|
|
|
|
static void reply_ump_stream_ep_info(struct f_midi2_ep *ep)
|
|
|
|
{
|
|
|
|
struct snd_ump_stream_msg_ep_info rep = {
|
|
|
|
.type = UMP_MSG_TYPE_STREAM,
|
|
|
|
.status = UMP_STREAM_MSG_STATUS_EP_INFO,
|
|
|
|
.ump_version_major = 0x01,
|
|
|
|
.ump_version_minor = 0x01,
|
|
|
|
.num_function_blocks = ep->num_blks,
|
|
|
|
.static_function_block = !!ep->card->info.static_block,
|
|
|
|
.protocol = (UMP_STREAM_MSG_EP_INFO_CAP_MIDI1 |
|
|
|
|
UMP_STREAM_MSG_EP_INFO_CAP_MIDI2) >> 8,
|
|
|
|
};
|
|
|
|
|
|
|
|
reply_ep_in(ep, &rep, sizeof(rep));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* reply a UMP EP device info */
|
|
|
|
static void reply_ump_stream_ep_device(struct f_midi2_ep *ep)
|
|
|
|
{
|
2025-05-11 16:11:45 +02:00
|
|
|
struct snd_ump_stream_msg_device_info rep = {
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
.type = UMP_MSG_TYPE_STREAM,
|
|
|
|
.status = UMP_STREAM_MSG_STATUS_DEVICE_INFO,
|
|
|
|
.manufacture_id = ep->info.manufacturer,
|
|
|
|
.family_lsb = ep->info.family & 0xff,
|
|
|
|
.family_msb = (ep->info.family >> 8) & 0xff,
|
|
|
|
.model_lsb = ep->info.model & 0xff,
|
|
|
|
.model_msb = (ep->info.model >> 8) & 0xff,
|
|
|
|
.sw_revision = ep->info.sw_revision,
|
|
|
|
};
|
|
|
|
|
|
|
|
reply_ep_in(ep, &rep, sizeof(rep));
|
|
|
|
}
|
|
|
|
|
|
|
|
#define UMP_STREAM_PKT_BYTES 16 /* UMP stream packet size = 16 bytes*/
|
|
|
|
#define UMP_STREAM_EP_STR_OFF 2 /* offset of name string for EP info */
|
|
|
|
#define UMP_STREAM_FB_STR_OFF 3 /* offset of name string for FB info */
|
|
|
|
|
|
|
|
/* Helper to replay a string */
|
|
|
|
static void reply_ump_stream_string(struct f_midi2_ep *ep, const u8 *name,
|
|
|
|
unsigned int type, unsigned int extra,
|
|
|
|
unsigned int start_ofs)
|
|
|
|
{
|
|
|
|
struct f_midi2_usb_ep *usb_ep = &ep->ep_in;
|
|
|
|
struct f_midi2 *midi2 = ep->card;
|
|
|
|
struct usb_request *req;
|
|
|
|
unsigned int pos;
|
|
|
|
u32 *buf;
|
|
|
|
|
|
|
|
if (!*name)
|
|
|
|
return;
|
|
|
|
req = get_empty_request(usb_ep);
|
|
|
|
if (!req)
|
|
|
|
return;
|
|
|
|
|
|
|
|
buf = (u32 *)req->buf;
|
|
|
|
pos = start_ofs;
|
|
|
|
for (;;) {
|
|
|
|
if (pos == start_ofs) {
|
|
|
|
memset(buf, 0, UMP_STREAM_PKT_BYTES);
|
|
|
|
buf[0] = ump_stream_compose(type, 0) | extra;
|
|
|
|
}
|
|
|
|
buf[pos / 4] |= *name++ << ((3 - (pos % 4)) * 8);
|
|
|
|
if (!*name) {
|
|
|
|
if (req->length)
|
|
|
|
buf[0] |= UMP_STREAM_MSG_FORMAT_END << 26;
|
|
|
|
req->length += UMP_STREAM_PKT_BYTES;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (++pos == UMP_STREAM_PKT_BYTES) {
|
|
|
|
if (!req->length)
|
|
|
|
buf[0] |= UMP_STREAM_MSG_FORMAT_START << 26;
|
|
|
|
else
|
|
|
|
buf[0] |= UMP_STREAM_MSG_FORMAT_CONTINUE << 26;
|
|
|
|
req->length += UMP_STREAM_PKT_BYTES;
|
|
|
|
if (midi2->info.req_buf_size - req->length < UMP_STREAM_PKT_BYTES)
|
|
|
|
break;
|
|
|
|
buf += 4;
|
|
|
|
pos = start_ofs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req->length)
|
|
|
|
queue_request_ep_in(req);
|
|
|
|
else
|
|
|
|
put_empty_request(req);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reply a UMP EP name string */
|
|
|
|
static void reply_ump_stream_ep_name(struct f_midi2_ep *ep)
|
|
|
|
{
|
|
|
|
reply_ump_stream_string(ep, ump_ep_name(ep),
|
|
|
|
UMP_STREAM_MSG_STATUS_EP_NAME, 0,
|
|
|
|
UMP_STREAM_EP_STR_OFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reply a UMP EP product ID string */
|
|
|
|
static void reply_ump_stream_ep_pid(struct f_midi2_ep *ep)
|
|
|
|
{
|
|
|
|
reply_ump_stream_string(ep, ump_product_id(ep),
|
|
|
|
UMP_STREAM_MSG_STATUS_PRODUCT_ID, 0,
|
|
|
|
UMP_STREAM_EP_STR_OFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reply a UMP EP stream config */
|
|
|
|
static void reply_ump_stream_ep_config(struct f_midi2_ep *ep)
|
|
|
|
{
|
|
|
|
struct snd_ump_stream_msg_stream_cfg rep = {
|
|
|
|
.type = UMP_MSG_TYPE_STREAM,
|
|
|
|
.status = UMP_STREAM_MSG_STATUS_STREAM_CFG,
|
|
|
|
};
|
|
|
|
|
2024-07-08 11:57:17 +02:00
|
|
|
if (ep->info.protocol == 2)
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
rep.protocol = UMP_STREAM_MSG_EP_INFO_CAP_MIDI2 >> 8;
|
|
|
|
else
|
|
|
|
rep.protocol = UMP_STREAM_MSG_EP_INFO_CAP_MIDI1 >> 8;
|
|
|
|
|
|
|
|
reply_ep_in(ep, &rep, sizeof(rep));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reply a UMP FB info */
|
|
|
|
static void reply_ump_stream_fb_info(struct f_midi2_ep *ep, int blk)
|
|
|
|
{
|
|
|
|
struct f_midi2_block_info *b = &ep->blks[blk].info;
|
|
|
|
struct snd_ump_stream_msg_fb_info rep = {
|
|
|
|
.type = UMP_MSG_TYPE_STREAM,
|
|
|
|
.status = UMP_STREAM_MSG_STATUS_FB_INFO,
|
|
|
|
.active = !!b->active,
|
|
|
|
.function_block_id = blk,
|
|
|
|
.ui_hint = b->ui_hint,
|
|
|
|
.midi_10 = b->is_midi1,
|
|
|
|
.direction = b->direction,
|
|
|
|
.first_group = b->first_group,
|
|
|
|
.num_groups = b->num_groups,
|
|
|
|
.midi_ci_version = b->midi_ci_version,
|
|
|
|
.sysex8_streams = b->sysex8_streams,
|
|
|
|
};
|
|
|
|
|
|
|
|
reply_ep_in(ep, &rep, sizeof(rep));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reply a FB name string */
|
|
|
|
static void reply_ump_stream_fb_name(struct f_midi2_ep *ep, unsigned int blk)
|
|
|
|
{
|
|
|
|
reply_ump_stream_string(ep, ump_fb_name(&ep->blks[blk].info),
|
|
|
|
UMP_STREAM_MSG_STATUS_FB_NAME, blk << 8,
|
|
|
|
UMP_STREAM_FB_STR_OFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Process a UMP Stream message */
|
|
|
|
static void process_ump_stream_msg(struct f_midi2_ep *ep, const u32 *data)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2 = ep->card;
|
|
|
|
unsigned int format, status, blk;
|
|
|
|
|
|
|
|
format = ump_stream_message_format(*data);
|
|
|
|
status = ump_stream_message_status(*data);
|
|
|
|
switch (status) {
|
|
|
|
case UMP_STREAM_MSG_STATUS_EP_DISCOVERY:
|
|
|
|
if (format)
|
|
|
|
return; // invalid
|
|
|
|
if (data[1] & UMP_STREAM_MSG_REQUEST_EP_INFO)
|
|
|
|
reply_ump_stream_ep_info(ep);
|
|
|
|
if (data[1] & UMP_STREAM_MSG_REQUEST_DEVICE_INFO)
|
|
|
|
reply_ump_stream_ep_device(ep);
|
|
|
|
if (data[1] & UMP_STREAM_MSG_REQUEST_EP_NAME)
|
|
|
|
reply_ump_stream_ep_name(ep);
|
|
|
|
if (data[1] & UMP_STREAM_MSG_REQUEST_PRODUCT_ID)
|
|
|
|
reply_ump_stream_ep_pid(ep);
|
|
|
|
if (data[1] & UMP_STREAM_MSG_REQUEST_STREAM_CFG)
|
|
|
|
reply_ump_stream_ep_config(ep);
|
|
|
|
return;
|
|
|
|
case UMP_STREAM_MSG_STATUS_STREAM_CFG_REQUEST:
|
|
|
|
if (*data & UMP_STREAM_MSG_EP_INFO_CAP_MIDI2) {
|
2024-07-08 11:57:17 +02:00
|
|
|
ep->info.protocol = 2;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
DBG(midi2, "Switching Protocol to MIDI2\n");
|
|
|
|
} else {
|
2024-07-08 11:57:17 +02:00
|
|
|
ep->info.protocol = 1;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
DBG(midi2, "Switching Protocol to MIDI1\n");
|
|
|
|
}
|
2024-07-08 11:57:17 +02:00
|
|
|
snd_ump_switch_protocol(ep->ump, to_ump_protocol(ep->info.protocol));
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
reply_ump_stream_ep_config(ep);
|
|
|
|
return;
|
|
|
|
case UMP_STREAM_MSG_STATUS_FB_DISCOVERY:
|
|
|
|
if (format)
|
|
|
|
return; // invalid
|
|
|
|
blk = (*data >> 8) & 0xff;
|
2024-07-17 11:50:53 +02:00
|
|
|
if (blk == 0xff) {
|
|
|
|
/* inquiry for all blocks */
|
|
|
|
for (blk = 0; blk < ep->num_blks; blk++) {
|
|
|
|
if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO)
|
|
|
|
reply_ump_stream_fb_info(ep, blk);
|
|
|
|
if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME)
|
|
|
|
reply_ump_stream_fb_name(ep, blk);
|
|
|
|
}
|
|
|
|
} else if (blk < ep->num_blks) {
|
|
|
|
/* only the specified block */
|
|
|
|
if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO)
|
|
|
|
reply_ump_stream_fb_info(ep, blk);
|
|
|
|
if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME)
|
|
|
|
reply_ump_stream_fb_name(ep, blk);
|
|
|
|
}
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Process UMP messages included in a USB request */
|
|
|
|
static void process_ump(struct f_midi2_ep *ep, const struct usb_request *req)
|
|
|
|
{
|
|
|
|
const u32 *data = (u32 *)req->buf;
|
|
|
|
int len = req->actual >> 2;
|
|
|
|
const u32 *in_buf = ep->ump->input_buf;
|
|
|
|
|
|
|
|
for (; len > 0; len--, data++) {
|
|
|
|
if (snd_ump_receive_ump_val(ep->ump, *data) <= 0)
|
|
|
|
continue;
|
|
|
|
if (ump_message_type(*in_buf) == UMP_MSG_TYPE_STREAM)
|
|
|
|
process_ump_stream_msg(ep, in_buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* MIDI 2.0 UMP USB request handling
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* complete handler for UMP EP-out requests */
|
|
|
|
static void f_midi2_ep_out_complete(struct usb_ep *usb_ep,
|
|
|
|
struct usb_request *req)
|
|
|
|
{
|
|
|
|
struct f_midi2_req_ctx *ctx = req->context;
|
|
|
|
struct f_midi2_ep *ep = ctx->usb_ep->ep;
|
|
|
|
struct f_midi2 *midi2 = ep->card;
|
|
|
|
int status = req->status;
|
|
|
|
|
|
|
|
if (status) {
|
|
|
|
DBG(midi2, "%s complete error %d: %d/%d\n",
|
|
|
|
usb_ep->name, status, req->actual, req->length);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert to UMP packet in native endianness */
|
|
|
|
le32_to_cpu_array((u32 *)req->buf, req->actual >> 2);
|
|
|
|
|
|
|
|
if (midi2->info.process_ump)
|
|
|
|
process_ump(ep, req);
|
|
|
|
|
|
|
|
snd_ump_receive(ep->ump, req->buf, req->actual & ~3);
|
|
|
|
|
|
|
|
if (midi2->operation_mode != MIDI_OP_MODE_MIDI2)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (queue_request_ep_raw(req))
|
|
|
|
goto error;
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
|
|
|
put_empty_request(req);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Transmit UMP packets received from user-space to the gadget */
|
|
|
|
static void process_ump_transmit(struct f_midi2_ep *ep)
|
|
|
|
{
|
|
|
|
struct f_midi2_usb_ep *usb_ep = &ep->ep_in;
|
|
|
|
struct f_midi2 *midi2 = ep->card;
|
|
|
|
struct usb_request *req;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (!usb_ep->usb_ep->enabled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
req = get_empty_request(usb_ep);
|
|
|
|
if (!req)
|
|
|
|
break;
|
|
|
|
len = snd_ump_transmit(ep->ump, (u32 *)req->buf,
|
|
|
|
midi2->info.req_buf_size);
|
|
|
|
if (len <= 0) {
|
|
|
|
put_empty_request(req);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
req->length = len;
|
|
|
|
if (queue_request_ep_in(req) < 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Complete handler for UMP EP-in requests */
|
|
|
|
static void f_midi2_ep_in_complete(struct usb_ep *usb_ep,
|
|
|
|
struct usb_request *req)
|
|
|
|
{
|
|
|
|
struct f_midi2_req_ctx *ctx = req->context;
|
|
|
|
struct f_midi2_ep *ep = ctx->usb_ep->ep;
|
|
|
|
struct f_midi2 *midi2 = ep->card;
|
|
|
|
int status = req->status;
|
|
|
|
|
|
|
|
put_empty_request(req);
|
|
|
|
|
|
|
|
if (status) {
|
|
|
|
DBG(midi2, "%s complete error %d: %d/%d\n",
|
|
|
|
usb_ep->name, status, req->actual, req->length);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
process_ump_transmit(ep);
|
|
|
|
}
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
/*
|
|
|
|
* MIDI1 (altset 0) USB request handling
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* process one MIDI byte -- copied from f_midi.c
|
|
|
|
*
|
|
|
|
* fill the packet or request if needed
|
|
|
|
* returns true if the request became empty (queued)
|
|
|
|
*/
|
|
|
|
static bool process_midi1_byte(struct f_midi2 *midi2, u8 cable, u8 b,
|
|
|
|
struct usb_request **req_p)
|
|
|
|
{
|
|
|
|
struct f_midi2_midi1_port *port = &midi2->midi1_port[cable];
|
|
|
|
u8 p[4] = { cable << 4, 0, 0, 0 };
|
|
|
|
int next_state = STATE_INITIAL;
|
|
|
|
struct usb_request *req = *req_p;
|
|
|
|
|
|
|
|
switch (b) {
|
|
|
|
case 0xf8 ... 0xff:
|
|
|
|
/* System Real-Time Messages */
|
|
|
|
p[0] |= 0x0f;
|
|
|
|
p[1] = b;
|
|
|
|
next_state = port->state;
|
|
|
|
port->state = STATE_REAL_TIME;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xf7:
|
|
|
|
/* End of SysEx */
|
|
|
|
switch (port->state) {
|
|
|
|
case STATE_SYSEX_0:
|
|
|
|
p[0] |= 0x05;
|
|
|
|
p[1] = 0xf7;
|
|
|
|
next_state = STATE_FINISHED;
|
|
|
|
break;
|
|
|
|
case STATE_SYSEX_1:
|
|
|
|
p[0] |= 0x06;
|
|
|
|
p[1] = port->data[0];
|
|
|
|
p[2] = 0xf7;
|
|
|
|
next_state = STATE_FINISHED;
|
|
|
|
break;
|
|
|
|
case STATE_SYSEX_2:
|
|
|
|
p[0] |= 0x07;
|
|
|
|
p[1] = port->data[0];
|
|
|
|
p[2] = port->data[1];
|
|
|
|
p[3] = 0xf7;
|
|
|
|
next_state = STATE_FINISHED;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Ignore byte */
|
|
|
|
next_state = port->state;
|
|
|
|
port->state = STATE_INITIAL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xf0 ... 0xf6:
|
|
|
|
/* System Common Messages */
|
|
|
|
port->data[0] = port->data[1] = 0;
|
|
|
|
port->state = STATE_INITIAL;
|
|
|
|
switch (b) {
|
|
|
|
case 0xf0:
|
|
|
|
port->data[0] = b;
|
|
|
|
port->data[1] = 0;
|
|
|
|
next_state = STATE_SYSEX_1;
|
|
|
|
break;
|
|
|
|
case 0xf1:
|
|
|
|
case 0xf3:
|
|
|
|
port->data[0] = b;
|
|
|
|
next_state = STATE_1PARAM;
|
|
|
|
break;
|
|
|
|
case 0xf2:
|
|
|
|
port->data[0] = b;
|
|
|
|
next_state = STATE_2PARAM_1;
|
|
|
|
break;
|
|
|
|
case 0xf4:
|
|
|
|
case 0xf5:
|
|
|
|
next_state = STATE_INITIAL;
|
|
|
|
break;
|
|
|
|
case 0xf6:
|
|
|
|
p[0] |= 0x05;
|
|
|
|
p[1] = 0xf6;
|
|
|
|
next_state = STATE_FINISHED;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x80 ... 0xef:
|
|
|
|
/*
|
|
|
|
* Channel Voice Messages, Channel Mode Messages
|
|
|
|
* and Control Change Messages.
|
|
|
|
*/
|
|
|
|
port->data[0] = b;
|
|
|
|
port->data[1] = 0;
|
|
|
|
port->state = STATE_INITIAL;
|
|
|
|
if (b >= 0xc0 && b <= 0xdf)
|
|
|
|
next_state = STATE_1PARAM;
|
|
|
|
else
|
|
|
|
next_state = STATE_2PARAM_1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x00 ... 0x7f:
|
|
|
|
/* Message parameters */
|
|
|
|
switch (port->state) {
|
|
|
|
case STATE_1PARAM:
|
|
|
|
if (port->data[0] < 0xf0)
|
|
|
|
p[0] |= port->data[0] >> 4;
|
|
|
|
else
|
|
|
|
p[0] |= 0x02;
|
|
|
|
|
|
|
|
p[1] = port->data[0];
|
|
|
|
p[2] = b;
|
|
|
|
/* This is to allow Running State Messages */
|
|
|
|
next_state = STATE_1PARAM;
|
|
|
|
break;
|
|
|
|
case STATE_2PARAM_1:
|
|
|
|
port->data[1] = b;
|
|
|
|
next_state = STATE_2PARAM_2;
|
|
|
|
break;
|
|
|
|
case STATE_2PARAM_2:
|
|
|
|
if (port->data[0] < 0xf0)
|
|
|
|
p[0] |= port->data[0] >> 4;
|
|
|
|
else
|
|
|
|
p[0] |= 0x03;
|
|
|
|
|
|
|
|
p[1] = port->data[0];
|
|
|
|
p[2] = port->data[1];
|
|
|
|
p[3] = b;
|
|
|
|
/* This is to allow Running State Messages */
|
|
|
|
next_state = STATE_2PARAM_1;
|
|
|
|
break;
|
|
|
|
case STATE_SYSEX_0:
|
|
|
|
port->data[0] = b;
|
|
|
|
next_state = STATE_SYSEX_1;
|
|
|
|
break;
|
|
|
|
case STATE_SYSEX_1:
|
|
|
|
port->data[1] = b;
|
|
|
|
next_state = STATE_SYSEX_2;
|
|
|
|
break;
|
|
|
|
case STATE_SYSEX_2:
|
|
|
|
p[0] |= 0x04;
|
|
|
|
p[1] = port->data[0];
|
|
|
|
p[2] = port->data[1];
|
|
|
|
p[3] = b;
|
|
|
|
next_state = STATE_SYSEX_0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* States where we have to write into the USB request */
|
|
|
|
if (next_state == STATE_FINISHED ||
|
|
|
|
port->state == STATE_SYSEX_2 ||
|
|
|
|
port->state == STATE_1PARAM ||
|
|
|
|
port->state == STATE_2PARAM_2 ||
|
|
|
|
port->state == STATE_REAL_TIME) {
|
|
|
|
memcpy(req->buf + req->length, p, sizeof(p));
|
|
|
|
req->length += sizeof(p);
|
|
|
|
|
|
|
|
if (next_state == STATE_FINISHED) {
|
|
|
|
next_state = STATE_INITIAL;
|
|
|
|
port->data[0] = port->data[1] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (midi2->info.req_buf_size - req->length <= 4) {
|
|
|
|
queue_request_ep_raw(req);
|
|
|
|
*req_p = NULL;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
port->state = next_state;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* process all pending MIDI bytes in the internal buffer;
|
|
|
|
* returns true if the request gets empty
|
|
|
|
* returns false if all have been processed
|
|
|
|
*/
|
|
|
|
static bool process_midi1_pending_buf(struct f_midi2 *midi2,
|
|
|
|
struct usb_request **req_p)
|
|
|
|
{
|
|
|
|
unsigned int cable, c;
|
|
|
|
|
2023-07-25 08:22:06 +02:00
|
|
|
for (cable = 0; cable < midi2->num_midi1_in; cable++) {
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
struct f_midi2_midi1_port *port = &midi2->midi1_port[cable];
|
|
|
|
|
|
|
|
if (!port->pending)
|
|
|
|
continue;
|
|
|
|
for (c = 0; c < port->pending; c++) {
|
|
|
|
if (process_midi1_byte(midi2, cable, port->buf[c],
|
|
|
|
req_p)) {
|
|
|
|
port->pending -= c;
|
|
|
|
if (port->pending)
|
|
|
|
memmove(port->buf, port->buf + c,
|
|
|
|
port->pending);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
port->pending = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fill the MIDI bytes onto the temporary buffer
|
|
|
|
*/
|
|
|
|
static void fill_midi1_pending_buf(struct f_midi2 *midi2, u8 cable, u8 *buf,
|
|
|
|
unsigned int size)
|
|
|
|
{
|
|
|
|
struct f_midi2_midi1_port *port = &midi2->midi1_port[cable];
|
|
|
|
|
|
|
|
if (port->pending + size > sizeof(port->buf))
|
|
|
|
return;
|
|
|
|
memcpy(port->buf + port->pending, buf, size);
|
|
|
|
port->pending += size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* try to process data given from the associated UMP stream */
|
|
|
|
static void process_midi1_transmit(struct f_midi2 *midi2)
|
|
|
|
{
|
|
|
|
struct f_midi2_usb_ep *usb_ep = &midi2->midi1_ep_in;
|
|
|
|
struct f_midi2_ep *ep = &midi2->midi2_eps[0];
|
|
|
|
struct usb_request *req = NULL;
|
|
|
|
/* 12 is the largest outcome (4 MIDI1 cmds) for a single UMP packet */
|
|
|
|
unsigned char outbuf[12];
|
2023-07-25 08:22:06 +02:00
|
|
|
unsigned char group, cable;
|
|
|
|
int len, size;
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
u32 ump;
|
|
|
|
|
|
|
|
if (!usb_ep->usb_ep || !usb_ep->usb_ep->enabled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
if (!req) {
|
|
|
|
req = get_empty_request(usb_ep);
|
|
|
|
if (!req)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process_midi1_pending_buf(midi2, &req))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
len = snd_ump_transmit(ep->ump, &ump, 4);
|
|
|
|
if (len <= 0)
|
|
|
|
break;
|
|
|
|
if (snd_ump_receive_ump_val(ep->ump, ump) <= 0)
|
|
|
|
continue;
|
|
|
|
size = snd_ump_convert_from_ump(ep->ump->input_buf, outbuf,
|
|
|
|
&group);
|
|
|
|
if (size <= 0)
|
|
|
|
continue;
|
2023-07-25 08:22:06 +02:00
|
|
|
cable = ep->in_group_to_cable[group];
|
|
|
|
if (!cable)
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
continue;
|
2023-07-25 08:22:06 +02:00
|
|
|
cable--; /* to 0-base */
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
fill_midi1_pending_buf(midi2, cable, outbuf, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req) {
|
|
|
|
if (req->length)
|
|
|
|
queue_request_ep_raw(req);
|
|
|
|
else
|
|
|
|
put_empty_request(req);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* complete handler for MIDI1 EP-in requests */
|
|
|
|
static void f_midi2_midi1_ep_in_complete(struct usb_ep *usb_ep,
|
|
|
|
struct usb_request *req)
|
|
|
|
{
|
|
|
|
struct f_midi2_req_ctx *ctx = req->context;
|
|
|
|
struct f_midi2 *midi2 = ctx->usb_ep->card;
|
|
|
|
int status = req->status;
|
|
|
|
|
|
|
|
put_empty_request(req);
|
|
|
|
|
|
|
|
if (status) {
|
|
|
|
DBG(midi2, "%s complete error %d: %d/%d\n",
|
|
|
|
usb_ep->name, status, req->actual, req->length);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
process_midi1_transmit(midi2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* complete handler for MIDI1 EP-out requests */
|
|
|
|
static void f_midi2_midi1_ep_out_complete(struct usb_ep *usb_ep,
|
|
|
|
struct usb_request *req)
|
|
|
|
{
|
|
|
|
struct f_midi2_req_ctx *ctx = req->context;
|
|
|
|
struct f_midi2 *midi2 = ctx->usb_ep->card;
|
2023-07-25 08:22:06 +02:00
|
|
|
struct f_midi2_ep *ep;
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
struct ump_cvt_to_ump *cvt = &midi2->midi1_ump_cvt;
|
|
|
|
static const u8 midi1_packet_bytes[16] = {
|
|
|
|
0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
|
|
|
|
};
|
2023-07-25 08:22:06 +02:00
|
|
|
unsigned int group, cable, bytes, c, len;
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
int status = req->status;
|
|
|
|
const u8 *buf = req->buf;
|
|
|
|
|
|
|
|
if (status) {
|
|
|
|
DBG(midi2, "%s complete error %d: %d/%d\n",
|
|
|
|
usb_ep->name, status, req->actual, req->length);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = req->actual >> 2;
|
|
|
|
for (; len; len--, buf += 4) {
|
2023-07-25 08:22:06 +02:00
|
|
|
cable = *buf >> 4;
|
|
|
|
ep = midi2->out_cable_mapping[cable].ep;
|
|
|
|
if (!ep)
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
continue;
|
2023-07-25 08:22:06 +02:00
|
|
|
group = midi2->out_cable_mapping[cable].group;
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
bytes = midi1_packet_bytes[*buf & 0x0f];
|
|
|
|
for (c = 0; c < bytes; c++) {
|
2024-07-08 11:57:17 +02:00
|
|
|
snd_ump_convert_to_ump(cvt, group,
|
|
|
|
to_ump_protocol(ep->info.protocol),
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
buf[c + 1]);
|
|
|
|
if (cvt->ump_bytes) {
|
|
|
|
snd_ump_receive(ep->ump, cvt->ump,
|
|
|
|
cvt->ump_bytes);
|
|
|
|
cvt->ump_bytes = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (midi2->operation_mode != MIDI_OP_MODE_MIDI1)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (queue_request_ep_raw(req))
|
|
|
|
goto error;
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
|
|
|
put_empty_request(req);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Common EP handling helpers
|
|
|
|
*/
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/* Start MIDI EP */
|
|
|
|
static int f_midi2_start_ep(struct f_midi2_usb_ep *usb_ep,
|
|
|
|
struct usb_function *fn)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
if (!usb_ep->usb_ep)
|
|
|
|
return 0;
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
usb_ep_disable(usb_ep->usb_ep);
|
|
|
|
err = config_ep_by_speed(usb_ep->card->gadget, fn, usb_ep->usb_ep);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
return usb_ep_enable(usb_ep->usb_ep);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Drop pending requests */
|
|
|
|
static void f_midi2_drop_reqs(struct f_midi2_usb_ep *usb_ep)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
if (!usb_ep->usb_ep || !usb_ep->num_reqs)
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < usb_ep->num_reqs; i++) {
|
|
|
|
if (!test_bit(i, &usb_ep->free_reqs) && usb_ep->reqs[i].req) {
|
|
|
|
usb_ep_dequeue(usb_ep->usb_ep, usb_ep->reqs[i].req);
|
|
|
|
set_bit(i, &usb_ep->free_reqs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate requests for the given EP */
|
|
|
|
static int f_midi2_alloc_ep_reqs(struct f_midi2_usb_ep *usb_ep)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2 = usb_ep->card;
|
|
|
|
int i;
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
if (!usb_ep->usb_ep)
|
|
|
|
return 0;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
if (!usb_ep->reqs)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
for (i = 0; i < midi2->info.num_reqs; i++) {
|
|
|
|
if (usb_ep->reqs[i].req)
|
|
|
|
continue;
|
|
|
|
usb_ep->reqs[i].req = alloc_ep_req(usb_ep->usb_ep,
|
|
|
|
midi2->info.req_buf_size);
|
|
|
|
if (!usb_ep->reqs[i].req)
|
|
|
|
return -ENOMEM;
|
|
|
|
usb_ep->reqs[i].req->context = &usb_ep->reqs[i];
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free allocated requests */
|
|
|
|
static void f_midi2_free_ep_reqs(struct f_midi2_usb_ep *usb_ep)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2 = usb_ep->card;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < midi2->info.num_reqs; i++) {
|
|
|
|
if (!usb_ep->reqs[i].req)
|
|
|
|
continue;
|
|
|
|
free_ep_req(usb_ep->usb_ep, usb_ep->reqs[i].req);
|
|
|
|
usb_ep->reqs[i].req = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize EP */
|
|
|
|
static int f_midi2_init_ep(struct f_midi2 *midi2, struct f_midi2_ep *ep,
|
|
|
|
struct f_midi2_usb_ep *usb_ep,
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
void *desc,
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
void (*complete)(struct usb_ep *usb_ep,
|
|
|
|
struct usb_request *req))
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
usb_ep->card = midi2;
|
|
|
|
usb_ep->ep = ep;
|
|
|
|
usb_ep->usb_ep = usb_ep_autoconfig(midi2->gadget, desc);
|
|
|
|
if (!usb_ep->usb_ep)
|
|
|
|
return -ENODEV;
|
|
|
|
usb_ep->complete = complete;
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
usb_ep->reqs = kcalloc(midi2->info.num_reqs, sizeof(*usb_ep->reqs),
|
|
|
|
GFP_KERNEL);
|
|
|
|
if (!usb_ep->reqs)
|
|
|
|
return -ENOMEM;
|
|
|
|
for (i = 0; i < midi2->info.num_reqs; i++) {
|
|
|
|
usb_ep->reqs[i].index = i;
|
|
|
|
usb_ep->reqs[i].usb_ep = usb_ep;
|
|
|
|
set_bit(i, &usb_ep->free_reqs);
|
|
|
|
usb_ep->num_reqs++;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free EP */
|
|
|
|
static void f_midi2_free_ep(struct f_midi2_usb_ep *usb_ep)
|
|
|
|
{
|
|
|
|
f_midi2_drop_reqs(usb_ep);
|
|
|
|
|
|
|
|
f_midi2_free_ep_reqs(usb_ep);
|
|
|
|
|
|
|
|
kfree(usb_ep->reqs);
|
|
|
|
usb_ep->num_reqs = 0;
|
|
|
|
usb_ep->free_reqs = 0;
|
|
|
|
usb_ep->reqs = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Queue requests for EP-out at start */
|
|
|
|
static void f_midi2_queue_out_reqs(struct f_midi2_usb_ep *usb_ep)
|
|
|
|
{
|
|
|
|
int i, err;
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
if (!usb_ep->usb_ep)
|
|
|
|
return;
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
for (i = 0; i < usb_ep->num_reqs; i++) {
|
|
|
|
if (!test_bit(i, &usb_ep->free_reqs) || !usb_ep->reqs[i].req)
|
|
|
|
continue;
|
|
|
|
usb_ep->reqs[i].req->complete = usb_ep->complete;
|
|
|
|
err = usb_ep_queue(usb_ep->usb_ep, usb_ep->reqs[i].req,
|
|
|
|
GFP_ATOMIC);
|
|
|
|
if (!err)
|
|
|
|
clear_bit(i, &usb_ep->free_reqs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Gadget Function callbacks
|
|
|
|
*/
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
/* stop both IN and OUT EPs */
|
|
|
|
static void f_midi2_stop_eps(struct f_midi2_usb_ep *ep_in,
|
|
|
|
struct f_midi2_usb_ep *ep_out)
|
|
|
|
{
|
|
|
|
f_midi2_drop_reqs(ep_in);
|
|
|
|
f_midi2_drop_reqs(ep_out);
|
|
|
|
f_midi2_free_ep_reqs(ep_in);
|
|
|
|
f_midi2_free_ep_reqs(ep_out);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* start/queue both IN and OUT EPs */
|
|
|
|
static int f_midi2_start_eps(struct f_midi2_usb_ep *ep_in,
|
|
|
|
struct f_midi2_usb_ep *ep_out,
|
|
|
|
struct usb_function *fn)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = f_midi2_start_ep(ep_in, fn);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
err = f_midi2_start_ep(ep_out, fn);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
err = f_midi2_alloc_ep_reqs(ep_in);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
err = f_midi2_alloc_ep_reqs(ep_out);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
f_midi2_queue_out_reqs(ep_out);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/* gadget function set_alt callback */
|
|
|
|
static int f_midi2_set_alt(struct usb_function *fn, unsigned int intf,
|
|
|
|
unsigned int alt)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2 = func_to_midi2(fn);
|
|
|
|
struct f_midi2_ep *ep;
|
|
|
|
int i, op_mode, err;
|
|
|
|
|
|
|
|
if (intf != midi2->midi_if || alt > 1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (alt == 0)
|
|
|
|
op_mode = MIDI_OP_MODE_MIDI1;
|
|
|
|
else
|
2024-11-07 13:33:48 +00:00
|
|
|
op_mode = MIDI_OP_MODE_MIDI2;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
|
|
|
if (midi2->operation_mode == op_mode)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
midi2->operation_mode = op_mode;
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
if (op_mode != MIDI_OP_MODE_MIDI1)
|
|
|
|
f_midi2_stop_eps(&midi2->midi1_ep_in, &midi2->midi1_ep_out);
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
if (op_mode != MIDI_OP_MODE_MIDI2) {
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
ep = &midi2->midi2_eps[i];
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
f_midi2_stop_eps(&ep->ep_in, &ep->ep_out);
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
if (op_mode == MIDI_OP_MODE_MIDI1)
|
|
|
|
return f_midi2_start_eps(&midi2->midi1_ep_in,
|
|
|
|
&midi2->midi1_ep_out, fn);
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
if (op_mode == MIDI_OP_MODE_MIDI2) {
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
ep = &midi2->midi2_eps[i];
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
err = f_midi2_start_eps(&ep->ep_in, &ep->ep_out, fn);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* gadget function get_alt callback */
|
|
|
|
static int f_midi2_get_alt(struct usb_function *fn, unsigned int intf)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2 = func_to_midi2(fn);
|
|
|
|
|
|
|
|
if (intf == midi2->midi_if &&
|
|
|
|
midi2->operation_mode == MIDI_OP_MODE_MIDI2)
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert UMP direction to USB MIDI 2.0 direction */
|
|
|
|
static unsigned int ump_to_usb_dir(unsigned int ump_dir)
|
|
|
|
{
|
|
|
|
switch (ump_dir) {
|
|
|
|
case SNDRV_UMP_DIR_INPUT:
|
|
|
|
return USB_MS_GR_TRM_BLOCK_TYPE_INPUT_ONLY;
|
|
|
|
case SNDRV_UMP_DIR_OUTPUT:
|
|
|
|
return USB_MS_GR_TRM_BLOCK_TYPE_OUTPUT_ONLY;
|
|
|
|
default:
|
|
|
|
return USB_MS_GR_TRM_BLOCK_TYPE_BIDIRECTIONAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* assign GTB descriptors (for the given request) */
|
|
|
|
static void assign_block_descriptors(struct f_midi2 *midi2,
|
|
|
|
struct usb_request *req,
|
|
|
|
int max_len)
|
|
|
|
{
|
|
|
|
struct usb_ms20_gr_trm_block_header_descriptor header;
|
|
|
|
struct usb_ms20_gr_trm_block_descriptor *desc;
|
|
|
|
struct f_midi2_block_info *b;
|
|
|
|
struct f_midi2_ep *ep;
|
|
|
|
int i, blk, len;
|
|
|
|
char *data;
|
|
|
|
|
|
|
|
len = sizeof(gtb_header_desc) + sizeof(gtb_desc) * midi2->total_blocks;
|
|
|
|
if (WARN_ON(len > midi2->info.req_buf_size))
|
|
|
|
return;
|
|
|
|
|
|
|
|
header = gtb_header_desc;
|
|
|
|
header.wTotalLength = cpu_to_le16(len);
|
|
|
|
if (max_len < len) {
|
|
|
|
len = min_t(int, len, sizeof(header));
|
|
|
|
memcpy(req->buf, &header, len);
|
|
|
|
req->length = len;
|
|
|
|
req->zero = len < max_len;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(req->buf, &header, sizeof(header));
|
|
|
|
data = req->buf + sizeof(header);
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
ep = &midi2->midi2_eps[i];
|
|
|
|
for (blk = 0; blk < ep->num_blks; blk++) {
|
|
|
|
b = &ep->blks[blk].info;
|
|
|
|
desc = (struct usb_ms20_gr_trm_block_descriptor *)data;
|
|
|
|
|
|
|
|
*desc = gtb_desc;
|
|
|
|
desc->bGrpTrmBlkID = ep->blks[blk].gtb_id;
|
|
|
|
desc->bGrpTrmBlkType = ump_to_usb_dir(b->direction);
|
|
|
|
desc->nGroupTrm = b->first_group;
|
|
|
|
desc->nNumGroupTrm = b->num_groups;
|
|
|
|
desc->iBlockItem = ep->blks[blk].string_id;
|
|
|
|
|
2024-07-08 11:57:17 +02:00
|
|
|
if (ep->info.protocol == 2)
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
desc->bMIDIProtocol = USB_MS_MIDI_PROTO_2_0;
|
|
|
|
else
|
|
|
|
desc->bMIDIProtocol = USB_MS_MIDI_PROTO_1_0_128;
|
|
|
|
|
|
|
|
if (b->is_midi1 == 2) {
|
|
|
|
desc->wMaxInputBandwidth = cpu_to_le16(1);
|
|
|
|
desc->wMaxOutputBandwidth = cpu_to_le16(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
data += sizeof(*desc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
req->length = len;
|
|
|
|
req->zero = len < max_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* gadget function setup callback: handle GTB requests */
|
|
|
|
static int f_midi2_setup(struct usb_function *fn,
|
|
|
|
const struct usb_ctrlrequest *ctrl)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2 = func_to_midi2(fn);
|
|
|
|
struct usb_composite_dev *cdev = fn->config->cdev;
|
|
|
|
struct usb_request *req = cdev->req;
|
|
|
|
u16 value, length;
|
|
|
|
|
|
|
|
if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD ||
|
|
|
|
ctrl->bRequest != USB_REQ_GET_DESCRIPTOR)
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
|
|
value = le16_to_cpu(ctrl->wValue);
|
|
|
|
length = le16_to_cpu(ctrl->wLength);
|
|
|
|
|
|
|
|
if ((value >> 8) != USB_DT_CS_GR_TRM_BLOCK)
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
|
|
/* handle only altset 1 */
|
|
|
|
if ((value & 0xff) != 1)
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
|
|
assign_block_descriptors(midi2, req, length);
|
|
|
|
return usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* gadget function disable callback */
|
|
|
|
static void f_midi2_disable(struct usb_function *fn)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2 = func_to_midi2(fn);
|
|
|
|
|
|
|
|
midi2->operation_mode = MIDI_OP_MODE_UNSET;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ALSA UMP ops: most of them are NOPs, only trigger for write is needed
|
|
|
|
*/
|
|
|
|
static int f_midi2_ump_open(struct snd_ump_endpoint *ump, int dir)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_midi2_ump_close(struct snd_ump_endpoint *ump, int dir)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_midi2_ump_trigger(struct snd_ump_endpoint *ump, int dir, int up)
|
|
|
|
{
|
|
|
|
struct f_midi2_ep *ep = ump->private_data;
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
struct f_midi2 *midi2 = ep->card;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
if (up && dir == SNDRV_RAWMIDI_STREAM_OUTPUT) {
|
|
|
|
switch (midi2->operation_mode) {
|
|
|
|
case MIDI_OP_MODE_MIDI1:
|
|
|
|
process_midi1_transmit(midi2);
|
|
|
|
break;
|
|
|
|
case MIDI_OP_MODE_MIDI2:
|
|
|
|
process_ump_transmit(ep);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void f_midi2_ump_drain(struct snd_ump_endpoint *ump, int dir)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct snd_ump_ops f_midi2_ump_ops = {
|
|
|
|
.open = f_midi2_ump_open,
|
|
|
|
.close = f_midi2_ump_close,
|
|
|
|
.trigger = f_midi2_ump_trigger,
|
|
|
|
.drain = f_midi2_ump_drain,
|
|
|
|
};
|
|
|
|
|
2023-07-25 08:22:05 +02:00
|
|
|
/*
|
|
|
|
* "Operation Mode" control element
|
|
|
|
*/
|
|
|
|
static int f_midi2_operation_mode_info(struct snd_kcontrol *kcontrol,
|
|
|
|
struct snd_ctl_elem_info *uinfo)
|
|
|
|
{
|
|
|
|
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
|
|
|
uinfo->count = 1;
|
|
|
|
uinfo->value.integer.min = MIDI_OP_MODE_UNSET;
|
|
|
|
uinfo->value.integer.max = MIDI_OP_MODE_MIDI2;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int f_midi2_operation_mode_get(struct snd_kcontrol *kcontrol,
|
|
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2 = snd_kcontrol_chip(kcontrol);
|
|
|
|
|
|
|
|
ucontrol->value.integer.value[0] = midi2->operation_mode;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct snd_kcontrol_new operation_mode_ctl = {
|
|
|
|
.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
|
|
|
|
.name = "Operation Mode",
|
|
|
|
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
|
|
|
.info = f_midi2_operation_mode_info,
|
|
|
|
.get = f_midi2_operation_mode_get,
|
|
|
|
};
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/*
|
|
|
|
* ALSA UMP instance creation / deletion
|
|
|
|
*/
|
|
|
|
static void f_midi2_free_card(struct f_midi2 *midi2)
|
|
|
|
{
|
|
|
|
if (midi2->card) {
|
|
|
|
snd_card_free_when_closed(midi2->card);
|
|
|
|
midi2->card = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* use a reverse direction for the gadget host */
|
|
|
|
static int reverse_dir(int dir)
|
|
|
|
{
|
|
|
|
if (!dir || dir == SNDRV_UMP_DIR_BIDIRECTION)
|
|
|
|
return dir;
|
|
|
|
return (dir == SNDRV_UMP_DIR_OUTPUT) ?
|
|
|
|
SNDRV_UMP_DIR_INPUT : SNDRV_UMP_DIR_OUTPUT;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int f_midi2_create_card(struct f_midi2 *midi2)
|
|
|
|
{
|
|
|
|
struct snd_card *card;
|
|
|
|
struct snd_ump_endpoint *ump;
|
|
|
|
struct f_midi2_ep *ep;
|
|
|
|
int i, id, blk, err;
|
|
|
|
__be32 sw;
|
|
|
|
|
|
|
|
err = snd_card_new(&midi2->gadget->dev, -1, NULL, THIS_MODULE, 0,
|
|
|
|
&card);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
midi2->card = card;
|
|
|
|
|
|
|
|
strcpy(card->driver, "f_midi2");
|
|
|
|
strcpy(card->shortname, "MIDI 2.0 Gadget");
|
|
|
|
strcpy(card->longname, "MIDI 2.0 Gadget");
|
|
|
|
|
|
|
|
id = 0;
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
ep = &midi2->midi2_eps[i];
|
|
|
|
err = snd_ump_endpoint_new(card, "MIDI 2.0 Gadget", id,
|
|
|
|
1, 1, &ump);
|
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
|
|
|
id++;
|
|
|
|
|
|
|
|
ep->ump = ump;
|
|
|
|
ump->no_process_stream = true;
|
|
|
|
ump->private_data = ep;
|
|
|
|
ump->ops = &f_midi2_ump_ops;
|
|
|
|
if (midi2->info.static_block)
|
|
|
|
ump->info.flags |= SNDRV_UMP_EP_INFO_STATIC_BLOCKS;
|
|
|
|
ump->info.protocol_caps = (ep->info.protocol_caps & 3) << 8;
|
2024-07-08 11:57:17 +02:00
|
|
|
ump->info.protocol = to_ump_protocol(ep->info.protocol);
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
ump->info.version = 0x0101;
|
|
|
|
ump->info.family_id = ep->info.family;
|
|
|
|
ump->info.model_id = ep->info.model;
|
|
|
|
ump->info.manufacturer_id = ep->info.manufacturer & 0xffffff;
|
|
|
|
sw = cpu_to_be32(ep->info.sw_revision);
|
|
|
|
memcpy(ump->info.sw_revision, &sw, 4);
|
|
|
|
|
|
|
|
strscpy(ump->info.name, ump_ep_name(ep),
|
|
|
|
sizeof(ump->info.name));
|
|
|
|
strscpy(ump->info.product_id, ump_product_id(ep),
|
|
|
|
sizeof(ump->info.product_id));
|
|
|
|
strscpy(ump->core.name, ump->info.name, sizeof(ump->core.name));
|
|
|
|
|
|
|
|
for (blk = 0; blk < ep->num_blks; blk++) {
|
|
|
|
const struct f_midi2_block_info *b = &ep->blks[blk].info;
|
|
|
|
struct snd_ump_block *fb;
|
|
|
|
|
|
|
|
err = snd_ump_block_new(ump, blk,
|
|
|
|
reverse_dir(b->direction),
|
|
|
|
b->first_group, b->num_groups,
|
|
|
|
&ep->blks[blk].fb);
|
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
|
|
|
fb = ep->blks[blk].fb;
|
|
|
|
fb->info.active = !!b->active;
|
|
|
|
fb->info.midi_ci_version = b->midi_ci_version;
|
|
|
|
fb->info.ui_hint = reverse_dir(b->ui_hint);
|
|
|
|
fb->info.sysex8_streams = b->sysex8_streams;
|
2024-11-27 08:02:11 +01:00
|
|
|
if (b->is_midi1 < 2)
|
|
|
|
fb->info.flags |= b->is_midi1;
|
|
|
|
else
|
|
|
|
fb->info.flags |= SNDRV_UMP_BLOCK_IS_MIDI1 |
|
|
|
|
SNDRV_UMP_BLOCK_IS_LOWSPEED;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
strscpy(fb->info.name, ump_fb_name(b),
|
|
|
|
sizeof(fb->info.name));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
err = snd_ump_attach_legacy_rawmidi(midi2->midi2_eps[i].ump,
|
|
|
|
"Legacy MIDI", id);
|
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
|
|
|
id++;
|
|
|
|
}
|
|
|
|
|
2023-07-25 08:22:05 +02:00
|
|
|
err = snd_ctl_add(card, snd_ctl_new1(&operation_mode_ctl, midi2));
|
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
err = snd_card_register(card);
|
|
|
|
if (err < 0)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
f_midi2_free_card(midi2);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Creation of USB descriptors
|
|
|
|
*/
|
|
|
|
struct f_midi2_usb_config {
|
|
|
|
struct usb_descriptor_header **list;
|
|
|
|
unsigned int size;
|
|
|
|
unsigned int alloc;
|
2023-07-25 08:22:02 +02:00
|
|
|
|
|
|
|
/* MIDI 1.0 jacks */
|
|
|
|
unsigned char jack_in, jack_out, jack_id;
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
struct usb_midi_in_jack_descriptor jack_ins[MAX_CABLES];
|
|
|
|
struct usb_midi_out_jack_descriptor_1 jack_outs[MAX_CABLES];
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static int append_config(struct f_midi2_usb_config *config, void *d)
|
|
|
|
{
|
|
|
|
unsigned int size;
|
|
|
|
void *buf;
|
|
|
|
|
|
|
|
if (config->size + 2 >= config->alloc) {
|
|
|
|
size = config->size + 16;
|
|
|
|
buf = krealloc(config->list, size * sizeof(void *), GFP_KERNEL);
|
|
|
|
if (!buf)
|
|
|
|
return -ENOMEM;
|
|
|
|
config->list = buf;
|
|
|
|
config->alloc = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
config->list[config->size] = d;
|
|
|
|
config->size++;
|
|
|
|
config->list[config->size] = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int append_configs(struct f_midi2_usb_config *config, void **d)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
for (; *d; d++) {
|
|
|
|
err = append_config(config, *d);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-07-25 08:22:02 +02:00
|
|
|
static int append_midi1_in_jack(struct f_midi2 *midi2,
|
|
|
|
struct f_midi2_usb_config *config,
|
2023-07-25 08:22:06 +02:00
|
|
|
struct midi1_cable_mapping *map,
|
2023-07-25 08:22:02 +02:00
|
|
|
unsigned int type)
|
|
|
|
{
|
|
|
|
struct usb_midi_in_jack_descriptor *jack =
|
|
|
|
&config->jack_ins[config->jack_in++];
|
|
|
|
int id = ++config->jack_id;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
jack->bLength = 0x06;
|
|
|
|
jack->bDescriptorType = USB_DT_CS_INTERFACE;
|
|
|
|
jack->bDescriptorSubtype = USB_MS_MIDI_IN_JACK;
|
|
|
|
jack->bJackType = type;
|
|
|
|
jack->bJackID = id;
|
2023-07-25 08:22:06 +02:00
|
|
|
/* use the corresponding block name as jack name */
|
|
|
|
if (map->ep)
|
|
|
|
jack->iJack = map->ep->blks[map->block].string_id;
|
2023-07-25 08:22:02 +02:00
|
|
|
|
|
|
|
err = append_config(config, jack);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int append_midi1_out_jack(struct f_midi2 *midi2,
|
|
|
|
struct f_midi2_usb_config *config,
|
2023-07-25 08:22:06 +02:00
|
|
|
struct midi1_cable_mapping *map,
|
2023-07-25 08:22:02 +02:00
|
|
|
unsigned int type, unsigned int source)
|
|
|
|
{
|
|
|
|
struct usb_midi_out_jack_descriptor_1 *jack =
|
|
|
|
&config->jack_outs[config->jack_out++];
|
|
|
|
int id = ++config->jack_id;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
jack->bLength = 0x09;
|
|
|
|
jack->bDescriptorType = USB_DT_CS_INTERFACE;
|
|
|
|
jack->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK;
|
|
|
|
jack->bJackType = type;
|
|
|
|
jack->bJackID = id;
|
|
|
|
jack->bNrInputPins = 1;
|
|
|
|
jack->pins[0].baSourceID = source;
|
|
|
|
jack->pins[0].baSourcePin = 0x01;
|
2023-07-25 08:22:06 +02:00
|
|
|
/* use the corresponding block name as jack name */
|
|
|
|
if (map->ep)
|
|
|
|
jack->iJack = map->ep->blks[map->block].string_id;
|
2023-07-25 08:22:02 +02:00
|
|
|
|
|
|
|
err = append_config(config, jack);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
static int f_midi2_create_usb_configs(struct f_midi2 *midi2,
|
|
|
|
struct f_midi2_usb_config *config,
|
|
|
|
int speed)
|
|
|
|
{
|
2023-07-25 08:22:02 +02:00
|
|
|
void **midi1_in_eps, **midi1_out_eps;
|
|
|
|
int i, jack, total;
|
|
|
|
int err;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
|
|
|
switch (speed) {
|
|
|
|
default:
|
|
|
|
case USB_SPEED_HIGH:
|
|
|
|
midi2_midi1_ep_out_desc.wMaxPacketSize = cpu_to_le16(512);
|
|
|
|
midi2_midi1_ep_in_desc.wMaxPacketSize = cpu_to_le16(512);
|
|
|
|
for (i = 0; i < midi2->num_eps; i++)
|
|
|
|
midi2_midi2_ep_out_desc[i].wMaxPacketSize =
|
|
|
|
cpu_to_le16(512);
|
|
|
|
fallthrough;
|
|
|
|
case USB_SPEED_FULL:
|
2023-07-25 08:22:02 +02:00
|
|
|
midi1_in_eps = midi2_midi1_ep_in_descs;
|
|
|
|
midi1_out_eps = midi2_midi1_ep_out_descs;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
break;
|
|
|
|
case USB_SPEED_SUPER:
|
|
|
|
midi2_midi1_ep_out_desc.wMaxPacketSize = cpu_to_le16(1024);
|
|
|
|
midi2_midi1_ep_in_desc.wMaxPacketSize = cpu_to_le16(1024);
|
|
|
|
for (i = 0; i < midi2->num_eps; i++)
|
|
|
|
midi2_midi2_ep_out_desc[i].wMaxPacketSize =
|
|
|
|
cpu_to_le16(1024);
|
2023-07-25 08:22:02 +02:00
|
|
|
midi1_in_eps = midi2_midi1_ep_in_ss_descs;
|
|
|
|
midi1_out_eps = midi2_midi1_ep_out_ss_descs;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = append_configs(config, midi2_audio_descs);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
2023-07-25 08:22:02 +02:00
|
|
|
|
2023-07-25 08:22:06 +02:00
|
|
|
if (midi2->num_midi1_in && midi2->num_midi1_out)
|
2023-07-25 08:22:02 +02:00
|
|
|
midi2_midi1_if_desc.bNumEndpoints = 2;
|
2023-07-25 08:22:06 +02:00
|
|
|
else
|
|
|
|
midi2_midi1_if_desc.bNumEndpoints = 1;
|
2023-07-25 08:22:02 +02:00
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
err = append_configs(config, midi2_midi1_descs);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
2023-07-25 08:22:02 +02:00
|
|
|
|
|
|
|
total = USB_DT_MS_HEADER_SIZE;
|
2023-07-25 08:22:06 +02:00
|
|
|
if (midi2->num_midi1_out) {
|
2023-07-25 08:22:02 +02:00
|
|
|
midi2_midi1_ep_out_class_desc.bLength =
|
2023-07-25 08:22:06 +02:00
|
|
|
USB_DT_MS_ENDPOINT_SIZE(midi2->num_midi1_out);
|
2023-07-25 08:22:02 +02:00
|
|
|
total += midi2_midi1_ep_out_class_desc.bLength;
|
|
|
|
midi2_midi1_ep_out_class_desc.bNumEmbMIDIJack =
|
2023-07-25 08:22:06 +02:00
|
|
|
midi2->num_midi1_out;
|
|
|
|
total += midi2->num_midi1_out *
|
2023-07-25 08:22:02 +02:00
|
|
|
(USB_DT_MIDI_IN_SIZE + USB_DT_MIDI_OUT_SIZE(1));
|
2023-07-25 08:22:06 +02:00
|
|
|
for (i = 0; i < midi2->num_midi1_out; i++) {
|
2023-07-25 08:22:02 +02:00
|
|
|
jack = append_midi1_in_jack(midi2, config,
|
2023-07-25 08:22:06 +02:00
|
|
|
&midi2->in_cable_mapping[i],
|
2023-07-25 08:22:02 +02:00
|
|
|
USB_MS_EMBEDDED);
|
|
|
|
if (jack < 0)
|
|
|
|
return jack;
|
|
|
|
midi2_midi1_ep_out_class_desc.baAssocJackID[i] = jack;
|
|
|
|
jack = append_midi1_out_jack(midi2, config,
|
2023-07-25 08:22:06 +02:00
|
|
|
&midi2->in_cable_mapping[i],
|
2023-07-25 08:22:02 +02:00
|
|
|
USB_MS_EXTERNAL, jack);
|
|
|
|
if (jack < 0)
|
|
|
|
return jack;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-25 08:22:06 +02:00
|
|
|
if (midi2->num_midi1_in) {
|
2023-07-25 08:22:02 +02:00
|
|
|
midi2_midi1_ep_in_class_desc.bLength =
|
2023-07-25 08:22:06 +02:00
|
|
|
USB_DT_MS_ENDPOINT_SIZE(midi2->num_midi1_in);
|
2023-07-25 08:22:02 +02:00
|
|
|
total += midi2_midi1_ep_in_class_desc.bLength;
|
|
|
|
midi2_midi1_ep_in_class_desc.bNumEmbMIDIJack =
|
2023-07-25 08:22:06 +02:00
|
|
|
midi2->num_midi1_in;
|
|
|
|
total += midi2->num_midi1_in *
|
2023-07-25 08:22:02 +02:00
|
|
|
(USB_DT_MIDI_IN_SIZE + USB_DT_MIDI_OUT_SIZE(1));
|
2023-07-25 08:22:06 +02:00
|
|
|
for (i = 0; i < midi2->num_midi1_in; i++) {
|
2023-07-25 08:22:02 +02:00
|
|
|
jack = append_midi1_in_jack(midi2, config,
|
2023-07-25 08:22:06 +02:00
|
|
|
&midi2->out_cable_mapping[i],
|
2023-07-25 08:22:02 +02:00
|
|
|
USB_MS_EXTERNAL);
|
|
|
|
if (jack < 0)
|
|
|
|
return jack;
|
|
|
|
jack = append_midi1_out_jack(midi2, config,
|
2023-07-25 08:22:06 +02:00
|
|
|
&midi2->out_cable_mapping[i],
|
2023-07-25 08:22:02 +02:00
|
|
|
USB_MS_EMBEDDED, jack);
|
|
|
|
if (jack < 0)
|
|
|
|
return jack;
|
|
|
|
midi2_midi1_ep_in_class_desc.baAssocJackID[i] = jack;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
midi2_midi1_class_desc.wTotalLength = cpu_to_le16(total);
|
|
|
|
|
2023-07-25 08:22:06 +02:00
|
|
|
if (midi2->num_midi1_out) {
|
2023-07-25 08:22:02 +02:00
|
|
|
err = append_configs(config, midi1_out_eps);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
}
|
2023-07-25 08:22:06 +02:00
|
|
|
if (midi2->num_midi1_in) {
|
2023-07-25 08:22:02 +02:00
|
|
|
err = append_configs(config, midi1_in_eps);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
err = append_configs(config, midi2_midi2_descs);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
err = append_config(config, &midi2_midi2_ep_out_desc[i]);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) {
|
|
|
|
err = append_config(config, &midi2_midi2_ep_out_ss_comp_desc);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
err = append_config(config, &midi2_midi2_ep_out_class_desc[i]);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
err = append_config(config, &midi2_midi2_ep_in_desc[i]);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
if (speed == USB_SPEED_SUPER || speed == USB_SPEED_SUPER_PLUS) {
|
|
|
|
err = append_config(config, &midi2_midi2_ep_in_ss_comp_desc);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
err = append_config(config, &midi2_midi2_ep_in_class_desc[i]);
|
|
|
|
if (err < 0)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_midi2_free_usb_configs(struct f_midi2_usb_config *config)
|
|
|
|
{
|
|
|
|
kfree(config->list);
|
|
|
|
memset(config, 0, sizeof(*config));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* as we use the static descriptors for simplicity, serialize bind call */
|
|
|
|
static DEFINE_MUTEX(f_midi2_desc_mutex);
|
|
|
|
|
|
|
|
/* fill MIDI2 EP class-specific descriptor */
|
|
|
|
static void fill_midi2_class_desc(struct f_midi2_ep *ep,
|
|
|
|
struct usb_ms20_endpoint_descriptor_32 *cdesc)
|
|
|
|
{
|
|
|
|
int blk;
|
|
|
|
|
|
|
|
cdesc->bLength = USB_DT_MS20_ENDPOINT_SIZE(ep->num_blks);
|
|
|
|
cdesc->bDescriptorType = USB_DT_CS_ENDPOINT;
|
|
|
|
cdesc->bDescriptorSubtype = USB_MS_GENERAL_2_0;
|
|
|
|
cdesc->bNumGrpTrmBlock = ep->num_blks;
|
|
|
|
for (blk = 0; blk < ep->num_blks; blk++)
|
|
|
|
cdesc->baAssoGrpTrmBlkID[blk] = ep->blks[blk].gtb_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize MIDI2 EP-in */
|
|
|
|
static int f_midi2_init_midi2_ep_in(struct f_midi2 *midi2, int index)
|
|
|
|
{
|
|
|
|
struct f_midi2_ep *ep = &midi2->midi2_eps[index];
|
|
|
|
struct usb_endpoint_descriptor *desc = &midi2_midi2_ep_in_desc[index];
|
|
|
|
|
|
|
|
desc->bLength = USB_DT_ENDPOINT_SIZE;
|
|
|
|
desc->bDescriptorType = USB_DT_ENDPOINT;
|
|
|
|
desc->bEndpointAddress = USB_DIR_IN;
|
|
|
|
desc->bmAttributes = USB_ENDPOINT_XFER_INT;
|
|
|
|
desc->wMaxPacketSize = cpu_to_le16(EP_MAX_PACKET_INT);
|
|
|
|
desc->bInterval = 1;
|
|
|
|
|
|
|
|
fill_midi2_class_desc(ep, &midi2_midi2_ep_in_class_desc[index]);
|
|
|
|
|
|
|
|
return f_midi2_init_ep(midi2, ep, &ep->ep_in, desc,
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
f_midi2_ep_in_complete);
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* initialize MIDI2 EP-out */
|
|
|
|
static int f_midi2_init_midi2_ep_out(struct f_midi2 *midi2, int index)
|
|
|
|
{
|
|
|
|
struct f_midi2_ep *ep = &midi2->midi2_eps[index];
|
|
|
|
struct usb_endpoint_descriptor *desc = &midi2_midi2_ep_out_desc[index];
|
|
|
|
|
|
|
|
desc->bLength = USB_DT_ENDPOINT_SIZE;
|
|
|
|
desc->bDescriptorType = USB_DT_ENDPOINT;
|
|
|
|
desc->bEndpointAddress = USB_DIR_OUT;
|
|
|
|
desc->bmAttributes = USB_ENDPOINT_XFER_BULK;
|
|
|
|
|
|
|
|
fill_midi2_class_desc(ep, &midi2_midi2_ep_out_class_desc[index]);
|
|
|
|
|
|
|
|
return f_midi2_init_ep(midi2, ep, &ep->ep_out, desc,
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
f_midi2_ep_out_complete);
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* gadget function bind callback */
|
|
|
|
static int f_midi2_bind(struct usb_configuration *c, struct usb_function *f)
|
|
|
|
{
|
|
|
|
struct usb_composite_dev *cdev = c->cdev;
|
|
|
|
struct f_midi2 *midi2 = func_to_midi2(f);
|
|
|
|
struct f_midi2_ep *ep;
|
|
|
|
struct f_midi2_usb_config config = {};
|
|
|
|
struct usb_gadget_strings string_fn = {
|
|
|
|
.language = 0x0409, /* en-us */
|
|
|
|
.strings = midi2->string_defs,
|
|
|
|
};
|
|
|
|
struct usb_gadget_strings *strings[] = {
|
|
|
|
&string_fn,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
int i, blk, status;
|
|
|
|
|
|
|
|
midi2->gadget = cdev->gadget;
|
|
|
|
midi2->operation_mode = MIDI_OP_MODE_UNSET;
|
|
|
|
|
|
|
|
status = f_midi2_create_card(midi2);
|
|
|
|
if (status < 0)
|
|
|
|
goto fail_register;
|
|
|
|
|
|
|
|
/* maybe allocate device-global string ID */
|
|
|
|
midi2->strings = usb_gstrings_attach(c->cdev, strings,
|
|
|
|
midi2->total_blocks + 1);
|
|
|
|
if (IS_ERR(midi2->strings)) {
|
|
|
|
status = PTR_ERR(midi2->strings);
|
|
|
|
goto fail_string;
|
|
|
|
}
|
|
|
|
|
|
|
|
mutex_lock(&f_midi2_desc_mutex);
|
|
|
|
midi2_midi1_if_desc.iInterface = midi2->strings[STR_IFACE].id;
|
|
|
|
midi2_midi2_if_desc.iInterface = midi2->strings[STR_IFACE].id;
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
ep = &midi2->midi2_eps[i];
|
|
|
|
for (blk = 0; blk < ep->num_blks; blk++)
|
|
|
|
ep->blks[blk].string_id =
|
|
|
|
midi2->strings[gtb_to_str_id(ep->blks[blk].gtb_id)].id;
|
|
|
|
}
|
|
|
|
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
midi2_midi2_if_desc.bNumEndpoints = midi2->num_eps * 2;
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/* audio interface */
|
|
|
|
status = usb_interface_id(c, f);
|
|
|
|
if (status < 0)
|
|
|
|
goto fail;
|
|
|
|
midi2_audio_if_desc.bInterfaceNumber = status;
|
|
|
|
|
|
|
|
/* MIDI streaming */
|
|
|
|
status = usb_interface_id(c, f);
|
|
|
|
if (status < 0)
|
|
|
|
goto fail;
|
|
|
|
midi2->midi_if = status;
|
|
|
|
midi2_midi1_if_desc.bInterfaceNumber = status;
|
|
|
|
midi2_midi2_if_desc.bInterfaceNumber = status;
|
|
|
|
midi2_audio_class_desc.baInterfaceNr[0] = status;
|
|
|
|
|
|
|
|
/* allocate instance-specific endpoints */
|
2023-07-25 08:22:02 +02:00
|
|
|
if (midi2->midi2_eps[0].blks[0].info.direction != SNDRV_UMP_DIR_OUTPUT) {
|
|
|
|
status = f_midi2_init_ep(midi2, NULL, &midi2->midi1_ep_in,
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
&midi2_midi1_ep_in_desc,
|
|
|
|
f_midi2_midi1_ep_in_complete);
|
2023-07-25 08:22:02 +02:00
|
|
|
if (status)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (midi2->midi2_eps[0].blks[0].info.direction != SNDRV_UMP_DIR_INPUT) {
|
|
|
|
status = f_midi2_init_ep(midi2, NULL, &midi2->midi1_ep_out,
|
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
This patch extends MIDI 2.0 function driver to add more proper support
for MIDI 1.0 interface. Before this patch, the driver only exposes
the USB descriptor of a MIDI 1.0 interface in altset 0 while no actual
I/O is running for it. This patch enables the actual I/O for the
altset 0; the backend UMP rawmidi is translated from/to the MIDI 1.0
USB commands.
For converting to USB MIDI 1.0 data protocol, a helper function is
copied from the existing f_midi driver, in addition to a few other UMP
Core helper functions. For the MIDI 1.0 OUT (that is, input for
gadget), the incoming USB MIDI 1.0 packet is translated to UMP packets
via UMP Core helper, and tossed to the attached UMP rawmidi. It's a
relatively straightforward. OTOH, for MIDI 1.0 IN (i.e. output for
gadget), it's a bit more complex: we need to convert a source UMP
packet once to the standard MIDI 1.0 byte stream, and convert it again
to USB MIDI 1.0 packets, then send them out.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-5-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:03 +02:00
|
|
|
&midi2_midi1_ep_out_desc,
|
|
|
|
f_midi2_midi1_ep_out_complete);
|
2023-07-25 08:22:02 +02:00
|
|
|
if (status)
|
|
|
|
goto fail;
|
|
|
|
}
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
status = f_midi2_init_midi2_ep_in(midi2, i);
|
|
|
|
if (status)
|
|
|
|
goto fail;
|
|
|
|
status = f_midi2_init_midi2_ep_out(midi2, i);
|
|
|
|
if (status)
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
status = f_midi2_create_usb_configs(midi2, &config, USB_SPEED_FULL);
|
|
|
|
if (status < 0)
|
|
|
|
goto fail;
|
|
|
|
f->fs_descriptors = usb_copy_descriptors(config.list);
|
|
|
|
if (!f->fs_descriptors) {
|
|
|
|
status = -ENOMEM;
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
f_midi2_free_usb_configs(&config);
|
|
|
|
|
2023-08-03 17:10:50 +08:00
|
|
|
status = f_midi2_create_usb_configs(midi2, &config, USB_SPEED_HIGH);
|
|
|
|
if (status < 0)
|
|
|
|
goto fail;
|
|
|
|
f->hs_descriptors = usb_copy_descriptors(config.list);
|
|
|
|
if (!f->hs_descriptors) {
|
|
|
|
status = -ENOMEM;
|
|
|
|
goto fail;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
}
|
2023-08-03 17:10:50 +08:00
|
|
|
f_midi2_free_usb_configs(&config);
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
2023-08-03 17:10:50 +08:00
|
|
|
status = f_midi2_create_usb_configs(midi2, &config, USB_SPEED_SUPER);
|
|
|
|
if (status < 0)
|
|
|
|
goto fail;
|
|
|
|
f->ss_descriptors = usb_copy_descriptors(config.list);
|
|
|
|
if (!f->ss_descriptors) {
|
|
|
|
status = -ENOMEM;
|
|
|
|
goto fail;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
}
|
2023-08-03 17:10:50 +08:00
|
|
|
f_midi2_free_usb_configs(&config);
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
|
|
|
mutex_unlock(&f_midi2_desc_mutex);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
f_midi2_free_usb_configs(&config);
|
|
|
|
mutex_unlock(&f_midi2_desc_mutex);
|
|
|
|
usb_free_all_descriptors(f);
|
|
|
|
fail_string:
|
|
|
|
f_midi2_free_card(midi2);
|
|
|
|
fail_register:
|
|
|
|
ERROR(midi2, "%s: can't bind, err %d\n", f->name, status);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* gadget function unbind callback */
|
|
|
|
static void f_midi2_unbind(struct usb_configuration *c, struct usb_function *f)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2 = func_to_midi2(f);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
f_midi2_free_card(midi2);
|
|
|
|
|
|
|
|
f_midi2_free_ep(&midi2->midi1_ep_in);
|
|
|
|
f_midi2_free_ep(&midi2->midi1_ep_out);
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
f_midi2_free_ep(&midi2->midi2_eps[i].ep_in);
|
|
|
|
f_midi2_free_ep(&midi2->midi2_eps[i].ep_out);
|
|
|
|
}
|
|
|
|
|
|
|
|
usb_free_all_descriptors(f);
|
|
|
|
}
|
|
|
|
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
/*
|
|
|
|
* ConfigFS interface
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* type conversion helpers */
|
|
|
|
static inline struct f_midi2_opts *to_f_midi2_opts(struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(to_config_group(item), struct f_midi2_opts,
|
|
|
|
func_inst.group);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline struct f_midi2_ep_opts *
|
|
|
|
to_f_midi2_ep_opts(struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(to_config_group(item), struct f_midi2_ep_opts,
|
|
|
|
group);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline struct f_midi2_block_opts *
|
|
|
|
to_f_midi2_block_opts(struct config_item *item)
|
|
|
|
{
|
|
|
|
return container_of(to_config_group(item), struct f_midi2_block_opts,
|
|
|
|
group);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* trim the string to be usable for EP and FB name strings */
|
|
|
|
static void make_name_string(char *s)
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
p = strchr(s, '\n');
|
|
|
|
if (p)
|
|
|
|
*p = 0;
|
|
|
|
|
|
|
|
p = s + strlen(s);
|
|
|
|
for (; p > s && isspace(*p); p--)
|
|
|
|
*p = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* configfs helpers: generic show/store for unisnged int */
|
|
|
|
static ssize_t f_midi2_opts_uint_show(struct f_midi2_opts *opts,
|
|
|
|
u32 val, const char *format, char *page)
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
|
|
|
mutex_lock(&opts->lock);
|
|
|
|
result = sprintf(page, format, val);
|
|
|
|
mutex_unlock(&opts->lock);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t f_midi2_opts_uint_store(struct f_midi2_opts *opts,
|
|
|
|
u32 *valp, u32 minval, u32 maxval,
|
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
mutex_lock(&opts->lock);
|
|
|
|
if (opts->refcnt) {
|
|
|
|
ret = -EBUSY;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = kstrtou32(page, 0, &val);
|
|
|
|
if (ret)
|
|
|
|
goto end;
|
|
|
|
if (val < minval || val > maxval) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
*valp = val;
|
|
|
|
ret = len;
|
|
|
|
|
|
|
|
end:
|
|
|
|
mutex_unlock(&opts->lock);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* generic store for bool */
|
|
|
|
static ssize_t f_midi2_opts_bool_store(struct f_midi2_opts *opts,
|
|
|
|
bool *valp, const char *page, size_t len)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
bool val;
|
|
|
|
|
|
|
|
mutex_lock(&opts->lock);
|
|
|
|
if (opts->refcnt) {
|
|
|
|
ret = -EBUSY;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = kstrtobool(page, &val);
|
|
|
|
if (ret)
|
|
|
|
goto end;
|
|
|
|
*valp = val;
|
|
|
|
ret = len;
|
|
|
|
|
|
|
|
end:
|
|
|
|
mutex_unlock(&opts->lock);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* generic show/store for string */
|
|
|
|
static ssize_t f_midi2_opts_str_show(struct f_midi2_opts *opts,
|
|
|
|
const char *str, char *page)
|
|
|
|
{
|
|
|
|
int result = 0;
|
|
|
|
|
|
|
|
mutex_lock(&opts->lock);
|
|
|
|
if (str)
|
|
|
|
result = scnprintf(page, PAGE_SIZE, "%s\n", str);
|
|
|
|
mutex_unlock(&opts->lock);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t f_midi2_opts_str_store(struct f_midi2_opts *opts,
|
|
|
|
const char **strp, size_t maxlen,
|
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
|
|
|
char *c;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
mutex_lock(&opts->lock);
|
|
|
|
if (opts->refcnt) {
|
|
|
|
ret = -EBUSY;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
c = kstrndup(page, min(len, maxlen), GFP_KERNEL);
|
|
|
|
if (!c) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
kfree(*strp);
|
|
|
|
make_name_string(c);
|
|
|
|
*strp = c;
|
|
|
|
ret = len;
|
|
|
|
|
|
|
|
end:
|
|
|
|
mutex_unlock(&opts->lock);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Definitions for UMP Block config
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* define an uint option for block */
|
|
|
|
#define F_MIDI2_BLOCK_OPT(name, format, minval, maxval) \
|
|
|
|
static ssize_t f_midi2_block_opts_##name##_show(struct config_item *item,\
|
|
|
|
char *page) \
|
|
|
|
{ \
|
|
|
|
struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item); \
|
|
|
|
return f_midi2_opts_uint_show(opts->ep->opts, opts->info.name, \
|
|
|
|
format "\n", page); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static ssize_t f_midi2_block_opts_##name##_store(struct config_item *item,\
|
|
|
|
const char *page, size_t len) \
|
|
|
|
{ \
|
|
|
|
struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item); \
|
|
|
|
return f_midi2_opts_uint_store(opts->ep->opts, &opts->info.name,\
|
|
|
|
minval, maxval, page, len); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
CONFIGFS_ATTR(f_midi2_block_opts_, name)
|
|
|
|
|
|
|
|
/* define a boolean option for block */
|
|
|
|
#define F_MIDI2_BLOCK_BOOL_OPT(name) \
|
|
|
|
static ssize_t f_midi2_block_opts_##name##_show(struct config_item *item,\
|
|
|
|
char *page) \
|
|
|
|
{ \
|
|
|
|
struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item); \
|
|
|
|
return f_midi2_opts_uint_show(opts->ep->opts, opts->info.name, \
|
|
|
|
"%u\n", page); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static ssize_t f_midi2_block_opts_##name##_store(struct config_item *item,\
|
|
|
|
const char *page, size_t len) \
|
|
|
|
{ \
|
|
|
|
struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item); \
|
|
|
|
return f_midi2_opts_bool_store(opts->ep->opts, &opts->info.name,\
|
|
|
|
page, len); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
CONFIGFS_ATTR(f_midi2_block_opts_, name)
|
|
|
|
|
|
|
|
F_MIDI2_BLOCK_OPT(direction, "0x%x", 1, 3);
|
|
|
|
F_MIDI2_BLOCK_OPT(first_group, "0x%x", 0, 15);
|
|
|
|
F_MIDI2_BLOCK_OPT(num_groups, "0x%x", 1, 16);
|
2023-07-25 08:22:06 +02:00
|
|
|
F_MIDI2_BLOCK_OPT(midi1_first_group, "0x%x", 0, 15);
|
|
|
|
F_MIDI2_BLOCK_OPT(midi1_num_groups, "0x%x", 0, 16);
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
F_MIDI2_BLOCK_OPT(ui_hint, "0x%x", 0, 3);
|
|
|
|
F_MIDI2_BLOCK_OPT(midi_ci_version, "%u", 0, 1);
|
|
|
|
F_MIDI2_BLOCK_OPT(sysex8_streams, "%u", 0, 255);
|
|
|
|
F_MIDI2_BLOCK_OPT(is_midi1, "%u", 0, 2);
|
|
|
|
F_MIDI2_BLOCK_BOOL_OPT(active);
|
|
|
|
|
|
|
|
static ssize_t f_midi2_block_opts_name_show(struct config_item *item,
|
|
|
|
char *page)
|
|
|
|
{
|
|
|
|
struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
|
|
|
|
|
|
|
|
return f_midi2_opts_str_show(opts->ep->opts, opts->info.name, page);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t f_midi2_block_opts_name_store(struct config_item *item,
|
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
|
|
|
struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
|
|
|
|
|
|
|
|
return f_midi2_opts_str_store(opts->ep->opts, &opts->info.name, 128,
|
|
|
|
page, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
CONFIGFS_ATTR(f_midi2_block_opts_, name);
|
|
|
|
|
|
|
|
static struct configfs_attribute *f_midi2_block_attrs[] = {
|
|
|
|
&f_midi2_block_opts_attr_direction,
|
|
|
|
&f_midi2_block_opts_attr_first_group,
|
|
|
|
&f_midi2_block_opts_attr_num_groups,
|
2023-07-25 08:22:06 +02:00
|
|
|
&f_midi2_block_opts_attr_midi1_first_group,
|
|
|
|
&f_midi2_block_opts_attr_midi1_num_groups,
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
&f_midi2_block_opts_attr_ui_hint,
|
|
|
|
&f_midi2_block_opts_attr_midi_ci_version,
|
|
|
|
&f_midi2_block_opts_attr_sysex8_streams,
|
|
|
|
&f_midi2_block_opts_attr_is_midi1,
|
|
|
|
&f_midi2_block_opts_attr_active,
|
|
|
|
&f_midi2_block_opts_attr_name,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void f_midi2_block_opts_release(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
|
|
|
|
|
|
|
|
kfree(opts->info.name);
|
|
|
|
kfree(opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_item_operations f_midi2_block_item_ops = {
|
|
|
|
.release = f_midi2_block_opts_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct config_item_type f_midi2_block_type = {
|
|
|
|
.ct_item_ops = &f_midi2_block_item_ops,
|
|
|
|
.ct_attrs = f_midi2_block_attrs,
|
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
|
};
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/* create a f_midi2_block_opts instance for the given block number */
|
|
|
|
static int f_midi2_block_opts_create(struct f_midi2_ep_opts *ep_opts,
|
|
|
|
unsigned int blk,
|
|
|
|
struct f_midi2_block_opts **block_p)
|
|
|
|
{
|
|
|
|
struct f_midi2_block_opts *block_opts;
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
mutex_lock(&ep_opts->opts->lock);
|
|
|
|
if (ep_opts->opts->refcnt || ep_opts->blks[blk]) {
|
|
|
|
ret = -EBUSY;
|
|
|
|
goto out;
|
|
|
|
}
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
|
|
|
block_opts = kzalloc(sizeof(*block_opts), GFP_KERNEL);
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
if (!block_opts) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
|
|
|
block_opts->ep = ep_opts;
|
|
|
|
block_opts->id = blk;
|
|
|
|
|
|
|
|
/* set up the default values */
|
|
|
|
block_opts->info.direction = SNDRV_UMP_DIR_BIDIRECTION;
|
|
|
|
block_opts->info.first_group = 0;
|
|
|
|
block_opts->info.num_groups = 1;
|
|
|
|
block_opts->info.ui_hint = SNDRV_UMP_BLOCK_UI_HINT_BOTH;
|
|
|
|
block_opts->info.active = 1;
|
|
|
|
|
|
|
|
ep_opts->blks[blk] = block_opts;
|
|
|
|
*block_p = block_opts;
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
|
|
|
|
out:
|
2023-07-28 16:51:20 +08:00
|
|
|
mutex_unlock(&ep_opts->opts->lock);
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
return ret;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
}
|
|
|
|
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
/* make_group callback for a block */
|
|
|
|
static struct config_group *
|
|
|
|
f_midi2_opts_block_make(struct config_group *group, const char *name)
|
|
|
|
{
|
|
|
|
struct f_midi2_ep_opts *ep_opts;
|
|
|
|
struct f_midi2_block_opts *block_opts;
|
|
|
|
unsigned int blk;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (strncmp(name, "block.", 6))
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
ret = kstrtouint(name + 6, 10, &blk);
|
|
|
|
if (ret)
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
|
|
ep_opts = to_f_midi2_ep_opts(&group->cg_item);
|
|
|
|
|
|
|
|
if (blk >= SNDRV_UMP_MAX_BLOCKS)
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
if (ep_opts->blks[blk])
|
|
|
|
return ERR_PTR(-EBUSY);
|
|
|
|
ret = f_midi2_block_opts_create(ep_opts, blk, &block_opts);
|
|
|
|
if (ret)
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
|
|
config_group_init_type_name(&block_opts->group, name,
|
|
|
|
&f_midi2_block_type);
|
|
|
|
return &block_opts->group;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* drop_item callback for a block */
|
|
|
|
static void
|
|
|
|
f_midi2_opts_block_drop(struct config_group *group, struct config_item *item)
|
|
|
|
{
|
|
|
|
struct f_midi2_block_opts *block_opts = to_f_midi2_block_opts(item);
|
|
|
|
|
|
|
|
mutex_lock(&block_opts->ep->opts->lock);
|
|
|
|
block_opts->ep->blks[block_opts->id] = NULL;
|
|
|
|
mutex_unlock(&block_opts->ep->opts->lock);
|
|
|
|
config_item_put(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Definitions for UMP Endpoint config
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* define an uint option for EP */
|
|
|
|
#define F_MIDI2_EP_OPT(name, format, minval, maxval) \
|
|
|
|
static ssize_t f_midi2_ep_opts_##name##_show(struct config_item *item, \
|
|
|
|
char *page) \
|
|
|
|
{ \
|
|
|
|
struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item); \
|
|
|
|
return f_midi2_opts_uint_show(opts->opts, opts->info.name, \
|
|
|
|
format "\n", page); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static ssize_t f_midi2_ep_opts_##name##_store(struct config_item *item, \
|
|
|
|
const char *page, size_t len)\
|
|
|
|
{ \
|
|
|
|
struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item); \
|
|
|
|
return f_midi2_opts_uint_store(opts->opts, &opts->info.name, \
|
|
|
|
minval, maxval, page, len); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
CONFIGFS_ATTR(f_midi2_ep_opts_, name)
|
|
|
|
|
|
|
|
/* define a string option for EP */
|
|
|
|
#define F_MIDI2_EP_STR_OPT(name, maxlen) \
|
|
|
|
static ssize_t f_midi2_ep_opts_##name##_show(struct config_item *item, \
|
|
|
|
char *page) \
|
|
|
|
{ \
|
|
|
|
struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item); \
|
|
|
|
return f_midi2_opts_str_show(opts->opts, opts->info.name, page);\
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static ssize_t f_midi2_ep_opts_##name##_store(struct config_item *item, \
|
|
|
|
const char *page, size_t len) \
|
|
|
|
{ \
|
|
|
|
struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item); \
|
|
|
|
return f_midi2_opts_str_store(opts->opts, &opts->info.name, maxlen,\
|
|
|
|
page, len); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
CONFIGFS_ATTR(f_midi2_ep_opts_, name)
|
|
|
|
|
|
|
|
F_MIDI2_EP_OPT(protocol, "0x%x", 1, 2);
|
|
|
|
F_MIDI2_EP_OPT(protocol_caps, "0x%x", 1, 3);
|
|
|
|
F_MIDI2_EP_OPT(manufacturer, "0x%x", 0, 0xffffff);
|
|
|
|
F_MIDI2_EP_OPT(family, "0x%x", 0, 0xffff);
|
|
|
|
F_MIDI2_EP_OPT(model, "0x%x", 0, 0xffff);
|
|
|
|
F_MIDI2_EP_OPT(sw_revision, "0x%x", 0, 0xffffffff);
|
|
|
|
F_MIDI2_EP_STR_OPT(ep_name, 128);
|
|
|
|
F_MIDI2_EP_STR_OPT(product_id, 128);
|
|
|
|
|
|
|
|
static struct configfs_attribute *f_midi2_ep_attrs[] = {
|
|
|
|
&f_midi2_ep_opts_attr_protocol,
|
|
|
|
&f_midi2_ep_opts_attr_protocol_caps,
|
|
|
|
&f_midi2_ep_opts_attr_ep_name,
|
|
|
|
&f_midi2_ep_opts_attr_product_id,
|
|
|
|
&f_midi2_ep_opts_attr_manufacturer,
|
|
|
|
&f_midi2_ep_opts_attr_family,
|
|
|
|
&f_midi2_ep_opts_attr_model,
|
|
|
|
&f_midi2_ep_opts_attr_sw_revision,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void f_midi2_ep_opts_release(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
|
|
|
|
|
|
|
|
kfree(opts->info.ep_name);
|
|
|
|
kfree(opts->info.product_id);
|
|
|
|
kfree(opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_item_operations f_midi2_ep_item_ops = {
|
|
|
|
.release = f_midi2_ep_opts_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct configfs_group_operations f_midi2_ep_group_ops = {
|
|
|
|
.make_group = f_midi2_opts_block_make,
|
|
|
|
.drop_item = f_midi2_opts_block_drop,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct config_item_type f_midi2_ep_type = {
|
|
|
|
.ct_item_ops = &f_midi2_ep_item_ops,
|
|
|
|
.ct_group_ops = &f_midi2_ep_group_ops,
|
|
|
|
.ct_attrs = f_midi2_ep_attrs,
|
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
|
};
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/* create a f_midi2_ep_opts instance */
|
|
|
|
static int f_midi2_ep_opts_create(struct f_midi2_opts *opts,
|
|
|
|
unsigned int index,
|
|
|
|
struct f_midi2_ep_opts **ep_p)
|
|
|
|
{
|
|
|
|
struct f_midi2_ep_opts *ep_opts;
|
|
|
|
|
|
|
|
ep_opts = kzalloc(sizeof(*ep_opts), GFP_KERNEL);
|
|
|
|
if (!ep_opts)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ep_opts->opts = opts;
|
|
|
|
ep_opts->index = index;
|
|
|
|
|
|
|
|
/* set up the default values */
|
|
|
|
ep_opts->info.protocol = 2;
|
|
|
|
ep_opts->info.protocol_caps = 3;
|
|
|
|
|
|
|
|
opts->eps[index] = ep_opts;
|
|
|
|
*ep_p = ep_opts;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
/* make_group callback for an EP */
|
|
|
|
static struct config_group *
|
|
|
|
f_midi2_opts_ep_make(struct config_group *group, const char *name)
|
|
|
|
{
|
|
|
|
struct f_midi2_opts *opts;
|
|
|
|
struct f_midi2_ep_opts *ep_opts;
|
|
|
|
unsigned int index;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (strncmp(name, "ep.", 3))
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
ret = kstrtouint(name + 3, 10, &index);
|
|
|
|
if (ret)
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
|
|
opts = to_f_midi2_opts(&group->cg_item);
|
|
|
|
if (index >= MAX_UMP_EPS)
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
if (opts->eps[index])
|
|
|
|
return ERR_PTR(-EBUSY);
|
|
|
|
ret = f_midi2_ep_opts_create(opts, index, &ep_opts);
|
|
|
|
if (ret)
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
|
|
config_group_init_type_name(&ep_opts->group, name, &f_midi2_ep_type);
|
|
|
|
return &ep_opts->group;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* drop_item callback for an EP */
|
|
|
|
static void
|
|
|
|
f_midi2_opts_ep_drop(struct config_group *group, struct config_item *item)
|
|
|
|
{
|
|
|
|
struct f_midi2_ep_opts *ep_opts = to_f_midi2_ep_opts(item);
|
|
|
|
|
|
|
|
mutex_lock(&ep_opts->opts->lock);
|
|
|
|
ep_opts->opts->eps[ep_opts->index] = NULL;
|
|
|
|
mutex_unlock(&ep_opts->opts->lock);
|
|
|
|
config_item_put(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Definitions for card config
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* define a bool option for card */
|
|
|
|
#define F_MIDI2_BOOL_OPT(name) \
|
|
|
|
static ssize_t f_midi2_opts_##name##_show(struct config_item *item, \
|
|
|
|
char *page) \
|
|
|
|
{ \
|
|
|
|
struct f_midi2_opts *opts = to_f_midi2_opts(item); \
|
|
|
|
return f_midi2_opts_uint_show(opts, opts->info.name, \
|
|
|
|
"%u\n", page); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
static ssize_t f_midi2_opts_##name##_store(struct config_item *item, \
|
|
|
|
const char *page, size_t len) \
|
|
|
|
{ \
|
|
|
|
struct f_midi2_opts *opts = to_f_midi2_opts(item); \
|
|
|
|
return f_midi2_opts_bool_store(opts, &opts->info.name, \
|
|
|
|
page, len); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
CONFIGFS_ATTR(f_midi2_opts_, name)
|
|
|
|
|
|
|
|
F_MIDI2_BOOL_OPT(process_ump);
|
|
|
|
F_MIDI2_BOOL_OPT(static_block);
|
|
|
|
|
|
|
|
static ssize_t f_midi2_opts_iface_name_show(struct config_item *item,
|
|
|
|
char *page)
|
|
|
|
{
|
|
|
|
struct f_midi2_opts *opts = to_f_midi2_opts(item);
|
|
|
|
|
|
|
|
return f_midi2_opts_str_show(opts, opts->info.iface_name, page);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t f_midi2_opts_iface_name_store(struct config_item *item,
|
|
|
|
const char *page, size_t len)
|
|
|
|
{
|
|
|
|
struct f_midi2_opts *opts = to_f_midi2_opts(item);
|
|
|
|
|
|
|
|
return f_midi2_opts_str_store(opts, &opts->info.iface_name, 128,
|
|
|
|
page, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
CONFIGFS_ATTR(f_midi2_opts_, iface_name);
|
|
|
|
|
|
|
|
static struct configfs_attribute *f_midi2_attrs[] = {
|
|
|
|
&f_midi2_opts_attr_process_ump,
|
|
|
|
&f_midi2_opts_attr_static_block,
|
|
|
|
&f_midi2_opts_attr_iface_name,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static void f_midi2_opts_release(struct config_item *item)
|
|
|
|
{
|
|
|
|
struct f_midi2_opts *opts = to_f_midi2_opts(item);
|
|
|
|
|
|
|
|
usb_put_function_instance(&opts->func_inst);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct configfs_item_operations f_midi2_item_ops = {
|
|
|
|
.release = f_midi2_opts_release,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct configfs_group_operations f_midi2_group_ops = {
|
|
|
|
.make_group = f_midi2_opts_ep_make,
|
|
|
|
.drop_item = f_midi2_opts_ep_drop,
|
|
|
|
};
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
static const struct config_item_type f_midi2_func_type = {
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
.ct_item_ops = &f_midi2_item_ops,
|
|
|
|
.ct_group_ops = &f_midi2_group_ops,
|
|
|
|
.ct_attrs = f_midi2_attrs,
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
.ct_owner = THIS_MODULE,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void f_midi2_free_inst(struct usb_function_instance *f)
|
|
|
|
{
|
|
|
|
struct f_midi2_opts *opts;
|
|
|
|
|
|
|
|
opts = container_of(f, struct f_midi2_opts, func_inst);
|
|
|
|
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
kfree(opts->info.iface_name);
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
kfree(opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* gadget alloc_inst */
|
|
|
|
static struct usb_function_instance *f_midi2_alloc_inst(void)
|
|
|
|
{
|
|
|
|
struct f_midi2_opts *opts;
|
|
|
|
struct f_midi2_ep_opts *ep_opts;
|
|
|
|
struct f_midi2_block_opts *block_opts;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
|
|
|
|
if (!opts)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
mutex_init(&opts->lock);
|
|
|
|
opts->func_inst.free_func_inst = f_midi2_free_inst;
|
|
|
|
opts->info.process_ump = true;
|
|
|
|
opts->info.static_block = true;
|
|
|
|
opts->info.num_reqs = 32;
|
|
|
|
opts->info.req_buf_size = 512;
|
|
|
|
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
/* create the default ep */
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
|
|
|
|
if (ret) {
|
|
|
|
kfree(opts);
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create the default block */
|
|
|
|
ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
|
|
|
|
if (ret) {
|
|
|
|
kfree(ep_opts);
|
|
|
|
kfree(opts);
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
}
|
|
|
|
|
2023-07-25 08:22:06 +02:00
|
|
|
/* set up the default MIDI1 (that is mandatory) */
|
|
|
|
block_opts->info.midi1_num_groups = 1;
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
config_group_init_type_name(&opts->func_inst.group, "",
|
|
|
|
&f_midi2_func_type);
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
|
|
|
|
config_group_init_type_name(&ep_opts->group, "ep.0",
|
|
|
|
&f_midi2_ep_type);
|
|
|
|
configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
|
|
|
|
|
|
|
|
config_group_init_type_name(&block_opts->group, "block.0",
|
|
|
|
&f_midi2_block_type);
|
|
|
|
configfs_add_default_group(&block_opts->group, &ep_opts->group);
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
return &opts->func_inst;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void do_f_midi2_free(struct f_midi2 *midi2, struct f_midi2_opts *opts)
|
|
|
|
{
|
|
|
|
mutex_lock(&opts->lock);
|
|
|
|
--opts->refcnt;
|
|
|
|
mutex_unlock(&opts->lock);
|
|
|
|
kfree(midi2->string_defs);
|
|
|
|
kfree(midi2);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void f_midi2_free(struct usb_function *f)
|
|
|
|
{
|
|
|
|
do_f_midi2_free(func_to_midi2(f),
|
|
|
|
container_of(f->fi, struct f_midi2_opts, func_inst));
|
|
|
|
}
|
|
|
|
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
/* verify the parameters set up via configfs;
|
|
|
|
* return the number of EPs or a negative error
|
|
|
|
*/
|
|
|
|
static int verify_parameters(struct f_midi2_opts *opts)
|
|
|
|
{
|
|
|
|
int i, j, num_eps, num_blks;
|
|
|
|
struct f_midi2_ep_info *ep;
|
|
|
|
struct f_midi2_block_info *bp;
|
|
|
|
|
|
|
|
for (num_eps = 0; num_eps < MAX_UMP_EPS && opts->eps[num_eps];
|
|
|
|
num_eps++)
|
|
|
|
;
|
|
|
|
if (!num_eps) {
|
|
|
|
pr_err("f_midi2: No EP is defined\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
num_blks = 0;
|
|
|
|
for (i = 0; i < num_eps; i++) {
|
|
|
|
ep = &opts->eps[i]->info;
|
|
|
|
if (!(ep->protocol_caps & ep->protocol)) {
|
|
|
|
pr_err("f_midi2: Invalid protocol 0x%x (caps 0x%x) for EP %d\n",
|
|
|
|
ep->protocol, ep->protocol_caps, i);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j = 0; j < SNDRV_UMP_MAX_BLOCKS && opts->eps[i]->blks[j];
|
|
|
|
j++, num_blks++) {
|
|
|
|
bp = &opts->eps[i]->blks[j]->info;
|
|
|
|
if (bp->first_group + bp->num_groups > SNDRV_UMP_MAX_GROUPS) {
|
|
|
|
pr_err("f_midi2: Invalid group definitions for block %d:%d\n",
|
|
|
|
i, j);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2023-07-25 08:22:06 +02:00
|
|
|
|
|
|
|
if (bp->midi1_num_groups) {
|
|
|
|
if (bp->midi1_first_group < bp->first_group ||
|
|
|
|
bp->midi1_first_group + bp->midi1_num_groups >
|
|
|
|
bp->first_group + bp->num_groups) {
|
|
|
|
pr_err("f_midi2: Invalid MIDI1 group definitions for block %d:%d\n",
|
|
|
|
i, j);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!num_blks) {
|
|
|
|
pr_err("f_midi2: No block is defined\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return num_eps;
|
|
|
|
}
|
|
|
|
|
2023-07-25 08:22:06 +02:00
|
|
|
/* fill mapping between MIDI 1.0 cable and UMP EP/group */
|
|
|
|
static void fill_midi1_cable_mapping(struct f_midi2 *midi2,
|
|
|
|
struct f_midi2_ep *ep,
|
|
|
|
int blk)
|
|
|
|
{
|
|
|
|
const struct f_midi2_block_info *binfo = &ep->blks[blk].info;
|
|
|
|
struct midi1_cable_mapping *map;
|
|
|
|
int i, group;
|
|
|
|
|
|
|
|
if (!binfo->midi1_num_groups)
|
|
|
|
return;
|
|
|
|
if (binfo->direction != SNDRV_UMP_DIR_OUTPUT) {
|
|
|
|
group = binfo->midi1_first_group;
|
|
|
|
map = midi2->in_cable_mapping + midi2->num_midi1_in;
|
|
|
|
for (i = 0; i < binfo->midi1_num_groups; i++, group++, map++) {
|
|
|
|
if (midi2->num_midi1_in >= MAX_CABLES)
|
|
|
|
break;
|
|
|
|
map->ep = ep;
|
|
|
|
map->block = blk;
|
|
|
|
map->group = group;
|
|
|
|
midi2->num_midi1_in++;
|
|
|
|
/* store 1-based cable number */
|
|
|
|
ep->in_group_to_cable[group] = midi2->num_midi1_in;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (binfo->direction != SNDRV_UMP_DIR_INPUT) {
|
|
|
|
group = binfo->midi1_first_group;
|
|
|
|
map = midi2->out_cable_mapping + midi2->num_midi1_out;
|
|
|
|
for (i = 0; i < binfo->midi1_num_groups; i++, group++, map++) {
|
|
|
|
if (midi2->num_midi1_out >= MAX_CABLES)
|
|
|
|
break;
|
|
|
|
map->ep = ep;
|
|
|
|
map->block = blk;
|
|
|
|
map->group = group;
|
|
|
|
midi2->num_midi1_out++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
/* gadget alloc callback */
|
|
|
|
static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi)
|
|
|
|
{
|
|
|
|
struct f_midi2 *midi2;
|
|
|
|
struct f_midi2_opts *opts;
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
struct f_midi2_ep *ep;
|
|
|
|
struct f_midi2_block *bp;
|
|
|
|
int i, num_eps, blk;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
|
|
|
midi2 = kzalloc(sizeof(*midi2), GFP_KERNEL);
|
|
|
|
if (!midi2)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
opts = container_of(fi, struct f_midi2_opts, func_inst);
|
|
|
|
mutex_lock(&opts->lock);
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
num_eps = verify_parameters(opts);
|
|
|
|
if (num_eps < 0) {
|
|
|
|
mutex_unlock(&opts->lock);
|
|
|
|
kfree(midi2);
|
|
|
|
return ERR_PTR(num_eps);
|
|
|
|
}
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
++opts->refcnt;
|
|
|
|
mutex_unlock(&opts->lock);
|
|
|
|
|
|
|
|
spin_lock_init(&midi2->queue_lock);
|
|
|
|
|
|
|
|
midi2->func.name = "midi2_func";
|
|
|
|
midi2->func.bind = f_midi2_bind;
|
|
|
|
midi2->func.unbind = f_midi2_unbind;
|
|
|
|
midi2->func.get_alt = f_midi2_get_alt;
|
|
|
|
midi2->func.set_alt = f_midi2_set_alt;
|
|
|
|
midi2->func.setup = f_midi2_setup;
|
|
|
|
midi2->func.disable = f_midi2_disable;
|
|
|
|
midi2->func.free_func = f_midi2_free;
|
|
|
|
|
|
|
|
midi2->info = opts->info;
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
midi2->num_eps = num_eps;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
for (i = 0; i < num_eps; i++) {
|
|
|
|
ep = &midi2->midi2_eps[i];
|
|
|
|
ep->info = opts->eps[i]->info;
|
|
|
|
ep->card = midi2;
|
|
|
|
for (blk = 0; blk < SNDRV_UMP_MAX_BLOCKS &&
|
|
|
|
opts->eps[i]->blks[blk]; blk++) {
|
|
|
|
bp = &ep->blks[blk];
|
|
|
|
ep->num_blks++;
|
|
|
|
bp->info = opts->eps[i]->blks[blk]->info;
|
|
|
|
bp->gtb_id = ++midi2->total_blocks;
|
|
|
|
}
|
|
|
|
}
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
|
|
|
midi2->string_defs = kcalloc(midi2->total_blocks + 1,
|
|
|
|
sizeof(*midi2->string_defs), GFP_KERNEL);
|
|
|
|
if (!midi2->string_defs) {
|
|
|
|
do_f_midi2_free(midi2, opts);
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (opts->info.iface_name && *opts->info.iface_name)
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
midi2->string_defs[STR_IFACE].s = opts->info.iface_name;
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
else
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
midi2->string_defs[STR_IFACE].s = ump_ep_name(&midi2->midi2_eps[0]);
|
|
|
|
|
|
|
|
for (i = 0; i < midi2->num_eps; i++) {
|
|
|
|
ep = &midi2->midi2_eps[i];
|
|
|
|
for (blk = 0; blk < ep->num_blks; blk++) {
|
|
|
|
bp = &ep->blks[blk];
|
|
|
|
midi2->string_defs[gtb_to_str_id(bp->gtb_id)].s =
|
|
|
|
ump_fb_name(&bp->info);
|
2023-07-25 08:22:06 +02:00
|
|
|
|
|
|
|
fill_midi1_cable_mapping(midi2, ep, blk);
|
usb: gadget: midi2: Add configfs support
This patch adds the support of configfs to MIDI 2.0 function driver
for users to allow configuring the UMP Endpoint and Function Blocks
more flexibly. The configuration is in a tree form. The top-most
contains some card-level configurations. UMP Endpoints are defined in
subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
configurations such as ep_name, etc. And, UMP Function Blocks are
defined in the subdirectories (block.0, block.1, etc) under EP
subdirectory. As default, the driver creates a single UMP Endpoint
(ep.0) and a single Function Block (block.0) to work in a minimalistic
manner. User can modify those attributes freely to fit with the
demands.
When multiple Function Blocks are required, user can create another
directory as block.1, block.2, and so on (up to block.31). A block.*
directory can be deleted dynamically, too. A caveat is that the block
number has to be continuous.
Similarly, when multiple UMP Endpoints are required, user can create
another directory as ep.1, ep.2, up to ep.3.
Also, some driver behavior can be controlled in the card top-level
configs. e.g. you can pass process_ump=0 to disable the processing of
UMP Stream messages. This would be equivalent with the older MIDI 2.0
spec that doesn't support UMP v1.1 features.
The configfs interface checks upper- / lower-bound of input values,
and more sanity checks are performed at binding.
Attributes can't be changed any longer once when the instance is
linked to UDC.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:01 +02:00
|
|
|
}
|
|
|
|
}
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
|
2023-07-25 08:22:06 +02:00
|
|
|
if (!midi2->num_midi1_in && !midi2->num_midi1_out) {
|
|
|
|
pr_err("f_midi2: MIDI1 definition is missing\n");
|
|
|
|
do_f_midi2_free(midi2, opts);
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
}
|
|
|
|
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
return &midi2->func;
|
|
|
|
}
|
|
|
|
|
|
|
|
DECLARE_USB_FUNCTION_INIT(midi2, f_midi2_alloc_inst, f_midi2_alloc);
|
|
|
|
|
2024-06-05 20:57:08 -07:00
|
|
|
MODULE_DESCRIPTION("USB MIDI 2.0 class function driver");
|
usb: gadget: Add support for USB MIDI 2.0 function driver
This patch adds the support for USB MIDI 2.0 gadget function driver.
The driver emulates a USB MIDI 2.0 interface with one or more UMP
Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
handling MIDI 2.0 UMP packets. When the function driver is bound, the
driver creates an ALSA card object with UMP rawmidi devices. This is
a kind of loop-back where the incoming and upcoming UMP packets
from/to the MIDI 2.0 UMP Endpoints are transferred as-is. In
addition, legacy (MIDI 1.0) rawmidi devices are created, so that
legacy applications can work in the gadget side, too.
When a USB MIDI 2.0 gadget interface appears, the connected host can
use it with the snd-usb-audio driver where MIDI 2.0 support is
enabled. Both gadget and connected hosts will have the similar UMP
Endpoint and Function Block (or Group Terminal Block) information.
Slight differences are the direction and UI-hint bits; it's due to the
nature of gadget driver, and the input/output direction is swapped in
both sides (the input for gadget is the output for host, and vice
versa).
The driver supports the brand-new UMP v1.1 feature, including the UMP
Stream message handling for providing UMP Endpoint and Function Block
information as well as dealing with the MIDI protocol switch. The
driver responds to UMP Stream messages by itself. OTOH, MIDI-CI
message handling isn't implemented in the kernel driver; it should be
processed in the user-space through the loopback UMP device.
As of this patch, the whole configuration is fixed, providing only one
bidirectional UMP Endpoint containing a single FB/GTB with a single
UMP Group. The configuration will be dynamically changeable in the
following patches.
The traditional MIDI 1.0 is still provided in the altset 0 (which is
mandatory per spec). But it's only about the configuration, and no
actual I/O will be running for the altset 0 as of this patch. The
proper support MIDI 1.0 altset will follow in later patches, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-07-25 08:22:00 +02:00
|
|
|
MODULE_LICENSE("GPL");
|