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