1 /* $NetBSD: umidi_quirks.c,v 1.22 2019/05/08 13:40:19 isaki Exp $ */
2
3 /*
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Takuya SHIOZAKI (tshiozak@NetBSD.org).
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.22 2019/05/08 13:40:19 isaki Exp $");
34
35 #ifdef _KERNEL_OPT
36 #include "opt_usb.h"
37 #endif
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/audioio.h>
43 #include <sys/device.h>
44 #include <sys/ioctl.h>
45 #include <sys/conf.h>
46 #include <sys/file.h>
47 #include <sys/select.h>
48 #include <sys/proc.h>
49 #include <sys/vnode.h>
50 #include <sys/poll.h>
51
52 #include <dev/usb/usb.h>
53 #include <dev/usb/usbdi.h>
54 #include <dev/usb/usbdi_util.h>
55
56 #include <dev/usb/usbdevs.h>
57 #include <dev/usb/uaudioreg.h>
58 #include <dev/usb/umidi_quirks.h>
59
60 /*
61 * quirk codes for UMIDI
62 */
63
64 #ifdef UMIDIQUIRK_DEBUG
65 #define DPRINTF(x) if (umidiquirkdebug) printf x
66 #define DPRINTFN(n,x) if (umidiquirkdebug >= (n)) printf x
67 int umidiquirkdebug = 1;
68 #else
69 #define DPRINTF(x)
70 #define DPRINTFN(n,x)
71 #endif
72
73
74 /*
75 * YAMAHA UX-256
76 * --- this is a typical yamaha device, but has a broken descriptor :-<
77 */
78
79 UMQ_FIXED_EP_DATA_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = {
80 /* out */
81 { 0, 16 },
82 /* in */
83 { 1, 8 }
84 };
85 UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1);
86
87 UMQ_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE) = {
88 UMQ_FIXED_EP_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
89 #if 0
90 UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
91 #endif
92 UMQ_TERMINATOR
93 };
94
95
96 /*
97 * YAMAHA generic
98 */
99 UMQ_DEF(YAMAHA, ANYPRODUCT, ANYIFACE) = {
100 UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
101 UMQ_TERMINATOR
102 };
103
104
105 /*
106 * ROLAND UM-1
107 */
108 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = {
109 /* out */
110 { 0, 1 },
111 /* in */
112 { 1, 1 }
113 };
114 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1);
115
116 UMQ_DEF(ROLAND, ROLAND_UM1, 2) = {
117 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2),
118 UMQ_TERMINATOR
119 };
120
121 /*
122 * ROLAND SC-8850
123 */
124 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = {
125 /* out */
126 { 0, 6 },
127 /* in */
128 { 1, 6 }
129 };
130 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1);
131
132 UMQ_DEF(ROLAND, ROLAND_SC8850, 2) = {
133 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8850, 2),
134 UMQ_TERMINATOR
135 };
136
137 /*
138 * ROLAND SD-90
139 */
140 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = {
141 /* out */
142 { 0, 4 },
143 /* in */
144 { 1, 4 }
145 };
146 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1);
147
148 UMQ_DEF(ROLAND, ROLAND_SD90, 2) = {
149 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD90, 2),
150 UMQ_TERMINATOR
151 };
152
153
154 /*
155 * ROLAND UM-880 (native mode)
156 */
157 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = {
158 /* out */
159 { 0, 9 },
160 /* in */
161 { 1, 9 }
162 };
163 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1);
164
165 UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = {
166 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0),
167 UMQ_TERMINATOR
168 };
169
170 /*
171 * ROLAND UA-100
172 */
173 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = {
174 /* out */
175 { 0, 3 },
176 /* in */
177 { 1, 3 }
178 };
179 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1);
180
181 UMQ_DEF(ROLAND, ROLAND_UA100, 2) = {
182 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA100, 2),
183 UMQ_TERMINATOR
184 };
185
186 /*
187 * ROLAND UM-4
188 */
189 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = {
190 /* out */
191 { 0, 4 },
192 /* in */
193 { 1, 4 }
194 };
195 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1);
196
197 UMQ_DEF(ROLAND, ROLAND_UM4, 2) = {
198 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM4, 2),
199 UMQ_TERMINATOR
200 };
201
202 /*
203 * ROLAND U-8
204 */
205 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_U8, 2, 1, 1) = {
206 /* out */
207 { 0, 2 },
208 /* in */
209 { 1, 2 }
210 };
211 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1);
212
213 UMQ_DEF(ROLAND, ROLAND_U8, 2) = {
214 UMQ_FIXED_EP_REG(ROLAND, ROLAND_U8, 2),
215 UMQ_TERMINATOR
216 };
217
218 /*
219 * ROLAND UM-2
220 */
221 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = {
222 /* out */
223 { 0, 2 },
224 /* in */
225 { 1, 2 }
226 };
227 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1);
228
229 UMQ_DEF(ROLAND, ROLAND_UM2, 2) = {
230 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM2, 2),
231 UMQ_TERMINATOR
232 };
233
234 /*
235 * ROLAND SC-8820
236 */
237 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1) = {
238 /* out */
239 { 0, 5 }, /* cables 0, 1, 4 only */
240 /* in */
241 { 1, 5 } /* do. */
242 };
243 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1);
244
245 UMQ_DEF(ROLAND, ROLAND_SC8820, 2) = {
246 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8820, 2),
247 UMQ_TERMINATOR
248 };
249
250 /*
251 * ROLAND PC-300
252 */
253 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = {
254 /* out */
255 { 0, 1 },
256 /* in */
257 { 1, 1 }
258 };
259 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1);
260
261 UMQ_DEF(ROLAND, ROLAND_PC300, 2) = {
262 UMQ_FIXED_EP_REG(ROLAND, ROLAND_PC300, 2),
263 UMQ_TERMINATOR
264 };
265
266 /*
267 * ROLAND SK-500
268 */
269 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SK500, 2, 1, 1) = {
270 /* out */
271 { 0, 5 }, /* cables 0, 1, 4 only */
272 /* in */
273 { 1, 5 } /* do. */
274 };
275 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1);
276
277 UMQ_DEF(ROLAND, ROLAND_SK500, 2) = {
278 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SK500, 2),
279 UMQ_TERMINATOR
280 };
281
282 /*
283 * ROLAND SC-D70
284 */
285 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = {
286 /* out */
287 { 0, 3 },
288 /* in */
289 { 1, 3 }
290 };
291 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1);
292
293 UMQ_DEF(ROLAND, ROLAND_SCD70, 2) = {
294 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SCD70, 2),
295 UMQ_TERMINATOR
296 };
297
298 /*
299 * ROLAND XV-5050
300 */
301 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1) = {
302 /* out */
303 { 0, 1 },
304 /* in */
305 { 1, 1 }
306 };
307 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_XV5050, 0, 1, 1);
308
309 UMQ_DEF(ROLAND, ROLAND_XV5050, 0) = {
310 UMQ_FIXED_EP_REG(ROLAND, ROLAND_XV5050, 0),
311 UMQ_TERMINATOR
312 };
313
314 /*
315 * ROLAND UM-550
316 */
317 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = {
318 /* out */
319 { 0, 6 },
320 /* in */
321 { 1, 6 }
322 };
323 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1);
324
325 UMQ_DEF(ROLAND, ROLAND_UM550, 0) = {
326 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM550, 0),
327 UMQ_TERMINATOR
328 };
329
330 /*
331 * ROLAND SD-20
332 */
333 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = {
334 /* out */
335 { 0, 2 },
336 /* in */
337 { 1, 3 }
338 };
339 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1);
340
341 UMQ_DEF(ROLAND, ROLAND_SD20, 0) = {
342 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD20, 0),
343 UMQ_TERMINATOR
344 };
345
346 /*
347 * ROLAND SD-80
348 */
349 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = {
350 /* out */
351 { 0, 4 },
352 /* in */
353 { 1, 4 }
354 };
355 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1);
356
357 UMQ_DEF(ROLAND, ROLAND_SD80, 0) = {
358 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD80, 0),
359 UMQ_TERMINATOR
360 };
361
362 /*
363 * ROLAND UA-700
364 */
365 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = {
366 /* out */
367 { 0, 2 },
368 /* in */
369 { 1, 2 }
370 };
371 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1);
372
373 UMQ_DEF(ROLAND, ROLAND_UA700, 3) = {
374 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA700, 3),
375 UMQ_TERMINATOR
376 };
377
378 /*
379 * ROLAND UA-1000
380 */
381 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1) = {
382 /* out */
383 { 0, 2 },
384 /* in */
385 { 1, 2 }
386 };
387 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA1000, 3, 1, 1);
388
389 UMQ_DEF(ROLAND, ROLAND_UA1000, 3) = {
390 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA1000, 3),
391 UMQ_TERMINATOR
392 };
393
394 /*
395 * ROLAND UA-101
396 */
397 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101, 2, 1, 1) = {
398 /* out */
399 { 0, 2 },
400 /* in */
401 { 1, 2 }
402 };
403 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101, 2, 1, 1);
404
405 UMQ_DEF(ROLAND, ROLAND_UA101, 2) = {
406 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101, 2),
407 UMQ_TERMINATOR
408 };
409
410 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1) = {
411 /* out */
412 { 0, 2 },
413 /* in */
414 { 1, 2 }
415 };
416 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA101F, 2, 1, 1);
417
418 UMQ_DEF(ROLAND, ROLAND_UA101F, 2) = {
419 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA101F, 2),
420 UMQ_TERMINATOR
421 };
422
423 /*
424 * ROLAND Fantom-X
425 */
426 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1) = {
427 /* out */
428 { 0, 1 },
429 /* in */
430 { 1, 1 }
431 };
432 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_FANTOMX, 0, 1, 1);
433
434 UMQ_DEF(ROLAND, ROLAND_FANTOMX, 0) = {
435 UMQ_FIXED_EP_REG(ROLAND, ROLAND_FANTOMX, 0),
436 UMQ_TERMINATOR
437 };
438
439 /*
440 * ROLAND PCR
441 */
442 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_PCR, 0, 1, 1) = {
443 /* out */
444 { 0, 3 },
445 /* in */
446 { 1, 3 }
447 };
448 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PCR, 0, 1, 1);
449
450 UMQ_DEF(ROLAND, ROLAND_PCR, 0) = {
451 UMQ_FIXED_EP_REG(ROLAND, ROLAND_PCR, 0),
452 UMQ_TERMINATOR
453 };
454
455 /*
456 * ROLAND UM-3EX
457 */
458 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UM3, 0, 1, 1) = {
459 /* out */
460 { 0, 3 },
461 /* in */
462 { 1, 3 }
463 };
464 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM3, 0, 1, 1);
465
466 UMQ_DEF(ROLAND, ROLAND_UM3, 0) = {
467 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM3, 0),
468 UMQ_TERMINATOR
469 };
470
471 /*
472 * ROLAND UA-25
473 */
474 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA25, 2, 1, 1) = {
475 /* out */
476 { 0, 1 },
477 /* in */
478 { 1, 1 }
479 };
480 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA25, 2, 1, 1);
481
482 UMQ_DEF(ROLAND, ROLAND_UA25, 2) = {
483 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA25, 2),
484 UMQ_TERMINATOR
485 };
486
487 /*
488 * ROLAND UA-4FX
489 */
490 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1) = {
491 /* out */
492 { 0, 1 },
493 /* in */
494 { 1, 1 }
495 };
496 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA4FX, 2, 1, 1);
497
498 UMQ_DEF(ROLAND, ROLAND_UA4FX, 2) = {
499 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA4FX, 2),
500 UMQ_TERMINATOR
501 };
502
503 /*
504 * ROLAND SonicCell
505 */
506 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1) = {
507 /* out */
508 { 0, 1 },
509 /* in */
510 { 1, 1 }
511 };
512 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SONICCELL, 2, 1, 1);
513
514 UMQ_DEF(ROLAND, ROLAND_SONICCELL, 2) = {
515 UMQ_FIXED_EP_REG(ROLAND, ROLAND_SONICCELL, 2),
516 UMQ_TERMINATOR
517 };
518
519 /*
520 * ROLAND UM-ONE
521 */
522 UMQ_FIXED_EP_DATA_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1) = {
523 /* out */
524 { 0, 1 },
525 /* in */
526 { 1, 1 }
527 };
528 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1);
529
530 UMQ_DEF(ROLAND, ROLAND_UMONE, ANYIFACE) = {
531 UMQ_FIXED_EP_REG(ROLAND, ROLAND_UMONE, ANYIFACE),
532 UMQ_TERMINATOR
533 };
534
535 /*
536 * Midiman Midisport 2x4. This has 2 physical MIDI IN jacks that are read
537 * on endpoint 0x81 (descriptor index 0). It has 4 physical MIDI OUT jacks
538 * that can be written on endpoints 2 or 4 (at descriptor index 2 or 4,
539 * coincidentally) interchangeably: either endpoint will accept a Cable Number
540 * field of 0 to 3, and data for a given CN will be routed to the same
541 * physical output regardless of the endpoint used for the transfer. But
542 * there's a catch: flow-control feedback only goes to endpoint 2 for
543 * CN 0 and 2, and only to endpoint 4 for CN 1 and 3. If you send output at
544 * high rates for CN 0 or 2 over endpoint 4, or for CN 1 or 3 over endpoint 2,
545 * the USB transfers complete as fast as possible, giving you an apparent data
546 * rate much higher than MIDI's 3125 cps (easy to measure using dd to blast a
547 * bunch of midi data to the rmidi device). Of course that isn't a way to make
548 * MIDI faster, just a way to overrun the device buffer and spray bits on the
549 * floor. So this device needs the fixed endpoint quirk, the fixed cable number
550 * quirk (to make sure CNs 0 and 2 are put on the first endpoint and 1 and 3
551 * on the other), and then the fixed mididev-assignment quirk (to match jacks
552 * to mididevs so the rmidi devices match the order of the blinkenlights).
553 */
554 UMQ_FIXED_EP_DATA_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1) = {
555 /* out: ep# jacks */
556 { 2, 2 },
557 { 4, 2 },
558 /* in: ep# jacks */
559 { 0, 2 }
560 };
561 UMQ_FIXED_EP_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE, 2, 1);
562 UMQ_FIXED_CN_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
563 0, 2, 1, 3, 0, 1
564 };
565 UMQ_FIXED_MD_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
566 0, 0, 2, 1, 1, -1, 3, -1
567 };
568 UMQ_DEF(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE) = {
569 UMQ_FIXED_EP_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
570 UMQ_FIXED_CN_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
571 UMQ_FIXED_MD_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
572 UMQ_TYPE(MIDIMAN_GARBLE),
573 UMQ_TERMINATOR
574 };
575
576 /*
577 * quirk list
578 */
579 static struct umidi_quirk umidi_quirklist[] = {
580 UMQ_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
581 UMQ_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
582 UMQ_REG(ROLAND, ROLAND_UM1, 2),
583 UMQ_REG(ROLAND, ROLAND_SC8850, 2),
584 UMQ_REG(ROLAND, ROLAND_SD90, 2),
585 UMQ_REG(ROLAND, ROLAND_UM880N, 0),
586 UMQ_REG(ROLAND, ROLAND_UA100, 2),
587 UMQ_REG(ROLAND, ROLAND_UM4, 2),
588 UMQ_REG(ROLAND, ROLAND_U8, 2),
589 UMQ_REG(ROLAND, ROLAND_UM2, 2),
590 UMQ_REG(ROLAND, ROLAND_SC8820, 2),
591 UMQ_REG(ROLAND, ROLAND_PC300, 2),
592 UMQ_REG(ROLAND, ROLAND_SK500, 2),
593 UMQ_REG(ROLAND, ROLAND_SCD70, 2),
594 UMQ_REG(ROLAND, ROLAND_XV5050, 0),
595 UMQ_REG(ROLAND, ROLAND_UM550, 0),
596 UMQ_REG(ROLAND, ROLAND_SD20, 0),
597 UMQ_REG(ROLAND, ROLAND_SD80, 0),
598 UMQ_REG(ROLAND, ROLAND_UA700, 3),
599 UMQ_REG(ROLAND, ROLAND_UA1000, 3),
600 UMQ_REG(ROLAND, ROLAND_UA101, 2),
601 UMQ_REG(ROLAND, ROLAND_UA101F, 2),
602 UMQ_REG(ROLAND, ROLAND_FANTOMX, 0),
603 UMQ_REG(ROLAND, ROLAND_PCR, 0),
604 UMQ_REG(ROLAND, ROLAND_UM3, 0),
605 UMQ_REG(ROLAND, ROLAND_UA25, 2),
606 UMQ_REG(ROLAND, ROLAND_UA4FX, 2),
607 UMQ_REG(ROLAND, ROLAND_SONICCELL, 2),
608 UMQ_REG(ROLAND, ROLAND_UMONE, ANYIFACE),
609 UMQ_REG(MIDIMAN, MIDIMAN_MIDISPORT2X4, ANYIFACE),
610 { .vendor = 0 },
611 };
612
613
614 /*
615 * quirk utilities
616 */
617
618 const struct umidi_quirk *
umidi_search_quirk(int vendor,int product,int ifaceno)619 umidi_search_quirk(int vendor, int product, int ifaceno)
620 {
621 struct umidi_quirk *p;
622 const struct umq_data *q;
623
624 DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n",
625 vendor, product, ifaceno));
626
627 for (p=&umidi_quirklist[0]; p->vendor; p++) {
628 DPRINTFN(10, ("\tv=%d, p=%d, i=%d",
629 p->vendor, p->product, p->iface));
630 if ((p->vendor==vendor || p->vendor==ANYVENDOR) &&
631 (p->product==product || p->product==ANYPRODUCT) &&
632 (p->iface==ifaceno || p->iface==ANYIFACE)) {
633 DPRINTFN(10, (" found\n"));
634 if (!p->type_mask)
635 /* make quirk mask */
636 for (q=p->quirks; q->type; q++)
637 p->type_mask |= 1<<(q->type-1);
638 return p;
639 }
640 DPRINTFN(10, ("\n"));
641 }
642
643 return NULL;
644 }
645
646 static const char *quirk_name[] = {
647 "NULL",
648 "Fixed Endpoint",
649 "Yamaha Specific",
650 "Midiman Packet Garbling",
651 "Cable Numbers per Endpoint",
652 "Cable Numbers Global",
653 "Cable Numbers Fixed",
654 "Unit Mapping Fixed",
655 };
656
657 void
umidi_print_quirk(const struct umidi_quirk * q)658 umidi_print_quirk(const struct umidi_quirk *q)
659 {
660 const struct umq_data *qd;
661 if (q) {
662 printf("(");
663 for (qd=q->quirks; qd->type; qd++)
664 printf("%s%s", quirk_name[qd->type],
665 (qd+1)->type?", ":")\n");
666 } else {
667 printf("(genuine USB-MIDI)\n");
668 }
669 }
670
671 const void *
umidi_get_quirk_data_from_type(const struct umidi_quirk * q,uint32_t type)672 umidi_get_quirk_data_from_type(const struct umidi_quirk *q, uint32_t type)
673 {
674 const struct umq_data *qd;
675 if (q) {
676 for (qd=q->quirks; qd->type; qd++)
677 if (qd->type == type)
678 return qd->data;
679 }
680 return NULL;
681 }
682