ALSA: oxfw: configure stream parameter in pcm.hw_params callback
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Wed, 12 Jun 2019 08:44:22 +0000 (17:44 +0900)
committerTakashi Iwai <tiwai@suse.de>
Wed, 12 Jun 2019 13:27:01 +0000 (15:27 +0200)
This commit is a part of preparation to perform allocation/release
of isochronous resources in pcm.hw_params/hw_free callbacks.

This commit splits out an operation to configure stream parameters into
pcm.hw_params callback. In pcm.prepare callback, establishing
connections and start isochronous contexts.

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

index 373154d8ee0e23779dd1bc80d0ac87bec4f385fa..837733f10736a0ab14b78000b34a000914cfee66 100644 (file)
@@ -103,51 +103,13 @@ static int set_stream_format(struct snd_oxfw *oxfw, struct amdtp_stream *s,
 
 static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
 {
-       u8 **formats;
-       enum avc_general_plug_dir dir;
        struct cmp_connection *conn;
-       struct snd_oxfw_stream_formation formation;
-       int i;
        int err;
 
-       if (stream == &oxfw->rx_stream) {
-               dir = AVC_GENERAL_PLUG_DIR_IN;
-               formats = oxfw->rx_stream_formats;
+       if (stream == &oxfw->rx_stream)
                conn = &oxfw->in_conn;
-       } else {
-               dir = AVC_GENERAL_PLUG_DIR_OUT;
-               formats = oxfw->tx_stream_formats;
+       else
                conn = &oxfw->out_conn;
-       }
-
-       err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
-       if (err < 0)
-               return err;
-
-       for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
-               struct snd_oxfw_stream_formation fmt;
-
-               if (formats[i] == NULL)
-                       break;
-
-               err = snd_oxfw_stream_parse_format(formats[i], &fmt);
-               if (err < 0)
-                       return err;
-               if (fmt.rate == formation.rate && fmt.pcm == formation.pcm &&
-                   fmt.midi == formation.midi)
-                       break;
-       }
-       if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
-               return -EINVAL;
-
-       // The stream should have one pcm channels at least.
-       if (formation.pcm == 0)
-               return -EINVAL;
-
-       err = amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
-                                        formation.midi * 8, false);
-       if (err < 0)
-               return err;
 
        err = cmp_connection_establish(conn,
                                       amdtp_stream_get_max_payload(stream));
@@ -236,6 +198,51 @@ static int init_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
        return 0;
 }
 
+static int keep_resources(struct snd_oxfw *oxfw, struct amdtp_stream *stream)
+{
+       enum avc_general_plug_dir dir;
+       u8 **formats;
+       struct snd_oxfw_stream_formation formation;
+       int i;
+       int err;
+
+       if (stream == &oxfw->rx_stream) {
+               dir = AVC_GENERAL_PLUG_DIR_IN;
+               formats = oxfw->rx_stream_formats;
+       } else {
+               dir = AVC_GENERAL_PLUG_DIR_OUT;
+               formats = oxfw->tx_stream_formats;
+       }
+
+       err = snd_oxfw_stream_get_current_formation(oxfw, dir, &formation);
+       if (err < 0)
+               return err;
+
+       for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
+               struct snd_oxfw_stream_formation fmt;
+
+               if (formats[i] == NULL)
+                       break;
+
+               err = snd_oxfw_stream_parse_format(formats[i], &fmt);
+               if (err < 0)
+                       return err;
+
+               if (fmt.rate == formation.rate && fmt.pcm == formation.pcm &&
+                   fmt.midi == formation.midi)
+                       break;
+       }
+       if (i == SND_OXFW_STREAM_FORMAT_ENTRIES)
+               return -EINVAL;
+
+       // The stream should have one pcm channels at least.
+       if (formation.pcm == 0)
+               return -EINVAL;
+
+       return amdtp_am824_set_parameters(stream, formation.rate, formation.pcm,
+                                        formation.midi * 8, false);
+}
+
 int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
                                   struct amdtp_stream *stream,
                                   unsigned int rate, unsigned int pcm_channels)
@@ -285,6 +292,16 @@ int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
                                "fail to set stream format: %d\n", err);
                        return err;
                }
+
+               err = keep_resources(oxfw, &oxfw->rx_stream);
+               if (err < 0)
+                       return err;
+
+               if (oxfw->has_output) {
+                       err = keep_resources(oxfw, &oxfw->tx_stream);
+                       if (err < 0)
+                               return err;
+               }
        }
 
        return 0;