Line data Source code
1 : /* $OpenBSD: umidi_quirks.c,v 1.16 2018/01/18 18:09:38 ratchov Exp $ */
2 : /* $NetBSD: umidi_quirks.c,v 1.4 2002/06/19 13:55:30 tshiozak Exp $ */
3 :
4 : /*
5 : * Copyright (c) 2001 The NetBSD Foundation, Inc.
6 : * All rights reserved.
7 : *
8 : * This code is derived from software contributed to The NetBSD Foundation
9 : * by Takuya SHIOZAKI (tshiozak@netbsd.org).
10 : *
11 : * Redistribution and use in source and binary forms, with or without
12 : * modification, are permitted provided that the following conditions
13 : * are met:
14 : * 1. Redistributions of source code must retain the above copyright
15 : * notice, this list of conditions and the following disclaimer.
16 : * 2. Redistributions in binary form must reproduce the above copyright
17 : * notice, this list of conditions and the following disclaimer in the
18 : * documentation and/or other materials provided with the distribution.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 : * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 : * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 : * POSSIBILITY OF SUCH DAMAGE.
31 : */
32 :
33 : #include <sys/param.h>
34 : #include <sys/systm.h>
35 : #include <sys/kernel.h>
36 : #include <sys/device.h>
37 : #include <sys/ioctl.h>
38 : #include <sys/conf.h>
39 : #include <sys/selinfo.h>
40 : #include <sys/poll.h>
41 :
42 : #include <dev/usb/usb.h>
43 : #include <dev/usb/usbdi.h>
44 : #include <dev/usb/usbdi_util.h>
45 :
46 : #include <dev/usb/usbdevs.h>
47 : #include <dev/usb/umidireg.h>
48 : #include <dev/usb/umidivar.h>
49 : #include <dev/usb/umidi_quirks.h>
50 :
51 : /*
52 : * quirk codes for UMIDI
53 : */
54 :
55 : #ifdef UMIDIQUIRK_DEBUG
56 : #define DPRINTF(x) if (umidiquirkdebug) printf x
57 : #define DPRINTFN(n,x) if (umidiquirkdebug >= (n)) printf x
58 : int umidiquirkdebug = 1;
59 : #else
60 : #define DPRINTF(x)
61 : #define DPRINTFN(n,x)
62 : #endif
63 :
64 :
65 : /*
66 : * YAMAHA UX-256
67 : * --- this is a typical yamaha device, but has a broken descriptor :-<
68 : */
69 :
70 : UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = {
71 : /* out */
72 : { 0, 16 },
73 : /* in */
74 : { 1, 8 }
75 : };
76 :
77 : UMQ_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE) = {
78 : UMQ_FIXED_EP_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
79 : UMQ_TERMINATOR
80 : };
81 :
82 : /*
83 : * ROLAND UM-1
84 : */
85 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = {
86 : /* out */
87 : { 0, 1 },
88 : /* in */
89 : { 1, 1 }
90 : };
91 :
92 : UMQ_DEF(ROLAND, ROLAND_UM1, 2) = {
93 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2),
94 : UMQ_TERMINATOR
95 : };
96 :
97 : /*
98 : * ROLAND SC-8850
99 : */
100 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = {
101 : /* out */
102 : { 0, 6 },
103 : /* in */
104 : { 1, 6 }
105 : };
106 :
107 : UMQ_DEF(ROLAND, ROLAND_SC8850, 2) = {
108 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8850, 2),
109 : UMQ_TERMINATOR
110 : };
111 :
112 : /*
113 : * ROLAND SD-90
114 : */
115 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = {
116 : /* out */
117 : { 0, 4 },
118 : /* in */
119 : { 1, 4 }
120 : };
121 :
122 : UMQ_DEF(ROLAND, ROLAND_SD90, 2) = {
123 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD90, 2),
124 : UMQ_TERMINATOR
125 : };
126 :
127 :
128 : /*
129 : * ROLAND UM-880 (native mode)
130 : */
131 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = {
132 : /* out */
133 : { 0, 9 },
134 : /* in */
135 : { 1, 9 }
136 : };
137 :
138 : UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = {
139 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0),
140 : UMQ_TERMINATOR
141 : };
142 :
143 : /*
144 : * ROLAND UA-100
145 : */
146 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = {
147 : /* out */
148 : { 0, 3 },
149 : /* in */
150 : { 1, 3 }
151 : };
152 :
153 : UMQ_DEF(ROLAND, ROLAND_UA100, 2) = {
154 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA100, 2),
155 : UMQ_TERMINATOR
156 : };
157 :
158 : /*
159 : * ROLAND UM-4
160 : */
161 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = {
162 : /* out */
163 : { 0, 4 },
164 : /* in */
165 : { 1, 4 }
166 : };
167 :
168 : UMQ_DEF(ROLAND, ROLAND_UM4, 2) = {
169 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM4, 2),
170 : UMQ_TERMINATOR
171 : };
172 :
173 : /*
174 : * ROLAND U-8
175 : */
176 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1) = {
177 : /* out */
178 : { 0, 2 },
179 : /* in */
180 : { 1, 2 }
181 : };
182 :
183 : UMQ_DEF(ROLAND, ROLAND_U8, 2) = {
184 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_U8, 2),
185 : UMQ_TERMINATOR
186 : };
187 :
188 : /*
189 : * ROLAND UM-2
190 : */
191 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = {
192 : /* out */
193 : { 0, 2 },
194 : /* in */
195 : { 1, 2 }
196 : };
197 :
198 : UMQ_DEF(ROLAND, ROLAND_UM2, 2) = {
199 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM2, 2),
200 : UMQ_TERMINATOR
201 : };
202 :
203 : /*
204 : * ROLAND SC-8820
205 : */
206 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1) = {
207 : /* out */
208 : { 0, 5 }, /* cables 0, 1, 4 only */
209 : /* in */
210 : { 1, 5 } /* do. */
211 : };
212 :
213 : UMQ_DEF(ROLAND, ROLAND_SC8820, 2) = {
214 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8820, 2),
215 : UMQ_TERMINATOR
216 : };
217 :
218 : /*
219 : * ROLAND PC-300
220 : */
221 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = {
222 : /* out */
223 : { 0, 1 },
224 : /* in */
225 : { 1, 1 }
226 : };
227 :
228 : UMQ_DEF(ROLAND, ROLAND_PC300, 2) = {
229 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_PC300, 2),
230 : UMQ_TERMINATOR
231 : };
232 :
233 : /*
234 : * ROLAND SK-500
235 : */
236 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1) = {
237 : /* out */
238 : { 0, 5 }, /* cables 0, 1, 4 only */
239 : /* in */
240 : { 1, 5 } /* do. */
241 : };
242 :
243 : UMQ_DEF(ROLAND, ROLAND_SK500, 2) = {
244 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_SK500, 2),
245 : UMQ_TERMINATOR
246 : };
247 :
248 : /*
249 : * ROLAND SC-D70
250 : */
251 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = {
252 : /* out */
253 : { 0, 3 },
254 : /* in */
255 : { 1, 3 }
256 : };
257 :
258 : UMQ_DEF(ROLAND, ROLAND_SCD70, 2) = {
259 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_SCD70, 2),
260 : UMQ_TERMINATOR
261 : };
262 :
263 : /*
264 : * ROLAND UM-550
265 : */
266 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = {
267 : /* out */
268 : { 0, 6 },
269 : /* in */
270 : { 1, 6 }
271 : };
272 :
273 : UMQ_DEF(ROLAND, ROLAND_UM550, 0) = {
274 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM550, 0),
275 : UMQ_TERMINATOR
276 : };
277 :
278 : /*
279 : * ROLAND SD-20
280 : */
281 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = {
282 : /* out */
283 : { 0, 2 },
284 : /* in */
285 : { 1, 3 }
286 : };
287 :
288 : UMQ_DEF(ROLAND, ROLAND_SD20, 0) = {
289 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD20, 0),
290 : UMQ_TERMINATOR
291 : };
292 :
293 : /*
294 : * ROLAND SD-80
295 : */
296 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = {
297 : /* out */
298 : { 0, 4 },
299 : /* in */
300 : { 1, 4 }
301 : };
302 :
303 : UMQ_DEF(ROLAND, ROLAND_SD80, 0) = {
304 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD80, 0),
305 : UMQ_TERMINATOR
306 : };
307 :
308 : /*
309 : * ROLAND UA-700
310 : */
311 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = {
312 : /* out */
313 : { 0, 2 },
314 : /* in */
315 : { 1, 2 }
316 : };
317 :
318 : UMQ_DEF(ROLAND, ROLAND_UA700, 3) = {
319 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA700, 3),
320 : UMQ_TERMINATOR
321 : };
322 :
323 : /*
324 : * ROLAND UM-ONE
325 : */
326 : UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1) = {
327 : /* out */
328 : { 0, 1 },
329 : /* in */
330 : { 1, 1 }
331 : };
332 :
333 : UMQ_DEF(ROLAND, ROLAND_UMONE, ANYIFACE) = {
334 : UMQ_FIXED_EP_REG(ROLAND, ROLAND_UMONE, ANYIFACE),
335 : UMQ_TERMINATOR
336 : };
337 :
338 : /*
339 : * quirk list
340 : */
341 : struct umidi_quirk umidi_quirklist[] = {
342 : UMQ_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
343 : UMQ_REG(ROLAND, ROLAND_UM1, 2),
344 : UMQ_REG(ROLAND, ROLAND_SC8850, 2),
345 : UMQ_REG(ROLAND, ROLAND_SD90, 2),
346 : UMQ_REG(ROLAND, ROLAND_UM880N, 0),
347 : UMQ_REG(ROLAND, ROLAND_UA100, 2),
348 : UMQ_REG(ROLAND, ROLAND_UM4, 2),
349 : UMQ_REG(ROLAND, ROLAND_U8, 2),
350 : UMQ_REG(ROLAND, ROLAND_UM2, 2),
351 : UMQ_REG(ROLAND, ROLAND_SC8820, 2),
352 : UMQ_REG(ROLAND, ROLAND_PC300, 2),
353 : UMQ_REG(ROLAND, ROLAND_SK500, 2),
354 : UMQ_REG(ROLAND, ROLAND_SCD70, 2),
355 : UMQ_REG(ROLAND, ROLAND_UM550, 0),
356 : UMQ_REG(ROLAND, ROLAND_SD20, 0),
357 : UMQ_REG(ROLAND, ROLAND_SD80, 0),
358 : UMQ_REG(ROLAND, ROLAND_UA700, 3),
359 : UMQ_REG(ROLAND, ROLAND_UMONE, ANYIFACE),
360 : UMQ_TERMINATOR
361 : };
362 :
363 :
364 : /*
365 : * quirk utilities
366 : */
367 :
368 : struct umidi_quirk *
369 0 : umidi_search_quirk(int vendor, int product, int ifaceno)
370 : {
371 : struct umidi_quirk *p;
372 : struct umq_data *q;
373 :
374 : DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n",
375 : vendor, product, ifaceno));
376 :
377 0 : for (p=&umidi_quirklist[0]; p->vendor; p++) {
378 : DPRINTFN(10, ("\tv=%d, p=%d, i=%d",
379 : p->vendor, p->product, p->iface));
380 0 : if ((p->vendor==vendor || p->vendor==ANYVENDOR) &&
381 0 : (p->product==product || p->product==ANYPRODUCT) &&
382 0 : (p->iface==ifaceno || p->iface==ANYIFACE)) {
383 : DPRINTFN(10, (" found\n"));
384 0 : if (!p->type_mask)
385 : /* make quirk mask */
386 0 : for (q=p->quirks; q->type; q++)
387 0 : p->type_mask |= 1<<(q->type-1);
388 0 : return p;
389 : }
390 : DPRINTFN(10, ("\n"));
391 : }
392 :
393 0 : return NULL;
394 0 : }
395 :
396 : static char *quirk_name[] = {
397 : "NULL",
398 : "Fixed Endpoint",
399 : "Yamaha Specific",
400 : };
401 :
402 : void
403 0 : umidi_print_quirk(struct umidi_quirk *q)
404 : {
405 : struct umq_data *qd;
406 0 : if (q) {
407 0 : printf("(");
408 0 : for (qd=q->quirks; qd->type; qd++)
409 0 : printf("%s%s", quirk_name[qd->type],
410 0 : (qd+1)->type?", ":")\n");
411 : } else {
412 0 : printf("(genuine USB-MIDI)\n");
413 : }
414 0 : }
415 :
416 : void *
417 0 : umidi_get_quirk_data_from_type(struct umidi_quirk *q, u_int32_t type)
418 : {
419 : struct umq_data *qd;
420 0 : if (q) {
421 0 : for (qd=q->quirks; qd->type; qd++)
422 0 : if (qd->type == type)
423 0 : return qd->data;
424 : }
425 0 : return NULL;
426 0 : }
|