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