[alsa-devel] [PATCH 0/6] ALSA: firewire-motu: add support for MOTU UltraLite and source packet header clock mode
Hi,
Devices in MOTU FireWire series uses source packet header (SPH) in IEC 61883-1 for each data block in CIP. The devices have a mode to use the series of SPH for generating sampling clock.
This patchset supports the above mechanism. Additionally, this patchset also supports MOTU UltraLite which adopts protocol version 2.
Takashi Sakamoto (6): ALSA: firewire-motu: fix wrong spelling for macro ALSA: firewire-motu: print for unknown source of sampling clock ALSA: firewire-motu: detect SPH source of sampling clock ALSA: firewire-motu: minor code refactoring for protocol version 2 ALSA: firewire-motu: code refactoring to handle model specific switch for protocol v2 ALSA: firewire-motu: add support for MOTU UltraLite
sound/firewire/motu/motu-pcm.c | 3 +- sound/firewire/motu/motu-proc.c | 2 + sound/firewire/motu/motu-protocol-v2.c | 142 ++++++++++++++----------- sound/firewire/motu/motu-protocol-v3.c | 4 +- sound/firewire/motu/motu.c | 34 ++++-- sound/firewire/motu/motu.h | 6 +- 6 files changed, 113 insertions(+), 78 deletions(-)
Just replace 'SEPARETED' with 'SEPARATED' for macro.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 2 +- sound/firewire/motu/motu-protocol-v3.c | 2 +- sound/firewire/motu/motu.c | 8 ++++---- sound/firewire/motu/motu.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 9e2f16eebe0a..a42f77fc3858 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -191,7 +191,7 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[1] += 2; } } else { - if (flags & SND_MOTU_SPEC_RX_SEPARETED_MAIN) { + if (flags & SND_MOTU_SPEC_RX_SEPARATED_MAIN) { 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 5eafa506e8a9..ba5794c724be 100644 --- a/sound/firewire/motu/motu-protocol-v3.c +++ b/sound/firewire/motu/motu-protocol-v3.c @@ -187,7 +187,7 @@ static void calculate_fixed_part(struct snd_motu_packet_format *formats, pcm_chunks[1] += 2; } } else { - if (flags & SND_MOTU_SPEC_RX_SEPARETED_MAIN) { + if (flags & SND_MOTU_SPEC_RX_SEPARATED_MAIN) { pcm_chunks[0] += 2; pcm_chunks[1] += 2; } diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c index 72908b4de77c..680e363d0a4b 100644 --- a/sound/firewire/motu/motu.c +++ b/sound/firewire/motu/motu.c @@ -178,7 +178,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_RX_SEPARATED_MAIN | SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_RX_MIDI_2ND_Q | SND_MOTU_SPEC_TX_MIDI_2ND_Q, @@ -224,7 +224,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_RX_SEPARATED_MAIN | SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_HAS_OPT_IFACE_B | SND_MOTU_SPEC_RX_MIDI_3RD_Q | @@ -240,7 +240,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_SEPARATED_MAIN | SND_MOTU_SPEC_RX_MIDI_2ND_Q | SND_MOTU_SPEC_TX_MIDI_3RD_Q, .analog_in_ports = 2, @@ -253,7 +253,7 @@ static const struct snd_motu_spec motu_4pre = { .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_SEPARATED_MAIN, .analog_in_ports = 2, .analog_out_ports = 2, }; diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index 35ed8b6bb8e8..08e3d568221d 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -86,7 +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, + SND_MOTU_SPEC_RX_SEPARATED_MAIN = 0x1000, };
#define SND_MOTU_CLOCK_RATE_COUNT 6
When unknown source is detected for sampling clock, corresponding label was not added for node on procfs.
This commit adds it.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-proc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/firewire/motu/motu-proc.c b/sound/firewire/motu/motu-proc.c index ea46fb4c1b5a..4e5767c0c8d7 100644 --- a/sound/firewire/motu/motu-proc.c +++ b/sound/firewire/motu/motu-proc.c @@ -19,6 +19,7 @@ static const char *const clock_names[] = { [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX] = "S/PCIF on coaxial interface", [SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR] = "AESEBU on XLR interface", [SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC] = "Word clock on BNC interface", + [SND_MOTU_CLOCK_SOURCE_UNKNOWN] = "Unknown", };
static void proc_read_clock(struct snd_info_entry *entry,
In MOTU FireWire series, devices have a mode to generate sampling clock from a sequence of source packet header (SPH) included in each data block of received packet. This mode is used for several purposes such as mode for SMPTE time code, sync to the other sound cards and so on.
This commit adds support for the SPH mode.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-pcm.c | 3 ++- sound/firewire/motu/motu-proc.c | 1 + sound/firewire/motu/motu-protocol-v2.c | 3 +++ sound/firewire/motu/motu-protocol-v3.c | 2 ++ sound/firewire/motu/motu.h | 1 + 5 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/sound/firewire/motu/motu-pcm.c b/sound/firewire/motu/motu-pcm.c index 55d3d6661731..490408b49157 100644 --- a/sound/firewire/motu/motu-pcm.c +++ b/sound/firewire/motu/motu-pcm.c @@ -159,7 +159,8 @@ static int pcm_open(struct snd_pcm_substream *substream) // When source of clock is not internal or any stream is reserved for // transmission of PCM frames, the available sampling rate is limited // at current one. - if (src != SND_MOTU_CLOCK_SOURCE_INTERNAL || + if ((src != SND_MOTU_CLOCK_SOURCE_INTERNAL && + src != SND_MOTU_CLOCK_SOURCE_SPH) || (motu->substreams_counter > 0 && d->events_per_period > 0)) { unsigned int frames_per_period = d->events_per_period; unsigned int frames_per_buffer = d->events_per_buffer; diff --git a/sound/firewire/motu/motu-proc.c b/sound/firewire/motu/motu-proc.c index 4e5767c0c8d7..b47ba818343f 100644 --- a/sound/firewire/motu/motu-proc.c +++ b/sound/firewire/motu/motu-proc.c @@ -19,6 +19,7 @@ static const char *const clock_names[] = { [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX] = "S/PCIF on coaxial interface", [SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR] = "AESEBU on XLR interface", [SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC] = "Word clock on BNC interface", + [SND_MOTU_CLOCK_SOURCE_SPH] = "Source packet header", [SND_MOTU_CLOCK_SOURCE_UNKNOWN] = "Unknown", };
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index a42f77fc3858..2757e5b42b9b 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -114,6 +114,9 @@ static int v2_get_clock_source(struct snd_motu *motu, case 2: *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; break; + case 3: + *src = SND_MOTU_CLOCK_SOURCE_SPH; + break; case 4: *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC; break; diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c index ba5794c724be..d1545e2b5caa 100644 --- a/sound/firewire/motu/motu-protocol-v3.c +++ b/sound/firewire/motu/motu-protocol-v3.c @@ -104,6 +104,8 @@ static int v3_get_clock_source(struct snd_motu *motu, *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; } else if (val == 0x01) { *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC; + } else if (val == 0x02) { + *src = SND_MOTU_CLOCK_SOURCE_SPH; } else if (val == 0x10) { *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; } else if (val == 0x18 || val == 0x19) { diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index 08e3d568221d..bd782ee4e763 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -104,6 +104,7 @@ enum snd_motu_clock_source { SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX, SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR, SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC, + SND_MOTU_CLOCK_SOURCE_SPH, SND_MOTU_CLOCK_SOURCE_UNKNOWN, };
This commit adds some helper functions to parse register value for source of sampling clock and nominal sampling transmission frequency.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 65 +++++++++++++++----------- 1 file changed, 39 insertions(+), 26 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 2757e5b42b9b..cb0e58a9f33d 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -26,10 +26,20 @@ #define V2_OPT_IFACE_MODE_ADAT 1 #define V2_OPT_IFACE_MODE_SPDIF 2
+static int get_clock_rate(u32 data, unsigned int *rate) +{ + unsigned int index = (data & V2_CLOCK_RATE_MASK) >> V2_CLOCK_RATE_SHIFT; + if (index >= ARRAY_SIZE(snd_motu_clock_rates)) + return -EIO; + + *rate = snd_motu_clock_rates[index]; + + return 0; +} + static int v2_get_clock_rate(struct snd_motu *motu, unsigned int *rate) { __be32 reg; - unsigned int index; int err;
err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, ®, @@ -37,13 +47,7 @@ static int v2_get_clock_rate(struct snd_motu *motu, unsigned int *rate) if (err < 0) return err;
- index = (be32_to_cpu(reg) & V2_CLOCK_RATE_MASK) >> V2_CLOCK_RATE_SHIFT; - if (index >= ARRAY_SIZE(snd_motu_clock_rates)) - return -EIO; - - *rate = snd_motu_clock_rates[index]; - - return 0; + return get_clock_rate(be32_to_cpu(reg), rate); }
static int v2_set_clock_rate(struct snd_motu *motu, unsigned int rate) @@ -79,38 +83,33 @@ static int v2_set_clock_rate(struct snd_motu *motu, unsigned int rate) sizeof(reg)); }
-static int v2_get_clock_source(struct snd_motu *motu, - enum snd_motu_clock_source *src) +static int get_clock_source(struct snd_motu *motu, u32 data, + enum snd_motu_clock_source *src) { - __be32 reg; - unsigned int index; - int err; - - err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, ®, - sizeof(reg)); - if (err < 0) - return err; - - index = be32_to_cpu(reg) & V2_CLOCK_SRC_MASK; + unsigned int index = data & V2_CLOCK_SRC_MASK; if (index > 5) return -EIO;
- /* To check the configuration of optical interface. */ - err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, ®, - sizeof(reg)); - if (err < 0) - return err; - switch (index) { case 0: *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; break; case 1: + { + __be32 reg; + + // To check the configuration of optical interface. + int err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, + ®, sizeof(reg)); + if (err < 0) + return err; + if (be32_to_cpu(reg) & 0x00000200) *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT; else *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT; break; + } case 2: *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; break; @@ -130,6 +129,20 @@ static int v2_get_clock_source(struct snd_motu *motu, return 0; }
+static int v2_get_clock_source(struct snd_motu *motu, + enum snd_motu_clock_source *src) +{ + __be32 reg; + int err; + + err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, ®, + sizeof(reg)); + if (err < 0) + return err; + + return get_clock_source(motu, be32_to_cpu(reg), src); +} + static int v2_switch_fetching_mode(struct snd_motu *motu, bool enable) { __be32 reg;
In MOTU FireWire series, devices which support protocol version 2 have several types of hardware design to process audio data frames for isoc packet. Roughly devices are categorized into three groups: - 828mkII - Traveler/896HD - UltraLite/8pre FireWire
Some bit flags in register addressed by 0x'ffff'f000'0b14 includes device-specific effects.
This commit cleanups implementation of protocol v2 in this point.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 72 +++++++++++++------------- sound/firewire/motu/motu.c | 12 ++--- sound/firewire/motu/motu.h | 3 +- 3 files changed, 43 insertions(+), 44 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index cb0e58a9f33d..619b6ae73f62 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -12,10 +12,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_CLOCK_8PRE_FETCH_DISABLE 0x02000000 -#define V2_CLOCK_8PRE_FETCH_ENABLE 0x00000000 +#define V2_CLOCK_FETCH_ENABLE 0x02000000 +#define V2_CLOCK_MODEL_SPECIFIC 0x04000000
#define V2_IN_OUT_CONF_OFFSET 0x0c04 #define V2_OPT_OUT_IFACE_MASK 0x00000c00 @@ -73,11 +71,6 @@ 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)); @@ -145,42 +138,49 @@ static int v2_get_clock_source(struct snd_motu *motu,
static int v2_switch_fetching_mode(struct snd_motu *motu, bool enable) { + enum snd_motu_clock_source src; __be32 reg; u32 data; int err = 0;
- if (motu->spec == &snd_motu_spec_traveler || - motu->spec == &snd_motu_spec_8pre) { - err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, - ®, sizeof(reg)); + // 828mkII implements Altera ACEX 1K EP1K30. Nothing to do. + if (motu->spec == &snd_motu_spec_828mk2) + return 0; + + err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, ®, + sizeof(reg)); + if (err < 0) + return err; + data = be32_to_cpu(reg); + + err = get_clock_source(motu, data, &src); + if (err < 0) + return err; + + data &= ~(V2_CLOCK_FETCH_ENABLE | V2_CLOCK_MODEL_SPECIFIC); + if (enable) + data |= V2_CLOCK_FETCH_ENABLE; + + if (motu->spec->flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) { + // Expected for Traveler and 896HD, which implements Altera + // Cyclone EP1C3. + data |= V2_CLOCK_MODEL_SPECIFIC; + } else { + // For UltraLite and 8pre, which implements Xilinx Spartan + // XC3S200. + unsigned int rate; + + err = get_clock_rate(data, &rate); if (err < 0) return err; - data = be32_to_cpu(reg); - - if (motu->spec == &snd_motu_spec_traveler) { - 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; - } else if (motu->spec == &snd_motu_spec_8pre) { - data &= ~(V2_CLOCK_8PRE_FETCH_DISABLE | - V2_CLOCK_8PRE_FETCH_ENABLE); - - if (enable) - data |= V2_CLOCK_8PRE_FETCH_DISABLE; - else - data |= V2_CLOCK_8PRE_FETCH_ENABLE; - }
- reg = cpu_to_be32(data); - err = snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, - ®, sizeof(reg)); + if (src == SND_MOTU_CLOCK_SOURCE_SPH && rate > 48000) + data |= V2_CLOCK_MODEL_SPECIFIC; }
- return err; + reg = cpu_to_be32(data); + return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, ®, + sizeof(reg)); }
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 680e363d0a4b..f249ad39d8a8 100644 --- a/sound/firewire/motu/motu.c +++ b/sound/firewire/motu/motu.c @@ -172,7 +172,7 @@ static void motu_bus_update(struct fw_unit *unit) snd_motu_transaction_reregister(motu); }
-static const struct snd_motu_spec motu_828mk2 = { +const struct snd_motu_spec snd_motu_spec_828mk2 = { .name = "828mk2", .protocol = &snd_motu_protocol_v2, .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | @@ -187,7 +187,7 @@ static const struct snd_motu_spec motu_828mk2 = { .analog_out_ports = 8, };
-const struct snd_motu_spec snd_motu_spec_traveler = { +static const struct snd_motu_spec motu_traveler = { .name = "Traveler", .protocol = &snd_motu_protocol_v2, .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | @@ -202,7 +202,7 @@ const struct snd_motu_spec snd_motu_spec_traveler = { .analog_out_ports = 8, };
-const struct snd_motu_spec snd_motu_spec_8pre = { +static const struct snd_motu_spec motu_8pre = { .name = "8pre", .protocol = &snd_motu_protocol_v2, // In tx, use coax chunks for mix-return 1/2. In rx, use coax chunks for @@ -270,9 +270,9 @@ static const struct snd_motu_spec motu_4pre = { }
static const struct ieee1394_device_id motu_id_table[] = { - SND_MOTU_DEV_ENTRY(0x000003, &motu_828mk2), - SND_MOTU_DEV_ENTRY(0x000009, &snd_motu_spec_traveler), - SND_MOTU_DEV_ENTRY(0x00000f, &snd_motu_spec_8pre), + SND_MOTU_DEV_ENTRY(0x000003, &snd_motu_spec_828mk2), + SND_MOTU_DEV_ENTRY(0x000009, &motu_traveler), + SND_MOTU_DEV_ENTRY(0x00000f, &motu_8pre), SND_MOTU_DEV_ENTRY(0x000015, &motu_828mk3), /* FireWire only. */ SND_MOTU_DEV_ENTRY(0x000035, &motu_828mk3), /* Hybrid. */ SND_MOTU_DEV_ENTRY(0x000033, &motu_audio_express), diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index bd782ee4e763..6efbde405a0d 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -130,8 +130,7 @@ 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; -extern const struct snd_motu_spec snd_motu_spec_8pre; +extern const struct snd_motu_spec snd_motu_spec_828mk2;
int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit, enum amdtp_stream_direction dir,
UltraLite was shipped in 2005 by MOTU, and already discontinued. This model consists of below ICs:
- Texus Instruments TSB41AB2 for physical layer of IEEE 1394 bus - Xilinx Spartan XC35S200 for link layer of IEEE 1394 bus, protocol layer and signal processing
This commit adds support for this model. Like the other MOTU models, ALSA firewire MOTU driver fails to drive the device for stable sampling clock and generate noisy sound.
$ python2 crpp < /sys/bus/firewire/devices/fw1/config_rom ROM header and bus information block ----------------------------------------------------------------- 400 04107574 bus_info_length 4, crc_length 16, crc 30068 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 0007b82d device_id 000007b82d | EUI-64 0001f2000007b82d
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 0003d80a directory_length 3, crc 55306 42c 120001f2 specifier id 430 1300000d version 434 17100800 model
eui-64 leaf at 438 ----------------------------------------------------------------- 438 00024566 leaf_length 2, crc 17766 43c 0001f200 company_id 0001f2 | 440 0007b82d device_id 000007b82d | EUI-64 0001f2000007b82d
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c index f249ad39d8a8..f2080d720aa9 100644 --- a/sound/firewire/motu/motu.c +++ b/sound/firewire/motu/motu.c @@ -202,6 +202,19 @@ static const struct snd_motu_spec motu_traveler = { .analog_out_ports = 8, };
+static const struct snd_motu_spec motu_ultralite = { + .name = "UltraLite", + .protocol = &snd_motu_protocol_v2, + .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | + SND_MOTU_SPEC_TX_MICINST_CHUNK | // padding. + SND_MOTU_SPEC_TX_RETURN_CHUNK | + SND_MOTU_SPEC_RX_MIDI_2ND_Q | + SND_MOTU_SPEC_TX_MIDI_2ND_Q | + SND_MOTU_SPEC_RX_SEPARATED_MAIN, + .analog_in_ports = 8, + .analog_out_ports = 8, +}; + static const struct snd_motu_spec motu_8pre = { .name = "8pre", .protocol = &snd_motu_protocol_v2, @@ -272,6 +285,7 @@ static const struct snd_motu_spec motu_4pre = { static const struct ieee1394_device_id motu_id_table[] = { SND_MOTU_DEV_ENTRY(0x000003, &snd_motu_spec_828mk2), SND_MOTU_DEV_ENTRY(0x000009, &motu_traveler), + SND_MOTU_DEV_ENTRY(0x00000d, &motu_ultralite), SND_MOTU_DEV_ENTRY(0x00000f, &motu_8pre), SND_MOTU_DEV_ENTRY(0x000015, &motu_828mk3), /* FireWire only. */ SND_MOTU_DEV_ENTRY(0x000035, &motu_828mk3), /* Hybrid. */
On Wed, 30 Oct 2019 09:06:38 +0100, Takashi Sakamoto wrote:
Hi,
Devices in MOTU FireWire series uses source packet header (SPH) in IEC 61883-1 for each data block in CIP. The devices have a mode to use the series of SPH for generating sampling clock.
This patchset supports the above mechanism. Additionally, this patchset also supports MOTU UltraLite which adopts protocol version 2.
Takashi Sakamoto (6): ALSA: firewire-motu: fix wrong spelling for macro ALSA: firewire-motu: print for unknown source of sampling clock ALSA: firewire-motu: detect SPH source of sampling clock ALSA: firewire-motu: minor code refactoring for protocol version 2 ALSA: firewire-motu: code refactoring to handle model specific switch for protocol v2 ALSA: firewire-motu: add support for MOTU UltraLite
Applied all patches now. Thanks.
Takashi
participants (2)
-
Takashi Iwai
-
Takashi Sakamoto