Thu Jan 24 08:22:38 2013 UTC ()
oops, turn uaudiodebug off by default again.


(mrg)
diff -r1.134 -r1.135 src/sys/dev/usb/uaudio.c

cvs diff -r1.134 -r1.135 src/sys/dev/usb/uaudio.c (switch to unified diff)

--- src/sys/dev/usb/uaudio.c 2013/01/22 12:40:43 1.134
+++ src/sys/dev/usb/uaudio.c 2013/01/24 08:22:38 1.135
@@ -1,1092 +1,1092 @@ @@ -1,1092 +1,1092 @@
1/* $NetBSD: uaudio.c,v 1.134 2013/01/22 12:40:43 jmcneill Exp $ */ 1/* $NetBSD: uaudio.c,v 1.135 2013/01/24 08:22:38 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999, 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999, 2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology, and Matthew R. Green (mrg@eterna.com.au). 9 * Carlstedt Research & Technology, and Matthew R. Green (mrg@eterna.com.au).
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 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 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 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf 34 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
35 * http://www.usb.org/developers/devclass_docs/frmts10.pdf 35 * http://www.usb.org/developers/devclass_docs/frmts10.pdf
36 * http://www.usb.org/developers/devclass_docs/termt10.pdf 36 * http://www.usb.org/developers/devclass_docs/termt10.pdf
37 */ 37 */
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.134 2013/01/22 12:40:43 jmcneill Exp $"); 40__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.135 2013/01/24 08:22:38 mrg Exp $");
41 41
42#include <sys/param.h> 42#include <sys/param.h>
43#include <sys/systm.h> 43#include <sys/systm.h>
44#include <sys/kernel.h> 44#include <sys/kernel.h>
45#include <sys/malloc.h> 45#include <sys/malloc.h>
46#include <sys/device.h> 46#include <sys/device.h>
47#include <sys/ioctl.h> 47#include <sys/ioctl.h>
48#include <sys/file.h> 48#include <sys/file.h>
49#include <sys/reboot.h> /* for bootverbose */ 49#include <sys/reboot.h> /* for bootverbose */
50#include <sys/select.h> 50#include <sys/select.h>
51#include <sys/proc.h> 51#include <sys/proc.h>
52#include <sys/vnode.h> 52#include <sys/vnode.h>
53#include <sys/poll.h> 53#include <sys/poll.h>
54#include <sys/module.h> 54#include <sys/module.h>
55#include <sys/bus.h> 55#include <sys/bus.h>
56#include <sys/cpu.h> 56#include <sys/cpu.h>
57 57
58#include <sys/audioio.h> 58#include <sys/audioio.h>
59#include <dev/audio_if.h> 59#include <dev/audio_if.h>
60#include <dev/audiovar.h> 60#include <dev/audiovar.h>
61#include <dev/mulaw.h> 61#include <dev/mulaw.h>
62#include <dev/auconv.h> 62#include <dev/auconv.h>
63 63
64#include <dev/usb/usb.h> 64#include <dev/usb/usb.h>
65#include <dev/usb/usbdi.h> 65#include <dev/usb/usbdi.h>
66#include <dev/usb/usbdivar.h> 66#include <dev/usb/usbdivar.h>
67#include <dev/usb/usbdi_util.h> 67#include <dev/usb/usbdi_util.h>
68#include <dev/usb/usb_quirks.h> 68#include <dev/usb/usb_quirks.h>
69 69
70#include <dev/usb/usbdevs.h> 70#include <dev/usb/usbdevs.h>
71 71
72#include <dev/usb/uaudioreg.h> 72#include <dev/usb/uaudioreg.h>
73 73
74/* #define UAUDIO_DEBUG */ 74/* #define UAUDIO_DEBUG */
75/* #define UAUDIO_MULTIPLE_ENDPOINTS */ 75/* #define UAUDIO_MULTIPLE_ENDPOINTS */
76#ifdef UAUDIO_DEBUG 76#ifdef UAUDIO_DEBUG
77#define DPRINTF(x,y...) do { \ 77#define DPRINTF(x,y...) do { \
78 if (uaudiodebug) { \ 78 if (uaudiodebug) { \
79 struct lwp *l = curlwp; \ 79 struct lwp *l = curlwp; \
80 printf("%s[%d:%d]: "x, __func__, l->l_proc->p_pid, l->l_lid, y); \ 80 printf("%s[%d:%d]: "x, __func__, l->l_proc->p_pid, l->l_lid, y); \
81 } \ 81 } \
82 } while (0) 82 } while (0)
83#define DPRINTFN_CLEAN(n,x...) do { \ 83#define DPRINTFN_CLEAN(n,x...) do { \
84 if (uaudiodebug > (n)) \ 84 if (uaudiodebug > (n)) \
85 printf(x); \ 85 printf(x); \
86 } while (0) 86 } while (0)
87#define DPRINTFN(n,x,y...) do { \ 87#define DPRINTFN(n,x,y...) do { \
88 if (uaudiodebug > (n)) { \ 88 if (uaudiodebug > (n)) { \
89 struct lwp *l = curlwp; \ 89 struct lwp *l = curlwp; \
90 printf("%s[%d:%d]: "x, __func__, l->l_proc->p_pid, l->l_lid, y); \ 90 printf("%s[%d:%d]: "x, __func__, l->l_proc->p_pid, l->l_lid, y); \
91 } \ 91 } \
92 } while (0) 92 } while (0)
93int uaudiodebug = 6; 93int uaudiodebug = 0;
94#else 94#else
95#define DPRINTF(x,y...) 95#define DPRINTF(x,y...)
96#define DPRINTFN_CLEAN(n,x...) 96#define DPRINTFN_CLEAN(n,x...)
97#define DPRINTFN(n,x,y...) 97#define DPRINTFN(n,x,y...)
98#endif 98#endif
99 99
100#define UAUDIO_NCHANBUFS 6 /* number of outstanding request */ 100#define UAUDIO_NCHANBUFS 6 /* number of outstanding request */
101#define UAUDIO_NFRAMES 10 /* ms of sound in each request */ 101#define UAUDIO_NFRAMES 10 /* ms of sound in each request */
102 102
103 103
104#define MIX_MAX_CHAN 8 104#define MIX_MAX_CHAN 8
105struct mixerctl { 105struct mixerctl {
106 uint16_t wValue[MIX_MAX_CHAN]; /* using nchan */ 106 uint16_t wValue[MIX_MAX_CHAN]; /* using nchan */
107 uint16_t wIndex; 107 uint16_t wIndex;
108 uint8_t nchan; 108 uint8_t nchan;
109 uint8_t type; 109 uint8_t type;
110#define MIX_ON_OFF 1 110#define MIX_ON_OFF 1
111#define MIX_SIGNED_16 2 111#define MIX_SIGNED_16 2
112#define MIX_UNSIGNED_16 3 112#define MIX_UNSIGNED_16 3
113#define MIX_SIGNED_8 4 113#define MIX_SIGNED_8 4
114#define MIX_SELECTOR 5 114#define MIX_SELECTOR 5
115#define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1) 115#define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
116#define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16) 116#define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
117 int minval, maxval; 117 int minval, maxval;
118 u_int delta; 118 u_int delta;
119 u_int mul; 119 u_int mul;
120 uint8_t class; 120 uint8_t class;
121 char ctlname[MAX_AUDIO_DEV_LEN]; 121 char ctlname[MAX_AUDIO_DEV_LEN];
122 const char *ctlunit; 122 const char *ctlunit;
123}; 123};
124#define MAKE(h,l) (((h) << 8) | (l)) 124#define MAKE(h,l) (((h) << 8) | (l))
125 125
126struct as_info { 126struct as_info {
127 uint8_t alt; 127 uint8_t alt;
128 uint8_t encoding; 128 uint8_t encoding;
129 uint8_t attributes; /* Copy of bmAttributes of 129 uint8_t attributes; /* Copy of bmAttributes of
130 * usb_audio_streaming_endpoint_descriptor 130 * usb_audio_streaming_endpoint_descriptor
131 */ 131 */
132 usbd_interface_handle ifaceh; 132 usbd_interface_handle ifaceh;
133 const usb_interface_descriptor_t *idesc; 133 const usb_interface_descriptor_t *idesc;
134 const usb_endpoint_descriptor_audio_t *edesc; 134 const usb_endpoint_descriptor_audio_t *edesc;
135 const usb_endpoint_descriptor_audio_t *edesc1; 135 const usb_endpoint_descriptor_audio_t *edesc1;
136 const struct usb_audio_streaming_type1_descriptor *asf1desc; 136 const struct usb_audio_streaming_type1_descriptor *asf1desc;
137 struct audio_format *aformat; 137 struct audio_format *aformat;
138 int sc_busy; /* currently used */ 138 int sc_busy; /* currently used */
139}; 139};
140 140
141struct chan { 141struct chan {
142 void (*intr)(void *); /* DMA completion intr handler */ 142 void (*intr)(void *); /* DMA completion intr handler */
143 void *arg; /* arg for intr() */ 143 void *arg; /* arg for intr() */
144 usbd_pipe_handle pipe; 144 usbd_pipe_handle pipe;
145 usbd_pipe_handle sync_pipe; 145 usbd_pipe_handle sync_pipe;
146 146
147 u_int sample_size; 147 u_int sample_size;
148 u_int sample_rate; 148 u_int sample_rate;
149 u_int bytes_per_frame; 149 u_int bytes_per_frame;
150 u_int fraction; /* fraction/1000 is the extra samples/frame */ 150 u_int fraction; /* fraction/1000 is the extra samples/frame */
151 u_int residue; /* accumulates the fractional samples */ 151 u_int residue; /* accumulates the fractional samples */
152 152
153 u_char *start; /* upper layer buffer start */ 153 u_char *start; /* upper layer buffer start */
154 u_char *end; /* upper layer buffer end */ 154 u_char *end; /* upper layer buffer end */
155 u_char *cur; /* current position in upper layer buffer */ 155 u_char *cur; /* current position in upper layer buffer */
156 int blksize; /* chunk size to report up */ 156 int blksize; /* chunk size to report up */
157 int transferred; /* transferred bytes not reported up */ 157 int transferred; /* transferred bytes not reported up */
158 158
159 int altidx; /* currently used altidx */ 159 int altidx; /* currently used altidx */
160 160
161 int curchanbuf; 161 int curchanbuf;
162 struct chanbuf { 162 struct chanbuf {
163 struct chan *chan; 163 struct chan *chan;
164 usbd_xfer_handle xfer; 164 usbd_xfer_handle xfer;
165 u_char *buffer; 165 u_char *buffer;
166 uint16_t sizes[UAUDIO_NFRAMES]; 166 uint16_t sizes[UAUDIO_NFRAMES];
167 uint16_t offsets[UAUDIO_NFRAMES]; 167 uint16_t offsets[UAUDIO_NFRAMES];
168 uint16_t size; 168 uint16_t size;
169 } chanbufs[UAUDIO_NCHANBUFS]; 169 } chanbufs[UAUDIO_NCHANBUFS];
170 170
171 struct uaudio_softc *sc; /* our softc */ 171 struct uaudio_softc *sc; /* our softc */
172}; 172};
173 173
174/* 174/*
175 * XXX Locking notes: 175 * XXX Locking notes:
176 * 176 *
177 * The MI USB audio subsystem is not MP-SAFE. Our strategy here 177 * The MI USB audio subsystem is not MP-SAFE. Our strategy here
178 * is to ensure we have the kernel lock held when calling into 178 * is to ensure we have the kernel lock held when calling into
179 * usbd, and, generally, to have dropped the sc_intr_lock during 179 * usbd, and, generally, to have dropped the sc_intr_lock during
180 * these sections as well since the usb code will sleep. 180 * these sections as well since the usb code will sleep.
181 */ 181 */
182struct uaudio_softc { 182struct uaudio_softc {
183 device_t sc_dev; /* base device */ 183 device_t sc_dev; /* base device */
184 kmutex_t sc_lock; 184 kmutex_t sc_lock;
185 kmutex_t sc_intr_lock; 185 kmutex_t sc_intr_lock;
186 usbd_device_handle sc_udev; /* USB device */ 186 usbd_device_handle sc_udev; /* USB device */
187 int sc_ac_iface; /* Audio Control interface */ 187 int sc_ac_iface; /* Audio Control interface */
188 usbd_interface_handle sc_ac_ifaceh; 188 usbd_interface_handle sc_ac_ifaceh;
189 struct chan sc_playchan; /* play channel */ 189 struct chan sc_playchan; /* play channel */
190 struct chan sc_recchan; /* record channel */ 190 struct chan sc_recchan; /* record channel */
191 int sc_nullalt; 191 int sc_nullalt;
192 int sc_audio_rev; 192 int sc_audio_rev;
193 struct as_info *sc_alts; /* alternate settings */ 193 struct as_info *sc_alts; /* alternate settings */
194 int sc_nalts; /* # of alternate settings */ 194 int sc_nalts; /* # of alternate settings */
195 int sc_altflags; 195 int sc_altflags;
196#define HAS_8 0x01 196#define HAS_8 0x01
197#define HAS_16 0x02 197#define HAS_16 0x02
198#define HAS_8U 0x04 198#define HAS_8U 0x04
199#define HAS_ALAW 0x08 199#define HAS_ALAW 0x08
200#define HAS_MULAW 0x10 200#define HAS_MULAW 0x10
201#define UA_NOFRAC 0x20 /* don't do sample rate adjustment */ 201#define UA_NOFRAC 0x20 /* don't do sample rate adjustment */
202#define HAS_24 0x40 202#define HAS_24 0x40
203 int sc_mode; /* play/record capability */ 203 int sc_mode; /* play/record capability */
204 struct mixerctl *sc_ctls; /* mixer controls */ 204 struct mixerctl *sc_ctls; /* mixer controls */
205 int sc_nctls; /* # of mixer controls */ 205 int sc_nctls; /* # of mixer controls */
206 device_t sc_audiodev; 206 device_t sc_audiodev;
207 struct audio_format *sc_formats; 207 struct audio_format *sc_formats;
208 int sc_nformats; 208 int sc_nformats;
209 struct audio_encoding_set *sc_encodings; 209 struct audio_encoding_set *sc_encodings;
210 u_int sc_channel_config; 210 u_int sc_channel_config;
211 char sc_dying; 211 char sc_dying;
212 struct audio_device sc_adev; 212 struct audio_device sc_adev;
213}; 213};
214 214
215struct terminal_list { 215struct terminal_list {
216 int size; 216 int size;
217 uint16_t terminals[1]; 217 uint16_t terminals[1];
218}; 218};
219#define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \ 219#define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \
220 + sizeof(uint16_t) * (N)) 220 + sizeof(uint16_t) * (N))
221 221
222struct io_terminal { 222struct io_terminal {
223 union { 223 union {
224 const uaudio_cs_descriptor_t *desc; 224 const uaudio_cs_descriptor_t *desc;
225 const struct usb_audio_input_terminal *it; 225 const struct usb_audio_input_terminal *it;
226 const struct usb_audio_output_terminal *ot; 226 const struct usb_audio_output_terminal *ot;
227 const struct usb_audio_mixer_unit *mu; 227 const struct usb_audio_mixer_unit *mu;
228 const struct usb_audio_selector_unit *su; 228 const struct usb_audio_selector_unit *su;
229 const struct usb_audio_feature_unit *fu; 229 const struct usb_audio_feature_unit *fu;
230 const struct usb_audio_processing_unit *pu; 230 const struct usb_audio_processing_unit *pu;
231 const struct usb_audio_extension_unit *eu; 231 const struct usb_audio_extension_unit *eu;
232 } d; 232 } d;
233 int inputs_size; 233 int inputs_size;
234 struct terminal_list **inputs; /* list of source input terminals */ 234 struct terminal_list **inputs; /* list of source input terminals */
235 struct terminal_list *output; /* list of destination output terminals */ 235 struct terminal_list *output; /* list of destination output terminals */
236 int direct; /* directly connected to an output terminal */ 236 int direct; /* directly connected to an output terminal */
237}; 237};
238 238
239#define UAC_OUTPUT 0 239#define UAC_OUTPUT 0
240#define UAC_INPUT 1 240#define UAC_INPUT 1
241#define UAC_EQUAL 2 241#define UAC_EQUAL 2
242#define UAC_RECORD 3 242#define UAC_RECORD 3
243#define UAC_NCLASSES 4 243#define UAC_NCLASSES 4
244#ifdef UAUDIO_DEBUG 244#ifdef UAUDIO_DEBUG
245Static const char *uac_names[] = { 245Static const char *uac_names[] = {
246 AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord, 246 AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
247}; 247};
248#endif 248#endif
249 249
250Static usbd_status uaudio_identify_ac 250Static usbd_status uaudio_identify_ac
251 (struct uaudio_softc *, const usb_config_descriptor_t *); 251 (struct uaudio_softc *, const usb_config_descriptor_t *);
252Static usbd_status uaudio_identify_as 252Static usbd_status uaudio_identify_as
253 (struct uaudio_softc *, const usb_config_descriptor_t *); 253 (struct uaudio_softc *, const usb_config_descriptor_t *);
254Static usbd_status uaudio_process_as 254Static usbd_status uaudio_process_as
255 (struct uaudio_softc *, const char *, int *, int, 255 (struct uaudio_softc *, const char *, int *, int,
256 const usb_interface_descriptor_t *); 256 const usb_interface_descriptor_t *);
257 257
258Static void uaudio_add_alt(struct uaudio_softc *, const struct as_info *); 258Static void uaudio_add_alt(struct uaudio_softc *, const struct as_info *);
259 259
260Static const usb_interface_descriptor_t *uaudio_find_iface 260Static const usb_interface_descriptor_t *uaudio_find_iface
261 (const char *, int, int *, int); 261 (const char *, int, int *, int);
262 262
263Static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *); 263Static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
264Static char *uaudio_id_name 264Static char *uaudio_id_name
265 (struct uaudio_softc *, const struct io_terminal *, int); 265 (struct uaudio_softc *, const struct io_terminal *, int);
266#ifdef UAUDIO_DEBUG 266#ifdef UAUDIO_DEBUG
267Static void uaudio_dump_cluster(const struct usb_audio_cluster *); 267Static void uaudio_dump_cluster(const struct usb_audio_cluster *);
268#endif 268#endif
269Static struct usb_audio_cluster uaudio_get_cluster 269Static struct usb_audio_cluster uaudio_get_cluster
270 (int, const struct io_terminal *); 270 (int, const struct io_terminal *);
271Static void uaudio_add_input 271Static void uaudio_add_input
272 (struct uaudio_softc *, const struct io_terminal *, int); 272 (struct uaudio_softc *, const struct io_terminal *, int);
273Static void uaudio_add_output 273Static void uaudio_add_output
274 (struct uaudio_softc *, const struct io_terminal *, int); 274 (struct uaudio_softc *, const struct io_terminal *, int);
275Static void uaudio_add_mixer 275Static void uaudio_add_mixer
276 (struct uaudio_softc *, const struct io_terminal *, int); 276 (struct uaudio_softc *, const struct io_terminal *, int);
277Static void uaudio_add_selector 277Static void uaudio_add_selector
278 (struct uaudio_softc *, const struct io_terminal *, int); 278 (struct uaudio_softc *, const struct io_terminal *, int);
279#ifdef UAUDIO_DEBUG 279#ifdef UAUDIO_DEBUG
280Static const char *uaudio_get_terminal_name(int); 280Static const char *uaudio_get_terminal_name(int);
281#endif 281#endif
282Static int uaudio_determine_class 282Static int uaudio_determine_class
283 (const struct io_terminal *, struct mixerctl *); 283 (const struct io_terminal *, struct mixerctl *);
284Static const char *uaudio_feature_name 284Static const char *uaudio_feature_name
285 (const struct io_terminal *, struct mixerctl *); 285 (const struct io_terminal *, struct mixerctl *);
286Static void uaudio_add_feature 286Static void uaudio_add_feature
287 (struct uaudio_softc *, const struct io_terminal *, int); 287 (struct uaudio_softc *, const struct io_terminal *, int);
288Static void uaudio_add_processing_updown 288Static void uaudio_add_processing_updown
289 (struct uaudio_softc *, const struct io_terminal *, int); 289 (struct uaudio_softc *, const struct io_terminal *, int);
290Static void uaudio_add_processing 290Static void uaudio_add_processing
291 (struct uaudio_softc *, const struct io_terminal *, int); 291 (struct uaudio_softc *, const struct io_terminal *, int);
292Static void uaudio_add_extension 292Static void uaudio_add_extension
293 (struct uaudio_softc *, const struct io_terminal *, int); 293 (struct uaudio_softc *, const struct io_terminal *, int);
294Static struct terminal_list *uaudio_merge_terminal_list 294Static struct terminal_list *uaudio_merge_terminal_list
295 (const struct io_terminal *); 295 (const struct io_terminal *);
296Static struct terminal_list *uaudio_io_terminaltype 296Static struct terminal_list *uaudio_io_terminaltype
297 (int, struct io_terminal *, int); 297 (int, struct io_terminal *, int);
298Static usbd_status uaudio_identify 298Static usbd_status uaudio_identify
299 (struct uaudio_softc *, const usb_config_descriptor_t *); 299 (struct uaudio_softc *, const usb_config_descriptor_t *);
300 300
301Static int uaudio_signext(int, int); 301Static int uaudio_signext(int, int);
302Static int uaudio_value2bsd(struct mixerctl *, int); 302Static int uaudio_value2bsd(struct mixerctl *, int);
303Static int uaudio_bsd2value(struct mixerctl *, int); 303Static int uaudio_bsd2value(struct mixerctl *, int);
304Static int uaudio_get(struct uaudio_softc *, int, int, int, int, int); 304Static int uaudio_get(struct uaudio_softc *, int, int, int, int, int);
305Static int uaudio_ctl_get 305Static int uaudio_ctl_get
306 (struct uaudio_softc *, int, struct mixerctl *, int); 306 (struct uaudio_softc *, int, struct mixerctl *, int);
307Static void uaudio_set 307Static void uaudio_set
308 (struct uaudio_softc *, int, int, int, int, int, int); 308 (struct uaudio_softc *, int, int, int, int, int, int);
309Static void uaudio_ctl_set 309Static void uaudio_ctl_set
310 (struct uaudio_softc *, int, struct mixerctl *, int, int); 310 (struct uaudio_softc *, int, struct mixerctl *, int, int);
311 311
312Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int); 312Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
313 313
314Static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *); 314Static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
315Static void uaudio_chan_close(struct uaudio_softc *, struct chan *); 315Static void uaudio_chan_close(struct uaudio_softc *, struct chan *);
316Static usbd_status uaudio_chan_alloc_buffers 316Static usbd_status uaudio_chan_alloc_buffers
317 (struct uaudio_softc *, struct chan *); 317 (struct uaudio_softc *, struct chan *);
318Static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *); 318Static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
319Static void uaudio_chan_init 319Static void uaudio_chan_init
320 (struct chan *, int, const struct audio_params *, int); 320 (struct chan *, int, const struct audio_params *, int);
321Static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int); 321Static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int);
322Static void uaudio_chan_ptransfer(struct chan *); 322Static void uaudio_chan_ptransfer(struct chan *);
323Static void uaudio_chan_pintr 323Static void uaudio_chan_pintr
324 (usbd_xfer_handle, usbd_private_handle, usbd_status); 324 (usbd_xfer_handle, usbd_private_handle, usbd_status);
325 325
326Static void uaudio_chan_rtransfer(struct chan *); 326Static void uaudio_chan_rtransfer(struct chan *);
327Static void uaudio_chan_rintr 327Static void uaudio_chan_rintr
328 (usbd_xfer_handle, usbd_private_handle, usbd_status); 328 (usbd_xfer_handle, usbd_private_handle, usbd_status);
329 329
330Static int uaudio_open(void *, int); 330Static int uaudio_open(void *, int);
331Static void uaudio_close(void *); 331Static void uaudio_close(void *);
332Static int uaudio_drain(void *); 332Static int uaudio_drain(void *);
333Static int uaudio_query_encoding(void *, struct audio_encoding *); 333Static int uaudio_query_encoding(void *, struct audio_encoding *);
334Static int uaudio_set_params 334Static int uaudio_set_params
335 (void *, int, int, struct audio_params *, struct audio_params *, 335 (void *, int, int, struct audio_params *, struct audio_params *,
336 stream_filter_list_t *, stream_filter_list_t *); 336 stream_filter_list_t *, stream_filter_list_t *);
337Static int uaudio_round_blocksize(void *, int, int, const audio_params_t *); 337Static int uaudio_round_blocksize(void *, int, int, const audio_params_t *);
338Static int uaudio_trigger_output 338Static int uaudio_trigger_output
339 (void *, void *, void *, int, void (*)(void *), void *, 339 (void *, void *, void *, int, void (*)(void *), void *,
340 const audio_params_t *); 340 const audio_params_t *);
341Static int uaudio_trigger_input 341Static int uaudio_trigger_input
342 (void *, void *, void *, int, void (*)(void *), void *, 342 (void *, void *, void *, int, void (*)(void *), void *,
343 const audio_params_t *); 343 const audio_params_t *);
344Static int uaudio_halt_in_dma(void *); 344Static int uaudio_halt_in_dma(void *);
345Static int uaudio_halt_out_dma(void *); 345Static int uaudio_halt_out_dma(void *);
346Static int uaudio_getdev(void *, struct audio_device *); 346Static int uaudio_getdev(void *, struct audio_device *);
347Static int uaudio_mixer_set_port(void *, mixer_ctrl_t *); 347Static int uaudio_mixer_set_port(void *, mixer_ctrl_t *);
348Static int uaudio_mixer_get_port(void *, mixer_ctrl_t *); 348Static int uaudio_mixer_get_port(void *, mixer_ctrl_t *);
349Static int uaudio_query_devinfo(void *, mixer_devinfo_t *); 349Static int uaudio_query_devinfo(void *, mixer_devinfo_t *);
350Static int uaudio_get_props(void *); 350Static int uaudio_get_props(void *);
351Static void uaudio_get_locks(void *, kmutex_t **, kmutex_t **); 351Static void uaudio_get_locks(void *, kmutex_t **, kmutex_t **);
352 352
353Static const struct audio_hw_if uaudio_hw_if = { 353Static const struct audio_hw_if uaudio_hw_if = {
354 uaudio_open, 354 uaudio_open,
355 uaudio_close, 355 uaudio_close,
356 uaudio_drain, 356 uaudio_drain,
357 uaudio_query_encoding, 357 uaudio_query_encoding,
358 uaudio_set_params, 358 uaudio_set_params,
359 uaudio_round_blocksize, 359 uaudio_round_blocksize,
360 NULL, 360 NULL,
361 NULL, 361 NULL,
362 NULL, 362 NULL,
363 NULL, 363 NULL,
364 NULL, 364 NULL,
365 uaudio_halt_out_dma, 365 uaudio_halt_out_dma,
366 uaudio_halt_in_dma, 366 uaudio_halt_in_dma,
367 NULL, 367 NULL,
368 uaudio_getdev, 368 uaudio_getdev,
369 NULL, 369 NULL,
370 uaudio_mixer_set_port, 370 uaudio_mixer_set_port,
371 uaudio_mixer_get_port, 371 uaudio_mixer_get_port,
372 uaudio_query_devinfo, 372 uaudio_query_devinfo,
373 NULL, 373 NULL,
374 NULL, 374 NULL,
375 NULL, 375 NULL,
376 NULL, 376 NULL,
377 uaudio_get_props, 377 uaudio_get_props,
378 uaudio_trigger_output, 378 uaudio_trigger_output,
379 uaudio_trigger_input, 379 uaudio_trigger_input,
380 NULL, 380 NULL,
381 uaudio_get_locks, 381 uaudio_get_locks,
382}; 382};
383 383
384int uaudio_match(device_t, cfdata_t, void *); 384int uaudio_match(device_t, cfdata_t, void *);
385void uaudio_attach(device_t, device_t, void *); 385void uaudio_attach(device_t, device_t, void *);
386int uaudio_detach(device_t, int); 386int uaudio_detach(device_t, int);
387void uaudio_childdet(device_t, device_t); 387void uaudio_childdet(device_t, device_t);
388int uaudio_activate(device_t, enum devact); 388int uaudio_activate(device_t, enum devact);
389 389
390extern struct cfdriver uaudio_cd; 390extern struct cfdriver uaudio_cd;
391 391
392CFATTACH_DECL2_NEW(uaudio, sizeof(struct uaudio_softc), 392CFATTACH_DECL2_NEW(uaudio, sizeof(struct uaudio_softc),
393 uaudio_match, uaudio_attach, uaudio_detach, uaudio_activate, NULL, 393 uaudio_match, uaudio_attach, uaudio_detach, uaudio_activate, NULL,
394 uaudio_childdet); 394 uaudio_childdet);
395 395
396int  396int
397uaudio_match(device_t parent, cfdata_t match, void *aux) 397uaudio_match(device_t parent, cfdata_t match, void *aux)
398{ 398{
399 struct usbif_attach_arg *uaa = aux; 399 struct usbif_attach_arg *uaa = aux;
400 400
401 /* Trigger on the control interface. */ 401 /* Trigger on the control interface. */
402 if (uaa->class != UICLASS_AUDIO || 402 if (uaa->class != UICLASS_AUDIO ||
403 uaa->subclass != UISUBCLASS_AUDIOCONTROL || 403 uaa->subclass != UISUBCLASS_AUDIOCONTROL ||
404 (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO)) 404 (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
405 return UMATCH_NONE; 405 return UMATCH_NONE;
406 406
407 return UMATCH_IFACECLASS_IFACESUBCLASS; 407 return UMATCH_IFACECLASS_IFACESUBCLASS;
408} 408}
409 409
410void  410void
411uaudio_attach(device_t parent, device_t self, void *aux) 411uaudio_attach(device_t parent, device_t self, void *aux)
412{ 412{
413 struct uaudio_softc *sc = device_private(self); 413 struct uaudio_softc *sc = device_private(self);
414 struct usbif_attach_arg *uaa = aux; 414 struct usbif_attach_arg *uaa = aux;
415 usb_interface_descriptor_t *id; 415 usb_interface_descriptor_t *id;
416 usb_config_descriptor_t *cdesc; 416 usb_config_descriptor_t *cdesc;
417 char *devinfop; 417 char *devinfop;
418 usbd_status err; 418 usbd_status err;
419 int i, j, found; 419 int i, j, found;
420 420
421 sc->sc_dev = self; 421 sc->sc_dev = self;
422 sc->sc_udev = uaa->device; 422 sc->sc_udev = uaa->device;
423 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 423 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
424 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED); 424 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
425 425
426 strlcpy(sc->sc_adev.name, "USB audio", sizeof(sc->sc_adev.name)); 426 strlcpy(sc->sc_adev.name, "USB audio", sizeof(sc->sc_adev.name));
427 strlcpy(sc->sc_adev.version, "", sizeof(sc->sc_adev.version)); 427 strlcpy(sc->sc_adev.version, "", sizeof(sc->sc_adev.version));
428 snprintf(sc->sc_adev.config, sizeof(sc->sc_adev.config), "usb:%08x", 428 snprintf(sc->sc_adev.config, sizeof(sc->sc_adev.config), "usb:%08x",
429 sc->sc_udev->cookie.cookie); 429 sc->sc_udev->cookie.cookie);
430 430
431 aprint_naive("\n"); 431 aprint_naive("\n");
432 aprint_normal("\n"); 432 aprint_normal("\n");
433 433
434 devinfop = usbd_devinfo_alloc(uaa->device, 0); 434 devinfop = usbd_devinfo_alloc(uaa->device, 0);
435 aprint_normal_dev(self, "%s\n", devinfop); 435 aprint_normal_dev(self, "%s\n", devinfop);
436 usbd_devinfo_free(devinfop); 436 usbd_devinfo_free(devinfop);
437 437
438 cdesc = usbd_get_config_descriptor(sc->sc_udev); 438 cdesc = usbd_get_config_descriptor(sc->sc_udev);
439 if (cdesc == NULL) { 439 if (cdesc == NULL) {
440 aprint_error_dev(self, 440 aprint_error_dev(self,
441 "failed to get configuration descriptor\n"); 441 "failed to get configuration descriptor\n");
442 return; 442 return;
443 } 443 }
444 444
445 err = uaudio_identify(sc, cdesc); 445 err = uaudio_identify(sc, cdesc);
446 if (err) { 446 if (err) {
447 aprint_error_dev(self, 447 aprint_error_dev(self,
448 "audio descriptors make no sense, error=%d\n", err); 448 "audio descriptors make no sense, error=%d\n", err);
449 return; 449 return;
450 } 450 }
451 451
452 sc->sc_ac_ifaceh = uaa->iface; 452 sc->sc_ac_ifaceh = uaa->iface;
453 /* Pick up the AS interface. */ 453 /* Pick up the AS interface. */
454 for (i = 0; i < uaa->nifaces; i++) { 454 for (i = 0; i < uaa->nifaces; i++) {
455 if (uaa->ifaces[i] == NULL) 455 if (uaa->ifaces[i] == NULL)
456 continue; 456 continue;
457 id = usbd_get_interface_descriptor(uaa->ifaces[i]); 457 id = usbd_get_interface_descriptor(uaa->ifaces[i]);
458 if (id == NULL) 458 if (id == NULL)
459 continue; 459 continue;
460 found = 0; 460 found = 0;
461 for (j = 0; j < sc->sc_nalts; j++) { 461 for (j = 0; j < sc->sc_nalts; j++) {
462 if (id->bInterfaceNumber == 462 if (id->bInterfaceNumber ==
463 sc->sc_alts[j].idesc->bInterfaceNumber) { 463 sc->sc_alts[j].idesc->bInterfaceNumber) {
464 sc->sc_alts[j].ifaceh = uaa->ifaces[i]; 464 sc->sc_alts[j].ifaceh = uaa->ifaces[i];
465 found = 1; 465 found = 1;
466 } 466 }
467 } 467 }
468 if (found) 468 if (found)
469 uaa->ifaces[i] = NULL; 469 uaa->ifaces[i] = NULL;
470 } 470 }
471 471
472 for (j = 0; j < sc->sc_nalts; j++) { 472 for (j = 0; j < sc->sc_nalts; j++) {
473 if (sc->sc_alts[j].ifaceh == NULL) { 473 if (sc->sc_alts[j].ifaceh == NULL) {
474 aprint_error_dev(self, 474 aprint_error_dev(self,
475 "alt %d missing AS interface(s)\n", j); 475 "alt %d missing AS interface(s)\n", j);
476 return; 476 return;
477 } 477 }
478 } 478 }
479 479
480 aprint_normal_dev(self, "audio rev %d.%02x\n", 480 aprint_normal_dev(self, "audio rev %d.%02x\n",
481 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff); 481 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
482 482
483 sc->sc_playchan.sc = sc->sc_recchan.sc = sc; 483 sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
484 sc->sc_playchan.altidx = -1; 484 sc->sc_playchan.altidx = -1;
485 sc->sc_recchan.altidx = -1; 485 sc->sc_recchan.altidx = -1;
486 486
487 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC) 487 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
488 sc->sc_altflags |= UA_NOFRAC; 488 sc->sc_altflags |= UA_NOFRAC;
489 489
490#ifndef UAUDIO_DEBUG 490#ifndef UAUDIO_DEBUG
491 if (bootverbose) 491 if (bootverbose)
492#endif 492#endif
493 aprint_normal_dev(self, "%d mixer controls\n", 493 aprint_normal_dev(self, "%d mixer controls\n",
494 sc->sc_nctls); 494 sc->sc_nctls);
495 495
496 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 496 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
497 sc->sc_dev); 497 sc->sc_dev);
498 498
499 DPRINTF("%s", "doing audio_attach_mi\n"); 499 DPRINTF("%s", "doing audio_attach_mi\n");
500 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, sc->sc_dev); 500 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, sc->sc_dev);
501 501
502 return; 502 return;
503} 503}
504 504
505int 505int
506uaudio_activate(device_t self, enum devact act) 506uaudio_activate(device_t self, enum devact act)
507{ 507{
508 struct uaudio_softc *sc = device_private(self); 508 struct uaudio_softc *sc = device_private(self);
509 509
510 switch (act) { 510 switch (act) {
511 case DVACT_DEACTIVATE: 511 case DVACT_DEACTIVATE:
512 sc->sc_dying = 1; 512 sc->sc_dying = 1;
513 return 0; 513 return 0;
514 default: 514 default:
515 return EOPNOTSUPP; 515 return EOPNOTSUPP;
516 } 516 }
517} 517}
518 518
519void 519void
520uaudio_childdet(device_t self, device_t child) 520uaudio_childdet(device_t self, device_t child)
521{ 521{
522 struct uaudio_softc *sc = device_private(self); 522 struct uaudio_softc *sc = device_private(self);
523 523
524 KASSERT(sc->sc_audiodev == child); 524 KASSERT(sc->sc_audiodev == child);
525 sc->sc_audiodev = NULL; 525 sc->sc_audiodev = NULL;
526} 526}
527 527
528int 528int
529uaudio_detach(device_t self, int flags) 529uaudio_detach(device_t self, int flags)
530{ 530{
531 struct uaudio_softc *sc = device_private(self); 531 struct uaudio_softc *sc = device_private(self);
532 int rv; 532 int rv;
533 533
534 rv = 0; 534 rv = 0;
535 /* Wait for outstanding requests to complete. */ 535 /* Wait for outstanding requests to complete. */
536 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); 536 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
537 537
538 if (sc->sc_audiodev != NULL) 538 if (sc->sc_audiodev != NULL)
539 rv = config_detach(sc->sc_audiodev, flags); 539 rv = config_detach(sc->sc_audiodev, flags);
540 540
541 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 541 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
542 sc->sc_dev); 542 sc->sc_dev);
543 543
544 if (sc->sc_formats != NULL) 544 if (sc->sc_formats != NULL)
545 free(sc->sc_formats, M_USBDEV); 545 free(sc->sc_formats, M_USBDEV);
546 auconv_delete_encodings(sc->sc_encodings); 546 auconv_delete_encodings(sc->sc_encodings);
547 547
548 mutex_destroy(&sc->sc_lock); 548 mutex_destroy(&sc->sc_lock);
549 mutex_destroy(&sc->sc_intr_lock); 549 mutex_destroy(&sc->sc_intr_lock);
550 550
551 return rv; 551 return rv;
552} 552}
553 553
554Static int 554Static int
555uaudio_query_encoding(void *addr, struct audio_encoding *fp) 555uaudio_query_encoding(void *addr, struct audio_encoding *fp)
556{ 556{
557 struct uaudio_softc *sc; 557 struct uaudio_softc *sc;
558 int flags; 558 int flags;
559 559
560 sc = addr; 560 sc = addr;
561 flags = sc->sc_altflags; 561 flags = sc->sc_altflags;
562 if (sc->sc_dying) 562 if (sc->sc_dying)
563 return EIO; 563 return EIO;
564 564
565 if (sc->sc_nalts == 0 || flags == 0) 565 if (sc->sc_nalts == 0 || flags == 0)
566 return ENXIO; 566 return ENXIO;
567 567
568 return auconv_query_encoding(sc->sc_encodings, fp); 568 return auconv_query_encoding(sc->sc_encodings, fp);
569} 569}
570 570
571Static const usb_interface_descriptor_t * 571Static const usb_interface_descriptor_t *
572uaudio_find_iface(const char *tbuf, int size, int *offsp, int subtype) 572uaudio_find_iface(const char *tbuf, int size, int *offsp, int subtype)
573{ 573{
574 const usb_interface_descriptor_t *d; 574 const usb_interface_descriptor_t *d;
575 575
576 while (*offsp < size) { 576 while (*offsp < size) {
577 d = (const void *)(tbuf + *offsp); 577 d = (const void *)(tbuf + *offsp);
578 *offsp += d->bLength; 578 *offsp += d->bLength;
579 if (d->bDescriptorType == UDESC_INTERFACE && 579 if (d->bDescriptorType == UDESC_INTERFACE &&
580 d->bInterfaceClass == UICLASS_AUDIO && 580 d->bInterfaceClass == UICLASS_AUDIO &&
581 d->bInterfaceSubClass == subtype) 581 d->bInterfaceSubClass == subtype)
582 return d; 582 return d;
583 } 583 }
584 return NULL; 584 return NULL;
585} 585}
586 586
587Static void 587Static void
588uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc) 588uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
589{ 589{
590 int res; 590 int res;
591 size_t len; 591 size_t len;
592 struct mixerctl *nmc; 592 struct mixerctl *nmc;
593 593
594 if (mc->class < UAC_NCLASSES) { 594 if (mc->class < UAC_NCLASSES) {
595 DPRINTF("adding %s.%s\n", uac_names[mc->class], mc->ctlname); 595 DPRINTF("adding %s.%s\n", uac_names[mc->class], mc->ctlname);
596 } else { 596 } else {
597 DPRINTF("adding %s\n", mc->ctlname); 597 DPRINTF("adding %s\n", mc->ctlname);
598 } 598 }
599 len = sizeof(*mc) * (sc->sc_nctls + 1); 599 len = sizeof(*mc) * (sc->sc_nctls + 1);
600 nmc = malloc(len, M_USBDEV, M_NOWAIT); 600 nmc = malloc(len, M_USBDEV, M_NOWAIT);
601 if (nmc == NULL) { 601 if (nmc == NULL) {
602 aprint_error("uaudio_mixer_add_ctl: no memory\n"); 602 aprint_error("uaudio_mixer_add_ctl: no memory\n");
603 return; 603 return;
604 } 604 }
605 /* Copy old data, if there was any */ 605 /* Copy old data, if there was any */
606 if (sc->sc_nctls != 0) { 606 if (sc->sc_nctls != 0) {
607 memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls)); 607 memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls));
608 free(sc->sc_ctls, M_USBDEV); 608 free(sc->sc_ctls, M_USBDEV);
609 } 609 }
610 sc->sc_ctls = nmc; 610 sc->sc_ctls = nmc;
611 611
612 mc->delta = 0; 612 mc->delta = 0;
613 if (mc->type == MIX_ON_OFF) { 613 if (mc->type == MIX_ON_OFF) {
614 mc->minval = 0; 614 mc->minval = 0;
615 mc->maxval = 1; 615 mc->maxval = 1;
616 } else if (mc->type == MIX_SELECTOR) { 616 } else if (mc->type == MIX_SELECTOR) {
617 ; 617 ;
618 } else { 618 } else {
619 /* Determine min and max values. */ 619 /* Determine min and max values. */
620 mc->minval = uaudio_signext(mc->type, 620 mc->minval = uaudio_signext(mc->type,
621 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE, 621 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
622 mc->wValue[0], mc->wIndex, 622 mc->wValue[0], mc->wIndex,
623 MIX_SIZE(mc->type))); 623 MIX_SIZE(mc->type)));
624 mc->maxval = 1 + uaudio_signext(mc->type, 624 mc->maxval = 1 + uaudio_signext(mc->type,
625 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE, 625 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
626 mc->wValue[0], mc->wIndex, 626 mc->wValue[0], mc->wIndex,
627 MIX_SIZE(mc->type))); 627 MIX_SIZE(mc->type)));
628 mc->mul = mc->maxval - mc->minval; 628 mc->mul = mc->maxval - mc->minval;
629 if (mc->mul == 0) 629 if (mc->mul == 0)
630 mc->mul = 1; 630 mc->mul = 1;
631 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE, 631 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
632 mc->wValue[0], mc->wIndex, 632 mc->wValue[0], mc->wIndex,
633 MIX_SIZE(mc->type)); 633 MIX_SIZE(mc->type));
634 if (res > 0) 634 if (res > 0)
635 mc->delta = (res * 255 + mc->mul/2) / mc->mul; 635 mc->delta = (res * 255 + mc->mul/2) / mc->mul;
636 } 636 }
637 637
638 sc->sc_ctls[sc->sc_nctls++] = *mc; 638 sc->sc_ctls[sc->sc_nctls++] = *mc;
639 639
640#ifdef UAUDIO_DEBUG 640#ifdef UAUDIO_DEBUG
641 if (uaudiodebug > 2) { 641 if (uaudiodebug > 2) {
642 int i; 642 int i;
643 643
644 DPRINTFN_CLEAN(2, "wValue=%04x", mc->wValue[0]); 644 DPRINTFN_CLEAN(2, "wValue=%04x", mc->wValue[0]);
645 for (i = 1; i < mc->nchan; i++) 645 for (i = 1; i < mc->nchan; i++)
646 DPRINTFN_CLEAN(2, ",%04x", mc->wValue[i]); 646 DPRINTFN_CLEAN(2, ",%04x", mc->wValue[i]);
647 DPRINTFN_CLEAN(2, " wIndex=%04x type=%d name='%s' unit='%s' " 647 DPRINTFN_CLEAN(2, " wIndex=%04x type=%d name='%s' unit='%s' "
648 "min=%d max=%d\n", 648 "min=%d max=%d\n",
649 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit, 649 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
650 mc->minval, mc->maxval); 650 mc->minval, mc->maxval);
651 } 651 }
652#endif 652#endif
653} 653}
654 654
655Static char * 655Static char *
656uaudio_id_name(struct uaudio_softc *sc, 656uaudio_id_name(struct uaudio_softc *sc,
657 const struct io_terminal *iot, int id) 657 const struct io_terminal *iot, int id)
658{ 658{
659 static char tbuf[32]; 659 static char tbuf[32];
660 660
661 snprintf(tbuf, sizeof(tbuf), "i%d", id); 661 snprintf(tbuf, sizeof(tbuf), "i%d", id);
662 return tbuf; 662 return tbuf;
663} 663}
664 664
665#ifdef UAUDIO_DEBUG 665#ifdef UAUDIO_DEBUG
666Static void 666Static void
667uaudio_dump_cluster(const struct usb_audio_cluster *cl) 667uaudio_dump_cluster(const struct usb_audio_cluster *cl)
668{ 668{
669 static const char *channel_names[16] = { 669 static const char *channel_names[16] = {
670 "LEFT", "RIGHT", "CENTER", "LFE", 670 "LEFT", "RIGHT", "CENTER", "LFE",
671 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER", 671 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER",
672 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP", 672 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP",
673 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15", 673 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15",
674 }; 674 };
675 int cc, i, first; 675 int cc, i, first;
676 676
677 cc = UGETW(cl->wChannelConfig); 677 cc = UGETW(cl->wChannelConfig);
678 printf("cluster: bNrChannels=%u wChannelConfig=0x%.4x", 678 printf("cluster: bNrChannels=%u wChannelConfig=0x%.4x",
679 cl->bNrChannels, cc); 679 cl->bNrChannels, cc);
680 first = TRUE; 680 first = TRUE;
681 for (i = 0; cc != 0; i++) { 681 for (i = 0; cc != 0; i++) {
682 if (cc & 1) { 682 if (cc & 1) {
683 printf("%c%s", first ? '<' : ',', channel_names[i]); 683 printf("%c%s", first ? '<' : ',', channel_names[i]);
684 first = FALSE; 684 first = FALSE;
685 } 685 }
686 cc = cc >> 1; 686 cc = cc >> 1;
687 } 687 }
688 printf("> iChannelNames=%u", cl->iChannelNames); 688 printf("> iChannelNames=%u", cl->iChannelNames);
689} 689}
690#endif 690#endif
691 691
692Static struct usb_audio_cluster 692Static struct usb_audio_cluster
693uaudio_get_cluster(int id, const struct io_terminal *iot) 693uaudio_get_cluster(int id, const struct io_terminal *iot)
694{ 694{
695 struct usb_audio_cluster r; 695 struct usb_audio_cluster r;
696 const uaudio_cs_descriptor_t *dp; 696 const uaudio_cs_descriptor_t *dp;
697 int i; 697 int i;
698 698
699 for (i = 0; i < 25; i++) { /* avoid infinite loops */ 699 for (i = 0; i < 25; i++) { /* avoid infinite loops */
700 dp = iot[id].d.desc; 700 dp = iot[id].d.desc;
701 if (dp == 0) 701 if (dp == 0)
702 goto bad; 702 goto bad;
703 switch (dp->bDescriptorSubtype) { 703 switch (dp->bDescriptorSubtype) {
704 case UDESCSUB_AC_INPUT: 704 case UDESCSUB_AC_INPUT:
705 r.bNrChannels = iot[id].d.it->bNrChannels; 705 r.bNrChannels = iot[id].d.it->bNrChannels;
706 USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig)); 706 USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig));
707 r.iChannelNames = iot[id].d.it->iChannelNames; 707 r.iChannelNames = iot[id].d.it->iChannelNames;
708 return r; 708 return r;
709 case UDESCSUB_AC_OUTPUT: 709 case UDESCSUB_AC_OUTPUT:
710 id = iot[id].d.ot->bSourceId; 710 id = iot[id].d.ot->bSourceId;
711 break; 711 break;
712 case UDESCSUB_AC_MIXER: 712 case UDESCSUB_AC_MIXER:
713 r = *(const struct usb_audio_cluster *) 713 r = *(const struct usb_audio_cluster *)
714 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins]; 714 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
715 return r; 715 return r;
716 case UDESCSUB_AC_SELECTOR: 716 case UDESCSUB_AC_SELECTOR:
717 /* XXX This is not really right */ 717 /* XXX This is not really right */
718 id = iot[id].d.su->baSourceId[0]; 718 id = iot[id].d.su->baSourceId[0];
719 break; 719 break;
720 case UDESCSUB_AC_FEATURE: 720 case UDESCSUB_AC_FEATURE:
721 id = iot[id].d.fu->bSourceId; 721 id = iot[id].d.fu->bSourceId;
722 break; 722 break;
723 case UDESCSUB_AC_PROCESSING: 723 case UDESCSUB_AC_PROCESSING:
724 r = *(const struct usb_audio_cluster *) 724 r = *(const struct usb_audio_cluster *)
725 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins]; 725 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
726 return r; 726 return r;
727 case UDESCSUB_AC_EXTENSION: 727 case UDESCSUB_AC_EXTENSION:
728 r = *(const struct usb_audio_cluster *) 728 r = *(const struct usb_audio_cluster *)
729 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins]; 729 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
730 return r; 730 return r;
731 default: 731 default:
732 goto bad; 732 goto bad;
733 } 733 }
734 } 734 }
735 bad: 735 bad:
736 aprint_error("uaudio_get_cluster: bad data\n"); 736 aprint_error("uaudio_get_cluster: bad data\n");
737 memset(&r, 0, sizeof r); 737 memset(&r, 0, sizeof r);
738 return r; 738 return r;
739 739
740} 740}
741 741
742Static void 742Static void
743uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 743uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
744{ 744{
745 const struct usb_audio_input_terminal *d; 745 const struct usb_audio_input_terminal *d;
746 746
747 d = iot[id].d.it; 747 d = iot[id].d.it;
748#ifdef UAUDIO_DEBUG 748#ifdef UAUDIO_DEBUG
749 DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x " 749 DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x "
750 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d " 750 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
751 "iChannelNames=%d iTerminal=%d\n", 751 "iChannelNames=%d iTerminal=%d\n",
752 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 752 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
753 d->bNrChannels, UGETW(d->wChannelConfig), 753 d->bNrChannels, UGETW(d->wChannelConfig),
754 d->iChannelNames, d->iTerminal); 754 d->iChannelNames, d->iTerminal);
755#endif 755#endif
756 /* If USB input terminal, record wChannelConfig */ 756 /* If USB input terminal, record wChannelConfig */
757 if ((UGETW(d->wTerminalType) & 0xff00) != 0x0100) 757 if ((UGETW(d->wTerminalType) & 0xff00) != 0x0100)
758 return; 758 return;
759 sc->sc_channel_config = UGETW(d->wChannelConfig); 759 sc->sc_channel_config = UGETW(d->wChannelConfig);
760} 760}
761 761
762Static void 762Static void
763uaudio_add_output(struct uaudio_softc *sc, 763uaudio_add_output(struct uaudio_softc *sc,
764 const struct io_terminal *iot, int id) 764 const struct io_terminal *iot, int id)
765{ 765{
766#ifdef UAUDIO_DEBUG 766#ifdef UAUDIO_DEBUG
767 const struct usb_audio_output_terminal *d; 767 const struct usb_audio_output_terminal *d;
768 768
769 d = iot[id].d.ot; 769 d = iot[id].d.ot;
770 DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x " 770 DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x "
771 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n", 771 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
772 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 772 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
773 d->bSourceId, d->iTerminal); 773 d->bSourceId, d->iTerminal);
774#endif 774#endif
775} 775}
776 776
777Static void 777Static void
778uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 778uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
779{ 779{
780 const struct usb_audio_mixer_unit *d; 780 const struct usb_audio_mixer_unit *d;
781 const struct usb_audio_mixer_unit_1 *d1; 781 const struct usb_audio_mixer_unit_1 *d1;
782 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k; 782 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
783 const uByte *bm; 783 const uByte *bm;
784 struct mixerctl mix; 784 struct mixerctl mix;
785 785
786 d = iot[id].d.mu; 786 d = iot[id].d.mu;
787 DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n", 787 DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n",
788 d->bUnitId, d->bNrInPins); 788 d->bUnitId, d->bNrInPins);
789 789
790 /* Compute the number of input channels */ 790 /* Compute the number of input channels */
791 ichs = 0; 791 ichs = 0;
792 for (i = 0; i < d->bNrInPins; i++) 792 for (i = 0; i < d->bNrInPins; i++)
793 ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels; 793 ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
794 794
795 /* and the number of output channels */ 795 /* and the number of output channels */
796 d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins]; 796 d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
797 ochs = d1->bNrChannels; 797 ochs = d1->bNrChannels;
798 DPRINTFN(2,"ichs=%d ochs=%d\n", ichs, ochs); 798 DPRINTFN(2,"ichs=%d ochs=%d\n", ichs, ochs);
799 799
800 bm = d1->bmControls; 800 bm = d1->bmControls;
801 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 801 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
802 uaudio_determine_class(&iot[id], &mix); 802 uaudio_determine_class(&iot[id], &mix);
803 mix.type = MIX_SIGNED_16; 803 mix.type = MIX_SIGNED_16;
804 mix.ctlunit = AudioNvolume; 804 mix.ctlunit = AudioNvolume;
805#define _BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1) 805#define _BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
806 for (p = i = 0; i < d->bNrInPins; i++) { 806 for (p = i = 0; i < d->bNrInPins; i++) {
807 chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels; 807 chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
808 mc = 0; 808 mc = 0;
809 for (c = 0; c < chs; c++) { 809 for (c = 0; c < chs; c++) {
810 mo = 0; 810 mo = 0;
811 for (o = 0; o < ochs; o++) { 811 for (o = 0; o < ochs; o++) {
812 bno = (p + c) * ochs + o; 812 bno = (p + c) * ochs + o;
813 if (_BIT(bno)) 813 if (_BIT(bno))
814 mo++; 814 mo++;
815 } 815 }
816 if (mo == 1) 816 if (mo == 1)
817 mc++; 817 mc++;
818 } 818 }
819 if (mc == chs && chs <= MIX_MAX_CHAN) { 819 if (mc == chs && chs <= MIX_MAX_CHAN) {
820 k = 0; 820 k = 0;
821 for (c = 0; c < chs; c++) 821 for (c = 0; c < chs; c++)
822 for (o = 0; o < ochs; o++) { 822 for (o = 0; o < ochs; o++) {
823 bno = (p + c) * ochs + o; 823 bno = (p + c) * ochs + o;
824 if (_BIT(bno)) 824 if (_BIT(bno))
825 mix.wValue[k++] = 825 mix.wValue[k++] =
826 MAKE(p+c+1, o+1); 826 MAKE(p+c+1, o+1);
827 } 827 }
828 snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s", 828 snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s",
829 d->bUnitId, uaudio_id_name(sc, iot, 829 d->bUnitId, uaudio_id_name(sc, iot,
830 d->baSourceId[i])); 830 d->baSourceId[i]));
831 mix.nchan = chs; 831 mix.nchan = chs;
832 uaudio_mixer_add_ctl(sc, &mix); 832 uaudio_mixer_add_ctl(sc, &mix);
833 } else { 833 } else {
834 /* XXX */ 834 /* XXX */
835 } 835 }
836#undef _BIT 836#undef _BIT
837 p += chs; 837 p += chs;
838 } 838 }
839 839
840} 840}
841 841
842Static void 842Static void
843uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 843uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
844{ 844{
845 const struct usb_audio_selector_unit *d; 845 const struct usb_audio_selector_unit *d;
846 struct mixerctl mix; 846 struct mixerctl mix;
847 int i, wp; 847 int i, wp;
848 848
849 d = iot[id].d.su; 849 d = iot[id].d.su;
850 DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n", 850 DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n",
851 d->bUnitId, d->bNrInPins); 851 d->bUnitId, d->bNrInPins);
852 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 852 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
853 mix.wValue[0] = MAKE(0, 0); 853 mix.wValue[0] = MAKE(0, 0);
854 uaudio_determine_class(&iot[id], &mix); 854 uaudio_determine_class(&iot[id], &mix);
855 mix.nchan = 1; 855 mix.nchan = 1;
856 mix.type = MIX_SELECTOR; 856 mix.type = MIX_SELECTOR;
857 mix.ctlunit = ""; 857 mix.ctlunit = "";
858 mix.minval = 1; 858 mix.minval = 1;
859 mix.maxval = d->bNrInPins; 859 mix.maxval = d->bNrInPins;
860 mix.mul = mix.maxval - mix.minval; 860 mix.mul = mix.maxval - mix.minval;
861 wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId); 861 wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId);
862 for (i = 1; i <= d->bNrInPins; i++) { 862 for (i = 1; i <= d->bNrInPins; i++) {
863 wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp, 863 wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp,
864 "i%d", d->baSourceId[i - 1]); 864 "i%d", d->baSourceId[i - 1]);
865 if (wp > MAX_AUDIO_DEV_LEN - 1) 865 if (wp > MAX_AUDIO_DEV_LEN - 1)
866 break; 866 break;
867 } 867 }
868 uaudio_mixer_add_ctl(sc, &mix); 868 uaudio_mixer_add_ctl(sc, &mix);
869} 869}
870 870
871#ifdef UAUDIO_DEBUG 871#ifdef UAUDIO_DEBUG
872Static const char * 872Static const char *
873uaudio_get_terminal_name(int terminal_type) 873uaudio_get_terminal_name(int terminal_type)
874{ 874{
875 static char tbuf[100]; 875 static char tbuf[100];
876 876
877 switch (terminal_type) { 877 switch (terminal_type) {
878 /* USB terminal types */ 878 /* USB terminal types */
879 case UAT_UNDEFINED: return "UAT_UNDEFINED"; 879 case UAT_UNDEFINED: return "UAT_UNDEFINED";
880 case UAT_STREAM: return "UAT_STREAM"; 880 case UAT_STREAM: return "UAT_STREAM";
881 case UAT_VENDOR: return "UAT_VENDOR"; 881 case UAT_VENDOR: return "UAT_VENDOR";
882 /* input terminal types */ 882 /* input terminal types */
883 case UATI_UNDEFINED: return "UATI_UNDEFINED"; 883 case UATI_UNDEFINED: return "UATI_UNDEFINED";
884 case UATI_MICROPHONE: return "UATI_MICROPHONE"; 884 case UATI_MICROPHONE: return "UATI_MICROPHONE";
885 case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE"; 885 case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE";
886 case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE"; 886 case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE";
887 case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE"; 887 case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE";
888 case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY"; 888 case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY";
889 case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR"; 889 case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR";
890 /* output terminal types */ 890 /* output terminal types */
891 case UATO_UNDEFINED: return "UATO_UNDEFINED"; 891 case UATO_UNDEFINED: return "UATO_UNDEFINED";
892 case UATO_SPEAKER: return "UATO_SPEAKER"; 892 case UATO_SPEAKER: return "UATO_SPEAKER";
893 case UATO_HEADPHONES: return "UATO_HEADPHONES"; 893 case UATO_HEADPHONES: return "UATO_HEADPHONES";
894 case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO"; 894 case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO";
895 case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER"; 895 case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER";
896 case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER"; 896 case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER";
897 case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER"; 897 case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER";
898 case UATO_SUBWOOFER: return "UATO_SUBWOOFER"; 898 case UATO_SUBWOOFER: return "UATO_SUBWOOFER";
899 /* bidir terminal types */ 899 /* bidir terminal types */
900 case UATB_UNDEFINED: return "UATB_UNDEFINED"; 900 case UATB_UNDEFINED: return "UATB_UNDEFINED";
901 case UATB_HANDSET: return "UATB_HANDSET"; 901 case UATB_HANDSET: return "UATB_HANDSET";
902 case UATB_HEADSET: return "UATB_HEADSET"; 902 case UATB_HEADSET: return "UATB_HEADSET";
903 case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE"; 903 case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE";
904 case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP"; 904 case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP";
905 case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC"; 905 case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC";
906 /* telephony terminal types */ 906 /* telephony terminal types */
907 case UATT_UNDEFINED: return "UATT_UNDEFINED"; 907 case UATT_UNDEFINED: return "UATT_UNDEFINED";
908 case UATT_PHONELINE: return "UATT_PHONELINE"; 908 case UATT_PHONELINE: return "UATT_PHONELINE";
909 case UATT_TELEPHONE: return "UATT_TELEPHONE"; 909 case UATT_TELEPHONE: return "UATT_TELEPHONE";
910 case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE"; 910 case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE";
911 /* external terminal types */ 911 /* external terminal types */
912 case UATE_UNDEFINED: return "UATE_UNDEFINED"; 912 case UATE_UNDEFINED: return "UATE_UNDEFINED";
913 case UATE_ANALOGCONN: return "UATE_ANALOGCONN"; 913 case UATE_ANALOGCONN: return "UATE_ANALOGCONN";
914 case UATE_LINECONN: return "UATE_LINECONN"; 914 case UATE_LINECONN: return "UATE_LINECONN";
915 case UATE_LEGACYCONN: return "UATE_LEGACYCONN"; 915 case UATE_LEGACYCONN: return "UATE_LEGACYCONN";
916 case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC"; 916 case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC";
917 case UATE_SPDIF: return "UATE_SPDIF"; 917 case UATE_SPDIF: return "UATE_SPDIF";
918 case UATE_1394DA: return "UATE_1394DA"; 918 case UATE_1394DA: return "UATE_1394DA";
919 case UATE_1394DV: return "UATE_1394DV"; 919 case UATE_1394DV: return "UATE_1394DV";
920 /* embedded function terminal types */ 920 /* embedded function terminal types */
921 case UATF_UNDEFINED: return "UATF_UNDEFINED"; 921 case UATF_UNDEFINED: return "UATF_UNDEFINED";
922 case UATF_CALIBNOISE: return "UATF_CALIBNOISE"; 922 case UATF_CALIBNOISE: return "UATF_CALIBNOISE";
923 case UATF_EQUNOISE: return "UATF_EQUNOISE"; 923 case UATF_EQUNOISE: return "UATF_EQUNOISE";
924 case UATF_CDPLAYER: return "UATF_CDPLAYER"; 924 case UATF_CDPLAYER: return "UATF_CDPLAYER";
925 case UATF_DAT: return "UATF_DAT"; 925 case UATF_DAT: return "UATF_DAT";
926 case UATF_DCC: return "UATF_DCC"; 926 case UATF_DCC: return "UATF_DCC";
927 case UATF_MINIDISK: return "UATF_MINIDISK"; 927 case UATF_MINIDISK: return "UATF_MINIDISK";
928 case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE"; 928 case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE";
929 case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH"; 929 case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH";
930 case UATF_VCRAUDIO: return "UATF_VCRAUDIO"; 930 case UATF_VCRAUDIO: return "UATF_VCRAUDIO";
931 case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO"; 931 case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO";
932 case UATF_DVDAUDIO: return "UATF_DVDAUDIO"; 932 case UATF_DVDAUDIO: return "UATF_DVDAUDIO";
933 case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO"; 933 case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO";
934 case UATF_SATELLITE: return "UATF_SATELLITE"; 934 case UATF_SATELLITE: return "UATF_SATELLITE";
935 case UATF_CABLETUNER: return "UATF_CABLETUNER"; 935 case UATF_CABLETUNER: return "UATF_CABLETUNER";
936 case UATF_DSS: return "UATF_DSS"; 936 case UATF_DSS: return "UATF_DSS";
937 case UATF_RADIORECV: return "UATF_RADIORECV"; 937 case UATF_RADIORECV: return "UATF_RADIORECV";
938 case UATF_RADIOXMIT: return "UATF_RADIOXMIT"; 938 case UATF_RADIOXMIT: return "UATF_RADIOXMIT";
939 case UATF_MULTITRACK: return "UATF_MULTITRACK"; 939 case UATF_MULTITRACK: return "UATF_MULTITRACK";
940 case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER"; 940 case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER";
941 default: 941 default:
942 snprintf(tbuf, sizeof(tbuf), "unknown type (0x%.4x)", terminal_type); 942 snprintf(tbuf, sizeof(tbuf), "unknown type (0x%.4x)", terminal_type);
943 return tbuf; 943 return tbuf;
944 } 944 }
945} 945}
946#endif 946#endif
947 947
948Static int 948Static int
949uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix) 949uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
950{ 950{
951 int terminal_type; 951 int terminal_type;
952 952
953 if (iot == NULL || iot->output == NULL) { 953 if (iot == NULL || iot->output == NULL) {
954 mix->class = UAC_OUTPUT; 954 mix->class = UAC_OUTPUT;
955 return 0; 955 return 0;
956 } 956 }
957 terminal_type = 0; 957 terminal_type = 0;
958 if (iot->output->size == 1) 958 if (iot->output->size == 1)
959 terminal_type = iot->output->terminals[0]; 959 terminal_type = iot->output->terminals[0];
960 /* 960 /*
961 * If the only output terminal is USB, 961 * If the only output terminal is USB,
962 * the class is UAC_RECORD. 962 * the class is UAC_RECORD.
963 */ 963 */
964 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) { 964 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
965 mix->class = UAC_RECORD; 965 mix->class = UAC_RECORD;
966 if (iot->inputs_size == 1 966 if (iot->inputs_size == 1
967 && iot->inputs[0] != NULL 967 && iot->inputs[0] != NULL
968 && iot->inputs[0]->size == 1) 968 && iot->inputs[0]->size == 1)
969 return iot->inputs[0]->terminals[0]; 969 return iot->inputs[0]->terminals[0];
970 else 970 else
971 return 0; 971 return 0;
972 } 972 }
973 /* 973 /*
974 * If the ultimate destination of the unit is just one output 974 * If the ultimate destination of the unit is just one output
975 * terminal and the unit is connected to the output terminal 975 * terminal and the unit is connected to the output terminal
976 * directly, the class is UAC_OUTPUT. 976 * directly, the class is UAC_OUTPUT.
977 */ 977 */
978 if (terminal_type != 0 && iot->direct) { 978 if (terminal_type != 0 && iot->direct) {
979 mix->class = UAC_OUTPUT; 979 mix->class = UAC_OUTPUT;
980 return terminal_type; 980 return terminal_type;
981 } 981 }
982 /* 982 /*
983 * If the unit is connected to just one input terminal, 983 * If the unit is connected to just one input terminal,
984 * the class is UAC_INPUT. 984 * the class is UAC_INPUT.
985 */ 985 */
986 if (iot->inputs_size == 1 && iot->inputs[0] != NULL 986 if (iot->inputs_size == 1 && iot->inputs[0] != NULL
987 && iot->inputs[0]->size == 1) { 987 && iot->inputs[0]->size == 1) {
988 mix->class = UAC_INPUT; 988 mix->class = UAC_INPUT;
989 return iot->inputs[0]->terminals[0]; 989 return iot->inputs[0]->terminals[0];
990 } 990 }
991 /* 991 /*
992 * Otherwise, the class is UAC_OUTPUT. 992 * Otherwise, the class is UAC_OUTPUT.
993 */ 993 */
994 mix->class = UAC_OUTPUT; 994 mix->class = UAC_OUTPUT;
995 return terminal_type; 995 return terminal_type;
996} 996}
997 997
998Static const char * 998Static const char *
999uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix) 999uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
1000{ 1000{
1001 int terminal_type; 1001 int terminal_type;
1002 1002
1003 terminal_type = uaudio_determine_class(iot, mix); 1003 terminal_type = uaudio_determine_class(iot, mix);
1004 if (mix->class == UAC_RECORD && terminal_type == 0) 1004 if (mix->class == UAC_RECORD && terminal_type == 0)
1005 return AudioNmixerout; 1005 return AudioNmixerout;
1006 DPRINTF("terminal_type=%s\n", uaudio_get_terminal_name(terminal_type)); 1006 DPRINTF("terminal_type=%s\n", uaudio_get_terminal_name(terminal_type));
1007 switch (terminal_type) { 1007 switch (terminal_type) {
1008 case UAT_STREAM: 1008 case UAT_STREAM:
1009 return AudioNdac; 1009 return AudioNdac;
1010 1010
1011 case UATI_MICROPHONE: 1011 case UATI_MICROPHONE:
1012 case UATI_DESKMICROPHONE: 1012 case UATI_DESKMICROPHONE:
1013 case UATI_PERSONALMICROPHONE: 1013 case UATI_PERSONALMICROPHONE:
1014 case UATI_OMNIMICROPHONE: 1014 case UATI_OMNIMICROPHONE:
1015 case UATI_MICROPHONEARRAY: 1015 case UATI_MICROPHONEARRAY:
1016 case UATI_PROCMICROPHONEARR: 1016 case UATI_PROCMICROPHONEARR:
1017 return AudioNmicrophone; 1017 return AudioNmicrophone;
1018 1018
1019 case UATO_SPEAKER: 1019 case UATO_SPEAKER:
1020 case UATO_DESKTOPSPEAKER: 1020 case UATO_DESKTOPSPEAKER:
1021 case UATO_ROOMSPEAKER: 1021 case UATO_ROOMSPEAKER:
1022 case UATO_COMMSPEAKER: 1022 case UATO_COMMSPEAKER:
1023 return AudioNspeaker; 1023 return AudioNspeaker;
1024 1024
1025 case UATO_HEADPHONES: 1025 case UATO_HEADPHONES:
1026 return AudioNheadphone; 1026 return AudioNheadphone;
1027 1027
1028 case UATO_SUBWOOFER: 1028 case UATO_SUBWOOFER:
1029 return AudioNlfe; 1029 return AudioNlfe;
1030 1030
1031 /* telephony terminal types */ 1031 /* telephony terminal types */
1032 case UATT_UNDEFINED: 1032 case UATT_UNDEFINED:
1033 case UATT_PHONELINE: 1033 case UATT_PHONELINE:
1034 case UATT_TELEPHONE: 1034 case UATT_TELEPHONE:
1035 case UATT_DOWNLINEPHONE: 1035 case UATT_DOWNLINEPHONE:
1036 return "phone"; 1036 return "phone";
1037 1037
1038 case UATE_ANALOGCONN: 1038 case UATE_ANALOGCONN:
1039 case UATE_LINECONN: 1039 case UATE_LINECONN:
1040 case UATE_LEGACYCONN: 1040 case UATE_LEGACYCONN:
1041 return AudioNline; 1041 return AudioNline;
1042 1042
1043 case UATE_DIGITALAUIFC: 1043 case UATE_DIGITALAUIFC:
1044 case UATE_SPDIF: 1044 case UATE_SPDIF:
1045 case UATE_1394DA: 1045 case UATE_1394DA:
1046 case UATE_1394DV: 1046 case UATE_1394DV:
1047 return AudioNaux; 1047 return AudioNaux;
1048 1048
1049 case UATF_CDPLAYER: 1049 case UATF_CDPLAYER:
1050 return AudioNcd; 1050 return AudioNcd;
1051 1051
1052 case UATF_SYNTHESIZER: 1052 case UATF_SYNTHESIZER:
1053 return AudioNfmsynth; 1053 return AudioNfmsynth;
1054 1054
1055 case UATF_VIDEODISCAUDIO: 1055 case UATF_VIDEODISCAUDIO:
1056 case UATF_DVDAUDIO: 1056 case UATF_DVDAUDIO:
1057 case UATF_TVTUNERAUDIO: 1057 case UATF_TVTUNERAUDIO:
1058 return AudioNvideo; 1058 return AudioNvideo;
1059 1059
1060 case UAT_UNDEFINED: 1060 case UAT_UNDEFINED:
1061 case UAT_VENDOR: 1061 case UAT_VENDOR:
1062 case UATI_UNDEFINED: 1062 case UATI_UNDEFINED:
1063/* output terminal types */ 1063/* output terminal types */
1064 case UATO_UNDEFINED: 1064 case UATO_UNDEFINED:
1065 case UATO_DISPLAYAUDIO: 1065 case UATO_DISPLAYAUDIO:
1066/* bidir terminal types */ 1066/* bidir terminal types */
1067 case UATB_UNDEFINED: 1067 case UATB_UNDEFINED:
1068 case UATB_HANDSET: 1068 case UATB_HANDSET:
1069 case UATB_HEADSET: 1069 case UATB_HEADSET:
1070 case UATB_SPEAKERPHONE: 1070 case UATB_SPEAKERPHONE:
1071 case UATB_SPEAKERPHONEESUP: 1071 case UATB_SPEAKERPHONEESUP:
1072 case UATB_SPEAKERPHONEECANC: 1072 case UATB_SPEAKERPHONEECANC:
1073/* external terminal types */ 1073/* external terminal types */
1074 case UATE_UNDEFINED: 1074 case UATE_UNDEFINED:
1075/* embedded function terminal types */ 1075/* embedded function terminal types */
1076 case UATF_UNDEFINED: 1076 case UATF_UNDEFINED:
1077 case UATF_CALIBNOISE: 1077 case UATF_CALIBNOISE:
1078 case UATF_EQUNOISE: 1078 case UATF_EQUNOISE:
1079 case UATF_DAT: 1079 case UATF_DAT:
1080 case UATF_DCC: 1080 case UATF_DCC:
1081 case UATF_MINIDISK: 1081 case UATF_MINIDISK:
1082 case UATF_ANALOGTAPE: 1082 case UATF_ANALOGTAPE:
1083 case UATF_PHONOGRAPH: 1083 case UATF_PHONOGRAPH:
1084 case UATF_VCRAUDIO: 1084 case UATF_VCRAUDIO:
1085 case UATF_SATELLITE: 1085 case UATF_SATELLITE:
1086 case UATF_CABLETUNER: 1086 case UATF_CABLETUNER:
1087 case UATF_DSS: 1087 case UATF_DSS:
1088 case UATF_RADIORECV: 1088 case UATF_RADIORECV:
1089 case UATF_RADIOXMIT: 1089 case UATF_RADIOXMIT:
1090 case UATF_MULTITRACK: 1090 case UATF_MULTITRACK:
1091 case 0xffff: 1091 case 0xffff:
1092 default: 1092 default: