ALSA: seq: ump: Notify UMP protocol change to sequencer
authorTakashi Iwai <tiwai@suse.de>
Mon, 12 Jun 2023 08:10:52 +0000 (10:10 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 12 Jun 2023 16:22:33 +0000 (18:22 +0200)
UMP v1.1 supports the protocol switch via a UMP Stream message.  When
it's received, we need to take care of the midi_version field in the
corresponding sequencer client, too.

This patch introduces a new ops to notify the protocol change to
snd_seq_ump_ops for handling it.

Link: https://lore.kernel.org/r/20230612081054.17200-9-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/ump.h
sound/core/seq/seq_ump_client.c
sound/core/ump.c

index 0e9c048..68478e7 100644 (file)
@@ -72,6 +72,7 @@ struct snd_seq_ump_ops {
                              const u32 *data, int words);
        int (*notify_fb_change)(struct snd_ump_endpoint *ump,
                                struct snd_ump_block *fb);
+       int (*switch_protocol)(struct snd_ump_endpoint *ump);
 };
 
 struct snd_ump_block {
index 901a670..fe21c80 100644 (file)
@@ -439,9 +439,19 @@ static int seq_ump_notify_fb_change(struct snd_ump_endpoint *ump,
        return 0;
 }
 
+/* UMP protocol change notification; just update the midi_version field */
+static int seq_ump_switch_protocol(struct snd_ump_endpoint *ump)
+{
+       if (!ump->seq_client)
+               return -ENODEV;
+       setup_client_midi_version(ump->seq_client);
+       return 0;
+}
+
 static const struct snd_seq_ump_ops seq_ump_ops = {
        .input_receive = seq_ump_input_receive,
        .notify_fb_change = seq_ump_notify_fb_change,
+       .switch_protocol = seq_ump_switch_protocol,
 };
 
 /* create a sequencer client and ports for the given UMP endpoint */
index c0cda12..f364bb2 100644 (file)
@@ -657,14 +657,27 @@ static int ump_handle_product_id_msg(struct snd_ump_endpoint *ump,
                                 buf->raw, 2);
 }
 
+/* notify the protocol change to sequencer */
+static void seq_notify_protocol(struct snd_ump_endpoint *ump)
+{
+#if IS_ENABLED(CONFIG_SND_SEQUENCER)
+       if (ump->seq_ops && ump->seq_ops->switch_protocol)
+               ump->seq_ops->switch_protocol(ump);
+#endif /* CONFIG_SND_SEQUENCER */
+}
+
 /* handle EP stream config message; update the UMP protocol */
 static int ump_handle_stream_cfg_msg(struct snd_ump_endpoint *ump,
                                     const union snd_ump_stream_msg *buf)
 {
+       unsigned int old_protocol = ump->info.protocol;
+
        ump->info.protocol =
                (buf->stream_cfg.protocol << 8) | buf->stream_cfg.jrts;
        ump_dbg(ump, "Current protocol = %x (caps = %x)\n",
                ump->info.protocol, ump->info.protocol_caps);
+       if (ump->parsed && ump->info.protocol != old_protocol)
+               seq_notify_protocol(ump);
        return 1; /* finished */
 }