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