Commit 8b460c76 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

ALSA: firewire-motu: add specification flag for position of flag for MIDI messages

In protocols of MOTU FireWire series, when transferring MIDI messages,
transmitter set existence flag to one byte on first several quadlets. The
position differs depending on protocols and models, however two cases are
confirmed; in 5th byte and 8th byte from MSB side.

This commit adds a series of specification flag to describe them. When
the existence flag is in the 5th byte, SND_MOTU_SPEC_[R|T]X_MIDI_2ND_Q is
used. Else, another set of the flag is used. Here, '_Q' means quadlet.
Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 5bbb1ab5
...@@ -145,7 +145,7 @@ static int pcm_open(struct snd_pcm_substream *substream) ...@@ -145,7 +145,7 @@ static int pcm_open(struct snd_pcm_substream *substream)
mutex_lock(&motu->mutex); mutex_lock(&motu->mutex);
err = protocol->cache_packet_formats(motu); err = snd_motu_stream_cache_packet_formats(motu);
if (err < 0) if (err < 0)
goto err_locked; goto err_locked;
......
...@@ -217,12 +217,7 @@ static int v2_cache_packet_formats(struct snd_motu *motu) ...@@ -217,12 +217,7 @@ static int v2_cache_packet_formats(struct snd_motu *motu)
calculate_differed_part(&motu->rx_packet_formats, motu->spec->flags, calculate_differed_part(&motu->rx_packet_formats, motu->spec->flags,
data, V2_OPT_OUT_IFACE_MASK, V2_OPT_OUT_IFACE_SHIFT); data, V2_OPT_OUT_IFACE_MASK, V2_OPT_OUT_IFACE_SHIFT);
motu->tx_packet_formats.midi_flag_offset = 4;
motu->tx_packet_formats.midi_byte_offset = 6;
motu->tx_packet_formats.pcm_byte_offset = 10; motu->tx_packet_formats.pcm_byte_offset = 10;
motu->rx_packet_formats.midi_flag_offset = 4;
motu->rx_packet_formats.midi_byte_offset = 6;
motu->rx_packet_formats.pcm_byte_offset = 10; motu->rx_packet_formats.pcm_byte_offset = 10;
return 0; return 0;
......
...@@ -291,12 +291,7 @@ static int v3_cache_packet_formats(struct snd_motu *motu) ...@@ -291,12 +291,7 @@ static int v3_cache_packet_formats(struct snd_motu *motu)
V3_ENABLE_OPT_OUT_IFACE_A, V3_NO_ADAT_OPT_OUT_IFACE_A, V3_ENABLE_OPT_OUT_IFACE_A, V3_NO_ADAT_OPT_OUT_IFACE_A,
V3_ENABLE_OPT_OUT_IFACE_B, V3_NO_ADAT_OPT_OUT_IFACE_B); V3_ENABLE_OPT_OUT_IFACE_B, V3_NO_ADAT_OPT_OUT_IFACE_B);
motu->tx_packet_formats.midi_flag_offset = 8;
motu->tx_packet_formats.midi_byte_offset = 7;
motu->tx_packet_formats.pcm_byte_offset = 10; motu->tx_packet_formats.pcm_byte_offset = 10;
motu->rx_packet_formats.midi_flag_offset = 8;
motu->rx_packet_formats.midi_byte_offset = 7;
motu->rx_packet_formats.pcm_byte_offset = 10; motu->rx_packet_formats.pcm_byte_offset = 10;
return 0; return 0;
......
...@@ -33,7 +33,8 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate) ...@@ -33,7 +33,8 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate)
u32 data; u32 data;
int err; int err;
if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) ||
(motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q))
midi_ports = 1; midi_ports = 1;
/* Set packet formation to our packet streaming engine. */ /* Set packet formation to our packet streaming engine. */
...@@ -42,6 +43,12 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate) ...@@ -42,6 +43,12 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate)
if (err < 0) if (err < 0)
return err; return err;
if ((motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) ||
(motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q))
midi_ports = 1;
else
midi_ports = 0;
err = amdtp_motu_set_parameters(&motu->tx_stream, rate, midi_ports, err = amdtp_motu_set_parameters(&motu->tx_stream, rate, midi_ports,
&motu->tx_packet_formats); &motu->tx_packet_formats);
if (err < 0) if (err < 0)
...@@ -141,6 +148,33 @@ static void stop_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream) ...@@ -141,6 +148,33 @@ static void stop_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream)
fw_iso_resources_free(resources); fw_iso_resources_free(resources);
} }
int snd_motu_stream_cache_packet_formats(struct snd_motu *motu)
{
int err;
err = motu->spec->protocol->cache_packet_formats(motu);
if (err < 0)
return err;
if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) {
motu->tx_packet_formats.midi_flag_offset = 4;
motu->tx_packet_formats.midi_byte_offset = 6;
} else if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q) {
motu->tx_packet_formats.midi_flag_offset = 8;
motu->tx_packet_formats.midi_byte_offset = 7;
}
if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) {
motu->rx_packet_formats.midi_flag_offset = 4;
motu->rx_packet_formats.midi_byte_offset = 6;
} else if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) {
motu->rx_packet_formats.midi_flag_offset = 8;
motu->rx_packet_formats.midi_byte_offset = 7;
}
return 0;
}
static int ensure_packet_formats(struct snd_motu *motu) static int ensure_packet_formats(struct snd_motu *motu)
{ {
__be32 reg; __be32 reg;
...@@ -184,7 +218,7 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate) ...@@ -184,7 +218,7 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate)
stop_both_streams(motu); stop_both_streams(motu);
} }
err = protocol->cache_packet_formats(motu); err = snd_motu_stream_cache_packet_formats(motu);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -103,7 +103,10 @@ static void do_registration(struct work_struct *work) ...@@ -103,7 +103,10 @@ static void do_registration(struct work_struct *work)
if (err < 0) if (err < 0)
goto error; goto error;
if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) { if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) ||
(motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) ||
(motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) ||
(motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q)) {
err = snd_motu_create_midi_devices(motu); err = snd_motu_create_midi_devices(motu);
if (err < 0) if (err < 0)
goto error; goto error;
...@@ -197,7 +200,8 @@ static struct snd_motu_spec motu_828mk2 = { ...@@ -197,7 +200,8 @@ static struct snd_motu_spec motu_828mk2 = {
SND_MOTU_SPEC_TX_MICINST_CHUNK | SND_MOTU_SPEC_TX_MICINST_CHUNK |
SND_MOTU_SPEC_TX_RETURN_CHUNK | SND_MOTU_SPEC_TX_RETURN_CHUNK |
SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_HAS_OPT_IFACE_A |
SND_MOTU_SPEC_HAS_MIDI, SND_MOTU_SPEC_RX_MIDI_2ND_Q |
SND_MOTU_SPEC_TX_MIDI_2ND_Q,
.analog_in_ports = 8, .analog_in_ports = 8,
.analog_out_ports = 8, .analog_out_ports = 8,
...@@ -213,7 +217,8 @@ static struct snd_motu_spec motu_828mk3 = { ...@@ -213,7 +217,8 @@ static struct snd_motu_spec motu_828mk3 = {
SND_MOTU_SPEC_TX_REVERB_CHUNK | SND_MOTU_SPEC_TX_REVERB_CHUNK |
SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_HAS_OPT_IFACE_A |
SND_MOTU_SPEC_HAS_OPT_IFACE_B | SND_MOTU_SPEC_HAS_OPT_IFACE_B |
SND_MOTU_SPEC_HAS_MIDI, SND_MOTU_SPEC_RX_MIDI_3RD_Q |
SND_MOTU_SPEC_TX_MIDI_3RD_Q,
.analog_in_ports = 8, .analog_in_ports = 8,
.analog_out_ports = 8, .analog_out_ports = 8,
......
...@@ -82,7 +82,10 @@ enum snd_motu_spec_flags { ...@@ -82,7 +82,10 @@ enum snd_motu_spec_flags {
SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020, SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020,
SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040, SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040,
SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080, SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080,
SND_MOTU_SPEC_HAS_MIDI = 0x0100, SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0100,
SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0200,
SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0400,
SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0800,
}; };
#define SND_MOTU_CLOCK_RATE_COUNT 6 #define SND_MOTU_CLOCK_RATE_COUNT 6
...@@ -146,6 +149,7 @@ void snd_motu_transaction_unregister(struct snd_motu *motu); ...@@ -146,6 +149,7 @@ void snd_motu_transaction_unregister(struct snd_motu *motu);
int snd_motu_stream_init_duplex(struct snd_motu *motu); int snd_motu_stream_init_duplex(struct snd_motu *motu);
void snd_motu_stream_destroy_duplex(struct snd_motu *motu); void snd_motu_stream_destroy_duplex(struct snd_motu *motu);
int snd_motu_stream_cache_packet_formats(struct snd_motu *motu);
int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate); int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate);
void snd_motu_stream_stop_duplex(struct snd_motu *motu); void snd_motu_stream_stop_duplex(struct snd_motu *motu);
int snd_motu_stream_lock_try(struct snd_motu *motu); int snd_motu_stream_lock_try(struct snd_motu *motu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment