[alsa-devel] [PATCH 12/19] ALSA: fireworks: support AMDTP domain

Takashi Sakamoto o-takashi at sakamocchi.jp
Sun Aug 4 08:21:31 CEST 2019


This commit adds AMDTP domain support for ALSA fireworks driver.

Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
 sound/firewire/fireworks/fireworks.h        |  2 +
 sound/firewire/fireworks/fireworks_stream.c | 92 +++++++++++----------
 2 files changed, 51 insertions(+), 43 deletions(-)

diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h
index 31efd4b53b4f..4cda297f8438 100644
--- a/sound/firewire/fireworks/fireworks.h
+++ b/sound/firewire/fireworks/fireworks.h
@@ -107,6 +107,8 @@ struct snd_efw {
 	u8 *resp_buf;
 	u8 *pull_ptr;
 	u8 *push_ptr;
+
+	struct amdtp_domain domain;
 };
 
 int snd_efw_transaction_cmd(struct fw_unit *unit,
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index af340491dc43..f2de304d2f26 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -61,17 +61,6 @@ static int init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
 	return err;
 }
 
-static void
-stop_stream(struct snd_efw *efw, struct amdtp_stream *stream)
-{
-	amdtp_stream_stop(stream);
-
-	if (stream == &efw->tx_stream)
-		cmp_connection_break(&efw->out_conn);
-	else
-		cmp_connection_break(&efw->in_conn);
-}
-
 static int start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
 			unsigned int rate)
 {
@@ -89,19 +78,13 @@ static int start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
 		return err;
 
 	// Start amdtp stream.
-	err = amdtp_stream_start(stream, conn->resources.channel, conn->speed);
+	err = amdtp_domain_add_stream(&efw->domain, stream,
+				      conn->resources.channel, conn->speed);
 	if (err < 0) {
 		cmp_connection_break(conn);
 		return err;
 	}
 
-	// Wait first callback.
-	if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
-		amdtp_stream_stop(stream);
-		cmp_connection_break(conn);
-		return -ETIMEDOUT;
-	}
-
 	return 0;
 }
 
@@ -155,6 +138,13 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw)
 		return err;
 	}
 
+	err = amdtp_domain_init(&efw->domain);
+	if (err < 0) {
+		destroy_stream(efw, &efw->tx_stream);
+		destroy_stream(efw, &efw->rx_stream);
+		return err;
+	}
+
 	// set IEC61883 compliant mode (actually not fully compliant...).
 	err = snd_efw_command_set_tx_mode(efw, SND_EFW_TRANSPORT_MODE_IEC61883);
 	if (err < 0) {
@@ -209,8 +199,10 @@ int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate)
 	if (rate == 0)
 		rate = curr_rate;
 	if (rate != curr_rate) {
-		stop_stream(efw, &efw->tx_stream);
-		stop_stream(efw, &efw->rx_stream);
+		amdtp_domain_stop(&efw->domain);
+
+		cmp_connection_break(&efw->out_conn);
+		cmp_connection_break(&efw->in_conn);
 
 		cmp_connection_release(&efw->out_conn);
 		cmp_connection_release(&efw->in_conn);
@@ -250,47 +242,57 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw)
 	if (efw->substreams_counter == 0)
 		return -EIO;
 
-	err = snd_efw_command_get_sampling_rate(efw, &rate);
-	if (err < 0)
-		return err;
-
 	if (amdtp_streaming_error(&efw->rx_stream) ||
 	    amdtp_streaming_error(&efw->tx_stream)) {
-		stop_stream(efw, &efw->rx_stream);
-		stop_stream(efw, &efw->tx_stream);
+		amdtp_domain_stop(&efw->domain);
+		cmp_connection_break(&efw->out_conn);
+		cmp_connection_break(&efw->in_conn);
 	}
 
-	/* master should be always running */
+	err = snd_efw_command_get_sampling_rate(efw, &rate);
+	if (err < 0)
+		return err;
+
 	if (!amdtp_stream_running(&efw->rx_stream)) {
 		err = start_stream(efw, &efw->rx_stream, rate);
-		if (err < 0) {
-			dev_err(&efw->unit->device,
-				"fail to start AMDTP master stream:%d\n", err);
+		if (err < 0)
 			goto error;
-		}
-	}
 
-	if (!amdtp_stream_running(&efw->tx_stream)) {
 		err = start_stream(efw, &efw->tx_stream, rate);
-		if (err < 0) {
-			dev_err(&efw->unit->device,
-				"fail to start AMDTP slave stream:%d\n", err);
+		if (err < 0)
+			goto error;
+
+		err = amdtp_domain_start(&efw->domain);
+		if (err < 0)
+			goto error;
+
+		// Wait first callback.
+		if (!amdtp_stream_wait_callback(&efw->rx_stream,
+						CALLBACK_TIMEOUT) ||
+		    !amdtp_stream_wait_callback(&efw->tx_stream,
+						CALLBACK_TIMEOUT)) {
+			err = -ETIMEDOUT;
 			goto error;
 		}
 	}
 
 	return 0;
 error:
-	stop_stream(efw, &efw->rx_stream);
-	stop_stream(efw, &efw->tx_stream);
+	amdtp_domain_stop(&efw->domain);
+
+	cmp_connection_break(&efw->out_conn);
+	cmp_connection_break(&efw->in_conn);
+
 	return err;
 }
 
 void snd_efw_stream_stop_duplex(struct snd_efw *efw)
 {
 	if (efw->substreams_counter == 0) {
-		stop_stream(efw, &efw->tx_stream);
-		stop_stream(efw, &efw->rx_stream);
+		amdtp_domain_stop(&efw->domain);
+
+		cmp_connection_break(&efw->out_conn);
+		cmp_connection_break(&efw->in_conn);
 
 		cmp_connection_release(&efw->out_conn);
 		cmp_connection_release(&efw->in_conn);
@@ -299,8 +301,10 @@ void snd_efw_stream_stop_duplex(struct snd_efw *efw)
 
 void snd_efw_stream_update_duplex(struct snd_efw *efw)
 {
-	stop_stream(efw, &efw->rx_stream);
-	stop_stream(efw, &efw->tx_stream);
+	amdtp_domain_stop(&efw->domain);
+
+	cmp_connection_break(&efw->out_conn);
+	cmp_connection_break(&efw->in_conn);
 
 	amdtp_stream_pcm_abort(&efw->rx_stream);
 	amdtp_stream_pcm_abort(&efw->tx_stream);
@@ -308,6 +312,8 @@ void snd_efw_stream_update_duplex(struct snd_efw *efw)
 
 void snd_efw_stream_destroy_duplex(struct snd_efw *efw)
 {
+	amdtp_domain_destroy(&efw->domain);
+
 	destroy_stream(efw, &efw->rx_stream);
 	destroy_stream(efw, &efw->tx_stream);
 }
-- 
2.20.1



More information about the Alsa-devel mailing list