[PATCH 0/9] ALSA: firewire-motu: misc fixes and code refactoring
Hi,
This patchset includes misc fixes and code refactoring, mainly for detection of sampling clock source and 828/896 support recently added.
Takashi Sakamoto (9): ALSA: firewire-motu: fix detection for S/PDIF source on optical interface in v2 protocol ALSA: firewire-motu: code refactoring for detection of clock source in v2 protocol ALSA: firewire-motu: add support for AES/EBU clock source in v2 protocol ALSA: firewire-motu: use macro instead of magic number for clock source in v2 protocol ALSA: firewire-motu: code refactoring for packet format detection in v2 protocol ALSA: firewire-motu: code refactoring for source detection of sampling clock in v3 protocol ALSA: firewire-motu: use macro instead of magic number for clock source in v3 protocol ALSA: firewire-motu: fix register handling for 828 ALSA: firewire-motu: fix register handling for 896
sound/firewire/motu/motu-protocol-v1.c | 86 ++++++++---- sound/firewire/motu/motu-protocol-v2.c | 176 +++++++++---------------- sound/firewire/motu/motu-protocol-v3.c | 79 ++++------- 3 files changed, 143 insertions(+), 198 deletions(-)
The devices in protocol version 2 has a register with flag for IEC 60958 signal detection as source of sampling clock without discrimination between coaxial and optical interfaces. On the other hand, current implementation of driver manage to interpret type of signal on optical interface instead.
This commit fixes the detection of optical/coaxial interface for S/PDIF signal.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 784073aa1026..f0a0ecad4d74 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -86,24 +86,23 @@ static int detect_clock_source_optical_model(struct snd_motu *motu, u32 data, *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; break; case 1: + *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT; + break; + case 2: { __be32 reg;
// To check the configuration of optical interface. - int err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, - ®, sizeof(reg)); + 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) + if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) == V2_OPT_IFACE_MODE_SPDIF) *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT; else - *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT; + *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; break; } - case 2: - *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; - break; case 3: *src = SND_MOTU_CLOCK_SOURCE_SPH; break;
Current implementation of driver has two similar helper functions for source detection of sampling clock. This commit merges them as a code refactoring.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 68 ++++++++------------------ 1 file changed, 21 insertions(+), 47 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index f0a0ecad4d74..7b69a8ef6b3d 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -78,10 +78,10 @@ int snd_motu_protocol_v2_set_clock_rate(struct snd_motu *motu, sizeof(reg)); }
-static int detect_clock_source_optical_model(struct snd_motu *motu, u32 data, - enum snd_motu_clock_source *src) +static int get_clock_source(struct snd_motu *motu, u32 data, + enum snd_motu_clock_source *src) { - switch (data) { + switch (data & V2_CLOCK_SRC_MASK) { case 0: *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; break; @@ -90,17 +90,26 @@ static int detect_clock_source_optical_model(struct snd_motu *motu, u32 data, break; case 2: { - __be32 reg; + bool support_iec60958_on_opt = (motu->spec == &snd_motu_spec_828mk2 || + motu->spec == &snd_motu_spec_traveler);
- // 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 (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) == V2_OPT_IFACE_MODE_SPDIF) - *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT; - else + if (!support_iec60958_on_opt) { *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; + } else { + __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 (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) == + V2_OPT_IFACE_MODE_SPDIF) + *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT; + else + *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; + } break; } case 3: @@ -120,41 +129,6 @@ static int detect_clock_source_optical_model(struct snd_motu *motu, u32 data, return 0; }
-static int v2_detect_clock_source(struct snd_motu *motu, u32 data, - enum snd_motu_clock_source *src) -{ - switch (data) { - case 0: - *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; - break; - 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; - default: - *src = SND_MOTU_CLOCK_SOURCE_UNKNOWN; - break; - } - - return 0; -} - -static int get_clock_source(struct snd_motu *motu, u32 data, - enum snd_motu_clock_source *src) -{ - data &= V2_CLOCK_SRC_MASK; - if (motu->spec == &snd_motu_spec_828mk2 || - motu->spec == &snd_motu_spec_traveler) - return detect_clock_source_optical_model(motu, data, src); - else - return v2_detect_clock_source(motu, data, src); -} - int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu, enum snd_motu_clock_source *src) {
Although MOTU Traveler supports AES/EBU source for sampling clock, current implementation of driver doesn't code it.
This commit adds support for AES/EBU source in protocol version 2.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 7b69a8ef6b3d..7893cc73e983 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -121,6 +121,9 @@ static int get_clock_source(struct snd_motu *motu, u32 data, case 5: *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB; break; + case 7: + *src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR; + break; default: *src = SND_MOTU_CLOCK_SOURCE_UNKNOWN; break;
This commit adds a series of macro for source of sampling clock in version 2 protocol.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 7893cc73e983..8865308c2c8e 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -12,6 +12,13 @@ #define V2_CLOCK_RATE_SHIFT 3 #define V2_CLOCK_SRC_MASK 0x00000007 #define V2_CLOCK_SRC_SHIFT 0 +#define V2_CLOCK_SRC_AESEBU_ON_XLR 0x07 +#define V2_CLOCK_SRC_ADAT_ON_DSUB 0x05 +#define V2_CLOCK_SRC_WORD_ON_BNC 0x04 +#define V2_CLOCK_SRC_SPH 0x03 +#define V2_CLOCK_SRC_SPDIF 0x02 // on either coaxial or optical +#define V2_CLOCK_SRC_ADAT_ON_OPT 0x01 +#define V2_CLOCK_SRC_INTERNAL 0x00 #define V2_CLOCK_FETCH_ENABLE 0x02000000 #define V2_CLOCK_MODEL_SPECIFIC 0x04000000
@@ -82,13 +89,13 @@ static int get_clock_source(struct snd_motu *motu, u32 data, enum snd_motu_clock_source *src) { switch (data & V2_CLOCK_SRC_MASK) { - case 0: + case V2_CLOCK_SRC_INTERNAL: *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; break; - case 1: + case V2_CLOCK_SRC_ADAT_ON_OPT: *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT; break; - case 2: + case V2_CLOCK_SRC_SPDIF: { bool support_iec60958_on_opt = (motu->spec == &snd_motu_spec_828mk2 || motu->spec == &snd_motu_spec_traveler); @@ -112,16 +119,16 @@ static int get_clock_source(struct snd_motu *motu, u32 data, } break; } - case 3: + case V2_CLOCK_SRC_SPH: *src = SND_MOTU_CLOCK_SOURCE_SPH; break; - case 4: + case V2_CLOCK_SRC_WORD_ON_BNC: *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC; break; - case 5: + case V2_CLOCK_SRC_ADAT_ON_DSUB: *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB; break; - case 7: + case V2_CLOCK_SRC_AESEBU_ON_XLR: *src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR; break; default:
Current implementation of driver has several similar helper functions for packet format detection in protocol version 2.
This commit merges them as code refactoring.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v2.c | 79 +++++++------------------- 1 file changed, 20 insertions(+), 59 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 8865308c2c8e..93d5df1ae550 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -218,59 +218,9 @@ int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu, } }
-static int detect_packet_formats_828mk2(struct snd_motu *motu, u32 data) -{ - if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) == - V2_OPT_IFACE_MODE_ADAT) { - motu->tx_packet_formats.pcm_chunks[0] += 8; - motu->tx_packet_formats.pcm_chunks[1] += 4; - } - - if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) == - V2_OPT_IFACE_MODE_ADAT) { - motu->rx_packet_formats.pcm_chunks[0] += 8; - motu->rx_packet_formats.pcm_chunks[1] += 4; - } - - return 0; -} - -static int detect_packet_formats_traveler(struct snd_motu *motu, u32 data) -{ - if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) == - V2_OPT_IFACE_MODE_ADAT) { - motu->tx_packet_formats.pcm_chunks[0] += 8; - motu->tx_packet_formats.pcm_chunks[1] += 4; - } - - if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) == - V2_OPT_IFACE_MODE_ADAT) { - motu->rx_packet_formats.pcm_chunks[0] += 8; - motu->rx_packet_formats.pcm_chunks[1] += 4; - } - - return 0; -} - -static int detect_packet_formats_8pre(struct snd_motu *motu, u32 data) -{ - if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) == - V2_OPT_IFACE_MODE_ADAT) { - motu->tx_packet_formats.pcm_chunks[0] += 8; - motu->tx_packet_formats.pcm_chunks[1] += 8; - } - - if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) == - V2_OPT_IFACE_MODE_ADAT) { - motu->rx_packet_formats.pcm_chunks[0] += 8; - motu->rx_packet_formats.pcm_chunks[1] += 8; - } - - return 0; -} - int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu) { + bool has_two_opt_ifaces = (motu->spec == &snd_motu_spec_8pre); __be32 reg; u32 data; int err; @@ -294,14 +244,25 @@ int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu) motu->spec->rx_fixed_pcm_chunks, sizeof(motu->rx_packet_formats.pcm_chunks));
- if (motu->spec == &snd_motu_spec_828mk2) - return detect_packet_formats_828mk2(motu, data); - else if (motu->spec == &snd_motu_spec_traveler) - return detect_packet_formats_traveler(motu, data); - else if (motu->spec == &snd_motu_spec_8pre) - return detect_packet_formats_8pre(motu, data); - else - return 0; + if (((data & V2_OPT_IN_IFACE_MASK) >> V2_OPT_IN_IFACE_SHIFT) == V2_OPT_IFACE_MODE_ADAT) { + motu->tx_packet_formats.pcm_chunks[0] += 8; + + if (!has_two_opt_ifaces) + motu->tx_packet_formats.pcm_chunks[1] += 4; + else + motu->tx_packet_formats.pcm_chunks[1] += 8; + } + + if (((data & V2_OPT_OUT_IFACE_MASK) >> V2_OPT_OUT_IFACE_SHIFT) == V2_OPT_IFACE_MODE_ADAT) { + motu->rx_packet_formats.pcm_chunks[0] += 8; + + if (!has_two_opt_ifaces) + motu->rx_packet_formats.pcm_chunks[1] += 4; + else + motu->rx_packet_formats.pcm_chunks[1] += 8; + } + + return 0; }
const struct snd_motu_spec snd_motu_spec_828mk2 = {
Current implementation of driver has two similar helper functions for source detection of sampling clock. This commit merges them as a code refactoring.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v3.c | 59 ++++++-------------------- 1 file changed, 12 insertions(+), 47 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c index 77e61e89770b..ab113651107b 100644 --- a/sound/firewire/motu/motu-protocol-v3.c +++ b/sound/firewire/motu/motu-protocol-v3.c @@ -97,9 +97,19 @@ int snd_motu_protocol_v3_set_clock_rate(struct snd_motu *motu, return 0; }
-static int detect_clock_source_828mk3(struct snd_motu *motu, u32 data, - enum snd_motu_clock_source *src) +int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu, + enum snd_motu_clock_source *src) { + __be32 reg; + u32 data; + int err; + + err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, ®, + sizeof(reg)); + if (err < 0) + return err; + data = be32_to_cpu(reg) & V3_CLOCK_SOURCE_MASK; + switch (data) { case 0x00: *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; @@ -118,7 +128,6 @@ static int detect_clock_source_828mk3(struct snd_motu *motu, u32 data, { __be32 reg; u32 options; - int err;
err = snd_motu_transaction_read(motu, V3_OPT_IFACE_MODE_OFFSET, ®, sizeof(reg)); @@ -137,7 +146,6 @@ static int detect_clock_source_828mk3(struct snd_motu *motu, u32 data, else *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B; } - break; } default: @@ -148,49 +156,6 @@ static int detect_clock_source_828mk3(struct snd_motu *motu, u32 data, return 0; }
-static int v3_detect_clock_source(struct snd_motu *motu, u32 data, - enum snd_motu_clock_source *src) -{ - switch (data) { - case 0x00: - *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; - break; - case 0x01: - *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC; - break; - case 0x02: - *src = SND_MOTU_CLOCK_SOURCE_SPH; - break; - case 0x10: - *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; - break; - default: - *src = SND_MOTU_CLOCK_SOURCE_UNKNOWN; - break; - } - - return 0; -} - -int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu, - enum snd_motu_clock_source *src) -{ - __be32 reg; - u32 data; - int err; - - err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, ®, - sizeof(reg)); - if (err < 0) - return err; - data = be32_to_cpu(reg) & V3_CLOCK_SOURCE_MASK; - - if (motu->spec == &snd_motu_spec_828mk3_fw || motu->spec == &snd_motu_spec_828mk3_hybrid) - return detect_clock_source_828mk3(motu, data, src); - else - return v3_detect_clock_source(motu, data, src); -} - int snd_motu_protocol_v3_switch_fetching_mode(struct snd_motu *motu, bool enable) {
This commit adds a series of macro for source of sampling clock in version 3 protocol.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v3.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c index ab113651107b..56e4504e7ec9 100644 --- a/sound/firewire/motu/motu-protocol-v3.c +++ b/sound/firewire/motu/motu-protocol-v3.c @@ -13,6 +13,12 @@ #define V3_CLOCK_RATE_MASK 0x0000ff00 #define V3_CLOCK_RATE_SHIFT 8 #define V3_CLOCK_SOURCE_MASK 0x000000ff +#define V3_CLOCK_SRC_INTERNAL 0x00 +#define V3_CLOCK_SRC_WORD_ON_BNC 0x01 +#define V3_CLOCK_SRC_SPH 0x02 +#define V3_CLOCK_SRC_SPDIF_ON_COAX 0x10 +#define V3_CLOCK_SRC_OPT_IFACE_A 0x18 +#define V3_CLOCK_SRC_OPT_IFACE_B 0x19
#define V3_OPT_IFACE_MODE_OFFSET 0x0c94 #define V3_ENABLE_OPT_IN_IFACE_A 0x00000001 @@ -111,20 +117,20 @@ int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu, data = be32_to_cpu(reg) & V3_CLOCK_SOURCE_MASK;
switch (data) { - case 0x00: + case V3_CLOCK_SRC_INTERNAL: *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; break; - case 0x01: + case V3_CLOCK_SRC_WORD_ON_BNC: *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC; break; - case 0x02: + case V3_CLOCK_SRC_SPH: *src = SND_MOTU_CLOCK_SOURCE_SPH; break; - case 0x10: + case V3_CLOCK_SRC_SPDIF_ON_COAX: *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; break; - case 0x18: - case 0x19: + case V3_CLOCK_SRC_OPT_IFACE_A: + case V3_CLOCK_SRC_OPT_IFACE_B: { __be32 reg; u32 options; @@ -135,7 +141,7 @@ int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu, return err; options = be32_to_cpu(reg);
- if (data == 0x18) { + if (data == V3_CLOCK_SRC_OPT_IFACE_A) { if (options & V3_NO_ADAT_OPT_IN_IFACE_A) *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A; else
After further investigation, I find out some mistakes for 828 about its register. This commit fixes it.
Fixes: d13d6b284d8b ("ALSA: firewire-motu: add support for MOTU 828") Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v1.c | 53 +++++++++++++++++--------- 1 file changed, 35 insertions(+), 18 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v1.c b/sound/firewire/motu/motu-protocol-v1.c index 65209e617e10..3b766615a9ee 100644 --- a/sound/firewire/motu/motu-protocol-v1.c +++ b/sound/firewire/motu/motu-protocol-v1.c @@ -19,7 +19,7 @@ // 0x00004000: mode of optical output interface. // 0x00004000: for S/PDIF signal. // 0x00000000: disabled or for ADAT signal. -// 0x00003f40: monitor input mode. +// 0x00003f00: monitor input mode. // 0x00000800: analog-1/2 // 0x00001a00: analog-3/4 // 0x00002c00: analog-5/6 @@ -32,26 +32,32 @@ // 0x00002d00: analog-6 // 0x00003600: analog-7 // 0x00003f00: analog-8 -// 0x00000040: disabled +// 0x00000080: enable stream input. +// 0x00000040: disable monitor input. +// 0x00000008: enable main out. // 0x00000004: rate of sampling clock. // 0x00000004: 48.0 kHz // 0x00000000: 44.1 kHz // 0x00000023: source of sampling clock. +// 0x00000003: source packet header (SPH) // 0x00000002: S/PDIF on optical/coaxial interface. // 0x00000021: ADAT on optical interface // 0x00000001: ADAT on Dsub 9pin -// 0x00000000: internal or SMPTE +// 0x00000000: internal
#define CLK_828_STATUS_OFFSET 0x0b00 #define CLK_828_STATUS_MASK 0x0000ffff #define CLK_828_STATUS_FLAG_OPT_IN_IFACE_IS_SPDIF 0x00008000 #define CLK_828_STATUS_FLAG_OPT_OUT_IFACE_IS_SPDIF 0x00004000 #define CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES 0x00000080 -#define CLK_828_STATUS_FLAG_SRC_IS_NOT_FROM_ADAT_DSUB 0x00000020 -#define CLK_828_STATUS_FLAG_OUTPUT_MUTE 0x00000008 +#define CLK_828_STATUS_FLAG_ENABLE_OUTPUT 0x00000008 #define CLK_828_STATUS_FLAG_RATE_48000 0x00000004 -#define CLK_828_STATUS_FLAG_SRC_SPDIF_ON_OPT_OR_COAX 0x00000002 -#define CLK_828_STATUS_FLAG_SRC_ADAT_ON_OPT_OR_DSUB 0x00000001 +#define CLK_828_STATUS_MASK_SRC 0x00000023 +#define CLK_828_STATUS_FLAG_SRC_ADAT_ON_OPT 0x00000021 +#define CLK_828_STATUS_FLAG_SRC_SPH 0x00000003 +#define CLK_828_STATUS_FLAG_SRC_SPDIF 0x00000002 +#define CLK_828_STATUS_FLAG_SRC_ADAT_ON_DSUB 0x00000001 +#define CLK_828_STATUS_FLAG_SRC_INTERNAL 0x00000000
// Status register for MOTU 896 (0x'ffff'f000'0b14). // @@ -249,18 +255,29 @@ static int get_clock_source_828(struct snd_motu *motu, enum snd_motu_clock_sourc return err; data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
- if (data & CLK_828_STATUS_FLAG_SRC_ADAT_ON_OPT_OR_DSUB) { - if (data & CLK_828_STATUS_FLAG_SRC_IS_NOT_FROM_ADAT_DSUB) - *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT; - else - *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB; - } else if (data & CLK_828_STATUS_FLAG_SRC_SPDIF_ON_OPT_OR_COAX) { + switch (data & CLK_828_STATUS_MASK_SRC) { + case CLK_828_STATUS_FLAG_SRC_ADAT_ON_OPT: + *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT; + break; + case CLK_828_STATUS_FLAG_SRC_SPH: + *src = SND_MOTU_CLOCK_SOURCE_SPH; + break; + case CLK_828_STATUS_FLAG_SRC_SPDIF: + { if (data & CLK_828_STATUS_FLAG_OPT_IN_IFACE_IS_SPDIF) - *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT; - else *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; - } else { + else + *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT; + break; + } + case CLK_828_STATUS_FLAG_SRC_ADAT_ON_DSUB: + *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB; + break; + case CLK_828_STATUS_FLAG_SRC_INTERNAL: *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; + break; + default: + return -ENXIO; }
return 0; @@ -321,13 +338,13 @@ static int switch_fetching_mode_828(struct snd_motu *motu, bool enable) return err; data = be32_to_cpu(reg) & CLK_828_STATUS_MASK;
- data &= ~(CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES | CLK_828_STATUS_FLAG_OUTPUT_MUTE); + data &= ~(CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES | CLK_828_STATUS_FLAG_ENABLE_OUTPUT); if (enable) { // This transaction should be initiated after the device receives batch of packets // since the device voluntarily mutes outputs. As a workaround, yield processor over // 100 msec. msleep(100); - data |= CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES | CLK_828_STATUS_FLAG_OUTPUT_MUTE; + data |= CLK_828_STATUS_FLAG_FETCH_PCM_FRAMES | CLK_828_STATUS_FLAG_ENABLE_OUTPUT; }
reg = cpu_to_be32(data);
After further investigation, I find out some mistakes for 896 about its register. This commit fixes it.
Fixes: b431f16f1685 ("ALSA: firewire-motu: add support for MOTU 896") Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- sound/firewire/motu/motu-protocol-v1.c | 33 ++++++++++++++++++-------- 1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/sound/firewire/motu/motu-protocol-v1.c b/sound/firewire/motu/motu-protocol-v1.c index 3b766615a9ee..f1d6a326dc07 100644 --- a/sound/firewire/motu/motu-protocol-v1.c +++ b/sound/firewire/motu/motu-protocol-v1.c @@ -61,13 +61,21 @@
// Status register for MOTU 896 (0x'ffff'f000'0b14). // -// 0x20000000: fetch PCM frames from communication IC to DAC. +// 0xf0000000: enable physical and stream input to DAC. +// 0x80000000: disable +// 0x40000000: disable +// 0x20000000: enable (prior to the other bits) +// 0x10000000: disable +// 0x00000000: disable // 0x08000000: speed of word clock signal output on BNC interface. -// 0x00000000: follow to system clock. -// 0x08000000: half of system clock. -// 0x01000000: Route main output to headphone output. -// 0x00ffff00: input to monitor. -// 0x00000000: none +// 0x00000000: force to low rate (44.1/48.0 kHz). +// 0x08000000: follow to system clock. +// 0x04000000: something relevant to clock. +// 0x03000000: enable output. +// 0x02000000: enabled irreversibly once standing unless the device voluntarily disables it. +// 0x01000000: enabled irreversibly once standing unless the device voluntarily disables it. +// 0x00ffff00: monitor input mode. +// 0x00000000: disabled // 0x00004800: analog-1/2 // 0x00005a00: analog-3/4 // 0x00006c00: analog-5/6 @@ -83,7 +91,7 @@ // 0x00007f00: analog-8 // 0x00104000: AES/EBU-1 // 0x00104900: AES/EBU-2 -// 0x00000060: sample rate conversin for AES/EBU input/output. +// 0x00000060: sample rate conversion for AES/EBU input/output. // 0x00000000: None // 0x00000020: input signal is converted to system rate // 0x00000040: output is slave to input, ignoring system rate @@ -97,16 +105,18 @@ // 0x00000000: internal // 0x00000001: ADAT on optical interface // 0x00000002: AES/EBU on XLR +// 0x00000003: source packet header (SPH) // 0x00000004: word clock on BNC // 0x00000005: ADAT on Dsub 9pin
#define CLK_896_STATUS_OFFSET 0x0b14 #define CLK_896_STATUS_FLAG_FETCH_ENABLE 0x20000000 -#define CLK_896_STATUS_FLAG_MAIN_TO_HP 0x01000000 +#define CLK_896_STATUS_FLAG_OUTPUT_ON 0x03000000 #define CLK_896_STATUS_MASK_SRC 0x00000007 #define CLK_896_STATUS_FLAG_SRC_INTERNAL 0x00000000 #define CLK_896_STATUS_FLAG_SRC_ADAT_ON_OPT 0x00000001 #define CLK_896_STATUS_FLAG_SRC_AESEBU 0x00000002 +#define CLK_896_STATUS_FLAG_SRC_SPH 0x00000003 #define CLK_896_STATUS_FLAG_SRC_WORD 0x00000004 #define CLK_896_STATUS_FLAG_SRC_ADAT_ON_DSUB 0x00000005 #define CLK_896_STATUS_MASK_RATE 0x00000018 @@ -304,6 +314,9 @@ static int get_clock_source_896(struct snd_motu *motu, enum snd_motu_clock_sourc case CLK_896_STATUS_FLAG_SRC_AESEBU: *src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR; break; + case CLK_896_STATUS_FLAG_SRC_SPH: + *src = SND_MOTU_CLOCK_SOURCE_SPH; + break; case CLK_896_STATUS_FLAG_SRC_WORD: *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC; break; @@ -362,9 +375,9 @@ static int switch_fetching_mode_896(struct snd_motu *motu, bool enable) return err; data = be32_to_cpu(reg);
- data &= ~(CLK_896_STATUS_FLAG_FETCH_ENABLE | CLK_896_STATUS_FLAG_MAIN_TO_HP); + data &= ~CLK_896_STATUS_FLAG_FETCH_ENABLE; if (enable) - data |= (CLK_896_STATUS_FLAG_FETCH_ENABLE | CLK_896_STATUS_FLAG_MAIN_TO_HP); + data |= CLK_896_STATUS_FLAG_FETCH_ENABLE | CLK_896_STATUS_FLAG_OUTPUT_ON;
reg = cpu_to_be32(data); return snd_motu_transaction_write(motu, CLK_896_STATUS_OFFSET, ®, sizeof(reg));
On Wed, 23 Jun 2021 09:59:32 +0200, Takashi Sakamoto wrote:
Hi,
This patchset includes misc fixes and code refactoring, mainly for detection of sampling clock source and 828/896 support recently added.
Takashi Sakamoto (9): ALSA: firewire-motu: fix detection for S/PDIF source on optical interface in v2 protocol ALSA: firewire-motu: code refactoring for detection of clock source in v2 protocol ALSA: firewire-motu: add support for AES/EBU clock source in v2 protocol ALSA: firewire-motu: use macro instead of magic number for clock source in v2 protocol ALSA: firewire-motu: code refactoring for packet format detection in v2 protocol ALSA: firewire-motu: code refactoring for source detection of sampling clock in v3 protocol ALSA: firewire-motu: use macro instead of magic number for clock source in v3 protocol ALSA: firewire-motu: fix register handling for 828 ALSA: firewire-motu: fix register handling for 896
Thanks, applied all patches.
Takashi
participants (2)
-
Takashi Iwai
-
Takashi Sakamoto