summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/ump.h1
-rw-r--r--include/uapi/sound/asequencer.h2
-rw-r--r--sound/core/seq/seq_ports.c2
-rw-r--r--sound/core/seq/seq_ports.h2
-rw-r--r--sound/core/seq/seq_ump_client.c4
-rw-r--r--sound/core/seq/seq_ump_convert.c11
-rw-r--r--sound/core/ump.c10
7 files changed, 25 insertions, 7 deletions
diff --git a/include/sound/ump.h b/include/sound/ump.h
index 7f68056acdff..7484f62fb234 100644
--- a/include/sound/ump.h
+++ b/include/sound/ump.h
@@ -18,6 +18,7 @@ struct snd_ump_group {
unsigned int dir_bits; /* directions */
bool active; /* activeness */
bool valid; /* valid group (referred by blocks) */
+ bool is_midi1; /* belongs to a MIDI1 FB */
char name[64]; /* group name */
};
diff --git a/include/uapi/sound/asequencer.h b/include/uapi/sound/asequencer.h
index 39b37edcf813..bc30c1f2a109 100644
--- a/include/uapi/sound/asequencer.h
+++ b/include/uapi/sound/asequencer.h
@@ -461,6 +461,8 @@ struct snd_seq_remove_events {
#define SNDRV_SEQ_PORT_FLG_TIMESTAMP (1<<1)
#define SNDRV_SEQ_PORT_FLG_TIME_REAL (1<<2)
+#define SNDRV_SEQ_PORT_FLG_IS_MIDI1 (1<<3) /* Keep MIDI 1.0 protocol */
+
/* port direction */
#define SNDRV_SEQ_PORT_DIR_UNKNOWN 0
#define SNDRV_SEQ_PORT_DIR_INPUT 1
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index ca631ca4f2c6..535290f24eed 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -362,6 +362,8 @@ int snd_seq_set_port_info(struct snd_seq_client_port * port,
port->direction |= SNDRV_SEQ_PORT_DIR_OUTPUT;
}
+ port->is_midi1 = !!(info->flags & SNDRV_SEQ_PORT_FLG_IS_MIDI1);
+
return 0;
}
diff --git a/sound/core/seq/seq_ports.h b/sound/core/seq/seq_ports.h
index b111382f697a..20a26bffecb7 100644
--- a/sound/core/seq/seq_ports.h
+++ b/sound/core/seq/seq_ports.h
@@ -87,6 +87,8 @@ struct snd_seq_client_port {
unsigned char direction;
unsigned char ump_group;
+ bool is_midi1; /* keep MIDI 1.0 protocol */
+
#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
struct snd_seq_ump_midi2_bank midi2_bank[16]; /* per channel */
#endif
diff --git a/sound/core/seq/seq_ump_client.c b/sound/core/seq/seq_ump_client.c
index 637154bd1a3f..e5d3f4d206bf 100644
--- a/sound/core/seq/seq_ump_client.c
+++ b/sound/core/seq/seq_ump_client.c
@@ -189,6 +189,8 @@ static void fill_port_info(struct snd_seq_port_info *port,
port->ump_group = group->group + 1;
if (!group->active)
port->capability |= SNDRV_SEQ_PORT_CAP_INACTIVE;
+ if (group->is_midi1)
+ port->flags |= SNDRV_SEQ_PORT_FLG_IS_MIDI1;
port->type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
SNDRV_SEQ_PORT_TYPE_MIDI_UMP |
SNDRV_SEQ_PORT_TYPE_HARDWARE |
@@ -223,7 +225,7 @@ static int seq_ump_group_init(struct seq_ump_client *client, int group_index)
return -ENOMEM;
fill_port_info(port, client, group);
- port->flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
+ port->flags |= SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
memset(&pcallbacks, 0, sizeof(pcallbacks));
pcallbacks.owner = THIS_MODULE;
pcallbacks.private_data = client;
diff --git a/sound/core/seq/seq_ump_convert.c b/sound/core/seq/seq_ump_convert.c
index d9dacfbe4a9a..90656980ae26 100644
--- a/sound/core/seq/seq_ump_convert.c
+++ b/sound/core/seq/seq_ump_convert.c
@@ -595,12 +595,13 @@ int snd_seq_deliver_from_ump(struct snd_seq_client *source,
type = ump_message_type(ump_ev->ump[0]);
if (snd_seq_client_is_ump(dest)) {
- if (snd_seq_client_is_midi2(dest) &&
- type == UMP_MSG_TYPE_MIDI1_CHANNEL_VOICE)
+ bool is_midi2 = snd_seq_client_is_midi2(dest) &&
+ !dest_port->is_midi1;
+
+ if (is_midi2 && type == UMP_MSG_TYPE_MIDI1_CHANNEL_VOICE)
return cvt_ump_midi1_to_midi2(dest, dest_port,
event, atomic, hop);
- else if (!snd_seq_client_is_midi2(dest) &&
- type == UMP_MSG_TYPE_MIDI2_CHANNEL_VOICE)
+ else if (!is_midi2 && type == UMP_MSG_TYPE_MIDI2_CHANNEL_VOICE)
return cvt_ump_midi2_to_midi1(dest, dest_port,
event, atomic, hop);
/* non-EP port and different group is set? */
@@ -1254,7 +1255,7 @@ int snd_seq_deliver_to_ump(struct snd_seq_client *source,
return 0; /* group filtered - skip the event */
if (event->type == SNDRV_SEQ_EVENT_SYSEX)
return cvt_sysex_to_ump(dest, dest_port, event, atomic, hop);
- else if (snd_seq_client_is_midi2(dest))
+ else if (snd_seq_client_is_midi2(dest) && !dest_port->is_midi1)
return cvt_to_ump_midi2(dest, dest_port, event, atomic, hop);
else
return cvt_to_ump_midi1(dest, dest_port, event, atomic, hop);
diff --git a/sound/core/ump.c b/sound/core/ump.c
index e39e9cda4912..c7c3581bbbbc 100644
--- a/sound/core/ump.c
+++ b/sound/core/ump.c
@@ -538,6 +538,7 @@ static void update_group_attrs(struct snd_ump_endpoint *ump)
group->active = 0;
group->group = i;
group->valid = false;
+ group->is_midi1 = false;
}
list_for_each_entry(fb, &ump->block_list, list) {
@@ -548,6 +549,8 @@ static void update_group_attrs(struct snd_ump_endpoint *ump)
group->valid = true;
if (fb->info.active)
group->active = 1;
+ if (fb->info.flags & SNDRV_UMP_BLOCK_IS_MIDI1)
+ group->is_midi1 = true;
switch (fb->info.direction) {
case SNDRV_UMP_DIR_INPUT:
group->dir_bits |= (1 << SNDRV_RAWMIDI_STREAM_INPUT);
@@ -1156,6 +1159,7 @@ static int process_legacy_output(struct snd_ump_endpoint *ump,
struct snd_rawmidi_substream *substream;
struct ump_cvt_to_ump *ctx;
const int dir = SNDRV_RAWMIDI_STREAM_OUTPUT;
+ unsigned int protocol;
unsigned char c;
int group, size = 0;
@@ -1168,9 +1172,13 @@ static int process_legacy_output(struct snd_ump_endpoint *ump,
if (!substream)
continue;
ctx = &ump->out_cvts[group];
+ protocol = ump->info.protocol;
+ if ((protocol & SNDRV_UMP_EP_INFO_PROTO_MIDI2) &&
+ ump->groups[group].is_midi1)
+ protocol = SNDRV_UMP_EP_INFO_PROTO_MIDI1;
while (!ctx->ump_bytes &&
snd_rawmidi_transmit(substream, &c, 1) > 0)
- snd_ump_convert_to_ump(ctx, group, ump->info.protocol, c);
+ snd_ump_convert_to_ump(ctx, group, protocol, c);
if (ctx->ump_bytes && ctx->ump_bytes <= count) {
size = ctx->ump_bytes;
memcpy(buffer, ctx->ump, size);