ALSA: fireworks/firewire-lib: Add a quirk for fixed interval of reported dbc
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Fri, 25 Apr 2014 13:45:06 +0000 (22:45 +0900)
committerTakashi Iwai <tiwai@suse.de>
Mon, 26 May 2014 12:25:15 +0000 (14:25 +0200)
Fireworks firmware version 5.5 reports fix interval for dbc in each packet.

For example, AudioFire4:
CIP0     CIP1     Payload
00070000 900484FF 72
00070008 9004A8FF 72
00070008 90FFFFFF 02
00070010 9004D0FF 72
00070018 9004C4FF 72
00070020 9004E8FF 72
00070020 90FFFFFF 02
00070028 900410FE 72

The interval of each dbc should be 16 except for empty packet but it's still 8.

This commit adds a flag for this quirk and codes to refer to a fixed value.

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 39033876593ee098a8ca3722f5c4fe06367c5523..4a7cc1f77d88d8af6c8959ec46697aaac59ae93a 100644 (file)
@@ -618,7 +618,8 @@ static void handle_in_packet(struct amdtp_stream *s,
                             __be32 *buffer)
 {
        u32 cip_header[2];
-       unsigned int data_blocks, data_block_quadlets, data_block_counter;
+       unsigned int data_blocks, data_block_quadlets, data_block_counter,
+                    dbc_interval;
        struct snd_pcm_substream *pcm = NULL;
        bool lost;
 
@@ -661,11 +662,17 @@ static void handle_in_packet(struct amdtp_stream *s,
 
        /* Check data block counter continuity */
        data_block_counter = cip_header[0] & AMDTP_DBC_MASK;
-       if (!(s->flags & CIP_DBC_IS_END_EVENT))
+       if (!(s->flags & CIP_DBC_IS_END_EVENT)) {
                lost = data_block_counter != s->data_block_counter;
-       else
+       } else {
+               if ((data_blocks > 0) && (s->tx_dbc_interval > 0))
+                       dbc_interval = s->tx_dbc_interval;
+               else
+                       dbc_interval = data_blocks;
+
                lost = data_block_counter !=
-                      ((s->data_block_counter + data_blocks) & 0xff);
+                      ((s->data_block_counter + dbc_interval) & 0xff);
+       }
 
        if (lost) {
                dev_info(&s->unit->device,
index f334ae51e44f97da281f3bafacdadc7bc1358d14..05f1b8b30e2b6630e39f71a89cafce87a31e2dae 100644 (file)
@@ -119,6 +119,9 @@ struct amdtp_stream {
 
        struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8];
 
+       /* quirk: fixed interval of dbc between previos/current packets. */
+       unsigned int tx_dbc_interval;
+
        bool callbacked;
        wait_queue_head_t callback_wait;
        struct amdtp_stream *sync_slave;
index 02b3259059f0af4b0fbde21086cf8b1d258f7019..25997f1ee300426494061e8e977590b6c1a59fe4 100644 (file)
@@ -84,6 +84,7 @@ get_hardware_info(struct snd_efw *efw)
                 (hwinfo->arm_version >> 16) & 0xff);
        if (err < 0)
                goto end;
+       efw->firmware_version = hwinfo->arm_version;
 
        strcpy(efw->card->driver, "Fireworks");
        strcpy(efw->card->shortname, hwinfo->model_name);
index 9534e93e3a3607bdcabde4b6049d0f50cb1100a5..3f998510ddf37f64dd59ca1f7482f0a3d05b9df5 100644 (file)
@@ -63,6 +63,7 @@ struct snd_efw {
 
        /* for quirks */
        bool is_af9;
+       u32 firmware_version;
 
        unsigned int midi_in_ports;
        unsigned int midi_out_ports;
index 7447af72ae3039cdcc8f82c87baeef026a6daa00..c75c2ef2ae31ad6cbd1b71826d8b8f394cc2129e 100644 (file)
@@ -201,6 +201,9 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw)
        /* 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;
 
        err = init_stream(efw, &efw->rx_stream);
        if (err < 0) {