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