diff mbox series

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

Message ID 20210531025103.17880-3-o-takashi@sakamocchi.jp (mailing list archive)
State New, archived
Headers show
Series ALSA: firewire: media clock recovery for syt-unaware devices | expand

Commit Message

Takashi Sakamoto May 31, 2021, 2:50 a.m. UTC
Echo Digital Audio Corporation had US patent US7599388B2 titled as
'System and method for high-bandwidth serial bus data transfer'. In the
patent, dual-banked shared memory is used to deliver data between
serial bus transmission and processor in FIFO way. The patent seems to be
used for Fireworks board module. The mechanism is not compliant to
synchronization based on presentation time expressed in syt field
of CIP header. Fireworks board module takes care of the sequence of
the number of data blocks per packet and just ignores the value of syt
field.

This commit takes fireworks driver to performs sequence replay for media
clock recovery. As long as I tested, Audiofire 2 and 4 have a quirk to
skip an isochronous cycle several thousands after starting packet
transmission.

The sequence replay is tested with below models:
 * Loud Technology Mackie 400f
 * Echo Audio Audiofire 12 (DSP model)
 * Echo Audio Audiofire 12 (FPGA model)
 * Echo Audio Audiofire 8 (DSP model)
 * Echo Audio Audiofire 8 (FPGA model)
 * Echo Audio Audiofire Pre8
 * Echo Audio Audiofire 4
 * Echo Audio Audiofire 2

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/fireworks/fireworks_stream.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index 6fc117c3a068..ac66f08acd6b 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -6,7 +6,7 @@ 
  */
 #include "./fireworks.h"
 
-#define READY_TIMEOUT_MS	100
+#define READY_TIMEOUT_MS	1000
 
 static int init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
 {
@@ -29,7 +29,7 @@  static int init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
 	if (err < 0)
 		return err;
 
-	err = amdtp_am824_init(stream, efw->unit, s_dir, CIP_BLOCKING);
+	err = amdtp_am824_init(stream, efw->unit, s_dir, CIP_BLOCKING | CIP_UNAWARE_SYT);
 	if (err < 0) {
 		amdtp_stream_destroy(stream);
 		cmp_connection_destroy(conn);
@@ -264,6 +264,15 @@  int snd_efw_stream_start_duplex(struct snd_efw *efw)
 		return err;
 
 	if (!amdtp_stream_running(&efw->rx_stream)) {
+		unsigned int tx_init_skip_cycles;
+
+		// Audiofire 2/4 skip an isochronous cycle several thousands after starting
+		// packet transmission.
+		if (efw->is_fireworks3 && !efw->is_af9)
+			tx_init_skip_cycles = 6000;
+		else
+			tx_init_skip_cycles = 0;
+
 		err = start_stream(efw, &efw->rx_stream, rate);
 		if (err < 0)
 			goto error;
@@ -272,7 +281,10 @@  int snd_efw_stream_start_duplex(struct snd_efw *efw)
 		if (err < 0)
 			goto error;
 
-		err = amdtp_domain_start(&efw->domain, 0, false, false);
+		// NOTE: The device ignores presentation time expressed by the value of syt field
+		// of CIP header in received packets. The sequence of the number of data blocks per
+		// packet is important for media clock recovery.
+		err = amdtp_domain_start(&efw->domain, tx_init_skip_cycles, true, false);
 		if (err < 0)
 			goto error;