xref: /freebsd/sys/dev/sound/usb/uaudio.c (revision 6af83ee0d2941d18880b6aaa2b4facd1d30c6106)
1 /*	$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $	*/
2 /*	$FreeBSD$ */
3 
4 /*-
5  * Copyright (c) 1999 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Lennart Augustsson (lennart@augustsson.net) at
10  * Carlstedt Research & Technology.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *        This product includes software developed by the NetBSD
23  *        Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*
42  * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
43  *                  http://www.usb.org/developers/devclass_docs/frmts10.pdf
44  *                  http://www.usb.org/developers/devclass_docs/termt10.pdf
45  */
46 
47 #include <sys/cdefs.h>
48 #if defined(__NetBSD__) || defined(__OpenBSD__)
49 __KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $");
50 #endif
51 
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/kernel.h>
55 #include <sys/malloc.h>
56 #if defined(__NetBSD__) || defined(__OpenBSD__)
57 #include <sys/device.h>
58 #include <sys/ioctl.h>
59 #endif
60 #include <sys/tty.h>
61 #include <sys/file.h>
62 #include <sys/reboot.h>		/* for bootverbose */
63 #include <sys/select.h>
64 #include <sys/proc.h>
65 #if defined(__NetBSD__) || defined(__OpenBSD__)
66 #include <sys/device.h>
67 #elif defined(__FreeBSD__)
68 #include <sys/module.h>
69 #include <sys/bus.h>
70 #include <sys/conf.h>
71 #endif
72 #include <sys/poll.h>
73 #if defined(__FreeBSD__)
74 #include <sys/sysctl.h>
75 #endif
76 
77 #if defined(__NetBSD__) || defined(__OpenBSD__)
78 #include <sys/audioio.h>
79 #include <dev/audio_if.h>
80 #include <dev/audiovar.h>
81 #include <dev/mulaw.h>
82 #include <dev/auconv.h>
83 #elif defined(__FreeBSD__)
84 #include <dev/sound/pcm/sound.h>	/* XXXXX */
85 #include <dev/sound/chip.h>
86 #endif
87 
88 #include <dev/usb/usb.h>
89 #include <dev/usb/usbdi.h>
90 #include <dev/usb/usbdi_util.h>
91 #include <dev/usb/usb_quirks.h>
92 
93 #if defined(__NetBSD__) || defined(__OpenBSD__)
94 #include <dev/usb/uaudioreg.h>
95 #elif defined(__FreeBSD__)
96 #include <dev/sound/usb/uaudioreg.h>
97 #include <dev/sound/usb/uaudio.h>
98 #endif
99 
100 #if defined(__NetBSD__) || defined(__OpenBSD__)
101 /* #define UAUDIO_DEBUG */
102 #else
103 /* #define USB_DEBUG */
104 #endif
105 /* #define UAUDIO_MULTIPLE_ENDPOINTS */
106 #ifdef USB_DEBUG
107 #define DPRINTF(x)	do { if (uaudiodebug) logprintf x; } while (0)
108 #define DPRINTFN(n,x)	do { if (uaudiodebug>(n)) logprintf x; } while (0)
109 int	uaudiodebug = 0;
110 #if defined(__FreeBSD__)
111 SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
112 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW,
113 	   &uaudiodebug, 0, "uaudio debug level");
114 #endif
115 #else
116 #define DPRINTF(x)
117 #define DPRINTFN(n,x)
118 #endif
119 
120 #define UAUDIO_NCHANBUFS 6	/* number of outstanding request */
121 #if defined(__NetBSD__) || defined(__OpenBSD__)
122 #define UAUDIO_NFRAMES   10	/* ms of sound in each request */
123 #elif defined(__FreeBSD__)
124 #define UAUDIO_NFRAMES   20	/* ms of sound in each request */
125 #endif
126 
127 
128 #define MIX_MAX_CHAN 8
129 struct mixerctl {
130 	u_int16_t	wValue[MIX_MAX_CHAN]; /* using nchan */
131 	u_int16_t	wIndex;
132 	u_int8_t	nchan;
133 	u_int8_t	type;
134 #define MIX_ON_OFF	1
135 #define MIX_SIGNED_16	2
136 #define MIX_UNSIGNED_16	3
137 #define MIX_SIGNED_8	4
138 #define MIX_SELECTOR	5
139 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
140 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
141 	int		minval, maxval;
142 	u_int		delta;
143 	u_int		mul;
144 #if defined(__FreeBSD__) /* XXXXX */
145 	unsigned	ctl;
146 #define MAX_SELECTOR_INPUT_PIN 256
147 	u_int8_t	slctrtype[MAX_SELECTOR_INPUT_PIN];
148 #endif
149 	u_int8_t	class;
150 #if !defined(__FreeBSD__)
151 	char		ctlname[MAX_AUDIO_DEV_LEN];
152 	char		*ctlunit;
153 #endif
154 };
155 #define MAKE(h,l) (((h) << 8) | (l))
156 
157 struct as_info {
158 	u_int8_t	alt;
159 	u_int8_t	encoding;
160 	u_int8_t	attributes; /* Copy of bmAttributes of
161 				     * usb_audio_streaming_endpoint_descriptor
162 				     */
163 	usbd_interface_handle	ifaceh;
164 	const usb_interface_descriptor_t *idesc;
165 	const usb_endpoint_descriptor_audio_t *edesc;
166 	const usb_endpoint_descriptor_audio_t *edesc1;
167 	const struct usb_audio_streaming_type1_descriptor *asf1desc;
168 	int		sc_busy;	/* currently used */
169 };
170 
171 struct chan {
172 #if defined(__NetBSD__) || defined(__OpenBSD__)
173 	void	(*intr)(void *);	/* DMA completion intr handler */
174 	void	*arg;		/* arg for intr() */
175 #else
176 	struct pcm_channel *pcm_ch;
177 #endif
178 	usbd_pipe_handle pipe;
179 	usbd_pipe_handle sync_pipe;
180 
181 	u_int	sample_size;
182 	u_int	sample_rate;
183 	u_int	bytes_per_frame;
184 	u_int	fraction;	/* fraction/1000 is the extra samples/frame */
185 	u_int	residue;	/* accumulates the fractional samples */
186 
187 	u_char	*start;		/* upper layer buffer start */
188 	u_char	*end;		/* upper layer buffer end */
189 	u_char	*cur;		/* current position in upper layer buffer */
190 	int	blksize;	/* chunk size to report up */
191 	int	transferred;	/* transferred bytes not reported up */
192 
193 	int	altidx;		/* currently used altidx */
194 
195 	int	curchanbuf;
196 	struct chanbuf {
197 		struct chan	*chan;
198 		usbd_xfer_handle xfer;
199 		u_char		*buffer;
200 		u_int16_t	sizes[UAUDIO_NFRAMES];
201 		u_int16_t	offsets[UAUDIO_NFRAMES];
202 		u_int16_t	size;
203 	} chanbufs[UAUDIO_NCHANBUFS];
204 
205 	struct uaudio_softc *sc; /* our softc */
206 #if defined(__FreeBSD__)
207 	u_int32_t format;
208 	int	precision;
209 	int	channels;
210 #endif
211 };
212 
213 struct uaudio_softc {
214 	USBBASEDEVICE	sc_dev;		/* base device */
215 	usbd_device_handle sc_udev;	/* USB device */
216 	int		sc_ac_iface;	/* Audio Control interface */
217 	usbd_interface_handle	sc_ac_ifaceh;
218 	struct chan	sc_playchan;	/* play channel */
219 	struct chan	sc_recchan;	/* record channel */
220 	int		sc_nullalt;
221 	int		sc_audio_rev;
222 	struct as_info	*sc_alts;	/* alternate settings */
223 	int		sc_nalts;	/* # of alternate settings */
224 	int		sc_altflags;
225 #define HAS_8		0x01
226 #define HAS_16		0x02
227 #define HAS_8U		0x04
228 #define HAS_ALAW	0x08
229 #define HAS_MULAW	0x10
230 #define UA_NOFRAC	0x20		/* don't do sample rate adjustment */
231 #define HAS_24		0x40
232 	int		sc_mode;	/* play/record capability */
233 	struct mixerctl *sc_ctls;	/* mixer controls */
234 	int		sc_nctls;	/* # of mixer controls */
235 	device_ptr_t	sc_audiodev;
236 	char		sc_dying;
237 };
238 
239 struct terminal_list {
240 	int size;
241 	uint16_t terminals[1];
242 };
243 #define TERMINAL_LIST_SIZE(N)	(offsetof(struct terminal_list, terminals) \
244 				+ sizeof(uint16_t) * (N))
245 
246 struct io_terminal {
247 	union {
248 		const usb_descriptor_t *desc;
249 		const struct usb_audio_input_terminal *it;
250 		const struct usb_audio_output_terminal *ot;
251 		const struct usb_audio_mixer_unit *mu;
252 		const struct usb_audio_selector_unit *su;
253 		const struct usb_audio_feature_unit *fu;
254 		const struct usb_audio_processing_unit *pu;
255 		const struct usb_audio_extension_unit *eu;
256 	} d;
257 	int inputs_size;
258 	struct terminal_list **inputs; /* list of source input terminals */
259 	struct terminal_list *output; /* list of destination output terminals */
260 	int direct;		/* directly connected to an output terminal */
261 };
262 
263 #define UAC_OUTPUT	0
264 #define UAC_INPUT	1
265 #define UAC_EQUAL	2
266 #define UAC_RECORD	3
267 #define UAC_NCLASSES	4
268 #ifdef USB_DEBUG
269 #if defined(__FreeBSD__)
270 #define AudioCinputs	"inputs"
271 #define AudioCoutputs	"outputs"
272 #define AudioCrecord	"record"
273 #define AudioCequalization	"equalization"
274 #endif
275 Static const char *uac_names[] = {
276 	AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
277 };
278 #endif
279 
280 Static usbd_status uaudio_identify_ac
281 	(struct uaudio_softc *, const usb_config_descriptor_t *);
282 Static usbd_status uaudio_identify_as
283 	(struct uaudio_softc *, const usb_config_descriptor_t *);
284 Static usbd_status uaudio_process_as
285 	(struct uaudio_softc *, const char *, int *, int,
286 	 const usb_interface_descriptor_t *);
287 
288 Static void	uaudio_add_alt(struct uaudio_softc *, const struct as_info *);
289 
290 Static const usb_interface_descriptor_t *uaudio_find_iface
291 	(const char *, int, int *, int);
292 
293 Static void	uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
294 
295 #if defined(__NetBSD__) || defined(__OpenBSD__)
296 Static char	*uaudio_id_name
297 	(struct uaudio_softc *, const struct io_terminal *, int);
298 #endif
299 
300 #ifdef USB_DEBUG
301 Static void	uaudio_dump_cluster(const struct usb_audio_cluster *);
302 #endif
303 Static struct usb_audio_cluster uaudio_get_cluster
304 	(int, const struct io_terminal *);
305 Static void	uaudio_add_input
306 	(struct uaudio_softc *, const struct io_terminal *, int);
307 Static void	uaudio_add_output
308 	(struct uaudio_softc *, const struct io_terminal *, int);
309 Static void	uaudio_add_mixer
310 	(struct uaudio_softc *, const struct io_terminal *, int);
311 Static void	uaudio_add_selector
312 	(struct uaudio_softc *, const struct io_terminal *, int);
313 #ifdef USB_DEBUG
314 Static const char *uaudio_get_terminal_name(int);
315 #endif
316 Static int	uaudio_determine_class
317 	(const struct io_terminal *, struct mixerctl *);
318 #if defined(__FreeBSD__)
319 Static const int uaudio_feature_name(const struct io_terminal *,
320 		    struct mixerctl *);
321 #else
322 Static const char *uaudio_feature_name
323 	(const struct io_terminal *, struct mixerctl *);
324 #endif
325 Static void	uaudio_add_feature
326 	(struct uaudio_softc *, const struct io_terminal *, int);
327 Static void	uaudio_add_processing_updown
328 	(struct uaudio_softc *, const struct io_terminal *, int);
329 Static void	uaudio_add_processing
330 	(struct uaudio_softc *, const struct io_terminal *, int);
331 Static void	uaudio_add_extension
332 	(struct uaudio_softc *, const struct io_terminal *, int);
333 Static struct terminal_list *uaudio_merge_terminal_list
334 	(const struct io_terminal *);
335 Static struct terminal_list *uaudio_io_terminaltype
336 	(int, struct io_terminal *, int);
337 Static usbd_status uaudio_identify
338 	(struct uaudio_softc *, const usb_config_descriptor_t *);
339 
340 Static int	uaudio_signext(int, int);
341 #if defined(__NetBSD__) || defined(__OpenBSD__)
342 Static int	uaudio_value2bsd(struct mixerctl *, int);
343 #endif
344 Static int	uaudio_bsd2value(struct mixerctl *, int);
345 Static int	uaudio_get(struct uaudio_softc *, int, int, int, int, int);
346 #if defined(__NetBSD__) || defined(__OpenBSD__)
347 Static int	uaudio_ctl_get
348 	(struct uaudio_softc *, int, struct mixerctl *, int);
349 #endif
350 Static void	uaudio_set
351 	(struct uaudio_softc *, int, int, int, int, int, int);
352 Static void	uaudio_ctl_set
353 	(struct uaudio_softc *, int, struct mixerctl *, int, int);
354 
355 Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
356 
357 Static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
358 Static void	uaudio_chan_close(struct uaudio_softc *, struct chan *);
359 Static usbd_status uaudio_chan_alloc_buffers
360 	(struct uaudio_softc *, struct chan *);
361 Static void	uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
362 
363 #if defined(__NetBSD__) || defined(__OpenBSD__)
364 Static void	uaudio_chan_init
365 	(struct chan *, int, const struct audio_params *, int);
366 Static void	uaudio_chan_set_param(struct chan *, u_char *, u_char *, int);
367 #endif
368 
369 Static void	uaudio_chan_ptransfer(struct chan *);
370 Static void	uaudio_chan_pintr
371 	(usbd_xfer_handle, usbd_private_handle, usbd_status);
372 
373 Static void	uaudio_chan_rtransfer(struct chan *);
374 Static void	uaudio_chan_rintr
375 	(usbd_xfer_handle, usbd_private_handle, usbd_status);
376 
377 #if defined(__NetBSD__) || defined(__OpenBSD__)
378 Static int	uaudio_open(void *, int);
379 Static void	uaudio_close(void *);
380 Static int	uaudio_drain(void *);
381 Static int	uaudio_query_encoding(void *, struct audio_encoding *);
382 Static void	uaudio_get_minmax_rates
383 	(int, const struct as_info *, const struct audio_params *,
384 	 int, u_long *, u_long *);
385 Static int	uaudio_match_alt_sub
386 	(int, const struct as_info *, const struct audio_params *, int, u_long);
387 Static int	uaudio_match_alt_chan
388 	(int, const struct as_info *, struct audio_params *, int);
389 Static int	uaudio_match_alt
390 	(int, const struct as_info *, struct audio_params *, int);
391 Static int	uaudio_set_params
392 	(void *, int, int, struct audio_params *, struct audio_params *);
393 Static int	uaudio_round_blocksize(void *, int);
394 Static int	uaudio_trigger_output
395 	(void *, void *, void *, int, void (*)(void *), void *,
396 	 struct audio_params *);
397 Static int	uaudio_trigger_input
398 	(void *, void *, void *, int, void (*)(void *), void *,
399 	 struct audio_params *);
400 Static int	uaudio_halt_in_dma(void *);
401 Static int	uaudio_halt_out_dma(void *);
402 Static int	uaudio_getdev(void *, struct audio_device *);
403 Static int	uaudio_mixer_set_port(void *, mixer_ctrl_t *);
404 Static int	uaudio_mixer_get_port(void *, mixer_ctrl_t *);
405 Static int	uaudio_query_devinfo(void *, mixer_devinfo_t *);
406 Static int	uaudio_get_props(void *);
407 
408 Static const struct audio_hw_if uaudio_hw_if = {
409 	uaudio_open,
410 	uaudio_close,
411 	uaudio_drain,
412 	uaudio_query_encoding,
413 	uaudio_set_params,
414 	uaudio_round_blocksize,
415 	NULL,
416 	NULL,
417 	NULL,
418 	NULL,
419 	NULL,
420 	uaudio_halt_out_dma,
421 	uaudio_halt_in_dma,
422 	NULL,
423 	uaudio_getdev,
424 	NULL,
425 	uaudio_mixer_set_port,
426 	uaudio_mixer_get_port,
427 	uaudio_query_devinfo,
428 	NULL,
429 	NULL,
430 	NULL,
431 	NULL,
432 	uaudio_get_props,
433 	uaudio_trigger_output,
434 	uaudio_trigger_input,
435 	NULL,
436 };
437 
438 Static struct audio_device uaudio_device = {
439 	"USB audio",
440 	"",
441 	"uaudio"
442 };
443 
444 #elif defined(__FreeBSD__)
445 Static int	audio_attach_mi(device_t);
446 Static int	uaudio_init_params(struct uaudio_softc * sc, struct chan *ch, int mode);
447 
448 /* for NetBSD compatibirity */
449 #define	AUMODE_PLAY	0x01
450 #define	AUMODE_RECORD	0x02
451 
452 #define	AUDIO_PROP_FULLDUPLEX	0x01
453 
454 #define	AUDIO_ENCODING_ULAW		1
455 #define	AUDIO_ENCODING_ALAW		2
456 #define	AUDIO_ENCODING_SLINEAR_LE	6
457 #define	AUDIO_ENCODING_SLINEAR_BE	7
458 #define	AUDIO_ENCODING_ULINEAR_LE	8
459 #define	AUDIO_ENCODING_ULINEAR_BE	9
460 
461 #endif	/* FreeBSD */
462 
463 
464 #if defined(__NetBSD__) || defined(__OpenBSD__)
465 
466 USB_DECLARE_DRIVER(uaudio);
467 
468 #elif defined(__FreeBSD__)
469 
470 USB_DECLARE_DRIVER_INIT(uaudio,
471 		DEVMETHOD(device_suspend, bus_generic_suspend),
472 		DEVMETHOD(device_resume, bus_generic_resume),
473 		DEVMETHOD(device_shutdown, bus_generic_shutdown),
474 		DEVMETHOD(bus_print_child, bus_generic_print_child)
475 		);
476 #endif
477 
478 
479 USB_MATCH(uaudio)
480 {
481 	USB_MATCH_START(uaudio, uaa);
482 	usb_interface_descriptor_t *id;
483 
484 	if (uaa->iface == NULL)
485 		return (UMATCH_NONE);
486 
487 	id = usbd_get_interface_descriptor(uaa->iface);
488 	/* Trigger on the control interface. */
489 	if (id == NULL ||
490 	    id->bInterfaceClass != UICLASS_AUDIO ||
491 	    id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
492 	    (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
493 		return (UMATCH_NONE);
494 
495 	return (UMATCH_IFACECLASS_IFACESUBCLASS);
496 }
497 
498 USB_ATTACH(uaudio)
499 {
500 	USB_ATTACH_START(uaudio, sc, uaa);
501 	usb_interface_descriptor_t *id;
502 	usb_config_descriptor_t *cdesc;
503 	char devinfo[1024];
504 	usbd_status err;
505 	int i, j, found;
506 
507 #if defined(__FreeBSD__)
508 	usbd_devinfo(uaa->device, 0, devinfo);
509 	USB_ATTACH_SETUP;
510 #else
511 	usbd_devinfo(uaa->device, 0, devinfo, sizeof(devinfo));
512 #endif
513 
514 #if !defined(__FreeBSD__)
515 	printf(": %s\n", devinfo);
516 #endif
517 
518 	sc->sc_udev = uaa->device;
519 
520 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
521 	if (cdesc == NULL) {
522 		printf("%s: failed to get configuration descriptor\n",
523 		       USBDEVNAME(sc->sc_dev));
524 		USB_ATTACH_ERROR_RETURN;
525 	}
526 
527 	err = uaudio_identify(sc, cdesc);
528 	if (err) {
529 		printf("%s: audio descriptors make no sense, error=%d\n",
530 		       USBDEVNAME(sc->sc_dev), err);
531 		USB_ATTACH_ERROR_RETURN;
532 	}
533 
534 	sc->sc_ac_ifaceh = uaa->iface;
535 	/* Pick up the AS interface. */
536 	for (i = 0; i < uaa->nifaces; i++) {
537 		if (uaa->ifaces[i] == NULL)
538 			continue;
539 		id = usbd_get_interface_descriptor(uaa->ifaces[i]);
540 		if (id == NULL)
541 			continue;
542 		found = 0;
543 		for (j = 0; j < sc->sc_nalts; j++) {
544 			if (id->bInterfaceNumber ==
545 			    sc->sc_alts[j].idesc->bInterfaceNumber) {
546 				sc->sc_alts[j].ifaceh = uaa->ifaces[i];
547 				found = 1;
548 			}
549 		}
550 		if (found)
551 			uaa->ifaces[i] = NULL;
552 	}
553 
554 	for (j = 0; j < sc->sc_nalts; j++) {
555 		if (sc->sc_alts[j].ifaceh == NULL) {
556 			printf("%s: alt %d missing AS interface(s)\n",
557 			    USBDEVNAME(sc->sc_dev), j);
558 			USB_ATTACH_ERROR_RETURN;
559 		}
560 	}
561 
562 	printf("%s: audio rev %d.%02x\n", USBDEVNAME(sc->sc_dev),
563 	       sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
564 
565 	sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
566 	sc->sc_playchan.altidx = -1;
567 	sc->sc_recchan.altidx = -1;
568 
569 	if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
570 		sc->sc_altflags |= UA_NOFRAC;
571 
572 #ifndef USB_DEBUG
573 	if (bootverbose)
574 #endif
575 		printf("%s: %d mixer controls\n", USBDEVNAME(sc->sc_dev),
576 		    sc->sc_nctls);
577 
578 #if !defined(__FreeBSD__)
579 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
580 			   USBDEV(sc->sc_dev));
581 #endif
582 
583 	DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
584 #if defined(__OpenBSD__)
585 	audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
586 #elif defined(__NetBSD__)
587 	sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
588 #elif defined(__FreeBSD__)
589 	sc->sc_dying = 0;
590 	if (audio_attach_mi(sc->sc_dev)) {
591 		printf("audio_attach_mi failed\n");
592 		USB_ATTACH_ERROR_RETURN;
593 	}
594 #endif
595 
596 	USB_ATTACH_SUCCESS_RETURN;
597 }
598 
599 #if defined(__NetBSD__) || defined(__OpenBSD__)
600 int
601 uaudio_activate(device_ptr_t self, enum devact act)
602 {
603 	struct uaudio_softc *sc = (struct uaudio_softc *)self;
604 	int rv = 0;
605 
606 	switch (act) {
607 	case DVACT_ACTIVATE:
608 		return (EOPNOTSUPP);
609 		break;
610 
611 	case DVACT_DEACTIVATE:
612 		if (sc->sc_audiodev != NULL)
613 			rv = config_deactivate(sc->sc_audiodev);
614 		sc->sc_dying = 1;
615 		break;
616 	}
617 	return (rv);
618 }
619 #endif
620 
621 #if defined(__NetBSD__) || defined(__OpenBSD__)
622 int
623 uaudio_detach(device_ptr_t self, int flags)
624 {
625 	struct uaudio_softc *sc = (struct uaudio_softc *)self;
626 	int rv = 0;
627 
628 	/* Wait for outstanding requests to complete. */
629 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
630 
631 	if (sc->sc_audiodev != NULL)
632 		rv = config_detach(sc->sc_audiodev, flags);
633 
634 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
635 			   USBDEV(sc->sc_dev));
636 
637 	return (rv);
638 }
639 #elif defined(__FreeBSD__)
640 
641 USB_DETACH(uaudio)
642 {
643 	USB_DETACH_START(uaudio, sc);
644 
645 	sc->sc_dying = 1;
646 
647 #if 0 /* XXX */
648 	/* Wait for outstanding requests to complete. */
649 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
650 #endif
651 
652 	/* do nothing ? */
653 	return bus_generic_detach(sc->sc_dev);
654 }
655 #endif
656 
657 #if defined(__NetBSD__) || defined(__OpenBSD__)
658 Static int
659 uaudio_query_encoding(void *addr, struct audio_encoding *fp)
660 {
661 	struct uaudio_softc *sc = addr;
662 	int flags = sc->sc_altflags;
663 	int idx;
664 
665 	if (sc->sc_dying)
666 		return (EIO);
667 
668 	if (sc->sc_nalts == 0 || flags == 0)
669 		return (ENXIO);
670 
671 	idx = fp->index;
672 	switch (idx) {
673 	case 0:
674 		strlcpy(fp->name, AudioEulinear, sizeof(fp->name));
675 		fp->encoding = AUDIO_ENCODING_ULINEAR;
676 		fp->precision = 8;
677 		fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
678 		return (0);
679 	case 1:
680 		strlcpy(fp->name, AudioEmulaw, sizeof(fp->name));
681 		fp->encoding = AUDIO_ENCODING_ULAW;
682 		fp->precision = 8;
683 		fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
684 		return (0);
685 	case 2:
686 		strlcpy(fp->name, AudioEalaw, sizeof(fp->name));
687 		fp->encoding = AUDIO_ENCODING_ALAW;
688 		fp->precision = 8;
689 		fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
690 		return (0);
691 	case 3:
692 		strlcpy(fp->name, AudioEslinear, sizeof(fp->name));
693 		fp->encoding = AUDIO_ENCODING_SLINEAR;
694 		fp->precision = 8;
695 		fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
696 		return (0);
697 	case 4:
698 		strlcpy(fp->name, AudioEslinear_le, sizeof(fp->name));
699 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
700 		fp->precision = 16;
701 		fp->flags = 0;
702 		return (0);
703 	case 5:
704 		strlcpy(fp->name, AudioEulinear_le, sizeof(fp->name));
705 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
706 		fp->precision = 16;
707 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
708 		return (0);
709 	case 6:
710 		strlcpy(fp->name, AudioEslinear_be, sizeof(fp->name));
711 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
712 		fp->precision = 16;
713 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
714 		return (0);
715 	case 7:
716 		strlcpy(fp->name, AudioEulinear_be, sizeof(fp->name));
717 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
718 		fp->precision = 16;
719 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
720 		return (0);
721 	default:
722 		return (EINVAL);
723 	}
724 }
725 #endif
726 
727 Static const usb_interface_descriptor_t *
728 uaudio_find_iface(const char *buf, int size, int *offsp, int subtype)
729 {
730 	const usb_interface_descriptor_t *d;
731 
732 	while (*offsp < size) {
733 		d = (const void *)(buf + *offsp);
734 		*offsp += d->bLength;
735 		if (d->bDescriptorType == UDESC_INTERFACE &&
736 		    d->bInterfaceClass == UICLASS_AUDIO &&
737 		    d->bInterfaceSubClass == subtype)
738 			return (d);
739 	}
740 	return (NULL);
741 }
742 
743 Static void
744 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
745 {
746 	int res;
747 	size_t len;
748 	struct mixerctl *nmc;
749 
750 #if defined(__FreeBSD__)
751 	if (mc->class < UAC_NCLASSES) {
752 		DPRINTF(("%s: adding %s.%d\n",
753 			 __func__, uac_names[mc->class], mc->ctl));
754 	} else {
755 		DPRINTF(("%s: adding %d\n", __func__, mc->ctl));
756 	}
757 #else
758 	if (mc->class < UAC_NCLASSES) {
759 		DPRINTF(("%s: adding %s.%s\n",
760 			 __func__, uac_names[mc->class], mc->ctlname));
761 	} else {
762 		DPRINTF(("%s: adding %s\n", __func__, mc->ctlname));
763 	}
764 #endif
765 	len = sizeof(*mc) * (sc->sc_nctls + 1);
766 	nmc = malloc(len, M_USBDEV, M_NOWAIT);
767 	if (nmc == NULL) {
768 		printf("uaudio_mixer_add_ctl: no memory\n");
769 		return;
770 	}
771 	/* Copy old data, if there was any */
772 	if (sc->sc_nctls != 0) {
773 		memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls));
774 		free(sc->sc_ctls, M_USBDEV);
775 	}
776 	sc->sc_ctls = nmc;
777 
778 	mc->delta = 0;
779 	if (mc->type == MIX_ON_OFF) {
780 		mc->minval = 0;
781 		mc->maxval = 1;
782 	} else if (mc->type == MIX_SELECTOR) {
783 		;
784 	} else {
785 		/* Determine min and max values. */
786 		mc->minval = uaudio_signext(mc->type,
787 			uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
788 				   mc->wValue[0], mc->wIndex,
789 				   MIX_SIZE(mc->type)));
790 		mc->maxval = 1 + uaudio_signext(mc->type,
791 			uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
792 				   mc->wValue[0], mc->wIndex,
793 				   MIX_SIZE(mc->type)));
794 		mc->mul = mc->maxval - mc->minval;
795 		if (mc->mul == 0)
796 			mc->mul = 1;
797 		res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
798 				 mc->wValue[0], mc->wIndex,
799 				 MIX_SIZE(mc->type));
800 		if (res > 0)
801 			mc->delta = (res * 255 + mc->mul/2) / mc->mul;
802 	}
803 
804 	sc->sc_ctls[sc->sc_nctls++] = *mc;
805 
806 #ifdef USB_DEBUG
807 	if (uaudiodebug > 2) {
808 		int i;
809 		DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
810 		for (i = 1; i < mc->nchan; i++)
811 			DPRINTF((",%04x", mc->wValue[i]));
812 #if defined(__FreeBSD__)
813 		DPRINTF((" wIndex=%04x type=%d ctl='%d' "
814 			 "min=%d max=%d\n",
815 			 mc->wIndex, mc->type, mc->ctl,
816 			 mc->minval, mc->maxval));
817 #else
818 		DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' "
819 			 "min=%d max=%d\n",
820 			 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
821 			 mc->minval, mc->maxval));
822 #endif
823 	}
824 #endif
825 }
826 
827 #if defined(__NetBSD__) || defined(__OpenBSD__)
828 Static char *
829 uaudio_id_name(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
830 {
831 	static char buf[32];
832 	snprintf(buf, sizeof(buf), "i%d", id);
833 	return (buf);
834 }
835 #endif
836 
837 #ifdef USB_DEBUG
838 Static void
839 uaudio_dump_cluster(const struct usb_audio_cluster *cl)
840 {
841 	static const char *channel_names[16] = {
842 		"LEFT", "RIGHT", "CENTER", "LFE",
843 		"LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER",
844 		"SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP",
845 		"RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15",
846 	};
847 	int cc, i, first;
848 
849 	cc = UGETW(cl->wChannelConfig);
850 	logprintf("cluster: bNrChannels=%u wChannelConfig=0x%.4x",
851 		  cl->bNrChannels, cc);
852 	first = TRUE;
853 	for (i = 0; cc != 0; i++) {
854 		if (cc & 1) {
855 			logprintf("%c%s", first ? '<' : ',', channel_names[i]);
856 			first = FALSE;
857 		}
858 		cc = cc >> 1;
859 	}
860 	logprintf("> iChannelNames=%u", cl->iChannelNames);
861 }
862 #endif
863 
864 Static struct usb_audio_cluster
865 uaudio_get_cluster(int id, const struct io_terminal *iot)
866 {
867 	struct usb_audio_cluster r;
868 	const usb_descriptor_t *dp;
869 	int i;
870 
871 	for (i = 0; i < 25; i++) { /* avoid infinite loops */
872 		dp = iot[id].d.desc;
873 		if (dp == 0)
874 			goto bad;
875 		switch (dp->bDescriptorSubtype) {
876 		case UDESCSUB_AC_INPUT:
877 			r.bNrChannels = iot[id].d.it->bNrChannels;
878 			USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig));
879 			r.iChannelNames = iot[id].d.it->iChannelNames;
880 			return (r);
881 		case UDESCSUB_AC_OUTPUT:
882 			id = iot[id].d.ot->bSourceId;
883 			break;
884 		case UDESCSUB_AC_MIXER:
885 			r = *(const struct usb_audio_cluster *)
886 				&iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
887 			return (r);
888 		case UDESCSUB_AC_SELECTOR:
889 			/* XXX This is not really right */
890 			id = iot[id].d.su->baSourceId[0];
891 			break;
892 		case UDESCSUB_AC_FEATURE:
893 			id = iot[id].d.fu->bSourceId;
894 			break;
895 		case UDESCSUB_AC_PROCESSING:
896 			r = *(const struct usb_audio_cluster *)
897 				&iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
898 			return (r);
899 		case UDESCSUB_AC_EXTENSION:
900 			r = *(const struct usb_audio_cluster *)
901 				&iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
902 			return (r);
903 		default:
904 			goto bad;
905 		}
906 	}
907  bad:
908 	printf("uaudio_get_cluster: bad data\n");
909 	memset(&r, 0, sizeof r);
910 	return (r);
911 
912 }
913 
914 Static void
915 uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
916 {
917 #ifdef USB_DEBUG
918 	const struct usb_audio_input_terminal *d = iot[id].d.it;
919 
920 	DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
921 		    "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
922 		    "iChannelNames=%d iTerminal=%d\n",
923 		    d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
924 		    d->bNrChannels, UGETW(d->wChannelConfig),
925 		    d->iChannelNames, d->iTerminal));
926 #endif
927 }
928 
929 Static void
930 uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
931 {
932 #ifdef USB_DEBUG
933 	const struct usb_audio_output_terminal *d = iot[id].d.ot;
934 
935 	DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
936 		    "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
937 		    d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
938 		    d->bSourceId, d->iTerminal));
939 #endif
940 }
941 
942 Static void
943 uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
944 {
945 	const struct usb_audio_mixer_unit *d = iot[id].d.mu;
946 	const struct usb_audio_mixer_unit_1 *d1;
947 	int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
948 	const uByte *bm;
949 	struct mixerctl mix;
950 
951 	DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
952 		    d->bUnitId, d->bNrInPins));
953 
954 	/* Compute the number of input channels */
955 	ichs = 0;
956 	for (i = 0; i < d->bNrInPins; i++)
957 		ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
958 
959 	/* and the number of output channels */
960 	d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
961 	ochs = d1->bNrChannels;
962 	DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
963 
964 	bm = d1->bmControls;
965 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
966 	uaudio_determine_class(&iot[id], &mix);
967 	mix.type = MIX_SIGNED_16;
968 #if !defined(__FreeBSD__)	/* XXXXX */
969 	mix.ctlunit = AudioNvolume;
970 #endif
971 
972 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
973 	for (p = i = 0; i < d->bNrInPins; i++) {
974 		chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
975 		mc = 0;
976 		for (c = 0; c < chs; c++) {
977 			mo = 0;
978 			for (o = 0; o < ochs; o++) {
979 				bno = (p + c) * ochs + o;
980 				if (BIT(bno))
981 					mo++;
982 			}
983 			if (mo == 1)
984 				mc++;
985 		}
986 		if (mc == chs && chs <= MIX_MAX_CHAN) {
987 			k = 0;
988 			for (c = 0; c < chs; c++)
989 				for (o = 0; o < ochs; o++) {
990 					bno = (p + c) * ochs + o;
991 					if (BIT(bno))
992 						mix.wValue[k++] =
993 							MAKE(p+c+1, o+1);
994 				}
995 #if !defined(__FreeBSD__)
996 			snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s",
997 			    d->bUnitId, uaudio_id_name(sc, iot,
998 			    d->baSourceId[i]));
999 #endif
1000 			mix.nchan = chs;
1001 			uaudio_mixer_add_ctl(sc, &mix);
1002 		} else {
1003 			/* XXX */
1004 		}
1005 #undef BIT
1006 		p += chs;
1007 	}
1008 
1009 }
1010 
1011 Static void
1012 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1013 {
1014 	const struct usb_audio_selector_unit *d = iot[id].d.su;
1015 	struct mixerctl mix;
1016 #if !defined(__FreeBSD__)
1017 	int i, wp;
1018 #else
1019 	int i;
1020 	struct mixerctl dummy;
1021 #endif
1022 
1023 	DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
1024 		    d->bUnitId, d->bNrInPins));
1025 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1026 	mix.wValue[0] = MAKE(0, 0);
1027 	uaudio_determine_class(&iot[id], &mix);
1028 	mix.nchan = 1;
1029 	mix.type = MIX_SELECTOR;
1030 #if defined(__FreeBSD__)
1031 	mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1032 	mix.minval = 1;
1033 	mix.maxval = d->bNrInPins;
1034 	mix.mul = mix.maxval - mix.minval;
1035 	for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) {
1036 		mix.slctrtype[i] = SOUND_MIXER_NRDEVICES;
1037 	}
1038 	for (i = mix.minval; i <= mix.maxval; i++) {
1039 		mix.slctrtype[i - 1] = uaudio_feature_name(&iot[d->baSourceId[i - 1]], &dummy);
1040 	}
1041 #else
1042 	mix.ctlunit = "";
1043 	mix.minval = 1;
1044 	mix.maxval = d->bNrInPins;
1045 	mix.mul = mix.maxval - mix.minval;
1046 	wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId);
1047 	for (i = 1; i <= d->bNrInPins; i++) {
1048 		wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp,
1049 			       "i%d", d->baSourceId[i - 1]);
1050 		if (wp > MAX_AUDIO_DEV_LEN - 1)
1051 			break;
1052 	}
1053 #endif
1054 	uaudio_mixer_add_ctl(sc, &mix);
1055 }
1056 
1057 #ifdef USB_DEBUG
1058 Static const char *
1059 uaudio_get_terminal_name(int terminal_type)
1060 {
1061 	static char buf[100];
1062 
1063 	switch (terminal_type) {
1064 	/* USB terminal types */
1065 	case UAT_UNDEFINED:	return "UAT_UNDEFINED";
1066 	case UAT_STREAM:	return "UAT_STREAM";
1067 	case UAT_VENDOR:	return "UAT_VENDOR";
1068 	/* input terminal types */
1069 	case UATI_UNDEFINED:	return "UATI_UNDEFINED";
1070 	case UATI_MICROPHONE:	return "UATI_MICROPHONE";
1071 	case UATI_DESKMICROPHONE:	return "UATI_DESKMICROPHONE";
1072 	case UATI_PERSONALMICROPHONE:	return "UATI_PERSONALMICROPHONE";
1073 	case UATI_OMNIMICROPHONE:	return "UATI_OMNIMICROPHONE";
1074 	case UATI_MICROPHONEARRAY:	return "UATI_MICROPHONEARRAY";
1075 	case UATI_PROCMICROPHONEARR:	return "UATI_PROCMICROPHONEARR";
1076 	/* output terminal types */
1077 	case UATO_UNDEFINED:	return "UATO_UNDEFINED";
1078 	case UATO_SPEAKER:	return "UATO_SPEAKER";
1079 	case UATO_HEADPHONES:	return "UATO_HEADPHONES";
1080 	case UATO_DISPLAYAUDIO:	return "UATO_DISPLAYAUDIO";
1081 	case UATO_DESKTOPSPEAKER:	return "UATO_DESKTOPSPEAKER";
1082 	case UATO_ROOMSPEAKER:	return "UATO_ROOMSPEAKER";
1083 	case UATO_COMMSPEAKER:	return "UATO_COMMSPEAKER";
1084 	case UATO_SUBWOOFER:	return "UATO_SUBWOOFER";
1085 	/* bidir terminal types */
1086 	case UATB_UNDEFINED:	return "UATB_UNDEFINED";
1087 	case UATB_HANDSET:	return "UATB_HANDSET";
1088 	case UATB_HEADSET:	return "UATB_HEADSET";
1089 	case UATB_SPEAKERPHONE:	return "UATB_SPEAKERPHONE";
1090 	case UATB_SPEAKERPHONEESUP:	return "UATB_SPEAKERPHONEESUP";
1091 	case UATB_SPEAKERPHONEECANC:	return "UATB_SPEAKERPHONEECANC";
1092 	/* telephony terminal types */
1093 	case UATT_UNDEFINED:	return "UATT_UNDEFINED";
1094 	case UATT_PHONELINE:	return "UATT_PHONELINE";
1095 	case UATT_TELEPHONE:	return "UATT_TELEPHONE";
1096 	case UATT_DOWNLINEPHONE:	return "UATT_DOWNLINEPHONE";
1097 	/* external terminal types */
1098 	case UATE_UNDEFINED:	return "UATE_UNDEFINED";
1099 	case UATE_ANALOGCONN:	return "UATE_ANALOGCONN";
1100 	case UATE_LINECONN:	return "UATE_LINECONN";
1101 	case UATE_LEGACYCONN:	return "UATE_LEGACYCONN";
1102 	case UATE_DIGITALAUIFC:	return "UATE_DIGITALAUIFC";
1103 	case UATE_SPDIF:	return "UATE_SPDIF";
1104 	case UATE_1394DA:	return "UATE_1394DA";
1105 	case UATE_1394DV:	return "UATE_1394DV";
1106 	/* embedded function terminal types */
1107 	case UATF_UNDEFINED:	return "UATF_UNDEFINED";
1108 	case UATF_CALIBNOISE:	return "UATF_CALIBNOISE";
1109 	case UATF_EQUNOISE:	return "UATF_EQUNOISE";
1110 	case UATF_CDPLAYER:	return "UATF_CDPLAYER";
1111 	case UATF_DAT:	return "UATF_DAT";
1112 	case UATF_DCC:	return "UATF_DCC";
1113 	case UATF_MINIDISK:	return "UATF_MINIDISK";
1114 	case UATF_ANALOGTAPE:	return "UATF_ANALOGTAPE";
1115 	case UATF_PHONOGRAPH:	return "UATF_PHONOGRAPH";
1116 	case UATF_VCRAUDIO:	return "UATF_VCRAUDIO";
1117 	case UATF_VIDEODISCAUDIO:	return "UATF_VIDEODISCAUDIO";
1118 	case UATF_DVDAUDIO:	return "UATF_DVDAUDIO";
1119 	case UATF_TVTUNERAUDIO:	return "UATF_TVTUNERAUDIO";
1120 	case UATF_SATELLITE:	return "UATF_SATELLITE";
1121 	case UATF_CABLETUNER:	return "UATF_CABLETUNER";
1122 	case UATF_DSS:	return "UATF_DSS";
1123 	case UATF_RADIORECV:	return "UATF_RADIORECV";
1124 	case UATF_RADIOXMIT:	return "UATF_RADIOXMIT";
1125 	case UATF_MULTITRACK:	return "UATF_MULTITRACK";
1126 	case UATF_SYNTHESIZER:	return "UATF_SYNTHESIZER";
1127 	default:
1128 		snprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type);
1129 		return buf;
1130 	}
1131 }
1132 #endif
1133 
1134 Static int
1135 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
1136 {
1137 	int terminal_type;
1138 
1139 	if (iot == NULL || iot->output == NULL) {
1140 		mix->class = UAC_OUTPUT;
1141 		return 0;
1142 	}
1143 	terminal_type = 0;
1144 	if (iot->output->size == 1)
1145 		terminal_type = iot->output->terminals[0];
1146 	/*
1147 	 * If the only output terminal is USB,
1148 	 * the class is UAC_RECORD.
1149 	 */
1150 	if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
1151 		mix->class = UAC_RECORD;
1152 		if (iot->inputs_size == 1
1153 		    && iot->inputs[0] != NULL
1154 		    && iot->inputs[0]->size == 1)
1155 			return iot->inputs[0]->terminals[0];
1156 		else
1157 			return 0;
1158 	}
1159 	/*
1160 	 * If the ultimate destination of the unit is just one output
1161 	 * terminal and the unit is connected to the output terminal
1162 	 * directly, the class is UAC_OUTPUT.
1163 	 */
1164 	if (terminal_type != 0 && iot->direct) {
1165 		mix->class = UAC_OUTPUT;
1166 		return terminal_type;
1167 	}
1168 	/*
1169 	 * If the unit is connected to just one input terminal,
1170 	 * the class is UAC_INPUT.
1171 	 */
1172 	if (iot->inputs_size == 1 && iot->inputs[0] != NULL
1173 	    && iot->inputs[0]->size == 1) {
1174 		mix->class = UAC_INPUT;
1175 		return iot->inputs[0]->terminals[0];
1176 	}
1177 	/*
1178 	 * Otherwise, the class is UAC_OUTPUT.
1179 	 */
1180 	mix->class = UAC_OUTPUT;
1181 	return terminal_type;
1182 }
1183 
1184 #if defined(__FreeBSD__)
1185 const int
1186 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
1187 {
1188 	int terminal_type;
1189 
1190 	terminal_type = uaudio_determine_class(iot, mix);
1191 	if (mix->class == UAC_RECORD && terminal_type == 0)
1192 		return SOUND_MIXER_IMIX;
1193 	DPRINTF(("%s: terminal_type=%s\n", __func__,
1194 		 uaudio_get_terminal_name(terminal_type)));
1195 	switch (terminal_type) {
1196 	case UAT_STREAM:
1197 		return SOUND_MIXER_PCM;
1198 
1199 	case UATI_MICROPHONE:
1200 	case UATI_DESKMICROPHONE:
1201 	case UATI_PERSONALMICROPHONE:
1202 	case UATI_OMNIMICROPHONE:
1203 	case UATI_MICROPHONEARRAY:
1204 	case UATI_PROCMICROPHONEARR:
1205 		return SOUND_MIXER_MIC;
1206 
1207 	case UATO_SPEAKER:
1208 	case UATO_DESKTOPSPEAKER:
1209 	case UATO_ROOMSPEAKER:
1210 	case UATO_COMMSPEAKER:
1211 		return SOUND_MIXER_SPEAKER;
1212 
1213 	case UATE_ANALOGCONN:
1214 	case UATE_LINECONN:
1215 	case UATE_LEGACYCONN:
1216 		return SOUND_MIXER_LINE;
1217 
1218 	case UATE_DIGITALAUIFC:
1219 	case UATE_SPDIF:
1220 	case UATE_1394DA:
1221 	case UATE_1394DV:
1222 		return SOUND_MIXER_ALTPCM;
1223 
1224 	case UATF_CDPLAYER:
1225 		return SOUND_MIXER_CD;
1226 
1227 	case UATF_SYNTHESIZER:
1228 		return SOUND_MIXER_SYNTH;
1229 
1230 	case UATF_VIDEODISCAUDIO:
1231 	case UATF_DVDAUDIO:
1232 	case UATF_TVTUNERAUDIO:
1233 		return SOUND_MIXER_VIDEO;
1234 
1235 /* telephony terminal types */
1236 	case UATT_UNDEFINED:
1237 	case UATT_PHONELINE:
1238 	case UATT_TELEPHONE:
1239 	case UATT_DOWNLINEPHONE:
1240 		return SOUND_MIXER_PHONEIN;
1241 /*		return SOUND_MIXER_PHONEOUT;*/
1242 
1243 	case UATF_RADIORECV:
1244 	case UATF_RADIOXMIT:
1245 		return SOUND_MIXER_RADIO;
1246 
1247 	case UAT_UNDEFINED:
1248 	case UAT_VENDOR:
1249 	case UATI_UNDEFINED:
1250 /* output terminal types */
1251 	case UATO_UNDEFINED:
1252 	case UATO_DISPLAYAUDIO:
1253 	case UATO_SUBWOOFER:
1254 	case UATO_HEADPHONES:
1255 /* bidir terminal types */
1256 	case UATB_UNDEFINED:
1257 	case UATB_HANDSET:
1258 	case UATB_HEADSET:
1259 	case UATB_SPEAKERPHONE:
1260 	case UATB_SPEAKERPHONEESUP:
1261 	case UATB_SPEAKERPHONEECANC:
1262 /* external terminal types */
1263 	case UATE_UNDEFINED:
1264 /* embedded function terminal types */
1265 	case UATF_UNDEFINED:
1266 	case UATF_CALIBNOISE:
1267 	case UATF_EQUNOISE:
1268 	case UATF_DAT:
1269 	case UATF_DCC:
1270 	case UATF_MINIDISK:
1271 	case UATF_ANALOGTAPE:
1272 	case UATF_PHONOGRAPH:
1273 	case UATF_VCRAUDIO:
1274 	case UATF_SATELLITE:
1275 	case UATF_CABLETUNER:
1276 	case UATF_DSS:
1277 	case UATF_MULTITRACK:
1278 	case 0xffff:
1279 	default:
1280 		DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
1281 		return SOUND_MIXER_VOLUME;
1282 	}
1283 	return SOUND_MIXER_VOLUME;
1284 }
1285 #else
1286 Static const char *
1287 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
1288 {
1289 	int terminal_type;
1290 
1291 	terminal_type = uaudio_determine_class(iot, mix);
1292 	if (mix->class == UAC_RECORD && terminal_type == 0)
1293 		return AudioNmixerout;
1294 	DPRINTF(("%s: terminal_type=%s\n", __func__,
1295 		 uaudio_get_terminal_name(terminal_type)));
1296 	switch (terminal_type) {
1297 	case UAT_STREAM:
1298 		return AudioNdac;
1299 
1300 	case UATI_MICROPHONE:
1301 	case UATI_DESKMICROPHONE:
1302 	case UATI_PERSONALMICROPHONE:
1303 	case UATI_OMNIMICROPHONE:
1304 	case UATI_MICROPHONEARRAY:
1305 	case UATI_PROCMICROPHONEARR:
1306 		return AudioNmicrophone;
1307 
1308 	case UATO_SPEAKER:
1309 	case UATO_DESKTOPSPEAKER:
1310 	case UATO_ROOMSPEAKER:
1311 	case UATO_COMMSPEAKER:
1312 		return AudioNspeaker;
1313 
1314 	case UATO_HEADPHONES:
1315 		return AudioNheadphone;
1316 
1317 	case UATO_SUBWOOFER:
1318 		return AudioNlfe;
1319 
1320 	/* telephony terminal types */
1321 	case UATT_UNDEFINED:
1322 	case UATT_PHONELINE:
1323 	case UATT_TELEPHONE:
1324 	case UATT_DOWNLINEPHONE:
1325 		return "phone";
1326 
1327 	case UATE_ANALOGCONN:
1328 	case UATE_LINECONN:
1329 	case UATE_LEGACYCONN:
1330 		return AudioNline;
1331 
1332 	case UATE_DIGITALAUIFC:
1333 	case UATE_SPDIF:
1334 	case UATE_1394DA:
1335 	case UATE_1394DV:
1336 		return AudioNaux;
1337 
1338 	case UATF_CDPLAYER:
1339 		return AudioNcd;
1340 
1341 	case UATF_SYNTHESIZER:
1342 		return AudioNfmsynth;
1343 
1344 	case UATF_VIDEODISCAUDIO:
1345 	case UATF_DVDAUDIO:
1346 	case UATF_TVTUNERAUDIO:
1347 		return AudioNvideo;
1348 
1349 	case UAT_UNDEFINED:
1350 	case UAT_VENDOR:
1351 	case UATI_UNDEFINED:
1352 /* output terminal types */
1353 	case UATO_UNDEFINED:
1354 	case UATO_DISPLAYAUDIO:
1355 /* bidir terminal types */
1356 	case UATB_UNDEFINED:
1357 	case UATB_HANDSET:
1358 	case UATB_HEADSET:
1359 	case UATB_SPEAKERPHONE:
1360 	case UATB_SPEAKERPHONEESUP:
1361 	case UATB_SPEAKERPHONEECANC:
1362 /* external terminal types */
1363 	case UATE_UNDEFINED:
1364 /* embedded function terminal types */
1365 	case UATF_UNDEFINED:
1366 	case UATF_CALIBNOISE:
1367 	case UATF_EQUNOISE:
1368 	case UATF_DAT:
1369 	case UATF_DCC:
1370 	case UATF_MINIDISK:
1371 	case UATF_ANALOGTAPE:
1372 	case UATF_PHONOGRAPH:
1373 	case UATF_VCRAUDIO:
1374 	case UATF_SATELLITE:
1375 	case UATF_CABLETUNER:
1376 	case UATF_DSS:
1377 	case UATF_RADIORECV:
1378 	case UATF_RADIOXMIT:
1379 	case UATF_MULTITRACK:
1380 	case 0xffff:
1381 	default:
1382 		DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
1383 		return AudioNmaster;
1384 	}
1385 	return AudioNmaster;
1386 }
1387 #endif
1388 
1389 Static void
1390 uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1391 {
1392 	const struct usb_audio_feature_unit *d = iot[id].d.fu;
1393 	uByte *ctls = d->bmaControls;
1394 	int ctlsize = d->bControlSize;
1395 	int nchan = (d->bLength - 7) / ctlsize;
1396 	u_int fumask, mmask, cmask;
1397 	struct mixerctl mix;
1398 	int chan, ctl, i, unit;
1399 #if defined(__FreeBSD__)
1400 	int mixernumber;
1401 #else
1402 	const char *mixername;
1403 #endif
1404 
1405 #define GET(i) (ctls[(i)*ctlsize] | \
1406 		(ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
1407 
1408 	mmask = GET(0);
1409 	/* Figure out what we can control */
1410 	for (cmask = 0, chan = 1; chan < nchan; chan++) {
1411 		DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
1412 			    chan, GET(chan)));
1413 		cmask |= GET(chan);
1414 	}
1415 
1416 #if !defined(__FreeBSD__)
1417 	DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, "
1418 		    "%d channels, mmask=0x%04x, cmask=0x%04x\n",
1419 		    d->bUnitId, nchan, mmask, cmask));
1420 #endif
1421 
1422 	if (nchan > MIX_MAX_CHAN)
1423 		nchan = MIX_MAX_CHAN;
1424 	unit = d->bUnitId;
1425 	mix.wIndex = MAKE(unit, sc->sc_ac_iface);
1426 	for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
1427 		fumask = FU_MASK(ctl);
1428 		DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
1429 			    ctl, fumask));
1430 		if (mmask & fumask) {
1431 			mix.nchan = 1;
1432 			mix.wValue[0] = MAKE(ctl, 0);
1433 		} else if (cmask & fumask) {
1434 			mix.nchan = nchan - 1;
1435 			for (i = 1; i < nchan; i++) {
1436 				if (GET(i) & fumask)
1437 					mix.wValue[i-1] = MAKE(ctl, i);
1438 				else
1439 					mix.wValue[i-1] = -1;
1440 			}
1441 		} else {
1442 			continue;
1443 		}
1444 #undef GET
1445 
1446 #if defined(__FreeBSD__)
1447 		mixernumber = uaudio_feature_name(&iot[id], &mix);
1448 #else
1449 		mixername = uaudio_feature_name(&iot[id], &mix);
1450 #endif
1451 		switch (ctl) {
1452 		case MUTE_CONTROL:
1453 			mix.type = MIX_ON_OFF;
1454 #if defined(__FreeBSD__)
1455 			mix.ctl = SOUND_MIXER_NRDEVICES;
1456 #else
1457 			mix.ctlunit = "";
1458 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1459 				 "%s.%s", mixername, AudioNmute);
1460 #endif
1461 			break;
1462 		case VOLUME_CONTROL:
1463 			mix.type = MIX_SIGNED_16;
1464 #if defined(__FreeBSD__)
1465 			mix.ctl = mixernumber;
1466 #else
1467 			mix.ctlunit = AudioNvolume;
1468 			strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname));
1469 #endif
1470 			break;
1471 		case BASS_CONTROL:
1472 			mix.type = MIX_SIGNED_8;
1473 #if defined(__FreeBSD__)
1474 			mix.ctl = SOUND_MIXER_BASS;
1475 #else
1476 			mix.ctlunit = AudioNbass;
1477 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1478 				 "%s.%s", mixername, AudioNbass);
1479 #endif
1480 			break;
1481 		case MID_CONTROL:
1482 			mix.type = MIX_SIGNED_8;
1483 #if defined(__FreeBSD__)
1484 			mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1485 #else
1486 			mix.ctlunit = AudioNmid;
1487 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1488 				 "%s.%s", mixername, AudioNmid);
1489 #endif
1490 			break;
1491 		case TREBLE_CONTROL:
1492 			mix.type = MIX_SIGNED_8;
1493 #if defined(__FreeBSD__)
1494 			mix.ctl = SOUND_MIXER_TREBLE;
1495 #else
1496 			mix.ctlunit = AudioNtreble;
1497 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1498 				 "%s.%s", mixername, AudioNtreble);
1499 #endif
1500 			break;
1501 		case GRAPHIC_EQUALIZER_CONTROL:
1502 			continue; /* XXX don't add anything */
1503 			break;
1504 		case AGC_CONTROL:
1505 			mix.type = MIX_ON_OFF;
1506 #if defined(__FreeBSD__)
1507 			mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1508 #else
1509 			mix.ctlunit = "";
1510 			snprintf(mix.ctlname, sizeof(mix.ctlname), "%s.%s",
1511 				 mixername, AudioNagc);
1512 #endif
1513 			break;
1514 		case DELAY_CONTROL:
1515 			mix.type = MIX_UNSIGNED_16;
1516 #if defined(__FreeBSD__)
1517 			mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1518 #else
1519 			mix.ctlunit = "4 ms";
1520 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1521 				 "%s.%s", mixername, AudioNdelay);
1522 #endif
1523 			break;
1524 		case BASS_BOOST_CONTROL:
1525 			mix.type = MIX_ON_OFF;
1526 #if defined(__FreeBSD__)
1527 			mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1528 #else
1529 			mix.ctlunit = "";
1530 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1531 				 "%s.%s", mixername, AudioNbassboost);
1532 #endif
1533 			break;
1534 		case LOUDNESS_CONTROL:
1535 			mix.type = MIX_ON_OFF;
1536 #if defined(__FreeBSD__)
1537 			mix.ctl = SOUND_MIXER_LOUD;	/* Is this correct ? */
1538 #else
1539 			mix.ctlunit = "";
1540 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1541 				 "%s.%s", mixername, AudioNloudness);
1542 #endif
1543 			break;
1544 		}
1545 		uaudio_mixer_add_ctl(sc, &mix);
1546 	}
1547 }
1548 
1549 Static void
1550 uaudio_add_processing_updown(struct uaudio_softc *sc,
1551 			     const struct io_terminal *iot, int id)
1552 {
1553 	const struct usb_audio_processing_unit *d = iot[id].d.pu;
1554 	const struct usb_audio_processing_unit_1 *d1 =
1555 	    (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
1556 	const struct usb_audio_processing_unit_updown *ud =
1557 	    (const struct usb_audio_processing_unit_updown *)
1558 		&d1->bmControls[d1->bControlSize];
1559 	struct mixerctl mix;
1560 	int i;
1561 
1562 	DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
1563 		    d->bUnitId, ud->bNrModes));
1564 
1565 	if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
1566 		DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
1567 		return;
1568 	}
1569 
1570 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1571 	mix.nchan = 1;
1572 	mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
1573 	uaudio_determine_class(&iot[id], &mix);
1574 	mix.type = MIX_ON_OFF;	/* XXX */
1575 #if !defined(__FreeBSD__)
1576 	mix.ctlunit = "";
1577 	snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId);
1578 #endif
1579 
1580 	for (i = 0; i < ud->bNrModes; i++) {
1581 		DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
1582 			    i, UGETW(ud->waModes[i])));
1583 		/* XXX */
1584 	}
1585 	uaudio_mixer_add_ctl(sc, &mix);
1586 }
1587 
1588 Static void
1589 uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1590 {
1591 	const struct usb_audio_processing_unit *d = iot[id].d.pu;
1592 	const struct usb_audio_processing_unit_1 *d1 =
1593 	    (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
1594 	int ptype = UGETW(d->wProcessType);
1595 	struct mixerctl mix;
1596 
1597 	DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
1598 		    "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
1599 
1600 	if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
1601 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1602 		mix.nchan = 1;
1603 		mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
1604 		uaudio_determine_class(&iot[id], &mix);
1605 		mix.type = MIX_ON_OFF;
1606 #if !defined(__FreeBSD__)
1607 		mix.ctlunit = "";
1608 		snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable",
1609 		    d->bUnitId, ptype);
1610 #endif
1611 		uaudio_mixer_add_ctl(sc, &mix);
1612 	}
1613 
1614 	switch(ptype) {
1615 	case UPDOWNMIX_PROCESS:
1616 		uaudio_add_processing_updown(sc, iot, id);
1617 		break;
1618 	case DOLBY_PROLOGIC_PROCESS:
1619 	case P3D_STEREO_EXTENDER_PROCESS:
1620 	case REVERBATION_PROCESS:
1621 	case CHORUS_PROCESS:
1622 	case DYN_RANGE_COMP_PROCESS:
1623 	default:
1624 #ifdef USB_DEBUG
1625 		printf("uaudio_add_processing: unit %d, type=%d not impl.\n",
1626 		       d->bUnitId, ptype);
1627 #endif
1628 		break;
1629 	}
1630 }
1631 
1632 Static void
1633 uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1634 {
1635 	const struct usb_audio_extension_unit *d = iot[id].d.eu;
1636 	const struct usb_audio_extension_unit_1 *d1 =
1637 	    (const struct usb_audio_extension_unit_1 *)&d->baSourceId[d->bNrInPins];
1638 	struct mixerctl mix;
1639 
1640 	DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
1641 		    d->bUnitId, d->bNrInPins));
1642 
1643 	if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
1644 		return;
1645 
1646 	if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
1647 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1648 		mix.nchan = 1;
1649 		mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
1650 		uaudio_determine_class(&iot[id], &mix);
1651 		mix.type = MIX_ON_OFF;
1652 #if !defined(__FreeBSD__)
1653 		mix.ctlunit = "";
1654 		snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable",
1655 		    d->bUnitId);
1656 #endif
1657 		uaudio_mixer_add_ctl(sc, &mix);
1658 	}
1659 }
1660 
1661 Static struct terminal_list*
1662 uaudio_merge_terminal_list(const struct io_terminal *iot)
1663 {
1664 	struct terminal_list *tml;
1665 	uint16_t *ptm;
1666 	int i, len;
1667 
1668 	len = 0;
1669 	if (iot->inputs == NULL)
1670 		return NULL;
1671 	for (i = 0; i < iot->inputs_size; i++) {
1672 		if (iot->inputs[i] != NULL)
1673 			len += iot->inputs[i]->size;
1674 	}
1675 	tml = malloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT);
1676 	if (tml == NULL) {
1677 		printf("uaudio_merge_terminal_list: no memory\n");
1678 		return NULL;
1679 	}
1680 	tml->size = 0;
1681 	ptm = tml->terminals;
1682 	for (i = 0; i < iot->inputs_size; i++) {
1683 		if (iot->inputs[i] == NULL)
1684 			continue;
1685 		if (iot->inputs[i]->size > len)
1686 			break;
1687 		memcpy(ptm, iot->inputs[i]->terminals,
1688 		       iot->inputs[i]->size * sizeof(uint16_t));
1689 		tml->size += iot->inputs[i]->size;
1690 		ptm += iot->inputs[i]->size;
1691 		len -= iot->inputs[i]->size;
1692 	}
1693 	return tml;
1694 }
1695 
1696 Static struct terminal_list *
1697 uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id)
1698 {
1699 	struct terminal_list *tml;
1700 	struct io_terminal *it;
1701 	int src_id, i;
1702 
1703 	it = &iot[id];
1704 	if (it->output != NULL) {
1705 		/* already has outtype? */
1706 		for (i = 0; i < it->output->size; i++)
1707 			if (it->output->terminals[i] == outtype)
1708 				return uaudio_merge_terminal_list(it);
1709 		tml = malloc(TERMINAL_LIST_SIZE(it->output->size + 1),
1710 			     M_TEMP, M_NOWAIT);
1711 		if (tml == NULL) {
1712 			printf("uaudio_io_terminaltype: no memory\n");
1713 			return uaudio_merge_terminal_list(it);
1714 		}
1715 		memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size));
1716 		tml->terminals[it->output->size] = outtype;
1717 		tml->size++;
1718 		free(it->output, M_TEMP);
1719 		it->output = tml;
1720 		if (it->inputs != NULL) {
1721 			for (i = 0; i < it->inputs_size; i++)
1722 				if (it->inputs[i] != NULL)
1723 					free(it->inputs[i], M_TEMP);
1724 			free(it->inputs, M_TEMP);
1725 		}
1726 		it->inputs_size = 0;
1727 		it->inputs = NULL;
1728 	} else {		/* end `iot[id] != NULL' */
1729 		it->inputs_size = 0;
1730 		it->inputs = NULL;
1731 		it->output = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1732 		if (it->output == NULL) {
1733 			printf("uaudio_io_terminaltype: no memory\n");
1734 			return NULL;
1735 		}
1736 		it->output->terminals[0] = outtype;
1737 		it->output->size = 1;
1738 		it->direct = FALSE;
1739 	}
1740 
1741 	switch (it->d.desc->bDescriptorSubtype) {
1742 	case UDESCSUB_AC_INPUT:
1743 		it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1744 		if (it->inputs == NULL) {
1745 			printf("uaudio_io_terminaltype: no memory\n");
1746 			return NULL;
1747 		}
1748 		tml = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1749 		if (tml == NULL) {
1750 			printf("uaudio_io_terminaltype: no memory\n");
1751 			free(it->inputs, M_TEMP);
1752 			it->inputs = NULL;
1753 			return NULL;
1754 		}
1755 		it->inputs[0] = tml;
1756 		tml->terminals[0] = UGETW(it->d.it->wTerminalType);
1757 		tml->size = 1;
1758 		it->inputs_size = 1;
1759 		return uaudio_merge_terminal_list(it);
1760 	case UDESCSUB_AC_FEATURE:
1761 		src_id = it->d.fu->bSourceId;
1762 		it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1763 		if (it->inputs == NULL) {
1764 			printf("uaudio_io_terminaltype: no memory\n");
1765 			return uaudio_io_terminaltype(outtype, iot, src_id);
1766 		}
1767 		it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1768 		it->inputs_size = 1;
1769 		return uaudio_merge_terminal_list(it);
1770 	case UDESCSUB_AC_OUTPUT:
1771 		it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1772 		if (it->inputs == NULL) {
1773 			printf("uaudio_io_terminaltype: no memory\n");
1774 			return NULL;
1775 		}
1776 		src_id = it->d.ot->bSourceId;
1777 		it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1778 		it->inputs_size = 1;
1779 		iot[src_id].direct = TRUE;
1780 		return NULL;
1781 	case UDESCSUB_AC_MIXER:
1782 		it->inputs_size = 0;
1783 		it->inputs = malloc(sizeof(struct terminal_list *)
1784 				    * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT);
1785 		if (it->inputs == NULL) {
1786 			printf("uaudio_io_terminaltype: no memory\n");
1787 			return NULL;
1788 		}
1789 		for (i = 0; i < it->d.mu->bNrInPins; i++) {
1790 			src_id = it->d.mu->baSourceId[i];
1791 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1792 							       src_id);
1793 			it->inputs_size++;
1794 		}
1795 		return uaudio_merge_terminal_list(it);
1796 	case UDESCSUB_AC_SELECTOR:
1797 		it->inputs_size = 0;
1798 		it->inputs = malloc(sizeof(struct terminal_list *)
1799 				    * it->d.su->bNrInPins, M_TEMP, M_NOWAIT);
1800 		if (it->inputs == NULL) {
1801 			printf("uaudio_io_terminaltype: no memory\n");
1802 			return NULL;
1803 		}
1804 		for (i = 0; i < it->d.su->bNrInPins; i++) {
1805 			src_id = it->d.su->baSourceId[i];
1806 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1807 							       src_id);
1808 			it->inputs_size++;
1809 		}
1810 		return uaudio_merge_terminal_list(it);
1811 	case UDESCSUB_AC_PROCESSING:
1812 		it->inputs_size = 0;
1813 		it->inputs = malloc(sizeof(struct terminal_list *)
1814 				    * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT);
1815 		if (it->inputs == NULL) {
1816 			printf("uaudio_io_terminaltype: no memory\n");
1817 			return NULL;
1818 		}
1819 		for (i = 0; i < it->d.pu->bNrInPins; i++) {
1820 			src_id = it->d.pu->baSourceId[i];
1821 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1822 							       src_id);
1823 			it->inputs_size++;
1824 		}
1825 		return uaudio_merge_terminal_list(it);
1826 	case UDESCSUB_AC_EXTENSION:
1827 		it->inputs_size = 0;
1828 		it->inputs = malloc(sizeof(struct terminal_list *)
1829 				    * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT);
1830 		if (it->inputs == NULL) {
1831 			printf("uaudio_io_terminaltype: no memory\n");
1832 			return NULL;
1833 		}
1834 		for (i = 0; i < it->d.eu->bNrInPins; i++) {
1835 			src_id = it->d.eu->baSourceId[i];
1836 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1837 							       src_id);
1838 			it->inputs_size++;
1839 		}
1840 		return uaudio_merge_terminal_list(it);
1841 	case UDESCSUB_AC_HEADER:
1842 	default:
1843 		return NULL;
1844 	}
1845 }
1846 
1847 Static usbd_status
1848 uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
1849 {
1850 	usbd_status err;
1851 
1852 	err = uaudio_identify_ac(sc, cdesc);
1853 	if (err)
1854 		return (err);
1855 	return (uaudio_identify_as(sc, cdesc));
1856 }
1857 
1858 Static void
1859 uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai)
1860 {
1861 	size_t len;
1862 	struct as_info *nai;
1863 
1864 	len = sizeof(*ai) * (sc->sc_nalts + 1);
1865 	nai = malloc(len, M_USBDEV, M_NOWAIT);
1866 	if (nai == NULL) {
1867 		printf("uaudio_add_alt: no memory\n");
1868 		return;
1869 	}
1870 	/* Copy old data, if there was any */
1871 	if (sc->sc_nalts != 0) {
1872 		memcpy(nai, sc->sc_alts, sizeof(*ai) * (sc->sc_nalts));
1873 		free(sc->sc_alts, M_USBDEV);
1874 	}
1875 	sc->sc_alts = nai;
1876 	DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
1877 		    ai->alt, ai->encoding));
1878 	sc->sc_alts[sc->sc_nalts++] = *ai;
1879 }
1880 
1881 Static usbd_status
1882 uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
1883 		  int size, const usb_interface_descriptor_t *id)
1884 #define offs (*offsp)
1885 {
1886 	const struct usb_audio_streaming_interface_descriptor *asid;
1887 	const struct usb_audio_streaming_type1_descriptor *asf1d;
1888 	const usb_endpoint_descriptor_audio_t *ed;
1889 	const usb_endpoint_descriptor_audio_t *epdesc1;
1890 	const struct usb_audio_streaming_endpoint_descriptor *sed;
1891 	int format, chan, prec, enc;
1892 	int dir, type, sync;
1893 	struct as_info ai;
1894 	const char *format_str;
1895 
1896 	asid = (const void *)(buf + offs);
1897 	if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
1898 	    asid->bDescriptorSubtype != AS_GENERAL)
1899 		return (USBD_INVAL);
1900 	DPRINTF(("uaudio_process_as: asid: bTerminakLink=%d wFormatTag=%d\n",
1901 		 asid->bTerminalLink, UGETW(asid->wFormatTag)));
1902 	offs += asid->bLength;
1903 	if (offs > size)
1904 		return (USBD_INVAL);
1905 
1906 	asf1d = (const void *)(buf + offs);
1907 	if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
1908 	    asf1d->bDescriptorSubtype != FORMAT_TYPE)
1909 		return (USBD_INVAL);
1910 	offs += asf1d->bLength;
1911 	if (offs > size)
1912 		return (USBD_INVAL);
1913 
1914 	if (asf1d->bFormatType != FORMAT_TYPE_I) {
1915 		printf("%s: ignored setting with type %d format\n",
1916 		       USBDEVNAME(sc->sc_dev), UGETW(asid->wFormatTag));
1917 		return (USBD_NORMAL_COMPLETION);
1918 	}
1919 
1920 	ed = (const void *)(buf + offs);
1921 	if (ed->bDescriptorType != UDESC_ENDPOINT)
1922 		return (USBD_INVAL);
1923 	DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
1924 		 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
1925 		 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
1926 		 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
1927 		 ed->bmAttributes, UGETW(ed->wMaxPacketSize),
1928 		 ed->bInterval, ed->bRefresh, ed->bSynchAddress));
1929 	offs += ed->bLength;
1930 	if (offs > size)
1931 		return (USBD_INVAL);
1932 	if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
1933 		return (USBD_INVAL);
1934 
1935 	dir = UE_GET_DIR(ed->bEndpointAddress);
1936 	type = UE_GET_ISO_TYPE(ed->bmAttributes);
1937 	if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
1938 	    dir == UE_DIR_IN && type == UE_ISO_ADAPT)
1939 		type = UE_ISO_ASYNC;
1940 
1941 	/* We can't handle endpoints that need a sync pipe yet. */
1942 	sync = FALSE;
1943 	if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
1944 		sync = TRUE;
1945 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1946 		printf("%s: ignored input endpoint of type adaptive\n",
1947 		       USBDEVNAME(sc->sc_dev));
1948 		return (USBD_NORMAL_COMPLETION);
1949 #endif
1950 	}
1951 	if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
1952 		sync = TRUE;
1953 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1954 		printf("%s: ignored output endpoint of type async\n",
1955 		       USBDEVNAME(sc->sc_dev));
1956 		return (USBD_NORMAL_COMPLETION);
1957 #endif
1958 	}
1959 
1960 	sed = (const void *)(buf + offs);
1961 	if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
1962 	    sed->bDescriptorSubtype != AS_GENERAL)
1963 		return (USBD_INVAL);
1964 	DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength));
1965 	offs += sed->bLength;
1966 	if (offs > size)
1967 		return (USBD_INVAL);
1968 
1969 	if (sync && id->bNumEndpoints <= 1) {
1970 		printf("%s: a sync-pipe endpoint but no other endpoint\n",
1971 		       USBDEVNAME(sc->sc_dev));
1972 		return USBD_INVAL;
1973 	}
1974 	if (!sync && id->bNumEndpoints > 1) {
1975 		printf("%s: non sync-pipe endpoint but multiple endpoints\n",
1976 		       USBDEVNAME(sc->sc_dev));
1977 		return USBD_INVAL;
1978 	}
1979 	epdesc1 = NULL;
1980 	if (id->bNumEndpoints > 1) {
1981 		epdesc1 = (const void*)(buf + offs);
1982 		if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
1983 			return USBD_INVAL;
1984 		DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
1985 			 "bDescriptorType=%d bEndpointAddress=%d "
1986 			 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
1987 			 "bRefresh=%d bSynchAddress=%d\n",
1988 			 epdesc1->bLength, epdesc1->bDescriptorType,
1989 			 epdesc1->bEndpointAddress, epdesc1->bmAttributes,
1990 			 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
1991 			 epdesc1->bRefresh, epdesc1->bSynchAddress));
1992 		offs += epdesc1->bLength;
1993 		if (offs > size)
1994 			return USBD_INVAL;
1995 		if (epdesc1->bSynchAddress != 0) {
1996 			printf("%s: invalid endpoint: bSynchAddress=0\n",
1997 			       USBDEVNAME(sc->sc_dev));
1998 			return USBD_INVAL;
1999 		}
2000 		if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
2001 			printf("%s: invalid endpoint: bmAttributes=0x%x\n",
2002 			       USBDEVNAME(sc->sc_dev), epdesc1->bmAttributes);
2003 			return USBD_INVAL;
2004 		}
2005 		if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
2006 			printf("%s: invalid endpoint addresses: "
2007 			       "ep[0]->bSynchAddress=0x%x "
2008 			       "ep[1]->bEndpointAddress=0x%x\n",
2009 			       USBDEVNAME(sc->sc_dev), ed->bSynchAddress,
2010 			       epdesc1->bEndpointAddress);
2011 			return USBD_INVAL;
2012 		}
2013 		/* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
2014 	}
2015 
2016 	format = UGETW(asid->wFormatTag);
2017 	chan = asf1d->bNrChannels;
2018 	prec = asf1d->bBitResolution;
2019 	if (prec != 8 && prec != 16 && prec != 24) {
2020 		printf("%s: ignored setting with precision %d\n",
2021 		       USBDEVNAME(sc->sc_dev), prec);
2022 		return (USBD_NORMAL_COMPLETION);
2023 	}
2024 	switch (format) {
2025 	case UA_FMT_PCM:
2026 		if (prec == 8) {
2027 			sc->sc_altflags |= HAS_8;
2028 		} else if (prec == 16) {
2029 			sc->sc_altflags |= HAS_16;
2030 		} else if (prec == 24) {
2031 			sc->sc_altflags |= HAS_24;
2032 		}
2033 		enc = AUDIO_ENCODING_SLINEAR_LE;
2034 		format_str = "pcm";
2035 		break;
2036 	case UA_FMT_PCM8:
2037 		enc = AUDIO_ENCODING_ULINEAR_LE;
2038 		sc->sc_altflags |= HAS_8U;
2039 		format_str = "pcm8";
2040 		break;
2041 	case UA_FMT_ALAW:
2042 		enc = AUDIO_ENCODING_ALAW;
2043 		sc->sc_altflags |= HAS_ALAW;
2044 		format_str = "alaw";
2045 		break;
2046 	case UA_FMT_MULAW:
2047 		enc = AUDIO_ENCODING_ULAW;
2048 		sc->sc_altflags |= HAS_MULAW;
2049 		format_str = "mulaw";
2050 		break;
2051 	case UA_FMT_IEEE_FLOAT:
2052 	default:
2053 		printf("%s: ignored setting with format %d\n",
2054 		       USBDEVNAME(sc->sc_dev), format);
2055 		return (USBD_NORMAL_COMPLETION);
2056 	}
2057 #ifdef USB_DEBUG
2058 	printf("%s: %s: %dch, %d/%dbit, %s,", USBDEVNAME(sc->sc_dev),
2059 	       dir == UE_DIR_IN ? "recording" : "playback",
2060 	       chan, prec, asf1d->bSubFrameSize * 8, format_str);
2061 	if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2062 		printf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
2063 	} else {
2064 		int r;
2065 		printf(" %d", UA_GETSAMP(asf1d, 0));
2066 		for (r = 1; r < asf1d->bSamFreqType; r++)
2067 			printf(",%d", UA_GETSAMP(asf1d, r));
2068 		printf("Hz\n");
2069 	}
2070 #endif
2071 	ai.alt = id->bAlternateSetting;
2072 	ai.encoding = enc;
2073 	ai.attributes = sed->bmAttributes;
2074 	ai.idesc = id;
2075 	ai.edesc = ed;
2076 	ai.edesc1 = epdesc1;
2077 	ai.asf1desc = asf1d;
2078 	ai.sc_busy = 0;
2079 	uaudio_add_alt(sc, &ai);
2080 #ifdef USB_DEBUG
2081 	if (ai.attributes & UA_SED_FREQ_CONTROL)
2082 		DPRINTFN(1, ("uaudio_process_as:  FREQ_CONTROL\n"));
2083 	if (ai.attributes & UA_SED_PITCH_CONTROL)
2084 		DPRINTFN(1, ("uaudio_process_as:  PITCH_CONTROL\n"));
2085 #endif
2086 	sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD;
2087 
2088 	return (USBD_NORMAL_COMPLETION);
2089 }
2090 #undef offs
2091 
2092 Static usbd_status
2093 uaudio_identify_as(struct uaudio_softc *sc,
2094 		   const usb_config_descriptor_t *cdesc)
2095 {
2096 	const usb_interface_descriptor_t *id;
2097 	const char *buf;
2098 	int size, offs;
2099 
2100 	size = UGETW(cdesc->wTotalLength);
2101 	buf = (const char *)cdesc;
2102 
2103 	/* Locate the AudioStreaming interface descriptor. */
2104 	offs = 0;
2105 	id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
2106 	if (id == NULL)
2107 		return (USBD_INVAL);
2108 
2109 	/* Loop through all the alternate settings. */
2110 	while (offs <= size) {
2111 		DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
2112 		    id->bInterfaceNumber, offs));
2113 		switch (id->bNumEndpoints) {
2114 		case 0:
2115 			DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
2116 				     id->bAlternateSetting));
2117 			sc->sc_nullalt = id->bAlternateSetting;
2118 			break;
2119 		case 1:
2120 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
2121 		case 2:
2122 #endif
2123 			uaudio_process_as(sc, buf, &offs, size, id);
2124 			break;
2125 		default:
2126 			printf("%s: ignored audio interface with %d "
2127 			       "endpoints\n",
2128 			       USBDEVNAME(sc->sc_dev), id->bNumEndpoints);
2129 			break;
2130 		}
2131 		id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
2132 		if (id == NULL)
2133 			break;
2134 	}
2135 	if (offs > size)
2136 		return (USBD_INVAL);
2137 	DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
2138 
2139 	if (sc->sc_mode == 0) {
2140 		printf("%s: no usable endpoint found\n",
2141 		       USBDEVNAME(sc->sc_dev));
2142 		return (USBD_INVAL);
2143 	}
2144 
2145 	return (USBD_NORMAL_COMPLETION);
2146 }
2147 
2148 Static usbd_status
2149 uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
2150 {
2151 	struct io_terminal* iot;
2152 	const usb_interface_descriptor_t *id;
2153 	const struct usb_audio_control_descriptor *acdp;
2154 	const usb_descriptor_t *dp;
2155 	const struct usb_audio_output_terminal *pot;
2156 	struct terminal_list *tml;
2157 	const char *buf, *ibuf, *ibufend;
2158 	int size, offs, aclen, ndps, i, j;
2159 
2160 	size = UGETW(cdesc->wTotalLength);
2161 	buf = (const char *)cdesc;
2162 
2163 	/* Locate the AudioControl interface descriptor. */
2164 	offs = 0;
2165 	id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
2166 	if (id == NULL)
2167 		return (USBD_INVAL);
2168 	if (offs + sizeof *acdp > size)
2169 		return (USBD_INVAL);
2170 	sc->sc_ac_iface = id->bInterfaceNumber;
2171 	DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface));
2172 
2173 	/* A class-specific AC interface header should follow. */
2174 	ibuf = buf + offs;
2175 	acdp = (const struct usb_audio_control_descriptor *)ibuf;
2176 	if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
2177 	    acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
2178 		return (USBD_INVAL);
2179 	aclen = UGETW(acdp->wTotalLength);
2180 	if (offs + aclen > size)
2181 		return (USBD_INVAL);
2182 
2183 	if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
2184 	     UGETW(acdp->bcdADC) != UAUDIO_VERSION)
2185 		return (USBD_INVAL);
2186 
2187 	sc->sc_audio_rev = UGETW(acdp->bcdADC);
2188 	DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n",
2189 		 sc->sc_audio_rev, aclen));
2190 
2191 	sc->sc_nullalt = -1;
2192 
2193 	/* Scan through all the AC specific descriptors */
2194 	ibufend = ibuf + aclen;
2195 	dp = (const usb_descriptor_t *)ibuf;
2196 	ndps = 0;
2197 	iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO);
2198 	if (iot == NULL) {
2199 		printf("%s: no memory\n", __func__);
2200 		return USBD_NOMEM;
2201 	}
2202 	for (;;) {
2203 		ibuf += dp->bLength;
2204 		if (ibuf >= ibufend)
2205 			break;
2206 		dp = (const usb_descriptor_t *)ibuf;
2207 		if (ibuf + dp->bLength > ibufend)
2208 			return (USBD_INVAL);
2209 		if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
2210 			printf("uaudio_identify_ac: skip desc type=0x%02x\n",
2211 			       dp->bDescriptorType);
2212 			continue;
2213 		}
2214 		i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId;
2215 		iot[i].d.desc = dp;
2216 		if (i > ndps)
2217 			ndps = i;
2218 	}
2219 	ndps++;
2220 
2221 	/* construct io_terminal */
2222 	for (i = 0; i < ndps; i++) {
2223 		dp = iot[i].d.desc;
2224 		if (dp == NULL)
2225 			continue;
2226 		if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT)
2227 			continue;
2228 		pot = iot[i].d.ot;
2229 		tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i);
2230 		if (tml != NULL)
2231 			free(tml, M_TEMP);
2232 	}
2233 
2234 #ifdef USB_DEBUG
2235 	for (i = 0; i < 256; i++) {
2236 		struct usb_audio_cluster cluster;
2237 
2238 		if (iot[i].d.desc == NULL)
2239 			continue;
2240 		logprintf("id %d:\t", i);
2241 		switch (iot[i].d.desc->bDescriptorSubtype) {
2242 		case UDESCSUB_AC_INPUT:
2243 			logprintf("AC_INPUT type=%s\n", uaudio_get_terminal_name
2244 				  (UGETW(iot[i].d.it->wTerminalType)));
2245 			logprintf("\t");
2246 			cluster = uaudio_get_cluster(i, iot);
2247 			uaudio_dump_cluster(&cluster);
2248 			logprintf("\n");
2249 			break;
2250 		case UDESCSUB_AC_OUTPUT:
2251 			logprintf("AC_OUTPUT type=%s ", uaudio_get_terminal_name
2252 				  (UGETW(iot[i].d.ot->wTerminalType)));
2253 			logprintf("src=%d\n", iot[i].d.ot->bSourceId);
2254 			break;
2255 		case UDESCSUB_AC_MIXER:
2256 			logprintf("AC_MIXER src=");
2257 			for (j = 0; j < iot[i].d.mu->bNrInPins; j++)
2258 				logprintf("%d ", iot[i].d.mu->baSourceId[j]);
2259 			logprintf("\n\t");
2260 			cluster = uaudio_get_cluster(i, iot);
2261 			uaudio_dump_cluster(&cluster);
2262 			logprintf("\n");
2263 			break;
2264 		case UDESCSUB_AC_SELECTOR:
2265 			logprintf("AC_SELECTOR src=");
2266 			for (j = 0; j < iot[i].d.su->bNrInPins; j++)
2267 				logprintf("%d ", iot[i].d.su->baSourceId[j]);
2268 			logprintf("\n");
2269 			break;
2270 		case UDESCSUB_AC_FEATURE:
2271 			logprintf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId);
2272 			break;
2273 		case UDESCSUB_AC_PROCESSING:
2274 			logprintf("AC_PROCESSING src=");
2275 			for (j = 0; j < iot[i].d.pu->bNrInPins; j++)
2276 				logprintf("%d ", iot[i].d.pu->baSourceId[j]);
2277 			logprintf("\n\t");
2278 			cluster = uaudio_get_cluster(i, iot);
2279 			uaudio_dump_cluster(&cluster);
2280 			logprintf("\n");
2281 			break;
2282 		case UDESCSUB_AC_EXTENSION:
2283 			logprintf("AC_EXTENSION src=");
2284 			for (j = 0; j < iot[i].d.eu->bNrInPins; j++)
2285 				logprintf("%d ", iot[i].d.eu->baSourceId[j]);
2286 			logprintf("\n\t");
2287 			cluster = uaudio_get_cluster(i, iot);
2288 			uaudio_dump_cluster(&cluster);
2289 			logprintf("\n");
2290 			break;
2291 		default:
2292 			logprintf("unknown audio control (subtype=%d)\n",
2293 				  iot[i].d.desc->bDescriptorSubtype);
2294 		}
2295 		for (j = 0; j < iot[i].inputs_size; j++) {
2296 			int k;
2297 			logprintf("\tinput%d: ", j);
2298 			tml = iot[i].inputs[j];
2299 			if (tml == NULL) {
2300 				logprintf("NULL\n");
2301 				continue;
2302 			}
2303 			for (k = 0; k < tml->size; k++)
2304 				logprintf("%s ", uaudio_get_terminal_name
2305 					  (tml->terminals[k]));
2306 			logprintf("\n");
2307 		}
2308 		logprintf("\toutput: ");
2309 		tml = iot[i].output;
2310 		for (j = 0; j < tml->size; j++)
2311 			logprintf("%s ", uaudio_get_terminal_name(tml->terminals[j]));
2312 		logprintf("\n");
2313 	}
2314 #endif
2315 
2316 	for (i = 0; i < ndps; i++) {
2317 		dp = iot[i].d.desc;
2318 		if (dp == NULL)
2319 			continue;
2320 		DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n",
2321 			 i, dp->bDescriptorSubtype));
2322 		switch (dp->bDescriptorSubtype) {
2323 		case UDESCSUB_AC_HEADER:
2324 			printf("uaudio_identify_ac: unexpected AC header\n");
2325 			break;
2326 		case UDESCSUB_AC_INPUT:
2327 			uaudio_add_input(sc, iot, i);
2328 			break;
2329 		case UDESCSUB_AC_OUTPUT:
2330 			uaudio_add_output(sc, iot, i);
2331 			break;
2332 		case UDESCSUB_AC_MIXER:
2333 			uaudio_add_mixer(sc, iot, i);
2334 			break;
2335 		case UDESCSUB_AC_SELECTOR:
2336 			uaudio_add_selector(sc, iot, i);
2337 			break;
2338 		case UDESCSUB_AC_FEATURE:
2339 			uaudio_add_feature(sc, iot, i);
2340 			break;
2341 		case UDESCSUB_AC_PROCESSING:
2342 			uaudio_add_processing(sc, iot, i);
2343 			break;
2344 		case UDESCSUB_AC_EXTENSION:
2345 			uaudio_add_extension(sc, iot, i);
2346 			break;
2347 		default:
2348 			printf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n",
2349 			       dp->bDescriptorSubtype);
2350 			break;
2351 		}
2352 	}
2353 
2354 	/* delete io_terminal */
2355 	for (i = 0; i < 256; i++) {
2356 		if (iot[i].d.desc == NULL)
2357 			continue;
2358 		if (iot[i].inputs != NULL) {
2359 			for (j = 0; j < iot[i].inputs_size; j++) {
2360 				if (iot[i].inputs[j] != NULL)
2361 					free(iot[i].inputs[j], M_TEMP);
2362 			}
2363 			free(iot[i].inputs, M_TEMP);
2364 		}
2365 		if (iot[i].output != NULL)
2366 			free(iot[i].output, M_TEMP);
2367 		iot[i].d.desc = NULL;
2368 	}
2369 	free(iot, M_TEMP);
2370 
2371 	return (USBD_NORMAL_COMPLETION);
2372 }
2373 
2374 #if defined(__NetBSD__) || defined(__OpenBSD__)
2375 Static int
2376 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
2377 {
2378 	struct uaudio_softc *sc = addr;
2379 	struct mixerctl *mc;
2380 	int n, nctls, i;
2381 
2382 	DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index));
2383 	if (sc->sc_dying)
2384 		return (EIO);
2385 
2386 	n = mi->index;
2387 	nctls = sc->sc_nctls;
2388 
2389 	switch (n) {
2390 	case UAC_OUTPUT:
2391 		mi->type = AUDIO_MIXER_CLASS;
2392 		mi->mixer_class = UAC_OUTPUT;
2393 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2394 		strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name));
2395 		return (0);
2396 	case UAC_INPUT:
2397 		mi->type = AUDIO_MIXER_CLASS;
2398 		mi->mixer_class = UAC_INPUT;
2399 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2400 		strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name));
2401 		return (0);
2402 	case UAC_EQUAL:
2403 		mi->type = AUDIO_MIXER_CLASS;
2404 		mi->mixer_class = UAC_EQUAL;
2405 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2406 		strlcpy(mi->label.name, AudioCequalization,
2407 		    sizeof(mi->label.name));
2408 		return (0);
2409 	case UAC_RECORD:
2410 		mi->type = AUDIO_MIXER_CLASS;
2411 		mi->mixer_class = UAC_RECORD;
2412 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2413 		strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name));
2414 		return 0;
2415 	default:
2416 		break;
2417 	}
2418 
2419 	n -= UAC_NCLASSES;
2420 	if (n < 0 || n >= nctls)
2421 		return (ENXIO);
2422 
2423 	mc = &sc->sc_ctls[n];
2424 	strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name));
2425 	mi->mixer_class = mc->class;
2426 	mi->next = mi->prev = AUDIO_MIXER_LAST;	/* XXX */
2427 	switch (mc->type) {
2428 	case MIX_ON_OFF:
2429 		mi->type = AUDIO_MIXER_ENUM;
2430 		mi->un.e.num_mem = 2;
2431 		strlcpy(mi->un.e.member[0].label.name, AudioNoff,
2432 		    sizeof(mi->un.e.member[0].label.name));
2433 		mi->un.e.member[0].ord = 0;
2434 		strlcpy(mi->un.e.member[1].label.name, AudioNon,
2435 		    sizeof(mi->un.e.member[1].label.name));
2436 		mi->un.e.member[1].ord = 1;
2437 		break;
2438 	case MIX_SELECTOR:
2439 		mi->type = AUDIO_MIXER_ENUM;
2440 		mi->un.e.num_mem = mc->maxval - mc->minval + 1;
2441 		for (i = 0; i <= mc->maxval - mc->minval; i++) {
2442 			snprintf(mi->un.e.member[i].label.name,
2443 				 sizeof(mi->un.e.member[i].label.name),
2444 				 "%d", i + mc->minval);
2445 			mi->un.e.member[i].ord = i + mc->minval;
2446 		}
2447 		break;
2448 	default:
2449 		mi->type = AUDIO_MIXER_VALUE;
2450 		strncpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN);
2451 		mi->un.v.num_channels = mc->nchan;
2452 		mi->un.v.delta = mc->delta;
2453 		break;
2454 	}
2455 	return (0);
2456 }
2457 
2458 Static int
2459 uaudio_open(void *addr, int flags)
2460 {
2461 	struct uaudio_softc *sc = addr;
2462 
2463 	DPRINTF(("uaudio_open: sc=%p\n", sc));
2464 	if (sc->sc_dying)
2465 		return (EIO);
2466 
2467 	if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY))
2468 		return (EACCES);
2469 	if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD))
2470 		return (EACCES);
2471 
2472 	return (0);
2473 }
2474 
2475 /*
2476  * Close function is called at splaudio().
2477  */
2478 Static void
2479 uaudio_close(void *addr)
2480 {
2481 }
2482 
2483 Static int
2484 uaudio_drain(void *addr)
2485 {
2486 	struct uaudio_softc *sc = addr;
2487 
2488 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
2489 
2490 	return (0);
2491 }
2492 
2493 Static int
2494 uaudio_halt_out_dma(void *addr)
2495 {
2496 	struct uaudio_softc *sc = addr;
2497 
2498 	if (sc->sc_dying)
2499 		return (EIO);
2500 
2501 	DPRINTF(("uaudio_halt_out_dma: enter\n"));
2502 	if (sc->sc_playchan.pipe != NULL) {
2503 		uaudio_chan_close(sc, &sc->sc_playchan);
2504 		sc->sc_playchan.pipe = NULL;
2505 		uaudio_chan_free_buffers(sc, &sc->sc_playchan);
2506 		sc->sc_playchan.intr = NULL;
2507 	}
2508 	return (0);
2509 }
2510 
2511 Static int
2512 uaudio_halt_in_dma(void *addr)
2513 {
2514 	struct uaudio_softc *sc = addr;
2515 
2516 	DPRINTF(("uaudio_halt_in_dma: enter\n"));
2517 	if (sc->sc_recchan.pipe != NULL) {
2518 		uaudio_chan_close(sc, &sc->sc_recchan);
2519 		sc->sc_recchan.pipe = NULL;
2520 		uaudio_chan_free_buffers(sc, &sc->sc_recchan);
2521 		sc->sc_recchan.intr = NULL;
2522 	}
2523 	return (0);
2524 }
2525 
2526 Static int
2527 uaudio_getdev(void *addr, struct audio_device *retp)
2528 {
2529 	struct uaudio_softc *sc = addr;
2530 
2531 	DPRINTF(("uaudio_mixer_getdev:\n"));
2532 	if (sc->sc_dying)
2533 		return (EIO);
2534 
2535 	*retp = uaudio_device;
2536 	return (0);
2537 }
2538 
2539 /*
2540  * Make sure the block size is large enough to hold all outstanding transfers.
2541  */
2542 Static int
2543 uaudio_round_blocksize(void *addr, int blk)
2544 {
2545 	struct uaudio_softc *sc = addr;
2546 	int bpf;
2547 
2548 	DPRINTF(("uaudio_round_blocksize: p.bpf=%d r.bpf=%d\n",
2549 		 sc->sc_playchan.bytes_per_frame,
2550 		 sc->sc_recchan.bytes_per_frame));
2551 	if (sc->sc_playchan.bytes_per_frame > sc->sc_recchan.bytes_per_frame) {
2552 		bpf = sc->sc_playchan.bytes_per_frame
2553 		    + sc->sc_playchan.sample_size;
2554 	} else {
2555 		bpf = sc->sc_recchan.bytes_per_frame
2556 		    + sc->sc_recchan.sample_size;
2557 	}
2558 	/* XXX */
2559 	bpf *= UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
2560 
2561 	bpf = (bpf + 15) &~ 15;
2562 
2563 	if (blk < bpf)
2564 		blk = bpf;
2565 
2566 #ifdef DIAGNOSTIC
2567 	if (blk <= 0) {
2568 		printf("uaudio_round_blocksize: blk=%d\n", blk);
2569 		blk = 512;
2570 	}
2571 #endif
2572 
2573 	DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk));
2574 	return (blk);
2575 }
2576 
2577 Static int
2578 uaudio_get_props(void *addr)
2579 {
2580 	return (AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT);
2581 
2582 }
2583 #endif	/* NetBSD or OpenBSD */
2584 
2585 Static int
2586 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
2587 	   int wIndex, int len)
2588 {
2589 	usb_device_request_t req;
2590 	u_int8_t data[4];
2591 	usbd_status err;
2592 	int val;
2593 
2594 #if defined(__FreeBSD__)
2595 	if (sc->sc_dying)
2596 		return (EIO);
2597 #endif
2598 
2599 	if (wValue == -1)
2600 		return (0);
2601 
2602 	req.bmRequestType = type;
2603 	req.bRequest = which;
2604 	USETW(req.wValue, wValue);
2605 	USETW(req.wIndex, wIndex);
2606 	USETW(req.wLength, len);
2607 	DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
2608 		    "wIndex=0x%04x len=%d\n",
2609 		    type, which, wValue, wIndex, len));
2610 	err = usbd_do_request(sc->sc_udev, &req, data);
2611 	if (err) {
2612 		DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
2613 		return (-1);
2614 	}
2615 	switch (len) {
2616 	case 1:
2617 		val = data[0];
2618 		break;
2619 	case 2:
2620 		val = data[0] | (data[1] << 8);
2621 		break;
2622 	default:
2623 		DPRINTF(("uaudio_get: bad length=%d\n", len));
2624 		return (-1);
2625 	}
2626 	DPRINTFN(2,("uaudio_get: val=%d\n", val));
2627 	return (val);
2628 }
2629 
2630 Static void
2631 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
2632 	   int wIndex, int len, int val)
2633 {
2634 	usb_device_request_t req;
2635 	u_int8_t data[4];
2636 	usbd_status err;
2637 
2638 #if defined(__FreeBSD__)
2639 	if (sc->sc_dying)
2640 		return;
2641 #endif
2642 
2643 	if (wValue == -1)
2644 		return;
2645 
2646 	req.bmRequestType = type;
2647 	req.bRequest = which;
2648 	USETW(req.wValue, wValue);
2649 	USETW(req.wIndex, wIndex);
2650 	USETW(req.wLength, len);
2651 	switch (len) {
2652 	case 1:
2653 		data[0] = val;
2654 		break;
2655 	case 2:
2656 		data[0] = val;
2657 		data[1] = val >> 8;
2658 		break;
2659 	default:
2660 		return;
2661 	}
2662 	DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
2663 		    "wIndex=0x%04x len=%d, val=%d\n",
2664 		    type, which, wValue, wIndex, len, val & 0xffff));
2665 	err = usbd_do_request(sc->sc_udev, &req, data);
2666 #ifdef USB_DEBUG
2667 	if (err)
2668 		DPRINTF(("uaudio_set: err=%d\n", err));
2669 #endif
2670 }
2671 
2672 Static int
2673 uaudio_signext(int type, int val)
2674 {
2675 	if (!MIX_UNSIGNED(type)) {
2676 		if (MIX_SIZE(type) == 2)
2677 			val = (int16_t)val;
2678 		else
2679 			val = (int8_t)val;
2680 	}
2681 	return (val);
2682 }
2683 
2684 #if defined(__NetBSD__) || defined(__OpenBSD__)
2685 Static int
2686 uaudio_value2bsd(struct mixerctl *mc, int val)
2687 {
2688 	DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
2689 		     mc->type, val, mc->minval, mc->maxval));
2690 	if (mc->type == MIX_ON_OFF) {
2691 		val = (val != 0);
2692 	} else if (mc->type == MIX_SELECTOR) {
2693 		if (val < mc->minval || val > mc->maxval)
2694 			val = mc->minval;
2695 	} else
2696 		val = ((uaudio_signext(mc->type, val) - mc->minval) * 255
2697 			+ mc->mul/2) / mc->mul;
2698 	DPRINTFN(5, ("val'=%d\n", val));
2699 	return (val);
2700 }
2701 #endif
2702 
2703 int
2704 uaudio_bsd2value(struct mixerctl *mc, int val)
2705 {
2706 	DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
2707 		    mc->type, val, mc->minval, mc->maxval));
2708 	if (mc->type == MIX_ON_OFF) {
2709 		val = (val != 0);
2710 	} else if (mc->type == MIX_SELECTOR) {
2711 		if (val < mc->minval || val > mc->maxval)
2712 			val = mc->minval;
2713 	} else
2714 		val = (val + mc->delta/2) * mc->mul / 255 + mc->minval;
2715 	DPRINTFN(5, ("val'=%d\n", val));
2716 	return (val);
2717 }
2718 
2719 #if defined(__NetBSD__) || defined(__OpenBSD__)
2720 Static int
2721 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2722 	       int chan)
2723 {
2724 	int val;
2725 
2726 	DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan));
2727 	val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
2728 			 mc->wIndex, MIX_SIZE(mc->type));
2729 	return (uaudio_value2bsd(mc, val));
2730 }
2731 #endif
2732 
2733 Static void
2734 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2735 	       int chan, int val)
2736 {
2737 	val = uaudio_bsd2value(mc, val);
2738 	uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
2739 		   mc->wIndex, MIX_SIZE(mc->type), val);
2740 }
2741 
2742 #if defined(__NetBSD__) || defined(__OpenBSD__)
2743 Static int
2744 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
2745 {
2746 	struct uaudio_softc *sc = addr;
2747 	struct mixerctl *mc;
2748 	int i, n, vals[MIX_MAX_CHAN], val;
2749 
2750 	DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev));
2751 
2752 	if (sc->sc_dying)
2753 		return (EIO);
2754 
2755 	n = cp->dev - UAC_NCLASSES;
2756 	if (n < 0 || n >= sc->sc_nctls)
2757 		return (ENXIO);
2758 	mc = &sc->sc_ctls[n];
2759 
2760 	if (mc->type == MIX_ON_OFF) {
2761 		if (cp->type != AUDIO_MIXER_ENUM)
2762 			return (EINVAL);
2763 		cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2764 	} else if (mc->type == MIX_SELECTOR) {
2765 		if (cp->type != AUDIO_MIXER_ENUM)
2766 			return (EINVAL);
2767 		cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2768 	} else {
2769 		if (cp->type != AUDIO_MIXER_VALUE)
2770 			return (EINVAL);
2771 		if (cp->un.value.num_channels != 1 &&
2772 		    cp->un.value.num_channels != mc->nchan)
2773 			return (EINVAL);
2774 		for (i = 0; i < mc->nchan; i++)
2775 			vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
2776 		if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
2777 			for (val = 0, i = 0; i < mc->nchan; i++)
2778 				val += vals[i];
2779 			vals[0] = val / mc->nchan;
2780 		}
2781 		for (i = 0; i < cp->un.value.num_channels; i++)
2782 			cp->un.value.level[i] = vals[i];
2783 	}
2784 
2785 	return (0);
2786 }
2787 
2788 Static int
2789 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
2790 {
2791 	struct uaudio_softc *sc = addr;
2792 	struct mixerctl *mc;
2793 	int i, n, vals[MIX_MAX_CHAN];
2794 
2795 	DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev));
2796 	if (sc->sc_dying)
2797 		return (EIO);
2798 
2799 	n = cp->dev - UAC_NCLASSES;
2800 	if (n < 0 || n >= sc->sc_nctls)
2801 		return (ENXIO);
2802 	mc = &sc->sc_ctls[n];
2803 
2804 	if (mc->type == MIX_ON_OFF) {
2805 		if (cp->type != AUDIO_MIXER_ENUM)
2806 			return (EINVAL);
2807 		uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2808 	} else if (mc->type == MIX_SELECTOR) {
2809 		if (cp->type != AUDIO_MIXER_ENUM)
2810 			return (EINVAL);
2811 		uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2812 	} else {
2813 		if (cp->type != AUDIO_MIXER_VALUE)
2814 			return (EINVAL);
2815 		if (cp->un.value.num_channels == 1)
2816 			for (i = 0; i < mc->nchan; i++)
2817 				vals[i] = cp->un.value.level[0];
2818 		else if (cp->un.value.num_channels == mc->nchan)
2819 			for (i = 0; i < mc->nchan; i++)
2820 				vals[i] = cp->un.value.level[i];
2821 		else
2822 			return (EINVAL);
2823 		for (i = 0; i < mc->nchan; i++)
2824 			uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
2825 	}
2826 	return (0);
2827 }
2828 
2829 Static int
2830 uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
2831 		     void (*intr)(void *), void *arg,
2832 		     struct audio_params *param)
2833 {
2834 	struct uaudio_softc *sc = addr;
2835 	struct chan *ch = &sc->sc_recchan;
2836 	usbd_status err;
2837 	int i, s;
2838 
2839 	if (sc->sc_dying)
2840 		return (EIO);
2841 
2842 	DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
2843 		    "blksize=%d\n", sc, start, end, blksize));
2844 
2845 	uaudio_chan_set_param(ch, start, end, blksize);
2846 	DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
2847 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2848 		    ch->fraction));
2849 
2850 	err = uaudio_chan_alloc_buffers(sc, ch);
2851 	if (err)
2852 		return (EIO);
2853 
2854 	err = uaudio_chan_open(sc, ch);
2855 	if (err) {
2856 		uaudio_chan_free_buffers(sc, ch);
2857 		return (EIO);
2858 	}
2859 
2860 	ch->intr = intr;
2861 	ch->arg = arg;
2862 
2863 	s = splusb();
2864 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
2865 		uaudio_chan_rtransfer(ch);
2866 	splx(s);
2867 
2868 	return (0);
2869 }
2870 
2871 Static int
2872 uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
2873 		      void (*intr)(void *), void *arg,
2874 		      struct audio_params *param)
2875 {
2876 	struct uaudio_softc *sc = addr;
2877 	struct chan *ch = &sc->sc_playchan;
2878 	usbd_status err;
2879 	int i, s;
2880 
2881 	if (sc->sc_dying)
2882 		return (EIO);
2883 
2884 	DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
2885 		    "blksize=%d\n", sc, start, end, blksize));
2886 
2887 	uaudio_chan_set_param(ch, start, end, blksize);
2888 	DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
2889 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2890 		    ch->fraction));
2891 
2892 	err = uaudio_chan_alloc_buffers(sc, ch);
2893 	if (err)
2894 		return (EIO);
2895 
2896 	err = uaudio_chan_open(sc, ch);
2897 	if (err) {
2898 		uaudio_chan_free_buffers(sc, ch);
2899 		return (EIO);
2900 	}
2901 
2902 	ch->intr = intr;
2903 	ch->arg = arg;
2904 
2905 	s = splusb();
2906 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
2907 		uaudio_chan_ptransfer(ch);
2908 	splx(s);
2909 
2910 	return (0);
2911 }
2912 #endif	/* NetBSD or OpenBSD */
2913 
2914 /* Set up a pipe for a channel. */
2915 Static usbd_status
2916 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
2917 {
2918 	struct as_info *as = &sc->sc_alts[ch->altidx];
2919 	int endpt = as->edesc->bEndpointAddress;
2920 	usbd_status err;
2921 
2922 #if defined(__FreeBSD__)
2923 	if (sc->sc_dying)
2924 		return (EIO);
2925 #endif
2926 
2927 	DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n",
2928 		 endpt, ch->sample_rate, as->alt));
2929 
2930 	/* Set alternate interface corresponding to the mode. */
2931 	err = usbd_set_interface(as->ifaceh, as->alt);
2932 	if (err)
2933 		return (err);
2934 
2935 	/*
2936 	 * If just one sampling rate is supported,
2937 	 * no need to call uaudio_set_speed().
2938 	 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request.
2939 	 */
2940 	if (as->asf1desc->bSamFreqType != 1) {
2941 		err = uaudio_set_speed(sc, endpt, ch->sample_rate);
2942 		if (err)
2943 			DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
2944 				 usbd_errstr(err)));
2945 	}
2946 
2947 	ch->pipe = 0;
2948 	ch->sync_pipe = 0;
2949 	DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt));
2950 	err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
2951 	if (err)
2952 		return err;
2953 	if (as->edesc1 != NULL) {
2954 		endpt = as->edesc1->bEndpointAddress;
2955 		DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt));
2956 		err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe);
2957 	}
2958 	return err;
2959 }
2960 
2961 Static void
2962 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
2963 {
2964 	struct as_info *as = &sc->sc_alts[ch->altidx];
2965 
2966 #if defined(__FreeBSD__)
2967 	if (sc->sc_dying)
2968 		return ;
2969 #endif
2970 
2971 	as->sc_busy = 0;
2972 	if (sc->sc_nullalt >= 0) {
2973 		DPRINTF(("uaudio_chan_close: set null alt=%d\n",
2974 			 sc->sc_nullalt));
2975 		usbd_set_interface(as->ifaceh, sc->sc_nullalt);
2976 	}
2977 	if (ch->pipe) {
2978 		usbd_abort_pipe(ch->pipe);
2979 		usbd_close_pipe(ch->pipe);
2980 	}
2981 	if (ch->sync_pipe) {
2982 		usbd_abort_pipe(ch->sync_pipe);
2983 		usbd_close_pipe(ch->sync_pipe);
2984 	}
2985 }
2986 
2987 Static usbd_status
2988 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
2989 {
2990 	usbd_xfer_handle xfer;
2991 	void *buf;
2992 	int i, size;
2993 
2994 	size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
2995 	for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
2996 		xfer = usbd_alloc_xfer(sc->sc_udev);
2997 		if (xfer == 0)
2998 			goto bad;
2999 		ch->chanbufs[i].xfer = xfer;
3000 		buf = usbd_alloc_buffer(xfer, size);
3001 		if (buf == 0) {
3002 			i++;
3003 			goto bad;
3004 		}
3005 		ch->chanbufs[i].buffer = buf;
3006 		ch->chanbufs[i].chan = ch;
3007 	}
3008 
3009 	return (USBD_NORMAL_COMPLETION);
3010 
3011 bad:
3012 	while (--i >= 0)
3013 		/* implicit buffer free */
3014 		usbd_free_xfer(ch->chanbufs[i].xfer);
3015 	return (USBD_NOMEM);
3016 }
3017 
3018 Static void
3019 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
3020 {
3021 	int i;
3022 
3023 	for (i = 0; i < UAUDIO_NCHANBUFS; i++)
3024 		usbd_free_xfer(ch->chanbufs[i].xfer);
3025 }
3026 
3027 /* Called at splusb() */
3028 Static void
3029 uaudio_chan_ptransfer(struct chan *ch)
3030 {
3031 	struct chanbuf *cb;
3032 	int i, n, size, residue, total;
3033 
3034 	if (ch->sc->sc_dying)
3035 		return;
3036 
3037 	/* Pick the next channel buffer. */
3038 	cb = &ch->chanbufs[ch->curchanbuf];
3039 	if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
3040 		ch->curchanbuf = 0;
3041 
3042 	/* Compute the size of each frame in the next transfer. */
3043 	residue = ch->residue;
3044 	total = 0;
3045 	for (i = 0; i < UAUDIO_NFRAMES; i++) {
3046 		size = ch->bytes_per_frame;
3047 		residue += ch->fraction;
3048 		if (residue >= USB_FRAMES_PER_SECOND) {
3049 			if ((ch->sc->sc_altflags & UA_NOFRAC) == 0)
3050 				size += ch->sample_size;
3051 			residue -= USB_FRAMES_PER_SECOND;
3052 		}
3053 		cb->sizes[i] = size;
3054 		total += size;
3055 	}
3056 	ch->residue = residue;
3057 	cb->size = total;
3058 
3059 	/*
3060 	 * Transfer data from upper layer buffer to channel buffer, taking
3061 	 * care of wrapping the upper layer buffer.
3062 	 */
3063 	n = min(total, ch->end - ch->cur);
3064 	memcpy(cb->buffer, ch->cur, n);
3065 	ch->cur += n;
3066 	if (ch->cur >= ch->end)
3067 		ch->cur = ch->start;
3068 	if (total > n) {
3069 		total -= n;
3070 		memcpy(cb->buffer + n, ch->cur, total);
3071 		ch->cur += total;
3072 	}
3073 
3074 #ifdef USB_DEBUG
3075 	if (uaudiodebug > 8) {
3076 		DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
3077 			 cb->buffer, ch->residue));
3078 		for (i = 0; i < UAUDIO_NFRAMES; i++) {
3079 			DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
3080 		}
3081 	}
3082 #endif
3083 
3084 	DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
3085 	/* Fill the request */
3086 	usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
3087 			     UAUDIO_NFRAMES, USBD_NO_COPY,
3088 			     uaudio_chan_pintr);
3089 
3090 	(void)usbd_transfer(cb->xfer);
3091 }
3092 
3093 Static void
3094 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
3095 		  usbd_status status)
3096 {
3097 	struct chanbuf *cb = priv;
3098 	struct chan *ch = cb->chan;
3099 	u_int32_t count;
3100 	int s;
3101 
3102 	/* Return if we are aborting. */
3103 	if (status == USBD_CANCELLED)
3104 		return;
3105 
3106 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
3107 	DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
3108 		    count, ch->transferred));
3109 #ifdef DIAGNOSTIC
3110 	if (count != cb->size) {
3111 		printf("uaudio_chan_pintr: count(%d) != size(%d)\n",
3112 		       count, cb->size);
3113 	}
3114 #endif
3115 
3116 	ch->transferred += cb->size;
3117 #if defined(__FreeBSD__)
3118 	/* s = spltty(); */
3119 	s = splhigh();
3120 	chn_intr(ch->pcm_ch);
3121 	splx(s);
3122 #else
3123 	s = splaudio();
3124 	/* Call back to upper layer */
3125 	while (ch->transferred >= ch->blksize) {
3126 		ch->transferred -= ch->blksize;
3127 		DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n",
3128 			    ch->intr, ch->arg));
3129 		ch->intr(ch->arg);
3130 	}
3131 	splx(s);
3132 #endif
3133 
3134 	/* start next transfer */
3135 	uaudio_chan_ptransfer(ch);
3136 }
3137 
3138 /* Called at splusb() */
3139 Static void
3140 uaudio_chan_rtransfer(struct chan *ch)
3141 {
3142 	struct chanbuf *cb;
3143 	int i, size, residue, total;
3144 
3145 	if (ch->sc->sc_dying)
3146 		return;
3147 
3148 	/* Pick the next channel buffer. */
3149 	cb = &ch->chanbufs[ch->curchanbuf];
3150 	if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
3151 		ch->curchanbuf = 0;
3152 
3153 	/* Compute the size of each frame in the next transfer. */
3154 	residue = ch->residue;
3155 	total = 0;
3156 	for (i = 0; i < UAUDIO_NFRAMES; i++) {
3157 		size = ch->bytes_per_frame;
3158 		cb->sizes[i] = size;
3159 		cb->offsets[i] = total;
3160 		total += size;
3161 	}
3162 	ch->residue = residue;
3163 	cb->size = total;
3164 
3165 #ifdef USB_DEBUG
3166 	if (uaudiodebug > 8) {
3167 		DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
3168 			 cb->buffer, ch->residue));
3169 		for (i = 0; i < UAUDIO_NFRAMES; i++) {
3170 			DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
3171 		}
3172 	}
3173 #endif
3174 
3175 	DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
3176 	/* Fill the request */
3177 	usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
3178 			     UAUDIO_NFRAMES, USBD_NO_COPY,
3179 			     uaudio_chan_rintr);
3180 
3181 	(void)usbd_transfer(cb->xfer);
3182 }
3183 
3184 Static void
3185 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
3186 		  usbd_status status)
3187 {
3188 	struct chanbuf *cb = priv;
3189 	struct chan *ch = cb->chan;
3190 	u_int32_t count;
3191 	int s, i, n, frsize;
3192 
3193 	/* Return if we are aborting. */
3194 	if (status == USBD_CANCELLED)
3195 		return;
3196 
3197 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
3198 	DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
3199 		    count, ch->transferred));
3200 
3201 	/* count < cb->size is normal for asynchronous source */
3202 #ifdef DIAGNOSTIC
3203 	if (count > cb->size) {
3204 		printf("uaudio_chan_rintr: count(%d) > size(%d)\n",
3205 		       count, cb->size);
3206 	}
3207 #endif
3208 
3209 	/*
3210 	 * Transfer data from channel buffer to upper layer buffer, taking
3211 	 * care of wrapping the upper layer buffer.
3212 	 */
3213 	for(i = 0; i < UAUDIO_NFRAMES; i++) {
3214 		frsize = cb->sizes[i];
3215 		n = min(frsize, ch->end - ch->cur);
3216 		memcpy(ch->cur, cb->buffer + cb->offsets[i], n);
3217 		ch->cur += n;
3218 		if (ch->cur >= ch->end)
3219 			ch->cur = ch->start;
3220 		if (frsize > n) {
3221 			memcpy(ch->cur, cb->buffer + cb->offsets[i] + n,
3222 			    frsize - n);
3223 			ch->cur += frsize - n;
3224 		}
3225 	}
3226 
3227 	/* Call back to upper layer */
3228 	ch->transferred += count;
3229 #if defined(__FreeBSD__)
3230 	s = spltty();
3231 	chn_intr(ch->pcm_ch);
3232 	splx(s);
3233 #else
3234 	s = splaudio();
3235 	while (ch->transferred >= ch->blksize) {
3236 		ch->transferred -= ch->blksize;
3237 		DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n",
3238 			    ch->intr, ch->arg));
3239 		ch->intr(ch->arg);
3240 	}
3241 	splx(s);
3242 #endif
3243 
3244 	/* start next transfer */
3245 	uaudio_chan_rtransfer(ch);
3246 }
3247 
3248 #if defined(__NetBSD__) || defined(__OpenBSD__)
3249 Static void
3250 uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param,
3251     int maxpktsize)
3252 {
3253 	int samples_per_frame, sample_size;
3254 
3255 	ch->altidx = altidx;
3256 	sample_size = param->precision * param->factor * param->hw_channels / 8;
3257 	samples_per_frame = param->hw_sample_rate / USB_FRAMES_PER_SECOND;
3258 	ch->sample_size = sample_size;
3259 	ch->sample_rate = param->hw_sample_rate;
3260 	if (maxpktsize == 0) {
3261 		ch->fraction = param->hw_sample_rate % USB_FRAMES_PER_SECOND;
3262 		ch->bytes_per_frame = samples_per_frame * sample_size;
3263 	} else {
3264 		ch->fraction = 0;
3265 		ch->bytes_per_frame = maxpktsize;
3266 	}
3267 	ch->residue = 0;
3268 }
3269 
3270 Static void
3271 uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize)
3272 {
3273 	ch->start = start;
3274 	ch->end = end;
3275 	ch->cur = start;
3276 	ch->blksize = blksize;
3277 	ch->transferred = 0;
3278 
3279 	ch->curchanbuf = 0;
3280 }
3281 
3282 Static void
3283 uaudio_get_minmax_rates(int nalts, const struct as_info *alts,
3284 			const struct audio_params *p, int mode,
3285 			u_long *min, u_long *max)
3286 {
3287 	const struct usb_audio_streaming_type1_descriptor *a1d;
3288 	int i, j;
3289 
3290 	*min = ULONG_MAX;
3291 	*max = 0;
3292 	for (i = 0; i < nalts; i++) {
3293 		a1d = alts[i].asf1desc;
3294 		if (alts[i].sc_busy)
3295 			continue;
3296 		if (p->hw_channels != a1d->bNrChannels)
3297 			continue;
3298 		if (p->hw_precision != a1d->bBitResolution)
3299 			continue;
3300 		if (p->hw_encoding != alts[i].encoding)
3301 			continue;
3302 		if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
3303 			continue;
3304 		if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
3305 			DPRINTFN(2,("uaudio_get_minmax_rates: cont %d-%d\n",
3306 				    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
3307 			if (UA_SAMP_LO(a1d) < *min)
3308 				*min = UA_SAMP_LO(a1d);
3309 			if (UA_SAMP_HI(a1d) > *max)
3310 				*max = UA_SAMP_HI(a1d);
3311 		} else {
3312 			for (j = 0; j < a1d->bSamFreqType; j++) {
3313 				DPRINTFN(2,("uaudio_get_minmax_rates: disc #%d: %d\n",
3314 					    j, UA_GETSAMP(a1d, j)));
3315 				if (UA_GETSAMP(a1d, j) < *min)
3316 					*min = UA_GETSAMP(a1d, j);
3317 				if (UA_GETSAMP(a1d, j) > *max)
3318 					*max = UA_GETSAMP(a1d, j);
3319 			}
3320 		}
3321 	}
3322 }
3323 
3324 Static int
3325 uaudio_match_alt_sub(int nalts, const struct as_info *alts,
3326 		     const struct audio_params *p, int mode, u_long rate)
3327 {
3328 	const struct usb_audio_streaming_type1_descriptor *a1d;
3329 	int i, j;
3330 
3331 	DPRINTF(("uaudio_match_alt_sub: search for %luHz %dch\n",
3332 		 rate, p->hw_channels));
3333 	for (i = 0; i < nalts; i++) {
3334 		a1d = alts[i].asf1desc;
3335 		if (alts[i].sc_busy)
3336 			continue;
3337 		if (p->hw_channels != a1d->bNrChannels)
3338 			continue;
3339 		if (p->hw_precision != a1d->bBitResolution)
3340 			continue;
3341 		if (p->hw_encoding != alts[i].encoding)
3342 			continue;
3343 		if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
3344 			continue;
3345 		if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
3346 			DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n",
3347 				    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
3348 			if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d))
3349 				return i;
3350 		} else {
3351 			for (j = 0; j < a1d->bSamFreqType; j++) {
3352 				DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n",
3353 					    j, UA_GETSAMP(a1d, j)));
3354 				/* XXX allow for some slack */
3355 				if (UA_GETSAMP(a1d, j) == rate)
3356 					return i;
3357 			}
3358 		}
3359 	}
3360 	return -1;
3361 }
3362 
3363 Static int
3364 uaudio_match_alt_chan(int nalts, const struct as_info *alts,
3365 		      struct audio_params *p, int mode)
3366 {
3367 	int i, n;
3368 	u_long min, max;
3369 	u_long rate;
3370 
3371 	/* Exact match */
3372 	DPRINTF(("uaudio_match_alt_chan: examine %ldHz %dch %dbit.\n",
3373 		 p->sample_rate, p->hw_channels, p->hw_precision));
3374 	i = uaudio_match_alt_sub(nalts, alts, p, mode, p->sample_rate);
3375 	if (i >= 0)
3376 		return i;
3377 
3378 	uaudio_get_minmax_rates(nalts, alts, p, mode, &min, &max);
3379 	DPRINTF(("uaudio_match_alt_chan: min=%lu max=%lu\n", min, max));
3380 	if (max <= 0)
3381 		return -1;
3382 	/* Search for biggers */
3383 	n = 2;
3384 	while ((rate = p->sample_rate * n++) <= max) {
3385 		i = uaudio_match_alt_sub(nalts, alts, p, mode, rate);
3386 		if (i >= 0) {
3387 			p->hw_sample_rate = rate;
3388 			return i;
3389 		}
3390 	}
3391 	if (p->sample_rate >= min) {
3392 		i = uaudio_match_alt_sub(nalts, alts, p, mode, max);
3393 		if (i >= 0) {
3394 			p->hw_sample_rate = max;
3395 			return i;
3396 		}
3397 	} else {
3398 		i = uaudio_match_alt_sub(nalts, alts, p, mode, min);
3399 		if (i >= 0) {
3400 			p->hw_sample_rate = min;
3401 			return i;
3402 		}
3403 	}
3404 	return -1;
3405 }
3406 
3407 Static int
3408 uaudio_match_alt(int nalts, const struct as_info *alts,
3409 		 struct audio_params *p, int mode)
3410 {
3411 	int i, n;
3412 
3413 	mode = mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN;
3414 	i = uaudio_match_alt_chan(nalts, alts, p, mode);
3415 	if (i >= 0)
3416 		return i;
3417 
3418 	for (n = p->channels + 1; n <= AUDIO_MAX_CHANNELS; n++) {
3419 		p->hw_channels = n;
3420 		i = uaudio_match_alt_chan(nalts, alts, p, mode);
3421 		if (i >= 0)
3422 			return i;
3423 	}
3424 
3425 	if (p->channels != 2)
3426 		return -1;
3427 	p->hw_channels = 1;
3428 	return uaudio_match_alt_chan(nalts, alts, p, mode);
3429 }
3430 
3431 Static int
3432 uaudio_set_params(void *addr, int setmode, int usemode,
3433 		  struct audio_params *play, struct audio_params *rec)
3434 {
3435 	struct uaudio_softc *sc = addr;
3436 	int flags = sc->sc_altflags;
3437 	int factor;
3438 	int enc, i;
3439 	int paltidx=-1, raltidx=-1;
3440 	void (*swcode)(void *, u_char *buf, int cnt);
3441 	struct audio_params *p;
3442 	int mode;
3443 
3444 	if (sc->sc_dying)
3445 		return (EIO);
3446 
3447 	if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) ||
3448 	    ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL))
3449 		return (EBUSY);
3450 
3451 	if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
3452 		sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0;
3453 	if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
3454 		sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0;
3455 
3456 	/* Some uaudio devices are unidirectional.  Don't try to find a
3457 	   matching mode for the unsupported direction. */
3458 	setmode &= sc->sc_mode;
3459 
3460 	for (mode = AUMODE_RECORD; mode != -1;
3461 	     mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
3462 		if ((setmode & mode) == 0)
3463 			continue;
3464 
3465 		p = (mode == AUMODE_PLAY) ? play : rec;
3466 
3467 		factor = 1;
3468 		swcode = 0;
3469 		enc = p->encoding;
3470 		switch (enc) {
3471 		case AUDIO_ENCODING_SLINEAR_BE:
3472 			/* FALLTHROUGH */
3473 		case AUDIO_ENCODING_SLINEAR_LE:
3474 			if (enc == AUDIO_ENCODING_SLINEAR_BE
3475 			    && p->precision == 16 && (flags & HAS_16)) {
3476 				swcode = swap_bytes;
3477 				enc = AUDIO_ENCODING_SLINEAR_LE;
3478 			} else if (p->precision == 8) {
3479 				if (flags & HAS_8) {
3480 					/* No conversion */
3481 				} else if (flags & HAS_8U) {
3482 					swcode = change_sign8;
3483 					enc = AUDIO_ENCODING_ULINEAR_LE;
3484 				} else if (flags & HAS_16) {
3485 					factor = 2;
3486 					p->hw_precision = 16;
3487 					if (mode == AUMODE_PLAY)
3488 						swcode = linear8_to_linear16_le;
3489 					else
3490 						swcode = linear16_to_linear8_le;
3491 				}
3492 			}
3493 			break;
3494 		case AUDIO_ENCODING_ULINEAR_BE:
3495 			/* FALLTHROUGH */
3496 		case AUDIO_ENCODING_ULINEAR_LE:
3497 			if (p->precision == 16) {
3498 				if (enc == AUDIO_ENCODING_ULINEAR_LE)
3499 					swcode = change_sign16_le;
3500 				else if (mode == AUMODE_PLAY)
3501 					swcode = swap_bytes_change_sign16_le;
3502 				else
3503 					swcode = change_sign16_swap_bytes_le;
3504 				enc = AUDIO_ENCODING_SLINEAR_LE;
3505 			} else if (p->precision == 8) {
3506 				if (flags & HAS_8U) {
3507 					/* No conversion */
3508 				} else if (flags & HAS_8) {
3509 					swcode = change_sign8;
3510 					enc = AUDIO_ENCODING_SLINEAR_LE;
3511 				} else if (flags & HAS_16) {
3512 					factor = 2;
3513 					p->hw_precision = 16;
3514 					enc = AUDIO_ENCODING_SLINEAR_LE;
3515 					if (mode == AUMODE_PLAY)
3516 						swcode = ulinear8_to_slinear16_le;
3517 					else
3518 						swcode = slinear16_to_ulinear8_le;
3519 				}
3520 			}
3521 			break;
3522 		case AUDIO_ENCODING_ULAW:
3523 			if (flags & HAS_MULAW)
3524 				break;
3525 			if (flags & HAS_16) {
3526 				if (mode == AUMODE_PLAY)
3527 					swcode = mulaw_to_slinear16_le;
3528 				else
3529 					swcode = slinear16_to_mulaw_le;
3530 				factor = 2;
3531 				enc = AUDIO_ENCODING_SLINEAR_LE;
3532 				p->hw_precision = 16;
3533 			} else if (flags & HAS_8U) {
3534 				if (mode == AUMODE_PLAY)
3535 					swcode = mulaw_to_ulinear8;
3536 				else
3537 					swcode = ulinear8_to_mulaw;
3538 				enc = AUDIO_ENCODING_ULINEAR_LE;
3539 			} else if (flags & HAS_8) {
3540 				if (mode == AUMODE_PLAY)
3541 					swcode = mulaw_to_slinear8;
3542 				else
3543 					swcode = slinear8_to_mulaw;
3544 				enc = AUDIO_ENCODING_SLINEAR_LE;
3545 			} else
3546 				return (EINVAL);
3547 			break;
3548 		case AUDIO_ENCODING_ALAW:
3549 			if (flags & HAS_ALAW)
3550 				break;
3551 			if (mode == AUMODE_PLAY && (flags & HAS_16)) {
3552 				swcode = alaw_to_slinear16_le;
3553 				factor = 2;
3554 				enc = AUDIO_ENCODING_SLINEAR_LE;
3555 				p->hw_precision = 16;
3556 			} else if (flags & HAS_8U) {
3557 				if (mode == AUMODE_PLAY)
3558 					swcode = alaw_to_ulinear8;
3559 				else
3560 					swcode = ulinear8_to_alaw;
3561 				enc = AUDIO_ENCODING_ULINEAR_LE;
3562 			} else if (flags & HAS_8) {
3563 				if (mode == AUMODE_PLAY)
3564 					swcode = alaw_to_slinear8;
3565 				else
3566 					swcode = slinear8_to_alaw;
3567 				enc = AUDIO_ENCODING_SLINEAR_LE;
3568 			} else
3569 				return (EINVAL);
3570 			break;
3571 		default:
3572 			return (EINVAL);
3573 		}
3574 		/* XXX do some other conversions... */
3575 
3576 		DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n",
3577 			 p->channels, p->hw_precision, enc, p->sample_rate));
3578 
3579 		p->hw_encoding = enc;
3580 		i = uaudio_match_alt(sc->sc_nalts, sc->sc_alts, p, mode);
3581 		if (i < 0)
3582 			return (EINVAL);
3583 
3584 		p->sw_code = swcode;
3585 		p->factor  = factor;
3586 
3587 		if (mode == AUMODE_PLAY)
3588 			paltidx = i;
3589 		else
3590 			raltidx = i;
3591 	}
3592 
3593 	if ((setmode & AUMODE_PLAY)) {
3594 		/* XXX abort transfer if currently happening? */
3595 		uaudio_chan_init(&sc->sc_playchan, paltidx, play, 0);
3596 	}
3597 	if ((setmode & AUMODE_RECORD)) {
3598 		/* XXX abort transfer if currently happening? */
3599 		uaudio_chan_init(&sc->sc_recchan, raltidx, rec,
3600 		    UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize));
3601 	}
3602 
3603 	if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
3604 		sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1;
3605 	if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
3606 		sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1;
3607 
3608 	DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n",
3609 		 sc->sc_playchan.altidx, sc->sc_recchan.altidx,
3610 		 (sc->sc_playchan.altidx >= 0)
3611 		   ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting
3612 		   : -1,
3613 		 (sc->sc_recchan.altidx >= 0)
3614 		   ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting
3615 		   : -1));
3616 
3617 	return (0);
3618 }
3619 #endif /* NetBSD or OpenBSD */
3620 
3621 Static usbd_status
3622 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
3623 {
3624 	usb_device_request_t req;
3625 	u_int8_t data[3];
3626 
3627 	DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
3628 	req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
3629 	req.bRequest = SET_CUR;
3630 	USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
3631 	USETW(req.wIndex, endpt);
3632 	USETW(req.wLength, 3);
3633 	data[0] = speed;
3634 	data[1] = speed >> 8;
3635 	data[2] = speed >> 16;
3636 
3637 	return (usbd_do_request(sc->sc_udev, &req, data));
3638 }
3639 
3640 
3641 #if defined(__FreeBSD__)
3642 /************************************************************/
3643 int
3644 uaudio_init_params(struct uaudio_softc *sc, struct chan *ch, int mode)
3645 {
3646 	int i, j, enc;
3647 	int samples_per_frame, sample_size;
3648 
3649 	if ((sc->sc_playchan.pipe != NULL) || (sc->sc_recchan.pipe != NULL))
3650 		return (-1);
3651 
3652 	switch(ch->format & 0x0000FFFF) {
3653 	case AFMT_U8:
3654 		enc = AUDIO_ENCODING_ULINEAR_LE;
3655 		ch->precision = 8;
3656 		break;
3657 	case AFMT_S8:
3658 		enc = AUDIO_ENCODING_SLINEAR_LE;
3659 		ch->precision = 8;
3660 		break;
3661 	case AFMT_A_LAW:	/* ? */
3662 		enc = AUDIO_ENCODING_ALAW;
3663 		ch->precision = 8;
3664 		break;
3665 	case AFMT_MU_LAW:	/* ? */
3666 		enc = AUDIO_ENCODING_ULAW;
3667 		ch->precision = 8;
3668 		break;
3669 	case AFMT_S16_LE:
3670 		enc = AUDIO_ENCODING_SLINEAR_LE;
3671 		ch->precision = 16;
3672 		break;
3673 	case AFMT_S16_BE:
3674 		enc = AUDIO_ENCODING_SLINEAR_BE;
3675 		ch->precision = 16;
3676 		break;
3677 	case AFMT_U16_LE:
3678 		enc = AUDIO_ENCODING_ULINEAR_LE;
3679 		ch->precision = 16;
3680 		break;
3681 	case AFMT_U16_BE:
3682 		enc = AUDIO_ENCODING_ULINEAR_BE;
3683 		ch->precision = 16;
3684 		break;
3685 	default:
3686 		enc = 0;
3687 		ch->precision = 16;
3688 		printf("Unknown format %x\n", ch->format);
3689 	}
3690 
3691 	if (ch->format & AFMT_STEREO) {
3692 		ch->channels = 2;
3693 	} else {
3694 		ch->channels = 1;
3695 	}
3696 
3697 /*	for (mode =  ......	 */
3698 		for (i = 0; i < sc->sc_nalts; i++) {
3699 			const struct usb_audio_streaming_type1_descriptor *a1d =
3700 				sc->sc_alts[i].asf1desc;
3701 			if (ch->channels == a1d->bNrChannels &&
3702 			    ch->precision == a1d->bBitResolution &&
3703 #if 0
3704 			    enc == sc->sc_alts[i].encoding) {
3705 #else
3706 			    enc == sc->sc_alts[i].encoding &&
3707 			    (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) ==
3708 			    UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) {
3709 #endif
3710 				if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
3711 					DPRINTFN(2,("uaudio_set_params: cont %d-%d\n",
3712 					    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
3713 					if (UA_SAMP_LO(a1d) < ch->sample_rate &&
3714 					    ch->sample_rate < UA_SAMP_HI(a1d)) {
3715 						if (mode == AUMODE_PLAY)
3716 							sc->sc_playchan.altidx = i;
3717 						else
3718 							sc->sc_recchan.altidx = i;
3719 						goto found;
3720 					}
3721 				} else {
3722 					for (j = 0; j < a1d->bSamFreqType; j++) {
3723 						DPRINTFN(2,("uaudio_set_params: disc #"
3724 						    "%d: %d\n", j, UA_GETSAMP(a1d, j)));
3725 						/* XXX allow for some slack */
3726 						if (UA_GETSAMP(a1d, j) ==
3727 						    ch->sample_rate) {
3728 							if (mode == AUMODE_PLAY)
3729 								sc->sc_playchan.altidx = i;
3730 							else
3731 								sc->sc_recchan.altidx = i;
3732 							goto found;
3733 						}
3734 					}
3735 				}
3736 			}
3737 		}
3738 		/* return (EINVAL); */
3739 		if (mode == AUMODE_PLAY)
3740 			printf("uaudio: This device can't play in rate=%d.\n", ch->sample_rate);
3741 		else
3742 			printf("uaudio: This device can't record in rate=%d.\n", ch->sample_rate);
3743 		return (-1);
3744 
3745 	found:
3746 #if 0 /* XXX */
3747 		p->sw_code = swcode;
3748 		p->factor  = factor;
3749 		if (usemode == mode)
3750 			sc->sc_curaltidx = i;
3751 #endif
3752 /*	} */
3753 
3754 	sample_size = ch->precision * ch->channels / 8;
3755 	samples_per_frame = ch->sample_rate / USB_FRAMES_PER_SECOND;
3756 	ch->fraction = ch->sample_rate % USB_FRAMES_PER_SECOND;
3757 	ch->sample_size = sample_size;
3758 	ch->bytes_per_frame = samples_per_frame * sample_size;
3759 	ch->residue = 0;
3760 
3761 	ch->cur = ch->start;
3762 	ch->transferred = 0;
3763 	ch->curchanbuf = 0;
3764 	return (0);
3765 }
3766 
3767 void
3768 uaudio_query_formats(device_t dev, u_int32_t *pfmt, u_int32_t *rfmt)
3769 {
3770 	int i, pn=0, rn=0;
3771 	int prec, dir;
3772 	u_int32_t fmt;
3773 	struct uaudio_softc *sc;
3774 
3775 	const struct usb_audio_streaming_type1_descriptor *a1d;
3776 
3777 	sc = device_get_softc(dev);
3778 
3779 	for (i = 0; i < sc->sc_nalts; i++) {
3780 		fmt = 0;
3781 		a1d = sc->sc_alts[i].asf1desc;
3782 		prec = a1d->bBitResolution;	/* precision */
3783 
3784 		switch (sc->sc_alts[i].encoding) {
3785 		case AUDIO_ENCODING_ULINEAR_LE:
3786 			if (prec == 8) {
3787 				fmt = AFMT_U8;
3788 			} else if (prec == 16) {
3789 				fmt = AFMT_U16_LE;
3790 			}
3791 			break;
3792 		case AUDIO_ENCODING_SLINEAR_LE:
3793 			if (prec == 8) {
3794 				fmt = AFMT_S8;
3795 			} else if (prec == 16) {
3796 				fmt = AFMT_S16_LE;
3797 			}
3798 			break;
3799 		case AUDIO_ENCODING_ULINEAR_BE:
3800 			if (prec == 16) {
3801 				fmt = AFMT_U16_BE;
3802 			}
3803 			break;
3804 		case AUDIO_ENCODING_SLINEAR_BE:
3805 			if (prec == 16) {
3806 				fmt = AFMT_S16_BE;
3807 			}
3808 			break;
3809 		case AUDIO_ENCODING_ALAW:
3810 			if (prec == 8) {
3811 				fmt = AFMT_A_LAW;
3812 			}
3813 			break;
3814 		case AUDIO_ENCODING_ULAW:
3815 			if (prec == 8) {
3816 				fmt = AFMT_MU_LAW;
3817 			}
3818 			break;
3819 		}
3820 
3821 		if (fmt != 0) {
3822 			if (a1d->bNrChannels == 2) {	/* stereo/mono */
3823 				fmt |= AFMT_STEREO;
3824 			} else if (a1d->bNrChannels != 1) {
3825 				fmt = 0;
3826 			}
3827 		}
3828 
3829 		if (fmt != 0) {
3830 			dir= UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
3831 			if (dir == UE_DIR_OUT) {
3832 				pfmt[pn++] = fmt;
3833 			} else if (dir == UE_DIR_IN) {
3834 				rfmt[rn++] = fmt;
3835 			}
3836 		}
3837 
3838 		if ((pn > 8*2) || (rn > 8*2))
3839 			break;
3840 	}
3841 	pfmt[pn] = 0;
3842 	rfmt[rn] = 0;
3843 	return;
3844 }
3845 
3846 void
3847 uaudio_chan_set_param_pcm_dma_buff(device_t dev, u_char *start, u_char *end,
3848 		struct pcm_channel *pc, int dir)
3849 {
3850 	struct uaudio_softc *sc;
3851 	struct chan *ch;
3852 
3853 	sc = device_get_softc(dev);
3854 #ifndef NO_RECORDING
3855 	if (dir == PCMDIR_PLAY)
3856 		ch = &sc->sc_playchan;
3857 	else
3858 		ch = &sc->sc_recchan;
3859 #else
3860 	ch = &sc->sc_playchan;
3861 #endif
3862 
3863 	ch->start = start;
3864 	ch->end = end;
3865 
3866 	ch->pcm_ch = pc;
3867 
3868 	return;
3869 }
3870 
3871 void
3872 uaudio_chan_set_param_blocksize(device_t dev, u_int32_t blocksize, int dir)
3873 {
3874 	struct uaudio_softc *sc;
3875 	struct chan *ch;
3876 
3877 	sc = device_get_softc(dev);
3878 #ifndef NO_RECORDING
3879 	if (dir == PCMDIR_PLAY)
3880 		ch = &sc->sc_playchan;
3881 	else
3882 		ch = &sc->sc_recchan;
3883 #else
3884 	ch = &sc->sc_playchan;
3885 #endif
3886 
3887 	ch->blksize = blocksize;
3888 
3889 	return;
3890 }
3891 
3892 void
3893 uaudio_chan_set_param_speed(device_t dev, u_int32_t speed, int dir)
3894 {
3895 	struct uaudio_softc *sc;
3896 	struct chan *ch;
3897 
3898 	sc = device_get_softc(dev);
3899 #ifndef NO_RECORDING
3900 	if (dir == PCMDIR_PLAY)
3901 		ch = &sc->sc_playchan;
3902 	else
3903 		ch = &sc->sc_recchan;
3904 #else
3905 	ch = &sc->sc_playchan;
3906 #endif
3907 
3908 	ch->sample_rate = speed;
3909 
3910 	return;
3911 }
3912 
3913 int
3914 uaudio_chan_getptr(device_t dev, int dir)
3915 {
3916 	struct uaudio_softc *sc;
3917 	struct chan *ch;
3918 	int ptr;
3919 
3920 	sc = device_get_softc(dev);
3921 #ifndef NO_RECORDING
3922 	if (dir == PCMDIR_PLAY)
3923 		ch = &sc->sc_playchan;
3924 	else
3925 		ch = &sc->sc_recchan;
3926 #else
3927 	ch = &sc->sc_playchan;
3928 #endif
3929 
3930 	ptr = ch->cur - ch->start;
3931 
3932 	return ptr;
3933 }
3934 
3935 void
3936 uaudio_chan_set_param_format(device_t dev, u_int32_t format, int dir)
3937 {
3938 	struct uaudio_softc *sc;
3939 	struct chan *ch;
3940 
3941 	sc = device_get_softc(dev);
3942 #ifndef NO_RECORDING
3943 	if (dir == PCMDIR_PLAY)
3944 		ch = &sc->sc_playchan;
3945 	else
3946 		ch = &sc->sc_recchan;
3947 #else
3948 	ch = &sc->sc_playchan;
3949 #endif
3950 
3951 	ch->format = format;
3952 
3953 	return;
3954 }
3955 
3956 int
3957 uaudio_halt_out_dma(device_t dev)
3958 {
3959 	struct uaudio_softc *sc;
3960 
3961 	sc = device_get_softc(dev);
3962 
3963 	DPRINTF(("uaudio_halt_out_dma: enter\n"));
3964 	if (sc->sc_playchan.pipe != NULL) {
3965 		uaudio_chan_close(sc, &sc->sc_playchan);
3966 		sc->sc_playchan.pipe = 0;
3967 		uaudio_chan_free_buffers(sc, &sc->sc_playchan);
3968 	}
3969         return (0);
3970 }
3971 
3972 int
3973 uaudio_halt_in_dma(device_t dev)
3974 {
3975 	struct uaudio_softc *sc;
3976 
3977 	sc = device_get_softc(dev);
3978 
3979 	if (sc->sc_dying)
3980 		return (EIO);
3981 
3982 	DPRINTF(("uaudio_halt_in_dma: enter\n"));
3983 	if (sc->sc_recchan.pipe != NULL) {
3984 		uaudio_chan_close(sc, &sc->sc_recchan);
3985 		sc->sc_recchan.pipe = NULL;
3986 		uaudio_chan_free_buffers(sc, &sc->sc_recchan);
3987 /*		sc->sc_recchan.intr = NULL; */
3988 	}
3989 	return (0);
3990 }
3991 
3992 int
3993 uaudio_trigger_input(device_t dev)
3994 {
3995 	struct uaudio_softc *sc;
3996 	struct chan *ch;
3997 	usbd_status err;
3998 	int i, s;
3999 
4000 	sc = device_get_softc(dev);
4001 	ch = &sc->sc_recchan;
4002 
4003 	if (sc->sc_dying)
4004 		return (EIO);
4005 
4006 /*	uaudio_chan_set_param(ch, start, end, blksize) */
4007 	if (uaudio_init_params(sc, ch, AUMODE_RECORD))
4008 		return (EIO);
4009 
4010 	err = uaudio_chan_alloc_buffers(sc, ch);
4011 	if (err)
4012 		return (EIO);
4013 
4014 	err = uaudio_chan_open(sc, ch);
4015 	if (err) {
4016 		uaudio_chan_free_buffers(sc, ch);
4017 		return (EIO);
4018 	}
4019 
4020 /*	ch->intr = intr;
4021 	ch->arg = arg; */
4022 
4023 	s = splusb();
4024 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
4025 		uaudio_chan_rtransfer(ch);
4026 	splx(s);
4027 
4028 	return (0);
4029 }
4030 
4031 int
4032 uaudio_trigger_output(device_t dev)
4033 {
4034 	struct uaudio_softc *sc;
4035 	struct chan *ch;
4036 	usbd_status err;
4037 	int i, s;
4038 
4039 	sc = device_get_softc(dev);
4040 	ch = &sc->sc_playchan;
4041 
4042 	if (sc->sc_dying)
4043 		return (EIO);
4044 
4045 	if (uaudio_init_params(sc, ch, AUMODE_PLAY))
4046 		return (EIO);
4047 
4048 	err = uaudio_chan_alloc_buffers(sc, ch);
4049 	if (err)
4050 		return (EIO);
4051 
4052 	err = uaudio_chan_open(sc, ch);
4053 	if (err) {
4054 		uaudio_chan_free_buffers(sc, ch);
4055 		return (EIO);
4056 	}
4057 
4058 	s = splusb();
4059 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
4060 		uaudio_chan_ptransfer(ch);
4061 	splx(s);
4062 
4063         return (0);
4064 }
4065 
4066 u_int32_t
4067 uaudio_query_mix_info(device_t dev)
4068 {
4069 	int i;
4070 	u_int32_t mask = 0;
4071 	struct uaudio_softc *sc;
4072 	struct mixerctl *mc;
4073 
4074 	sc = device_get_softc(dev);
4075 	for (i=0; i < sc->sc_nctls; i++) {
4076 		mc = &sc->sc_ctls[i];
4077 		if (mc->ctl != SOUND_MIXER_NRDEVICES) {
4078 			/* Set device mask bits.
4079 			   See /usr/include/machine/soundcard.h */
4080 			mask |= (1 << mc->ctl);
4081 		}
4082 	}
4083 	return mask;
4084 }
4085 
4086 u_int32_t
4087 uaudio_query_recsrc_info(device_t dev)
4088 {
4089 	int i, rec_selector_id;
4090 	u_int32_t mask = 0;
4091 	struct uaudio_softc *sc;
4092 	struct mixerctl *mc;
4093 
4094 	sc = device_get_softc(dev);
4095 	rec_selector_id = -1;
4096 	for (i=0; i < sc->sc_nctls; i++) {
4097 		mc = &sc->sc_ctls[i];
4098 		if (mc->ctl == SOUND_MIXER_NRDEVICES &&
4099 		    mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
4100 			if (rec_selector_id == -1) {
4101 				rec_selector_id = i;
4102 			} else {
4103 				printf("There are many selectors.  Can't recognize which selector is a record source selector.\n");
4104 				return mask;
4105 			}
4106 		}
4107 	}
4108 	if (rec_selector_id == -1)
4109 		return mask;
4110 	mc = &sc->sc_ctls[rec_selector_id];
4111 	for (i = mc->minval; i <= mc->maxval; i++) {
4112 		if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES)
4113 			continue;
4114 		mask |= 1 << mc->slctrtype[i - 1];
4115 	}
4116 	return mask;
4117 }
4118 
4119 void
4120 uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
4121 {
4122 	int i;
4123 	struct uaudio_softc *sc;
4124 	struct mixerctl *mc;
4125 
4126 	sc = device_get_softc(dev);
4127 	for (i=0; i < sc->sc_nctls; i++) {
4128 		mc = &sc->sc_ctls[i];
4129 		if (mc->ctl == type) {
4130 			if (mc->nchan == 2) {
4131 				/* set Right */
4132 				uaudio_ctl_set(sc, SET_CUR, mc, 1, (int)(right*256)/100);
4133 			}
4134 			/* set Left or Mono */
4135 			uaudio_ctl_set(sc, SET_CUR, mc, 0, (int)(left*256)/100);
4136 		}
4137 	}
4138 	return;
4139 }
4140 
4141 u_int32_t
4142 uaudio_mixer_setrecsrc(device_t dev, u_int32_t src)
4143 {
4144 	int i, rec_selector_id;
4145 	struct uaudio_softc *sc;
4146 	struct mixerctl *mc;
4147 
4148 	sc = device_get_softc(dev);
4149 	rec_selector_id = -1;
4150 	for (i=0; i < sc->sc_nctls; i++) {
4151 		mc = &sc->sc_ctls[i];
4152 		if (mc->ctl == SOUND_MIXER_NRDEVICES &&
4153 		    mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
4154 			if (rec_selector_id == -1) {
4155 				rec_selector_id = i;
4156 			} else {
4157 				return src; /* Can't recognize which selector is record source selector */
4158 			}
4159 		}
4160 	}
4161 	if (rec_selector_id == -1)
4162 		return src;
4163 	mc = &sc->sc_ctls[rec_selector_id];
4164 	for (i = mc->minval; i <= mc->maxval; i++) {
4165 		if (src != (1 << mc->slctrtype[i - 1]))
4166 			continue;
4167 		uaudio_ctl_set(sc, SET_CUR, mc, 0, i);
4168 		return (1 << mc->slctrtype[i - 1]);
4169 	}
4170 	uaudio_ctl_set(sc, SET_CUR, mc, 0, mc->minval);
4171 	return (1 << mc->slctrtype[mc->minval - 1]);
4172 }
4173 
4174 Static int
4175 audio_attach_mi(device_t dev)
4176 {
4177 	device_t child;
4178 	struct sndcard_func *func;
4179 
4180 	/* Attach the children. */
4181 	/* PCM Audio */
4182 	func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT);
4183 	if (func == NULL)
4184 		return (ENOMEM);
4185 	bzero(func, sizeof(*func));
4186 	func->func = SCF_PCM;
4187 	child = device_add_child(dev, "pcm", -1);
4188 	device_set_ivars(child, func);
4189 
4190 	bus_generic_attach(dev);
4191 
4192 	return 0; /* XXXXX */
4193 }
4194 
4195 DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, usbd_driver_load, 0);
4196 MODULE_VERSION(uaudio, 1);
4197 
4198 #endif
4199