All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
To: tiwai@suse.de
Cc: alsa-devel@alsa-project.org, clemens@ladisch.de
Subject: [PATCH 3/3] ALSA: firewire-lib: transfer rx packets on-the-fly when replaying
Date: Thu, 27 May 2021 21:26:11 +0900	[thread overview]
Message-ID: <20210527122611.173711-4-o-takashi@sakamocchi.jp> (raw)
In-Reply-To: <20210527122611.173711-1-o-takashi@sakamocchi.jp>

Models in below series start transmission of packet after receiving the
sequence of packets:

 * Digidesign Digi00x family
 * RME Fireface series

Additionally, models in Tascam FireWire series start multiplexing PCM
frames into packets enough after receiving packets. It's required to
transfer packets on-the-fly for the above models according to nominal
sampling transfer frequency before starting sequence replay.

This commit allows drivers to decide whether the engine transfers packet
on-the-fly or not.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/amdtp-stream.c               | 27 +++++++++++++++++----
 sound/firewire/amdtp-stream.h               |  6 +++--
 sound/firewire/bebob/bebob_stream.c         |  2 +-
 sound/firewire/dice/dice-stream.c           |  2 +-
 sound/firewire/digi00x/digi00x-stream.c     |  2 +-
 sound/firewire/fireface/ff-stream.c         |  2 +-
 sound/firewire/fireworks/fireworks_stream.c |  2 +-
 sound/firewire/motu/motu-stream.c           |  2 +-
 sound/firewire/oxfw/oxfw-stream.c           |  2 +-
 sound/firewire/tascam/tascam-stream.c       |  2 +-
 10 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 47ea03370858..d0e9b417c019 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -577,10 +577,23 @@ static void pool_seq_descs(struct amdtp_stream *s, unsigned int count)
 {
 	struct amdtp_domain *d = s->domain;
 
-	if (!d->replay.enable || !s->ctx_data.rx.replay_target)
+	if (!d->replay.enable || !s->ctx_data.rx.replay_target) {
 		pool_ideal_seq_descs(s, count);
-	else
-		pool_replayed_seq(s, count);
+	} else {
+		if (!d->replay.on_the_fly) {
+			pool_replayed_seq(s, count);
+		} else {
+			struct amdtp_stream *tx = s->ctx_data.rx.replay_target;
+			const unsigned int cache_size = tx->ctx_data.tx.cache.size;
+			const unsigned int cache_head = s->ctx_data.rx.cache_head;
+			unsigned int cached_cycles = calculate_cached_cycle_count(tx, cache_head);
+
+			if (cached_cycles > count && cached_cycles > cache_size / 2)
+				pool_replayed_seq(s, count);
+			else
+				pool_ideal_seq_descs(s, count);
+		}
+	}
 }
 
 static void update_pcm_pointers(struct amdtp_stream *s,
@@ -1444,7 +1457,7 @@ static void irq_target_callback_skip(struct fw_iso_context *context, u32 tstamp,
 	skip_rx_packets(context, tstamp, header_length, header, private_data);
 	process_ctxs_in_domain(d);
 
-	if (d->replay.enable) {
+	if (d->replay.enable && !d->replay.on_the_fly) {
 		unsigned int rx_count = 0;
 		unsigned int rx_ready_count = 0;
 		struct amdtp_stream *rx;
@@ -1929,8 +1942,11 @@ static int make_association(struct amdtp_domain *d)
  *			 contexts.
  * @replay_seq: whether to replay the sequence of packet in IR context for the sequence of packet in
  *		IT context.
+ * @replay_on_the_fly: transfer rx packets according to nominal frequency, then begin to replay
+ *		       according to arrival of events in tx packets.
  */
-int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq)
+int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq,
+		       bool replay_on_the_fly)
 {
 	unsigned int events_per_buffer = d->events_per_buffer;
 	unsigned int events_per_period = d->events_per_period;
@@ -1944,6 +1960,7 @@ int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles,
 			return err;
 	}
 	d->replay.enable = replay_seq;
+	d->replay.on_the_fly = replay_on_the_fly;
 
 	// Select an IT context as IRQ target.
 	list_for_each_entry(s, &d->streams, list) {
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index 61b6b5ae8b3b..b25592d5f6af 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -303,7 +303,8 @@ struct amdtp_domain {
 	} processing_cycle;
 
 	struct {
-		bool enable;
+		bool enable:1;
+		bool on_the_fly:1;
 	} replay;
 };
 
@@ -313,7 +314,8 @@ void amdtp_domain_destroy(struct amdtp_domain *d);
 int amdtp_domain_add_stream(struct amdtp_domain *d, struct amdtp_stream *s,
 			    int channel, int speed);
 
-int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq);
+int amdtp_domain_start(struct amdtp_domain *d, unsigned int tx_init_skip_cycles, bool replay_seq,
+		       bool replay_on_the_fly);
 void amdtp_domain_stop(struct amdtp_domain *d);
 
 static inline int amdtp_domain_set_events_per_period(struct amdtp_domain *d,
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
index fb776f871133..47773ca97e46 100644
--- a/sound/firewire/bebob/bebob_stream.c
+++ b/sound/firewire/bebob/bebob_stream.c
@@ -652,7 +652,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob)
 		// MEMO: In the early stage of packet streaming, the device transfers NODATA packets.
 		// After several hundred cycles, it begins to multiplex event into the packet with
 		// syt information.
-		err = amdtp_domain_start(&bebob->domain, tx_init_skip_cycles, false);
+		err = amdtp_domain_start(&bebob->domain, tx_init_skip_cycles, false, false);
 		if (err < 0)
 			goto error;
 
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index 064f28f1822b..0fb8b4ae6a0a 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -459,7 +459,7 @@ int snd_dice_stream_start_duplex(struct snd_dice *dice)
 			goto error;
 		}
 
-		err = amdtp_domain_start(&dice->domain, 0, false);
+		err = amdtp_domain_start(&dice->domain, 0, false, false);
 		if (err < 0)
 			goto error;
 
diff --git a/sound/firewire/digi00x/digi00x-stream.c b/sound/firewire/digi00x/digi00x-stream.c
index 5daba75a5bf3..2019f6533477 100644
--- a/sound/firewire/digi00x/digi00x-stream.c
+++ b/sound/firewire/digi00x/digi00x-stream.c
@@ -375,7 +375,7 @@ int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x)
 		if (err < 0)
 			goto error;
 
-		err = amdtp_domain_start(&dg00x->domain, 0, false);
+		err = amdtp_domain_start(&dg00x->domain, 0, false, false);
 		if (err < 0)
 			goto error;
 
diff --git a/sound/firewire/fireface/ff-stream.c b/sound/firewire/fireface/ff-stream.c
index 12779e7caf22..97c356f2ac04 100644
--- a/sound/firewire/fireface/ff-stream.c
+++ b/sound/firewire/fireface/ff-stream.c
@@ -199,7 +199,7 @@ 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);
+		err = amdtp_domain_start(&ff->domain, 0, false, false);
 		if (err < 0)
 			goto error;
 
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index 0106fa6d1eaf..6fc117c3a068 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -272,7 +272,7 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw)
 		if (err < 0)
 			goto error;
 
-		err = amdtp_domain_start(&efw->domain, 0, false);
+		err = amdtp_domain_start(&efw->domain, 0, false, false);
 		if (err < 0)
 			goto error;
 
diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c
index 5af9d7487cdc..5d8d067f366d 100644
--- a/sound/firewire/motu/motu-stream.c
+++ b/sound/firewire/motu/motu-stream.c
@@ -260,7 +260,7 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu)
 		if (err < 0)
 			goto stop_streams;
 
-		err = amdtp_domain_start(&motu->domain, 0, false);
+		err = amdtp_domain_start(&motu->domain, 0, false, false);
 		if (err < 0)
 			goto stop_streams;
 
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c
index a6e97a37f129..9792d4b4373c 100644
--- a/sound/firewire/oxfw/oxfw-stream.c
+++ b/sound/firewire/oxfw/oxfw-stream.c
@@ -354,7 +354,7 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw)
 			}
 		}
 
-		err = amdtp_domain_start(&oxfw->domain, 0, false);
+		err = amdtp_domain_start(&oxfw->domain, 0, false, false);
 		if (err < 0)
 			goto error;
 
diff --git a/sound/firewire/tascam/tascam-stream.c b/sound/firewire/tascam/tascam-stream.c
index eb4c7c47f8e9..4811b60e5823 100644
--- a/sound/firewire/tascam/tascam-stream.c
+++ b/sound/firewire/tascam/tascam-stream.c
@@ -473,7 +473,7 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
 		if (err < 0)
 			goto error;
 
-		err = amdtp_domain_start(&tscm->domain, 0, false);
+		err = amdtp_domain_start(&tscm->domain, 0, false, false);
 		if (err < 0)
 			return err;
 
-- 
2.27.0


  parent reply	other threads:[~2021-05-27 12:28 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-27 12:26 [PATCH 0/3] ALSA: firewire-lib: preparation for media clock recovery Takashi Sakamoto
2021-05-27 12:26 ` [PATCH 1/3] ALSA: firewire-lib: add replay target to cache sequence of packet Takashi Sakamoto
2021-05-27 12:26 ` [PATCH 2/3] ALSA: firewire-lib: replay sequence of incoming packets for outgoing packets Takashi Sakamoto
2021-05-27 12:26 ` Takashi Sakamoto [this message]
2021-05-28  9:08 ` [PATCH 0/3] ALSA: firewire-lib: preparation for media clock recovery Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210527122611.173711-4-o-takashi@sakamocchi.jp \
    --to=o-takashi@sakamocchi.jp \
    --cc=alsa-devel@alsa-project.org \
    --cc=clemens@ladisch.de \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.