[alsa-devel] [PATCH 0/5] ALSA: firewire-motu: add support for MOTU Traveler
Hi,
This patchset adds support for MOTU Traveler launched in 2005. Any transmission of PCM frames/MIDI messages is available via ALSA PCM and RawMIDI/Sequencer interfaces to handle MOTU specific protocol version 2.
Like ALSA Dice driver, this driver can't enable target device to generate sound properly at some sampling transmission frequency yet, due to timestamping issue. However, at sampling transmission frequencies for major sampling rate such as 44.1/48.0 kHz, it works well, as long as I tested. This situation might be improved future.
Takashi Sakamoto (5): ALSA: firewire-motu: suppless consumption for unused element of array in stack ALSA: firewire-motu: add a flag for chunks for main 1/2 out ALSA: firewire-motu: add a flag for AES/EBU on XLR interface ALSA: firewire-motu: cancel chunk alignment for protocol version 2 ALSA: firewire-motu: add support for Motu Traveler
sound/firewire/motu/motu-protocol-v2.c | 64 ++++++++++++++++++++++++++-------- sound/firewire/motu/motu-protocol-v3.c | 19 +++++++--- sound/firewire/motu/motu.c | 19 ++++++++++ sound/firewire/motu/motu.h | 5 ++- 4 files changed, 87 insertions(+), 20 deletions(-)
In MOTU firewire protocol, data block consists of 24 bit data chunks except for one quadlet for source packet header (SPH). The number of data chunk in a data block is different between three clock modes; low, middle and high. When unit supports ADAT on optical interface, the data block includes some chunks for ADAT channels. These ADAT chunks are unavailable at high mode.
This driver has local functions to calculate the number of ADAT chunks. But They uses stack for three clock modes. This is useless for higher mode.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 525b746330be..a51fd196d884 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -176,7 +176,7 @@ static void calculate_differed_part(struct snd_motu_packet_format *formats, enum snd_motu_spec_flags flags, u32 data, u32 mask, u32 shift) { - unsigned char pcm_chunks[3] = {0, 0}; + unsigned char pcm_chunks[2] = {0, 0};
/* * When optical interfaces are configured for S/PDIF (TOSLINK),
This driver explicitly assumes that all of supported models have main data chunk separated from chunk for analog ports. However, MOTU Traveler doesn't support the separated main data chunk.
This commit adds a flag for the separated main data chunk.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 14 +++++++++----- sound/firewire/motu/motu-protocol-v3.c | 14 +++++++++----- sound/firewire/motu/motu.c | 3 +++ sound/firewire/motu/motu.h | 1 + 4 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index a51fd196d884..614f9b11e010 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -149,11 +149,15 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[1] += 2; } } else { - /* - * Packets to v2 units transfer main-out-1/2 and phone-out-1/2. - */ - pcm_chunks[0] += 4; - pcm_chunks[1] += 4; + if (flags & SND_MOTU_SPEC_RX_SEPARETED_MAIN) { + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; + } + + // Packets to v2 units include 2 chunks for phone 1/2, except + // for 176.4/192.0 kHz. + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; }
/* diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c index c7cd9864dc4d..293353991591 100644 --- a/sound/firewire/motu/motu-protocol-v3.c +++ b/sound/firewire/motu/motu-protocol-v3.c @@ -188,11 +188,15 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[1] += 2; } } else { - /* - * Packets to v2 units transfer main-out-1/2 and phone-out-1/2. - */ - pcm_chunks[0] += 4; - pcm_chunks[1] += 4; + if (flags & SND_MOTU_SPEC_RX_SEPARETED_MAIN) { + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; + } + + // Packets to v3 units include 2 chunks for phone 1/2, except + // for 176.4/192.0 kHz. + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; }
/* diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c index 0d6b526105ab..445aa589582d 100644 --- a/sound/firewire/motu/motu.c +++ b/sound/firewire/motu/motu.c @@ -200,6 +200,7 @@ static const struct snd_motu_spec motu_828mk2 = { .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | SND_MOTU_SPEC_TX_MICINST_CHUNK | SND_MOTU_SPEC_TX_RETURN_CHUNK | + SND_MOTU_SPEC_RX_SEPARETED_MAIN | SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_RX_MIDI_2ND_Q | SND_MOTU_SPEC_TX_MIDI_2ND_Q, @@ -216,6 +217,7 @@ static const struct snd_motu_spec motu_828mk3 = { SND_MOTU_SPEC_TX_MICINST_CHUNK | SND_MOTU_SPEC_TX_RETURN_CHUNK | SND_MOTU_SPEC_TX_REVERB_CHUNK | + SND_MOTU_SPEC_RX_SEPARETED_MAIN | SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_HAS_OPT_IFACE_B | SND_MOTU_SPEC_RX_MIDI_3RD_Q | @@ -231,6 +233,7 @@ static const struct snd_motu_spec motu_audio_express = { .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | SND_MOTU_SPEC_TX_MICINST_CHUNK | SND_MOTU_SPEC_TX_RETURN_CHUNK | + SND_MOTU_SPEC_RX_SEPARETED_MAIN | SND_MOTU_SPEC_RX_MIDI_2ND_Q | SND_MOTU_SPEC_TX_MIDI_3RD_Q, .analog_in_ports = 2, diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index 4b23cf337c4b..bced0407179e 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -86,6 +86,7 @@ enum snd_motu_spec_flags { SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0200, SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0400, SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0800, + SND_MOTU_SPEC_RX_SEPARETED_MAIN = 0x1000, };
#define SND_MOTU_CLOCK_RATE_COUNT 6
MOTU Traveler supports AES/EBU on XLR interface and data block of rx/tx packet includes two chunk for the interface. This commit adds a flag for this purpose.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 5 +++++ sound/firewire/motu/motu-protocol-v3.c | 5 +++++ sound/firewire/motu/motu.h | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 614f9b11e010..f25b1ba118a2 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -160,6 +160,11 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[1] += 2; }
+ if (flags & SND_MOTU_SPEC_HAS_AESEBU_IFACE) { + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; + } + /* * All of v2 models have a pair of coaxial interfaces for digital in/out * port. At 44.1/48.0/88.2/96.0 kHz, packets includes PCM from these diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c index 293353991591..7cc80a05e91f 100644 --- a/sound/firewire/motu/motu-protocol-v3.c +++ b/sound/firewire/motu/motu-protocol-v3.c @@ -199,6 +199,11 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[1] += 2; }
+ if (flags & SND_MOTU_SPEC_HAS_AESEBU_IFACE) { + pcm_chunks[0] += 2; + pcm_chunks[1] += 2; + } + /* * At least, packets have two data chunks for S/PDIF on coaxial * interface. diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index bced0407179e..2764bcaab327 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -79,7 +79,7 @@ enum snd_motu_spec_flags { SND_MOTU_SPEC_TX_MICINST_CHUNK = 0x0004, SND_MOTU_SPEC_TX_RETURN_CHUNK = 0x0008, SND_MOTU_SPEC_TX_REVERB_CHUNK = 0x0010, - SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020, + SND_MOTU_SPEC_HAS_AESEBU_IFACE = 0x0020, SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040, SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080, SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0100,
For MOTU protocol version 2, this driver arranges the number of data chunks to align chunks to quadlet data channel. However, MOTU Traveler has padding bytes in the end of data block at high clock mode.
This commit removes the arrangement. Fortunately, at low and middle clock mode, supported model for v2 protocol (828mkII) gets no influence from this change because all of combination for data chunks are just aligned to quadlet data channel.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index f25b1ba118a2..e5bd3ac02300 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -173,12 +173,9 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[0] += 2; pcm_chunks[1] += 2;
- /* This part should be multiples of 4. */ - formats->fixed_part_pcm_chunks[0] = round_up(2 + pcm_chunks[0], 4) - 2; - formats->fixed_part_pcm_chunks[1] = round_up(2 + pcm_chunks[1], 4) - 2; - if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) - formats->fixed_part_pcm_chunks[2] = - round_up(2 + pcm_chunks[2], 4) - 2; + formats->fixed_part_pcm_chunks[0] = pcm_chunks[0]; + formats->fixed_part_pcm_chunks[1] = pcm_chunks[1]; + formats->fixed_part_pcm_chunks[2] = pcm_chunks[2]; }
static void calculate_differed_part(struct snd_motu_packet_format *formats,
This commit adds support for MOTU Traveler, launched in 2005, discontinued quite before. As a result, transmission of PCM frame and MIDI messages is available via ALSA PCM and RawMIDI/Sequencer interfaces.
This model supports sampling transmission frequency up to 192.0 kHz, and AES/EBU on XLR interface and ADAT on optical interface. Unlike Motu 828MkII, Windows driver can switch fetching mode for DSP, like mute/unmute feature.
Although this commit enables high sampling transmission frequency, actual sound from this model is not good. As long as I tested, it's silence at 176.4 kHz, and it includes hissing noise at 192.0 kHz. In my opinion, as I reported at 3526ce7f9ba7 ('ALSA: firewire-motu: add MOTU specific protocol layer'), timestamping on source packet header (SPH) may not still be good for this model as well.
$ python2 crpp < /sys/bus/firewire/devices/fw1/config_rom ROM header and bus information block ----------------------------------------------------------------- 400 04106505 bus_info_length 4, crc_length 16, crc 25861 404 31333934 bus_name "1394" 408 20001000 irmc 0, cmc 0, isc 1, bmc 0, cyc_clk_acc 0, max_rec 1 (4) 40c 0001f200 company_id 0001f2 | 410 0001f32f device_id 000001f32f | EUI-64 0001f2000001f32f
root directory ----------------------------------------------------------------- 414 0004c65c directory_length 4, crc 50780 418 030001f2 vendor 41c 0c0083c0 node capabilities per IEEE 1394 420 8d000006 --> eui-64 leaf at 438 424 d1000001 --> unit directory at 428
unit directory at 428 ----------------------------------------------------------------- 428 00035955 directory_length 3, crc 22869 42c 120001f2 specifier id 430 13000009 version 434 17107800 model
eui-64 leaf at 438 ----------------------------------------------------------------- 438 000206b2 leaf_length 2, crc 1714 43c 0001f200 company_id 0001f2 | 440 0001f32f device_id 000001f32f | EUI-64 0001f2000001f32f
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 34 ++++++++++++++++++++++++++++++++-- sound/firewire/motu/motu.c | 16 ++++++++++++++++ sound/firewire/motu/motu.h | 2 ++ 3 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index e5bd3ac02300..453fc29fade7 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -13,6 +13,8 @@ #define V2_CLOCK_RATE_SHIFT 3 #define V2_CLOCK_SRC_MASK 0x00000007 #define V2_CLOCK_SRC_SHIFT 0 +#define V2_CLOCK_TRAVELER_FETCH_DISABLE 0x04000000 +#define V2_CLOCK_TRAVELER_FETCH_ENABLE 0x03000000
#define V2_IN_OUT_CONF_OFFSET 0x0c04 #define V2_OPT_OUT_IFACE_MASK 0x00000c00 @@ -66,6 +68,11 @@ static int v2_set_clock_rate(struct snd_motu *motu, unsigned int rate) data &= ~V2_CLOCK_RATE_MASK; data |= i << V2_CLOCK_RATE_SHIFT;
+ if (motu->spec == &snd_motu_spec_traveler) { + data &= ~V2_CLOCK_TRAVELER_FETCH_ENABLE; + data |= V2_CLOCK_TRAVELER_FETCH_DISABLE; + } + reg = cpu_to_be32(data); return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, ®, sizeof(reg)); @@ -121,8 +128,31 @@ static int v2_get_clock_source(struct snd_motu *motu,
static int v2_switch_fetching_mode(struct snd_motu *motu, bool enable) { - /* V2 protocol doesn't have this feature. */ - return 0; + __be32 reg; + u32 data; + int err = 0; + + if (motu->spec == &snd_motu_spec_traveler) { + err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, + ®, sizeof(reg)); + if (err < 0) + return err; + data = be32_to_cpu(reg); + + data &= ~(V2_CLOCK_TRAVELER_FETCH_DISABLE | + V2_CLOCK_TRAVELER_FETCH_ENABLE); + + if (enable) + data |= V2_CLOCK_TRAVELER_FETCH_ENABLE; + else + data |= V2_CLOCK_TRAVELER_FETCH_DISABLE; + + reg = cpu_to_be32(data); + err = snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, + ®, sizeof(reg)); + } + + return err; }
static void calculate_fixed_part(struct snd_motu_packet_format *formats, diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c index 445aa589582d..300d31b6f191 100644 --- a/sound/firewire/motu/motu.c +++ b/sound/firewire/motu/motu.c @@ -209,6 +209,21 @@ static const struct snd_motu_spec motu_828mk2 = { .analog_out_ports = 8, };
+const struct snd_motu_spec snd_motu_spec_traveler = { + .name = "Traveler", + .protocol = &snd_motu_protocol_v2, + .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | + SND_MOTU_SPEC_SUPPORT_CLOCK_X4 | + SND_MOTU_SPEC_TX_RETURN_CHUNK | + SND_MOTU_SPEC_HAS_AESEBU_IFACE | + SND_MOTU_SPEC_HAS_OPT_IFACE_A | + SND_MOTU_SPEC_RX_MIDI_2ND_Q | + SND_MOTU_SPEC_TX_MIDI_2ND_Q, + + .analog_in_ports = 8, + .analog_out_ports = 8, +}; + static const struct snd_motu_spec motu_828mk3 = { .name = "828mk3", .protocol = &snd_motu_protocol_v3, @@ -253,6 +268,7 @@ static const struct snd_motu_spec motu_audio_express = {
static const struct ieee1394_device_id motu_id_table[] = { SND_MOTU_DEV_ENTRY(0x101800, &motu_828mk2), + SND_MOTU_DEV_ENTRY(0x107800, &snd_motu_spec_traveler), SND_MOTU_DEV_ENTRY(0x106800, &motu_828mk3), /* FireWire only. */ SND_MOTU_DEV_ENTRY(0x100800, &motu_828mk3), /* Hybrid. */ SND_MOTU_DEV_ENTRY(0x104800, &motu_audio_express), diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index 2764bcaab327..fd5327d30ab1 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -129,6 +129,8 @@ struct snd_motu_spec { extern const struct snd_motu_protocol snd_motu_protocol_v2; extern const struct snd_motu_protocol snd_motu_protocol_v3;
+extern const struct snd_motu_spec snd_motu_spec_traveler; + int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit, enum amdtp_stream_direction dir, const struct snd_motu_protocol *const protocol);
On Mon, 18 Jun 2018 14:07:50 +0200, Takashi Sakamoto wrote:
Hi,
This patchset adds support for MOTU Traveler launched in 2005. Any transmission of PCM frames/MIDI messages is available via ALSA PCM and RawMIDI/Sequencer interfaces to handle MOTU specific protocol version 2.
Like ALSA Dice driver, this driver can't enable target device to generate sound properly at some sampling transmission frequency yet, due to timestamping issue. However, at sampling transmission frequencies for major sampling rate such as 44.1/48.0 kHz, it works well, as long as I tested. This situation might be improved future.
Takashi Sakamoto (5): ALSA: firewire-motu: suppless consumption for unused element of array in stack ALSA: firewire-motu: add a flag for chunks for main 1/2 out ALSA: firewire-motu: add a flag for AES/EBU on XLR interface ALSA: firewire-motu: cancel chunk alignment for protocol version 2 ALSA: firewire-motu: add support for Motu Traveler
Applied all five patches now. Thanks.
Takashi
participants (2)
-
Takashi Iwai
-
Takashi Sakamoto