@@ -88,6 +88,8 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
s->sort_table = NULL;
s->left_packets = NULL;
+ s->blocks_for_midi = UINT_MAX;
+
return 0;
}
EXPORT_SYMBOL(amdtp_stream_init);
@@ -556,8 +558,14 @@ static void amdtp_fill_midi(struct amdtp_stream *s,
buffer[s->midi_position] = 0x00;
b = (u8 *)&buffer[s->midi_position];
+ /*
+ * NOTE:
+ * Fireworks ignores midi messages in more than first 8
+ * data blocks of an packet.
+ */
port = (s->data_block_counter + f) % 8;
- if ((s->midi[port] == NULL) ||
+ if ((f >= s->blocks_for_midi) ||
+ (s->midi[port] == NULL) ||
(snd_rawmidi_transmit(s->midi[port], b + 1, 1) <= 0)) {
b[0] = 0x80;
b[1] = 0x00; /* confirm to be zero */
@@ -710,7 +718,7 @@ static void handle_in_packet(struct amdtp_stream *s,
__be32 *buffer)
{
u32 cip_header[2];
- unsigned int data_block_quadlets, data_blocks, data_block_counter;
+ unsigned int data_blocks;
struct snd_pcm_substream *pcm;
cip_header[0] = be32_to_cpu(buffer[0]);
@@ -735,27 +743,16 @@ static void handle_in_packet(struct amdtp_stream *s,
AMDTP_FDF_NO_DATA))
return;
- data_block_quadlets =
- (cip_header[1] & AMDTP_DBS_MASK) >> AMDTP_DBS_SHIFT;
- /* avoid division by zero */
- if (data_block_quadlets == 0) {
- dev_info_ratelimited(&s->unit->device,
- "Detect invalid value in dbs field: %08X\n",
- data_block_quadlets);
- return;
- }
-
- data_blocks = (payload_quadlets - 2) / data_block_quadlets;
- data_block_counter = cip_header[1] & AMDTP_DBC_MASK;
-
- /* check packet continuity */
- s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
- if (s->data_block_counter != data_block_counter) {
- dev_info_ratelimited(&s->unit->device,
- "Detect uncontinuity of CIP packets\n");
- s->data_block_counter = data_block_counter;
- return;
- }
+ /*
+ * This module don't use the value of dbs and dbc beceause Echo
+ * AudioFirePre8 reports inappropriate value.
+ *
+ * This model always reports a fixed value "8" as data block size at
+ * any sampling rates but actually data block size is different.
+ * Additionally the value of data block count always incremented by
+ * "8" at any sampling rates but actually it's different.
+ */
+ data_blocks = (payload_quadlets - 2) / s->data_block_quadlets;
buffer += 2;
@@ -1033,11 +1030,14 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
goto err_context;
} while (s->packet_index > 0);
- /* NOTE: TAG1 matches CIP. This just affects in stream */
+ /*
+ * NOTE: TAG1 matches CIP. This just affects in stream.
+ * Fireworks transmits NODATA packets with TAG0.
+ */
s->data_block_counter = 0;
s->callbacked = false;
err = fw_iso_context_start(s->context, -1, 0,
- FW_ISO_CONTEXT_MATCH_TAG1);
+ FW_ISO_CONTEXT_MATCH_TAG0 | FW_ISO_CONTEXT_MATCH_TAG1);
if (err < 0)
goto err_context;
@@ -113,6 +113,8 @@ struct amdtp_stream {
bool pointer_flush;
struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8];
+ /* quirk: the first count of data blocks in an AMDTP packet for MIDI */
+ unsigned int blocks_for_midi;
bool callbacked;
wait_queue_head_t callback_wait;