summary refs log tree commit diff
path: root/sound/firewire/tascam
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2019-08-04 15:21:35 +0900
committerTakashi Iwai <tiwai@suse.de>2019-08-05 19:57:27 +0200
commitc281d46a51e31703183aa66ed9315446a0a10953 (patch)
tree09b01c49150ce0c58ed5e5f122edb72bce804946 /sound/firewire/tascam
parent9a08067ec318cbeaf0caa2d104cf677e723e02a3 (diff)
downloadlinux-c281d46a51e31703183aa66ed9315446a0a10953.tar.gz
ALSA: firewire-tascam: support AMDTP domain
This commit adds AMDTP domain support for ALSA firewire-tascam driver.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/tascam')
-rw-r--r--sound/firewire/tascam/tascam-stream.c54
-rw-r--r--sound/firewire/tascam/tascam.h2
2 files changed, 34 insertions, 22 deletions
diff --git a/sound/firewire/tascam/tascam-stream.c b/sound/firewire/tascam/tascam-stream.c
index d5e77036e0ee..9e2dc2fe3271 100644
--- a/sound/firewire/tascam/tascam-stream.c
+++ b/sound/firewire/tascam/tascam-stream.c
@@ -180,9 +180,6 @@ static void finish_session(struct snd_tscm *tscm)
 {
 	__be32 reg;
 
-	amdtp_stream_stop(&tscm->rx_stream);
-	amdtp_stream_stop(&tscm->tx_stream);
-
 	reg = 0;
 	snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
 			   TSCM_ADDR_BASE + TSCM_OFFSET_START_STREAMING,
@@ -339,8 +336,16 @@ int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
 		return err;
 
 	err = init_stream(tscm, &tscm->rx_stream);
-	if (err < 0)
+	if (err < 0) {
+		destroy_stream(tscm, &tscm->tx_stream);
+		return err;
+	}
+
+	err = amdtp_domain_init(&tscm->domain);
+	if (err < 0) {
 		destroy_stream(tscm, &tscm->tx_stream);
+		destroy_stream(tscm, &tscm->rx_stream);
+	}
 
 	return err;
 }
@@ -348,17 +353,18 @@ int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
 // At bus reset, streaming is stopped and some registers are clear.
 void snd_tscm_stream_update_duplex(struct snd_tscm *tscm)
 {
-	amdtp_stream_pcm_abort(&tscm->tx_stream);
-	amdtp_stream_stop(&tscm->tx_stream);
+	amdtp_domain_stop(&tscm->domain);
 
+	amdtp_stream_pcm_abort(&tscm->tx_stream);
 	amdtp_stream_pcm_abort(&tscm->rx_stream);
-	amdtp_stream_stop(&tscm->rx_stream);
 }
 
 // This function should be called before starting streams or after stopping
 // streams.
 void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm)
 {
+	amdtp_domain_destroy(&tscm->domain);
+
 	destroy_stream(tscm, &tscm->rx_stream);
 	destroy_stream(tscm, &tscm->tx_stream);
 }
@@ -373,6 +379,8 @@ int snd_tscm_stream_reserve_duplex(struct snd_tscm *tscm, unsigned int rate)
 		return err;
 
 	if (tscm->substreams_counter == 0 || rate != curr_rate) {
+		amdtp_domain_stop(&tscm->domain);
+
 		finish_session(tscm);
 
 		fw_iso_resources_free(&tscm->tx_resources);
@@ -405,8 +413,10 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
 		return 0;
 
 	if (amdtp_streaming_error(&tscm->rx_stream) ||
-	    amdtp_streaming_error(&tscm->tx_stream))
+	    amdtp_streaming_error(&tscm->tx_stream)) {
+		amdtp_domain_stop(&tscm->domain);
 		finish_session(tscm);
+	}
 
 	if (generation != fw_parent_device(tscm->unit)->card->generation) {
 		err = fw_iso_resources_update(&tscm->tx_resources);
@@ -419,6 +429,8 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
 	}
 
 	if (!amdtp_stream_running(&tscm->rx_stream)) {
+		int spd = fw_parent_device(tscm->unit)->max_speed;
+
 		err = set_stream_formats(tscm, rate);
 		if (err < 0)
 			goto error;
@@ -427,27 +439,23 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
 		if (err < 0)
 			goto error;
 
-		err = amdtp_stream_start(&tscm->rx_stream,
-				tscm->rx_resources.channel,
-				fw_parent_device(tscm->unit)->max_speed);
+		err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream,
+					      tscm->rx_resources.channel, spd);
 		if (err < 0)
 			goto error;
 
-		if (!amdtp_stream_wait_callback(&tscm->rx_stream,
-						CALLBACK_TIMEOUT)) {
-			err = -ETIMEDOUT;
+		err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream,
+					      tscm->tx_resources.channel, spd);
+		if (err < 0)
 			goto error;
-		}
-	}
 
-	if (!amdtp_stream_running(&tscm->tx_stream)) {
-		err = amdtp_stream_start(&tscm->tx_stream,
-				tscm->tx_resources.channel,
-				fw_parent_device(tscm->unit)->max_speed);
+		err = amdtp_domain_start(&tscm->domain);
 		if (err < 0)
-			goto error;
+			return err;
 
-		if (!amdtp_stream_wait_callback(&tscm->tx_stream,
+		if (!amdtp_stream_wait_callback(&tscm->rx_stream,
+						CALLBACK_TIMEOUT) ||
+		    !amdtp_stream_wait_callback(&tscm->tx_stream,
 						CALLBACK_TIMEOUT)) {
 			err = -ETIMEDOUT;
 			goto error;
@@ -456,6 +464,7 @@ int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate)
 
 	return 0;
 error:
+	amdtp_domain_stop(&tscm->domain);
 	finish_session(tscm);
 
 	return err;
@@ -464,6 +473,7 @@ error:
 void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm)
 {
 	if (tscm->substreams_counter == 0) {
+		amdtp_domain_stop(&tscm->domain);
 		finish_session(tscm);
 
 		fw_iso_resources_free(&tscm->tx_resources);
diff --git a/sound/firewire/tascam/tascam.h b/sound/firewire/tascam/tascam.h
index 734e5bb9c3da..64a2e4d2bbfe 100644
--- a/sound/firewire/tascam/tascam.h
+++ b/sound/firewire/tascam/tascam.h
@@ -97,6 +97,8 @@ struct snd_tscm {
 	struct snd_firewire_tascam_change queue[SND_TSCM_QUEUE_COUNT];
 	unsigned int pull_pos;
 	unsigned int push_pos;
+
+	struct amdtp_domain domain;
 };
 
 #define TSCM_ADDR_BASE			0xffff00000000ull