Commit d9cd0065 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

ALSA: fireworks/firewire-lib: Add a quirk for fixed interval of reported dbc

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: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 69702239
......@@ -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,
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment