summaryrefslogtreecommitdiff
path: root/sound/firewire/amdtp.c
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2014-04-25 13:45:04 (GMT)
committerTakashi Iwai <tiwai@suse.de>2014-05-26 12:24:47 (GMT)
commitc8bdf49b9935cdeec917347df00a5434d58e9df0 (patch)
treef178340abddc6f5527dfe4a03d2a8e9124cc3b59 /sound/firewire/amdtp.c
parent7ab566453fe32d6745a82772a16e9bc34c5403a5 (diff)
downloadlinux-c8bdf49b9935cdeec917347df00a5434d58e9df0.tar.xz
ALSA: fireworks/firewire-lib: Add a quirk for the meaning of dbc
Fireworks has a quirk for the value of dbc field in transmitted packets. For Fireworks, dbc means the end of events in current packet. This is out of specification. For example, AudioFire4: CIP0 CIP1 Payload 01070092 90FFFFFF 02 0107009A 9001E17B 3A <- 010700A2 9001F6E5 3A 010700A2 90FFFFFF 02 010700AA 9001104F 3A <- 010700B2 900125B9 3A 010700BA 90013B23 3A 010700BA 90FFFFFF 02 010700C2 9001548E 3A <- 010700CA 900169F8 3A 010700CA 90FFFFFF 02 010700D2 90018362 3A <- 010700DA 900198CC 3A According to IEC 61883-1/6, a packet following to empty packet has the same value for its dbc. But for Fireworks, it's incremented and empty packet has the same value as previous packet in dbc field. This commit adds a flag for Fireworks and some codes to checking dbc continuity. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire/amdtp.c')
-rw-r--r--sound/firewire/amdtp.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c
index dce4c6d..51aad68 100644
--- a/sound/firewire/amdtp.c
+++ b/sound/firewire/amdtp.c
@@ -620,6 +620,7 @@ static void handle_in_packet(struct amdtp_stream *s,
u32 cip_header[2];
unsigned int data_blocks, data_block_quadlets, data_block_counter;
struct snd_pcm_substream *pcm = NULL;
+ bool lost;
cip_header[0] = be32_to_cpu(buffer[0]);
cip_header[1] = be32_to_cpu(buffer[1]);
@@ -658,7 +659,13 @@ static void handle_in_packet(struct amdtp_stream *s,
/* Check data block counter continuity */
data_block_counter = cip_header[0] & AMDTP_DBC_MASK;
- if (data_block_counter != s->data_block_counter) {
+ if (!(s->flags & CIP_DBC_IS_END_EVENT))
+ lost = data_block_counter != s->data_block_counter;
+ else
+ lost = data_block_counter !=
+ ((s->data_block_counter + data_blocks) & 0xff);
+
+ if (lost) {
dev_info(&s->unit->device,
"Detect discontinuity of CIP: %02X %02X\n",
s->data_block_counter, data_block_counter);
@@ -676,7 +683,11 @@ static void handle_in_packet(struct amdtp_stream *s,
amdtp_pull_midi(s, buffer, data_blocks);
}
- s->data_block_counter = (data_block_counter + data_blocks) & 0xff;
+ if (s->flags & CIP_DBC_IS_END_EVENT)
+ s->data_block_counter = data_block_counter;
+ else
+ s->data_block_counter =
+ (data_block_counter + data_blocks) & 0xff;
end:
if (queue_in_packet(s) < 0)
goto err;