ALSA: fireworks/firewire-lib: Add a quirk for wrong dbs in tx packets
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Fri, 25 Apr 2014 13:45:05 +0000 (22:45 +0900)
committerTakashi Iwai <tiwai@suse.de>
Mon, 26 May 2014 12:25:00 +0000 (14:25 +0200)
One of Fireworks firmware, named  as 'AudioFire9', seems to transmit
packets with wrong value of dbs. It's always 0x11 but actual size of
data block is different.

This commit adds a flag for this quirk and some codes to calculate
correct size.

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

index 51aad680886db14594072608e73d377e84118bd8..39033876593ee098a8ca3722f5c4fe06367c5523 100644 (file)
@@ -653,6 +653,8 @@ static void handle_in_packet(struct amdtp_stream *s,
                                cip_header[0]);
                        goto err;
                }
+               if (s->flags & CIP_WRONG_DBS)
+                       data_block_quadlets = s->data_block_quadlets;
 
                data_blocks = (payload_quadlets - 2) / data_block_quadlets;
        }
index 1ca1a193bbc07a1a1eb92765d2bd73686d607284..f334ae51e44f97da281f3bafacdadc7bc1358d14 100644 (file)
@@ -21,6 +21,8 @@
  * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0.
  * @CIP_DBC_IS_END_EVENT: Only for in-stream. The value of dbc in an in-packet
  *     corresponds to the end of event in the packet. Out of IEC 61883.
+ * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets.
+ *     The value of data_block_quadlets is used instead of reported value.
  */
 enum cip_flags {
        CIP_NONBLOCKING         = 0x00,
@@ -28,6 +30,7 @@ enum cip_flags {
        CIP_SYNC_TO_DEVICE      = 0x02,
        CIP_EMPTY_WITH_TAG0     = 0x04,
        CIP_DBC_IS_END_EVENT    = 0x08,
+       CIP_WRONG_DBS           = 0x10,
 };
 
 /**
index 307fb2f250dac2ba20154ebf7d4baaa66c9c7a78..02b3259059f0af4b0fbde21086cf8b1d258f7019 100644 (file)
@@ -205,6 +205,8 @@ efw_probe(struct fw_unit *unit,
        err = get_hardware_info(efw);
        if (err < 0)
                goto error;
+       if (entry->model_id == MODEL_ECHO_AUDIOFIRE_9)
+               efw->is_af9 = true;
 
        err = snd_efw_stream_init_duplex(efw);
        if (err < 0)
index ce511be4611b4f5ec63d3ea6efc6d6fd146073e7..9534e93e3a3607bdcabde4b6049d0f50cb1100a5 100644 (file)
@@ -61,6 +61,9 @@ struct snd_efw {
        u32 seqnum;
        bool resp_addr_changable;
 
+       /* for quirks */
+       bool is_af9;
+
        unsigned int midi_in_ports;
        unsigned int midi_out_ports;
 
index d687b047446bc8edb44d43fdd3b15dc804ab2b0f..7447af72ae3039cdcc8f82c87baeef026a6daa00 100644 (file)
@@ -198,6 +198,9 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw)
        efw->tx_stream.flags |= CIP_EMPTY_WITH_TAG0;
        /* Fireworks has its own meaning for dbc. */
        efw->tx_stream.flags |= CIP_DBC_IS_END_EVENT;
+       /* AudioFire9 always reports wrong dbs. */
+       if (efw->is_af9)
+               efw->tx_stream.flags |= CIP_WRONG_DBS;
 
        err = init_stream(efw, &efw->rx_stream);
        if (err < 0) {