xref: /openbsd-src/sys/dev/usb/umidi_quirks.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
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 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 	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 		if ((p->vendor==vendor || p->vendor==ANYVENDOR) &&
381 		    (p->product==product || p->product==ANYPRODUCT) &&
382 		    (p->iface==ifaceno || p->iface==ANYIFACE)) {
383 			DPRINTFN(10, (" found\n"));
384 			if (!p->type_mask)
385 				/* make quirk mask */
386 				for (q=p->quirks; q->type; q++)
387 					p->type_mask |= 1<<(q->type-1);
388 			return p;
389                 }
390 		DPRINTFN(10, ("\n"));
391 	}
392 
393 	return NULL;
394 }
395 
396 static char *quirk_name[] = {
397 	"NULL",
398 	"Fixed Endpoint",
399 	"Yamaha Specific",
400 };
401 
402 void
403 umidi_print_quirk(struct umidi_quirk *q)
404 {
405 	struct umq_data *qd;
406 	if (q) {
407 		printf("(");
408 		for (qd=q->quirks; qd->type; qd++)
409 			printf("%s%s", quirk_name[qd->type],
410 			       (qd+1)->type?", ":")\n");
411 	} else {
412 		printf("(genuine USB-MIDI)\n");
413 	}
414 }
415 
416 void *
417 umidi_get_quirk_data_from_type(struct umidi_quirk *q, u_int32_t type)
418 {
419 	struct umq_data *qd;
420 	if (q) {
421 		for (qd=q->quirks; qd->type; qd++)
422 			if (qd->type == type)
423 				return qd->data;
424 	}
425 	return NULL;
426 }
427