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