diff mbox series

[6/6] ALSA: fireface: perform sequence replay for media clock recovery

Message ID 20210531025103.17880-7-o-takashi@sakamocchi.jp
State Accepted
Commit dfacca39867b0263fedbd0cccae5574d40c1ddf2
Headers show
Series ALSA: firewire: media clock recovery for syt-unaware devices | expand

Commit Message

Takashi Sakamoto May 31, 2021, 2:51 a.m. UTC
This commit takes ALSA fireface driver to perform sequence replay for
media clock recovery.

The protocol specific to RME Fireface series is not compliant to
IEC 61883-1/6 since it has no CIP header, therefore presentation time
is not used for media clock recovery. The sequence of the number of data
blocks per packet is important.

I note that the device skips an isochronous cycle corresponding to an
empty packet or a NODATA packet in blocking transmission method of
IEC 61883-1/6. For sequence replay, the cycle is handled as receiving an
empty packet. Furthermore, it doesn't start packet transmission till
receiving any packet.

The sequence replay is tested with below models:

* Fireface 400
* Fireface 800
* Fireface 802

I note that it is better to initialize Fireface 400 in advance by
initialization transaction implemented in snd-fireface-ctl-service of
snd-firewire-ctl-services project. You can see whether initialized or
not by HOST LED on the device. Unless, the device often stops packet
transmission even if session starts.

I guess the sequence replay also works well with below models:

* Fireface UFX
* Fireface UCX

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/fireface/amdtp-ff.c  | 2 +-
 sound/firewire/fireface/ff-stream.c | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/sound/firewire/fireface/amdtp-ff.c b/sound/firewire/fireface/amdtp-ff.c
index 119c0076b17a..98177b0666d3 100644
--- a/sound/firewire/fireface/amdtp-ff.c
+++ b/sound/firewire/fireface/amdtp-ff.c
@@ -168,6 +168,6 @@  int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,
 	else
 		process_ctx_payloads = process_it_ctx_payloads;
 
-	return amdtp_stream_init(s, unit, dir, CIP_NO_HEADER, 0,
+	return amdtp_stream_init(s, unit, dir, CIP_BLOCKING | CIP_UNAWARE_SYT | CIP_NO_HEADER, 0,
 				 process_ctx_payloads, sizeof(struct amdtp_ff));
 }
diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c
index 97c356f2ac04..95bf405adb3d 100644
--- a/sound/firewire/fireface/ff-stream.c
+++ b/sound/firewire/fireface/ff-stream.c
@@ -199,7 +199,11 @@  int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
 		if (err < 0)
 			goto error;
 
-		err = amdtp_domain_start(&ff->domain, 0, false, false);
+		// NOTE: The device doesn't transfer packets unless receiving any packet. The
+		// sequence of tx packets includes cycle skip corresponding to empty packet or
+		// NODATA packet in IEC 61883-1/6. The sequence of the number of data blocks per
+		// packet is important for media clock recovery.
+		err = amdtp_domain_start(&ff->domain, 0, true, true);
 		if (err < 0)
 			goto error;