summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/firewire/amdtp.c15
-rw-r--r--sound/firewire/amdtp.h3
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c2
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,
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;
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 @@
* @CIP_SYNC_TO_DEVICE: In sync to device mode, time stamp in out packets is
* generated by in packets. Defaultly this driver generates timestamp.
* @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0.
+ * @CIP_DBC_IS_END_EVENT: Only for in-stream. The value of dbc in an in-packet
+ * corresponds to the end of event in the packet. Out of IEC 61883.
*/
enum cip_flags {
CIP_NONBLOCKING = 0x00,
CIP_BLOCKING = 0x01,
CIP_SYNC_TO_DEVICE = 0x02,
CIP_EMPTY_WITH_TAG0 = 0x04,
+ CIP_DBC_IS_END_EVENT = 0x08,
};
/**
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)
goto end;
/* Fireworks transmits NODATA packets with TAG0. */
efw->tx_stream.flags |= CIP_EMPTY_WITH_TAG0;
+ /* Fireworks has its own meaning for dbc. */
+ efw->tx_stream.flags |= CIP_DBC_IS_END_EVENT;
err = init_stream(efw, &efw->rx_stream);
if (err < 0) {