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]);
/* 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);
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;
* @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,
};
/**
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) {