summaryrefslogtreecommitdiff
path: root/sound/core/ump.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2023-05-23 09:53:53 +0200
committerTakashi Iwai <tiwai@suse.de>2023-05-23 12:11:33 +0200
commit81fd444aa371261cd33f31d4ffd80faeeeab0cc9 (patch)
tree6a2a4eabc82533e6e1e93935f6ae93fb031fce27 /sound/core/ump.c
parent329ffe11a014834fdef9167c7ea24bd459829f86 (diff)
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>
Diffstat (limited to 'sound/core/ump.c')
-rw-r--r--sound/core/ump.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/sound/core/ump.c b/sound/core/ump.c
index cbe704b5d90d..69993cad6772 100644
--- a/sound/core/ump.c
+++ b/sound/core/ump.c
@@ -132,8 +132,8 @@ int snd_ump_endpoint_new(struct snd_card *card, char *id, int device,
if (!ump)
return -ENOMEM;
INIT_LIST_HEAD(&ump->block_list);
-#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
mutex_init(&ump->open_mutex);
+#if IS_ENABLED(CONFIG_SND_UMP_LEGACY_RAWMIDI)
spin_lock_init(&ump->legacy_locks[0]);
spin_lock_init(&ump->legacy_locks[1]);
#endif
@@ -166,8 +166,30 @@ EXPORT_SYMBOL_GPL(snd_ump_endpoint_new);
* Device register / unregister hooks;
* do nothing, placeholders for avoiding the default rawmidi handling
*/
+
+#if IS_ENABLED(CONFIG_SND_SEQUENCER)
+static void snd_ump_dev_seq_free(struct snd_seq_device *device)
+{
+ struct snd_ump_endpoint *ump = device->private_data;
+
+ ump->seq_dev = NULL;
+}
+#endif
+
static int snd_ump_dev_register(struct snd_rawmidi *rmidi)
{
+#if IS_ENABLED(CONFIG_SND_SEQUENCER)
+ struct snd_ump_endpoint *ump = rawmidi_to_ump(rmidi);
+ int err;
+
+ err = snd_seq_device_new(ump->core.card, ump->core.device,
+ SNDRV_SEQ_DEV_ID_UMP, 0, &ump->seq_dev);
+ if (err < 0)
+ return err;
+ ump->seq_dev->private_data = ump;
+ ump->seq_dev->private_free = snd_ump_dev_seq_free;
+ snd_device_register(ump->core.card, ump->seq_dev);
+#endif
return 0;
}
@@ -280,6 +302,10 @@ int snd_ump_receive(struct snd_ump_endpoint *ump, const u32 *buffer, int count)
n = snd_ump_receive_ump_val(ump, *p++);
if (!n)
continue;
+#if IS_ENABLED(CONFIG_SND_SEQUENCER)
+ if (ump->seq_ops)
+ ump->seq_ops->input_receive(ump, ump->input_buf, n);
+#endif
process_legacy_input(ump, ump->input_buf, n);
}