diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index 39033876593e..4a7cc1f77d88 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c @@ -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, diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index f334ae51e44f..05f1b8b30e2b 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h @@ -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; diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c index 02b3259059f0..25997f1ee300 100644 --- a/sound/firewire/fireworks/fireworks.c +++ b/sound/firewire/fireworks/fireworks.c @@ -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); diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h index 9534e93e3a36..3f998510ddf3 100644 --- a/sound/firewire/fireworks/fireworks.h +++ b/sound/firewire/fireworks/fireworks.h @@ -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; diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index 7447af72ae30..c75c2ef2ae31 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c @@ -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) {