From 3f58f004bff3273d102583e0b2f478526cf9d3c8 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Wed, 30 Oct 2019 17:06:41 +0900 Subject: [PATCH] ALSA: firewire-motu: detect SPH source of sampling clock 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 Link: https://lore.kernel.org/r/20191030080644.1704-4-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai --- 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 55d3d66..490408b 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 4e5767c..b47ba81 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 a42f77f..2757e5b 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 ba5794c..d1545e2 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 08e3d56..bd782ee 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, }; -- 2.7.4