Commit 3ab4a319 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: seq: Notify UMP EP and FB changes



So far we notify the sequencer client and port changes upon UMP FB
changes, but those aren't really corresponding to the UMP updates.
e.g. when a FB info gets updated, it's not notified but done only when
some of sequencer port attribute is changed.  This is no ideal
behavior.

This patch adds the two new sequencer event types for notifying the
UMP EP and FB changes via the announce port.  The new event takes
snd_seq_ev_ump_notify type data, which is compatible with
snd_seq_addr (where the port number is replaced with the block
number).

The events are sent when the EP and FB info gets updated explicitly
via ioctl, or the backend UMP receives the corresponding UMP
messages.

The sequencer protocol version is bumped to 1.0.5 along with it.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20250110155943.31578-9-tiwai@suse.de
parent 10a29de1
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -388,6 +388,13 @@ Sequencer API Extensions
  announcement to the ALSA sequencer system port, similarly like the
  normal port change notification.

* There are two extended event types for notifying the UMP Endpoint and
  Function Block changes via the system announcement port:
  type 68 (`SNDRV_SEQ_EVENT_UMP_EP_CHANGE`) and type 69
  (`SNDRV_SEQ_EVENT_UMP_BLOCK_CHANGE`). They take the new type,
  `snd_seq_ev_ump_notify` in the payload, indicating the client number
  and the FB number that are changed.


MIDI2 USB Gadget Function Driver
================================
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ struct snd_ump_ops {
struct snd_seq_ump_ops {
	void (*input_receive)(struct snd_ump_endpoint *ump,
			      const u32 *data, int words);
	int (*notify_ep_change)(struct snd_ump_endpoint *ump);
	int (*notify_fb_change)(struct snd_ump_endpoint *ump,
				struct snd_ump_block *fb);
	int (*switch_protocol)(struct snd_ump_endpoint *ump);
+11 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
#include <sound/asound.h>

/** version of the sequencer */
#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 4)
#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 5)

/**
 * definition of sequencer event types
@@ -92,6 +92,9 @@
#define SNDRV_SEQ_EVENT_PORT_SUBSCRIBED	66	/* ports connected */
#define SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED 67	/* ports disconnected */

#define SNDRV_SEQ_EVENT_UMP_EP_CHANGE	68	/* UMP EP info has changed */
#define SNDRV_SEQ_EVENT_UMP_BLOCK_CHANGE 69	/* UMP block info has changed */

/* 70-89:  synthesizer events - obsoleted */

/** user-defined events with fixed length
@@ -253,6 +256,12 @@ struct snd_seq_ev_quote {
	struct snd_seq_event *event;		/* quoted event */
} __packed;

	/* UMP info change notify */
struct snd_seq_ev_ump_notify {
	unsigned char client;	/**< Client number */
	unsigned char block;	/**< Block number (optional) */
};

union snd_seq_event_data { /* event data... */
	struct snd_seq_ev_note note;
	struct snd_seq_ev_ctrl control;
@@ -265,6 +274,7 @@ union snd_seq_event_data { /* event data... */
	struct snd_seq_connect connect;
	struct snd_seq_result result;
	struct snd_seq_ev_quote quote;
	struct snd_seq_ev_ump_notify ump_notify;
};

	/* sequencer event */
+10 −0
Original line number Diff line number Diff line
@@ -2230,6 +2230,16 @@ static int snd_seq_ioctl_client_ump_info(struct snd_seq_client *caller,
 error:
	mutex_unlock(&cptr->ioctl_mutex);
	snd_seq_client_unlock(cptr);
	if (!err && cmd == SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO) {
		if (type == SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT)
			snd_seq_system_ump_notify(client, 0,
						  SNDRV_SEQ_EVENT_UMP_EP_CHANGE,
						  false);
		else
			snd_seq_system_ump_notify(client, type - 1,
						  SNDRV_SEQ_EVENT_UMP_BLOCK_CHANGE,
						  false);
	}
	return err;
}
#endif
+10 −0
Original line number Diff line number Diff line
@@ -16,6 +16,16 @@ void snd_seq_system_broadcast(int client, int port, int type, bool atomic);
#define notify_event(client, port, type) \
	snd_seq_system_broadcast(client, port, type, false)

/* notify UMP EP/FB change event */
static inline void snd_seq_system_ump_notify(int client, int block, int type,
					     bool atomic)
{
	/* reuse the existing snd_seq_system_broadcast():
	 * struct snd_seq_ev_ump_notify is compatible with struct snd_seq_addr
	 */
	snd_seq_system_broadcast(client, block, type, atomic);
}

#define snd_seq_system_client_ev_client_start(client) notify_event(client, 0, SNDRV_SEQ_EVENT_CLIENT_START)
#define snd_seq_system_client_ev_client_exit(client) notify_event(client, 0, SNDRV_SEQ_EVENT_CLIENT_EXIT)
#define snd_seq_system_client_ev_client_change(client) notify_event(client, 0, SNDRV_SEQ_EVENT_CLIENT_CHANGE)
Loading