xref: /openbsd-src/sys/dev/usb/umidi_quirks.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: umidi_quirks.c,v 1.12 2013/03/28 03:58:03 tedu 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/malloc.h>
37 #include <sys/device.h>
38 #include <sys/ioctl.h>
39 #include <sys/conf.h>
40 #include <sys/file.h>
41 #include <sys/selinfo.h>
42 #include <sys/poll.h>
43 
44 #include <dev/usb/usb.h>
45 #include <dev/usb/usbdi.h>
46 #include <dev/usb/usbdi_util.h>
47 
48 #include <dev/usb/usbdevs.h>
49 #include <dev/usb/uaudioreg.h>
50 #include <dev/usb/umidireg.h>
51 #include <dev/usb/umidivar.h>
52 #include <dev/usb/umidi_quirks.h>
53 
54 /*
55  * quirk codes for UMIDI
56  */
57 
58 #ifdef UMIDIQUIRK_DEBUG
59 #define DPRINTF(x)	if (umidiquirkdebug) printf x
60 #define DPRINTFN(n,x)	if (umidiquirkdebug >= (n)) printf x
61 int	umidiquirkdebug = 1;
62 #else
63 #define DPRINTF(x)
64 #define DPRINTFN(n,x)
65 #endif
66 
67 
68 /*
69  * YAMAHA UX-256
70  *  --- this is a typical yamaha device, but has a broken descriptor :-<
71  */
72 
73 UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = {
74 	/* out */
75 	{ 0, 16 },
76 	/* in */
77 	{ 1, 8 }
78 };
79 
80 UMQ_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE) = {
81 	UMQ_FIXED_EP_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
82 #if 0
83 	UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
84 #endif
85 	UMQ_TERMINATOR
86 };
87 
88 
89 /*
90  * YAMAHA generic
91  */
92 UMQ_DEF(YAMAHA, ANYPRODUCT, ANYIFACE) = {
93 	UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
94 	UMQ_TERMINATOR
95 };
96 
97 
98 /*
99  * ROLAND UM-1
100  */
101 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = {
102 	/* out */
103 	{ 0, 1 },
104 	/* in */
105 	{ 1, 1 }
106 };
107 
108 UMQ_DEF(ROLAND, ROLAND_UM1, 2) = {
109 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2),
110 	UMQ_TERMINATOR
111 };
112 
113 /*
114  * ROLAND SC-8850
115  */
116 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8850, 2, 1, 1) = {
117 	/* out */
118 	{ 0, 6 },
119 	/* in */
120 	{ 1, 6 }
121 };
122 
123 UMQ_DEF(ROLAND, ROLAND_SC8850, 2) = {
124 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8850, 2),
125 	UMQ_TERMINATOR
126 };
127 
128 /*
129  * ROLAND SD-90
130  */
131 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD90, 2, 1, 1) = {
132 	/* out */
133 	{ 0, 4 },
134 	/* in */
135 	{ 1, 4 }
136 };
137 
138 UMQ_DEF(ROLAND, ROLAND_SD90, 2) = {
139 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD90, 2),
140 	UMQ_TERMINATOR
141 };
142 
143 
144 /*
145  * ROLAND UM-880 (native mode)
146  */
147 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = {
148 	/* out */
149 	{ 0, 9 },
150 	/* in */
151 	{ 1, 9 }
152 };
153 
154 UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = {
155 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0),
156 	UMQ_TERMINATOR
157 };
158 
159 /*
160  * ROLAND UA-100
161  */
162 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA100, 2, 1, 1) = {
163 	/* out */
164 	{ 0, 3 },
165 	/* in */
166 	{ 1, 3 }
167 };
168 
169 UMQ_DEF(ROLAND, ROLAND_UA100, 2) = {
170 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA100, 2),
171 	UMQ_TERMINATOR
172 };
173 
174 /*
175  * ROLAND UM-4
176  */
177 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM4, 2, 1, 1) = {
178 	/* out */
179 	{ 0, 4 },
180 	/* in */
181 	{ 1, 4 }
182 };
183 
184 UMQ_DEF(ROLAND, ROLAND_UM4, 2) = {
185 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM4, 2),
186 	UMQ_TERMINATOR
187 };
188 
189 /*
190  * ROLAND U-8
191  */
192 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_U8, 2, 1, 1) = {
193 	/* out */
194 	{ 0, 2 },
195 	/* in */
196 	{ 1, 2 }
197 };
198 
199 UMQ_DEF(ROLAND, ROLAND_U8, 2) = {
200 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_U8, 2),
201 	UMQ_TERMINATOR
202 };
203 
204 /*
205  * ROLAND UM-2
206  */
207 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM2, 2, 1, 1) = {
208 	/* out */
209 	{ 0, 2 },
210 	/* in */
211 	{ 1, 2 }
212 };
213 
214 UMQ_DEF(ROLAND, ROLAND_UM2, 2) = {
215 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM2, 2),
216 	UMQ_TERMINATOR
217 };
218 
219 /*
220  * ROLAND SC-8820
221  */
222 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SC8820, 2, 1, 1) = {
223 	/* out */
224 	{ 0, 5 }, /* cables 0, 1, 4 only */
225 	/* in */
226 	{ 1, 5 } /* do. */
227 };
228 
229 UMQ_DEF(ROLAND, ROLAND_SC8820, 2) = {
230 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SC8820, 2),
231 	UMQ_TERMINATOR
232 };
233 
234 /*
235  * ROLAND PC-300
236  */
237 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_PC300, 2, 1, 1) = {
238 	/* out */
239 	{ 0, 1 },
240 	/* in */
241 	{ 1, 1 }
242 };
243 
244 UMQ_DEF(ROLAND, ROLAND_PC300, 2) = {
245 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_PC300, 2),
246 	UMQ_TERMINATOR
247 };
248 
249 /*
250  * ROLAND SK-500
251  */
252 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SK500, 2, 1, 1) = {
253 	/* out */
254 	{ 0, 5 }, /* cables 0, 1, 4 only */
255 	/* in */
256 	{ 1, 5 } /* do. */
257 };
258 
259 UMQ_DEF(ROLAND, ROLAND_SK500, 2) = {
260 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SK500, 2),
261 	UMQ_TERMINATOR
262 };
263 
264 /*
265  * ROLAND SC-D70
266  */
267 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SCD70, 2, 1, 1) = {
268 	/* out */
269 	{ 0, 3 },
270 	/* in */
271 	{ 1, 3 }
272 };
273 
274 UMQ_DEF(ROLAND, ROLAND_SCD70, 2) = {
275 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SCD70, 2),
276 	UMQ_TERMINATOR
277 };
278 
279 /*
280  * ROLAND UM-550
281  */
282 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM550, 0, 1, 1) = {
283 	/* out */
284 	{ 0, 6 },
285 	/* in */
286 	{ 1, 6 }
287 };
288 
289 UMQ_DEF(ROLAND, ROLAND_UM550, 0) = {
290 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM550, 0),
291 	UMQ_TERMINATOR
292 };
293 
294 /*
295  * ROLAND SD-20
296  */
297 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD20, 0, 1, 1) = {
298 	/* out */
299 	{ 0, 2 },
300 	/* in */
301 	{ 1, 3 }
302 };
303 
304 UMQ_DEF(ROLAND, ROLAND_SD20, 0) = {
305 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD20, 0),
306 	UMQ_TERMINATOR
307 };
308 
309 /*
310  * ROLAND SD-80
311  */
312 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_SD80, 0, 1, 1) = {
313 	/* out */
314 	{ 0, 4 },
315 	/* in */
316 	{ 1, 4 }
317 };
318 
319 UMQ_DEF(ROLAND, ROLAND_SD80, 0) = {
320 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_SD80, 0),
321 	UMQ_TERMINATOR
322 };
323 
324 /*
325  * ROLAND UA-700
326  */
327 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UA700, 3, 1, 1) = {
328 	/* out */
329 	{ 0, 2 },
330 	/* in */
331 	{ 1, 2 }
332 };
333 
334 UMQ_DEF(ROLAND, ROLAND_UA700, 3) = {
335 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UA700, 3),
336 	UMQ_TERMINATOR
337 };
338 
339 /*
340  * ROLAND UM-ONE
341  */
342 UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UMONE, ANYIFACE, 1, 1) = {
343 	/* out */
344 	{ 0, 1 },
345 	/* in */
346 	{ 1, 1 }
347 };
348 
349 UMQ_DEF(ROLAND, ROLAND_UMONE, ANYIFACE) = {
350 	UMQ_FIXED_EP_REG(ROLAND, ROLAND_UMONE, ANYIFACE),
351 	UMQ_TERMINATOR
352 };
353 
354 /*
355  * quirk list
356  */
357 struct umidi_quirk umidi_quirklist[] = {
358 	UMQ_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
359 	UMQ_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
360 	UMQ_REG(ROLAND, ROLAND_UM1, 2),
361 	UMQ_REG(ROLAND, ROLAND_SC8850, 2),
362 	UMQ_REG(ROLAND, ROLAND_SD90, 2),
363 	UMQ_REG(ROLAND, ROLAND_UM880N, 0),
364 	UMQ_REG(ROLAND, ROLAND_UA100, 2),
365 	UMQ_REG(ROLAND, ROLAND_UM4, 2),
366 	UMQ_REG(ROLAND, ROLAND_U8, 2),
367 	UMQ_REG(ROLAND, ROLAND_UM2, 2),
368 	UMQ_REG(ROLAND, ROLAND_SC8820, 2),
369 	UMQ_REG(ROLAND, ROLAND_PC300, 2),
370 	UMQ_REG(ROLAND, ROLAND_SK500, 2),
371 	UMQ_REG(ROLAND, ROLAND_SCD70, 2),
372 	UMQ_REG(ROLAND, ROLAND_UM550, 0),
373 	UMQ_REG(ROLAND, ROLAND_SD20, 0),
374 	UMQ_REG(ROLAND, ROLAND_SD80, 0),
375 	UMQ_REG(ROLAND, ROLAND_UA700, 3),
376 	UMQ_REG(ROLAND, ROLAND_UMONE, ANYIFACE),
377 	UMQ_TERMINATOR
378 };
379 
380 
381 /*
382  * quirk utilities
383  */
384 
385 struct umidi_quirk *
386 umidi_search_quirk(int vendor, int product, int ifaceno)
387 {
388 	struct umidi_quirk *p;
389 	struct umq_data *q;
390 
391 	DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n",
392 		 vendor, product, ifaceno));
393 
394 	for (p=&umidi_quirklist[0]; p->vendor; p++) {
395 		DPRINTFN(10, ("\tv=%d, p=%d, i=%d",
396 			      p->vendor, p->product, p->iface));
397 		if ((p->vendor==vendor || p->vendor==ANYVENDOR) &&
398 		    (p->product==product || p->product==ANYPRODUCT) &&
399 		    (p->iface==ifaceno || p->iface==ANYIFACE)) {
400 			DPRINTFN(10, (" found\n"));
401 			if (!p->type_mask)
402 				/* make quirk mask */
403 				for (q=p->quirks; q->type; q++)
404 					p->type_mask |= 1<<(q->type-1);
405 			return p;
406                 }
407 		DPRINTFN(10, ("\n"));
408 	}
409 
410 	return NULL;
411 }
412 
413 static char *quirk_name[] = {
414 	"NULL",
415 	"Fixed Endpoint",
416 	"Yamaha Specific",
417 };
418 
419 void
420 umidi_print_quirk(struct umidi_quirk *q)
421 {
422 	struct umq_data *qd;
423 	if (q) {
424 		printf("(");
425 		for (qd=q->quirks; qd->type; qd++)
426 			printf("%s%s", quirk_name[qd->type],
427 			       (qd+1)->type?", ":")\n");
428 	} else {
429 		printf("(genuine USB-MIDI)\n");
430 	}
431 }
432 
433 void *
434 umidi_get_quirk_data_from_type(struct umidi_quirk *q, u_int32_t type)
435 {
436 	struct umq_data *qd;
437 	if (q) {
438 		for (qd=q->quirks; qd->type; qd++)
439 			if (qd->type == type)
440 				return qd->data;
441 	}
442 	return NULL;
443 }
444