1 // SPDX-License-Identifier: GPL-2.0
2 // ff-protocol-former.c - a part of driver for RME Fireface series
3 //
4 // Copyright (c) 2019 Takashi Sakamoto
5
6 #include <linux/delay.h>
7
8 #include "ff.h"
9
10 #define FORMER_REG_SYNC_STATUS 0x0000801c0000ull
11 /* For block write request. */
12 #define FORMER_REG_FETCH_PCM_FRAMES 0x0000801c0000ull
13 #define FORMER_REG_CLOCK_CONFIG 0x0000801c0004ull
14
parse_clock_bits(u32 data,unsigned int * rate,enum snd_ff_clock_src * src)15 static int parse_clock_bits(u32 data, unsigned int *rate,
16 enum snd_ff_clock_src *src)
17 {
18 static const struct {
19 unsigned int rate;
20 u32 mask;
21 } *rate_entry, rate_entries[] = {
22 { 32000, 0x00000002, },
23 { 44100, 0x00000000, },
24 { 48000, 0x00000006, },
25 { 64000, 0x0000000a, },
26 { 88200, 0x00000008, },
27 { 96000, 0x0000000e, },
28 { 128000, 0x00000012, },
29 { 176400, 0x00000010, },
30 { 192000, 0x00000016, },
31 };
32 static const struct {
33 enum snd_ff_clock_src src;
34 u32 mask;
35 } *clk_entry, clk_entries[] = {
36 { SND_FF_CLOCK_SRC_ADAT1, 0x00000000, },
37 { SND_FF_CLOCK_SRC_ADAT2, 0x00000400, },
38 { SND_FF_CLOCK_SRC_SPDIF, 0x00000c00, },
39 { SND_FF_CLOCK_SRC_WORD, 0x00001000, },
40 { SND_FF_CLOCK_SRC_LTC, 0x00001800, },
41 };
42 int i;
43
44 for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) {
45 rate_entry = rate_entries + i;
46 if ((data & 0x0000001e) == rate_entry->mask) {
47 *rate = rate_entry->rate;
48 break;
49 }
50 }
51 if (i == ARRAY_SIZE(rate_entries))
52 return -EIO;
53
54 if (data & 0x00000001) {
55 *src = SND_FF_CLOCK_SRC_INTERNAL;
56 } else {
57 for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) {
58 clk_entry = clk_entries + i;
59 if ((data & 0x00001c00) == clk_entry->mask) {
60 *src = clk_entry->src;
61 break;
62 }
63 }
64 if (i == ARRAY_SIZE(clk_entries))
65 return -EIO;
66 }
67
68 return 0;
69 }
70
former_get_clock(struct snd_ff * ff,unsigned int * rate,enum snd_ff_clock_src * src)71 static int former_get_clock(struct snd_ff *ff, unsigned int *rate,
72 enum snd_ff_clock_src *src)
73 {
74 __le32 reg;
75 u32 data;
76 int err;
77
78 err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
79 FORMER_REG_CLOCK_CONFIG, ®, sizeof(reg), 0);
80 if (err < 0)
81 return err;
82 data = le32_to_cpu(reg);
83
84 return parse_clock_bits(data, rate, src);
85 }
86
former_switch_fetching_mode(struct snd_ff * ff,bool enable)87 static int former_switch_fetching_mode(struct snd_ff *ff, bool enable)
88 {
89 unsigned int count;
90 __le32 *reg;
91 int i;
92 int err;
93
94 count = 0;
95 for (i = 0; i < SND_FF_STREAM_MODE_COUNT; ++i)
96 count = max(count, ff->spec->pcm_playback_channels[i]);
97
98 reg = kcalloc(count, sizeof(__le32), GFP_KERNEL);
99 if (!reg)
100 return -ENOMEM;
101
102 if (!enable) {
103 /*
104 * Each quadlet is corresponding to data channels in a data
105 * blocks in reverse order. Precisely, quadlets for available
106 * data channels should be enabled. Here, I take second best
107 * to fetch PCM frames from all of data channels regardless of
108 * stf.
109 */
110 for (i = 0; i < count; ++i)
111 reg[i] = cpu_to_le32(0x00000001);
112 }
113
114 err = snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,
115 FORMER_REG_FETCH_PCM_FRAMES, reg,
116 sizeof(__le32) * count, 0);
117 kfree(reg);
118 return err;
119 }
120
dump_clock_config(struct snd_ff * ff,struct snd_info_buffer * buffer)121 static void dump_clock_config(struct snd_ff *ff, struct snd_info_buffer *buffer)
122 {
123 __le32 reg;
124 u32 data;
125 unsigned int rate;
126 enum snd_ff_clock_src src;
127 const char *label;
128 int err;
129
130 err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST,
131 FORMER_REG_CLOCK_CONFIG, ®, sizeof(reg), 0);
132 if (err < 0)
133 return;
134 data = le32_to_cpu(reg);
135
136 snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n",
137 (data & 0x00000020) ? "Professional" : "Consumer",
138 (data & 0x00000040) ? "on" : "off");
139
140 snd_iprintf(buffer, "Optical output interface format: %s\n",
141 (data & 0x00000100) ? "S/PDIF" : "ADAT");
142
143 snd_iprintf(buffer, "Word output single speed: %s\n",
144 (data & 0x00002000) ? "on" : "off");
145
146 snd_iprintf(buffer, "S/PDIF input interface: %s\n",
147 (data & 0x00000200) ? "Optical" : "Coaxial");
148
149 err = parse_clock_bits(data, &rate, &src);
150 if (err < 0)
151 return;
152 label = snd_ff_proc_get_clk_label(src);
153 if (!label)
154 return;
155
156 snd_iprintf(buffer, "Clock configuration: %d %s\n", rate, label);
157 }
158
dump_sync_status(struct snd_ff * ff,struct snd_info_buffer * buffer)159 static void dump_sync_status(struct snd_ff *ff, struct snd_info_buffer *buffer)
160 {
161 static const struct {
162 char *const label;
163 u32 locked_mask;
164 u32 synced_mask;
165 } *clk_entry, clk_entries[] = {
166 { "WDClk", 0x40000000, 0x20000000, },
167 { "S/PDIF", 0x00080000, 0x00040000, },
168 { "ADAT1", 0x00000400, 0x00001000, },
169 { "ADAT2", 0x00000800, 0x00002000, },
170 };
171 static const struct {
172 char *const label;
173 u32 mask;
174 } *referred_entry, referred_entries[] = {
175 { "ADAT1", 0x00000000, },
176 { "ADAT2", 0x00400000, },
177 { "S/PDIF", 0x00c00000, },
178 { "WDclk", 0x01000000, },
179 { "TCO", 0x01400000, },
180 };
181 static const struct {
182 unsigned int rate;
183 u32 mask;
184 } *rate_entry, rate_entries[] = {
185 { 32000, 0x02000000, },
186 { 44100, 0x04000000, },
187 { 48000, 0x06000000, },
188 { 64000, 0x08000000, },
189 { 88200, 0x0a000000, },
190 { 96000, 0x0c000000, },
191 { 128000, 0x0e000000, },
192 { 176400, 0x10000000, },
193 { 192000, 0x12000000, },
194 };
195 __le32 reg[2];
196 u32 data[2];
197 int i;
198 int err;
199
200 err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST,
201 FORMER_REG_SYNC_STATUS, reg, sizeof(reg), 0);
202 if (err < 0)
203 return;
204 data[0] = le32_to_cpu(reg[0]);
205 data[1] = le32_to_cpu(reg[1]);
206
207 snd_iprintf(buffer, "External source detection:\n");
208
209 for (i = 0; i < ARRAY_SIZE(clk_entries); ++i) {
210 const char *state;
211
212 clk_entry = clk_entries + i;
213 if (data[0] & clk_entry->locked_mask) {
214 if (data[0] & clk_entry->synced_mask)
215 state = "sync";
216 else
217 state = "lock";
218 } else {
219 state = "none";
220 }
221
222 snd_iprintf(buffer, "%s: %s\n", clk_entry->label, state);
223 }
224
225 snd_iprintf(buffer, "Referred clock:\n");
226
227 if (data[1] & 0x00000001) {
228 snd_iprintf(buffer, "Internal\n");
229 } else {
230 unsigned int rate;
231 const char *label;
232
233 for (i = 0; i < ARRAY_SIZE(referred_entries); ++i) {
234 referred_entry = referred_entries + i;
235 if ((data[0] & 0x1e0000) == referred_entry->mask) {
236 label = referred_entry->label;
237 break;
238 }
239 }
240 if (i == ARRAY_SIZE(referred_entries))
241 label = "none";
242
243 for (i = 0; i < ARRAY_SIZE(rate_entries); ++i) {
244 rate_entry = rate_entries + i;
245 if ((data[0] & 0x1e000000) == rate_entry->mask) {
246 rate = rate_entry->rate;
247 break;
248 }
249 }
250 if (i == ARRAY_SIZE(rate_entries))
251 rate = 0;
252
253 snd_iprintf(buffer, "%s %d\n", label, rate);
254 }
255 }
256
former_dump_status(struct snd_ff * ff,struct snd_info_buffer * buffer)257 static void former_dump_status(struct snd_ff *ff,
258 struct snd_info_buffer *buffer)
259 {
260 dump_clock_config(ff, buffer);
261 dump_sync_status(ff, buffer);
262 }
263
former_fill_midi_msg(struct snd_ff * ff,struct snd_rawmidi_substream * substream,unsigned int port)264 static int former_fill_midi_msg(struct snd_ff *ff,
265 struct snd_rawmidi_substream *substream,
266 unsigned int port)
267 {
268 u8 *buf = (u8 *)ff->msg_buf[port];
269 int len;
270 int i;
271
272 len = snd_rawmidi_transmit_peek(substream, buf,
273 SND_FF_MAXIMIM_MIDI_QUADS);
274 if (len <= 0)
275 return len;
276
277 // One quadlet includes one byte.
278 for (i = len - 1; i >= 0; --i)
279 ff->msg_buf[port][i] = cpu_to_le32(buf[i]);
280 ff->rx_bytes[port] = len;
281
282 return len;
283 }
284
285 #define FF800_STF 0x0000fc88f000
286 #define FF800_RX_PACKET_FORMAT 0x0000fc88f004
287 #define FF800_ALLOC_TX_STREAM 0x0000fc88f008
288 #define FF800_ISOC_COMM_START 0x0000fc88f00c
289 #define FF800_TX_S800_FLAG 0x00000800
290 #define FF800_ISOC_COMM_STOP 0x0000fc88f010
291
292 #define FF800_TX_PACKET_ISOC_CH 0x0000801c0008
293
allocate_tx_resources(struct snd_ff * ff)294 static int allocate_tx_resources(struct snd_ff *ff)
295 {
296 __le32 reg;
297 unsigned int count;
298 unsigned int tx_isoc_channel;
299 int err;
300
301 reg = cpu_to_le32(ff->tx_stream.data_block_quadlets);
302 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
303 FF800_ALLOC_TX_STREAM, ®, sizeof(reg), 0);
304 if (err < 0)
305 return err;
306
307 // Wait till the format of tx packet is available.
308 count = 0;
309 while (count++ < 10) {
310 u32 data;
311 err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,
312 FF800_TX_PACKET_ISOC_CH, ®, sizeof(reg), 0);
313 if (err < 0)
314 return err;
315
316 data = le32_to_cpu(reg);
317 if (data != 0xffffffff) {
318 tx_isoc_channel = data;
319 break;
320 }
321
322 msleep(50);
323 }
324 if (count >= 10)
325 return -ETIMEDOUT;
326
327 // NOTE: this is a makeshift to start OHCI 1394 IR context in the
328 // channel. On the other hand, 'struct fw_iso_resources.allocated' is
329 // not true and it's not deallocated at stop.
330 ff->tx_resources.channel = tx_isoc_channel;
331
332 return 0;
333 }
334
ff800_allocate_resources(struct snd_ff * ff,unsigned int rate)335 static int ff800_allocate_resources(struct snd_ff *ff, unsigned int rate)
336 {
337 u32 data;
338 __le32 reg;
339 int err;
340
341 reg = cpu_to_le32(rate);
342 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
343 FF800_STF, ®, sizeof(reg), 0);
344 if (err < 0)
345 return err;
346
347 // If starting isochronous communication immediately, change of STF has
348 // no effect. In this case, the communication runs based on former STF.
349 // Let's sleep for a bit.
350 msleep(100);
351
352 // Controllers should allocate isochronous resources for rx stream.
353 err = fw_iso_resources_allocate(&ff->rx_resources,
354 amdtp_stream_get_max_payload(&ff->rx_stream),
355 fw_parent_device(ff->unit)->max_speed);
356 if (err < 0)
357 return err;
358
359 // Set isochronous channel and the number of quadlets of rx packets.
360 // This should be done before the allocation of tx resources to avoid
361 // periodical noise.
362 data = ff->rx_stream.data_block_quadlets << 3;
363 data = (data << 8) | ff->rx_resources.channel;
364 reg = cpu_to_le32(data);
365 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
366 FF800_RX_PACKET_FORMAT, ®, sizeof(reg), 0);
367 if (err < 0)
368 return err;
369
370 return allocate_tx_resources(ff);
371 }
372
ff800_begin_session(struct snd_ff * ff,unsigned int rate)373 static int ff800_begin_session(struct snd_ff *ff, unsigned int rate)
374 {
375 unsigned int generation = ff->rx_resources.generation;
376 __le32 reg;
377
378 if (generation != fw_parent_device(ff->unit)->card->generation) {
379 int err = fw_iso_resources_update(&ff->rx_resources);
380 if (err < 0)
381 return err;
382 }
383
384 reg = cpu_to_le32(0x80000000);
385 reg |= cpu_to_le32(ff->tx_stream.data_block_quadlets);
386 if (fw_parent_device(ff->unit)->max_speed == SCODE_800)
387 reg |= cpu_to_le32(FF800_TX_S800_FLAG);
388 return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
389 FF800_ISOC_COMM_START, ®, sizeof(reg), 0);
390 }
391
ff800_finish_session(struct snd_ff * ff)392 static void ff800_finish_session(struct snd_ff *ff)
393 {
394 __le32 reg;
395
396 reg = cpu_to_le32(0x80000000);
397 snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
398 FF800_ISOC_COMM_STOP, ®, sizeof(reg), 0);
399 }
400
401 // Fireface 800 doesn't allow drivers to register lower 4 bytes of destination
402 // address.
403 // A write transaction to clear registered higher 4 bytes of destination address
404 // has an effect to suppress asynchronous transaction from device.
ff800_handle_midi_msg(struct snd_ff * ff,unsigned int offset,const __le32 * buf,size_t length,u32 tstamp)405 static void ff800_handle_midi_msg(struct snd_ff *ff, unsigned int offset, const __le32 *buf,
406 size_t length, u32 tstamp)
407 {
408 int i;
409
410 for (i = 0; i < length / 4; i++) {
411 u8 byte = le32_to_cpu(buf[i]) & 0xff;
412 struct snd_rawmidi_substream *substream;
413
414 substream = READ_ONCE(ff->tx_midi_substreams[0]);
415 if (substream)
416 snd_rawmidi_receive(substream, &byte, 1);
417 }
418 }
419
420 const struct snd_ff_protocol snd_ff_protocol_ff800 = {
421 .handle_msg = ff800_handle_midi_msg,
422 .fill_midi_msg = former_fill_midi_msg,
423 .get_clock = former_get_clock,
424 .switch_fetching_mode = former_switch_fetching_mode,
425 .allocate_resources = ff800_allocate_resources,
426 .begin_session = ff800_begin_session,
427 .finish_session = ff800_finish_session,
428 .dump_status = former_dump_status,
429 };
430
431 #define FF400_STF 0x000080100500ull
432 #define FF400_RX_PACKET_FORMAT 0x000080100504ull
433 #define FF400_ISOC_COMM_START 0x000080100508ull
434 #define FF400_TX_PACKET_FORMAT 0x00008010050cull
435 #define FF400_ISOC_COMM_STOP 0x000080100510ull
436
437 // Fireface 400 manages isochronous channel number in 3 bit field. Therefore,
438 // we can allocate between 0 and 7 channel.
ff400_allocate_resources(struct snd_ff * ff,unsigned int rate)439 static int ff400_allocate_resources(struct snd_ff *ff, unsigned int rate)
440 {
441 __le32 reg;
442 enum snd_ff_stream_mode mode;
443 int i;
444 int err;
445
446 // Check whether the given value is supported or not.
447 for (i = 0; i < CIP_SFC_COUNT; i++) {
448 if (amdtp_rate_table[i] == rate)
449 break;
450 }
451 if (i >= CIP_SFC_COUNT)
452 return -EINVAL;
453
454 // Set the number of data blocks transferred in a second.
455 reg = cpu_to_le32(rate);
456 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
457 FF400_STF, ®, sizeof(reg), 0);
458 if (err < 0)
459 return err;
460
461 msleep(100);
462
463 err = snd_ff_stream_get_multiplier_mode(i, &mode);
464 if (err < 0)
465 return err;
466
467 // Keep resources for in-stream.
468 ff->tx_resources.channels_mask = 0x00000000000000ffuLL;
469 err = fw_iso_resources_allocate(&ff->tx_resources,
470 amdtp_stream_get_max_payload(&ff->tx_stream),
471 fw_parent_device(ff->unit)->max_speed);
472 if (err < 0)
473 return err;
474
475 // Keep resources for out-stream.
476 ff->rx_resources.channels_mask = 0x00000000000000ffuLL;
477 err = fw_iso_resources_allocate(&ff->rx_resources,
478 amdtp_stream_get_max_payload(&ff->rx_stream),
479 fw_parent_device(ff->unit)->max_speed);
480 if (err < 0)
481 fw_iso_resources_free(&ff->tx_resources);
482
483 return err;
484 }
485
ff400_begin_session(struct snd_ff * ff,unsigned int rate)486 static int ff400_begin_session(struct snd_ff *ff, unsigned int rate)
487 {
488 unsigned int generation = ff->rx_resources.generation;
489 __le32 reg;
490 int err;
491
492 if (generation != fw_parent_device(ff->unit)->card->generation) {
493 err = fw_iso_resources_update(&ff->tx_resources);
494 if (err < 0)
495 return err;
496
497 err = fw_iso_resources_update(&ff->rx_resources);
498 if (err < 0)
499 return err;
500 }
501
502 // Set isochronous channel and the number of quadlets of received
503 // packets.
504 reg = cpu_to_le32(((ff->rx_stream.data_block_quadlets << 3) << 8) |
505 ff->rx_resources.channel);
506 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
507 FF400_RX_PACKET_FORMAT, ®, sizeof(reg), 0);
508 if (err < 0)
509 return err;
510
511 // Set isochronous channel and the number of quadlets of transmitted
512 // packet.
513 // TODO: investigate the purpose of this 0x80.
514 reg = cpu_to_le32((0x80 << 24) |
515 (ff->tx_resources.channel << 5) |
516 (ff->tx_stream.data_block_quadlets));
517 err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
518 FF400_TX_PACKET_FORMAT, ®, sizeof(reg), 0);
519 if (err < 0)
520 return err;
521
522 // Allow to transmit packets.
523 reg = cpu_to_le32(0x00000001);
524 return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
525 FF400_ISOC_COMM_START, ®, sizeof(reg), 0);
526 }
527
ff400_finish_session(struct snd_ff * ff)528 static void ff400_finish_session(struct snd_ff *ff)
529 {
530 __le32 reg;
531
532 reg = cpu_to_le32(0x80000000);
533 snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,
534 FF400_ISOC_COMM_STOP, ®, sizeof(reg), 0);
535 }
536
parse_midi_msg(struct snd_ff * ff,u32 quad,unsigned int port)537 static void parse_midi_msg(struct snd_ff *ff, u32 quad, unsigned int port)
538 {
539 struct snd_rawmidi_substream *substream = READ_ONCE(ff->tx_midi_substreams[port]);
540
541 if (substream != NULL) {
542 u8 byte = (quad >> (16 * port)) & 0x000000ff;
543
544 snd_rawmidi_receive(substream, &byte, 1);
545 }
546 }
547
548 #define FF400_QUEUE_SIZE 32
549
550 struct ff400_msg_parser {
551 struct {
552 u32 msg;
553 u32 tstamp;
554 } msgs[FF400_QUEUE_SIZE];
555 size_t push_pos;
556 size_t pull_pos;
557 };
558
ff400_has_msg(struct snd_ff * ff)559 static bool ff400_has_msg(struct snd_ff *ff)
560 {
561 struct ff400_msg_parser *parser = ff->msg_parser;
562
563 return (parser->push_pos != parser->pull_pos);
564 }
565
566 // For Fireface 400, lower 4 bytes of destination address is configured by bit
567 // flag in quadlet register (little endian) at 0x'0000'801'0051c. Drivers can
568 // select one of 4 options:
569 //
570 // bit flags: offset of destination address
571 // - 0x04000000: 0x'....'....'0000'0000
572 // - 0x08000000: 0x'....'....'0000'0080
573 // - 0x10000000: 0x'....'....'0000'0100
574 // - 0x20000000: 0x'....'....'0000'0180
575 //
576 // Drivers can suppress the device to transfer asynchronous transactions by
577 // using below 2 bits.
578 // - 0x01000000: suppress transmission
579 // - 0x02000000: suppress transmission
580 //
581 // Actually, the register is write-only and includes the other options such as
582 // input attenuation. This driver allocates destination address with '0000'0000
583 // in its lower offset and expects userspace application to configure the
584 // register for it.
585
586 // When the message is for signal level operation, the upper 4 bits in MSB expresses the pair of
587 // stereo physical port.
588 // - 0: Microphone input 0/1
589 // - 1: Line input 0/1
590 // - [2-4]: Line output 0-5
591 // - 5: Headphone output 0/1
592 // - 6: S/PDIF output 0/1
593 // - [7-10]: ADAT output 0-7
594 //
595 // The value of signal level can be detected by mask of 0x00fffc00. For signal level of microphone
596 // input:
597 //
598 // - 0: 0.0 dB
599 // - 10: +10.0 dB
600 // - 11: +11.0 dB
601 // - 12: +12.0 dB
602 // - ...
603 // - 63: +63.0 dB:
604 // - 64: +64.0 dB:
605 // - 65: +65.0 dB:
606 //
607 // For signal level of line input:
608 //
609 // - 0: 0.0 dB
610 // - 1: +0.5 dB
611 // - 2: +1.0 dB
612 // - 3: +1.5 dB
613 // - ...
614 // - 34: +17.0 dB:
615 // - 35: +17.5 dB:
616 // - 36: +18.0 dB:
617 //
618 // For signal level of any type of output:
619 //
620 // - 63: -infinite
621 // - 62: -58.0 dB
622 // - 61: -56.0 dB
623 // - 60: -54.0 dB
624 // - 59: -53.0 dB
625 // - 58: -52.0 dB
626 // - ...
627 // - 7: -1.0 dB
628 // - 6: 0.0 dB
629 // - 5: +1.0 dB
630 // - ...
631 // - 2: +4.0 dB
632 // - 1: +5.0 dB
633 // - 0: +6.0 dB
634 //
635 // When the message is not for signal level operation, it's for MIDI bytes. When matching to
636 // FF400_MSG_FLAG_IS_MIDI_PORT_0, one MIDI byte can be detected by mask of 0x000000ff. When
637 // matching to FF400_MSG_FLAG_IS_MIDI_PORT_1, one MIDI byte can be detected by mask of 0x00ff0000.
638 #define FF400_MSG_FLAG_IS_SIGNAL_LEVEL 0x04000000
639 #define FF400_MSG_FLAG_IS_RIGHT_CHANNEL 0x08000000
640 #define FF400_MSG_FLAG_IS_STEREO_PAIRED 0x02000000
641 #define FF400_MSG_MASK_STEREO_PAIR 0xf0000000
642 #define FF400_MSG_MASK_SIGNAL_LEVEL 0x00fffc00
643 #define FF400_MSG_FLAG_IS_MIDI_PORT_0 0x00000100
644 #define FF400_MSG_MASK_MIDI_PORT_0 0x000000ff
645 #define FF400_MSG_FLAG_IS_MIDI_PORT_1 0x01000000
646 #define FF400_MSG_MASK_MIDI_PORT_1 0x00ff0000
647
ff400_handle_msg(struct snd_ff * ff,unsigned int offset,const __le32 * buf,size_t length,u32 tstamp)648 static void ff400_handle_msg(struct snd_ff *ff, unsigned int offset, const __le32 *buf,
649 size_t length, u32 tstamp)
650 {
651 bool need_hwdep_wake_up = false;
652 int i;
653
654 for (i = 0; i < length / 4; i++) {
655 u32 quad = le32_to_cpu(buf[i]);
656
657 if (quad & FF400_MSG_FLAG_IS_SIGNAL_LEVEL) {
658 struct ff400_msg_parser *parser = ff->msg_parser;
659
660 parser->msgs[parser->push_pos].msg = quad;
661 parser->msgs[parser->push_pos].tstamp = tstamp;
662 ++parser->push_pos;
663 if (parser->push_pos >= FF400_QUEUE_SIZE)
664 parser->push_pos = 0;
665
666 need_hwdep_wake_up = true;
667 } else if (quad & FF400_MSG_FLAG_IS_MIDI_PORT_0) {
668 parse_midi_msg(ff, quad, 0);
669 } else if (quad & FF400_MSG_FLAG_IS_MIDI_PORT_1) {
670 parse_midi_msg(ff, quad, 1);
671 }
672 }
673
674 if (need_hwdep_wake_up)
675 wake_up(&ff->hwdep_wait);
676 }
677
ff400_copy_msg_to_user(struct snd_ff * ff,char __user * buf,long count)678 static long ff400_copy_msg_to_user(struct snd_ff *ff, char __user *buf, long count)
679 {
680 struct snd_firewire_event_ff400_message ev = {
681 .type = SNDRV_FIREWIRE_EVENT_FF400_MESSAGE,
682 .message_count = 0,
683 };
684 struct ff400_msg_parser *parser = ff->msg_parser;
685 long consumed = 0;
686 long ret = 0;
687
688 if (count < sizeof(ev) || parser->pull_pos == parser->push_pos)
689 return 0;
690
691 count -= sizeof(ev);
692 consumed += sizeof(ev);
693
694 while (count >= sizeof(*parser->msgs) && parser->pull_pos != parser->push_pos) {
695 spin_unlock_irq(&ff->lock);
696 if (copy_to_user(buf + consumed, parser->msgs + parser->pull_pos,
697 sizeof(*parser->msgs)))
698 ret = -EFAULT;
699 spin_lock_irq(&ff->lock);
700 if (ret)
701 return ret;
702
703 ++parser->pull_pos;
704 if (parser->pull_pos >= FF400_QUEUE_SIZE)
705 parser->pull_pos = 0;
706 ++ev.message_count;
707 count -= sizeof(*parser->msgs);
708 consumed += sizeof(*parser->msgs);
709 }
710
711 spin_unlock_irq(&ff->lock);
712 if (copy_to_user(buf, &ev, sizeof(ev)))
713 ret = -EFAULT;
714 spin_lock_irq(&ff->lock);
715 if (ret)
716 return ret;
717
718 return consumed;
719 }
720
721 const struct snd_ff_protocol snd_ff_protocol_ff400 = {
722 .msg_parser_size = sizeof(struct ff400_msg_parser),
723 .has_msg = ff400_has_msg,
724 .copy_msg_to_user = ff400_copy_msg_to_user,
725 .handle_msg = ff400_handle_msg,
726 .fill_midi_msg = former_fill_midi_msg,
727 .get_clock = former_get_clock,
728 .switch_fetching_mode = former_switch_fetching_mode,
729 .allocate_resources = ff400_allocate_resources,
730 .begin_session = ff400_begin_session,
731 .finish_session = ff400_finish_session,
732 .dump_status = former_dump_status,
733 };
734