ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/*
|
|
|
|
* Universal MIDI Packet (UMP) Support
|
|
|
|
*/
|
|
|
|
#ifndef __SOUND_UMP_H
|
|
|
|
#define __SOUND_UMP_H
|
|
|
|
|
|
|
|
#include <sound/rawmidi.h>
|
|
|
|
|
|
|
|
struct snd_ump_endpoint;
|
|
|
|
struct snd_ump_block;
|
2023-05-23 07:53:34 +00:00
|
|
|
struct snd_ump_ops;
|
2023-05-23 07:53:35 +00:00
|
|
|
struct ump_cvt_to_ump;
|
ALSA: seq: Bind UMP device
This patch introduces a new ALSA sequencer client for the kernel UMP
object, snd-seq-ump-client. It's a UMP version of snd-seq-midi
driver, while this driver creates a sequencer client per UMP endpoint
which contains (fixed) 16 ports.
The UMP rawmidi device is opened in APPEND mode for output, so that
multiple sequencer clients can share the same UMP endpoint, as well as
the legacy UMP rawmidi devices that are opened in APPEND mode, too.
For input, on the other hand, the incoming data is processed on the
fly in the dedicated hook, hence it doesn't open a rawmidi device.
The UMP packet group is updated upon delivery depending on the target
sequencer port (which corresponds to the actual UMP group).
Each sequencer port sets a new port type bit,
SNDRV_SEQ_PORT_TYPE_MIDI_UMP, in addition to the other standard
types for MIDI.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-33-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:53 +00:00
|
|
|
struct snd_seq_ump_ops;
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
|
|
|
|
struct snd_ump_endpoint {
|
|
|
|
struct snd_rawmidi core; /* raw UMP access */
|
|
|
|
|
|
|
|
struct snd_ump_endpoint_info info;
|
|
|
|
|
2023-05-23 07:53:34 +00:00
|
|
|
const struct snd_ump_ops *ops; /* UMP ops set by the driver */
|
|
|
|
struct snd_rawmidi_substream *substreams[2]; /* opened substreams */
|
|
|
|
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
void *private_data;
|
|
|
|
void (*private_free)(struct snd_ump_endpoint *ump);
|
|
|
|
|
2023-06-12 08:10:46 +00:00
|
|
|
/* UMP Stream message processing */
|
|
|
|
u32 stream_wait_for; /* expected stream message status */
|
|
|
|
bool stream_finished; /* set when message has been processed */
|
|
|
|
bool parsed; /* UMP / FB parse finished? */
|
|
|
|
wait_queue_head_t stream_wait;
|
|
|
|
struct snd_rawmidi_file stream_rfile;
|
|
|
|
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
struct list_head block_list; /* list of snd_ump_block objects */
|
2023-05-23 07:53:35 +00:00
|
|
|
|
|
|
|
/* intermediate buffer for UMP input */
|
|
|
|
u32 input_buf[4];
|
|
|
|
int input_buf_head;
|
|
|
|
int input_pending;
|
|
|
|
|
|
|
|
struct mutex open_mutex;
|
|
|
|
|
ALSA: seq: Bind UMP device
This patch introduces a new ALSA sequencer client for the kernel UMP
object, snd-seq-ump-client. It's a UMP version of snd-seq-midi
driver, while this driver creates a sequencer client per UMP endpoint
which contains (fixed) 16 ports.
The UMP rawmidi device is opened in APPEND mode for output, so that
multiple sequencer clients can share the same UMP endpoint, as well as
the legacy UMP rawmidi devices that are opened in APPEND mode, too.
For input, on the other hand, the incoming data is processed on the
fly in the dedicated hook, hence it doesn't open a rawmidi device.
The UMP packet group is updated upon delivery depending on the target
sequencer port (which corresponds to the actual UMP group).
Each sequencer port sets a new port type bit,
SNDRV_SEQ_PORT_TYPE_MIDI_UMP, in addition to the other standard
types for MIDI.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-33-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:53 +00:00
|
|
|
#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
|
2023-05-23 07:53:35 +00:00
|
|
|
spinlock_t legacy_locks[2];
|
|
|
|
struct snd_rawmidi *legacy_rmidi;
|
|
|
|
struct snd_rawmidi_substream *legacy_substreams[2][SNDRV_UMP_MAX_GROUPS];
|
|
|
|
|
|
|
|
/* for legacy output; need to open the actual substream unlike input */
|
|
|
|
int legacy_out_opens;
|
|
|
|
struct snd_rawmidi_file legacy_out_rfile;
|
|
|
|
struct ump_cvt_to_ump *out_cvts;
|
|
|
|
#endif
|
ALSA: seq: Bind UMP device
This patch introduces a new ALSA sequencer client for the kernel UMP
object, snd-seq-ump-client. It's a UMP version of snd-seq-midi
driver, while this driver creates a sequencer client per UMP endpoint
which contains (fixed) 16 ports.
The UMP rawmidi device is opened in APPEND mode for output, so that
multiple sequencer clients can share the same UMP endpoint, as well as
the legacy UMP rawmidi devices that are opened in APPEND mode, too.
For input, on the other hand, the incoming data is processed on the
fly in the dedicated hook, hence it doesn't open a rawmidi device.
The UMP packet group is updated upon delivery depending on the target
sequencer port (which corresponds to the actual UMP group).
Each sequencer port sets a new port type bit,
SNDRV_SEQ_PORT_TYPE_MIDI_UMP, in addition to the other standard
types for MIDI.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-33-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:53 +00:00
|
|
|
|
|
|
|
#if IS_ENABLED(CONFIG_SND_SEQUENCER)
|
|
|
|
struct snd_seq_device *seq_dev;
|
|
|
|
const struct snd_seq_ump_ops *seq_ops;
|
|
|
|
void *seq_client;
|
|
|
|
#endif
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
};
|
|
|
|
|
2023-05-23 07:53:34 +00:00
|
|
|
/* ops filled by UMP drivers */
|
|
|
|
struct snd_ump_ops {
|
|
|
|
int (*open)(struct snd_ump_endpoint *ump, int dir);
|
|
|
|
void (*close)(struct snd_ump_endpoint *ump, int dir);
|
|
|
|
void (*trigger)(struct snd_ump_endpoint *ump, int dir, int up);
|
|
|
|
void (*drain)(struct snd_ump_endpoint *ump, int dir);
|
|
|
|
};
|
|
|
|
|
ALSA: seq: Bind UMP device
This patch introduces a new ALSA sequencer client for the kernel UMP
object, snd-seq-ump-client. It's a UMP version of snd-seq-midi
driver, while this driver creates a sequencer client per UMP endpoint
which contains (fixed) 16 ports.
The UMP rawmidi device is opened in APPEND mode for output, so that
multiple sequencer clients can share the same UMP endpoint, as well as
the legacy UMP rawmidi devices that are opened in APPEND mode, too.
For input, on the other hand, the incoming data is processed on the
fly in the dedicated hook, hence it doesn't open a rawmidi device.
The UMP packet group is updated upon delivery depending on the target
sequencer port (which corresponds to the actual UMP group).
Each sequencer port sets a new port type bit,
SNDRV_SEQ_PORT_TYPE_MIDI_UMP, in addition to the other standard
types for MIDI.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-33-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:53 +00:00
|
|
|
/* ops filled by sequencer binding */
|
|
|
|
struct snd_seq_ump_ops {
|
|
|
|
void (*input_receive)(struct snd_ump_endpoint *ump,
|
|
|
|
const u32 *data, int words);
|
2023-06-12 08:10:50 +00:00
|
|
|
int (*notify_fb_change)(struct snd_ump_endpoint *ump,
|
|
|
|
struct snd_ump_block *fb);
|
2023-06-12 08:10:52 +00:00
|
|
|
int (*switch_protocol)(struct snd_ump_endpoint *ump);
|
ALSA: seq: Bind UMP device
This patch introduces a new ALSA sequencer client for the kernel UMP
object, snd-seq-ump-client. It's a UMP version of snd-seq-midi
driver, while this driver creates a sequencer client per UMP endpoint
which contains (fixed) 16 ports.
The UMP rawmidi device is opened in APPEND mode for output, so that
multiple sequencer clients can share the same UMP endpoint, as well as
the legacy UMP rawmidi devices that are opened in APPEND mode, too.
For input, on the other hand, the incoming data is processed on the
fly in the dedicated hook, hence it doesn't open a rawmidi device.
The UMP packet group is updated upon delivery depending on the target
sequencer port (which corresponds to the actual UMP group).
Each sequencer port sets a new port type bit,
SNDRV_SEQ_PORT_TYPE_MIDI_UMP, in addition to the other standard
types for MIDI.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-33-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:53 +00:00
|
|
|
};
|
|
|
|
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
struct snd_ump_block {
|
|
|
|
struct snd_ump_block_info info;
|
|
|
|
struct snd_ump_endpoint *ump;
|
|
|
|
|
|
|
|
void *private_data;
|
|
|
|
void (*private_free)(struct snd_ump_block *blk);
|
|
|
|
|
|
|
|
struct list_head list;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define rawmidi_to_ump(rmidi) container_of(rmidi, struct snd_ump_endpoint, core)
|
|
|
|
|
|
|
|
int snd_ump_endpoint_new(struct snd_card *card, char *id, int device,
|
|
|
|
int output, int input,
|
|
|
|
struct snd_ump_endpoint **ump_ret);
|
2023-06-12 08:10:46 +00:00
|
|
|
int snd_ump_parse_endpoint(struct snd_ump_endpoint *ump);
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
int snd_ump_block_new(struct snd_ump_endpoint *ump, unsigned int blk,
|
|
|
|
unsigned int direction, unsigned int first_group,
|
|
|
|
unsigned int num_groups, struct snd_ump_block **blk_ret);
|
2023-05-23 07:53:34 +00:00
|
|
|
int snd_ump_receive(struct snd_ump_endpoint *ump, const u32 *buffer, int count);
|
|
|
|
int snd_ump_transmit(struct snd_ump_endpoint *ump, u32 *buffer, int count);
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
|
2023-05-23 07:53:35 +00:00
|
|
|
#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
|
|
|
|
int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,
|
|
|
|
char *id, int device);
|
|
|
|
#else
|
|
|
|
static inline int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,
|
|
|
|
char *id, int device)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
/*
|
|
|
|
* Some definitions for UMP
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* MIDI 2.0 Message Type */
|
|
|
|
enum {
|
|
|
|
UMP_MSG_TYPE_UTILITY = 0x00,
|
|
|
|
UMP_MSG_TYPE_SYSTEM = 0x01,
|
|
|
|
UMP_MSG_TYPE_MIDI1_CHANNEL_VOICE = 0x02,
|
|
|
|
UMP_MSG_TYPE_DATA = 0x03,
|
|
|
|
UMP_MSG_TYPE_MIDI2_CHANNEL_VOICE = 0x04,
|
|
|
|
UMP_MSG_TYPE_EXTENDED_DATA = 0x05,
|
2023-06-12 08:10:46 +00:00
|
|
|
UMP_MSG_TYPE_FLEX_DATA = 0x0d,
|
|
|
|
UMP_MSG_TYPE_STREAM = 0x0f,
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* MIDI 2.0 SysEx / Data Status; same values for both 7-bit and 8-bit SysEx */
|
|
|
|
enum {
|
|
|
|
UMP_SYSEX_STATUS_SINGLE = 0,
|
|
|
|
UMP_SYSEX_STATUS_START = 1,
|
|
|
|
UMP_SYSEX_STATUS_CONTINUE = 2,
|
|
|
|
UMP_SYSEX_STATUS_END = 3,
|
|
|
|
};
|
|
|
|
|
2023-06-12 08:10:46 +00:00
|
|
|
/* UMP Utility Type Status (type 0x0) */
|
|
|
|
enum {
|
|
|
|
UMP_UTILITY_MSG_STATUS_NOOP = 0x00,
|
|
|
|
UMP_UTILITY_MSG_STATUS_JR_CLOCK = 0x01,
|
|
|
|
UMP_UTILITY_MSG_STATUS_JR_TSTAMP = 0x02,
|
|
|
|
UMP_UTILITY_MSG_STATUS_DCTPQ = 0x03,
|
|
|
|
UMP_UTILITY_MSG_STATUS_DC = 0x04,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* UMP Stream Message Status (type 0xf) */
|
|
|
|
enum {
|
|
|
|
UMP_STREAM_MSG_STATUS_EP_DISCOVERY = 0x00,
|
|
|
|
UMP_STREAM_MSG_STATUS_EP_INFO = 0x01,
|
|
|
|
UMP_STREAM_MSG_STATUS_DEVICE_INFO = 0x02,
|
|
|
|
UMP_STREAM_MSG_STATUS_EP_NAME = 0x03,
|
|
|
|
UMP_STREAM_MSG_STATUS_PRODUCT_ID = 0x04,
|
|
|
|
UMP_STREAM_MSG_STATUS_STREAM_CFG_REQUEST = 0x05,
|
|
|
|
UMP_STREAM_MSG_STATUS_STREAM_CFG = 0x06,
|
|
|
|
UMP_STREAM_MSG_STATUS_FB_DISCOVERY = 0x10,
|
|
|
|
UMP_STREAM_MSG_STATUS_FB_INFO = 0x11,
|
|
|
|
UMP_STREAM_MSG_STATUS_FB_NAME = 0x12,
|
|
|
|
UMP_STREAM_MSG_STATUS_START_CLIP = 0x20,
|
|
|
|
UMP_STREAM_MSG_STATUS_END_CLIP = 0x21,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* UMP Endpoint Discovery filter bitmap */
|
|
|
|
enum {
|
|
|
|
UMP_STREAM_MSG_REQUEST_EP_INFO = (1U << 0),
|
|
|
|
UMP_STREAM_MSG_REQUEST_DEVICE_INFO = (1U << 1),
|
|
|
|
UMP_STREAM_MSG_REQUEST_EP_NAME = (1U << 2),
|
|
|
|
UMP_STREAM_MSG_REQUEST_PRODUCT_ID = (1U << 3),
|
|
|
|
UMP_STREAM_MSG_REQUEST_STREAM_CFG = (1U << 4),
|
|
|
|
};
|
|
|
|
|
|
|
|
/* UMP Function Block Discovery filter bitmap */
|
|
|
|
enum {
|
|
|
|
UMP_STREAM_MSG_REQUEST_FB_INFO = (1U << 0),
|
|
|
|
UMP_STREAM_MSG_REQUEST_FB_NAME = (1U << 1),
|
|
|
|
};
|
|
|
|
|
|
|
|
/* UMP Endpoint Info capability bits (used for protocol request/notify, too) */
|
|
|
|
enum {
|
|
|
|
UMP_STREAM_MSG_EP_INFO_CAP_TXJR = (1U << 0), /* Sending JRTS */
|
|
|
|
UMP_STREAM_MSG_EP_INFO_CAP_RXJR = (1U << 1), /* Receiving JRTS */
|
|
|
|
UMP_STREAM_MSG_EP_INFO_CAP_MIDI1 = (1U << 8), /* MIDI 1.0 */
|
|
|
|
UMP_STREAM_MSG_EP_INFO_CAP_MIDI2 = (1U << 9), /* MIDI 2.0 */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* UMP EP / FB name string format; same as SysEx string handling */
|
|
|
|
enum {
|
|
|
|
UMP_STREAM_MSG_FORMAT_SINGLE = 0,
|
|
|
|
UMP_STREAM_MSG_FORMAT_START = 1,
|
|
|
|
UMP_STREAM_MSG_FORMAT_CONTINUE = 2,
|
|
|
|
UMP_STREAM_MSG_FORMAT_END = 3,
|
|
|
|
};
|
|
|
|
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
/*
|
|
|
|
* Helpers for retrieving / filling bits from UMP
|
|
|
|
*/
|
|
|
|
/* get the message type (4bit) from a UMP packet (header) */
|
|
|
|
static inline unsigned char ump_message_type(u32 data)
|
|
|
|
{
|
|
|
|
return data >> 28;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the group number (0-based, 4bit) from a UMP packet (header) */
|
|
|
|
static inline unsigned char ump_message_group(u32 data)
|
|
|
|
{
|
|
|
|
return (data >> 24) & 0x0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the MIDI status code (4bit) from a UMP packet (header) */
|
|
|
|
static inline unsigned char ump_message_status_code(u32 data)
|
|
|
|
{
|
|
|
|
return (data >> 20) & 0x0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the MIDI channel number (0-based, 4bit) from a UMP packet (header) */
|
|
|
|
static inline unsigned char ump_message_channel(u32 data)
|
|
|
|
{
|
|
|
|
return (data >> 16) & 0x0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the MIDI status + channel combo byte (8bit) from a UMP packet (header) */
|
|
|
|
static inline unsigned char ump_message_status_channel(u32 data)
|
|
|
|
{
|
|
|
|
return (data >> 16) & 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* compose a UMP packet (header) from type, group and status values */
|
|
|
|
static inline u32 ump_compose(unsigned char type, unsigned char group,
|
|
|
|
unsigned char status, unsigned char channel)
|
|
|
|
{
|
|
|
|
return ((u32)type << 28) | ((u32)group << 24) | ((u32)status << 20) |
|
|
|
|
((u32)channel << 16);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get SysEx message status (for both 7 and 8bits) from a UMP packet (header) */
|
|
|
|
static inline unsigned char ump_sysex_message_status(u32 data)
|
|
|
|
{
|
|
|
|
return (data >> 20) & 0xf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get SysEx message length (for both 7 and 8bits) from a UMP packet (header) */
|
|
|
|
static inline unsigned char ump_sysex_message_length(u32 data)
|
|
|
|
{
|
|
|
|
return (data >> 16) & 0xf;
|
|
|
|
}
|
|
|
|
|
2023-06-12 08:10:46 +00:00
|
|
|
/* For Stream Messages */
|
|
|
|
static inline unsigned char ump_stream_message_format(u32 data)
|
|
|
|
{
|
|
|
|
return (data >> 26) & 0x03;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int ump_stream_message_status(u32 data)
|
|
|
|
{
|
|
|
|
return (data >> 16) & 0x3ff;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u32 ump_stream_compose(unsigned char status, unsigned short form)
|
|
|
|
{
|
|
|
|
return (UMP_MSG_TYPE_STREAM << 28) | ((u32)form << 26) |
|
|
|
|
((u32)status << 16);
|
|
|
|
}
|
|
|
|
|
2023-06-12 08:10:49 +00:00
|
|
|
#define ump_is_groupless_msg(type) \
|
|
|
|
((type) == UMP_MSG_TYPE_UTILITY || (type) == UMP_MSG_TYPE_STREAM)
|
|
|
|
|
ALSA: rawmidi: UMP support
This patch adds the support helpers for UMP (Universal MIDI Packet) in
ALSA core.
The basic design is that a rawmidi instance is assigned to each UMP
Endpoint. A UMP Endpoint provides a UMP stream, typically
bidirectional (but can be also uni-directional, too), which may hold
up to 16 UMP Groups, where each UMP (input/output) Group corresponds
to the traditional MIDI I/O Endpoint.
Additionally, the ALSA UMP abstraction provides the multiple UMP
Blocks that can be assigned to each UMP Endpoint. A UMP Block is a
metadata to hold the UMP Group clusters, and can represent the
functions assigned to each UMP Group. A typical implementation of UMP
Block is the Group Terminal Blocks of USB MIDI 2.0 specification.
For distinguishing from the legacy byte-stream MIDI device, a new
device "umpC*D*" will be created, instead of the standard (MIDI 1.0)
devices "midiC*D*". The UMP instance can be identified by the new
rawmidi info bit SNDRV_RAWMIDI_INFO_UMP, too.
A UMP rawmidi device reads/writes only in 4-bytes words alignment,
stored in CPU native endianness.
The transmit and receive functions take care of the input/out data
alignment, and may return zero or aligned size, and the params ioctl
may return -EINVAL when the given input/output buffer size isn't
aligned.
A few new UMP-specific ioctls are added for obtaining the new UMP
endpoint and block information.
As of this commit, no ALSA sequencer instance is attached to UMP
devices yet. They will be supported by later patches.
Along with those changes, the protocol version for rawmidi is bumped
to 2.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 07:53:24 +00:00
|
|
|
#endif /* __SOUND_UMP_H */
|