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