OSDN Git Service

ALSA: fireface: add protocol-dependent operation to switch mode to fetch PCM frame
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 20 Jan 2019 08:25:49 +0000 (17:25 +0900)
committerTakashi Iwai <tiwai@suse.de>
Mon, 21 Jan 2019 14:12:19 +0000 (15:12 +0100)
This commit adds a member for a callback function to switch frame
fetching mode to former protocol.

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

index 5f97e7f..279bd03 100644 (file)
 #include "ff.h"
 
 #define FORMER_REG_SYNC_STATUS         0x0000801c0000ull
+/* For block write request. */
+#define FORMER_REG_FETCH_PCM_FRAMES    0x0000801c0000ull
+
+static int former_switch_fetching_mode(struct snd_ff *ff, bool enable)
+{
+       unsigned int count;
+       __le32 *reg;
+       int i;
+       int err;
+
+       count = 0;
+       for (i = 0; i < SND_FF_STREAM_MODE_COUNT; ++i)
+               count = max(count, ff->spec->pcm_playback_channels[i]);
+
+       reg = kcalloc(count, sizeof(__le32), GFP_KERNEL);
+       if (!reg)
+               return -ENOMEM;
+
+       if (!enable) {
+               /*
+                * Each quadlet is corresponding to data channels in a data
+                * blocks in reverse order. Precisely, quadlets for available
+                * data channels should be enabled. Here, I take second best
+                * to fetch PCM frames from all of data channels regardless of
+                * stf.
+                */
+               for (i = 0; i < count; ++i)
+                       reg[i] = cpu_to_le32(0x00000001);
+       }
+
+       err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
+                                FORMER_REG_FETCH_PCM_FRAMES, reg,
+                                sizeof(__le32) * count, 0);
+       kfree(reg);
+       return err;
+}
 
 static void dump_clock_config(struct snd_ff *ff, struct snd_info_buffer *buffer)
 {
@@ -347,6 +383,7 @@ static void ff800_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length)
 
 const struct snd_ff_protocol snd_ff_protocol_ff800 = {
        .handle_midi_msg        = ff800_handle_midi_msg,
+       .switch_fetching_mode   = former_switch_fetching_mode,
        .begin_session          = ff800_begin_session,
        .finish_session         = ff800_finish_session,
        .dump_status            = former_dump_status,
@@ -495,6 +532,7 @@ static void ff400_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length)
 
 const struct snd_ff_protocol snd_ff_protocol_ff400 = {
        .handle_midi_msg        = ff400_handle_midi_msg,
+       .switch_fetching_mode   = former_switch_fetching_mode,
        .begin_session          = ff400_begin_session,
        .finish_session         = ff400_finish_session,
        .dump_status            = former_dump_status,
index a490e45..43e1e26 100644 (file)
@@ -37,44 +37,10 @@ static void release_resources(struct snd_ff *ff)
        fw_iso_resources_free(&ff->rx_resources);
 }
 
-static int switch_fetching_mode(struct snd_ff *ff, bool enable)
-{
-       unsigned int count;
-       __le32 *reg;
-       int i;
-       int err;
-
-       count = 0;
-       for (i = 0; i < SND_FF_STREAM_MODE_COUNT; ++i)
-               count = max(count, ff->spec->pcm_playback_channels[i]);
-
-       reg = kcalloc(count, sizeof(__le32), GFP_KERNEL);
-       if (!reg)
-               return -ENOMEM;
-
-       if (!enable) {
-               /*
-                * Each quadlet is corresponding to data channels in a data
-                * blocks in reverse order. Precisely, quadlets for available
-                * data channels should be enabled. Here, I take second best
-                * to fetch PCM frames from all of data channels regardless of
-                * stf.
-                */
-               for (i = 0; i < count; ++i)
-                       reg[i] = cpu_to_le32(0x00000001);
-       }
-
-       err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
-                                SND_FF_REG_FETCH_PCM_FRAMES, reg,
-                                sizeof(__le32) * count, 0);
-       kfree(reg);
-       return err;
-}
-
 static inline void finish_session(struct snd_ff *ff)
 {
        ff->spec->protocol->finish_session(ff);
-       switch_fetching_mode(ff, false);
+       ff->spec->protocol->switch_fetching_mode(ff, false);
 }
 
 static int init_stream(struct snd_ff *ff, enum amdtp_stream_direction dir)
@@ -206,7 +172,7 @@ int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)
                        goto error;
                }
 
-               err = switch_fetching_mode(ff, true);
+               err = ff->spec->protocol->switch_fetching_mode(ff, true);
                if (err < 0)
                        goto error;
        }
index 3f22b8d..29f5551 100644 (file)
@@ -35,8 +35,6 @@
 #define SND_FF_IN_MIDI_PORTS           2
 #define SND_FF_OUT_MIDI_PORTS          2
 
-/* For block write request. */
-#define SND_FF_REG_FETCH_PCM_FRAMES    0x0000801c0000ull
 #define SND_FF_REG_CLOCK_CONFIG                0x0000801c0004ull
 
 enum snd_ff_stream_mode {
@@ -108,6 +106,7 @@ enum snd_ff_clock_src {
 
 struct snd_ff_protocol {
        void (*handle_midi_msg)(struct snd_ff *ff, __le32 *buf, size_t length);
+       int (*switch_fetching_mode)(struct snd_ff *ff, bool enable);
        int (*begin_session)(struct snd_ff *ff, unsigned int rate);
        void (*finish_session)(struct snd_ff *ff);
        void (*dump_status)(struct snd_ff *ff, struct snd_info_buffer *buffer);