ALSA: fireface: support AMDTP domain
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 4 Aug 2019 06:21:37 +0000 (15:21 +0900)
committerTakashi Iwai <tiwai@suse.de>
Mon, 5 Aug 2019 17:57:28 +0000 (19:57 +0200)
This commit adds AMDTP domain support for ALSA fireface driver.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/fireface/ff-stream.c
sound/firewire/fireface/ff.h

index e4710204f4817f99b6d6441a99f7c6823fc92a66..e8e6f9fd64339d2becc5d68888d6772cd411b3b6 100644 (file)
@@ -32,9 +32,6 @@ int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc,
 
 static inline void finish_session(struct snd_ff *ff)
 {
-       amdtp_stream_stop(&ff->tx_stream);
-       amdtp_stream_stop(&ff->rx_stream);
-
        ff->spec->protocol->finish_session(ff);
        ff->spec->protocol->switch_fetching_mode(ff, false);
 }
@@ -83,8 +80,16 @@ int snd_ff_stream_init_duplex(struct snd_ff *ff)
                return err;
 
        err = init_stream(ff, &ff->tx_stream);
-       if (err < 0)
+       if (err < 0) {
                destroy_stream(ff, &ff->rx_stream);
+               return err;
+       }
+
+       err = amdtp_domain_init(&ff->domain);
+       if (err < 0) {
+               destroy_stream(ff, &ff->rx_stream);
+               destroy_stream(ff, &ff->tx_stream);
+       }
 
        return err;
 }
@@ -95,6 +100,8 @@ int snd_ff_stream_init_duplex(struct snd_ff *ff)
  */
 void snd_ff_stream_destroy_duplex(struct snd_ff *ff)
 {
+       amdtp_domain_destroy(&ff->domain);
+
        destroy_stream(ff, &ff->rx_stream);
        destroy_stream(ff, &ff->tx_stream);
 }
@@ -113,6 +120,7 @@ int snd_ff_stream_reserve_duplex(struct snd_ff *ff, unsigned int rate)
                enum snd_ff_stream_mode mode;
                int i;
 
+               amdtp_domain_stop(&ff->domain);
                finish_session(ff);
 
                fw_iso_resources_free(&ff->tx_resources);
@@ -155,51 +163,52 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
                return 0;
 
        if (amdtp_streaming_error(&ff->tx_stream) ||
-           amdtp_streaming_error(&ff->rx_stream))
+           amdtp_streaming_error(&ff->rx_stream)) {
+               amdtp_domain_stop(&ff->domain);
                finish_session(ff);
+       }
 
        /*
         * Regardless of current source of clock signal, drivers transfer some
         * packets. Then, the device transfers packets.
         */
        if (!amdtp_stream_running(&ff->rx_stream)) {
+               int spd = fw_parent_device(ff->unit)->max_speed;
+
                err = ff->spec->protocol->begin_session(ff, rate);
                if (err < 0)
                        goto error;
 
-               err = amdtp_stream_start(&ff->rx_stream,
-                                        ff->rx_resources.channel,
-                                        fw_parent_device(ff->unit)->max_speed);
+               err = amdtp_domain_add_stream(&ff->domain, &ff->rx_stream,
+                                             ff->rx_resources.channel, spd);
                if (err < 0)
                        goto error;
 
-               if (!amdtp_stream_wait_callback(&ff->rx_stream,
-                                               CALLBACK_TIMEOUT_MS)) {
-                       err = -ETIMEDOUT;
-                       goto error;
-               }
-
-               err = ff->spec->protocol->switch_fetching_mode(ff, true);
+               err = amdtp_domain_add_stream(&ff->domain, &ff->tx_stream,
+                                             ff->tx_resources.channel, spd);
                if (err < 0)
                        goto error;
-       }
 
-       if (!amdtp_stream_running(&ff->tx_stream)) {
-               err = amdtp_stream_start(&ff->tx_stream,
-                                        ff->tx_resources.channel,
-                                        fw_parent_device(ff->unit)->max_speed);
+               err = amdtp_domain_start(&ff->domain);
                if (err < 0)
                        goto error;
 
-               if (!amdtp_stream_wait_callback(&ff->tx_stream,
+               if (!amdtp_stream_wait_callback(&ff->rx_stream,
+                                               CALLBACK_TIMEOUT_MS) ||
+                   !amdtp_stream_wait_callback(&ff->tx_stream,
                                                CALLBACK_TIMEOUT_MS)) {
                        err = -ETIMEDOUT;
                        goto error;
                }
+
+               err = ff->spec->protocol->switch_fetching_mode(ff, true);
+               if (err < 0)
+                       goto error;
        }
 
        return 0;
 error:
+       amdtp_domain_stop(&ff->domain);
        finish_session(ff);
 
        return err;
@@ -208,6 +217,7 @@ error:
 void snd_ff_stream_stop_duplex(struct snd_ff *ff)
 {
        if (ff->substreams_counter == 0) {
+               amdtp_domain_stop(&ff->domain);
                finish_session(ff);
 
                fw_iso_resources_free(&ff->tx_resources);
@@ -217,12 +227,11 @@ void snd_ff_stream_stop_duplex(struct snd_ff *ff)
 
 void snd_ff_stream_update_duplex(struct snd_ff *ff)
 {
+       amdtp_domain_stop(&ff->domain);
+
        // The device discontinue to transfer packets.
        amdtp_stream_pcm_abort(&ff->tx_stream);
-       amdtp_stream_stop(&ff->tx_stream);
-
        amdtp_stream_pcm_abort(&ff->rx_stream);
-       amdtp_stream_stop(&ff->rx_stream);
 }
 
 void snd_ff_stream_lock_changed(struct snd_ff *ff)
index 36dd0c75b9f713c5dace547a8de358240d44dfa9..b4c22ca6079ee41bef2a8f6f34fe712bb15e9ede 100644 (file)
@@ -91,6 +91,8 @@ struct snd_ff {
        int dev_lock_count;
        bool dev_lock_changed;
        wait_queue_head_t hwdep_wait;
+
+       struct amdtp_domain domain;
 };
 
 enum snd_ff_clock_src {