Wed Mar 23 22:04:18 2016 UTC ()
Whitespace


(skrll)
diff -r1.140.2.13 -r1.140.2.14 src/sys/dev/usb/uaudio.c

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

--- src/sys/dev/usb/uaudio.c 2016/03/13 07:11:01 1.140.2.13
+++ src/sys/dev/usb/uaudio.c 2016/03/23 22:04:18 1.140.2.14
@@ -1,1039 +1,1039 @@ @@ -1,1039 +1,1039 @@
1/* $NetBSD: uaudio.c,v 1.140.2.13 2016/03/13 07:11:01 skrll Exp $ */ 1/* $NetBSD: uaudio.c,v 1.140.2.14 2016/03/23 22:04:18 skrll 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/docs/devclass_docs/audio10.pdf 34 * USB audio specs: http://www.usb.org/developers/docs/devclass_docs/audio10.pdf
35 * http://www.usb.org/developers/docs/devclass_docs/frmts10.pdf 35 * http://www.usb.org/developers/docs/devclass_docs/frmts10.pdf
36 * http://www.usb.org/developers/docs/devclass_docs/termt10.pdf 36 * http://www.usb.org/developers/docs/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.140.2.13 2016/03/13 07:11:01 skrll Exp $"); 40__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.140.2.14 2016/03/23 22:04:18 skrll Exp $");
41 41
42#ifdef _KERNEL_OPT 42#ifdef _KERNEL_OPT
43#include "opt_usb.h" 43#include "opt_usb.h"
44#endif 44#endif
45 45
46#include <sys/param.h> 46#include <sys/param.h>
47#include <sys/systm.h> 47#include <sys/systm.h>
48#include <sys/kernel.h> 48#include <sys/kernel.h>
49#include <sys/malloc.h> 49#include <sys/malloc.h>
50#include <sys/device.h> 50#include <sys/device.h>
51#include <sys/ioctl.h> 51#include <sys/ioctl.h>
52#include <sys/file.h> 52#include <sys/file.h>
53#include <sys/reboot.h> /* for bootverbose */ 53#include <sys/reboot.h> /* for bootverbose */
54#include <sys/select.h> 54#include <sys/select.h>
55#include <sys/proc.h> 55#include <sys/proc.h>
56#include <sys/vnode.h> 56#include <sys/vnode.h>
57#include <sys/poll.h> 57#include <sys/poll.h>
58#include <sys/module.h> 58#include <sys/module.h>
59#include <sys/bus.h> 59#include <sys/bus.h>
60#include <sys/cpu.h> 60#include <sys/cpu.h>
61#include <sys/atomic.h> 61#include <sys/atomic.h>
62 62
63#include <sys/audioio.h> 63#include <sys/audioio.h>
64#include <dev/audio_if.h> 64#include <dev/audio_if.h>
65#include <dev/audiovar.h> 65#include <dev/audiovar.h>
66#include <dev/mulaw.h> 66#include <dev/mulaw.h>
67#include <dev/auconv.h> 67#include <dev/auconv.h>
68 68
69#include <dev/usb/usb.h> 69#include <dev/usb/usb.h>
70#include <dev/usb/usbdi.h> 70#include <dev/usb/usbdi.h>
71#include <dev/usb/usbdivar.h> 71#include <dev/usb/usbdivar.h>
72#include <dev/usb/usbdi_util.h> 72#include <dev/usb/usbdi_util.h>
73#include <dev/usb/usb_quirks.h> 73#include <dev/usb/usb_quirks.h>
74 74
75#include <dev/usb/usbdevs.h> 75#include <dev/usb/usbdevs.h>
76 76
77#include <dev/usb/uaudioreg.h> 77#include <dev/usb/uaudioreg.h>
78 78
79/* #define UAUDIO_DEBUG */ 79/* #define UAUDIO_DEBUG */
80/* #define UAUDIO_MULTIPLE_ENDPOINTS */ 80/* #define UAUDIO_MULTIPLE_ENDPOINTS */
81#ifdef UAUDIO_DEBUG 81#ifdef UAUDIO_DEBUG
82#define DPRINTF(x,y...) do { \ 82#define DPRINTF(x,y...) do { \
83 if (uaudiodebug) { \ 83 if (uaudiodebug) { \
84 struct lwp *l = curlwp; \ 84 struct lwp *l = curlwp; \
85 printf("%s[%d:%d]: "x, __func__, l->l_proc->p_pid, l->l_lid, y); \ 85 printf("%s[%d:%d]: "x, __func__, l->l_proc->p_pid, l->l_lid, y); \
86 } \ 86 } \
87 } while (0) 87 } while (0)
88#define DPRINTFN_CLEAN(n,x...) do { \ 88#define DPRINTFN_CLEAN(n,x...) do { \
89 if (uaudiodebug > (n)) \ 89 if (uaudiodebug > (n)) \
90 printf(x); \ 90 printf(x); \
91 } while (0) 91 } while (0)
92#define DPRINTFN(n,x,y...) do { \ 92#define DPRINTFN(n,x,y...) do { \
93 if (uaudiodebug > (n)) { \ 93 if (uaudiodebug > (n)) { \
94 struct lwp *l = curlwp; \ 94 struct lwp *l = curlwp; \
95 printf("%s[%d:%d]: "x, __func__, l->l_proc->p_pid, l->l_lid, y); \ 95 printf("%s[%d:%d]: "x, __func__, l->l_proc->p_pid, l->l_lid, y); \
96 } \ 96 } \
97 } while (0) 97 } while (0)
98int uaudiodebug = 0; 98int uaudiodebug = 0;
99#else 99#else
100#define DPRINTF(x,y...) 100#define DPRINTF(x,y...)
101#define DPRINTFN_CLEAN(n,x...) 101#define DPRINTFN_CLEAN(n,x...)
102#define DPRINTFN(n,x,y...) 102#define DPRINTFN(n,x,y...)
103#endif 103#endif
104 104
105#define UAUDIO_NCHANBUFS 6 /* number of outstanding request */ 105#define UAUDIO_NCHANBUFS 6 /* number of outstanding request */
106#define UAUDIO_NFRAMES 10 /* ms of sound in each request */ 106#define UAUDIO_NFRAMES 10 /* ms of sound in each request */
107 107
108 108
109#define MIX_MAX_CHAN 8 109#define MIX_MAX_CHAN 8
110struct mixerctl { 110struct mixerctl {
111 uint16_t wValue[MIX_MAX_CHAN]; /* using nchan */ 111 uint16_t wValue[MIX_MAX_CHAN]; /* using nchan */
112 uint16_t wIndex; 112 uint16_t wIndex;
113 uint8_t nchan; 113 uint8_t nchan;
114 uint8_t type; 114 uint8_t type;
115#define MIX_ON_OFF 1 115#define MIX_ON_OFF 1
116#define MIX_SIGNED_16 2 116#define MIX_SIGNED_16 2
117#define MIX_UNSIGNED_16 3 117#define MIX_UNSIGNED_16 3
118#define MIX_SIGNED_8 4 118#define MIX_SIGNED_8 4
119#define MIX_SELECTOR 5 119#define MIX_SELECTOR 5
120#define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1) 120#define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
121#define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16) 121#define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
122 int minval, maxval; 122 int minval, maxval;
123 u_int delta; 123 u_int delta;
124 u_int mul; 124 u_int mul;
125 uint8_t class; 125 uint8_t class;
126 char ctlname[MAX_AUDIO_DEV_LEN]; 126 char ctlname[MAX_AUDIO_DEV_LEN];
127 const char *ctlunit; 127 const char *ctlunit;
128}; 128};
129#define MAKE(h,l) (((h) << 8) | (l)) 129#define MAKE(h,l) (((h) << 8) | (l))
130 130
131struct as_info { 131struct as_info {
132 uint8_t alt; 132 uint8_t alt;
133 uint8_t encoding; 133 uint8_t encoding;
134 uint8_t attributes; /* Copy of bmAttributes of 134 uint8_t attributes; /* Copy of bmAttributes of
135 * usb_audio_streaming_endpoint_descriptor 135 * usb_audio_streaming_endpoint_descriptor
136 */ 136 */
137 struct usbd_interface * ifaceh; 137 struct usbd_interface * ifaceh;
138 const usb_interface_descriptor_t *idesc; 138 const usb_interface_descriptor_t *idesc;
139 const usb_endpoint_descriptor_audio_t *edesc; 139 const usb_endpoint_descriptor_audio_t *edesc;
140 const usb_endpoint_descriptor_audio_t *edesc1; 140 const usb_endpoint_descriptor_audio_t *edesc1;
141 const struct usb_audio_streaming_type1_descriptor *asf1desc; 141 const struct usb_audio_streaming_type1_descriptor *asf1desc;
142 struct audio_format *aformat; 142 struct audio_format *aformat;
143 int sc_busy; /* currently used */ 143 int sc_busy; /* currently used */
144}; 144};
145 145
146struct chan { 146struct chan {
147 void (*intr)(void *); /* DMA completion intr handler */ 147 void (*intr)(void *); /* DMA completion intr handler */
148 void *arg; /* arg for intr() */ 148 void *arg; /* arg for intr() */
149 struct usbd_pipe *pipe; 149 struct usbd_pipe *pipe;
150 struct usbd_pipe *sync_pipe; 150 struct usbd_pipe *sync_pipe;
151 151
152 u_int sample_size; 152 u_int sample_size;
153 u_int sample_rate; 153 u_int sample_rate;
154 u_int bytes_per_frame; 154 u_int bytes_per_frame;
155 u_int fraction; /* fraction/1000 is the extra samples/frame */ 155 u_int fraction; /* fraction/1000 is the extra samples/frame */
156 u_int residue; /* accumulates the fractional samples */ 156 u_int residue; /* accumulates the fractional samples */
157 157
158 u_char *start; /* upper layer buffer start */ 158 u_char *start; /* upper layer buffer start */
159 u_char *end; /* upper layer buffer end */ 159 u_char *end; /* upper layer buffer end */
160 u_char *cur; /* current position in upper layer buffer */ 160 u_char *cur; /* current position in upper layer buffer */
161 int blksize; /* chunk size to report up */ 161 int blksize; /* chunk size to report up */
162 int transferred; /* transferred bytes not reported up */ 162 int transferred; /* transferred bytes not reported up */
163 163
164 int altidx; /* currently used altidx */ 164 int altidx; /* currently used altidx */
165 165
166 int curchanbuf; 166 int curchanbuf;
167 struct chanbuf { 167 struct chanbuf {
168 struct chan *chan; 168 struct chan *chan;
169 struct usbd_xfer *xfer; 169 struct usbd_xfer *xfer;
170 u_char *buffer; 170 u_char *buffer;
171 uint16_t sizes[UAUDIO_NFRAMES]; 171 uint16_t sizes[UAUDIO_NFRAMES];
172 uint16_t offsets[UAUDIO_NFRAMES]; 172 uint16_t offsets[UAUDIO_NFRAMES];
173 uint16_t size; 173 uint16_t size;
174 } chanbufs[UAUDIO_NCHANBUFS]; 174 } chanbufs[UAUDIO_NCHANBUFS];
175 175
176 struct uaudio_softc *sc; /* our softc */ 176 struct uaudio_softc *sc; /* our softc */
177}; 177};
178 178
179/* 179/*
180 * XXX Locking notes: 180 * XXX Locking notes:
181 * 181 *
182 * The MI USB audio subsystem is not MP-SAFE. Our strategy here 182 * The MI USB audio subsystem is not MP-SAFE. Our strategy here
183 * is to ensure we have the kernel lock held when calling into 183 * is to ensure we have the kernel lock held when calling into
184 * usbd, and, generally, to have dropped the sc_intr_lock during 184 * usbd, and, generally, to have dropped the sc_intr_lock during
185 * these sections as well since the usb code will sleep. 185 * these sections as well since the usb code will sleep.
186 */ 186 */
187struct uaudio_softc { 187struct uaudio_softc {
188 device_t sc_dev; /* base device */ 188 device_t sc_dev; /* base device */
189 kmutex_t sc_lock; 189 kmutex_t sc_lock;
190 kmutex_t sc_intr_lock; 190 kmutex_t sc_intr_lock;
191 struct usbd_device *sc_udev; /* USB device */ 191 struct usbd_device *sc_udev; /* USB device */
192 int sc_ac_iface; /* Audio Control interface */ 192 int sc_ac_iface; /* Audio Control interface */
193 struct usbd_interface * sc_ac_ifaceh; 193 struct usbd_interface * sc_ac_ifaceh;
194 struct chan sc_playchan; /* play channel */ 194 struct chan sc_playchan; /* play channel */
195 struct chan sc_recchan; /* record channel */ 195 struct chan sc_recchan; /* record channel */
196 int sc_nullalt; 196 int sc_nullalt;
197 int sc_audio_rev; 197 int sc_audio_rev;
198 struct as_info *sc_alts; /* alternate settings */ 198 struct as_info *sc_alts; /* alternate settings */
199 int sc_nalts; /* # of alternate settings */ 199 int sc_nalts; /* # of alternate settings */
200 int sc_altflags; 200 int sc_altflags;
201#define HAS_8 0x01 201#define HAS_8 0x01
202#define HAS_16 0x02 202#define HAS_16 0x02
203#define HAS_8U 0x04 203#define HAS_8U 0x04
204#define HAS_ALAW 0x08 204#define HAS_ALAW 0x08
205#define HAS_MULAW 0x10 205#define HAS_MULAW 0x10
206#define UA_NOFRAC 0x20 /* don't do sample rate adjustment */ 206#define UA_NOFRAC 0x20 /* don't do sample rate adjustment */
207#define HAS_24 0x40 207#define HAS_24 0x40
208 int sc_mode; /* play/record capability */ 208 int sc_mode; /* play/record capability */
209 struct mixerctl *sc_ctls; /* mixer controls */ 209 struct mixerctl *sc_ctls; /* mixer controls */
210 int sc_nctls; /* # of mixer controls */ 210 int sc_nctls; /* # of mixer controls */
211 device_t sc_audiodev; 211 device_t sc_audiodev;
212 struct audio_format *sc_formats; 212 struct audio_format *sc_formats;
213 int sc_nformats; 213 int sc_nformats;
214 struct audio_encoding_set *sc_encodings; 214 struct audio_encoding_set *sc_encodings;
215 u_int sc_channel_config; 215 u_int sc_channel_config;
216 char sc_dying; 216 char sc_dying;
217 struct audio_device sc_adev; 217 struct audio_device sc_adev;
218}; 218};
219 219
220struct terminal_list { 220struct terminal_list {
221 int size; 221 int size;
222 uint16_t terminals[1]; 222 uint16_t terminals[1];
223}; 223};
224#define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \ 224#define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \
225 + sizeof(uint16_t) * (N)) 225 + sizeof(uint16_t) * (N))
226 226
227struct io_terminal { 227struct io_terminal {
228 union { 228 union {
229 const uaudio_cs_descriptor_t *desc; 229 const uaudio_cs_descriptor_t *desc;
230 const struct usb_audio_input_terminal *it; 230 const struct usb_audio_input_terminal *it;
231 const struct usb_audio_output_terminal *ot; 231 const struct usb_audio_output_terminal *ot;
232 const struct usb_audio_mixer_unit *mu; 232 const struct usb_audio_mixer_unit *mu;
233 const struct usb_audio_selector_unit *su; 233 const struct usb_audio_selector_unit *su;
234 const struct usb_audio_feature_unit *fu; 234 const struct usb_audio_feature_unit *fu;
235 const struct usb_audio_processing_unit *pu; 235 const struct usb_audio_processing_unit *pu;
236 const struct usb_audio_extension_unit *eu; 236 const struct usb_audio_extension_unit *eu;
237 } d; 237 } d;
238 int inputs_size; 238 int inputs_size;
239 struct terminal_list **inputs; /* list of source input terminals */ 239 struct terminal_list **inputs; /* list of source input terminals */
240 struct terminal_list *output; /* list of destination output terminals */ 240 struct terminal_list *output; /* list of destination output terminals */
241 int direct; /* directly connected to an output terminal */ 241 int direct; /* directly connected to an output terminal */
242}; 242};
243 243
244#define UAC_OUTPUT 0 244#define UAC_OUTPUT 0
245#define UAC_INPUT 1 245#define UAC_INPUT 1
246#define UAC_EQUAL 2 246#define UAC_EQUAL 2
247#define UAC_RECORD 3 247#define UAC_RECORD 3
248#define UAC_NCLASSES 4 248#define UAC_NCLASSES 4
249#ifdef UAUDIO_DEBUG 249#ifdef UAUDIO_DEBUG
250Static const char *uac_names[] = { 250Static const char *uac_names[] = {
251 AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord, 251 AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
252}; 252};
253#endif 253#endif
254 254
255#ifdef UAUDIO_DEBUG 255#ifdef UAUDIO_DEBUG
256Static void uaudio_dump_tml 256Static void uaudio_dump_tml
257 (struct terminal_list *tml); 257 (struct terminal_list *tml);
258#endif 258#endif
259Static usbd_status uaudio_identify_ac 259Static usbd_status uaudio_identify_ac
260 (struct uaudio_softc *, const usb_config_descriptor_t *); 260 (struct uaudio_softc *, const usb_config_descriptor_t *);
261Static usbd_status uaudio_identify_as 261Static usbd_status uaudio_identify_as
262 (struct uaudio_softc *, const usb_config_descriptor_t *); 262 (struct uaudio_softc *, const usb_config_descriptor_t *);
263Static usbd_status uaudio_process_as 263Static usbd_status uaudio_process_as
264 (struct uaudio_softc *, const char *, int *, int, 264 (struct uaudio_softc *, const char *, int *, int,
265 const usb_interface_descriptor_t *); 265 const usb_interface_descriptor_t *);
266 266
267Static void uaudio_add_alt(struct uaudio_softc *, const struct as_info *); 267Static void uaudio_add_alt(struct uaudio_softc *, const struct as_info *);
268 268
269Static const usb_interface_descriptor_t *uaudio_find_iface 269Static const usb_interface_descriptor_t *uaudio_find_iface
270 (const char *, int, int *, int); 270 (const char *, int, int *, int);
271 271
272Static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *); 272Static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
273Static char *uaudio_id_name 273Static char *uaudio_id_name
274 (struct uaudio_softc *, const struct io_terminal *, int); 274 (struct uaudio_softc *, const struct io_terminal *, int);
275#ifdef UAUDIO_DEBUG 275#ifdef UAUDIO_DEBUG
276Static void uaudio_dump_cluster(const struct usb_audio_cluster *); 276Static void uaudio_dump_cluster(const struct usb_audio_cluster *);
277#endif 277#endif
278Static struct usb_audio_cluster uaudio_get_cluster 278Static struct usb_audio_cluster uaudio_get_cluster
279 (int, const struct io_terminal *); 279 (int, const struct io_terminal *);
280Static void uaudio_add_input 280Static void uaudio_add_input
281 (struct uaudio_softc *, const struct io_terminal *, int); 281 (struct uaudio_softc *, const struct io_terminal *, int);
282Static void uaudio_add_output 282Static void uaudio_add_output
283 (struct uaudio_softc *, const struct io_terminal *, int); 283 (struct uaudio_softc *, const struct io_terminal *, int);
284Static void uaudio_add_mixer 284Static void uaudio_add_mixer
285 (struct uaudio_softc *, const struct io_terminal *, int); 285 (struct uaudio_softc *, const struct io_terminal *, int);
286Static void uaudio_add_selector 286Static void uaudio_add_selector
287 (struct uaudio_softc *, const struct io_terminal *, int); 287 (struct uaudio_softc *, const struct io_terminal *, int);
288#ifdef UAUDIO_DEBUG 288#ifdef UAUDIO_DEBUG
289Static const char *uaudio_get_terminal_name(int); 289Static const char *uaudio_get_terminal_name(int);
290#endif 290#endif
291Static int uaudio_determine_class 291Static int uaudio_determine_class
292 (const struct io_terminal *, struct mixerctl *); 292 (const struct io_terminal *, struct mixerctl *);
293Static const char *uaudio_feature_name 293Static const char *uaudio_feature_name
294 (const struct io_terminal *, struct mixerctl *); 294 (const struct io_terminal *, struct mixerctl *);
295Static void uaudio_add_feature 295Static void uaudio_add_feature
296 (struct uaudio_softc *, const struct io_terminal *, int); 296 (struct uaudio_softc *, const struct io_terminal *, int);
297Static void uaudio_add_processing_updown 297Static void uaudio_add_processing_updown
298 (struct uaudio_softc *, const struct io_terminal *, int); 298 (struct uaudio_softc *, const struct io_terminal *, int);
299Static void uaudio_add_processing 299Static void uaudio_add_processing
300 (struct uaudio_softc *, const struct io_terminal *, int); 300 (struct uaudio_softc *, const struct io_terminal *, int);
301Static void uaudio_add_extension 301Static void uaudio_add_extension
302 (struct uaudio_softc *, const struct io_terminal *, int); 302 (struct uaudio_softc *, const struct io_terminal *, int);
303Static struct terminal_list *uaudio_merge_terminal_list 303Static struct terminal_list *uaudio_merge_terminal_list
304 (const struct io_terminal *); 304 (const struct io_terminal *);
305Static struct terminal_list *uaudio_io_terminaltype 305Static struct terminal_list *uaudio_io_terminaltype
306 (int, struct io_terminal *, int); 306 (int, struct io_terminal *, int);
307Static usbd_status uaudio_identify 307Static usbd_status uaudio_identify
308 (struct uaudio_softc *, const usb_config_descriptor_t *); 308 (struct uaudio_softc *, const usb_config_descriptor_t *);
309 309
310Static int uaudio_signext(int, int); 310Static int uaudio_signext(int, int);
311Static int uaudio_value2bsd(struct mixerctl *, int); 311Static int uaudio_value2bsd(struct mixerctl *, int);
312Static int uaudio_bsd2value(struct mixerctl *, int); 312Static int uaudio_bsd2value(struct mixerctl *, int);
313Static int uaudio_get(struct uaudio_softc *, int, int, int, int, int); 313Static int uaudio_get(struct uaudio_softc *, int, int, int, int, int);
314Static int uaudio_ctl_get 314Static int uaudio_ctl_get
315 (struct uaudio_softc *, int, struct mixerctl *, int); 315 (struct uaudio_softc *, int, struct mixerctl *, int);
316Static void uaudio_set 316Static void uaudio_set
317 (struct uaudio_softc *, int, int, int, int, int, int); 317 (struct uaudio_softc *, int, int, int, int, int, int);
318Static void uaudio_ctl_set 318Static void uaudio_ctl_set
319 (struct uaudio_softc *, int, struct mixerctl *, int, int); 319 (struct uaudio_softc *, int, struct mixerctl *, int, int);
320 320
321Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int); 321Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
322 322
323Static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *); 323Static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
324Static void uaudio_chan_abort(struct uaudio_softc *, struct chan *); 324Static void uaudio_chan_abort(struct uaudio_softc *, struct chan *);
325Static void uaudio_chan_close(struct uaudio_softc *, struct chan *); 325Static void uaudio_chan_close(struct uaudio_softc *, struct chan *);
326Static usbd_status uaudio_chan_alloc_buffers 326Static usbd_status uaudio_chan_alloc_buffers
327 (struct uaudio_softc *, struct chan *); 327 (struct uaudio_softc *, struct chan *);
328Static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *); 328Static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
329Static void uaudio_chan_init 329Static void uaudio_chan_init
330 (struct chan *, int, const struct audio_params *, int); 330 (struct chan *, int, const struct audio_params *, int);
331Static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int); 331Static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int);
332Static void uaudio_chan_ptransfer(struct chan *); 332Static void uaudio_chan_ptransfer(struct chan *);
333Static void uaudio_chan_pintr 333Static void uaudio_chan_pintr
334 (struct usbd_xfer *, void *, usbd_status); 334 (struct usbd_xfer *, void *, usbd_status);
335 335
336Static void uaudio_chan_rtransfer(struct chan *); 336Static void uaudio_chan_rtransfer(struct chan *);
337Static void uaudio_chan_rintr 337Static void uaudio_chan_rintr
338 (struct usbd_xfer *, void *, usbd_status); 338 (struct usbd_xfer *, void *, usbd_status);
339 339
340Static int uaudio_open(void *, int); 340Static int uaudio_open(void *, int);
341Static void uaudio_close(void *); 341Static void uaudio_close(void *);
342Static int uaudio_drain(void *); 342Static int uaudio_drain(void *);
343Static int uaudio_query_encoding(void *, struct audio_encoding *); 343Static int uaudio_query_encoding(void *, struct audio_encoding *);
344Static int uaudio_set_params 344Static int uaudio_set_params
345 (void *, int, int, struct audio_params *, struct audio_params *, 345 (void *, int, int, struct audio_params *, struct audio_params *,
346 stream_filter_list_t *, stream_filter_list_t *); 346 stream_filter_list_t *, stream_filter_list_t *);
347Static int uaudio_round_blocksize(void *, int, int, const audio_params_t *); 347Static int uaudio_round_blocksize(void *, int, int, const audio_params_t *);
348Static int uaudio_trigger_output 348Static int uaudio_trigger_output
349 (void *, void *, void *, int, void (*)(void *), void *, 349 (void *, void *, void *, int, void (*)(void *), void *,
350 const audio_params_t *); 350 const audio_params_t *);
351Static int uaudio_trigger_input 351Static int uaudio_trigger_input
352 (void *, void *, void *, int, void (*)(void *), void *, 352 (void *, void *, void *, int, void (*)(void *), void *,
353 const audio_params_t *); 353 const audio_params_t *);
354Static int uaudio_halt_in_dma(void *); 354Static int uaudio_halt_in_dma(void *);
355Static int uaudio_halt_out_dma(void *); 355Static int uaudio_halt_out_dma(void *);
356Static int uaudio_getdev(void *, struct audio_device *); 356Static int uaudio_getdev(void *, struct audio_device *);
357Static int uaudio_mixer_set_port(void *, mixer_ctrl_t *); 357Static int uaudio_mixer_set_port(void *, mixer_ctrl_t *);
358Static int uaudio_mixer_get_port(void *, mixer_ctrl_t *); 358Static int uaudio_mixer_get_port(void *, mixer_ctrl_t *);
359Static int uaudio_query_devinfo(void *, mixer_devinfo_t *); 359Static int uaudio_query_devinfo(void *, mixer_devinfo_t *);
360Static int uaudio_get_props(void *); 360Static int uaudio_get_props(void *);
361Static void uaudio_get_locks(void *, kmutex_t **, kmutex_t **); 361Static void uaudio_get_locks(void *, kmutex_t **, kmutex_t **);
362 362
363Static const struct audio_hw_if uaudio_hw_if = { 363Static const struct audio_hw_if uaudio_hw_if = {
364 uaudio_open, 364 uaudio_open,
365 uaudio_close, 365 uaudio_close,
366 uaudio_drain, 366 uaudio_drain,
367 uaudio_query_encoding, 367 uaudio_query_encoding,
368 uaudio_set_params, 368 uaudio_set_params,
369 uaudio_round_blocksize, 369 uaudio_round_blocksize,
370 NULL, 370 NULL,
371 NULL, 371 NULL,
372 NULL, 372 NULL,
373 NULL, 373 NULL,
374 NULL, 374 NULL,
375 uaudio_halt_out_dma, 375 uaudio_halt_out_dma,
376 uaudio_halt_in_dma, 376 uaudio_halt_in_dma,
377 NULL, 377 NULL,
378 uaudio_getdev, 378 uaudio_getdev,
379 NULL, 379 NULL,
380 uaudio_mixer_set_port, 380 uaudio_mixer_set_port,
381 uaudio_mixer_get_port, 381 uaudio_mixer_get_port,
382 uaudio_query_devinfo, 382 uaudio_query_devinfo,
383 NULL, 383 NULL,
384 NULL, 384 NULL,
385 NULL, 385 NULL,
386 NULL, 386 NULL,
387 uaudio_get_props, 387 uaudio_get_props,
388 uaudio_trigger_output, 388 uaudio_trigger_output,
389 uaudio_trigger_input, 389 uaudio_trigger_input,
390 NULL, 390 NULL,
391 uaudio_get_locks, 391 uaudio_get_locks,
392}; 392};
393 393
394int uaudio_match(device_t, cfdata_t, void *); 394int uaudio_match(device_t, cfdata_t, void *);
395void uaudio_attach(device_t, device_t, void *); 395void uaudio_attach(device_t, device_t, void *);
396int uaudio_detach(device_t, int); 396int uaudio_detach(device_t, int);
397void uaudio_childdet(device_t, device_t); 397void uaudio_childdet(device_t, device_t);
398int uaudio_activate(device_t, enum devact); 398int uaudio_activate(device_t, enum devact);
399 399
400extern struct cfdriver uaudio_cd; 400extern struct cfdriver uaudio_cd;
401 401
402CFATTACH_DECL2_NEW(uaudio, sizeof(struct uaudio_softc), 402CFATTACH_DECL2_NEW(uaudio, sizeof(struct uaudio_softc),
403 uaudio_match, uaudio_attach, uaudio_detach, uaudio_activate, NULL, 403 uaudio_match, uaudio_attach, uaudio_detach, uaudio_activate, NULL,
404 uaudio_childdet); 404 uaudio_childdet);
405 405
406int 406int
407uaudio_match(device_t parent, cfdata_t match, void *aux) 407uaudio_match(device_t parent, cfdata_t match, void *aux)
408{ 408{
409 struct usbif_attach_arg *uiaa = aux; 409 struct usbif_attach_arg *uiaa = aux;
410 410
411 /* Trigger on the control interface. */ 411 /* Trigger on the control interface. */
412 if (uiaa->uiaa_class != UICLASS_AUDIO || 412 if (uiaa->uiaa_class != UICLASS_AUDIO ||
413 uiaa->uiaa_subclass != UISUBCLASS_AUDIOCONTROL || 413 uiaa->uiaa_subclass != UISUBCLASS_AUDIOCONTROL ||
414 (usbd_get_quirks(uiaa->uiaa_device)->uq_flags & UQ_BAD_AUDIO)) 414 (usbd_get_quirks(uiaa->uiaa_device)->uq_flags & UQ_BAD_AUDIO))
415 return UMATCH_NONE; 415 return UMATCH_NONE;
416 416
417 return UMATCH_IFACECLASS_IFACESUBCLASS; 417 return UMATCH_IFACECLASS_IFACESUBCLASS;
418} 418}
419 419
420void 420void
421uaudio_attach(device_t parent, device_t self, void *aux) 421uaudio_attach(device_t parent, device_t self, void *aux)
422{ 422{
423 struct uaudio_softc *sc = device_private(self); 423 struct uaudio_softc *sc = device_private(self);
424 struct usbif_attach_arg *uiaa = aux; 424 struct usbif_attach_arg *uiaa = aux;
425 usb_interface_descriptor_t *id; 425 usb_interface_descriptor_t *id;
426 usb_config_descriptor_t *cdesc; 426 usb_config_descriptor_t *cdesc;
427 char *devinfop; 427 char *devinfop;
428 usbd_status err; 428 usbd_status err;
429 int i, j, found; 429 int i, j, found;
430 430
431 sc->sc_dev = self; 431 sc->sc_dev = self;
432 sc->sc_udev = uiaa->uiaa_device; 432 sc->sc_udev = uiaa->uiaa_device;
433 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 433 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
434 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED); 434 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
435 435
436 strlcpy(sc->sc_adev.name, "USB audio", sizeof(sc->sc_adev.name)); 436 strlcpy(sc->sc_adev.name, "USB audio", sizeof(sc->sc_adev.name));
437 strlcpy(sc->sc_adev.version, "", sizeof(sc->sc_adev.version)); 437 strlcpy(sc->sc_adev.version, "", sizeof(sc->sc_adev.version));
438 snprintf(sc->sc_adev.config, sizeof(sc->sc_adev.config), "usb:%08x", 438 snprintf(sc->sc_adev.config, sizeof(sc->sc_adev.config), "usb:%08x",
439 sc->sc_udev->ud_cookie.cookie); 439 sc->sc_udev->ud_cookie.cookie);
440 440
441 aprint_naive("\n"); 441 aprint_naive("\n");
442 aprint_normal("\n"); 442 aprint_normal("\n");
443 443
444 devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); 444 devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0);
445 aprint_normal_dev(self, "%s\n", devinfop); 445 aprint_normal_dev(self, "%s\n", devinfop);
446 usbd_devinfo_free(devinfop); 446 usbd_devinfo_free(devinfop);
447 447
448 cdesc = usbd_get_config_descriptor(sc->sc_udev); 448 cdesc = usbd_get_config_descriptor(sc->sc_udev);
449 if (cdesc == NULL) { 449 if (cdesc == NULL) {
450 aprint_error_dev(self, 450 aprint_error_dev(self,
451 "failed to get configuration descriptor\n"); 451 "failed to get configuration descriptor\n");
452 return; 452 return;
453 } 453 }
454 454
455 err = uaudio_identify(sc, cdesc); 455 err = uaudio_identify(sc, cdesc);
456 if (err) { 456 if (err) {
457 aprint_error_dev(self, 457 aprint_error_dev(self,
458 "audio descriptors make no sense, error=%d\n", err); 458 "audio descriptors make no sense, error=%d\n", err);
459 return; 459 return;
460 } 460 }
461 461
462 sc->sc_ac_ifaceh = uiaa->uiaa_iface; 462 sc->sc_ac_ifaceh = uiaa->uiaa_iface;
463 /* Pick up the AS interface. */ 463 /* Pick up the AS interface. */
464 for (i = 0; i < uiaa->uiaa_nifaces; i++) { 464 for (i = 0; i < uiaa->uiaa_nifaces; i++) {
465 if (uiaa->uiaa_ifaces[i] == NULL) 465 if (uiaa->uiaa_ifaces[i] == NULL)
466 continue; 466 continue;
467 id = usbd_get_interface_descriptor(uiaa->uiaa_ifaces[i]); 467 id = usbd_get_interface_descriptor(uiaa->uiaa_ifaces[i]);
468 if (id == NULL) 468 if (id == NULL)
469 continue; 469 continue;
470 found = 0; 470 found = 0;
471 for (j = 0; j < sc->sc_nalts; j++) { 471 for (j = 0; j < sc->sc_nalts; j++) {
472 if (id->bInterfaceNumber == 472 if (id->bInterfaceNumber ==
473 sc->sc_alts[j].idesc->bInterfaceNumber) { 473 sc->sc_alts[j].idesc->bInterfaceNumber) {
474 sc->sc_alts[j].ifaceh = uiaa->uiaa_ifaces[i]; 474 sc->sc_alts[j].ifaceh = uiaa->uiaa_ifaces[i];
475 found = 1; 475 found = 1;
476 } 476 }
477 } 477 }
478 if (found) 478 if (found)
479 uiaa->uiaa_ifaces[i] = NULL; 479 uiaa->uiaa_ifaces[i] = NULL;
480 } 480 }
481 481
482 for (j = 0; j < sc->sc_nalts; j++) { 482 for (j = 0; j < sc->sc_nalts; j++) {
483 if (sc->sc_alts[j].ifaceh == NULL) { 483 if (sc->sc_alts[j].ifaceh == NULL) {
484 aprint_error_dev(self, 484 aprint_error_dev(self,
485 "alt %d missing AS interface(s)\n", j); 485 "alt %d missing AS interface(s)\n", j);
486 return; 486 return;
487 } 487 }
488 } 488 }
489 489
490 aprint_normal_dev(self, "audio rev %d.%02x\n", 490 aprint_normal_dev(self, "audio rev %d.%02x\n",
491 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff); 491 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
492 492
493 sc->sc_playchan.sc = sc->sc_recchan.sc = sc; 493 sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
494 sc->sc_playchan.altidx = -1; 494 sc->sc_playchan.altidx = -1;
495 sc->sc_recchan.altidx = -1; 495 sc->sc_recchan.altidx = -1;
496 496
497 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC) 497 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
498 sc->sc_altflags |= UA_NOFRAC; 498 sc->sc_altflags |= UA_NOFRAC;
499 499
500#ifndef UAUDIO_DEBUG 500#ifndef UAUDIO_DEBUG
501 if (bootverbose) 501 if (bootverbose)
502#endif 502#endif
503 aprint_normal_dev(self, "%d mixer controls\n", 503 aprint_normal_dev(self, "%d mixer controls\n",
504 sc->sc_nctls); 504 sc->sc_nctls);
505 505
506 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 506 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
507 sc->sc_dev); 507 sc->sc_dev);
508 508
509 DPRINTF("%s", "doing audio_attach_mi\n"); 509 DPRINTF("%s", "doing audio_attach_mi\n");
510 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, sc->sc_dev); 510 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, sc->sc_dev);
511 511
512 return; 512 return;
513} 513}
514 514
515int 515int
516uaudio_activate(device_t self, enum devact act) 516uaudio_activate(device_t self, enum devact act)
517{ 517{
518 struct uaudio_softc *sc = device_private(self); 518 struct uaudio_softc *sc = device_private(self);
519 519
520 switch (act) { 520 switch (act) {
521 case DVACT_DEACTIVATE: 521 case DVACT_DEACTIVATE:
522 sc->sc_dying = 1; 522 sc->sc_dying = 1;
523 return 0; 523 return 0;
524 default: 524 default:
525 return EOPNOTSUPP; 525 return EOPNOTSUPP;
526 } 526 }
527} 527}
528 528
529void 529void
530uaudio_childdet(device_t self, device_t child) 530uaudio_childdet(device_t self, device_t child)
531{ 531{
532 struct uaudio_softc *sc = device_private(self); 532 struct uaudio_softc *sc = device_private(self);
533 533
534 KASSERT(sc->sc_audiodev == child); 534 KASSERT(sc->sc_audiodev == child);
535 sc->sc_audiodev = NULL; 535 sc->sc_audiodev = NULL;
536} 536}
537 537
538int 538int
539uaudio_detach(device_t self, int flags) 539uaudio_detach(device_t self, int flags)
540{ 540{
541 struct uaudio_softc *sc = device_private(self); 541 struct uaudio_softc *sc = device_private(self);
542 int rv; 542 int rv;
543 543
544 rv = 0; 544 rv = 0;
545 /* Wait for outstanding requests to complete. */ 545 /* Wait for outstanding requests to complete. */
546 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); 546 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
547 547
548 if (sc->sc_audiodev != NULL) 548 if (sc->sc_audiodev != NULL)
549 rv = config_detach(sc->sc_audiodev, flags); 549 rv = config_detach(sc->sc_audiodev, flags);
550 550
551 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 551 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
552 sc->sc_dev); 552 sc->sc_dev);
553 553
554 if (sc->sc_formats != NULL) 554 if (sc->sc_formats != NULL)
555 kmem_free(sc->sc_formats, 555 kmem_free(sc->sc_formats,
556 sizeof(struct audio_format) * sc->sc_nformats); 556 sizeof(struct audio_format) * sc->sc_nformats);
557 auconv_delete_encodings(sc->sc_encodings); 557 auconv_delete_encodings(sc->sc_encodings);
558 558
559 mutex_destroy(&sc->sc_lock); 559 mutex_destroy(&sc->sc_lock);
560 mutex_destroy(&sc->sc_intr_lock); 560 mutex_destroy(&sc->sc_intr_lock);
561 561
562 return rv; 562 return rv;
563} 563}
564 564
565Static int 565Static int
566uaudio_query_encoding(void *addr, struct audio_encoding *fp) 566uaudio_query_encoding(void *addr, struct audio_encoding *fp)
567{ 567{
568 struct uaudio_softc *sc; 568 struct uaudio_softc *sc;
569 int flags; 569 int flags;
570 570
571 sc = addr; 571 sc = addr;
572 flags = sc->sc_altflags; 572 flags = sc->sc_altflags;
573 if (sc->sc_dying) 573 if (sc->sc_dying)
574 return EIO; 574 return EIO;
575 575
576 if (sc->sc_nalts == 0 || flags == 0) 576 if (sc->sc_nalts == 0 || flags == 0)
577 return ENXIO; 577 return ENXIO;
578 578
579 return auconv_query_encoding(sc->sc_encodings, fp); 579 return auconv_query_encoding(sc->sc_encodings, fp);
580} 580}
581 581
582Static const usb_interface_descriptor_t * 582Static const usb_interface_descriptor_t *
583uaudio_find_iface(const char *tbuf, int size, int *offsp, int subtype) 583uaudio_find_iface(const char *tbuf, int size, int *offsp, int subtype)
584{ 584{
585 const usb_interface_descriptor_t *d; 585 const usb_interface_descriptor_t *d;
586 586
587 while (*offsp < size) { 587 while (*offsp < size) {
588 d = (const void *)(tbuf + *offsp); 588 d = (const void *)(tbuf + *offsp);
589 *offsp += d->bLength; 589 *offsp += d->bLength;
590 if (d->bDescriptorType == UDESC_INTERFACE && 590 if (d->bDescriptorType == UDESC_INTERFACE &&
591 d->bInterfaceClass == UICLASS_AUDIO && 591 d->bInterfaceClass == UICLASS_AUDIO &&
592 d->bInterfaceSubClass == subtype) 592 d->bInterfaceSubClass == subtype)
593 return d; 593 return d;
594 } 594 }
595 return NULL; 595 return NULL;
596} 596}
597 597
598Static void 598Static void
599uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc) 599uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
600{ 600{
601 int res; 601 int res;
602 size_t len; 602 size_t len;
603 struct mixerctl *nmc; 603 struct mixerctl *nmc;
604 604
605 if (mc->class < UAC_NCLASSES) { 605 if (mc->class < UAC_NCLASSES) {
606 DPRINTF("adding %s.%s\n", uac_names[mc->class], mc->ctlname); 606 DPRINTF("adding %s.%s\n", uac_names[mc->class], mc->ctlname);
607 } else { 607 } else {
608 DPRINTF("adding %s\n", mc->ctlname); 608 DPRINTF("adding %s\n", mc->ctlname);
609 } 609 }
610 len = sizeof(*mc) * (sc->sc_nctls + 1); 610 len = sizeof(*mc) * (sc->sc_nctls + 1);
611 nmc = kmem_alloc(len, KM_SLEEP); 611 nmc = kmem_alloc(len, KM_SLEEP);
612 if (nmc == NULL) { 612 if (nmc == NULL) {
613 aprint_error("uaudio_mixer_add_ctl: no memory\n"); 613 aprint_error("uaudio_mixer_add_ctl: no memory\n");
614 return; 614 return;
615 } 615 }
616 /* Copy old data, if there was any */ 616 /* Copy old data, if there was any */
617 if (sc->sc_nctls != 0) { 617 if (sc->sc_nctls != 0) {
618 memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls)); 618 memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls));
619 kmem_free(sc->sc_ctls, sizeof(*mc) * sc->sc_nctls); 619 kmem_free(sc->sc_ctls, sizeof(*mc) * sc->sc_nctls);
620 } 620 }
621 sc->sc_ctls = nmc; 621 sc->sc_ctls = nmc;
622 622
623 mc->delta = 0; 623 mc->delta = 0;
624 if (mc->type == MIX_ON_OFF) { 624 if (mc->type == MIX_ON_OFF) {
625 mc->minval = 0; 625 mc->minval = 0;
626 mc->maxval = 1; 626 mc->maxval = 1;
627 } else if (mc->type == MIX_SELECTOR) { 627 } else if (mc->type == MIX_SELECTOR) {
628 ; 628 ;
629 } else { 629 } else {
630 /* Determine min and max values. */ 630 /* Determine min and max values. */
631 mc->minval = uaudio_signext(mc->type, 631 mc->minval = uaudio_signext(mc->type,
632 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE, 632 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
633 mc->wValue[0], mc->wIndex, 633 mc->wValue[0], mc->wIndex,
634 MIX_SIZE(mc->type))); 634 MIX_SIZE(mc->type)));
635 mc->maxval = 1 + uaudio_signext(mc->type, 635 mc->maxval = 1 + uaudio_signext(mc->type,
636 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE, 636 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
637 mc->wValue[0], mc->wIndex, 637 mc->wValue[0], mc->wIndex,
638 MIX_SIZE(mc->type))); 638 MIX_SIZE(mc->type)));
639 mc->mul = mc->maxval - mc->minval; 639 mc->mul = mc->maxval - mc->minval;
640 if (mc->mul == 0) 640 if (mc->mul == 0)
641 mc->mul = 1; 641 mc->mul = 1;
642 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE, 642 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
643 mc->wValue[0], mc->wIndex, 643 mc->wValue[0], mc->wIndex,
644 MIX_SIZE(mc->type)); 644 MIX_SIZE(mc->type));
645 if (res > 0) 645 if (res > 0)
646 mc->delta = (res * 255 + mc->mul/2) / mc->mul; 646 mc->delta = (res * 255 + mc->mul/2) / mc->mul;
647 } 647 }
648 648
649 sc->sc_ctls[sc->sc_nctls++] = *mc; 649 sc->sc_ctls[sc->sc_nctls++] = *mc;
650 650
651#ifdef UAUDIO_DEBUG 651#ifdef UAUDIO_DEBUG
652 if (uaudiodebug > 2) { 652 if (uaudiodebug > 2) {
653 int i; 653 int i;
654 654
655 DPRINTFN_CLEAN(2, "wValue=%04x", mc->wValue[0]); 655 DPRINTFN_CLEAN(2, "wValue=%04x", mc->wValue[0]);
656 for (i = 1; i < mc->nchan; i++) 656 for (i = 1; i < mc->nchan; i++)
657 DPRINTFN_CLEAN(2, ",%04x", mc->wValue[i]); 657 DPRINTFN_CLEAN(2, ",%04x", mc->wValue[i]);
658 DPRINTFN_CLEAN(2, " wIndex=%04x type=%d name='%s' unit='%s' " 658 DPRINTFN_CLEAN(2, " wIndex=%04x type=%d name='%s' unit='%s' "
659 "min=%d max=%d\n", 659 "min=%d max=%d\n",
660 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit, 660 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
661 mc->minval, mc->maxval); 661 mc->minval, mc->maxval);
662 } 662 }
663#endif 663#endif
664} 664}
665 665
666Static char * 666Static char *
667uaudio_id_name(struct uaudio_softc *sc, 667uaudio_id_name(struct uaudio_softc *sc,
668 const struct io_terminal *iot, int id) 668 const struct io_terminal *iot, int id)
669{ 669{
670 static char tbuf[32]; 670 static char tbuf[32];
671 671
672 snprintf(tbuf, sizeof(tbuf), "i%d", id); 672 snprintf(tbuf, sizeof(tbuf), "i%d", id);
673 return tbuf; 673 return tbuf;
674} 674}
675 675
676#ifdef UAUDIO_DEBUG 676#ifdef UAUDIO_DEBUG
677Static void 677Static void
678uaudio_dump_cluster(const struct usb_audio_cluster *cl) 678uaudio_dump_cluster(const struct usb_audio_cluster *cl)
679{ 679{
680 static const char *channel_names[16] = { 680 static const char *channel_names[16] = {
681 "LEFT", "RIGHT", "CENTER", "LFE", 681 "LEFT", "RIGHT", "CENTER", "LFE",
682 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER", 682 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER",
683 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP", 683 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP",
684 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15", 684 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15",
685 }; 685 };
686 int cc, i, first; 686 int cc, i, first;
687 687
688 cc = UGETW(cl->wChannelConfig); 688 cc = UGETW(cl->wChannelConfig);
689 printf("cluster: bNrChannels=%u wChannelConfig=0x%.4x", 689 printf("cluster: bNrChannels=%u wChannelConfig=0x%.4x",
690 cl->bNrChannels, cc); 690 cl->bNrChannels, cc);
691 first = TRUE; 691 first = TRUE;
692 for (i = 0; cc != 0; i++) { 692 for (i = 0; cc != 0; i++) {
693 if (cc & 1) { 693 if (cc & 1) {
694 printf("%c%s", first ? '<' : ',', channel_names[i]); 694 printf("%c%s", first ? '<' : ',', channel_names[i]);
695 first = FALSE; 695 first = FALSE;
696 } 696 }
697 cc = cc >> 1; 697 cc = cc >> 1;
698 } 698 }
699 printf("> iChannelNames=%u", cl->iChannelNames); 699 printf("> iChannelNames=%u", cl->iChannelNames);
700} 700}
701#endif 701#endif
702 702
703Static struct usb_audio_cluster 703Static struct usb_audio_cluster
704uaudio_get_cluster(int id, const struct io_terminal *iot) 704uaudio_get_cluster(int id, const struct io_terminal *iot)
705{ 705{
706 struct usb_audio_cluster r; 706 struct usb_audio_cluster r;
707 const uaudio_cs_descriptor_t *dp; 707 const uaudio_cs_descriptor_t *dp;
708 int i; 708 int i;
709 709
710 for (i = 0; i < 25; i++) { /* avoid infinite loops */ 710 for (i = 0; i < 25; i++) { /* avoid infinite loops */
711 dp = iot[id].d.desc; 711 dp = iot[id].d.desc;
712 if (dp == 0) 712 if (dp == 0)
713 goto bad; 713 goto bad;
714 switch (dp->bDescriptorSubtype) { 714 switch (dp->bDescriptorSubtype) {
715 case UDESCSUB_AC_INPUT: 715 case UDESCSUB_AC_INPUT:
716 r.bNrChannels = iot[id].d.it->bNrChannels; 716 r.bNrChannels = iot[id].d.it->bNrChannels;
717 USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig)); 717 USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig));
718 r.iChannelNames = iot[id].d.it->iChannelNames; 718 r.iChannelNames = iot[id].d.it->iChannelNames;
719 return r; 719 return r;
720 case UDESCSUB_AC_OUTPUT: 720 case UDESCSUB_AC_OUTPUT:
721 id = iot[id].d.ot->bSourceId; 721 id = iot[id].d.ot->bSourceId;
722 break; 722 break;
723 case UDESCSUB_AC_MIXER: 723 case UDESCSUB_AC_MIXER:
724 r = *(const struct usb_audio_cluster *) 724 r = *(const struct usb_audio_cluster *)
725 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins]; 725 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
726 return r; 726 return r;
727 case UDESCSUB_AC_SELECTOR: 727 case UDESCSUB_AC_SELECTOR:
728 /* XXX This is not really right */ 728 /* XXX This is not really right */
729 id = iot[id].d.su->baSourceId[0]; 729 id = iot[id].d.su->baSourceId[0];
730 break; 730 break;
731 case UDESCSUB_AC_FEATURE: 731 case UDESCSUB_AC_FEATURE:
732 id = iot[id].d.fu->bSourceId; 732 id = iot[id].d.fu->bSourceId;
733 break; 733 break;
734 case UDESCSUB_AC_PROCESSING: 734 case UDESCSUB_AC_PROCESSING:
735 r = *(const struct usb_audio_cluster *) 735 r = *(const struct usb_audio_cluster *)
736 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins]; 736 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
737 return r; 737 return r;
738 case UDESCSUB_AC_EXTENSION: 738 case UDESCSUB_AC_EXTENSION:
739 r = *(const struct usb_audio_cluster *) 739 r = *(const struct usb_audio_cluster *)
740 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins]; 740 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
741 return r; 741 return r;
742 default: 742 default:
743 goto bad; 743 goto bad;
744 } 744 }
745 } 745 }
746 bad: 746 bad:
747 aprint_error("uaudio_get_cluster: bad data\n"); 747 aprint_error("uaudio_get_cluster: bad data\n");
748 memset(&r, 0, sizeof(r)); 748 memset(&r, 0, sizeof(r));
749 return r; 749 return r;
750 750
751} 751}
752 752
753Static void 753Static void
754uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 754uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
755{ 755{
756 const struct usb_audio_input_terminal *d; 756 const struct usb_audio_input_terminal *d;
757 757
758 d = iot[id].d.it; 758 d = iot[id].d.it;
759#ifdef UAUDIO_DEBUG 759#ifdef UAUDIO_DEBUG
760 DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x " 760 DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x "
761 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d " 761 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
762 "iChannelNames=%d iTerminal=%d\n", 762 "iChannelNames=%d iTerminal=%d\n",
763 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 763 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
764 d->bNrChannels, UGETW(d->wChannelConfig), 764 d->bNrChannels, UGETW(d->wChannelConfig),
765 d->iChannelNames, d->iTerminal); 765 d->iChannelNames, d->iTerminal);
766#endif 766#endif
767 /* If USB input terminal, record wChannelConfig */ 767 /* If USB input terminal, record wChannelConfig */
768 if ((UGETW(d->wTerminalType) & 0xff00) != 0x0100) 768 if ((UGETW(d->wTerminalType) & 0xff00) != 0x0100)
769 return; 769 return;
770 sc->sc_channel_config = UGETW(d->wChannelConfig); 770 sc->sc_channel_config = UGETW(d->wChannelConfig);
771} 771}
772 772
773Static void 773Static void
774uaudio_add_output(struct uaudio_softc *sc, 774uaudio_add_output(struct uaudio_softc *sc,
775 const struct io_terminal *iot, int id) 775 const struct io_terminal *iot, int id)
776{ 776{
777#ifdef UAUDIO_DEBUG 777#ifdef UAUDIO_DEBUG
778 const struct usb_audio_output_terminal *d; 778 const struct usb_audio_output_terminal *d;
779 779
780 d = iot[id].d.ot; 780 d = iot[id].d.ot;
781 DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x " 781 DPRINTFN(2,"bTerminalId=%d wTerminalType=0x%04x "
782 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n", 782 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
783 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 783 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
784 d->bSourceId, d->iTerminal); 784 d->bSourceId, d->iTerminal);
785#endif 785#endif
786} 786}
787 787
788Static void 788Static void
789uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 789uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
790{ 790{
791 const struct usb_audio_mixer_unit *d; 791 const struct usb_audio_mixer_unit *d;
792 const struct usb_audio_mixer_unit_1 *d1; 792 const struct usb_audio_mixer_unit_1 *d1;
793 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k; 793 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
794 const uByte *bm; 794 const uByte *bm;
795 struct mixerctl mix; 795 struct mixerctl mix;
796 796
797 d = iot[id].d.mu; 797 d = iot[id].d.mu;
798 DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n", 798 DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n",
799 d->bUnitId, d->bNrInPins); 799 d->bUnitId, d->bNrInPins);
800 800
801 /* Compute the number of input channels */ 801 /* Compute the number of input channels */
802 ichs = 0; 802 ichs = 0;
803 for (i = 0; i < d->bNrInPins; i++) 803 for (i = 0; i < d->bNrInPins; i++)
804 ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels; 804 ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
805 805
806 /* and the number of output channels */ 806 /* and the number of output channels */
807 d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins]; 807 d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
808 ochs = d1->bNrChannels; 808 ochs = d1->bNrChannels;
809 DPRINTFN(2,"ichs=%d ochs=%d\n", ichs, ochs); 809 DPRINTFN(2,"ichs=%d ochs=%d\n", ichs, ochs);
810 810
811 bm = d1->bmControls; 811 bm = d1->bmControls;
812 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 812 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
813 uaudio_determine_class(&iot[id], &mix); 813 uaudio_determine_class(&iot[id], &mix);
814 mix.type = MIX_SIGNED_16; 814 mix.type = MIX_SIGNED_16;
815 mix.ctlunit = AudioNvolume; 815 mix.ctlunit = AudioNvolume;
816#define _BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1) 816#define _BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
817 for (p = i = 0; i < d->bNrInPins; i++) { 817 for (p = i = 0; i < d->bNrInPins; i++) {
818 chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels; 818 chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
819 mc = 0; 819 mc = 0;
820 for (c = 0; c < chs; c++) { 820 for (c = 0; c < chs; c++) {
821 mo = 0; 821 mo = 0;
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 mo++; 825 mo++;
826 } 826 }
827 if (mo == 1) 827 if (mo == 1)
828 mc++; 828 mc++;
829 } 829 }
830 if (mc == chs && chs <= MIX_MAX_CHAN) { 830 if (mc == chs && chs <= MIX_MAX_CHAN) {
831 k = 0; 831 k = 0;
832 for (c = 0; c < chs; c++) 832 for (c = 0; c < chs; c++)
833 for (o = 0; o < ochs; o++) { 833 for (o = 0; o < ochs; o++) {
834 bno = (p + c) * ochs + o; 834 bno = (p + c) * ochs + o;
835 if (_BIT(bno)) 835 if (_BIT(bno))
836 mix.wValue[k++] = 836 mix.wValue[k++] =
837 MAKE(p+c+1, o+1); 837 MAKE(p+c+1, o+1);
838 } 838 }
839 snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s", 839 snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s",
840 d->bUnitId, uaudio_id_name(sc, iot, 840 d->bUnitId, uaudio_id_name(sc, iot,
841 d->baSourceId[i])); 841 d->baSourceId[i]));
842 mix.nchan = chs; 842 mix.nchan = chs;
843 uaudio_mixer_add_ctl(sc, &mix); 843 uaudio_mixer_add_ctl(sc, &mix);
844 } else { 844 } else {
845 /* XXX */ 845 /* XXX */
846 } 846 }
847#undef _BIT 847#undef _BIT
848 p += chs; 848 p += chs;
849 } 849 }
850 850
851} 851}
852 852
853Static void 853Static void
854uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 854uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
855{ 855{
856 const struct usb_audio_selector_unit *d; 856 const struct usb_audio_selector_unit *d;
857 struct mixerctl mix; 857 struct mixerctl mix;
858 int i, wp; 858 int i, wp;
859 859
860 d = iot[id].d.su; 860 d = iot[id].d.su;
861 DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n", 861 DPRINTFN(2,"bUnitId=%d bNrInPins=%d\n",
862 d->bUnitId, d->bNrInPins); 862 d->bUnitId, d->bNrInPins);
863 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 863 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
864 mix.wValue[0] = MAKE(0, 0); 864 mix.wValue[0] = MAKE(0, 0);
865 uaudio_determine_class(&iot[id], &mix); 865 uaudio_determine_class(&iot[id], &mix);
866 mix.nchan = 1; 866 mix.nchan = 1;
867 mix.type = MIX_SELECTOR; 867 mix.type = MIX_SELECTOR;
868 mix.ctlunit = ""; 868 mix.ctlunit = "";
869 mix.minval = 1; 869 mix.minval = 1;
870 mix.maxval = d->bNrInPins; 870 mix.maxval = d->bNrInPins;
871 mix.mul = mix.maxval - mix.minval; 871 mix.mul = mix.maxval - mix.minval;
872 wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId); 872 wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId);
873 for (i = 1; i <= d->bNrInPins; i++) { 873 for (i = 1; i <= d->bNrInPins; i++) {
874 wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp, 874 wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp,
875 "i%d", d->baSourceId[i - 1]); 875 "i%d", d->baSourceId[i - 1]);
876 if (wp > MAX_AUDIO_DEV_LEN - 1) 876 if (wp > MAX_AUDIO_DEV_LEN - 1)
877 break; 877 break;
878 } 878 }
879 uaudio_mixer_add_ctl(sc, &mix); 879 uaudio_mixer_add_ctl(sc, &mix);
880} 880}
881 881
882#ifdef UAUDIO_DEBUG 882#ifdef UAUDIO_DEBUG
883Static const char * 883Static const char *
884uaudio_get_terminal_name(int terminal_type) 884uaudio_get_terminal_name(int terminal_type)
885{ 885{
886 static char tbuf[100]; 886 static char tbuf[100];
887 887
888 switch (terminal_type) { 888 switch (terminal_type) {
889 /* USB terminal types */ 889 /* USB terminal types */
890 case UAT_UNDEFINED: return "UAT_UNDEFINED"; 890 case UAT_UNDEFINED: return "UAT_UNDEFINED";
891 case UAT_STREAM: return "UAT_STREAM"; 891 case UAT_STREAM: return "UAT_STREAM";
892 case UAT_VENDOR: return "UAT_VENDOR"; 892 case UAT_VENDOR: return "UAT_VENDOR";
893 /* input terminal types */ 893 /* input terminal types */
894 case UATI_UNDEFINED: return "UATI_UNDEFINED"; 894 case UATI_UNDEFINED: return "UATI_UNDEFINED";
895 case UATI_MICROPHONE: return "UATI_MICROPHONE"; 895 case UATI_MICROPHONE: return "UATI_MICROPHONE";
896 case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE"; 896 case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE";
897 case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE"; 897 case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE";
898 case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE"; 898 case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE";
899 case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY"; 899 case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY";
900 case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR"; 900 case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR";
901 /* output terminal types */ 901 /* output terminal types */
902 case UATO_UNDEFINED: return "UATO_UNDEFINED"; 902 case UATO_UNDEFINED: return "UATO_UNDEFINED";
903 case UATO_SPEAKER: return "UATO_SPEAKER"; 903 case UATO_SPEAKER: return "UATO_SPEAKER";
904 case UATO_HEADPHONES: return "UATO_HEADPHONES"; 904 case UATO_HEADPHONES: return "UATO_HEADPHONES";
905 case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO"; 905 case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO";
906 case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER"; 906 case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER";
907 case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER"; 907 case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER";
908 case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER"; 908 case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER";
909 case UATO_SUBWOOFER: return "UATO_SUBWOOFER"; 909 case UATO_SUBWOOFER: return "UATO_SUBWOOFER";
910 /* bidir terminal types */ 910 /* bidir terminal types */
911 case UATB_UNDEFINED: return "UATB_UNDEFINED"; 911 case UATB_UNDEFINED: return "UATB_UNDEFINED";
912 case UATB_HANDSET: return "UATB_HANDSET"; 912 case UATB_HANDSET: return "UATB_HANDSET";
913 case UATB_HEADSET: return "UATB_HEADSET"; 913 case UATB_HEADSET: return "UATB_HEADSET";
914 case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE"; 914 case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE";
915 case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP"; 915 case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP";
916 case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC"; 916 case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC";
917 /* telephony terminal types */ 917 /* telephony terminal types */
918 case UATT_UNDEFINED: return "UATT_UNDEFINED"; 918 case UATT_UNDEFINED: return "UATT_UNDEFINED";
919 case UATT_PHONELINE: return "UATT_PHONELINE"; 919 case UATT_PHONELINE: return "UATT_PHONELINE";
920 case UATT_TELEPHONE: return "UATT_TELEPHONE"; 920 case UATT_TELEPHONE: return "UATT_TELEPHONE";
921 case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE"; 921 case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE";
922 /* external terminal types */ 922 /* external terminal types */
923 case UATE_UNDEFINED: return "UATE_UNDEFINED"; 923 case UATE_UNDEFINED: return "UATE_UNDEFINED";
924 case UATE_ANALOGCONN: return "UATE_ANALOGCONN"; 924 case UATE_ANALOGCONN: return "UATE_ANALOGCONN";
925 case UATE_LINECONN: return "UATE_LINECONN"; 925 case UATE_LINECONN: return "UATE_LINECONN";
926 case UATE_LEGACYCONN: return "UATE_LEGACYCONN"; 926 case UATE_LEGACYCONN: return "UATE_LEGACYCONN";
927 case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC"; 927 case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC";
928 case UATE_SPDIF: return "UATE_SPDIF"; 928 case UATE_SPDIF: return "UATE_SPDIF";
929 case UATE_1394DA: return "UATE_1394DA"; 929 case UATE_1394DA: return "UATE_1394DA";
930 case UATE_1394DV: return "UATE_1394DV"; 930 case UATE_1394DV: return "UATE_1394DV";
931 /* embedded function terminal types */ 931 /* embedded function terminal types */
932 case UATF_UNDEFINED: return "UATF_UNDEFINED"; 932 case UATF_UNDEFINED: return "UATF_UNDEFINED";
933 case UATF_CALIBNOISE: return "UATF_CALIBNOISE"; 933 case UATF_CALIBNOISE: return "UATF_CALIBNOISE";
934 case UATF_EQUNOISE: return "UATF_EQUNOISE"; 934 case UATF_EQUNOISE: return "UATF_EQUNOISE";
935 case UATF_CDPLAYER: return "UATF_CDPLAYER"; 935 case UATF_CDPLAYER: return "UATF_CDPLAYER";
936 case UATF_DAT: return "UATF_DAT"; 936 case UATF_DAT: return "UATF_DAT";
937 case UATF_DCC: return "UATF_DCC"; 937 case UATF_DCC: return "UATF_DCC";
938 case UATF_MINIDISK: return "UATF_MINIDISK"; 938 case UATF_MINIDISK: return "UATF_MINIDISK";
939 case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE"; 939 case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE";
940 case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH"; 940 case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH";
941 case UATF_VCRAUDIO: return "UATF_VCRAUDIO"; 941 case UATF_VCRAUDIO: return "UATF_VCRAUDIO";
942 case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO"; 942 case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO";
943 case UATF_DVDAUDIO: return "UATF_DVDAUDIO"; 943 case UATF_DVDAUDIO: return "UATF_DVDAUDIO";
944 case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO"; 944 case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO";
945 case UATF_SATELLITE: return "UATF_SATELLITE"; 945 case UATF_SATELLITE: return "UATF_SATELLITE";
946 case UATF_CABLETUNER: return "UATF_CABLETUNER"; 946 case UATF_CABLETUNER: return "UATF_CABLETUNER";
947 case UATF_DSS: return "UATF_DSS"; 947 case UATF_DSS: return "UATF_DSS";
948 case UATF_RADIORECV: return "UATF_RADIORECV"; 948 case UATF_RADIORECV: return "UATF_RADIORECV";
949 case UATF_RADIOXMIT: return "UATF_RADIOXMIT"; 949 case UATF_RADIOXMIT: return "UATF_RADIOXMIT";
950 case UATF_MULTITRACK: return "UATF_MULTITRACK"; 950 case UATF_MULTITRACK: return "UATF_MULTITRACK";
951 case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER"; 951 case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER";
952 default: 952 default:
953 snprintf(tbuf, sizeof(tbuf), "unknown type (0x%.4x)", terminal_type); 953 snprintf(tbuf, sizeof(tbuf), "unknown type (0x%.4x)", terminal_type);
954 return tbuf; 954 return tbuf;
955 } 955 }
956} 956}
957#endif 957#endif
958 958
959Static int 959Static int
960uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix) 960uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
961{ 961{
962 int terminal_type; 962 int terminal_type;
963 963
964 if (iot == NULL || iot->output == NULL) { 964 if (iot == NULL || iot->output == NULL) {
965 mix->class = UAC_OUTPUT; 965 mix->class = UAC_OUTPUT;
966 return 0; 966 return 0;
967 } 967 }
968 terminal_type = 0; 968 terminal_type = 0;
969 if (iot->output->size == 1) 969 if (iot->output->size == 1)
970 terminal_type = iot->output->terminals[0]; 970 terminal_type = iot->output->terminals[0];
971 /* 971 /*
972 * If the only output terminal is USB, 972 * If the only output terminal is USB,
973 * the class is UAC_RECORD. 973 * the class is UAC_RECORD.
974 */ 974 */
975 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) { 975 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
976 mix->class = UAC_RECORD; 976 mix->class = UAC_RECORD;
977 if (iot->inputs_size == 1 977 if (iot->inputs_size == 1
978 && iot->inputs[0] != NULL 978 && iot->inputs[0] != NULL
979 && iot->inputs[0]->size == 1) 979 && iot->inputs[0]->size == 1)
980 return iot->inputs[0]->terminals[0]; 980 return iot->inputs[0]->terminals[0];
981 else 981 else
982 return 0; 982 return 0;
983 } 983 }
984 /* 984 /*
985 * If the ultimate destination of the unit is just one output 985 * If the ultimate destination of the unit is just one output
986 * terminal and the unit is connected to the output terminal 986 * terminal and the unit is connected to the output terminal
987 * directly, the class is UAC_OUTPUT. 987 * directly, the class is UAC_OUTPUT.
988 */ 988 */
989 if (terminal_type != 0 && iot->direct) { 989 if (terminal_type != 0 && iot->direct) {
990 mix->class = UAC_OUTPUT; 990 mix->class = UAC_OUTPUT;
991 return terminal_type; 991 return terminal_type;
992 } 992 }
993 /* 993 /*
994 * If the unit is connected to just one input terminal, 994 * If the unit is connected to just one input terminal,
995 * the class is UAC_INPUT. 995 * the class is UAC_INPUT.
996 */ 996 */
997 if (iot->inputs_size == 1 && iot->inputs[0] != NULL 997 if (iot->inputs_size == 1 && iot->inputs[0] != NULL
998 && iot->inputs[0]->size == 1) { 998 && iot->inputs[0]->size == 1) {
999 mix->class = UAC_INPUT; 999 mix->class = UAC_INPUT;
1000 return iot->inputs[0]->terminals[0]; 1000 return iot->inputs[0]->terminals[0];
1001 } 1001 }
1002 /* 1002 /*
1003 * Otherwise, the class is UAC_OUTPUT. 1003 * Otherwise, the class is UAC_OUTPUT.
1004 */ 1004 */
1005 mix->class = UAC_OUTPUT; 1005 mix->class = UAC_OUTPUT;
1006 return terminal_type; 1006 return terminal_type;
1007} 1007}
1008 1008
1009Static const char * 1009Static const char *
1010uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix) 1010uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
1011{ 1011{
1012 int terminal_type; 1012 int terminal_type;
1013 1013
1014 terminal_type = uaudio_determine_class(iot, mix); 1014 terminal_type = uaudio_determine_class(iot, mix);
1015 if (mix->class == UAC_RECORD && terminal_type == 0) 1015 if (mix->class == UAC_RECORD && terminal_type == 0)
1016 return AudioNmixerout; 1016 return AudioNmixerout;
1017 DPRINTF("terminal_type=%s\n", uaudio_get_terminal_name(terminal_type)); 1017 DPRINTF("terminal_type=%s\n", uaudio_get_terminal_name(terminal_type));
1018 switch (terminal_type) { 1018 switch (terminal_type) {
1019 case UAT_STREAM: 1019 case UAT_STREAM:
1020 return AudioNdac; 1020 return AudioNdac;
1021 1021
1022 case UATI_MICROPHONE: 1022 case UATI_MICROPHONE:
1023 case UATI_DESKMICROPHONE: 1023 case UATI_DESKMICROPHONE:
1024 case UATI_PERSONALMICROPHONE: 1024 case UATI_PERSONALMICROPHONE:
1025 case UATI_OMNIMICROPHONE: 1025 case UATI_OMNIMICROPHONE:
1026 case UATI_MICROPHONEARRAY: 1026 case UATI_MICROPHONEARRAY:
1027 case UATI_PROCMICROPHONEARR: 1027 case UATI_PROCMICROPHONEARR:
1028 return AudioNmicrophone; 1028 return AudioNmicrophone;
1029 1029
1030 case UATO_SPEAKER: 1030 case UATO_SPEAKER:
1031 case UATO_DESKTOPSPEAKER: 1031 case UATO_DESKTOPSPEAKER:
1032 case UATO_ROOMSPEAKER: 1032 case UATO_ROOMSPEAKER:
1033 case UATO_COMMSPEAKER: 1033 case UATO_COMMSPEAKER:
1034 return AudioNspeaker; 1034 return AudioNspeaker;
1035 1035
1036 case UATO_HEADPHONES: 1036 case UATO_HEADPHONES:
1037 return AudioNheadphone; 1037 return AudioNheadphone;
1038 1038
1039 case UATO_SUBWOOFER: 1039 case UATO_SUBWOOFER:
@@ -1628,1593 +1628,1593 @@ uaudio_process_as(struct uaudio_softc *s @@ -1628,1593 +1628,1593 @@ uaudio_process_as(struct uaudio_softc *s
1628#ifndef UAUDIO_MULTIPLE_ENDPOINTS 1628#ifndef UAUDIO_MULTIPLE_ENDPOINTS
1629 aprint_error_dev(sc->sc_dev, 1629 aprint_error_dev(sc->sc_dev,
1630 "ignored input endpoint of type adaptive\n"); 1630 "ignored input endpoint of type adaptive\n");
1631 return USBD_NORMAL_COMPLETION; 1631 return USBD_NORMAL_COMPLETION;
1632#endif 1632#endif
1633 } 1633 }
1634 if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) { 1634 if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
1635 sync = TRUE; 1635 sync = TRUE;
1636#ifndef UAUDIO_MULTIPLE_ENDPOINTS 1636#ifndef UAUDIO_MULTIPLE_ENDPOINTS
1637 aprint_error_dev(sc->sc_dev, 1637 aprint_error_dev(sc->sc_dev,
1638 "ignored output endpoint of type async\n"); 1638 "ignored output endpoint of type async\n");
1639 return USBD_NORMAL_COMPLETION; 1639 return USBD_NORMAL_COMPLETION;
1640#endif 1640#endif
1641 } 1641 }
1642 1642
1643 sed = (const void *)(tbuf + offs); 1643 sed = (const void *)(tbuf + offs);
1644 if (sed->bDescriptorType != UDESC_CS_ENDPOINT || 1644 if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
1645 sed->bDescriptorSubtype != AS_GENERAL) 1645 sed->bDescriptorSubtype != AS_GENERAL)
1646 return USBD_INVAL; 1646 return USBD_INVAL;
1647 DPRINTF(" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength); 1647 DPRINTF(" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength);
1648 offs += sed->bLength; 1648 offs += sed->bLength;
1649 if (offs > size) 1649 if (offs > size)
1650 return USBD_INVAL; 1650 return USBD_INVAL;
1651 1651
1652#ifdef UAUDIO_MULTIPLE_ENDPOINTS 1652#ifdef UAUDIO_MULTIPLE_ENDPOINTS
1653 if (sync && id->bNumEndpoints <= 1) { 1653 if (sync && id->bNumEndpoints <= 1) {
1654 aprint_error_dev(sc->sc_dev, 1654 aprint_error_dev(sc->sc_dev,
1655 "a sync-pipe endpoint but no other endpoint\n"); 1655 "a sync-pipe endpoint but no other endpoint\n");
1656 return USBD_INVAL; 1656 return USBD_INVAL;
1657 } 1657 }
1658#endif 1658#endif
1659 if (!sync && id->bNumEndpoints > 1) { 1659 if (!sync && id->bNumEndpoints > 1) {
1660 aprint_error_dev(sc->sc_dev, 1660 aprint_error_dev(sc->sc_dev,
1661 "non sync-pipe endpoint but multiple endpoints\n"); 1661 "non sync-pipe endpoint but multiple endpoints\n");
1662 return USBD_INVAL; 1662 return USBD_INVAL;
1663 } 1663 }
1664 epdesc1 = NULL; 1664 epdesc1 = NULL;
1665 if (id->bNumEndpoints > 1) { 1665 if (id->bNumEndpoints > 1) {
1666 epdesc1 = (const void*)(tbuf + offs); 1666 epdesc1 = (const void*)(tbuf + offs);
1667 if (epdesc1->bDescriptorType != UDESC_ENDPOINT) 1667 if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
1668 return USBD_INVAL; 1668 return USBD_INVAL;
1669 DPRINTF("endpoint[1] bLength=%d " 1669 DPRINTF("endpoint[1] bLength=%d "
1670 "bDescriptorType=%d bEndpointAddress=%d " 1670 "bDescriptorType=%d bEndpointAddress=%d "
1671 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d " 1671 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
1672 "bRefresh=%d bSynchAddress=%d\n", 1672 "bRefresh=%d bSynchAddress=%d\n",
1673 epdesc1->bLength, epdesc1->bDescriptorType, 1673 epdesc1->bLength, epdesc1->bDescriptorType,
1674 epdesc1->bEndpointAddress, epdesc1->bmAttributes, 1674 epdesc1->bEndpointAddress, epdesc1->bmAttributes,
1675 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval, 1675 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
1676 epdesc1->bRefresh, epdesc1->bSynchAddress); 1676 epdesc1->bRefresh, epdesc1->bSynchAddress);
1677 offs += epdesc1->bLength; 1677 offs += epdesc1->bLength;
1678 if (offs > size) 1678 if (offs > size)
1679 return USBD_INVAL; 1679 return USBD_INVAL;
1680 if (epdesc1->bSynchAddress != 0) { 1680 if (epdesc1->bSynchAddress != 0) {
1681 aprint_error_dev(sc->sc_dev, 1681 aprint_error_dev(sc->sc_dev,
1682 "invalid endpoint: bSynchAddress=0\n"); 1682 "invalid endpoint: bSynchAddress=0\n");
1683 return USBD_INVAL; 1683 return USBD_INVAL;
1684 } 1684 }
1685 if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) { 1685 if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
1686 aprint_error_dev(sc->sc_dev, 1686 aprint_error_dev(sc->sc_dev,
1687 "invalid endpoint: bmAttributes=0x%x\n", 1687 "invalid endpoint: bmAttributes=0x%x\n",
1688 epdesc1->bmAttributes); 1688 epdesc1->bmAttributes);
1689 return USBD_INVAL; 1689 return USBD_INVAL;
1690 } 1690 }
1691 if (epdesc1->bEndpointAddress != ed->bSynchAddress) { 1691 if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
1692 aprint_error_dev(sc->sc_dev, 1692 aprint_error_dev(sc->sc_dev,
1693 "invalid endpoint addresses: " 1693 "invalid endpoint addresses: "
1694 "ep[0]->bSynchAddress=0x%x " 1694 "ep[0]->bSynchAddress=0x%x "
1695 "ep[1]->bEndpointAddress=0x%x\n", 1695 "ep[1]->bEndpointAddress=0x%x\n",
1696 ed->bSynchAddress, epdesc1->bEndpointAddress); 1696 ed->bSynchAddress, epdesc1->bEndpointAddress);
1697 return USBD_INVAL; 1697 return USBD_INVAL;
1698 } 1698 }
1699 /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */ 1699 /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
1700 } 1700 }
1701 1701
1702 format = UGETW(asid->wFormatTag); 1702 format = UGETW(asid->wFormatTag);
1703 chan = asf1d->bNrChannels; 1703 chan = asf1d->bNrChannels;
1704 prec = asf1d->bBitResolution; 1704 prec = asf1d->bBitResolution;
1705 if (prec != 8 && prec != 16 && prec != 24) { 1705 if (prec != 8 && prec != 16 && prec != 24) {
1706 aprint_error_dev(sc->sc_dev, 1706 aprint_error_dev(sc->sc_dev,
1707 "ignored setting with precision %d\n", prec); 1707 "ignored setting with precision %d\n", prec);
1708 return USBD_NORMAL_COMPLETION; 1708 return USBD_NORMAL_COMPLETION;
1709 } 1709 }
1710 switch (format) { 1710 switch (format) {
1711 case UA_FMT_PCM: 1711 case UA_FMT_PCM:
1712 if (prec == 8) { 1712 if (prec == 8) {
1713 sc->sc_altflags |= HAS_8; 1713 sc->sc_altflags |= HAS_8;
1714 } else if (prec == 16) { 1714 } else if (prec == 16) {
1715 sc->sc_altflags |= HAS_16; 1715 sc->sc_altflags |= HAS_16;
1716 } else if (prec == 24) { 1716 } else if (prec == 24) {
1717 sc->sc_altflags |= HAS_24; 1717 sc->sc_altflags |= HAS_24;
1718 } 1718 }
1719 enc = AUDIO_ENCODING_SLINEAR_LE; 1719 enc = AUDIO_ENCODING_SLINEAR_LE;
1720 format_str = "pcm"; 1720 format_str = "pcm";
1721 break; 1721 break;
1722 case UA_FMT_PCM8: 1722 case UA_FMT_PCM8:
1723 enc = AUDIO_ENCODING_ULINEAR_LE; 1723 enc = AUDIO_ENCODING_ULINEAR_LE;
1724 sc->sc_altflags |= HAS_8U; 1724 sc->sc_altflags |= HAS_8U;
1725 format_str = "pcm8"; 1725 format_str = "pcm8";
1726 break; 1726 break;
1727 case UA_FMT_ALAW: 1727 case UA_FMT_ALAW:
1728 enc = AUDIO_ENCODING_ALAW; 1728 enc = AUDIO_ENCODING_ALAW;
1729 sc->sc_altflags |= HAS_ALAW; 1729 sc->sc_altflags |= HAS_ALAW;
1730 format_str = "alaw"; 1730 format_str = "alaw";
1731 break; 1731 break;
1732 case UA_FMT_MULAW: 1732 case UA_FMT_MULAW:
1733 enc = AUDIO_ENCODING_ULAW; 1733 enc = AUDIO_ENCODING_ULAW;
1734 sc->sc_altflags |= HAS_MULAW; 1734 sc->sc_altflags |= HAS_MULAW;
1735 format_str = "mulaw"; 1735 format_str = "mulaw";
1736 break; 1736 break;
1737 case UA_FMT_IEEE_FLOAT: 1737 case UA_FMT_IEEE_FLOAT:
1738 default: 1738 default:
1739 aprint_error_dev(sc->sc_dev, 1739 aprint_error_dev(sc->sc_dev,
1740 "ignored setting with format %d\n", format); 1740 "ignored setting with format %d\n", format);
1741 return USBD_NORMAL_COMPLETION; 1741 return USBD_NORMAL_COMPLETION;
1742 } 1742 }
1743#ifdef UAUDIO_DEBUG 1743#ifdef UAUDIO_DEBUG
1744 aprint_debug_dev(sc->sc_dev, "%s: %dch, %d/%dbit, %s,", 1744 aprint_debug_dev(sc->sc_dev, "%s: %dch, %d/%dbit, %s,",
1745 dir == UE_DIR_IN ? "recording" : "playback", 1745 dir == UE_DIR_IN ? "recording" : "playback",
1746 chan, prec, asf1d->bSubFrameSize * 8, format_str); 1746 chan, prec, asf1d->bSubFrameSize * 8, format_str);
1747 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 1747 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
1748 aprint_debug(" %d-%dHz\n", UA_SAMP_LO(asf1d), 1748 aprint_debug(" %d-%dHz\n", UA_SAMP_LO(asf1d),
1749 UA_SAMP_HI(asf1d)); 1749 UA_SAMP_HI(asf1d));
1750 } else { 1750 } else {
1751 int r; 1751 int r;
1752 aprint_debug(" %d", UA_GETSAMP(asf1d, 0)); 1752 aprint_debug(" %d", UA_GETSAMP(asf1d, 0));
1753 for (r = 1; r < asf1d->bSamFreqType; r++) 1753 for (r = 1; r < asf1d->bSamFreqType; r++)
1754 aprint_debug(",%d", UA_GETSAMP(asf1d, r)); 1754 aprint_debug(",%d", UA_GETSAMP(asf1d, r));
1755 aprint_debug("Hz\n"); 1755 aprint_debug("Hz\n");
1756 } 1756 }
1757#endif 1757#endif
1758 ai.alt = id->bAlternateSetting; 1758 ai.alt = id->bAlternateSetting;
1759 ai.encoding = enc; 1759 ai.encoding = enc;
1760 ai.attributes = sed->bmAttributes; 1760 ai.attributes = sed->bmAttributes;
1761 ai.idesc = id; 1761 ai.idesc = id;
1762 ai.edesc = ed; 1762 ai.edesc = ed;
1763 ai.edesc1 = epdesc1; 1763 ai.edesc1 = epdesc1;
1764 ai.asf1desc = asf1d; 1764 ai.asf1desc = asf1d;
1765 ai.sc_busy = 0; 1765 ai.sc_busy = 0;
1766 ai.aformat = NULL; 1766 ai.aformat = NULL;
1767 ai.ifaceh = NULL; 1767 ai.ifaceh = NULL;
1768 uaudio_add_alt(sc, &ai); 1768 uaudio_add_alt(sc, &ai);
1769#ifdef UAUDIO_DEBUG 1769#ifdef UAUDIO_DEBUG
1770 if (ai.attributes & UA_SED_FREQ_CONTROL) 1770 if (ai.attributes & UA_SED_FREQ_CONTROL)
1771 DPRINTFN(1, "%s", "FREQ_CONTROL\n"); 1771 DPRINTFN(1, "%s", "FREQ_CONTROL\n");
1772 if (ai.attributes & UA_SED_PITCH_CONTROL) 1772 if (ai.attributes & UA_SED_PITCH_CONTROL)
1773 DPRINTFN(1, "%s", "PITCH_CONTROL\n"); 1773 DPRINTFN(1, "%s", "PITCH_CONTROL\n");
1774#endif 1774#endif
1775 sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD; 1775 sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD;
1776 1776
1777 return USBD_NORMAL_COMPLETION; 1777 return USBD_NORMAL_COMPLETION;
1778} 1778}
1779#undef offs 1779#undef offs
1780 1780
1781Static usbd_status 1781Static usbd_status
1782uaudio_identify_as(struct uaudio_softc *sc, 1782uaudio_identify_as(struct uaudio_softc *sc,
1783 const usb_config_descriptor_t *cdesc) 1783 const usb_config_descriptor_t *cdesc)
1784{ 1784{
1785 const usb_interface_descriptor_t *id; 1785 const usb_interface_descriptor_t *id;
1786 const char *tbuf; 1786 const char *tbuf;
1787 struct audio_format *auf; 1787 struct audio_format *auf;
1788 const struct usb_audio_streaming_type1_descriptor *t1desc; 1788 const struct usb_audio_streaming_type1_descriptor *t1desc;
1789 int size, offs; 1789 int size, offs;
1790 int i, j; 1790 int i, j;
1791 1791
1792 size = UGETW(cdesc->wTotalLength); 1792 size = UGETW(cdesc->wTotalLength);
1793 tbuf = (const char *)cdesc; 1793 tbuf = (const char *)cdesc;
1794 1794
1795 /* Locate the AudioStreaming interface descriptor. */ 1795 /* Locate the AudioStreaming interface descriptor. */
1796 offs = 0; 1796 offs = 0;
1797 id = uaudio_find_iface(tbuf, size, &offs, UISUBCLASS_AUDIOSTREAM); 1797 id = uaudio_find_iface(tbuf, size, &offs, UISUBCLASS_AUDIOSTREAM);
1798 if (id == NULL) 1798 if (id == NULL)
1799 return USBD_INVAL; 1799 return USBD_INVAL;
1800 1800
1801 /* Loop through all the alternate settings. */ 1801 /* Loop through all the alternate settings. */
1802 while (offs <= size) { 1802 while (offs <= size) {
1803 DPRINTFN(2, "interface=%d offset=%d\n", 1803 DPRINTFN(2, "interface=%d offset=%d\n",
1804 id->bInterfaceNumber, offs); 1804 id->bInterfaceNumber, offs);
1805 switch (id->bNumEndpoints) { 1805 switch (id->bNumEndpoints) {
1806 case 0: 1806 case 0:
1807 DPRINTFN(2, "AS null alt=%d\n", 1807 DPRINTFN(2, "AS null alt=%d\n",
1808 id->bAlternateSetting); 1808 id->bAlternateSetting);
1809 sc->sc_nullalt = id->bAlternateSetting; 1809 sc->sc_nullalt = id->bAlternateSetting;
1810 break; 1810 break;
1811 case 1: 1811 case 1:
1812#ifdef UAUDIO_MULTIPLE_ENDPOINTS 1812#ifdef UAUDIO_MULTIPLE_ENDPOINTS
1813 case 2: 1813 case 2:
1814#endif 1814#endif
1815 uaudio_process_as(sc, tbuf, &offs, size, id); 1815 uaudio_process_as(sc, tbuf, &offs, size, id);
1816 break; 1816 break;
1817 default: 1817 default:
1818 aprint_error_dev(sc->sc_dev, 1818 aprint_error_dev(sc->sc_dev,
1819 "ignored audio interface with %d endpoints\n", 1819 "ignored audio interface with %d endpoints\n",
1820 id->bNumEndpoints); 1820 id->bNumEndpoints);
1821 break; 1821 break;
1822 } 1822 }
1823 id = uaudio_find_iface(tbuf, size, &offs,UISUBCLASS_AUDIOSTREAM); 1823 id = uaudio_find_iface(tbuf, size, &offs,UISUBCLASS_AUDIOSTREAM);
1824 if (id == NULL) 1824 if (id == NULL)
1825 break; 1825 break;
1826 } 1826 }
1827 if (offs > size) 1827 if (offs > size)
1828 return USBD_INVAL; 1828 return USBD_INVAL;
1829 DPRINTF("%d alts available\n", sc->sc_nalts); 1829 DPRINTF("%d alts available\n", sc->sc_nalts);
1830 1830
1831 if (sc->sc_mode == 0) { 1831 if (sc->sc_mode == 0) {
1832 aprint_error_dev(sc->sc_dev, "no usable endpoint found\n"); 1832 aprint_error_dev(sc->sc_dev, "no usable endpoint found\n");
1833 return USBD_INVAL; 1833 return USBD_INVAL;
1834 } 1834 }
1835 1835
1836 /* build audio_format array */ 1836 /* build audio_format array */
1837 sc->sc_formats = kmem_alloc(sizeof(struct audio_format) * sc->sc_nalts, 1837 sc->sc_formats = kmem_alloc(sizeof(struct audio_format) * sc->sc_nalts,
1838 KM_SLEEP); 1838 KM_SLEEP);
1839 if (sc->sc_formats == NULL) 1839 if (sc->sc_formats == NULL)
1840 return USBD_NOMEM; 1840 return USBD_NOMEM;
1841 sc->sc_nformats = sc->sc_nalts; 1841 sc->sc_nformats = sc->sc_nalts;
1842 for (i = 0; i < sc->sc_nalts; i++) { 1842 for (i = 0; i < sc->sc_nalts; i++) {
1843 auf = &sc->sc_formats[i]; 1843 auf = &sc->sc_formats[i];
1844 t1desc = sc->sc_alts[i].asf1desc; 1844 t1desc = sc->sc_alts[i].asf1desc;
1845 auf->driver_data = NULL; 1845 auf->driver_data = NULL;
1846 if (UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress) == UE_DIR_OUT) 1846 if (UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress) == UE_DIR_OUT)
1847 auf->mode = AUMODE_PLAY; 1847 auf->mode = AUMODE_PLAY;
1848 else 1848 else
1849 auf->mode = AUMODE_RECORD; 1849 auf->mode = AUMODE_RECORD;
1850 auf->encoding = sc->sc_alts[i].encoding; 1850 auf->encoding = sc->sc_alts[i].encoding;
1851 auf->validbits = t1desc->bBitResolution; 1851 auf->validbits = t1desc->bBitResolution;
1852 auf->precision = t1desc->bSubFrameSize * 8; 1852 auf->precision = t1desc->bSubFrameSize * 8;
1853 auf->channels = t1desc->bNrChannels; 1853 auf->channels = t1desc->bNrChannels;
1854 auf->channel_mask = sc->sc_channel_config; 1854 auf->channel_mask = sc->sc_channel_config;
1855 auf->frequency_type = t1desc->bSamFreqType; 1855 auf->frequency_type = t1desc->bSamFreqType;
1856 if (t1desc->bSamFreqType == UA_SAMP_CONTNUOUS) { 1856 if (t1desc->bSamFreqType == UA_SAMP_CONTNUOUS) {
1857 auf->frequency[0] = UA_SAMP_LO(t1desc); 1857 auf->frequency[0] = UA_SAMP_LO(t1desc);
1858 auf->frequency[1] = UA_SAMP_HI(t1desc); 1858 auf->frequency[1] = UA_SAMP_HI(t1desc);
1859 } else { 1859 } else {
1860 for (j = 0; j < t1desc->bSamFreqType; j++) { 1860 for (j = 0; j < t1desc->bSamFreqType; j++) {
1861 if (j >= AUFMT_MAX_FREQUENCIES) { 1861 if (j >= AUFMT_MAX_FREQUENCIES) {
1862 aprint_error("%s: please increase " 1862 aprint_error("%s: please increase "
1863 "AUFMT_MAX_FREQUENCIES to %d\n", 1863 "AUFMT_MAX_FREQUENCIES to %d\n",
1864 __func__, t1desc->bSamFreqType); 1864 __func__, t1desc->bSamFreqType);
1865 auf->frequency_type = 1865 auf->frequency_type =
1866 AUFMT_MAX_FREQUENCIES; 1866 AUFMT_MAX_FREQUENCIES;
1867 break; 1867 break;
1868 } 1868 }
1869 auf->frequency[j] = UA_GETSAMP(t1desc, j); 1869 auf->frequency[j] = UA_GETSAMP(t1desc, j);
1870 } 1870 }
1871 } 1871 }
1872 sc->sc_alts[i].aformat = auf; 1872 sc->sc_alts[i].aformat = auf;
1873 } 1873 }
1874 1874
1875 if (0 != auconv_create_encodings(sc->sc_formats, sc->sc_nformats, 1875 if (0 != auconv_create_encodings(sc->sc_formats, sc->sc_nformats,
1876 &sc->sc_encodings)) { 1876 &sc->sc_encodings)) {
1877 kmem_free(sc->sc_formats, 1877 kmem_free(sc->sc_formats,
1878 sizeof(struct audio_format) * sc->sc_nformats); 1878 sizeof(struct audio_format) * sc->sc_nformats);
1879 sc->sc_formats = NULL; 1879 sc->sc_formats = NULL;
1880 return ENOMEM; 1880 return ENOMEM;
1881 } 1881 }
1882 1882
1883 return USBD_NORMAL_COMPLETION; 1883 return USBD_NORMAL_COMPLETION;
1884} 1884}
1885 1885
1886#ifdef UAUDIO_DEBUG 1886#ifdef UAUDIO_DEBUG
1887Static void 1887Static void
1888uaudio_dump_tml(struct terminal_list *tml) { 1888uaudio_dump_tml(struct terminal_list *tml) {
1889 if (tml == NULL) { 1889 if (tml == NULL) {
1890 printf("NULL"); 1890 printf("NULL");
1891 } else { 1891 } else {
1892 int i; 1892 int i;
1893 for (i = 0; i < tml->size; i++) 1893 for (i = 0; i < tml->size; i++)
1894 printf("%s ", uaudio_get_terminal_name 1894 printf("%s ", uaudio_get_terminal_name
1895 (tml->terminals[i])); 1895 (tml->terminals[i]));
1896 } 1896 }
1897 printf("\n"); 1897 printf("\n");
1898} 1898}
1899#endif 1899#endif
1900 1900
1901Static usbd_status 1901Static usbd_status
1902uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc) 1902uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
1903{ 1903{
1904 struct io_terminal* iot; 1904 struct io_terminal* iot;
1905 const usb_interface_descriptor_t *id; 1905 const usb_interface_descriptor_t *id;
1906 const struct usb_audio_control_descriptor *acdp; 1906 const struct usb_audio_control_descriptor *acdp;
1907 const uaudio_cs_descriptor_t *dp; 1907 const uaudio_cs_descriptor_t *dp;
1908 const struct usb_audio_output_terminal *pot; 1908 const struct usb_audio_output_terminal *pot;
1909 struct terminal_list *tml; 1909 struct terminal_list *tml;
1910 const char *tbuf, *ibuf, *ibufend; 1910 const char *tbuf, *ibuf, *ibufend;
1911 int size, offs, ndps, i, j; 1911 int size, offs, ndps, i, j;
1912 1912
1913 size = UGETW(cdesc->wTotalLength); 1913 size = UGETW(cdesc->wTotalLength);
1914 tbuf = (const char *)cdesc; 1914 tbuf = (const char *)cdesc;
1915 1915
1916 /* Locate the AudioControl interface descriptor. */ 1916 /* Locate the AudioControl interface descriptor. */
1917 offs = 0; 1917 offs = 0;
1918 id = uaudio_find_iface(tbuf, size, &offs, UISUBCLASS_AUDIOCONTROL); 1918 id = uaudio_find_iface(tbuf, size, &offs, UISUBCLASS_AUDIOCONTROL);
1919 if (id == NULL) 1919 if (id == NULL)
1920 return USBD_INVAL; 1920 return USBD_INVAL;
1921 if (offs + sizeof(*acdp) > size) 1921 if (offs + sizeof(*acdp) > size)
1922 return USBD_INVAL; 1922 return USBD_INVAL;
1923 sc->sc_ac_iface = id->bInterfaceNumber; 1923 sc->sc_ac_iface = id->bInterfaceNumber;
1924 DPRINTFN(2,"AC interface is %d\n", sc->sc_ac_iface); 1924 DPRINTFN(2,"AC interface is %d\n", sc->sc_ac_iface);
1925 1925
1926 /* A class-specific AC interface header should follow. */ 1926 /* A class-specific AC interface header should follow. */
1927 ibuf = tbuf + offs; 1927 ibuf = tbuf + offs;
1928 ibufend = tbuf + size; 1928 ibufend = tbuf + size;
1929 acdp = (const struct usb_audio_control_descriptor *)ibuf; 1929 acdp = (const struct usb_audio_control_descriptor *)ibuf;
1930 if (acdp->bDescriptorType != UDESC_CS_INTERFACE || 1930 if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
1931 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER) 1931 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
1932 return USBD_INVAL; 1932 return USBD_INVAL;
1933 1933
1934 if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) && 1934 if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
1935 UGETW(acdp->bcdADC) != UAUDIO_VERSION) 1935 UGETW(acdp->bcdADC) != UAUDIO_VERSION)
1936 return USBD_INVAL; 1936 return USBD_INVAL;
1937 1937
1938 sc->sc_audio_rev = UGETW(acdp->bcdADC); 1938 sc->sc_audio_rev = UGETW(acdp->bcdADC);
1939 DPRINTFN(2, "found AC header, vers=%03x\n", sc->sc_audio_rev); 1939 DPRINTFN(2, "found AC header, vers=%03x\n", sc->sc_audio_rev);
1940 1940
1941 sc->sc_nullalt = -1; 1941 sc->sc_nullalt = -1;
1942 1942
1943 /* Scan through all the AC specific descriptors */ 1943 /* Scan through all the AC specific descriptors */
1944 dp = (const uaudio_cs_descriptor_t *)ibuf; 1944 dp = (const uaudio_cs_descriptor_t *)ibuf;
1945 ndps = 0; 1945 ndps = 0;
1946 iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO); 1946 iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO);
1947 if (iot == NULL) { 1947 if (iot == NULL) {
1948 aprint_error("%s: no memory\n", __func__); 1948 aprint_error("%s: no memory\n", __func__);
1949 return USBD_NOMEM; 1949 return USBD_NOMEM;
1950 } 1950 }
1951 for (;;) { 1951 for (;;) {
1952 ibuf += dp->bLength; 1952 ibuf += dp->bLength;
1953 if (ibuf >= ibufend) 1953 if (ibuf >= ibufend)
1954 break; 1954 break;
1955 dp = (const uaudio_cs_descriptor_t *)ibuf; 1955 dp = (const uaudio_cs_descriptor_t *)ibuf;
1956 if (ibuf + dp->bLength > ibufend) { 1956 if (ibuf + dp->bLength > ibufend) {
1957 free(iot, M_TEMP); 1957 free(iot, M_TEMP);
1958 return USBD_INVAL; 1958 return USBD_INVAL;
1959 } 1959 }
1960 if (dp->bDescriptorType != UDESC_CS_INTERFACE) 1960 if (dp->bDescriptorType != UDESC_CS_INTERFACE)
1961 break; 1961 break;
1962 i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId; 1962 i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId;
1963 iot[i].d.desc = dp; 1963 iot[i].d.desc = dp;
1964 if (i > ndps) 1964 if (i > ndps)
1965 ndps = i; 1965 ndps = i;
1966 } 1966 }
1967 ndps++; 1967 ndps++;
1968 1968
1969 /* construct io_terminal */ 1969 /* construct io_terminal */
1970 for (i = 0; i < ndps; i++) { 1970 for (i = 0; i < ndps; i++) {
1971 dp = iot[i].d.desc; 1971 dp = iot[i].d.desc;
1972 if (dp == NULL) 1972 if (dp == NULL)
1973 continue; 1973 continue;
1974 if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT) 1974 if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT)
1975 continue; 1975 continue;
1976 pot = iot[i].d.ot; 1976 pot = iot[i].d.ot;
1977 tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i); 1977 tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i);
1978 if (tml != NULL) 1978 if (tml != NULL)
1979 free(tml, M_TEMP); 1979 free(tml, M_TEMP);
1980 } 1980 }
1981 1981
1982#ifdef UAUDIO_DEBUG 1982#ifdef UAUDIO_DEBUG
1983 for (i = 0; i < 256; i++) { 1983 for (i = 0; i < 256; i++) {
1984 struct usb_audio_cluster cluster; 1984 struct usb_audio_cluster cluster;
1985 1985
1986 if (iot[i].d.desc == NULL) 1986 if (iot[i].d.desc == NULL)
1987 continue; 1987 continue;
1988 printf("id %d:\t", i); 1988 printf("id %d:\t", i);
1989 switch (iot[i].d.desc->bDescriptorSubtype) { 1989 switch (iot[i].d.desc->bDescriptorSubtype) {
1990 case UDESCSUB_AC_INPUT: 1990 case UDESCSUB_AC_INPUT:
1991 printf("AC_INPUT type=%s\n", uaudio_get_terminal_name 1991 printf("AC_INPUT type=%s\n", uaudio_get_terminal_name
1992 (UGETW(iot[i].d.it->wTerminalType))); 1992 (UGETW(iot[i].d.it->wTerminalType)));
1993 printf("\t"); 1993 printf("\t");
1994 cluster = uaudio_get_cluster(i, iot); 1994 cluster = uaudio_get_cluster(i, iot);
1995 uaudio_dump_cluster(&cluster); 1995 uaudio_dump_cluster(&cluster);
1996 printf("\n"); 1996 printf("\n");
1997 break; 1997 break;
1998 case UDESCSUB_AC_OUTPUT: 1998 case UDESCSUB_AC_OUTPUT:
1999 printf("AC_OUTPUT type=%s ", uaudio_get_terminal_name 1999 printf("AC_OUTPUT type=%s ", uaudio_get_terminal_name
2000 (UGETW(iot[i].d.ot->wTerminalType))); 2000 (UGETW(iot[i].d.ot->wTerminalType)));
2001 printf("src=%d\n", iot[i].d.ot->bSourceId); 2001 printf("src=%d\n", iot[i].d.ot->bSourceId);
2002 break; 2002 break;
2003 case UDESCSUB_AC_MIXER: 2003 case UDESCSUB_AC_MIXER:
2004 printf("AC_MIXER src="); 2004 printf("AC_MIXER src=");
2005 for (j = 0; j < iot[i].d.mu->bNrInPins; j++) 2005 for (j = 0; j < iot[i].d.mu->bNrInPins; j++)
2006 printf("%d ", iot[i].d.mu->baSourceId[j]); 2006 printf("%d ", iot[i].d.mu->baSourceId[j]);
2007 printf("\n\t"); 2007 printf("\n\t");
2008 cluster = uaudio_get_cluster(i, iot); 2008 cluster = uaudio_get_cluster(i, iot);
2009 uaudio_dump_cluster(&cluster); 2009 uaudio_dump_cluster(&cluster);
2010 printf("\n"); 2010 printf("\n");
2011 break; 2011 break;
2012 case UDESCSUB_AC_SELECTOR: 2012 case UDESCSUB_AC_SELECTOR:
2013 printf("AC_SELECTOR src="); 2013 printf("AC_SELECTOR src=");
2014 for (j = 0; j < iot[i].d.su->bNrInPins; j++) 2014 for (j = 0; j < iot[i].d.su->bNrInPins; j++)
2015 printf("%d ", iot[i].d.su->baSourceId[j]); 2015 printf("%d ", iot[i].d.su->baSourceId[j]);
2016 printf("\n"); 2016 printf("\n");
2017 break; 2017 break;
2018 case UDESCSUB_AC_FEATURE: 2018 case UDESCSUB_AC_FEATURE:
2019 printf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId); 2019 printf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId);
2020 break; 2020 break;
2021 case UDESCSUB_AC_PROCESSING: 2021 case UDESCSUB_AC_PROCESSING:
2022 printf("AC_PROCESSING src="); 2022 printf("AC_PROCESSING src=");
2023 for (j = 0; j < iot[i].d.pu->bNrInPins; j++) 2023 for (j = 0; j < iot[i].d.pu->bNrInPins; j++)
2024 printf("%d ", iot[i].d.pu->baSourceId[j]); 2024 printf("%d ", iot[i].d.pu->baSourceId[j]);
2025 printf("\n\t"); 2025 printf("\n\t");
2026 cluster = uaudio_get_cluster(i, iot); 2026 cluster = uaudio_get_cluster(i, iot);
2027 uaudio_dump_cluster(&cluster); 2027 uaudio_dump_cluster(&cluster);
2028 printf("\n"); 2028 printf("\n");
2029 break; 2029 break;
2030 case UDESCSUB_AC_EXTENSION: 2030 case UDESCSUB_AC_EXTENSION:
2031 printf("AC_EXTENSION src="); 2031 printf("AC_EXTENSION src=");
2032 for (j = 0; j < iot[i].d.eu->bNrInPins; j++) 2032 for (j = 0; j < iot[i].d.eu->bNrInPins; j++)
2033 printf("%d ", iot[i].d.eu->baSourceId[j]); 2033 printf("%d ", iot[i].d.eu->baSourceId[j]);
2034 printf("\n\t"); 2034 printf("\n\t");
2035 cluster = uaudio_get_cluster(i, iot); 2035 cluster = uaudio_get_cluster(i, iot);
2036 uaudio_dump_cluster(&cluster); 2036 uaudio_dump_cluster(&cluster);
2037 printf("\n"); 2037 printf("\n");
2038 break; 2038 break;
2039 default: 2039 default:
2040 printf("unknown audio control (subtype=%d)\n", 2040 printf("unknown audio control (subtype=%d)\n",
2041 iot[i].d.desc->bDescriptorSubtype); 2041 iot[i].d.desc->bDescriptorSubtype);
2042 } 2042 }
2043 for (j = 0; j < iot[i].inputs_size; j++) { 2043 for (j = 0; j < iot[i].inputs_size; j++) {
2044 printf("\tinput%d: ", j); 2044 printf("\tinput%d: ", j);
2045 uaudio_dump_tml(iot[i].inputs[j]); 2045 uaudio_dump_tml(iot[i].inputs[j]);
2046 } 2046 }
2047 printf("\toutput: "); 2047 printf("\toutput: ");
2048 uaudio_dump_tml(iot[i].output); 2048 uaudio_dump_tml(iot[i].output);
2049 } 2049 }
2050#endif 2050#endif
2051 2051
2052 for (i = 0; i < ndps; i++) { 2052 for (i = 0; i < ndps; i++) {
2053 dp = iot[i].d.desc; 2053 dp = iot[i].d.desc;
2054 if (dp == NULL) 2054 if (dp == NULL)
2055 continue; 2055 continue;
2056 DPRINTF("id=%d subtype=%d\n", i, dp->bDescriptorSubtype); 2056 DPRINTF("id=%d subtype=%d\n", i, dp->bDescriptorSubtype);
2057 switch (dp->bDescriptorSubtype) { 2057 switch (dp->bDescriptorSubtype) {
2058 case UDESCSUB_AC_HEADER: 2058 case UDESCSUB_AC_HEADER:
2059 aprint_error("uaudio_identify_ac: unexpected AC header\n"); 2059 aprint_error("uaudio_identify_ac: unexpected AC header\n");
2060 break; 2060 break;
2061 case UDESCSUB_AC_INPUT: 2061 case UDESCSUB_AC_INPUT:
2062 uaudio_add_input(sc, iot, i); 2062 uaudio_add_input(sc, iot, i);
2063 break; 2063 break;
2064 case UDESCSUB_AC_OUTPUT: 2064 case UDESCSUB_AC_OUTPUT:
2065 uaudio_add_output(sc, iot, i); 2065 uaudio_add_output(sc, iot, i);
2066 break; 2066 break;
2067 case UDESCSUB_AC_MIXER: 2067 case UDESCSUB_AC_MIXER:
2068 uaudio_add_mixer(sc, iot, i); 2068 uaudio_add_mixer(sc, iot, i);
2069 break; 2069 break;
2070 case UDESCSUB_AC_SELECTOR: 2070 case UDESCSUB_AC_SELECTOR:
2071 uaudio_add_selector(sc, iot, i); 2071 uaudio_add_selector(sc, iot, i);
2072 break; 2072 break;
2073 case UDESCSUB_AC_FEATURE: 2073 case UDESCSUB_AC_FEATURE:
2074 uaudio_add_feature(sc, iot, i); 2074 uaudio_add_feature(sc, iot, i);
2075 break; 2075 break;
2076 case UDESCSUB_AC_PROCESSING: 2076 case UDESCSUB_AC_PROCESSING:
2077 uaudio_add_processing(sc, iot, i); 2077 uaudio_add_processing(sc, iot, i);
2078 break; 2078 break;
2079 case UDESCSUB_AC_EXTENSION: 2079 case UDESCSUB_AC_EXTENSION:
2080 uaudio_add_extension(sc, iot, i); 2080 uaudio_add_extension(sc, iot, i);
2081 break; 2081 break;
2082 default: 2082 default:
2083 aprint_error( 2083 aprint_error(
2084 "uaudio_identify_ac: bad AC desc subtype=0x%02x\n", 2084 "uaudio_identify_ac: bad AC desc subtype=0x%02x\n",
2085 dp->bDescriptorSubtype); 2085 dp->bDescriptorSubtype);
2086 break; 2086 break;
2087 } 2087 }
2088 } 2088 }
2089 2089
2090 /* delete io_terminal */ 2090 /* delete io_terminal */
2091 for (i = 0; i < 256; i++) { 2091 for (i = 0; i < 256; i++) {
2092 if (iot[i].d.desc == NULL) 2092 if (iot[i].d.desc == NULL)
2093 continue; 2093 continue;
2094 if (iot[i].inputs != NULL) { 2094 if (iot[i].inputs != NULL) {
2095 for (j = 0; j < iot[i].inputs_size; j++) { 2095 for (j = 0; j < iot[i].inputs_size; j++) {
2096 if (iot[i].inputs[j] != NULL) 2096 if (iot[i].inputs[j] != NULL)
2097 free(iot[i].inputs[j], M_TEMP); 2097 free(iot[i].inputs[j], M_TEMP);
2098 } 2098 }
2099 free(iot[i].inputs, M_TEMP); 2099 free(iot[i].inputs, M_TEMP);
2100 } 2100 }
2101 if (iot[i].output != NULL) 2101 if (iot[i].output != NULL)
2102 free(iot[i].output, M_TEMP); 2102 free(iot[i].output, M_TEMP);
2103 iot[i].d.desc = NULL; 2103 iot[i].d.desc = NULL;
2104 } 2104 }
2105 free(iot, M_TEMP); 2105 free(iot, M_TEMP);
2106 2106
2107 return USBD_NORMAL_COMPLETION; 2107 return USBD_NORMAL_COMPLETION;
2108} 2108}
2109 2109
2110Static int 2110Static int
2111uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi) 2111uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
2112{ 2112{
2113 struct uaudio_softc *sc; 2113 struct uaudio_softc *sc;
2114 struct mixerctl *mc; 2114 struct mixerctl *mc;
2115 int n, nctls, i; 2115 int n, nctls, i;
2116 2116
2117 DPRINTFN(7, "index=%d\n", mi->index); 2117 DPRINTFN(7, "index=%d\n", mi->index);
2118 sc = addr; 2118 sc = addr;
2119 if (sc->sc_dying) 2119 if (sc->sc_dying)
2120 return EIO; 2120 return EIO;
2121 2121
2122 n = mi->index; 2122 n = mi->index;
2123 nctls = sc->sc_nctls; 2123 nctls = sc->sc_nctls;
2124 2124
2125 switch (n) { 2125 switch (n) {
2126 case UAC_OUTPUT: 2126 case UAC_OUTPUT:
2127 mi->type = AUDIO_MIXER_CLASS; 2127 mi->type = AUDIO_MIXER_CLASS;
2128 mi->mixer_class = UAC_OUTPUT; 2128 mi->mixer_class = UAC_OUTPUT;
2129 mi->next = mi->prev = AUDIO_MIXER_LAST; 2129 mi->next = mi->prev = AUDIO_MIXER_LAST;
2130 strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name)); 2130 strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name));
2131 return 0; 2131 return 0;
2132 case UAC_INPUT: 2132 case UAC_INPUT:
2133 mi->type = AUDIO_MIXER_CLASS; 2133 mi->type = AUDIO_MIXER_CLASS;
2134 mi->mixer_class = UAC_INPUT; 2134 mi->mixer_class = UAC_INPUT;
2135 mi->next = mi->prev = AUDIO_MIXER_LAST; 2135 mi->next = mi->prev = AUDIO_MIXER_LAST;
2136 strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name)); 2136 strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name));
2137 return 0; 2137 return 0;
2138 case UAC_EQUAL: 2138 case UAC_EQUAL:
2139 mi->type = AUDIO_MIXER_CLASS; 2139 mi->type = AUDIO_MIXER_CLASS;
2140 mi->mixer_class = UAC_EQUAL; 2140 mi->mixer_class = UAC_EQUAL;
2141 mi->next = mi->prev = AUDIO_MIXER_LAST; 2141 mi->next = mi->prev = AUDIO_MIXER_LAST;
2142 strlcpy(mi->label.name, AudioCequalization, 2142 strlcpy(mi->label.name, AudioCequalization,
2143 sizeof(mi->label.name)); 2143 sizeof(mi->label.name));
2144 return 0; 2144 return 0;
2145 case UAC_RECORD: 2145 case UAC_RECORD:
2146 mi->type = AUDIO_MIXER_CLASS; 2146 mi->type = AUDIO_MIXER_CLASS;
2147 mi->mixer_class = UAC_RECORD; 2147 mi->mixer_class = UAC_RECORD;
2148 mi->next = mi->prev = AUDIO_MIXER_LAST; 2148 mi->next = mi->prev = AUDIO_MIXER_LAST;
2149 strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name)); 2149 strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name));
2150 return 0; 2150 return 0;
2151 default: 2151 default:
2152 break; 2152 break;
2153 } 2153 }
2154 2154
2155 n -= UAC_NCLASSES; 2155 n -= UAC_NCLASSES;
2156 if (n < 0 || n >= nctls) 2156 if (n < 0 || n >= nctls)
2157 return ENXIO; 2157 return ENXIO;
2158 2158
2159 mc = &sc->sc_ctls[n]; 2159 mc = &sc->sc_ctls[n];
2160 strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name)); 2160 strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name));
2161 mi->mixer_class = mc->class; 2161 mi->mixer_class = mc->class;
2162 mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */ 2162 mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */
2163 switch (mc->type) { 2163 switch (mc->type) {
2164 case MIX_ON_OFF: 2164 case MIX_ON_OFF:
2165 mi->type = AUDIO_MIXER_ENUM; 2165 mi->type = AUDIO_MIXER_ENUM;
2166 mi->un.e.num_mem = 2; 2166 mi->un.e.num_mem = 2;
2167 strlcpy(mi->un.e.member[0].label.name, AudioNoff, 2167 strlcpy(mi->un.e.member[0].label.name, AudioNoff,
2168 sizeof(mi->un.e.member[0].label.name)); 2168 sizeof(mi->un.e.member[0].label.name));
2169 mi->un.e.member[0].ord = 0; 2169 mi->un.e.member[0].ord = 0;
2170 strlcpy(mi->un.e.member[1].label.name, AudioNon, 2170 strlcpy(mi->un.e.member[1].label.name, AudioNon,
2171 sizeof(mi->un.e.member[1].label.name)); 2171 sizeof(mi->un.e.member[1].label.name));
2172 mi->un.e.member[1].ord = 1; 2172 mi->un.e.member[1].ord = 1;
2173 break; 2173 break;
2174 case MIX_SELECTOR: 2174 case MIX_SELECTOR:
2175 mi->type = AUDIO_MIXER_ENUM; 2175 mi->type = AUDIO_MIXER_ENUM;
2176 mi->un.e.num_mem = mc->maxval - mc->minval + 1; 2176 mi->un.e.num_mem = mc->maxval - mc->minval + 1;
2177 for (i = 0; i <= mc->maxval - mc->minval; i++) { 2177 for (i = 0; i <= mc->maxval - mc->minval; i++) {
2178 snprintf(mi->un.e.member[i].label.name, 2178 snprintf(mi->un.e.member[i].label.name,
2179 sizeof(mi->un.e.member[i].label.name), 2179 sizeof(mi->un.e.member[i].label.name),
2180 "%d", i + mc->minval); 2180 "%d", i + mc->minval);
2181 mi->un.e.member[i].ord = i + mc->minval; 2181 mi->un.e.member[i].ord = i + mc->minval;
2182 } 2182 }
2183 break; 2183 break;
2184 default: 2184 default:
2185 mi->type = AUDIO_MIXER_VALUE; 2185 mi->type = AUDIO_MIXER_VALUE;
2186 strncpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN); 2186 strncpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN);
2187 mi->un.v.num_channels = mc->nchan; 2187 mi->un.v.num_channels = mc->nchan;
2188 mi->un.v.delta = mc->delta; 2188 mi->un.v.delta = mc->delta;
2189 break; 2189 break;
2190 } 2190 }
2191 return 0; 2191 return 0;
2192} 2192}
2193 2193
2194Static int 2194Static int
2195uaudio_open(void *addr, int flags) 2195uaudio_open(void *addr, int flags)
2196{ 2196{
2197 struct uaudio_softc *sc; 2197 struct uaudio_softc *sc;
2198 2198
2199 sc = addr; 2199 sc = addr;
2200 DPRINTF("sc=%p\n", sc); 2200 DPRINTF("sc=%p\n", sc);
2201 if (sc->sc_dying) 2201 if (sc->sc_dying)
2202 return EIO; 2202 return EIO;
2203 2203
2204 if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY)) 2204 if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY))
2205 return EACCES; 2205 return EACCES;
2206 if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD)) 2206 if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD))
2207 return EACCES; 2207 return EACCES;
2208 2208
2209 return 0; 2209 return 0;
2210} 2210}
2211 2211
2212/* 2212/*
2213 * Close function is called at splaudio(). 2213 * Close function is called at splaudio().
2214 */ 2214 */
2215Static void 2215Static void
2216uaudio_close(void *addr) 2216uaudio_close(void *addr)
2217{ 2217{
2218} 2218}
2219 2219
2220Static int 2220Static int
2221uaudio_drain(void *addr) 2221uaudio_drain(void *addr)
2222{ 2222{
2223 struct uaudio_softc *sc = addr; 2223 struct uaudio_softc *sc = addr;
2224 2224
2225 KASSERT(mutex_owned(&sc->sc_intr_lock)); 2225 KASSERT(mutex_owned(&sc->sc_intr_lock));
2226 2226
2227 kpause("uaudiodr", false, 2227 kpause("uaudiodr", false,
2228 mstohz(UAUDIO_NCHANBUFS * UAUDIO_NFRAMES), &sc->sc_intr_lock); 2228 mstohz(UAUDIO_NCHANBUFS * UAUDIO_NFRAMES), &sc->sc_intr_lock);
2229 2229
2230 return 0; 2230 return 0;
2231} 2231}
2232 2232
2233Static int 2233Static int
2234uaudio_halt_out_dma(void *addr) 2234uaudio_halt_out_dma(void *addr)
2235{ 2235{
2236 struct uaudio_softc *sc = addr; 2236 struct uaudio_softc *sc = addr;
2237 2237
2238 DPRINTF("%s", "enter\n"); 2238 DPRINTF("%s", "enter\n");
2239 2239
2240 mutex_spin_exit(&sc->sc_intr_lock); 2240 mutex_spin_exit(&sc->sc_intr_lock);
2241 if (sc->sc_playchan.pipe != NULL) { 2241 if (sc->sc_playchan.pipe != NULL) {
2242 uaudio_chan_abort(sc, &sc->sc_playchan); 2242 uaudio_chan_abort(sc, &sc->sc_playchan);
2243 uaudio_chan_free_buffers(sc, &sc->sc_playchan); 2243 uaudio_chan_free_buffers(sc, &sc->sc_playchan);
2244 uaudio_chan_close(sc, &sc->sc_playchan); 2244 uaudio_chan_close(sc, &sc->sc_playchan);
2245 sc->sc_playchan.intr = NULL; 2245 sc->sc_playchan.intr = NULL;
2246 } 2246 }
2247 mutex_spin_enter(&sc->sc_intr_lock); 2247 mutex_spin_enter(&sc->sc_intr_lock);
2248 2248
2249 return 0; 2249 return 0;
2250} 2250}
2251 2251
2252Static int 2252Static int
2253uaudio_halt_in_dma(void *addr) 2253uaudio_halt_in_dma(void *addr)
2254{ 2254{
2255 struct uaudio_softc *sc = addr; 2255 struct uaudio_softc *sc = addr;
2256 2256
2257 DPRINTF("%s", "enter\n"); 2257 DPRINTF("%s", "enter\n");
2258 2258
2259 mutex_spin_exit(&sc->sc_intr_lock); 2259 mutex_spin_exit(&sc->sc_intr_lock);
2260 if (sc->sc_recchan.pipe != NULL) { 2260 if (sc->sc_recchan.pipe != NULL) {
2261 uaudio_chan_abort(sc, &sc->sc_recchan); 2261 uaudio_chan_abort(sc, &sc->sc_recchan);
2262 uaudio_chan_free_buffers(sc, &sc->sc_recchan); 2262 uaudio_chan_free_buffers(sc, &sc->sc_recchan);
2263 uaudio_chan_close(sc, &sc->sc_recchan); 2263 uaudio_chan_close(sc, &sc->sc_recchan);
2264 sc->sc_recchan.intr = NULL; 2264 sc->sc_recchan.intr = NULL;
2265 } 2265 }
2266 mutex_spin_enter(&sc->sc_intr_lock); 2266 mutex_spin_enter(&sc->sc_intr_lock);
2267 2267
2268 return 0; 2268 return 0;
2269} 2269}
2270 2270
2271Static int 2271Static int
2272uaudio_getdev(void *addr, struct audio_device *retp) 2272uaudio_getdev(void *addr, struct audio_device *retp)
2273{ 2273{
2274 struct uaudio_softc *sc; 2274 struct uaudio_softc *sc;
2275 2275
2276 DPRINTF("%s", "\n"); 2276 DPRINTF("%s", "\n");
2277 sc = addr; 2277 sc = addr;
2278 if (sc->sc_dying) 2278 if (sc->sc_dying)
2279 return EIO; 2279 return EIO;
2280 2280
2281 *retp = sc->sc_adev; 2281 *retp = sc->sc_adev;
2282 return 0; 2282 return 0;
2283} 2283}
2284 2284
2285/* 2285/*
2286 * Make sure the block size is large enough to hold all outstanding transfers. 2286 * Make sure the block size is large enough to hold all outstanding transfers.
2287 */ 2287 */
2288Static int 2288Static int
2289uaudio_round_blocksize(void *addr, int blk, 2289uaudio_round_blocksize(void *addr, int blk,
2290 int mode, const audio_params_t *param) 2290 int mode, const audio_params_t *param)
2291{ 2291{
2292 struct uaudio_softc *sc; 2292 struct uaudio_softc *sc;
2293 int b; 2293 int b;
2294 2294
2295 sc = addr; 2295 sc = addr;
2296 DPRINTF("blk=%d mode=%s\n", blk, 2296 DPRINTF("blk=%d mode=%s\n", blk,
2297 mode == AUMODE_PLAY ? "AUMODE_PLAY" : "AUMODE_RECORD"); 2297 mode == AUMODE_PLAY ? "AUMODE_PLAY" : "AUMODE_RECORD");
2298 2298
2299 /* chan.bytes_per_frame can be 0. */ 2299 /* chan.bytes_per_frame can be 0. */
2300 if (mode == AUMODE_PLAY || sc->sc_recchan.bytes_per_frame <= 0) { 2300 if (mode == AUMODE_PLAY || sc->sc_recchan.bytes_per_frame <= 0) {
2301 b = param->sample_rate * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS; 2301 b = param->sample_rate * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
2302 2302
2303 /* 2303 /*
2304 * This does not make accurate value in the case 2304 * This does not make accurate value in the case
2305 * of b % USB_FRAMES_PER_SECOND != 0 2305 * of b % USB_FRAMES_PER_SECOND != 0
2306 */ 2306 */
2307 b /= USB_FRAMES_PER_SECOND; 2307 b /= USB_FRAMES_PER_SECOND;
2308 2308
2309 b *= param->precision / 8 * param->channels; 2309 b *= param->precision / 8 * param->channels;
2310 } else { 2310 } else {
2311 /* 2311 /*
2312 * use wMaxPacketSize in bytes_per_frame. 2312 * use wMaxPacketSize in bytes_per_frame.
2313 * See uaudio_set_params() and uaudio_chan_init() 2313 * See uaudio_set_params() and uaudio_chan_init()
2314 */ 2314 */
2315 b = sc->sc_recchan.bytes_per_frame 2315 b = sc->sc_recchan.bytes_per_frame
2316 * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS; 2316 * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
2317 } 2317 }
2318 2318
2319 if (b <= 0) 2319 if (b <= 0)
2320 b = 1; 2320 b = 1;
2321 blk = blk <= b ? b : blk / b * b; 2321 blk = blk <= b ? b : blk / b * b;
2322 2322
2323#ifdef DIAGNOSTIC 2323#ifdef DIAGNOSTIC
2324 if (blk <= 0) { 2324 if (blk <= 0) {
2325 aprint_debug("uaudio_round_blocksize: blk=%d\n", blk); 2325 aprint_debug("uaudio_round_blocksize: blk=%d\n", blk);
2326 blk = 512; 2326 blk = 512;
2327 } 2327 }
2328#endif 2328#endif
2329 2329
2330 DPRINTF("resultant blk=%d\n", blk); 2330 DPRINTF("resultant blk=%d\n", blk);
2331 return blk; 2331 return blk;
2332} 2332}
2333 2333
2334Static int 2334Static int
2335uaudio_get_props(void *addr) 2335uaudio_get_props(void *addr)
2336{ 2336{
2337 return AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT; 2337 return AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT;
2338 2338
2339} 2339}
2340 2340
2341Static void 2341Static void
2342uaudio_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread) 2342uaudio_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread)
2343{ 2343{
2344 struct uaudio_softc *sc; 2344 struct uaudio_softc *sc;
2345 2345
2346 sc = addr; 2346 sc = addr;
2347 *intr = &sc->sc_intr_lock; 2347 *intr = &sc->sc_intr_lock;
2348 *thread = &sc->sc_lock; 2348 *thread = &sc->sc_lock;
2349} 2349}
2350 2350
2351Static int 2351Static int
2352uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue, 2352uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
2353 int wIndex, int len) 2353 int wIndex, int len)
2354{ 2354{
2355 usb_device_request_t req; 2355 usb_device_request_t req;
2356 uint8_t data[4]; 2356 uint8_t data[4];
2357 usbd_status err; 2357 usbd_status err;
2358 int val; 2358 int val;
2359 2359
2360 if (wValue == -1) 2360 if (wValue == -1)
2361 return 0; 2361 return 0;
2362 2362
2363 req.bmRequestType = type; 2363 req.bmRequestType = type;
2364 req.bRequest = which; 2364 req.bRequest = which;
2365 USETW(req.wValue, wValue); 2365 USETW(req.wValue, wValue);
2366 USETW(req.wIndex, wIndex); 2366 USETW(req.wIndex, wIndex);
2367 USETW(req.wLength, len); 2367 USETW(req.wLength, len);
2368 DPRINTFN(2,"type=0x%02x req=0x%02x wValue=0x%04x " 2368 DPRINTFN(2,"type=0x%02x req=0x%02x wValue=0x%04x "
2369 "wIndex=0x%04x len=%d\n", 2369 "wIndex=0x%04x len=%d\n",
2370 type, which, wValue, wIndex, len); 2370 type, which, wValue, wIndex, len);
2371 err = usbd_do_request(sc->sc_udev, &req, data); 2371 err = usbd_do_request(sc->sc_udev, &req, data);
2372 if (err) { 2372 if (err) {
2373 DPRINTF("err=%s\n", usbd_errstr(err)); 2373 DPRINTF("err=%s\n", usbd_errstr(err));
2374 return -1; 2374 return -1;
2375 } 2375 }
2376 switch (len) { 2376 switch (len) {
2377 case 1: 2377 case 1:
2378 val = data[0]; 2378 val = data[0];
2379 break; 2379 break;
2380 case 2: 2380 case 2:
2381 val = data[0] | (data[1] << 8); 2381 val = data[0] | (data[1] << 8);
2382 break; 2382 break;
2383 default: 2383 default:
2384 DPRINTF("bad length=%d\n", len); 2384 DPRINTF("bad length=%d\n", len);
2385 return -1; 2385 return -1;
2386 } 2386 }
2387 DPRINTFN(2,"val=%d\n", val); 2387 DPRINTFN(2,"val=%d\n", val);
2388 return val; 2388 return val;
2389} 2389}
2390 2390
2391Static void 2391Static void
2392uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue, 2392uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
2393 int wIndex, int len, int val) 2393 int wIndex, int len, int val)
2394{ 2394{
2395 usb_device_request_t req; 2395 usb_device_request_t req;
2396 uint8_t data[4]; 2396 uint8_t data[4];
2397 int err __unused; 2397 int err __unused;
2398 2398
2399 if (wValue == -1) 2399 if (wValue == -1)
2400 return; 2400 return;
2401 2401
2402 req.bmRequestType = type; 2402 req.bmRequestType = type;
2403 req.bRequest = which; 2403 req.bRequest = which;
2404 USETW(req.wValue, wValue); 2404 USETW(req.wValue, wValue);
2405 USETW(req.wIndex, wIndex); 2405 USETW(req.wIndex, wIndex);
2406 USETW(req.wLength, len); 2406 USETW(req.wLength, len);
2407 switch (len) { 2407 switch (len) {
2408 case 1: 2408 case 1:
2409 data[0] = val; 2409 data[0] = val;
2410 break; 2410 break;
2411 case 2: 2411 case 2:
2412 data[0] = val; 2412 data[0] = val;
2413 data[1] = val >> 8; 2413 data[1] = val >> 8;
2414 break; 2414 break;
2415 default: 2415 default:
2416 return; 2416 return;
2417 } 2417 }
2418 DPRINTFN(2,"type=0x%02x req=0x%02x wValue=0x%04x " 2418 DPRINTFN(2,"type=0x%02x req=0x%02x wValue=0x%04x "
2419 "wIndex=0x%04x len=%d, val=%d\n", 2419 "wIndex=0x%04x len=%d, val=%d\n",
2420 type, which, wValue, wIndex, len, val & 0xffff); 2420 type, which, wValue, wIndex, len, val & 0xffff);
2421 err = usbd_do_request(sc->sc_udev, &req, data); 2421 err = usbd_do_request(sc->sc_udev, &req, data);
2422#ifdef UAUDIO_DEBUG 2422#ifdef UAUDIO_DEBUG
2423 if (err) 2423 if (err)
2424 DPRINTF("err=%d\n", err); 2424 DPRINTF("err=%d\n", err);
2425#endif 2425#endif
2426} 2426}
2427 2427
2428Static int 2428Static int
2429uaudio_signext(int type, int val) 2429uaudio_signext(int type, int val)
2430{ 2430{
2431 if (!MIX_UNSIGNED(type)) { 2431 if (!MIX_UNSIGNED(type)) {
2432 if (MIX_SIZE(type) == 2) 2432 if (MIX_SIZE(type) == 2)
2433 val = (int16_t)val; 2433 val = (int16_t)val;
2434 else 2434 else
2435 val = (int8_t)val; 2435 val = (int8_t)val;
2436 } 2436 }
2437 return val; 2437 return val;
2438} 2438}
2439 2439
2440Static int 2440Static int
2441uaudio_value2bsd(struct mixerctl *mc, int val) 2441uaudio_value2bsd(struct mixerctl *mc, int val)
2442{ 2442{
2443 DPRINTFN(5, "type=%03x val=%d min=%d max=%d ", 2443 DPRINTFN(5, "type=%03x val=%d min=%d max=%d ",
2444 mc->type, val, mc->minval, mc->maxval); 2444 mc->type, val, mc->minval, mc->maxval);
2445 if (mc->type == MIX_ON_OFF) { 2445 if (mc->type == MIX_ON_OFF) {
2446 val = (val != 0); 2446 val = (val != 0);
2447 } else if (mc->type == MIX_SELECTOR) { 2447 } else if (mc->type == MIX_SELECTOR) {
2448 if (val < mc->minval || val > mc->maxval) 2448 if (val < mc->minval || val > mc->maxval)
2449 val = mc->minval; 2449 val = mc->minval;
2450 } else 2450 } else
2451 val = ((uaudio_signext(mc->type, val) - mc->minval) * 255 2451 val = ((uaudio_signext(mc->type, val) - mc->minval) * 255
2452 + mc->mul/2) / mc->mul; 2452 + mc->mul/2) / mc->mul;
2453 DPRINTFN_CLEAN(5, "val'=%d\n", val); 2453 DPRINTFN_CLEAN(5, "val'=%d\n", val);
2454 return val; 2454 return val;
2455} 2455}
2456 2456
2457int 2457int
2458uaudio_bsd2value(struct mixerctl *mc, int val) 2458uaudio_bsd2value(struct mixerctl *mc, int val)
2459{ 2459{
2460 DPRINTFN(5,"type=%03x val=%d min=%d max=%d ", 2460 DPRINTFN(5,"type=%03x val=%d min=%d max=%d ",
2461 mc->type, val, mc->minval, mc->maxval); 2461 mc->type, val, mc->minval, mc->maxval);
2462 if (mc->type == MIX_ON_OFF) { 2462 if (mc->type == MIX_ON_OFF) {
2463 val = (val != 0); 2463 val = (val != 0);
2464 } else if (mc->type == MIX_SELECTOR) { 2464 } else if (mc->type == MIX_SELECTOR) {
2465 if (val < mc->minval || val > mc->maxval) 2465 if (val < mc->minval || val > mc->maxval)
2466 val = mc->minval; 2466 val = mc->minval;
2467 } else 2467 } else
2468 val = (val + mc->delta/2) * mc->mul / 255 + mc->minval; 2468 val = (val + mc->delta/2) * mc->mul / 255 + mc->minval;
2469 DPRINTFN_CLEAN(5, "val'=%d\n", val); 2469 DPRINTFN_CLEAN(5, "val'=%d\n", val);
2470 return val; 2470 return val;
2471} 2471}
2472 2472
2473Static int 2473Static int
2474uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc, 2474uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2475 int chan) 2475 int chan)
2476{ 2476{
2477 int val; 2477 int val;
2478 2478
2479 DPRINTFN(5,"which=%d chan=%d\n", which, chan); 2479 DPRINTFN(5,"which=%d chan=%d\n", which, chan);
2480 mutex_exit(&sc->sc_lock); 2480 mutex_exit(&sc->sc_lock);
2481 val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan], 2481 val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
2482 mc->wIndex, MIX_SIZE(mc->type)); 2482 mc->wIndex, MIX_SIZE(mc->type));
2483 mutex_enter(&sc->sc_lock); 2483 mutex_enter(&sc->sc_lock);
2484 return uaudio_value2bsd(mc, val); 2484 return uaudio_value2bsd(mc, val);
2485} 2485}
2486 2486
2487Static void 2487Static void
2488uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc, 2488uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2489 int chan, int val) 2489 int chan, int val)
2490{ 2490{
2491 2491
2492 val = uaudio_bsd2value(mc, val); 2492 val = uaudio_bsd2value(mc, val);
2493 mutex_exit(&sc->sc_lock); 2493 mutex_exit(&sc->sc_lock);
2494 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan], 2494 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
2495 mc->wIndex, MIX_SIZE(mc->type), val); 2495 mc->wIndex, MIX_SIZE(mc->type), val);
2496 mutex_enter(&sc->sc_lock); 2496 mutex_enter(&sc->sc_lock);
2497} 2497}
2498 2498
2499Static int 2499Static int
2500uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp) 2500uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
2501{ 2501{
2502 struct uaudio_softc *sc; 2502 struct uaudio_softc *sc;
2503 struct mixerctl *mc; 2503 struct mixerctl *mc;
2504 int i, n, vals[MIX_MAX_CHAN], val; 2504 int i, n, vals[MIX_MAX_CHAN], val;
2505 2505
2506 DPRINTFN(2, "index=%d\n", cp->dev); 2506 DPRINTFN(2, "index=%d\n", cp->dev);
2507 sc = addr; 2507 sc = addr;
2508 if (sc->sc_dying) 2508 if (sc->sc_dying)
2509 return EIO; 2509 return EIO;
2510 2510
2511 n = cp->dev - UAC_NCLASSES; 2511 n = cp->dev - UAC_NCLASSES;
2512 if (n < 0 || n >= sc->sc_nctls) 2512 if (n < 0 || n >= sc->sc_nctls)
2513 return ENXIO; 2513 return ENXIO;
2514 mc = &sc->sc_ctls[n]; 2514 mc = &sc->sc_ctls[n];
2515 2515
2516 if (mc->type == MIX_ON_OFF) { 2516 if (mc->type == MIX_ON_OFF) {
2517 if (cp->type != AUDIO_MIXER_ENUM) 2517 if (cp->type != AUDIO_MIXER_ENUM)
2518 return EINVAL; 2518 return EINVAL;
2519 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0); 2519 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2520 } else if (mc->type == MIX_SELECTOR) { 2520 } else if (mc->type == MIX_SELECTOR) {
2521 if (cp->type != AUDIO_MIXER_ENUM) 2521 if (cp->type != AUDIO_MIXER_ENUM)
2522 return EINVAL; 2522 return EINVAL;
2523 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0); 2523 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2524 } else { 2524 } else {
2525 if (cp->type != AUDIO_MIXER_VALUE) 2525 if (cp->type != AUDIO_MIXER_VALUE)
2526 return EINVAL; 2526 return EINVAL;
2527 if (cp->un.value.num_channels != 1 && 2527 if (cp->un.value.num_channels != 1 &&
2528 cp->un.value.num_channels != mc->nchan) 2528 cp->un.value.num_channels != mc->nchan)
2529 return EINVAL; 2529 return EINVAL;
2530 for (i = 0; i < mc->nchan; i++) 2530 for (i = 0; i < mc->nchan; i++)
2531 vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i); 2531 vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
2532 if (cp->un.value.num_channels == 1 && mc->nchan != 1) { 2532 if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
2533 for (val = 0, i = 0; i < mc->nchan; i++) 2533 for (val = 0, i = 0; i < mc->nchan; i++)
2534 val += vals[i]; 2534 val += vals[i];
2535 vals[0] = val / mc->nchan; 2535 vals[0] = val / mc->nchan;
2536 } 2536 }
2537 for (i = 0; i < cp->un.value.num_channels; i++) 2537 for (i = 0; i < cp->un.value.num_channels; i++)
2538 cp->un.value.level[i] = vals[i]; 2538 cp->un.value.level[i] = vals[i];
2539 } 2539 }
2540 2540
2541 return 0; 2541 return 0;
2542} 2542}
2543 2543
2544Static int 2544Static int
2545uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp) 2545uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
2546{ 2546{
2547 struct uaudio_softc *sc; 2547 struct uaudio_softc *sc;
2548 struct mixerctl *mc; 2548 struct mixerctl *mc;
2549 int i, n, vals[MIX_MAX_CHAN]; 2549 int i, n, vals[MIX_MAX_CHAN];
2550 2550
2551 DPRINTFN(2, "index = %d\n", cp->dev); 2551 DPRINTFN(2, "index = %d\n", cp->dev);
2552 sc = addr; 2552 sc = addr;
2553 if (sc->sc_dying) 2553 if (sc->sc_dying)
2554 return EIO; 2554 return EIO;
2555 2555
2556 n = cp->dev - UAC_NCLASSES; 2556 n = cp->dev - UAC_NCLASSES;
2557 if (n < 0 || n >= sc->sc_nctls) 2557 if (n < 0 || n >= sc->sc_nctls)
2558 return ENXIO; 2558 return ENXIO;
2559 mc = &sc->sc_ctls[n]; 2559 mc = &sc->sc_ctls[n];
2560 2560
2561 if (mc->type == MIX_ON_OFF) { 2561 if (mc->type == MIX_ON_OFF) {
2562 if (cp->type != AUDIO_MIXER_ENUM) 2562 if (cp->type != AUDIO_MIXER_ENUM)
2563 return EINVAL; 2563 return EINVAL;
2564 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord); 2564 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2565 } else if (mc->type == MIX_SELECTOR) { 2565 } else if (mc->type == MIX_SELECTOR) {
2566 if (cp->type != AUDIO_MIXER_ENUM) 2566 if (cp->type != AUDIO_MIXER_ENUM)
2567 return EINVAL; 2567 return EINVAL;
2568 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord); 2568 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2569 } else { 2569 } else {
2570 if (cp->type != AUDIO_MIXER_VALUE) 2570 if (cp->type != AUDIO_MIXER_VALUE)
2571 return EINVAL; 2571 return EINVAL;
2572 if (cp->un.value.num_channels == 1) 2572 if (cp->un.value.num_channels == 1)
2573 for (i = 0; i < mc->nchan; i++) 2573 for (i = 0; i < mc->nchan; i++)
2574 vals[i] = cp->un.value.level[0]; 2574 vals[i] = cp->un.value.level[0];
2575 else if (cp->un.value.num_channels == mc->nchan) 2575 else if (cp->un.value.num_channels == mc->nchan)
2576 for (i = 0; i < mc->nchan; i++) 2576 for (i = 0; i < mc->nchan; i++)
2577 vals[i] = cp->un.value.level[i]; 2577 vals[i] = cp->un.value.level[i];
2578 else 2578 else
2579 return EINVAL; 2579 return EINVAL;
2580 for (i = 0; i < mc->nchan; i++) 2580 for (i = 0; i < mc->nchan; i++)
2581 uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]); 2581 uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
2582 } 2582 }
2583 return 0; 2583 return 0;
2584} 2584}
2585 2585
2586Static int 2586Static int
2587uaudio_trigger_input(void *addr, void *start, void *end, int blksize, 2587uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
2588 void (*intr)(void *), void *arg, 2588 void (*intr)(void *), void *arg,
2589 const audio_params_t *param) 2589 const audio_params_t *param)
2590{ 2590{
2591 struct uaudio_softc *sc; 2591 struct uaudio_softc *sc;
2592 struct chan *ch; 2592 struct chan *ch;
2593 usbd_status err; 2593 usbd_status err;
2594 int i; 2594 int i;
2595 2595
2596 sc = addr; 2596 sc = addr;
2597 if (sc->sc_dying) 2597 if (sc->sc_dying)
2598 return EIO; 2598 return EIO;
2599 2599
2600 DPRINTFN(3, "sc=%p start=%p end=%p " 2600 DPRINTFN(3, "sc=%p start=%p end=%p "
2601 "blksize=%d\n", sc, start, end, blksize); 2601 "blksize=%d\n", sc, start, end, blksize);
2602 ch = &sc->sc_recchan; 2602 ch = &sc->sc_recchan;
2603 uaudio_chan_set_param(ch, start, end, blksize); 2603 uaudio_chan_set_param(ch, start, end, blksize);
2604 DPRINTFN(3, "sample_size=%d bytes/frame=%d " 2604 DPRINTFN(3, "sample_size=%d bytes/frame=%d "
2605 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 2605 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2606 ch->fraction); 2606 ch->fraction);
2607 2607
2608 mutex_spin_exit(&sc->sc_intr_lock); 2608 mutex_spin_exit(&sc->sc_intr_lock);
2609 err = uaudio_chan_open(sc, ch); 2609 err = uaudio_chan_open(sc, ch);
2610 if (err) { 2610 if (err) {
2611 mutex_spin_enter(&sc->sc_intr_lock); 2611 mutex_spin_enter(&sc->sc_intr_lock);
2612 return EIO; 2612 return EIO;
2613 } 2613 }
2614 2614
2615 err = uaudio_chan_alloc_buffers(sc, ch); 2615 err = uaudio_chan_alloc_buffers(sc, ch);
2616 if (err) { 2616 if (err) {
2617 uaudio_chan_close(sc, ch); 2617 uaudio_chan_close(sc, ch);
2618 mutex_spin_enter(&sc->sc_intr_lock); 2618 mutex_spin_enter(&sc->sc_intr_lock);
2619 return EIO; 2619 return EIO;
2620 } 2620 }
2621 2621
2622 2622
2623 ch->intr = intr; 2623 ch->intr = intr;
2624 ch->arg = arg; 2624 ch->arg = arg;
2625 2625
2626 /* XXX -1 shouldn't be needed */ 2626 /* XXX -1 shouldn't be needed */
2627 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) { 2627 for (i = 0; i < UAUDIO_NCHANBUFS - 1; i++) {
2628 uaudio_chan_rtransfer(ch); 2628 uaudio_chan_rtransfer(ch);
2629 } 2629 }
2630 2630
2631 mutex_spin_enter(&sc->sc_intr_lock); 2631 mutex_spin_enter(&sc->sc_intr_lock);
2632 2632
2633 return 0; 2633 return 0;
2634} 2634}
2635 2635
2636Static int 2636Static int
2637uaudio_trigger_output(void *addr, void *start, void *end, int blksize, 2637uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
2638 void (*intr)(void *), void *arg, 2638 void (*intr)(void *), void *arg,
2639 const audio_params_t *param) 2639 const audio_params_t *param)
2640{ 2640{
2641 struct uaudio_softc *sc; 2641 struct uaudio_softc *sc;
2642 struct chan *ch; 2642 struct chan *ch;
2643 usbd_status err; 2643 usbd_status err;
2644 int i; 2644 int i;
2645 2645
2646 sc = addr; 2646 sc = addr;
2647 if (sc->sc_dying) 2647 if (sc->sc_dying)
2648 return EIO; 2648 return EIO;
2649 2649
2650 DPRINTFN(3, "sc=%p start=%p end=%p " 2650 DPRINTFN(3, "sc=%p start=%p end=%p "
2651 "blksize=%d\n", sc, start, end, blksize); 2651 "blksize=%d\n", sc, start, end, blksize);
2652 ch = &sc->sc_playchan; 2652 ch = &sc->sc_playchan;
2653 uaudio_chan_set_param(ch, start, end, blksize); 2653 uaudio_chan_set_param(ch, start, end, blksize);
2654 DPRINTFN(3, "sample_size=%d bytes/frame=%d " 2654 DPRINTFN(3, "sample_size=%d bytes/frame=%d "
2655 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 2655 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2656 ch->fraction); 2656 ch->fraction);
2657 2657
2658 mutex_spin_exit(&sc->sc_intr_lock); 2658 mutex_spin_exit(&sc->sc_intr_lock);
2659 err = uaudio_chan_open(sc, ch); 2659 err = uaudio_chan_open(sc, ch);
2660 if (err) { 2660 if (err) {
2661 mutex_spin_enter(&sc->sc_intr_lock); 2661 mutex_spin_enter(&sc->sc_intr_lock);
2662 return EIO; 2662 return EIO;
2663 } 2663 }
2664 2664
2665 err = uaudio_chan_alloc_buffers(sc, ch); 2665 err = uaudio_chan_alloc_buffers(sc, ch);
2666 if (err) { 2666 if (err) {
2667 uaudio_chan_close(sc, ch); 2667 uaudio_chan_close(sc, ch);
2668 mutex_spin_enter(&sc->sc_intr_lock); 2668 mutex_spin_enter(&sc->sc_intr_lock);
2669 return EIO; 2669 return EIO;
2670 } 2670 }
2671 2671
2672 ch->intr = intr; 2672 ch->intr = intr;
2673 ch->arg = arg; 2673 ch->arg = arg;
2674 2674
2675 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */ 2675 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
2676 uaudio_chan_ptransfer(ch); 2676 uaudio_chan_ptransfer(ch);
2677 mutex_spin_enter(&sc->sc_intr_lock); 2677 mutex_spin_enter(&sc->sc_intr_lock);
2678 2678
2679 return 0; 2679 return 0;
2680} 2680}
2681 2681
2682/* Set up a pipe for a channel. */ 2682/* Set up a pipe for a channel. */
2683Static usbd_status 2683Static usbd_status
2684uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch) 2684uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
2685{ 2685{
2686 struct as_info *as; 2686 struct as_info *as;
2687 usb_device_descriptor_t *ddesc; 2687 usb_device_descriptor_t *ddesc;
2688 int endpt; 2688 int endpt;
2689 usbd_status err; 2689 usbd_status err;
2690 2690
2691 as = &sc->sc_alts[ch->altidx]; 2691 as = &sc->sc_alts[ch->altidx];
2692 endpt = as->edesc->bEndpointAddress; 2692 endpt = as->edesc->bEndpointAddress;
2693 DPRINTF("endpt=0x%02x, speed=%d, alt=%d\n", 2693 DPRINTF("endpt=0x%02x, speed=%d, alt=%d\n",
2694 endpt, ch->sample_rate, as->alt); 2694 endpt, ch->sample_rate, as->alt);
2695 2695
2696 /* Set alternate interface corresponding to the mode. */ 2696 /* Set alternate interface corresponding to the mode. */
2697 err = usbd_set_interface(as->ifaceh, as->alt); 2697 err = usbd_set_interface(as->ifaceh, as->alt);
2698 if (err) 2698 if (err)
2699 return err; 2699 return err;
2700 2700
2701 /* 2701 /*
2702 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request. 2702 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request.
2703 */ 2703 */
2704 ddesc = usbd_get_device_descriptor(sc->sc_udev); 2704 ddesc = usbd_get_device_descriptor(sc->sc_udev);
2705 if ((UGETW(ddesc->idVendor) != USB_VENDOR_ROLAND) && 2705 if ((UGETW(ddesc->idVendor) != USB_VENDOR_ROLAND) &&
2706 (UGETW(ddesc->idProduct) != USB_PRODUCT_ROLAND_SD90)) { 2706 (UGETW(ddesc->idProduct) != USB_PRODUCT_ROLAND_SD90)) {
2707 err = uaudio_set_speed(sc, endpt, ch->sample_rate); 2707 err = uaudio_set_speed(sc, endpt, ch->sample_rate);
2708 if (err) { 2708 if (err) {
2709 DPRINTF("set_speed failed err=%s\n", usbd_errstr(err)); 2709 DPRINTF("set_speed failed err=%s\n", usbd_errstr(err));
2710 } 2710 }
2711 } 2711 }
2712 2712
2713 DPRINTF("create pipe to 0x%02x\n", endpt); 2713 DPRINTF("create pipe to 0x%02x\n", endpt);
2714 err = usbd_open_pipe(as->ifaceh, endpt, USBD_MPSAFE, &ch->pipe); 2714 err = usbd_open_pipe(as->ifaceh, endpt, USBD_MPSAFE, &ch->pipe);
2715 if (err) 2715 if (err)
2716 return err; 2716 return err;
2717 if (as->edesc1 != NULL) { 2717 if (as->edesc1 != NULL) {
2718 endpt = as->edesc1->bEndpointAddress; 2718 endpt = as->edesc1->bEndpointAddress;
2719 DPRINTF("create sync-pipe to 0x%02x\n", endpt); 2719 DPRINTF("create sync-pipe to 0x%02x\n", endpt);
2720 err = usbd_open_pipe(as->ifaceh, endpt, USBD_MPSAFE, 2720 err = usbd_open_pipe(as->ifaceh, endpt, USBD_MPSAFE,
2721 &ch->sync_pipe); 2721 &ch->sync_pipe);
2722 } 2722 }
2723 return err; 2723 return err;
2724} 2724}
2725 2725
2726Static void 2726Static void
2727uaudio_chan_abort(struct uaudio_softc *sc, struct chan *ch) 2727uaudio_chan_abort(struct uaudio_softc *sc, struct chan *ch)
2728{ 2728{
2729 struct usbd_pipe *pipe; 2729 struct usbd_pipe *pipe;
2730 struct as_info *as; 2730 struct as_info *as;
2731 2731
2732 as = &sc->sc_alts[ch->altidx]; 2732 as = &sc->sc_alts[ch->altidx];
2733 as->sc_busy = 0; 2733 as->sc_busy = 0;
2734 AUFMT_VALIDATE(as->aformat); 2734 AUFMT_VALIDATE(as->aformat);
2735 if (sc->sc_nullalt >= 0) { 2735 if (sc->sc_nullalt >= 0) {
2736 DPRINTF("set null alt=%d\n", sc->sc_nullalt); 2736 DPRINTF("set null alt=%d\n", sc->sc_nullalt);
2737 usbd_set_interface(as->ifaceh, sc->sc_nullalt); 2737 usbd_set_interface(as->ifaceh, sc->sc_nullalt);
2738 } 2738 }
2739 pipe = ch->pipe; 2739 pipe = ch->pipe;
2740 if (pipe) { 2740 if (pipe) {
2741 usbd_abort_pipe(pipe); 2741 usbd_abort_pipe(pipe);
2742 } 2742 }
2743 pipe = ch->sync_pipe; 2743 pipe = ch->sync_pipe;
2744 if (pipe) { 2744 if (pipe) {
2745 usbd_abort_pipe(pipe); 2745 usbd_abort_pipe(pipe);
2746 } 2746 }
2747} 2747}
2748 2748
2749Static void 2749Static void
2750uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch) 2750uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
2751{ 2751{
2752 struct usbd_pipe *pipe; 2752 struct usbd_pipe *pipe;
2753 2753
2754 pipe = atomic_swap_ptr(&ch->pipe, NULL); 2754 pipe = atomic_swap_ptr(&ch->pipe, NULL);
2755 if (pipe) { 2755 if (pipe) {
2756 usbd_close_pipe(pipe); 2756 usbd_close_pipe(pipe);
2757 } 2757 }
2758 pipe = atomic_swap_ptr(&ch->sync_pipe, NULL); 2758 pipe = atomic_swap_ptr(&ch->sync_pipe, NULL);
2759 if (pipe) { 2759 if (pipe) {
2760 usbd_close_pipe(pipe); 2760 usbd_close_pipe(pipe);
2761 } 2761 }
2762} 2762}
2763 2763
2764Static usbd_status 2764Static usbd_status
2765uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch) 2765uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
2766{ 2766{
2767 int i, size; 2767 int i, size;
2768 2768
2769 size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES; 2769 size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
2770 for (i = 0; i < UAUDIO_NCHANBUFS; i++) { 2770 for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
2771 struct usbd_xfer *xfer; 2771 struct usbd_xfer *xfer;
2772 2772
2773 int err = usbd_create_xfer(ch->pipe, size, 0, UAUDIO_NFRAMES, 2773 int err = usbd_create_xfer(ch->pipe, size, 0, UAUDIO_NFRAMES,
2774 &xfer); 2774 &xfer);
2775 if (err) 2775 if (err)
2776 goto bad; 2776 goto bad;
2777 2777
2778 ch->chanbufs[i].xfer = xfer; 2778 ch->chanbufs[i].xfer = xfer;
2779 ch->chanbufs[i].buffer = usbd_get_buffer(xfer); 2779 ch->chanbufs[i].buffer = usbd_get_buffer(xfer);
2780 ch->chanbufs[i].chan = ch; 2780 ch->chanbufs[i].chan = ch;
2781 } 2781 }
2782 2782
2783 return USBD_NORMAL_COMPLETION; 2783 return USBD_NORMAL_COMPLETION;
2784 2784
2785bad: 2785bad:
2786 while (--i >= 0) 2786 while (--i >= 0)
2787 /* implicit buffer free */ 2787 /* implicit buffer free */
2788 usbd_destroy_xfer(ch->chanbufs[i].xfer); 2788 usbd_destroy_xfer(ch->chanbufs[i].xfer);
2789 return USBD_NOMEM; 2789 return USBD_NOMEM;
2790} 2790}
2791 2791
2792Static void 2792Static void
2793uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch) 2793uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
2794{ 2794{
2795 int i; 2795 int i;
2796 2796
2797 for (i = 0; i < UAUDIO_NCHANBUFS; i++) 2797 for (i = 0; i < UAUDIO_NCHANBUFS; i++)
2798 usbd_destroy_xfer(ch->chanbufs[i].xfer); 2798 usbd_destroy_xfer(ch->chanbufs[i].xfer);
2799} 2799}
2800 2800
2801/* Called with USB lock held. */ 2801/* Called with USB lock held. */
2802Static void 2802Static void
2803uaudio_chan_ptransfer(struct chan *ch) 2803uaudio_chan_ptransfer(struct chan *ch)
2804{ 2804{
2805 struct chanbuf *cb; 2805 struct chanbuf *cb;
2806 int i, n, size, residue, total; 2806 int i, n, size, residue, total;
2807 2807
2808 if (ch->sc->sc_dying) 2808 if (ch->sc->sc_dying)
2809 return; 2809 return;
2810 2810
2811 /* Pick the next channel buffer. */ 2811 /* Pick the next channel buffer. */
2812 cb = &ch->chanbufs[ch->curchanbuf]; 2812 cb = &ch->chanbufs[ch->curchanbuf];
2813 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 2813 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2814 ch->curchanbuf = 0; 2814 ch->curchanbuf = 0;
2815 2815
2816 /* Compute the size of each frame in the next transfer. */ 2816 /* Compute the size of each frame in the next transfer. */
2817 residue = ch->residue; 2817 residue = ch->residue;
2818 total = 0; 2818 total = 0;
2819 for (i = 0; i < UAUDIO_NFRAMES; i++) { 2819 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2820 size = ch->bytes_per_frame; 2820 size = ch->bytes_per_frame;
2821 residue += ch->fraction; 2821 residue += ch->fraction;
2822 if (residue >= USB_FRAMES_PER_SECOND) { 2822 if (residue >= USB_FRAMES_PER_SECOND) {
2823 if ((ch->sc->sc_altflags & UA_NOFRAC) == 0) 2823 if ((ch->sc->sc_altflags & UA_NOFRAC) == 0)
2824 size += ch->sample_size; 2824 size += ch->sample_size;
2825 residue -= USB_FRAMES_PER_SECOND; 2825 residue -= USB_FRAMES_PER_SECOND;
2826 } 2826 }
2827 cb->sizes[i] = size; 2827 cb->sizes[i] = size;
2828 total += size; 2828 total += size;
2829 } 2829 }
2830 ch->residue = residue; 2830 ch->residue = residue;
2831 cb->size = total; 2831 cb->size = total;
2832 2832
2833 /* 2833 /*
2834 * Transfer data from upper layer buffer to channel buffer, taking 2834 * Transfer data from upper layer buffer to channel buffer, taking
2835 * care of wrapping the upper layer buffer. 2835 * care of wrapping the upper layer buffer.
2836 */ 2836 */
2837 n = min(total, ch->end - ch->cur); 2837 n = min(total, ch->end - ch->cur);
2838 memcpy(cb->buffer, ch->cur, n); 2838 memcpy(cb->buffer, ch->cur, n);
2839 ch->cur += n; 2839 ch->cur += n;
2840 if (ch->cur >= ch->end) 2840 if (ch->cur >= ch->end)
2841 ch->cur = ch->start; 2841 ch->cur = ch->start;
2842 if (total > n) { 2842 if (total > n) {
2843 total -= n; 2843 total -= n;
2844 memcpy(cb->buffer + n, ch->cur, total); 2844 memcpy(cb->buffer + n, ch->cur, total);
2845 ch->cur += total; 2845 ch->cur += total;
2846 } 2846 }
2847 2847
2848#ifdef UAUDIO_DEBUG 2848#ifdef UAUDIO_DEBUG
2849 if (uaudiodebug > 8) { 2849 if (uaudiodebug > 8) {
2850 DPRINTF("buffer=%p, residue=0.%03d\n", cb->buffer, ch->residue); 2850 DPRINTF("buffer=%p, residue=0.%03d\n", cb->buffer, ch->residue);
2851 for (i = 0; i < UAUDIO_NFRAMES; i++) { 2851 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2852 DPRINTF(" [%d] length %d\n", i, cb->sizes[i]); 2852 DPRINTF(" [%d] length %d\n", i, cb->sizes[i]);
2853 } 2853 }
2854 } 2854 }
2855#endif 2855#endif
2856 2856
2857 //DPRINTFN(5, "ptransfer xfer=%p\n", cb->xfer); 2857 //DPRINTFN(5, "ptransfer xfer=%p\n", cb->xfer);
2858 /* Fill the request */ 2858 /* Fill the request */
2859 usbd_setup_isoc_xfer(cb->xfer, cb, cb->sizes, UAUDIO_NFRAMES, 0, 2859 usbd_setup_isoc_xfer(cb->xfer, cb, cb->sizes, UAUDIO_NFRAMES, 0,
2860 uaudio_chan_pintr); 2860 uaudio_chan_pintr);
2861 2861
2862 (void)usbd_transfer(cb->xfer); 2862 (void)usbd_transfer(cb->xfer);
2863} 2863}
2864 2864
2865Static void 2865Static void
2866uaudio_chan_pintr(struct usbd_xfer *xfer, void *priv, 2866uaudio_chan_pintr(struct usbd_xfer *xfer, void *priv,
2867 usbd_status status) 2867 usbd_status status)
2868{ 2868{
2869 struct chanbuf *cb; 2869 struct chanbuf *cb;
2870 struct chan *ch; 2870 struct chan *ch;
2871 uint32_t count; 2871 uint32_t count;
2872 2872
2873 cb = priv; 2873 cb = priv;
2874 ch = cb->chan; 2874 ch = cb->chan;
2875 /* Return if we are aborting. */ 2875 /* Return if we are aborting. */
2876 if (status == USBD_CANCELLED) 2876 if (status == USBD_CANCELLED)
2877 return; 2877 return;
2878 2878
2879 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 2879 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2880 DPRINTFN(5, "count=%d, transferred=%d\n", 2880 DPRINTFN(5, "count=%d, transferred=%d\n",
2881 count, ch->transferred); 2881 count, ch->transferred);
2882#ifdef DIAGNOSTIC 2882#ifdef DIAGNOSTIC
2883 if (count != cb->size) { 2883 if (count != cb->size) {
2884 aprint_error("uaudio_chan_pintr: count(%d) != size(%d)\n", 2884 aprint_error("uaudio_chan_pintr: count(%d) != size(%d)\n",
2885 count, cb->size); 2885 count, cb->size);
2886 } 2886 }
2887#endif 2887#endif
2888 2888
2889 ch->transferred += cb->size; 2889 ch->transferred += cb->size;
2890 mutex_spin_enter(&ch->sc->sc_intr_lock); 2890 mutex_spin_enter(&ch->sc->sc_intr_lock);
2891 /* Call back to upper layer */ 2891 /* Call back to upper layer */
2892 while (ch->transferred >= ch->blksize) { 2892 while (ch->transferred >= ch->blksize) {
2893 ch->transferred -= ch->blksize; 2893 ch->transferred -= ch->blksize;
2894 DPRINTFN(5, "call %p(%p)\n", ch->intr, ch->arg); 2894 DPRINTFN(5, "call %p(%p)\n", ch->intr, ch->arg);
2895 ch->intr(ch->arg); 2895 ch->intr(ch->arg);
2896 } 2896 }
2897 mutex_spin_exit(&ch->sc->sc_intr_lock); 2897 mutex_spin_exit(&ch->sc->sc_intr_lock);
2898 2898
2899 /* start next transfer */ 2899 /* start next transfer */
2900 uaudio_chan_ptransfer(ch); 2900 uaudio_chan_ptransfer(ch);
2901} 2901}
2902 2902
2903/* Called with USB lock held. */ 2903/* Called with USB lock held. */
2904Static void 2904Static void
2905uaudio_chan_rtransfer(struct chan *ch) 2905uaudio_chan_rtransfer(struct chan *ch)
2906{ 2906{
2907 struct chanbuf *cb; 2907 struct chanbuf *cb;
2908 int i, size, residue, total; 2908 int i, size, residue, total;
2909 2909
2910 if (ch->sc->sc_dying) 2910 if (ch->sc->sc_dying)
2911 return; 2911 return;
2912 2912
2913 /* Pick the next channel buffer. */ 2913 /* Pick the next channel buffer. */
2914 cb = &ch->chanbufs[ch->curchanbuf]; 2914 cb = &ch->chanbufs[ch->curchanbuf];
2915 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 2915 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2916 ch->curchanbuf = 0; 2916 ch->curchanbuf = 0;
2917 2917
2918 /* Compute the size of each frame in the next transfer. */ 2918 /* Compute the size of each frame in the next transfer. */
2919 residue = ch->residue; 2919 residue = ch->residue;
2920 total = 0; 2920 total = 0;
2921 for (i = 0; i < UAUDIO_NFRAMES; i++) { 2921 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2922 size = ch->bytes_per_frame; 2922 size = ch->bytes_per_frame;
2923 cb->sizes[i] = size; 2923 cb->sizes[i] = size;
2924 cb->offsets[i] = total; 2924 cb->offsets[i] = total;
2925 total += size; 2925 total += size;
2926 } 2926 }
2927 ch->residue = residue; 2927 ch->residue = residue;
2928 cb->size = total; 2928 cb->size = total;
2929 2929
2930#ifdef UAUDIO_DEBUG 2930#ifdef UAUDIO_DEBUG
2931 if (uaudiodebug > 8) { 2931 if (uaudiodebug > 8) {
2932 DPRINTF("buffer=%p, residue=0.%03d\n", cb->buffer, ch->residue); 2932 DPRINTF("buffer=%p, residue=0.%03d\n", cb->buffer, ch->residue);
2933 for (i = 0; i < UAUDIO_NFRAMES; i++) { 2933 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2934 DPRINTF(" [%d] length %d\n", i, cb->sizes[i]); 2934 DPRINTF(" [%d] length %d\n", i, cb->sizes[i]);
2935 } 2935 }
2936 } 2936 }
2937#endif 2937#endif
2938 2938
2939 DPRINTFN(5, "transfer xfer=%p\n", cb->xfer); 2939 DPRINTFN(5, "transfer xfer=%p\n", cb->xfer);
2940 /* Fill the request */ 2940 /* Fill the request */
2941 usbd_setup_isoc_xfer(cb->xfer, cb, cb->sizes, UAUDIO_NFRAMES, 0, 2941 usbd_setup_isoc_xfer(cb->xfer, cb, cb->sizes, UAUDIO_NFRAMES, 0,
2942 uaudio_chan_rintr); 2942 uaudio_chan_rintr);
2943 2943
2944 (void)usbd_transfer(cb->xfer); 2944 (void)usbd_transfer(cb->xfer);
2945} 2945}
2946 2946
2947Static void 2947Static void
2948uaudio_chan_rintr(struct usbd_xfer *xfer, void *priv, 2948uaudio_chan_rintr(struct usbd_xfer *xfer, void *priv,
2949 usbd_status status) 2949 usbd_status status)
2950{ 2950{
2951 struct chanbuf *cb; 2951 struct chanbuf *cb;
2952 struct chan *ch; 2952 struct chan *ch;
2953 uint32_t count; 2953 uint32_t count;
2954 int i, n, frsize; 2954 int i, n, frsize;
2955 2955
2956 cb = priv; 2956 cb = priv;
2957 ch = cb->chan; 2957 ch = cb->chan;
2958 /* Return if we are aborting. */ 2958 /* Return if we are aborting. */
2959 if (status == USBD_CANCELLED) 2959 if (status == USBD_CANCELLED)
2960 return; 2960 return;
2961 2961
2962 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 2962 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2963 DPRINTFN(5, "count=%d, transferred=%d\n", count, ch->transferred); 2963 DPRINTFN(5, "count=%d, transferred=%d\n", count, ch->transferred);
2964 2964
2965 /* count < cb->size is normal for asynchronous source */ 2965 /* count < cb->size is normal for asynchronous source */
2966#ifdef DIAGNOSTIC 2966#ifdef DIAGNOSTIC
2967 if (count > cb->size) { 2967 if (count > cb->size) {
2968 aprint_error("uaudio_chan_rintr: count(%d) > size(%d)\n", 2968 aprint_error("uaudio_chan_rintr: count(%d) > size(%d)\n",
2969 count, cb->size); 2969 count, cb->size);
2970 } 2970 }
2971#endif 2971#endif
2972 2972
2973 /* 2973 /*
2974 * Transfer data from channel buffer to upper layer buffer, taking 2974 * Transfer data from channel buffer to upper layer buffer, taking
2975 * care of wrapping the upper layer buffer. 2975 * care of wrapping the upper layer buffer.
2976 */ 2976 */
2977 for (i = 0; i < UAUDIO_NFRAMES; i++) { 2977 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2978 frsize = cb->sizes[i]; 2978 frsize = cb->sizes[i];
2979 n = min(frsize, ch->end - ch->cur); 2979 n = min(frsize, ch->end - ch->cur);
2980 memcpy(ch->cur, cb->buffer + cb->offsets[i], n); 2980 memcpy(ch->cur, cb->buffer + cb->offsets[i], n);
2981 ch->cur += n; 2981 ch->cur += n;
2982 if (ch->cur >= ch->end) 2982 if (ch->cur >= ch->end)
2983 ch->cur = ch->start; 2983 ch->cur = ch->start;
2984 if (frsize > n) { 2984 if (frsize > n) {
2985 memcpy(ch->cur, cb->buffer + cb->offsets[i] + n, 2985 memcpy(ch->cur, cb->buffer + cb->offsets[i] + n,
2986 frsize - n); 2986 frsize - n);
2987 ch->cur += frsize - n; 2987 ch->cur += frsize - n;
2988 } 2988 }
2989 } 2989 }
2990 2990
2991 /* Call back to upper layer */ 2991 /* Call back to upper layer */
2992 ch->transferred += count; 2992 ch->transferred += count;
2993 mutex_spin_enter(&ch->sc->sc_intr_lock); 2993 mutex_spin_enter(&ch->sc->sc_intr_lock);
2994 while (ch->transferred >= ch->blksize) { 2994 while (ch->transferred >= ch->blksize) {
2995 ch->transferred -= ch->blksize; 2995 ch->transferred -= ch->blksize;
2996 DPRINTFN(5, "call %p(%p)\n", ch->intr, ch->arg); 2996 DPRINTFN(5, "call %p(%p)\n", ch->intr, ch->arg);
2997 ch->intr(ch->arg); 2997 ch->intr(ch->arg);
2998 } 2998 }
2999 mutex_spin_exit(&ch->sc->sc_intr_lock); 2999 mutex_spin_exit(&ch->sc->sc_intr_lock);
3000 3000
3001 /* start next transfer */ 3001 /* start next transfer */
3002 uaudio_chan_rtransfer(ch); 3002 uaudio_chan_rtransfer(ch);
3003} 3003}
3004 3004
3005Static void 3005Static void
3006uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param, 3006uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param,
3007 int maxpktsize) 3007 int maxpktsize)
3008{ 3008{
3009 int samples_per_frame, sample_size; 3009 int samples_per_frame, sample_size;
3010 3010
3011 ch->altidx = altidx; 3011 ch->altidx = altidx;
3012 sample_size = param->precision * param->channels / 8; 3012 sample_size = param->precision * param->channels / 8;
3013 samples_per_frame = param->sample_rate / USB_FRAMES_PER_SECOND; 3013 samples_per_frame = param->sample_rate / USB_FRAMES_PER_SECOND;
3014 ch->sample_size = sample_size; 3014 ch->sample_size = sample_size;
3015 ch->sample_rate = param->sample_rate; 3015 ch->sample_rate = param->sample_rate;
3016 if (maxpktsize == 0) { 3016 if (maxpktsize == 0) {
3017 ch->fraction = param->sample_rate % USB_FRAMES_PER_SECOND; 3017 ch->fraction = param->sample_rate % USB_FRAMES_PER_SECOND;
3018 ch->bytes_per_frame = samples_per_frame * sample_size; 3018 ch->bytes_per_frame = samples_per_frame * sample_size;
3019 } else { 3019 } else {
3020 ch->fraction = 0; 3020 ch->fraction = 0;
3021 ch->bytes_per_frame = maxpktsize; 3021 ch->bytes_per_frame = maxpktsize;
3022 } 3022 }
3023 ch->residue = 0; 3023 ch->residue = 0;
3024} 3024}
3025 3025
3026Static void 3026Static void
3027uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize) 3027uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize)
3028{ 3028{
3029 3029
3030 ch->start = start; 3030 ch->start = start;
3031 ch->end = end; 3031 ch->end = end;
3032 ch->cur = start; 3032 ch->cur = start;
3033 ch->blksize = blksize; 3033 ch->blksize = blksize;
3034 ch->transferred = 0; 3034 ch->transferred = 0;
3035 ch->curchanbuf = 0; 3035 ch->curchanbuf = 0;
3036} 3036}
3037 3037
3038Static int 3038Static int
3039uaudio_set_params(void *addr, int setmode, int usemode, 3039uaudio_set_params(void *addr, int setmode, int usemode,
3040 struct audio_params *play, struct audio_params *rec, 3040 struct audio_params *play, struct audio_params *rec,
3041 stream_filter_list_t *pfil, stream_filter_list_t *rfil) 3041 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
3042{ 3042{
3043 struct uaudio_softc *sc; 3043 struct uaudio_softc *sc;
3044 int paltidx, raltidx; 3044 int paltidx, raltidx;
3045 struct audio_params *p; 3045 struct audio_params *p;
3046 stream_filter_list_t *fil; 3046 stream_filter_list_t *fil;
3047 int mode, i; 3047 int mode, i;
3048 3048
3049 sc = addr; 3049 sc = addr;
3050 paltidx = -1; 3050 paltidx = -1;
3051 raltidx = -1; 3051 raltidx = -1;
3052 if (sc->sc_dying) 3052 if (sc->sc_dying)
3053 return EIO; 3053 return EIO;
3054 3054
3055 if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) || 3055 if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) ||
3056 ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL)) 3056 ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL))
3057 return EBUSY; 3057 return EBUSY;
3058 3058
3059 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) { 3059 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) {
3060 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0; 3060 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0;
3061 AUFMT_VALIDATE(sc->sc_alts[sc->sc_playchan.altidx].aformat); 3061 AUFMT_VALIDATE(sc->sc_alts[sc->sc_playchan.altidx].aformat);
3062 } 3062 }
3063 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) { 3063 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) {
3064 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0; 3064 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0;
3065 AUFMT_VALIDATE(sc->sc_alts[sc->sc_recchan.altidx].aformat); 3065 AUFMT_VALIDATE(sc->sc_alts[sc->sc_recchan.altidx].aformat);
3066 } 3066 }
3067 3067
3068 /* Some uaudio devices are unidirectional. Don't try to find a 3068 /* Some uaudio devices are unidirectional. Don't try to find a
3069 matching mode for the unsupported direction. */ 3069 matching mode for the unsupported direction. */
3070 setmode &= sc->sc_mode; 3070 setmode &= sc->sc_mode;
3071 3071
3072 for (mode = AUMODE_RECORD; mode != -1; 3072 for (mode = AUMODE_RECORD; mode != -1;
3073 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 3073 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
3074 if ((setmode & mode) == 0) 3074 if ((setmode & mode) == 0)
3075 continue; 3075 continue;
3076 3076
3077 if (mode == AUMODE_PLAY) { 3077 if (mode == AUMODE_PLAY) {
3078 p = play; 3078 p = play;
3079 fil = pfil; 3079 fil = pfil;
3080 } else { 3080 } else {
3081 p = rec; 3081 p = rec;
3082 fil = rfil; 3082 fil = rfil;
3083 } 3083 }
3084 i = auconv_set_converter(sc->sc_formats, sc->sc_nformats, 3084 i = auconv_set_converter(sc->sc_formats, sc->sc_nformats,
3085 mode, p, TRUE, fil); 3085 mode, p, TRUE, fil);
3086 if (i < 0) 3086 if (i < 0)
3087 return EINVAL; 3087 return EINVAL;
3088 3088
3089 if (mode == AUMODE_PLAY) 3089 if (mode == AUMODE_PLAY)
3090 paltidx = i; 3090 paltidx = i;
3091 else 3091 else
3092 raltidx = i; 3092 raltidx = i;
3093 } 3093 }
3094 3094
3095 if ((setmode & AUMODE_PLAY)) { 3095 if ((setmode & AUMODE_PLAY)) {
3096 p = pfil->req_size > 0 ? &pfil->filters[0].param : play; 3096 p = pfil->req_size > 0 ? &pfil->filters[0].param : play;
3097 /* XXX abort transfer if currently happening? */ 3097 /* XXX abort transfer if currently happening? */
3098 uaudio_chan_init(&sc->sc_playchan, paltidx, p, 0); 3098 uaudio_chan_init(&sc->sc_playchan, paltidx, p, 0);
3099 } 3099 }
3100 if ((setmode & AUMODE_RECORD)) { 3100 if ((setmode & AUMODE_RECORD)) {
3101 p = rfil->req_size > 0 ? &rfil->filters[0].param : rec; 3101 p = rfil->req_size > 0 ? &rfil->filters[0].param : rec;
3102 /* XXX abort transfer if currently happening? */ 3102 /* XXX abort transfer if currently happening? */
3103 uaudio_chan_init(&sc->sc_recchan, raltidx, p, 3103 uaudio_chan_init(&sc->sc_recchan, raltidx, p,
3104 UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize)); 3104 UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize));
3105 } 3105 }
3106 3106
3107 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) { 3107 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) {
3108 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1; 3108 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1;
3109 AUFMT_INVALIDATE(sc->sc_alts[sc->sc_playchan.altidx].aformat); 3109 AUFMT_INVALIDATE(sc->sc_alts[sc->sc_playchan.altidx].aformat);
3110 } 3110 }
3111 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) { 3111 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) {
3112 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1; 3112 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1;
3113 AUFMT_INVALIDATE(sc->sc_alts[sc->sc_recchan.altidx].aformat); 3113 AUFMT_INVALIDATE(sc->sc_alts[sc->sc_recchan.altidx].aformat);
3114 } 3114 }
3115 3115
3116 DPRINTF("use altidx=p%d/r%d, altno=p%d/r%d\n", 3116 DPRINTF("use altidx=p%d/r%d, altno=p%d/r%d\n",
3117 sc->sc_playchan.altidx, sc->sc_recchan.altidx, 3117 sc->sc_playchan.altidx, sc->sc_recchan.altidx,
3118 (sc->sc_playchan.altidx >= 0) 3118 (sc->sc_playchan.altidx >= 0)
3119 ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting 3119 ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting
3120 : -1, 3120 : -1,
3121 (sc->sc_recchan.altidx >= 0) 3121 (sc->sc_recchan.altidx >= 0)
3122 ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting 3122 ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting
3123 : -1); 3123 : -1);
3124 3124
3125 return 0; 3125 return 0;
3126} 3126}
3127 3127
3128Static usbd_status 3128Static usbd_status
3129uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed) 3129uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
3130{ 3130{
3131 usb_device_request_t req; 3131 usb_device_request_t req;
3132 usbd_status err; 3132 usbd_status err;
3133 uint8_t data[3]; 3133 uint8_t data[3];
3134 3134
3135 DPRINTFN(5, "endpt=%d speed=%u\n", endpt, speed); 3135 DPRINTFN(5, "endpt=%d speed=%u\n", endpt, speed);
3136 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT; 3136 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
3137 req.bRequest = SET_CUR; 3137 req.bRequest = SET_CUR;
3138 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0); 3138 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
3139 USETW(req.wIndex, endpt); 3139 USETW(req.wIndex, endpt);
3140 USETW(req.wLength, 3); 3140 USETW(req.wLength, 3);
3141 data[0] = speed; 3141 data[0] = speed;
3142 data[1] = speed >> 8; 3142 data[1] = speed >> 8;
3143 data[2] = speed >> 16; 3143 data[2] = speed >> 16;
3144 3144
3145 err = usbd_do_request(sc->sc_udev, &req, data); 3145 err = usbd_do_request(sc->sc_udev, &req, data);
3146 3146
3147 return err; 3147 return err;
3148} 3148}
3149 3149
3150#ifdef _MODULE 3150#ifdef _MODULE
3151 3151
3152MODULE(MODULE_CLASS_DRIVER, uaudio, NULL); 3152MODULE(MODULE_CLASS_DRIVER, uaudio, NULL);
3153 3153
3154static const struct cfiattrdata audiobuscf_iattrdata = { 3154static const struct cfiattrdata audiobuscf_iattrdata = {
3155 "audiobus", 0, { { NULL, NULL, 0 }, } 3155 "audiobus", 0, { { NULL, NULL, 0 }, }
3156}; 3156};
3157static const struct cfiattrdata * const uaudio_attrs[] = { 3157static const struct cfiattrdata * const uaudio_attrs[] = {
3158 &audiobuscf_iattrdata, NULL 3158 &audiobuscf_iattrdata, NULL
3159}; 3159};
3160CFDRIVER_DECL(uaudio, DV_DULL, uaudio_attrs); 3160CFDRIVER_DECL(uaudio, DV_DULL, uaudio_attrs);
3161extern struct cfattach uaudio_ca; 3161extern struct cfattach uaudio_ca;
3162static int uaudioloc[6/*USBIFIFCF_NLOCS*/] = { 3162static int uaudioloc[6/*USBIFIFCF_NLOCS*/] = {
3163 -1/*USBIFIFCF_PORT_DEFAULT*/, 3163 -1/*USBIFIFCF_PORT_DEFAULT*/,
3164 -1/*USBIFIFCF_CONFIGURATION_DEFAULT*/, 3164 -1/*USBIFIFCF_CONFIGURATION_DEFAULT*/,
3165 -1/*USBIFIFCF_INTERFACE_DEFAULT*/, 3165 -1/*USBIFIFCF_INTERFACE_DEFAULT*/,
3166 -1/*USBIFIFCF_VENDOR_DEFAULT*/, 3166 -1/*USBIFIFCF_VENDOR_DEFAULT*/,
3167 -1/*USBIFIFCF_PRODUCT_DEFAULT*/, 3167 -1/*USBIFIFCF_PRODUCT_DEFAULT*/,
3168 -1/*USBIFIFCF_RELEASE_DEFAULT*/}; 3168 -1/*USBIFIFCF_RELEASE_DEFAULT*/};
3169static struct cfparent uhubparent = { 3169static struct cfparent uhubparent = {
3170 "usbifif", NULL, DVUNIT_ANY 3170 "usbifif", NULL, DVUNIT_ANY
3171}; 3171};
3172static struct cfdata uaudio_cfdata[] = { 3172static struct cfdata uaudio_cfdata[] = {
3173 { 3173 {
3174 .cf_name = "uaudio", 3174 .cf_name = "uaudio",
3175 .cf_atname = "uaudio", 3175 .cf_atname = "uaudio",
3176 .cf_unit = 0, 3176 .cf_unit = 0,
3177 .cf_fstate = FSTATE_STAR, 3177 .cf_fstate = FSTATE_STAR,
3178 .cf_loc = uaudioloc, 3178 .cf_loc = uaudioloc,
3179 .cf_flags = 0, 3179 .cf_flags = 0,
3180 .cf_pspec = &uhubparent, 3180 .cf_pspec = &uhubparent,
3181 }, 3181 },
3182 { NULL } 3182 { NULL }
3183}; 3183};
3184 3184
3185static int 3185static int
3186uaudio_modcmd(modcmd_t cmd, void *arg) 3186uaudio_modcmd(modcmd_t cmd, void *arg)
3187{ 3187{
3188 int err; 3188 int err;
3189 3189
3190 switch (cmd) { 3190 switch (cmd) {
3191 case MODULE_CMD_INIT: 3191 case MODULE_CMD_INIT:
3192 err = config_cfdriver_attach(&uaudio_cd); 3192 err = config_cfdriver_attach(&uaudio_cd);
3193 if (err) { 3193 if (err) {
3194 return err; 3194 return err;
3195 } 3195 }
3196 err = config_cfattach_attach("uaudio", &uaudio_ca); 3196 err = config_cfattach_attach("uaudio", &uaudio_ca);
3197 if (err) { 3197 if (err) {
3198 config_cfdriver_detach(&uaudio_cd); 3198 config_cfdriver_detach(&uaudio_cd);
3199 return err; 3199 return err;
3200 } 3200 }
3201 err = config_cfdata_attach(uaudio_cfdata, 1); 3201 err = config_cfdata_attach(uaudio_cfdata, 1);
3202 if (err) { 3202 if (err) {
3203 config_cfattach_detach("uaudio", &uaudio_ca); 3203 config_cfattach_detach("uaudio", &uaudio_ca);
3204 config_cfdriver_detach(&uaudio_cd); 3204 config_cfdriver_detach(&uaudio_cd);
3205 return err; 3205 return err;
3206 } 3206 }
3207 return 0; 3207 return 0;
3208 case MODULE_CMD_FINI: 3208 case MODULE_CMD_FINI:
3209 err = config_cfdata_detach(uaudio_cfdata); 3209 err = config_cfdata_detach(uaudio_cfdata);
3210 if (err) 3210 if (err)
3211 return err; 3211 return err;
3212 config_cfattach_detach("uaudio", &uaudio_ca); 3212 config_cfattach_detach("uaudio", &uaudio_ca);
3213 config_cfdriver_detach(&uaudio_cd); 3213 config_cfdriver_detach(&uaudio_cd);
3214 return 0; 3214 return 0;
3215 default: 3215 default:
3216 return ENOTTY; 3216 return ENOTTY;
3217 } 3217 }
3218} 3218}
3219 3219
3220#endif 3220#endif