diff options
-rw-r--r-- | sound/firewire/amdtp.c | 15 | ||||
-rw-r--r-- | sound/firewire/amdtp.h | 3 | ||||
-rw-r--r-- | sound/firewire/fireworks/fireworks_stream.c | 2 |
3 files changed, 18 insertions, 2 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index dce4c6dd3f6d..51aad680886d 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
@@ -620,6 +620,7 @@ static void handle_in_packet(struct amdtp_stream *s, | |||
620 | u32 cip_header[2]; | 620 | u32 cip_header[2]; |
621 | unsigned int data_blocks, data_block_quadlets, data_block_counter; | 621 | unsigned int data_blocks, data_block_quadlets, data_block_counter; |
622 | struct snd_pcm_substream *pcm = NULL; | 622 | struct snd_pcm_substream *pcm = NULL; |
623 | bool lost; | ||
623 | 624 | ||
624 | cip_header[0] = be32_to_cpu(buffer[0]); | 625 | cip_header[0] = be32_to_cpu(buffer[0]); |
625 | cip_header[1] = be32_to_cpu(buffer[1]); | 626 | cip_header[1] = be32_to_cpu(buffer[1]); |
@@ -658,7 +659,13 @@ static void handle_in_packet(struct amdtp_stream *s, | |||
658 | 659 | ||
659 | /* Check data block counter continuity */ | 660 | /* Check data block counter continuity */ |
660 | data_block_counter = cip_header[0] & AMDTP_DBC_MASK; | 661 | data_block_counter = cip_header[0] & AMDTP_DBC_MASK; |
661 | if (data_block_counter != s->data_block_counter) { | 662 | if (!(s->flags & CIP_DBC_IS_END_EVENT)) |
663 | lost = data_block_counter != s->data_block_counter; | ||
664 | else | ||
665 | lost = data_block_counter != | ||
666 | ((s->data_block_counter + data_blocks) & 0xff); | ||
667 | |||
668 | if (lost) { | ||
662 | dev_info(&s->unit->device, | 669 | dev_info(&s->unit->device, |
663 | "Detect discontinuity of CIP: %02X %02X\n", | 670 | "Detect discontinuity of CIP: %02X %02X\n", |
664 | s->data_block_counter, data_block_counter); | 671 | s->data_block_counter, data_block_counter); |
@@ -676,7 +683,11 @@ static void handle_in_packet(struct amdtp_stream *s, | |||
676 | amdtp_pull_midi(s, buffer, data_blocks); | 683 | amdtp_pull_midi(s, buffer, data_blocks); |
677 | } | 684 | } |
678 | 685 | ||
679 | s->data_block_counter = (data_block_counter + data_blocks) & 0xff; | 686 | if (s->flags & CIP_DBC_IS_END_EVENT) |
687 | s->data_block_counter = data_block_counter; | ||
688 | else | ||
689 | s->data_block_counter = | ||
690 | (data_block_counter + data_blocks) & 0xff; | ||
680 | end: | 691 | end: |
681 | if (queue_in_packet(s) < 0) | 692 | if (queue_in_packet(s) < 0) |
682 | goto err; | 693 | goto err; |
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index 96b96ec812b2..1ca1a193bbc0 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h | |||
@@ -19,12 +19,15 @@ | |||
19 | * @CIP_SYNC_TO_DEVICE: In sync to device mode, time stamp in out packets is | 19 | * @CIP_SYNC_TO_DEVICE: In sync to device mode, time stamp in out packets is |
20 | * generated by in packets. Defaultly this driver generates timestamp. | 20 | * generated by in packets. Defaultly this driver generates timestamp. |
21 | * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0. | 21 | * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0. |
22 | * @CIP_DBC_IS_END_EVENT: Only for in-stream. The value of dbc in an in-packet | ||
23 | * corresponds to the end of event in the packet. Out of IEC 61883. | ||
22 | */ | 24 | */ |
23 | enum cip_flags { | 25 | enum cip_flags { |
24 | CIP_NONBLOCKING = 0x00, | 26 | CIP_NONBLOCKING = 0x00, |
25 | CIP_BLOCKING = 0x01, | 27 | CIP_BLOCKING = 0x01, |
26 | CIP_SYNC_TO_DEVICE = 0x02, | 28 | CIP_SYNC_TO_DEVICE = 0x02, |
27 | CIP_EMPTY_WITH_TAG0 = 0x04, | 29 | CIP_EMPTY_WITH_TAG0 = 0x04, |
30 | CIP_DBC_IS_END_EVENT = 0x08, | ||
28 | }; | 31 | }; |
29 | 32 | ||
30 | /** | 33 | /** |
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index 360e871bf838..d687b047446b 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c | |||
@@ -196,6 +196,8 @@ int snd_efw_stream_init_duplex(struct snd_efw *efw) | |||
196 | goto end; | 196 | goto end; |
197 | /* Fireworks transmits NODATA packets with TAG0. */ | 197 | /* Fireworks transmits NODATA packets with TAG0. */ |
198 | efw->tx_stream.flags |= CIP_EMPTY_WITH_TAG0; | 198 | efw->tx_stream.flags |= CIP_EMPTY_WITH_TAG0; |
199 | /* Fireworks has its own meaning for dbc. */ | ||
200 | efw->tx_stream.flags |= CIP_DBC_IS_END_EVENT; | ||
199 | 201 | ||
200 | err = init_stream(efw, &efw->rx_stream); | 202 | err = init_stream(efw, &efw->rx_stream); |
201 | if (err < 0) { | 203 | if (err < 0) { |