ALSA: firewire-lib: use union for directional parameters
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 21 May 2019 14:57:34 +0000 (23:57 +0900)
committerTakashi Iwai <tiwai@suse.de>
Wed, 22 May 2019 10:28:00 +0000 (12:28 +0200)
Some parameters of struct amdtp_stream is dependent on direction.

This commit uses union for such parameters to distinguish from
common parameters.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/amdtp-am824.c
sound/firewire/amdtp-stream.c
sound/firewire/amdtp-stream.h
sound/firewire/digi00x/amdtp-dot.c
sound/firewire/fireworks/fireworks_stream.c
sound/firewire/motu/amdtp-motu.c
sound/firewire/tascam/amdtp-tascam.c

index 4210e5c6262eb9f19e4d08f6d195bca793f4c680..7019a2143581869cd7da5870650558ef72c8ec0d 100644 (file)
@@ -83,7 +83,7 @@ int amdtp_am824_set_parameters(struct amdtp_stream *s, unsigned int rate,
        if (err < 0)
                return err;
 
-       s->fdf = AMDTP_FDF_AM824 | s->sfc;
+       s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc;
 
        p->pcm_channels = pcm_channels;
        p->midi_ports = midi_ports;
index 6b3f936fab9170857c7cf745a6b4332fb34a9e33..6977fbbef755834c036c662f5738536636db1728 100644 (file)
@@ -260,11 +260,18 @@ int amdtp_stream_set_parameters(struct amdtp_stream *s, unsigned int rate,
        s->data_block_quadlets = data_block_quadlets;
        s->syt_interval = amdtp_syt_intervals[sfc];
 
-       /* default buffering in the device */
-       s->transfer_delay = TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE;
-       if (s->flags & CIP_BLOCKING)
-               /* additional buffering needed to adjust for no-data packets */
-               s->transfer_delay += TICKS_PER_SECOND * s->syt_interval / rate;
+       // default buffering in the device.
+       if (s->direction == AMDTP_OUT_STREAM) {
+               s->ctx_data.rx.transfer_delay =
+                                       TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE;
+
+               if (s->flags & CIP_BLOCKING) {
+                       // additional buffering needed to adjust for no-data
+                       // packets.
+                       s->ctx_data.rx.transfer_delay +=
+                               TICKS_PER_SECOND * s->syt_interval / rate;
+               }
+       }
 
        return 0;
 }
@@ -321,10 +328,10 @@ static unsigned int calculate_data_blocks(struct amdtp_stream *s,
        /* Non-blocking mode. */
        } else {
                if (!cip_sfc_is_base_44100(s->sfc)) {
-                       /* Sample_rate / 8000 is an integer, and precomputed. */
-                       data_blocks = s->data_block_state;
+                       // Sample_rate / 8000 is an integer, and precomputed.
+                       data_blocks = s->ctx_data.rx.data_block_state;
                } else {
-                       phase = s->data_block_state;
+                       phase = s->ctx_data.rx.data_block_state;
 
                /*
                 * This calculates the number of data blocks per packet so that
@@ -343,7 +350,7 @@ static unsigned int calculate_data_blocks(struct amdtp_stream *s,
                                data_blocks = 11 * (s->sfc >> 1) + (phase == 0);
                        if (++phase >= (80 >> (s->sfc >> 1)))
                                phase = 0;
-                       s->data_block_state = phase;
+                       s->ctx_data.rx.data_block_state = phase;
                }
        }
 
@@ -355,9 +362,10 @@ static unsigned int calculate_syt(struct amdtp_stream *s,
 {
        unsigned int syt_offset, phase, index, syt;
 
-       if (s->last_syt_offset < TICKS_PER_CYCLE) {
+       if (s->ctx_data.rx.last_syt_offset < TICKS_PER_CYCLE) {
                if (!cip_sfc_is_base_44100(s->sfc))
-                       syt_offset = s->last_syt_offset + s->syt_offset_state;
+                       syt_offset = s->ctx_data.rx.last_syt_offset +
+                                    s->ctx_data.rx.syt_offset_state;
                else {
                /*
                 * The time, in ticks, of the n'th SYT_INTERVAL sample is:
@@ -369,21 +377,21 @@ static unsigned int calculate_syt(struct amdtp_stream *s,
                 *   1386 1386 1387 1386 1386 1386 1387 1386 1386 1386 1387 ...
                 * This code generates _exactly_ the same sequence.
                 */
-                       phase = s->syt_offset_state;
+                       phase = s->ctx_data.rx.syt_offset_state;
                        index = phase % 13;
-                       syt_offset = s->last_syt_offset;
+                       syt_offset = s->ctx_data.rx.last_syt_offset;
                        syt_offset += 1386 + ((index && !(index & 3)) ||
                                              phase == 146);
                        if (++phase >= 147)
                                phase = 0;
-                       s->syt_offset_state = phase;
+                       s->ctx_data.rx.syt_offset_state = phase;
                }
        } else
-               syt_offset = s->last_syt_offset - TICKS_PER_CYCLE;
-       s->last_syt_offset = syt_offset;
+               syt_offset = s->ctx_data.rx.last_syt_offset - TICKS_PER_CYCLE;
+       s->ctx_data.rx.last_syt_offset = syt_offset;
 
        if (syt_offset < TICKS_PER_CYCLE) {
-               syt_offset += s->transfer_delay;
+               syt_offset += s->ctx_data.rx.transfer_delay;
                syt = (cycle + syt_offset / TICKS_PER_CYCLE) << 12;
                syt += syt_offset % TICKS_PER_CYCLE;
 
@@ -457,7 +465,8 @@ static inline int queue_out_packet(struct amdtp_stream *s,
 
 static inline int queue_in_packet(struct amdtp_stream *s)
 {
-       return queue_packet(s, IR_HEADER_SIZE, s->max_payload_length);
+       return queue_packet(s, s->ctx_data.tx.ctx_header_size,
+                           s->ctx_data.tx.max_payload_length);
 }
 
 static int handle_out_packet(struct amdtp_stream *s,
@@ -484,9 +493,9 @@ static int handle_out_packet(struct amdtp_stream *s,
                                ((s->sph << CIP_SPH_SHIFT) & CIP_SPH_MASK) |
                                s->data_block_counter);
        buffer[1] = cpu_to_be32(CIP_EOH |
-                               ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) |
-                               ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) |
-                               (syt & CIP_SYT_MASK));
+                       ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) |
+                       ((s->ctx_data.rx.fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) |
+                       (syt & CIP_SYT_MASK));
 
        if (!(s->flags & CIP_DBC_IS_END_EVENT))
                s->data_block_counter =
@@ -610,14 +619,14 @@ static int handle_in_packet(struct amdtp_stream *s,
                data_block_counter = s->data_block_counter;
 
        if (((s->flags & CIP_SKIP_DBC_ZERO_CHECK) &&
-            data_block_counter == s->tx_first_dbc) ||
+            data_block_counter == s->ctx_data.tx.first_dbc) ||
            s->data_block_counter == UINT_MAX) {
                lost = false;
        } else if (!(s->flags & CIP_DBC_IS_END_EVENT)) {
                lost = data_block_counter != s->data_block_counter;
        } else {
-               if (data_blocks > 0 && s->tx_dbc_interval > 0)
-                       dbc_interval = s->tx_dbc_interval;
+               if (data_blocks > 0 && s->ctx_data.tx.dbc_interval > 0)
+                       dbc_interval = s->ctx_data.tx.dbc_interval;
                else
                        dbc_interval = data_blocks;
 
@@ -740,11 +749,11 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
        if (s->packet_index < 0)
                return;
 
-       /* The number of packets in buffer */
-       packets = header_length / IR_HEADER_SIZE;
+       // The number of packets in buffer.
+       packets = header_length / s->ctx_data.tx.ctx_header_size;
 
        /* For buffer-over-run prevention. */
-       max_payload_length = s->max_payload_length;
+       max_payload_length = s->ctx_data.tx.max_payload_length;
 
        for (i = 0; i < packets; i++) {
                u32 iso_header = be32_to_cpu(ctx_header[0]);
@@ -765,7 +774,7 @@ static void in_stream_callback(struct fw_iso_context *context, u32 tstamp,
                if (s->handle_packet(s, payload_length, cycle, i) < 0)
                        break;
 
-               ctx_header += IR_HEADER_SIZE / sizeof(__be32);
+               ctx_header += s->ctx_data.tx.ctx_header_size / sizeof(*ctx_header);
        }
 
        /* Queueing error or detecting invalid payload. */
@@ -837,7 +846,7 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
        static const struct {
                unsigned int data_block;
                unsigned int syt_offset;
-       } initial_state[] = {
+       } *entry, initial_state[] = {
                [CIP_SFC_32000]  = {  4, 3072 },
                [CIP_SFC_48000]  = {  6, 1024 },
                [CIP_SFC_96000]  = { 12, 1024 },
@@ -846,7 +855,7 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
                [CIP_SFC_88200]  = {  0,   67 },
                [CIP_SFC_176400] = {  0,   67 },
        };
-       unsigned int header_size;
+       unsigned int ctx_header_size;
        enum dma_data_direction dir;
        int type, tag, err;
 
@@ -858,23 +867,26 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
                goto err_unlock;
        }
 
-       if (s->direction == AMDTP_IN_STREAM)
+       if (s->direction == AMDTP_IN_STREAM) {
                s->data_block_counter = UINT_MAX;
-       else
+       } else {
+               entry = &initial_state[s->sfc];
+
                s->data_block_counter = 0;
-       s->data_block_state = initial_state[s->sfc].data_block;
-       s->syt_offset_state = initial_state[s->sfc].syt_offset;
-       s->last_syt_offset = TICKS_PER_CYCLE;
+               s->ctx_data.rx.data_block_state = entry->data_block;
+               s->ctx_data.rx.syt_offset_state = entry->syt_offset;
+               s->ctx_data.rx.last_syt_offset = TICKS_PER_CYCLE;
+       }
 
        /* initialize packet buffer */
        if (s->direction == AMDTP_IN_STREAM) {
                dir = DMA_FROM_DEVICE;
                type = FW_ISO_CONTEXT_RECEIVE;
-               header_size = IR_HEADER_SIZE;
+               ctx_header_size = IR_HEADER_SIZE;
        } else {
                dir = DMA_TO_DEVICE;
                type = FW_ISO_CONTEXT_TRANSMIT;
-               header_size = OUT_PACKET_HEADER_SIZE;
+               ctx_header_size = OUT_PACKET_HEADER_SIZE;
        }
        err = iso_packets_buffer_init(&s->buffer, s->unit, QUEUE_LENGTH,
                                      amdtp_stream_get_max_payload(s), dir);
@@ -882,8 +894,8 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
                goto err_unlock;
 
        s->context = fw_iso_context_create(fw_parent_device(s->unit)->card,
-                                          type, channel, speed, header_size,
-                                          amdtp_stream_first_callback, s);
+                                         type, channel, speed, ctx_header_size,
+                                         amdtp_stream_first_callback, s);
        if (IS_ERR(s->context)) {
                err = PTR_ERR(s->context);
                if (err == -EBUSY)
@@ -894,8 +906,11 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
 
        amdtp_stream_update(s);
 
-       if (s->direction == AMDTP_IN_STREAM)
-               s->max_payload_length = amdtp_stream_get_max_payload(s);
+       if (s->direction == AMDTP_IN_STREAM) {
+               s->ctx_data.tx.max_payload_length =
+                                               amdtp_stream_get_max_payload(s);
+               s->ctx_data.tx.ctx_header_size = ctx_header_size;
+       }
 
        if (s->flags & CIP_NO_HEADER)
                s->tag = TAG_NO_CIP_HEADER;
index e45de3eecfe39cb9b3b2f928f9a50307b05a3210..1945ef59ab92dd04feb01b37a211efba719d9d79 100644 (file)
@@ -111,7 +111,31 @@ struct amdtp_stream {
        int (*handle_packet)(struct amdtp_stream *s,
                        unsigned int payload_quadlets, unsigned int cycle,
                        unsigned int index);
-       unsigned int max_payload_length;
+       union {
+               struct {
+                       unsigned int ctx_header_size;
+
+                       // limit for payload of iso packet.
+                       unsigned int max_payload_length;
+
+                       // For quirks of CIP headers.
+                       // Fixed interval of dbc between previos/current
+                       // packets.
+                       unsigned int dbc_interval;
+                       // Indicate the value of dbc field in a first packet.
+                       unsigned int first_dbc;
+               } tx;
+               struct {
+                       // To calculate CIP data blocks and tstamp.
+                       unsigned int transfer_delay;
+                       unsigned int data_block_state;
+                       unsigned int last_syt_offset;
+                       unsigned int syt_offset_state;
+
+                       // To generate CIP header.
+                       unsigned int fdf;
+               } rx;
+       } ctx_data;
 
        /* For CIP headers. */
        unsigned int source_node_id_field;
@@ -119,19 +143,10 @@ struct amdtp_stream {
        unsigned int data_block_counter;
        unsigned int sph;
        unsigned int fmt;
-       unsigned int fdf;
-       /* quirk: fixed interval of dbc between previos/current packets. */
-       unsigned int tx_dbc_interval;
-       /* quirk: indicate the value of dbc field in a first packet. */
-       unsigned int tx_first_dbc;
 
        /* Internal flags. */
        enum cip_sfc sfc;
        unsigned int syt_interval;
-       unsigned int transfer_delay;
-       unsigned int data_block_state;
-       unsigned int last_syt_offset;
-       unsigned int syt_offset_state;
 
        /* For a PCM substream processing. */
        struct snd_pcm_substream *pcm;
index 4a884a33524809a23ba6a07e8319711f76771081..3fb1997dca30d6a160baaf13fad2215d4e03d317 100644 (file)
@@ -128,7 +128,7 @@ int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate,
        if (err < 0)
                return err;
 
-       s->fdf = AMDTP_FDF_AM824 | s->sfc;
+       s->ctx_data.rx.fdf = AMDTP_FDF_AM824 | s->sfc;
 
        p->pcm_channels = pcm_channels;
 
index 827161bc269cfa1414972692bcdb45d0a42ad9ed..74e122e6e68a28ea1848045ffb5bfbe1c7e6d7a4 100644 (file)
@@ -165,13 +165,13 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw)
            (efw->firmware_version == 0x5070000 ||
             efw->firmware_version == 0x5070300 ||
             efw->firmware_version == 0x5080000))
-               efw->tx_stream.tx_first_dbc = 0x02;
+               efw->tx_stream.ctx_data.tx.first_dbc = 0x02;
        /* AudioFire9 always reports wrong dbs. */
        if (efw->is_af9)
                efw->tx_stream.flags |= CIP_WRONG_DBS;
        /* Firmware version 5.5 reports fixed interval for dbc. */
        if (efw->firmware_version == 0x5050000)
-               efw->tx_stream.tx_dbc_interval = 8;
+               efw->tx_stream.ctx_data.tx.dbc_interval = 8;
 
        err = init_stream(efw, &efw->rx_stream);
        if (err < 0) {
index cb0c967dea6318e1a246a60f56f7fac993304bd6..62685f2528ce12c37153c3e4d58cc214d5e9f190 100644 (file)
@@ -429,7 +429,7 @@ int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
                return err;
 
        s->sph = 1;
-       s->fdf = MOTU_FDF_AM824;
+       s->ctx_data.rx.fdf = MOTU_FDF_AM824;
 
        return 0;
 }
index a52d1f76c610fbed8003e8195d60a61251e8dc45..1cf0f9470449d014510e4b28d604b129e987e9eb 100644 (file)
@@ -224,7 +224,7 @@ int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit,
                return 0;
 
        /* Use fixed value for FDF field. */
-       s->fdf = 0x00;
+       s->ctx_data.rx.fdf = 0x00;
 
        /* This protocol uses fixed number of data channels for PCM samples. */
        p = s->protocol;