1 /* $NetBSD: umidi_quirks.h,v 1.7 2008/04/28 20:24:00 martin Exp $ */ 2 3 /* 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Takuya SHIOZAKI (tshiozak@NetBSD.org). 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 33 /* 34 * quirk code for UMIDI 35 */ 36 37 #ifndef _DEV_USB_UMIDI_QUIRKS_H_ 38 #define _DEV_USB_UMIDI_QUIRKS_H_ 39 40 struct umq_data { 41 int type; 42 #define UMQ_TYPE_NONE 0 43 #define UMQ_TYPE_FIXED_EP 1 44 #define UMQ_TYPE_YAMAHA 2 45 #define UMQ_TYPE_MIDIMAN_GARBLE 3 46 #define UMQ_TYPE_CN_SEQ_PER_EP 4 /* should be default behavior, but isn't */ 47 #define UMQ_TYPE_CN_SEQ_GLOBAL 5 /* shouldn't be default behavior, but is */ 48 #define UMQ_TYPE_CN_FIXED 6 /* should be a joke, but isn't funny */ 49 #define UMQ_TYPE_MD_FIXED 7 /* in case CN_FIXED gives a weird order */ 50 void *data; 51 }; 52 53 struct umidi_quirk { 54 int vendor; 55 int product; 56 int iface; 57 struct umq_data *quirks; 58 u_int32_t type_mask; 59 }; 60 #define UMQ_ISTYPE(q, type) \ 61 ((q)->sc_quirk && ((q)->sc_quirk->type_mask & (1<<((type)-1)))) 62 63 #define UMQ_TERMINATOR { .type = UMQ_TYPE_NONE, }, 64 #define UMQ_DEF(v, p, i) \ 65 static struct umq_data umq_##v##_##p##_##i[] 66 #define UMQ_REG(v, p, i) \ 67 { USB_VENDOR_##v, USB_PRODUCT_##p, i, \ 68 umq_##v##_##p##_##i, 0 } 69 #define ANYIFACE -1 70 #define ANYVENDOR -1 71 #define USB_VENDOR_ANYVENDOR ANYVENDOR 72 #define ANYPRODUCT -1 73 #define USB_PRODUCT_ANYPRODUCT ANYPRODUCT 74 75 /* 76 * quirk - fixed port. By the way, the ep field contains not the 77 * endpoint address, but the index of the endpoint descriptor. 78 */ 79 80 struct umq_fixed_ep_endpoint { 81 int ep; 82 int num_jacks; 83 }; 84 struct umq_fixed_ep_desc { 85 int num_out_ep; 86 int num_in_ep; 87 struct umq_fixed_ep_endpoint *out_ep; 88 struct umq_fixed_ep_endpoint *in_ep; 89 }; 90 91 #define UMQ_FIXED_EP_DEF(v, p, i, noep, niep) \ 92 static struct umq_fixed_ep_endpoint \ 93 umq_##v##_##p##_##i##_fixed_ep_endpoints[noep+niep]; \ 94 static struct umq_fixed_ep_desc \ 95 umq_##v##_##p##_##i##_fixed_ep_desc = { \ 96 noep, niep, \ 97 &umq_##v##_##p##_##i##_fixed_ep_endpoints[0], \ 98 &umq_##v##_##p##_##i##_fixed_ep_endpoints[noep], \ 99 }; \ 100 static struct umq_fixed_ep_endpoint \ 101 umq_##v##_##p##_##i##_fixed_ep_endpoints[noep+niep] 102 103 #define UMQ_FIXED_EP_REG(v, p, i) \ 104 { UMQ_TYPE_FIXED_EP, (void *)&umq_##v##_##p##_##i##_fixed_ep_desc } 105 106 /* 107 * quirk - fixed cable numbers. Supply as many values as there are jacks, 108 * in the same jack order implied by the FIXED_EP_DEF. Each value becomes 109 * the cable number of the corresponding jack. 110 */ 111 #if __STDC_VERSION__ >= 199901L 112 #define UMQ_CN_FIXED_REG(...) \ 113 { .type=UMQ_TYPE_CN_FIXED, .data=(unsigned char[]){__VA_ARGS__} } 114 #else /* assume gcc 2.95.3 */ 115 #define UMQ_CN_FIXED_REG(cns...) \ 116 { .type=UMQ_TYPE_CN_FIXED, .data=(unsigned char[]){cns} } 117 #endif 118 119 /* 120 * quirk - fixed mididev assignment. Supply pairs of numbers out, in, as 121 * many pairs as mididevs (that is, max(num_out_jack,num_in_jack)). The 122 * pairs, in order, correspond to the mididevs that will be created; in 123 * each pair, out is the index of the out_jack to bind and in is the 124 * index of the in_jack, both in the order implied by the FIXED_EP_DEF. 125 * Either out or in can be -1 to bind no out jack or in jack, respectively, 126 * to the corresponding mididev. 127 */ 128 #if __STDC_VERSION__ >= 199901L 129 #define UMQ_MD_FIXED_REG(...) \ 130 { .type=UMQ_TYPE_MD_FIXED, .data=(unsigned char[]){__VA_ARGS__} } 131 #else /* assume gcc 2.95.3 */ 132 #define UMQ_MD_FIXED_REG(mds...) \ 133 { .type=UMQ_TYPE_MD_FIXED, .data=(unsigned char[]){mds} } 134 #endif 135 136 /* 137 * generic boolean quirk, no data 138 */ 139 #define UMQ_TYPE(t) \ 140 { UMQ_TYPE_##t, NULL } 141 142 /* 143 * quirk - yamaha style midi I/F 144 */ 145 #define UMQ_YAMAHA_REG(v, p, i) \ 146 UMQ_TYPE(YAMAHA) 147 148 149 /* extern struct umidi_quirk umidi_quirklist[]; */ 150 struct umidi_quirk *umidi_search_quirk(int, int, int); 151 void umidi_print_quirk(struct umidi_quirk *); 152 void *umidi_get_quirk_data_from_type(struct umidi_quirk *, u_int32_t); 153 154 #endif 155