]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
ALSA: dice: code refactoring to keep isochronous resources
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 11 Jun 2019 13:21:15 +0000 (22:21 +0900)
committerTakashi Iwai <tiwai@suse.de>
Tue, 11 Jun 2019 14:02:08 +0000 (16:02 +0200)
This commit is a part of preparation to perform allocation/release
of isochronous resources in pcm.hw_params/hw_free callbacks.

This commit adds a helper function to allocate isochronous resources,
separated from operations to start packet streaming, I note that some
dice-based devices have two pair of endpoints for isochronous packet
straeming.

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

index 8bce923dc4bdaa4aea2149e243e93e7c75027bf5..010cbf02de4fc205f71ab1dcdbf6c1bf030091ec 100644 (file)
@@ -175,35 +175,22 @@ static void stop_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
        }
 }
 
-static int keep_resources(struct snd_dice *dice,
-                         enum amdtp_stream_direction dir, unsigned int index,
-                         unsigned int rate, unsigned int pcm_chs,
-                         unsigned int midi_ports)
+static int keep_resources(struct snd_dice *dice, struct amdtp_stream *stream,
+                         struct fw_iso_resources *resources, unsigned int rate,
+                         unsigned int pcm_chs, unsigned int midi_ports)
 {
-       struct amdtp_stream *stream;
-       struct fw_iso_resources *resources;
        bool double_pcm_frames;
        unsigned int i;
        int err;
 
-       if (dir == AMDTP_IN_STREAM) {
-               stream = &dice->tx_stream[index];
-               resources = &dice->tx_resources[index];
-       } else {
-               stream = &dice->rx_stream[index];
-               resources = &dice->rx_resources[index];
-       }
-
-       /*
-        * At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
-        * one data block of AMDTP packet. Thus sampling transfer frequency is
-        * a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
-        * transferred on AMDTP packets at 96 kHz. Two successive samples of a
-        * channel are stored consecutively in the packet. This quirk is called
-        * as 'Dual Wire'.
-        * For this quirk, blocking mode is required and PCM buffer size should
-        * be aligned to SYT_INTERVAL.
-        */
+       // At 176.4/192.0 kHz, Dice has a quirk to transfer two PCM frames in
+       // one data block of AMDTP packet. Thus sampling transfer frequency is
+       // a half of PCM sampling frequency, i.e. PCM frames at 192.0 kHz are
+       // transferred on AMDTP packets at 96 kHz. Two successive samples of a
+       // channel are stored consecutively in the packet. This quirk is called
+       // as 'Dual Wire'.
+       // For this quirk, blocking mode is required and PCM buffer size should
+       // be aligned to SYT_INTERVAL.
        double_pcm_frames = rate > 96000;
        if (double_pcm_frames) {
                rate /= 2;
@@ -230,49 +217,40 @@ static int keep_resources(struct snd_dice *dice,
                                fw_parent_device(dice->unit)->max_speed);
 }
 
-static void finish_session(struct snd_dice *dice, struct reg_params *tx_params,
-                          struct reg_params *rx_params)
+static int keep_dual_resources(struct snd_dice *dice, unsigned int rate,
+                              enum amdtp_stream_direction dir,
+                              struct reg_params *params)
 {
-       stop_streams(dice, AMDTP_IN_STREAM, tx_params);
-       stop_streams(dice, AMDTP_OUT_STREAM, rx_params);
-
-       snd_dice_transaction_clear_enable(dice);
-}
-
-static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
-                        unsigned int rate, struct reg_params *params)
-{
-       __be32 reg[2];
        enum snd_dice_rate_mode mode;
-       unsigned int i, pcm_chs, midi_ports;
-       struct amdtp_stream *streams;
-       struct fw_iso_resources *resources;
-       struct fw_device *fw_dev = fw_parent_device(dice->unit);
-       int err = 0;
-
-       if (dir == AMDTP_IN_STREAM) {
-               streams = dice->tx_stream;
-               resources = dice->tx_resources;
-       } else {
-               streams = dice->rx_stream;
-               resources = dice->rx_resources;
-       }
+       int i;
+       int err;
 
        err = snd_dice_stream_get_rate_mode(dice, rate, &mode);
        if (err < 0)
                return err;
 
-       for (i = 0; i < params->count; i++) {
+       for (i = 0; i < params->count; ++i) {
+               __be32 reg[2];
+               struct amdtp_stream *stream;
+               struct fw_iso_resources *resources;
                unsigned int pcm_cache;
                unsigned int midi_cache;
+               unsigned int pcm_chs;
+               unsigned int midi_ports;
 
                if (dir == AMDTP_IN_STREAM) {
+                       stream = &dice->tx_stream[i];
+                       resources = &dice->tx_resources[i];
+
                        pcm_cache = dice->tx_pcm_chs[i][mode];
                        midi_cache = dice->tx_midi_ports[i];
                        err = snd_dice_transaction_read_tx(dice,
                                        params->size * i + TX_NUMBER_AUDIO,
                                        reg, sizeof(reg));
                } else {
+                       stream = &dice->rx_stream[i];
+                       resources = &dice->rx_resources[i];
+
                        pcm_cache = dice->rx_pcm_chs[i][mode];
                        midi_cache = dice->rx_midi_ports[i];
                        err = snd_dice_transaction_read_rx(dice,
@@ -284,7 +262,7 @@ static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
                pcm_chs = be32_to_cpu(reg[0]);
                midi_ports = be32_to_cpu(reg[1]);
 
-               /* These are important for developer of this driver. */
+               // These are important for developer of this driver.
                if (pcm_chs != pcm_cache || midi_ports != midi_cache) {
                        dev_info(&dice->unit->device,
                                 "cache mismatch: pcm: %u:%u, midi: %u:%u\n",
@@ -292,34 +270,71 @@ static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
                        return -EPROTO;
                }
 
-               err = keep_resources(dice, dir, i, rate, pcm_chs, midi_ports);
+               err = keep_resources(dice, stream, resources, rate, pcm_chs,
+                                    midi_ports);
                if (err < 0)
                        return err;
+       }
+
+       return 0;
+}
+
+static void finish_session(struct snd_dice *dice, struct reg_params *tx_params,
+                          struct reg_params *rx_params)
+{
+       stop_streams(dice, AMDTP_IN_STREAM, tx_params);
+       stop_streams(dice, AMDTP_OUT_STREAM, rx_params);
+
+       snd_dice_transaction_clear_enable(dice);
+}
+
+static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
+                        unsigned int rate, struct reg_params *params)
+{
+       unsigned int max_speed = fw_parent_device(dice->unit)->max_speed;
+       int i;
+       int err;
+
+       err = keep_dual_resources(dice, rate, dir, params);
+       if (err < 0)
+               return err;
+
+       for (i = 0; i < params->count; i++) {
+               struct amdtp_stream *stream;
+               struct fw_iso_resources *resources;
+               __be32 reg;
+
+               if (dir == AMDTP_IN_STREAM) {
+                       stream = dice->tx_stream + i;
+                       resources = dice->tx_resources + i;
+               } else {
+                       stream = dice->rx_stream + i;
+                       resources = dice->rx_resources + i;
+               }
 
-               reg[0] = cpu_to_be32(resources[i].channel);
+               reg = cpu_to_be32(resources->channel);
                if (dir == AMDTP_IN_STREAM) {
                        err = snd_dice_transaction_write_tx(dice,
                                        params->size * i + TX_ISOCHRONOUS,
-                                       reg, sizeof(reg[0]));
+                                       &reg, sizeof(reg));
                } else {
                        err = snd_dice_transaction_write_rx(dice,
                                        params->size * i + RX_ISOCHRONOUS,
-                                       reg, sizeof(reg[0]));
+                                       &reg, sizeof(reg));
                }
                if (err < 0)
                        return err;
 
                if (dir == AMDTP_IN_STREAM) {
-                       reg[0] = cpu_to_be32(fw_dev->max_speed);
+                       reg = cpu_to_be32(max_speed);
                        err = snd_dice_transaction_write_tx(dice,
                                        params->size * i + TX_SPEED,
-                                       reg, sizeof(reg[0]));
+                                       &reg, sizeof(reg));
                        if (err < 0)
                                return err;
                }
 
-               err = amdtp_stream_start(&streams[i], resources[i].channel,
-                                        fw_dev->max_speed);
+               err = amdtp_stream_start(stream, resources->channel, max_speed);
                if (err < 0)
                        return err;
        }