OSDN Git Service

ALSA: fireface: allocate isochronous resources in mode-specific implementation
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 16 Dec 2018 08:32:31 +0000 (17:32 +0900)
committerTakashi Iwai <tiwai@suse.de>
Sun, 16 Dec 2018 09:18:27 +0000 (10:18 +0100)
The way to maintain isochronous resources on bus is different between
Fireface 400/800.

This commit is a preparation. This commit moves a function to allocate resource to
model-dependent implementation.

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

index 3740095..2280fab 100644 (file)
 #define FF400_TX_PACKET_FORMAT 0x00008010050cull
 #define FF400_ISOC_COMM_STOP   0x000080100510ull
 
-static int ff400_begin_session(struct snd_ff *ff, unsigned int rate)
+/*
+ * Fireface 400 manages isochronous channel number in 3 bit field. Therefore,
+ * we can allocate between 0 and 7 channel.
+ */
+static int keep_resources(struct snd_ff *ff, unsigned int rate)
 {
-       __le32 reg;
-       int i, err;
+       enum snd_ff_stream_mode mode;
+       int i;
+       int err;
 
-       /* Check whether the given value is supported or not. */
+       // Check whether the given value is supported or not.
        for (i = 0; i < CIP_SFC_COUNT; i++) {
                if (amdtp_rate_table[i] == rate)
                        break;
        }
-       if (i == CIP_SFC_COUNT)
+       if (i >= CIP_SFC_COUNT)
                return -EINVAL;
 
+       err = snd_ff_stream_get_multiplier_mode(i, &mode);
+       if (err < 0)
+               return err;
+
+       /* Keep resources for in-stream. */
+       ff->tx_resources.channels_mask = 0x00000000000000ffuLL;
+       err = fw_iso_resources_allocate(&ff->tx_resources,
+                       amdtp_stream_get_max_payload(&ff->tx_stream),
+                       fw_parent_device(ff->unit)->max_speed);
+       if (err < 0)
+               return err;
+
+       /* Keep resources for out-stream. */
+       err = amdtp_ff_set_parameters(&ff->rx_stream, rate,
+                                     ff->spec->pcm_playback_channels[mode]);
+       if (err < 0)
+               return err;
+       ff->rx_resources.channels_mask = 0x00000000000000ffuLL;
+       err = fw_iso_resources_allocate(&ff->rx_resources,
+                       amdtp_stream_get_max_payload(&ff->rx_stream),
+                       fw_parent_device(ff->unit)->max_speed);
+       if (err < 0)
+               fw_iso_resources_free(&ff->tx_resources);
+
+       return err;
+}
+
+static int ff400_begin_session(struct snd_ff *ff, unsigned int rate)
+{
+       __le32 reg;
+       int err;
+
+       err = keep_resources(ff, rate);
+       if (err < 0)
+               return err;
+
        /* Set the number of data blocks transferred in a second. */
        reg = cpu_to_le32(rate);
        err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
index e6a8229..a490e45 100644 (file)
@@ -31,54 +31,6 @@ int snd_ff_stream_get_multiplier_mode(enum cip_sfc sfc,
        return 0;
 }
 
-/*
- * Fireface 400 manages isochronous channel number in 3 bit field. Therefore,
- * we can allocate between 0 and 7 channel.
- */
-static int keep_resources(struct snd_ff *ff, unsigned int rate)
-{
-       enum snd_ff_stream_mode mode;
-       int i;
-       int err;
-
-       for (i = 0; i < CIP_SFC_COUNT; ++i) {
-               if (amdtp_rate_table[i] == rate)
-                       break;
-       }
-       if (i == CIP_SFC_COUNT)
-               return -EINVAL;
-
-       err = snd_ff_stream_get_multiplier_mode(i, &mode);
-       if (err < 0)
-               return err;
-
-       /* Keep resources for in-stream. */
-       err = amdtp_ff_set_parameters(&ff->tx_stream, rate,
-                                     ff->spec->pcm_capture_channels[mode]);
-       if (err < 0)
-               return err;
-       ff->tx_resources.channels_mask = 0x00000000000000ffuLL;
-       err = fw_iso_resources_allocate(&ff->tx_resources,
-                       amdtp_stream_get_max_payload(&ff->tx_stream),
-                       fw_parent_device(ff->unit)->max_speed);
-       if (err < 0)
-               return err;
-
-       /* Keep resources for out-stream. */
-       err = amdtp_ff_set_parameters(&ff->rx_stream, rate,
-                                     ff->spec->pcm_playback_channels[mode]);
-       if (err < 0)
-               return err;
-       ff->rx_resources.channels_mask = 0x00000000000000ffuLL;
-       err = fw_iso_resources_allocate(&ff->rx_resources,
-                       amdtp_stream_get_max_payload(&ff->rx_stream),
-                       fw_parent_device(ff->unit)->max_speed);
-       if (err < 0)
-               fw_iso_resources_free(&ff->tx_resources);
-
-       return err;
-}
-
 static void release_resources(struct snd_ff *ff)
 {
        fw_iso_resources_free(&ff->tx_resources);
@@ -214,9 +166,29 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
         * packets. Then, the device transfers packets.
         */
        if (!amdtp_stream_running(&ff->rx_stream)) {
-               err = keep_resources(ff, rate);
+               enum snd_ff_stream_mode mode;
+               int i;
+
+               for (i = 0; i < CIP_SFC_COUNT; ++i) {
+                       if (amdtp_rate_table[i] == rate)
+                               break;
+               }
+               if (i >= CIP_SFC_COUNT)
+                       return -EINVAL;
+
+               err = snd_ff_stream_get_multiplier_mode(i, &mode);
                if (err < 0)
-                       goto error;
+                       return err;
+
+               err = amdtp_ff_set_parameters(&ff->tx_stream, rate,
+                                       ff->spec->pcm_capture_channels[mode]);
+               if (err < 0)
+                       return err;
+
+               err = amdtp_ff_set_parameters(&ff->rx_stream, rate,
+                                       ff->spec->pcm_playback_channels[mode]);
+               if (err < 0)
+                       return err;
 
                err = ff->spec->protocol->begin_session(ff, rate);
                if (err < 0)