xref: /openbsd/sys/dev/usb/uaudio.c (revision 404b540a)
1 /*	$OpenBSD: uaudio.c,v 1.63 2009/10/15 08:47:44 jakemsr Exp $ */
2 /*	$NetBSD: uaudio.c,v 1.90 2004/10/29 17:12:53 kent Exp $	*/
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  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
36  *                  http://www.usb.org/developers/devclass_docs/frmts10.pdf
37  *                  http://www.usb.org/developers/devclass_docs/termt10.pdf
38  */
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/device.h>
45 #include <sys/ioctl.h>
46 #include <sys/tty.h>
47 #include <sys/file.h>
48 #include <sys/reboot.h>			/* for bootverbose */
49 #include <sys/selinfo.h>
50 #include <sys/proc.h>
51 #include <sys/vnode.h>
52 #include <sys/device.h>
53 #include <sys/poll.h>
54 
55 #include <sys/audioio.h>
56 #include <dev/audio_if.h>
57 #include <dev/mulaw.h>
58 #include <dev/auconv.h>
59 
60 #include <dev/usb/usb.h>
61 #include <dev/usb/usbdi.h>
62 #include <dev/usb/usbdi_util.h>
63 #include <dev/usb/usb_quirks.h>
64 
65 #include <dev/usb/uaudioreg.h>
66 
67 /* #define UAUDIO_DEBUG */
68 /* #define UAUDIO_MULTIPLE_ENDPOINTS */
69 #ifdef UAUDIO_DEBUG
70 #define DPRINTF(x)	do { if (uaudiodebug) printf x; } while (0)
71 #define DPRINTFN(n,x)	do { if (uaudiodebug>(n)) printf x; } while (0)
72 int	uaudiodebug = 0;
73 #else
74 #define DPRINTF(x)
75 #define DPRINTFN(n,x)
76 #endif
77 
78 #define UAUDIO_NCHANBUFS 6	/* number of outstanding request */
79 #define UAUDIO_NFRAMES   10	/* ms of sound in each request */
80 
81 
82 #define MIX_MAX_CHAN 8
83 struct mixerctl {
84 	u_int16_t	wValue[MIX_MAX_CHAN]; /* using nchan */
85 	u_int16_t	wIndex;
86 	u_int8_t	nchan;
87 	u_int8_t	type;
88 #define MIX_ON_OFF	1
89 #define MIX_SIGNED_16	2
90 #define MIX_UNSIGNED_16	3
91 #define MIX_SIGNED_8	4
92 #define MIX_SELECTOR	5
93 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
94 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
95 	int		minval, maxval;
96 	u_int		delta;
97 	u_int8_t	class;
98 	char		ctlname[MAX_AUDIO_DEV_LEN];
99 	char		*ctlunit;
100 };
101 #define MAKE(h,l) (((h) << 8) | (l))
102 
103 struct as_info {
104 	u_int8_t	alt;
105 	u_int8_t	encoding;
106 	u_int8_t	attributes; /* Copy of bmAttributes of
107 				     * usb_audio_streaming_endpoint_descriptor
108 				     */
109 	usbd_interface_handle	ifaceh;
110 	const usb_interface_descriptor_t *idesc;
111 	const usb_endpoint_descriptor_audio_t *edesc;
112 	const usb_endpoint_descriptor_audio_t *edesc1;
113 	const struct usb_audio_streaming_type1_descriptor *asf1desc;
114 	int		sc_busy;	/* currently used */
115 };
116 
117 struct chan {
118 	void	(*intr)(void *);	/* DMA completion intr handler */
119 	void	*arg;		/* arg for intr() */
120 	usbd_pipe_handle pipe;
121 	usbd_pipe_handle sync_pipe;
122 
123 	u_int	sample_size;
124 	u_int	sample_rate;
125 	u_int	bytes_per_frame;
126 	u_int	fraction;	/* fraction/1000 is the extra samples/frame */
127 	u_int	residue;	/* accumulates the fractional samples */
128 
129 	u_char	*start;		/* upper layer buffer start */
130 	u_char	*end;		/* upper layer buffer end */
131 	u_char	*cur;		/* current position in upper layer buffer */
132 	int	blksize;	/* chunk size to report up */
133 	int	transferred;	/* transferred bytes not reported up */
134 
135 	int	altidx;		/* currently used altidx */
136 
137 	int	curchanbuf;
138 	struct chanbuf {
139 		struct chan	*chan;
140 		usbd_xfer_handle xfer;
141 		u_char		*buffer;
142 		u_int16_t	sizes[UAUDIO_NFRAMES];
143 		u_int16_t	offsets[UAUDIO_NFRAMES];
144 		u_int16_t	size;
145 	} chanbufs[UAUDIO_NCHANBUFS];
146 
147 	struct uaudio_softc *sc; /* our softc */
148 };
149 
150 struct uaudio_softc {
151 	struct device	 sc_dev;	/* base device */
152 	usbd_device_handle sc_udev;	/* USB device */
153 	int		 sc_ac_iface;	/* Audio Control interface */
154 	usbd_interface_handle	sc_ac_ifaceh;
155 	struct chan	 sc_playchan;	/* play channel */
156 	struct chan	 sc_recchan;	/* record channel */
157 	int		 sc_nullalt;
158 	int		 sc_audio_rev;
159 	struct as_info	*sc_alts;	/* alternate settings */
160 	int		 sc_nalts;	/* # of alternate settings */
161 	int		 sc_altflags;
162 #define HAS_8		 0x01
163 #define HAS_16		 0x02
164 #define HAS_8U		 0x04
165 #define HAS_ALAW	 0x08
166 #define HAS_MULAW	 0x10
167 #define UA_NOFRAC	 0x20		/* don't do sample rate adjustment */
168 #define HAS_24		 0x40
169 	int		 sc_mode;	/* play/record capability */
170 	struct mixerctl *sc_ctls;	/* mixer controls */
171 	int		 sc_nctls;	/* # of mixer controls */
172 	struct device	*sc_audiodev;
173 	char		 sc_dying;
174 };
175 
176 struct terminal_list {
177 	int size;
178 	uint16_t terminals[1];
179 };
180 #define TERMINAL_LIST_SIZE(N)	(offsetof(struct terminal_list, terminals) \
181 				+ sizeof(uint16_t) * (N))
182 
183 struct io_terminal {
184 	union {
185 		const usb_descriptor_t *desc;
186 		const struct usb_audio_input_terminal *it;
187 		const struct usb_audio_output_terminal *ot;
188 		const struct usb_audio_mixer_unit *mu;
189 		const struct usb_audio_selector_unit *su;
190 		const struct usb_audio_feature_unit *fu;
191 		const struct usb_audio_processing_unit *pu;
192 		const struct usb_audio_extension_unit *eu;
193 	} d;
194 	int inputs_size;
195 	struct terminal_list **inputs; /* list of source input terminals */
196 	struct terminal_list *output; /* list of destination output terminals */
197 	int direct;		/* directly connected to an output terminal */
198 };
199 
200 #define UAC_OUTPUT	0
201 #define UAC_INPUT	1
202 #define UAC_EQUAL	2
203 #define UAC_RECORD	3
204 #define UAC_NCLASSES	4
205 #ifdef UAUDIO_DEBUG
206 const char *uac_names[] = {
207 	AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
208 };
209 #endif
210 
211 usbd_status uaudio_identify_ac
212 	(struct uaudio_softc *, const usb_config_descriptor_t *);
213 usbd_status uaudio_identify_as
214 	(struct uaudio_softc *, const usb_config_descriptor_t *);
215 usbd_status uaudio_process_as
216 	(struct uaudio_softc *, const char *, int *, int,
217 	 const usb_interface_descriptor_t *);
218 
219 void	uaudio_add_alt(struct uaudio_softc *, const struct as_info *);
220 
221 const usb_interface_descriptor_t *uaudio_find_iface
222 	(const char *, int, int *, int);
223 
224 void	uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
225 char	*uaudio_id_name
226 	(struct uaudio_softc *, const struct io_terminal *, int);
227 struct usb_audio_cluster uaudio_get_cluster
228 	(int, const struct io_terminal *);
229 void	uaudio_add_input
230 	(struct uaudio_softc *, const struct io_terminal *, int);
231 void	uaudio_add_output
232 	(struct uaudio_softc *, const struct io_terminal *, int);
233 void	uaudio_add_mixer
234 	(struct uaudio_softc *, const struct io_terminal *, int);
235 void	uaudio_add_selector
236 	(struct uaudio_softc *, const struct io_terminal *, int);
237 #ifdef UAUDIO_DEBUG
238 const char *uaudio_get_terminal_name(int);
239 #endif
240 int	uaudio_determine_class
241 	(const struct io_terminal *, struct mixerctl *);
242 const char *uaudio_feature_name
243 	(const struct io_terminal *, struct mixerctl *);
244 void	uaudio_add_feature
245 	(struct uaudio_softc *, const struct io_terminal *, int);
246 void	uaudio_add_processing_updown
247 	(struct uaudio_softc *, const struct io_terminal *, int);
248 void	uaudio_add_processing
249 	(struct uaudio_softc *, const struct io_terminal *, int);
250 void	uaudio_add_extension
251 	(struct uaudio_softc *, const struct io_terminal *, int);
252 struct terminal_list *uaudio_merge_terminal_list
253 	(const struct io_terminal *);
254 struct terminal_list *uaudio_io_terminaltype
255 	(int, struct io_terminal *, int);
256 usbd_status uaudio_identify
257 	(struct uaudio_softc *, const usb_config_descriptor_t *);
258 
259 int	uaudio_signext(int, int);
260 int	uaudio_unsignext(int, int);
261 int	uaudio_value2bsd(struct mixerctl *, int);
262 int	uaudio_bsd2value(struct mixerctl *, int);
263 int	uaudio_get(struct uaudio_softc *, int, int, int, int, int);
264 int	uaudio_ctl_get
265 	(struct uaudio_softc *, int, struct mixerctl *, int);
266 void	uaudio_set
267 	(struct uaudio_softc *, int, int, int, int, int, int);
268 void	uaudio_ctl_set
269 	(struct uaudio_softc *, int, struct mixerctl *, int, int);
270 
271 usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
272 
273 usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
274 void	uaudio_chan_close(struct uaudio_softc *, struct chan *);
275 usbd_status uaudio_chan_alloc_buffers
276 	(struct uaudio_softc *, struct chan *);
277 void	uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
278 void	uaudio_chan_init
279 	(struct chan *, int, const struct audio_params *, int);
280 void	uaudio_chan_set_param(struct chan *, u_char *, u_char *, int);
281 void	uaudio_chan_ptransfer(struct chan *);
282 void	uaudio_chan_pintr
283 	(usbd_xfer_handle, usbd_private_handle, usbd_status);
284 
285 void	uaudio_chan_rtransfer(struct chan *);
286 void	uaudio_chan_rintr
287 	(usbd_xfer_handle, usbd_private_handle, usbd_status);
288 
289 int	uaudio_open(void *, int);
290 void	uaudio_close(void *);
291 int	uaudio_drain(void *);
292 int	uaudio_query_encoding(void *, struct audio_encoding *);
293 void	uaudio_get_minmax_rates
294 	(int, const struct as_info *, const struct audio_params *,
295 	 int, int, int, u_long *, u_long *);
296 int	uaudio_match_alt_sub
297 	(int, const struct as_info *, const struct audio_params *,
298 	 int, int, int, u_long);
299 int	uaudio_match_alt_chan
300 	(int, const struct as_info *, struct audio_params *, int, int, int);
301 int	uaudio_match_alt
302 	(int, const struct as_info *, struct audio_params *, int, int, int);
303 int	uaudio_set_params
304 	(void *, int, int, struct audio_params *, struct audio_params *);
305 int	uaudio_round_blocksize(void *, int);
306 int	uaudio_trigger_output
307 	(void *, void *, void *, int, void (*)(void *), void *,
308 	 struct audio_params *);
309 int	uaudio_trigger_input
310 	(void *, void *, void *, int, void (*)(void *), void *,
311 	 struct audio_params *);
312 int	uaudio_halt_in_dma(void *);
313 int	uaudio_halt_out_dma(void *);
314 int	uaudio_getdev(void *, struct audio_device *);
315 int	uaudio_mixer_set_port(void *, mixer_ctrl_t *);
316 int	uaudio_mixer_get_port(void *, mixer_ctrl_t *);
317 int	uaudio_query_devinfo(void *, mixer_devinfo_t *);
318 int	uaudio_get_props(void *);
319 
320 struct audio_hw_if uaudio_hw_if = {
321 	uaudio_open,
322 	uaudio_close,
323 	uaudio_drain,
324 	uaudio_query_encoding,
325 	uaudio_set_params,
326 	uaudio_round_blocksize,
327 	NULL,
328 	NULL,
329 	NULL,
330 	NULL,
331 	NULL,
332 	uaudio_halt_out_dma,
333 	uaudio_halt_in_dma,
334 	NULL,
335 	uaudio_getdev,
336 	NULL,
337 	uaudio_mixer_set_port,
338 	uaudio_mixer_get_port,
339 	uaudio_query_devinfo,
340 	NULL,
341 	NULL,
342 	NULL,
343 	NULL,
344 	uaudio_get_props,
345 	uaudio_trigger_output,
346 	uaudio_trigger_input,
347 	NULL
348 };
349 
350 struct audio_device uaudio_device = {
351 	"USB audio",
352 	"",
353 	"uaudio"
354 };
355 
356 int uaudio_match(struct device *, void *, void *);
357 void uaudio_attach(struct device *, struct device *, void *);
358 int uaudio_detach(struct device *, int);
359 int uaudio_activate(struct device *, int);
360 
361 struct cfdriver uaudio_cd = {
362 	NULL, "uaudio", DV_DULL
363 };
364 
365 const struct cfattach uaudio_ca = {
366 	sizeof(struct uaudio_softc),
367 	uaudio_match,
368 	uaudio_attach,
369 	uaudio_detach,
370 	uaudio_activate,
371 };
372 
373 int
374 uaudio_match(struct device *parent, void *match, void *aux)
375 {
376 	struct usb_attach_arg *uaa = aux;
377 	usb_interface_descriptor_t *id;
378 
379 	if (uaa->iface == NULL)
380 		return (UMATCH_NONE);
381 
382 	id = usbd_get_interface_descriptor(uaa->iface);
383 	/* Trigger on the control interface. */
384 	if (id == NULL ||
385 	    id->bInterfaceClass != UICLASS_AUDIO ||
386 	    id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
387 	    (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
388 		return (UMATCH_NONE);
389 
390 	return (UMATCH_IFACECLASS_IFACESUBCLASS);
391 }
392 
393 void
394 uaudio_attach(struct device *parent, struct device *self, void *aux)
395 {
396 	struct uaudio_softc *sc = (struct uaudio_softc *)self;
397 	struct usb_attach_arg *uaa = aux;
398 	usb_interface_descriptor_t *id;
399 	usb_config_descriptor_t *cdesc;
400 	usbd_status err;
401 	int i, j, found;
402 
403 	sc->sc_udev = uaa->device;
404 
405 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
406 	if (cdesc == NULL) {
407 		printf("%s: failed to get configuration descriptor\n",
408 		       sc->sc_dev.dv_xname);
409 		return;
410 	}
411 
412 	err = uaudio_identify(sc, cdesc);
413 	if (err) {
414 		printf("%s: audio descriptors make no sense, error=%d\n",
415 		       sc->sc_dev.dv_xname, err);
416 		return;
417 	}
418 
419 	sc->sc_ac_ifaceh = uaa->iface;
420 	/* Pick up the AS interface. */
421 	for (i = 0; i < uaa->nifaces; i++) {
422 		if (uaa->ifaces[i] == NULL)
423 			continue;
424 		id = usbd_get_interface_descriptor(uaa->ifaces[i]);
425 		if (id == NULL)
426 			continue;
427 		found = 0;
428 		for (j = 0; j < sc->sc_nalts; j++) {
429 			if (id->bInterfaceNumber ==
430 			    sc->sc_alts[j].idesc->bInterfaceNumber) {
431 				sc->sc_alts[j].ifaceh = uaa->ifaces[i];
432 				found = 1;
433 			}
434 		}
435 		if (found)
436 			uaa->ifaces[i] = NULL;
437 	}
438 
439 	for (j = 0; j < sc->sc_nalts; j++) {
440 		if (sc->sc_alts[j].ifaceh == NULL) {
441 			printf("%s: alt %d missing AS interface(s)\n",
442 			    sc->sc_dev.dv_xname, j);
443 			return;
444 		}
445 	}
446 
447 	printf("%s: audio rev %d.%02x", sc->sc_dev.dv_xname,
448 	       sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
449 
450 	sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
451 	sc->sc_playchan.altidx = -1;
452 	sc->sc_recchan.altidx = -1;
453 
454 	if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
455 		sc->sc_altflags |= UA_NOFRAC;
456 
457 	printf(", %d mixer controls\n", sc->sc_nctls);
458 
459 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
460 			   &sc->sc_dev);
461 
462 	DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
463 	sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
464 }
465 
466 int
467 uaudio_activate(struct device *self, int act)
468 {
469 	struct uaudio_softc *sc = (struct uaudio_softc *)self;
470 	int rv = 0;
471 
472 	switch (act) {
473 	case DVACT_ACTIVATE:
474 		break;
475 	case DVACT_DEACTIVATE:
476 		if (sc->sc_audiodev != NULL)
477 			rv = config_deactivate(sc->sc_audiodev);
478 		sc->sc_dying = 1;
479 		break;
480 	}
481 	return (rv);
482 }
483 
484 int
485 uaudio_detach(struct device *self, int flags)
486 {
487 	struct uaudio_softc *sc = (struct uaudio_softc *)self;
488 	int rv = 0;
489 
490 	/* Wait for outstanding requests to complete. */
491 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
492 
493 	if (sc->sc_audiodev != NULL)
494 		rv = config_detach(sc->sc_audiodev, flags);
495 
496 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
497 			   &sc->sc_dev);
498 
499 	return (rv);
500 }
501 
502 int
503 uaudio_query_encoding(void *addr, struct audio_encoding *fp)
504 {
505 	struct uaudio_softc *sc = addr;
506 	int flags = sc->sc_altflags;
507 	int idx;
508 
509 	if (sc->sc_dying)
510 		return (EIO);
511 
512 	if (sc->sc_nalts == 0 || flags == 0)
513 		return (ENXIO);
514 
515 	idx = fp->index;
516 	switch (idx) {
517 	case 0:
518 		strlcpy(fp->name, AudioEulinear, sizeof(fp->name));
519 		fp->encoding = AUDIO_ENCODING_ULINEAR;
520 		fp->precision = 8;
521 		fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
522 		return (0);
523 	case 1:
524 		strlcpy(fp->name, AudioEmulaw, sizeof(fp->name));
525 		fp->encoding = AUDIO_ENCODING_ULAW;
526 		fp->precision = 8;
527 		fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
528 		return (0);
529 	case 2:
530 		strlcpy(fp->name, AudioEalaw, sizeof(fp->name));
531 		fp->encoding = AUDIO_ENCODING_ALAW;
532 		fp->precision = 8;
533 		fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
534 		return (0);
535 	case 3:
536 		strlcpy(fp->name, AudioEslinear, sizeof(fp->name));
537 		fp->encoding = AUDIO_ENCODING_SLINEAR;
538 		fp->precision = 8;
539 		fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
540 		return (0);
541 	case 4:
542 		strlcpy(fp->name, AudioEslinear_le, sizeof(fp->name));
543 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
544 		fp->precision = 16;
545 		fp->flags = 0;
546 		return (0);
547 	case 5:
548 		strlcpy(fp->name, AudioEulinear_le, sizeof(fp->name));
549 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
550 		fp->precision = 16;
551 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
552 		return (0);
553 	case 6:
554 		strlcpy(fp->name, AudioEslinear_be, sizeof(fp->name));
555 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
556 		fp->precision = 16;
557 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
558 		return (0);
559 	case 7:
560 		strlcpy(fp->name, AudioEulinear_be, sizeof(fp->name));
561 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
562 		fp->precision = 16;
563 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
564 		return (0);
565 	default:
566 		return (EINVAL);
567 	}
568 }
569 
570 const usb_interface_descriptor_t *
571 uaudio_find_iface(const char *buf, int size, int *offsp, int subtype)
572 {
573 	const usb_interface_descriptor_t *d;
574 
575 	while (*offsp < size) {
576 		d = (const void *)(buf + *offsp);
577 		*offsp += d->bLength;
578 		if (d->bDescriptorType == UDESC_INTERFACE &&
579 		    d->bInterfaceClass == UICLASS_AUDIO &&
580 		    d->bInterfaceSubClass == subtype)
581 			return (d);
582 	}
583 	return (NULL);
584 }
585 
586 void
587 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
588 {
589 	int res, range;
590 	size_t len;
591 	struct mixerctl *nmc;
592 
593 	if (mc->class < UAC_NCLASSES) {
594 		DPRINTF(("%s: adding %s.%s\n",
595 			 __func__, uac_names[mc->class], mc->ctlname));
596 	} else {
597 		DPRINTF(("%s: adding %s\n", __func__, mc->ctlname));
598 	}
599 	len = sizeof(*mc) * (sc->sc_nctls + 1);
600 	nmc = malloc(len, M_USBDEV, M_NOWAIT);
601 	if (nmc == NULL) {
602 		printf("uaudio_mixer_add_ctl: no memory\n");
603 		return;
604 	}
605 	/* Copy old data, if there was any */
606 	if (sc->sc_nctls != 0) {
607 		bcopy(sc->sc_ctls, nmc, sizeof(*mc) * (sc->sc_nctls));
608 		free(sc->sc_ctls, M_USBDEV);
609 	}
610 	sc->sc_ctls = nmc;
611 
612 	mc->delta = 0;
613 	if (mc->type == MIX_ON_OFF) {
614 		mc->minval = 0;
615 		mc->maxval = 1;
616 	} else if (mc->type == MIX_SELECTOR) {
617 		;
618 	} else {
619 		/* Determine min and max values. */
620 		mc->minval = uaudio_signext(mc->type,
621 			uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
622 				   mc->wValue[0], mc->wIndex,
623 				   MIX_SIZE(mc->type)));
624 		mc->maxval = uaudio_signext(mc->type,
625 			uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
626 				   mc->wValue[0], mc->wIndex,
627 				   MIX_SIZE(mc->type)));
628 		range = mc->maxval - mc->minval;
629 		res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
630 				 mc->wValue[0], mc->wIndex,
631 				 MIX_SIZE(mc->type));
632 		if (res > 0 && range > 0)
633 			mc->delta = (res * 255 + res - 1) / range;
634 	}
635 
636 	sc->sc_ctls[sc->sc_nctls++] = *mc;
637 
638 #ifdef UAUDIO_DEBUG
639 	if (uaudiodebug > 2) {
640 		int i;
641 		DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
642 		for (i = 1; i < mc->nchan; i++)
643 			DPRINTF((",%04x", mc->wValue[i]));
644 		DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' "
645 			 "min=%d max=%d\n",
646 			 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
647 			 mc->minval, mc->maxval));
648 	}
649 #endif
650 }
651 
652 char *
653 uaudio_id_name(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
654 {
655 	static char buf[32];
656 	snprintf(buf, sizeof(buf), "i%d", id);
657 	return (buf);
658 }
659 
660 struct usb_audio_cluster
661 uaudio_get_cluster(int id, const struct io_terminal *iot)
662 {
663 	struct usb_audio_cluster r;
664 	const usb_descriptor_t *dp;
665 	int i;
666 
667 	for (i = 0; i < 25; i++) { /* avoid infinite loops */
668 		dp = iot[id].d.desc;
669 		if (dp == 0)
670 			goto bad;
671 		switch (dp->bDescriptorSubtype) {
672 		case UDESCSUB_AC_INPUT:
673 			r.bNrChannels = iot[id].d.it->bNrChannels;
674 			USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig));
675 			r.iChannelNames = iot[id].d.it->iChannelNames;
676 			return (r);
677 		case UDESCSUB_AC_OUTPUT:
678 			id = iot[id].d.ot->bSourceId;
679 			break;
680 		case UDESCSUB_AC_MIXER:
681 			r = *(struct usb_audio_cluster *)
682 				&iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
683 			return (r);
684 		case UDESCSUB_AC_SELECTOR:
685 			/* XXX This is not really right */
686 			id = iot[id].d.su->baSourceId[0];
687 			break;
688 		case UDESCSUB_AC_FEATURE:
689 			id = iot[id].d.fu->bSourceId;
690 			break;
691 		case UDESCSUB_AC_PROCESSING:
692 			r = *(struct usb_audio_cluster *)
693 				&iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
694 			return (r);
695 		case UDESCSUB_AC_EXTENSION:
696 			r = *(struct usb_audio_cluster *)
697 				&iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
698 			return (r);
699 		default:
700 			goto bad;
701 		}
702 	}
703  bad:
704 	printf("uaudio_get_cluster: bad data\n");
705 	memset(&r, 0, sizeof r);
706 	return (r);
707 
708 }
709 
710 void
711 uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
712 {
713 #ifdef UAUDIO_DEBUG
714 	const struct usb_audio_input_terminal *d = iot[id].d.it;
715 
716 	DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
717 		    "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
718 		    "iChannelNames=%d iTerminal=%d\n",
719 		    d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
720 		    d->bNrChannels, UGETW(d->wChannelConfig),
721 		    d->iChannelNames, d->iTerminal));
722 #endif
723 }
724 
725 void
726 uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
727 {
728 #ifdef UAUDIO_DEBUG
729 	const struct usb_audio_output_terminal *d = iot[id].d.ot;
730 
731 	DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
732 		    "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
733 		    d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
734 		    d->bSourceId, d->iTerminal));
735 #endif
736 }
737 
738 void
739 uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
740 {
741 	const struct usb_audio_mixer_unit *d = iot[id].d.mu;
742 	struct usb_audio_mixer_unit_1 *d1;
743 	int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
744 	uByte *bm;
745 	struct mixerctl mix;
746 
747 	DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
748 		    d->bUnitId, d->bNrInPins));
749 
750 	/* Compute the number of input channels */
751 	ichs = 0;
752 	for (i = 0; i < d->bNrInPins; i++)
753 		ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
754 
755 	/* and the number of output channels */
756 	d1 = (struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
757 	ochs = d1->bNrChannels;
758 	DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
759 
760 	bm = d1->bmControls;
761 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
762 	uaudio_determine_class(&iot[id], &mix);
763 	mix.type = MIX_SIGNED_16;
764 	mix.ctlunit = AudioNvolume;
765 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
766 	for (p = i = 0; i < d->bNrInPins; i++) {
767 		chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
768 		mc = 0;
769 		for (c = 0; c < chs; c++) {
770 			mo = 0;
771 			for (o = 0; o < ochs; o++) {
772 				bno = (p + c) * ochs + o;
773 				if (BIT(bno))
774 					mo++;
775 			}
776 			if (mo == 1)
777 				mc++;
778 		}
779 		if (mc == chs && chs <= MIX_MAX_CHAN) {
780 			k = 0;
781 			for (c = 0; c < chs; c++)
782 				for (o = 0; o < ochs; o++) {
783 					bno = (p + c) * ochs + o;
784 					if (BIT(bno))
785 						mix.wValue[k++] =
786 							MAKE(p+c+1, o+1);
787 				}
788 			snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s",
789 			    d->bUnitId, uaudio_id_name(sc, iot,
790 			    d->baSourceId[i]));
791 			mix.nchan = chs;
792 			uaudio_mixer_add_ctl(sc, &mix);
793 		} else {
794 			/* XXX */
795 		}
796 #undef BIT
797 		p += chs;
798 	}
799 
800 }
801 
802 void
803 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
804 {
805 	const struct usb_audio_selector_unit *d = iot[id].d.su;
806 	struct mixerctl mix;
807 	int i, wp;
808 
809 	DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
810 		    d->bUnitId, d->bNrInPins));
811 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
812 	mix.wValue[0] = MAKE(0, 0);
813 	uaudio_determine_class(&iot[id], &mix);
814 	mix.nchan = 1;
815 	mix.type = MIX_SELECTOR;
816 	mix.ctlunit = "";
817 	mix.minval = 1;
818 	mix.maxval = d->bNrInPins;
819 	wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId);
820 	for (i = 1; i <= d->bNrInPins; i++) {
821 		wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp,
822 			       "i%d", d->baSourceId[i - 1]);
823 		if (wp > MAX_AUDIO_DEV_LEN - 1)
824 			break;
825 	}
826 	uaudio_mixer_add_ctl(sc, &mix);
827 }
828 
829 #ifdef UAUDIO_DEBUG
830 const char *
831 uaudio_get_terminal_name(int terminal_type)
832 {
833 	static char buf[100];
834 
835 	switch (terminal_type) {
836 	/* USB terminal types */
837 	case UAT_UNDEFINED:	return "UAT_UNDEFINED";
838 	case UAT_STREAM:	return "UAT_STREAM";
839 	case UAT_VENDOR:	return "UAT_VENDOR";
840 	/* input terminal types */
841 	case UATI_UNDEFINED:	return "UATI_UNDEFINED";
842 	case UATI_MICROPHONE:	return "UATI_MICROPHONE";
843 	case UATI_DESKMICROPHONE:	return "UATI_DESKMICROPHONE";
844 	case UATI_PERSONALMICROPHONE:	return "UATI_PERSONALMICROPHONE";
845 	case UATI_OMNIMICROPHONE:	return "UATI_OMNIMICROPHONE";
846 	case UATI_MICROPHONEARRAY:	return "UATI_MICROPHONEARRAY";
847 	case UATI_PROCMICROPHONEARR:	return "UATI_PROCMICROPHONEARR";
848 	/* output terminal types */
849 	case UATO_UNDEFINED:	return "UATO_UNDEFINED";
850 	case UATO_SPEAKER:	return "UATO_SPEAKER";
851 	case UATO_HEADPHONES:	return "UATO_HEADPHONES";
852 	case UATO_DISPLAYAUDIO:	return "UATO_DISPLAYAUDIO";
853 	case UATO_DESKTOPSPEAKER:	return "UATO_DESKTOPSPEAKER";
854 	case UATO_ROOMSPEAKER:	return "UATO_ROOMSPEAKER";
855 	case UATO_COMMSPEAKER:	return "UATO_COMMSPEAKER";
856 	case UATO_SUBWOOFER:	return "UATO_SUBWOOFER";
857 	/* bidir terminal types */
858 	case UATB_UNDEFINED:	return "UATB_UNDEFINED";
859 	case UATB_HANDSET:	return "UATB_HANDSET";
860 	case UATB_HEADSET:	return "UATB_HEADSET";
861 	case UATB_SPEAKERPHONE:	return "UATB_SPEAKERPHONE";
862 	case UATB_SPEAKERPHONEESUP:	return "UATB_SPEAKERPHONEESUP";
863 	case UATB_SPEAKERPHONEECANC:	return "UATB_SPEAKERPHONEECANC";
864 	/* telephony terminal types */
865 	case UATT_UNDEFINED:	return "UATT_UNDEFINED";
866 	case UATT_PHONELINE:	return "UATT_PHONELINE";
867 	case UATT_TELEPHONE:	return "UATT_TELEPHONE";
868 	case UATT_DOWNLINEPHONE:	return "UATT_DOWNLINEPHONE";
869 	/* external terminal types */
870 	case UATE_UNDEFINED:	return "UATE_UNDEFINED";
871 	case UATE_ANALOGCONN:	return "UATE_ANALOGCONN";
872 	case UATE_LINECONN:	return "UATE_LINECONN";
873 	case UATE_LEGACYCONN:	return "UATE_LEGACYCONN";
874 	case UATE_DIGITALAUIFC:	return "UATE_DIGITALAUIFC";
875 	case UATE_SPDIF:	return "UATE_SPDIF";
876 	case UATE_1394DA:	return "UATE_1394DA";
877 	case UATE_1394DV:	return "UATE_1394DV";
878 	/* embedded function terminal types */
879 	case UATF_UNDEFINED:	return "UATF_UNDEFINED";
880 	case UATF_CALIBNOISE:	return "UATF_CALIBNOISE";
881 	case UATF_EQUNOISE:	return "UATF_EQUNOISE";
882 	case UATF_CDPLAYER:	return "UATF_CDPLAYER";
883 	case UATF_DAT:	return "UATF_DAT";
884 	case UATF_DCC:	return "UATF_DCC";
885 	case UATF_MINIDISK:	return "UATF_MINIDISK";
886 	case UATF_ANALOGTAPE:	return "UATF_ANALOGTAPE";
887 	case UATF_PHONOGRAPH:	return "UATF_PHONOGRAPH";
888 	case UATF_VCRAUDIO:	return "UATF_VCRAUDIO";
889 	case UATF_VIDEODISCAUDIO:	return "UATF_VIDEODISCAUDIO";
890 	case UATF_DVDAUDIO:	return "UATF_DVDAUDIO";
891 	case UATF_TVTUNERAUDIO:	return "UATF_TVTUNERAUDIO";
892 	case UATF_SATELLITE:	return "UATF_SATELLITE";
893 	case UATF_CABLETUNER:	return "UATF_CABLETUNER";
894 	case UATF_DSS:	return "UATF_DSS";
895 	case UATF_RADIORECV:	return "UATF_RADIORECV";
896 	case UATF_RADIOXMIT:	return "UATF_RADIOXMIT";
897 	case UATF_MULTITRACK:	return "UATF_MULTITRACK";
898 	case UATF_SYNTHESIZER:	return "UATF_SYNTHESIZER";
899 	default:
900 		snprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type);
901 		return buf;
902 	}
903 }
904 #endif
905 
906 int
907 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
908 {
909 	int terminal_type;
910 
911 	if (iot == NULL || iot->output == NULL) {
912 		mix->class = UAC_OUTPUT;
913 		return 0;
914 	}
915 	terminal_type = 0;
916 	if (iot->output->size == 1)
917 		terminal_type = iot->output->terminals[0];
918 	/*
919 	 * If the only output terminal is USB,
920 	 * the class is UAC_RECORD.
921 	 */
922 	if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
923 		mix->class = UAC_RECORD;
924 		if (iot->inputs_size == 1
925 		    && iot->inputs[0] != NULL
926 		    && iot->inputs[0]->size == 1)
927 			return iot->inputs[0]->terminals[0];
928 		else
929 			return 0;
930 	}
931 	/*
932 	 * If the ultimate destination of the unit is just one output
933 	 * terminal and the unit is connected to the output terminal
934 	 * directly, the class is UAC_OUTPUT.
935 	 */
936 	if (terminal_type != 0 && iot->direct) {
937 		mix->class = UAC_OUTPUT;
938 		return terminal_type;
939 	}
940 	/*
941 	 * If the unit is connected to just one input terminal,
942 	 * the class is UAC_INPUT.
943 	 */
944 	if (iot->inputs_size == 1 && iot->inputs[0] != NULL
945 	    && iot->inputs[0]->size == 1) {
946 		mix->class = UAC_INPUT;
947 		return iot->inputs[0]->terminals[0];
948 	}
949 	/*
950 	 * Otherwise, the class is UAC_OUTPUT.
951 	 */
952 	mix->class = UAC_OUTPUT;
953 	return terminal_type;
954 }
955 
956 const char *
957 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
958 {
959 	int terminal_type;
960 
961 	terminal_type = uaudio_determine_class(iot, mix);
962 	if (mix->class == UAC_RECORD && terminal_type == 0)
963 		return AudioNmixerout;
964 	DPRINTF(("%s: terminal_type=%s\n", __func__,
965 		 uaudio_get_terminal_name(terminal_type)));
966 	switch (terminal_type) {
967 	case UAT_STREAM:
968 		return AudioNdac;
969 
970 	case UATI_MICROPHONE:
971 	case UATI_DESKMICROPHONE:
972 	case UATI_PERSONALMICROPHONE:
973 	case UATI_OMNIMICROPHONE:
974 	case UATI_MICROPHONEARRAY:
975 	case UATI_PROCMICROPHONEARR:
976 		return AudioNmicrophone;
977 
978 	case UATO_SPEAKER:
979 	case UATO_DESKTOPSPEAKER:
980 	case UATO_ROOMSPEAKER:
981 	case UATO_COMMSPEAKER:
982 		return AudioNspeaker;
983 
984 	case UATO_HEADPHONES:
985 		return AudioNheadphone;
986 
987 	case UATO_SUBWOOFER:
988 		return AudioNlfe;
989 
990 	/* telephony terminal types */
991 	case UATT_UNDEFINED:
992 	case UATT_PHONELINE:
993 	case UATT_TELEPHONE:
994 	case UATT_DOWNLINEPHONE:
995 		return "phone";
996 
997 	case UATE_ANALOGCONN:
998 	case UATE_LINECONN:
999 	case UATE_LEGACYCONN:
1000 		return AudioNline;
1001 
1002 	case UATE_DIGITALAUIFC:
1003 	case UATE_SPDIF:
1004 	case UATE_1394DA:
1005 	case UATE_1394DV:
1006 		return AudioNaux;
1007 
1008 	case UATF_CDPLAYER:
1009 		return AudioNcd;
1010 
1011 	case UATF_SYNTHESIZER:
1012 		return AudioNfmsynth;
1013 
1014 	case UATF_VIDEODISCAUDIO:
1015 	case UATF_DVDAUDIO:
1016 	case UATF_TVTUNERAUDIO:
1017 		return AudioNvideo;
1018 
1019 	case UAT_UNDEFINED:
1020 	case UAT_VENDOR:
1021 	case UATI_UNDEFINED:
1022 /* output terminal types */
1023 	case UATO_UNDEFINED:
1024 	case UATO_DISPLAYAUDIO:
1025 /* bidir terminal types */
1026 	case UATB_UNDEFINED:
1027 	case UATB_HANDSET:
1028 	case UATB_HEADSET:
1029 	case UATB_SPEAKERPHONE:
1030 	case UATB_SPEAKERPHONEESUP:
1031 	case UATB_SPEAKERPHONEECANC:
1032 /* external terminal types */
1033 	case UATE_UNDEFINED:
1034 /* embedded function terminal types */
1035 	case UATF_UNDEFINED:
1036 	case UATF_CALIBNOISE:
1037 	case UATF_EQUNOISE:
1038 	case UATF_DAT:
1039 	case UATF_DCC:
1040 	case UATF_MINIDISK:
1041 	case UATF_ANALOGTAPE:
1042 	case UATF_PHONOGRAPH:
1043 	case UATF_VCRAUDIO:
1044 	case UATF_SATELLITE:
1045 	case UATF_CABLETUNER:
1046 	case UATF_DSS:
1047 	case UATF_RADIORECV:
1048 	case UATF_RADIOXMIT:
1049 	case UATF_MULTITRACK:
1050 	case 0xffff:
1051 	default:
1052 		DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
1053 		return AudioNmaster;
1054 	}
1055 }
1056 
1057 void
1058 uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1059 {
1060 	const struct usb_audio_feature_unit *d = iot[id].d.fu;
1061 	uByte *ctls = (uByte *)d->bmaControls;
1062 	int ctlsize = d->bControlSize;
1063 	int nchan = (d->bLength - 7) / ctlsize;
1064 	u_int fumask, mmask, cmask;
1065 	struct mixerctl mix;
1066 	int chan, ctl, i, unit;
1067 	const char *mixername;
1068 
1069 #define GET(i) (ctls[(i)*ctlsize] | \
1070 		(ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
1071 
1072 	mmask = GET(0);
1073 	/* Figure out what we can control */
1074 	for (cmask = 0, chan = 1; chan < nchan; chan++) {
1075 		DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
1076 			    chan, GET(chan)));
1077 		cmask |= GET(chan);
1078 	}
1079 
1080 	DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, "
1081 		    "%d channels, mmask=0x%04x, cmask=0x%04x\n",
1082 		    d->bUnitId, nchan, mmask, cmask));
1083 
1084 	if (nchan > MIX_MAX_CHAN)
1085 		nchan = MIX_MAX_CHAN;
1086 	unit = d->bUnitId;
1087 	mix.wIndex = MAKE(unit, sc->sc_ac_iface);
1088 	for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
1089 		fumask = FU_MASK(ctl);
1090 		DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
1091 			    ctl, fumask));
1092 		if (mmask & fumask) {
1093 			mix.nchan = 1;
1094 			mix.wValue[0] = MAKE(ctl, 0);
1095 		} else if (cmask & fumask) {
1096 			mix.nchan = nchan - 1;
1097 			for (i = 1; i < nchan; i++) {
1098 				if (GET(i) & fumask)
1099 					mix.wValue[i-1] = MAKE(ctl, i);
1100 				else
1101 					mix.wValue[i-1] = -1;
1102 			}
1103 		} else {
1104 			continue;
1105 		}
1106 #undef GET
1107 		mixername = uaudio_feature_name(&iot[id], &mix);
1108 		switch (ctl) {
1109 		case MUTE_CONTROL:
1110 			mix.type = MIX_ON_OFF;
1111 			mix.ctlunit = "";
1112 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1113 				 "%s.%s", mixername, AudioNmute);
1114 			break;
1115 		case VOLUME_CONTROL:
1116 			mix.type = MIX_SIGNED_16;
1117 			mix.ctlunit = AudioNvolume;
1118 			strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname));
1119 			break;
1120 		case BASS_CONTROL:
1121 			mix.type = MIX_SIGNED_8;
1122 			mix.ctlunit = AudioNbass;
1123 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1124 				 "%s.%s", mixername, AudioNbass);
1125 			break;
1126 		case MID_CONTROL:
1127 			mix.type = MIX_SIGNED_8;
1128 			mix.ctlunit = AudioNmid;
1129 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1130 				 "%s.%s", mixername, AudioNmid);
1131 			break;
1132 		case TREBLE_CONTROL:
1133 			mix.type = MIX_SIGNED_8;
1134 			mix.ctlunit = AudioNtreble;
1135 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1136 				 "%s.%s", mixername, AudioNtreble);
1137 			break;
1138 		case GRAPHIC_EQUALIZER_CONTROL:
1139 			continue; /* XXX don't add anything */
1140 			break;
1141 		case AGC_CONTROL:
1142 			mix.type = MIX_ON_OFF;
1143 			mix.ctlunit = "";
1144 			snprintf(mix.ctlname, sizeof(mix.ctlname), "%s.%s",
1145 				 mixername, AudioNagc);
1146 			break;
1147 		case DELAY_CONTROL:
1148 			mix.type = MIX_UNSIGNED_16;
1149 			mix.ctlunit = "4 ms";
1150 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1151 				 "%s.%s", mixername, AudioNdelay);
1152 			break;
1153 		case BASS_BOOST_CONTROL:
1154 			mix.type = MIX_ON_OFF;
1155 			mix.ctlunit = "";
1156 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1157 				 "%s.%s", mixername, AudioNbassboost);
1158 			break;
1159 		case LOUDNESS_CONTROL:
1160 			mix.type = MIX_ON_OFF;
1161 			mix.ctlunit = "";
1162 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1163 				 "%s.%s", mixername, AudioNloudness);
1164 			break;
1165 		}
1166 		uaudio_mixer_add_ctl(sc, &mix);
1167 	}
1168 }
1169 
1170 void
1171 uaudio_add_processing_updown(struct uaudio_softc *sc,
1172 			     const struct io_terminal *iot, int id)
1173 {
1174 	const struct usb_audio_processing_unit *d = iot[id].d.pu;
1175 	const struct usb_audio_processing_unit_1 *d1 =
1176 	    (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
1177 	const struct usb_audio_processing_unit_updown *ud =
1178 	    (const struct usb_audio_processing_unit_updown *)
1179 		&d1->bmControls[d1->bControlSize];
1180 	struct mixerctl mix;
1181 	int i;
1182 
1183 	DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
1184 		    d->bUnitId, ud->bNrModes));
1185 
1186 	if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
1187 		DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
1188 		return;
1189 	}
1190 
1191 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1192 	mix.nchan = 1;
1193 	mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
1194 	uaudio_determine_class(&iot[id], &mix);
1195 	mix.type = MIX_ON_OFF;	/* XXX */
1196 	mix.ctlunit = "";
1197 	snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId);
1198 
1199 	for (i = 0; i < ud->bNrModes; i++) {
1200 		DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
1201 			    i, UGETW(ud->waModes[i])));
1202 		/* XXX */
1203 	}
1204 	uaudio_mixer_add_ctl(sc, &mix);
1205 }
1206 
1207 void
1208 uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1209 {
1210 	const struct usb_audio_processing_unit *d = iot[id].d.pu;
1211 	const struct usb_audio_processing_unit_1 *d1 =
1212 	    (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
1213 	int ptype = UGETW(d->wProcessType);
1214 	struct mixerctl mix;
1215 
1216 	DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
1217 		    "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
1218 
1219 	if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
1220 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1221 		mix.nchan = 1;
1222 		mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
1223 		uaudio_determine_class(&iot[id], &mix);
1224 		mix.type = MIX_ON_OFF;
1225 		mix.ctlunit = "";
1226 		snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable",
1227 		    d->bUnitId, ptype);
1228 		uaudio_mixer_add_ctl(sc, &mix);
1229 	}
1230 
1231 	switch(ptype) {
1232 	case UPDOWNMIX_PROCESS:
1233 		uaudio_add_processing_updown(sc, iot, id);
1234 		break;
1235 	case DOLBY_PROLOGIC_PROCESS:
1236 	case P3D_STEREO_EXTENDER_PROCESS:
1237 	case REVERBATION_PROCESS:
1238 	case CHORUS_PROCESS:
1239 	case DYN_RANGE_COMP_PROCESS:
1240 	default:
1241 #ifdef UAUDIO_DEBUG
1242 		printf("uaudio_add_processing: unit %d, type=%d not impl.\n",
1243 		       d->bUnitId, ptype);
1244 #endif
1245 		break;
1246 	}
1247 }
1248 
1249 void
1250 uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1251 {
1252 	const struct usb_audio_extension_unit *d = iot[id].d.eu;
1253 	const struct usb_audio_extension_unit_1 *d1 =
1254 	    (const struct usb_audio_extension_unit_1 *)&d->baSourceId[d->bNrInPins];
1255 	struct mixerctl mix;
1256 
1257 	DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
1258 		    d->bUnitId, d->bNrInPins));
1259 
1260 	if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
1261 		return;
1262 
1263 	if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
1264 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1265 		mix.nchan = 1;
1266 		mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
1267 		uaudio_determine_class(&iot[id], &mix);
1268 		mix.type = MIX_ON_OFF;
1269 		mix.ctlunit = "";
1270 		snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable",
1271 		    d->bUnitId);
1272 		uaudio_mixer_add_ctl(sc, &mix);
1273 	}
1274 }
1275 
1276 struct terminal_list*
1277 uaudio_merge_terminal_list(const struct io_terminal *iot)
1278 {
1279 	struct terminal_list *tml;
1280 	uint16_t *ptm;
1281 	int i, len;
1282 
1283 	len = 0;
1284 	if (iot->inputs == NULL)
1285 		return NULL;
1286 	for (i = 0; i < iot->inputs_size; i++) {
1287 		if (iot->inputs[i] != NULL)
1288 			len += iot->inputs[i]->size;
1289 	}
1290 	tml = malloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT);
1291 	if (tml == NULL) {
1292 		printf("uaudio_merge_terminal_list: no memory\n");
1293 		return NULL;
1294 	}
1295 	tml->size = 0;
1296 	ptm = tml->terminals;
1297 	for (i = 0; i < iot->inputs_size; i++) {
1298 		if (iot->inputs[i] == NULL)
1299 			continue;
1300 		if (iot->inputs[i]->size > len)
1301 			break;
1302 		memcpy(ptm, iot->inputs[i]->terminals,
1303 		       iot->inputs[i]->size * sizeof(uint16_t));
1304 		tml->size += iot->inputs[i]->size;
1305 		ptm += iot->inputs[i]->size;
1306 		len -= iot->inputs[i]->size;
1307 	}
1308 	return tml;
1309 }
1310 
1311 struct terminal_list *
1312 uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id)
1313 {
1314 	struct terminal_list *tml;
1315 	struct io_terminal *it;
1316 	int src_id, i;
1317 
1318 	it = &iot[id];
1319 	if (it->output != NULL) {
1320 		/* already has outtype? */
1321 		for (i = 0; i < it->output->size; i++)
1322 			if (it->output->terminals[i] == outtype)
1323 				return uaudio_merge_terminal_list(it);
1324 		tml = malloc(TERMINAL_LIST_SIZE(it->output->size + 1),
1325 			     M_TEMP, M_NOWAIT);
1326 		if (tml == NULL) {
1327 			printf("uaudio_io_terminaltype: no memory\n");
1328 			return uaudio_merge_terminal_list(it);
1329 		}
1330 		memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size));
1331 		tml->terminals[it->output->size] = outtype;
1332 		tml->size++;
1333 		free(it->output, M_TEMP);
1334 		it->output = tml;
1335 		if (it->inputs != NULL) {
1336 			for (i = 0; i < it->inputs_size; i++)
1337 				if (it->inputs[i] != NULL)
1338 					free(it->inputs[i], M_TEMP);
1339 			free(it->inputs, M_TEMP);
1340 		}
1341 		it->inputs_size = 0;
1342 		it->inputs = NULL;
1343 	} else {		/* end `iot[id] != NULL' */
1344 		it->inputs_size = 0;
1345 		it->inputs = NULL;
1346 		it->output = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1347 		if (it->output == NULL) {
1348 			printf("uaudio_io_terminaltype: no memory\n");
1349 			return NULL;
1350 		}
1351 		it->output->terminals[0] = outtype;
1352 		it->output->size = 1;
1353 		it->direct = FALSE;
1354 	}
1355 
1356 	switch (it->d.desc->bDescriptorSubtype) {
1357 	case UDESCSUB_AC_INPUT:
1358 		it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1359 		if (it->inputs == NULL) {
1360 			printf("uaudio_io_terminaltype: no memory\n");
1361 			return NULL;
1362 		}
1363 		tml = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1364 		if (tml == NULL) {
1365 			printf("uaudio_io_terminaltype: no memory\n");
1366 			free(it->inputs, M_TEMP);
1367 			it->inputs = NULL;
1368 			return NULL;
1369 		}
1370 		it->inputs[0] = tml;
1371 		tml->terminals[0] = UGETW(it->d.it->wTerminalType);
1372 		tml->size = 1;
1373 		it->inputs_size = 1;
1374 		return uaudio_merge_terminal_list(it);
1375 	case UDESCSUB_AC_FEATURE:
1376 		src_id = it->d.fu->bSourceId;
1377 		it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1378 		if (it->inputs == NULL) {
1379 			printf("uaudio_io_terminaltype: no memory\n");
1380 			return uaudio_io_terminaltype(outtype, iot, src_id);
1381 		}
1382 		it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1383 		it->inputs_size = 1;
1384 		return uaudio_merge_terminal_list(it);
1385 	case UDESCSUB_AC_OUTPUT:
1386 		it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1387 		if (it->inputs == NULL) {
1388 			printf("uaudio_io_terminaltype: no memory\n");
1389 			return NULL;
1390 		}
1391 		src_id = it->d.ot->bSourceId;
1392 		it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1393 		it->inputs_size = 1;
1394 		iot[src_id].direct = TRUE;
1395 		return NULL;
1396 	case UDESCSUB_AC_MIXER:
1397 		it->inputs_size = 0;
1398 		it->inputs = malloc(sizeof(struct terminal_list *)
1399 				    * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT);
1400 		if (it->inputs == NULL) {
1401 			printf("uaudio_io_terminaltype: no memory\n");
1402 			return NULL;
1403 		}
1404 		for (i = 0; i < it->d.mu->bNrInPins; i++) {
1405 			src_id = it->d.mu->baSourceId[i];
1406 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1407 							       src_id);
1408 			it->inputs_size++;
1409 		}
1410 		return uaudio_merge_terminal_list(it);
1411 	case UDESCSUB_AC_SELECTOR:
1412 		it->inputs_size = 0;
1413 		it->inputs = malloc(sizeof(struct terminal_list *)
1414 				    * it->d.su->bNrInPins, M_TEMP, M_NOWAIT);
1415 		if (it->inputs == NULL) {
1416 			printf("uaudio_io_terminaltype: no memory\n");
1417 			return NULL;
1418 		}
1419 		for (i = 0; i < it->d.su->bNrInPins; i++) {
1420 			src_id = it->d.su->baSourceId[i];
1421 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1422 							       src_id);
1423 			it->inputs_size++;
1424 		}
1425 		return uaudio_merge_terminal_list(it);
1426 	case UDESCSUB_AC_PROCESSING:
1427 		it->inputs_size = 0;
1428 		it->inputs = malloc(sizeof(struct terminal_list *)
1429 				    * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT);
1430 		if (it->inputs == NULL) {
1431 			printf("uaudio_io_terminaltype: no memory\n");
1432 			return NULL;
1433 		}
1434 		for (i = 0; i < it->d.pu->bNrInPins; i++) {
1435 			src_id = it->d.pu->baSourceId[i];
1436 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1437 							       src_id);
1438 			it->inputs_size++;
1439 		}
1440 		return uaudio_merge_terminal_list(it);
1441 	case UDESCSUB_AC_EXTENSION:
1442 		it->inputs_size = 0;
1443 		it->inputs = malloc(sizeof(struct terminal_list *)
1444 				    * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT);
1445 		if (it->inputs == NULL) {
1446 			printf("uaudio_io_terminaltype: no memory\n");
1447 			return NULL;
1448 		}
1449 		for (i = 0; i < it->d.eu->bNrInPins; i++) {
1450 			src_id = it->d.eu->baSourceId[i];
1451 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1452 							       src_id);
1453 			it->inputs_size++;
1454 		}
1455 		return uaudio_merge_terminal_list(it);
1456 	case UDESCSUB_AC_HEADER:
1457 	default:
1458 		return NULL;
1459 	}
1460 }
1461 
1462 usbd_status
1463 uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
1464 {
1465 	usbd_status err;
1466 
1467 	err = uaudio_identify_ac(sc, cdesc);
1468 	if (err)
1469 		return (err);
1470 	return (uaudio_identify_as(sc, cdesc));
1471 }
1472 
1473 void
1474 uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai)
1475 {
1476 	size_t len;
1477 	struct as_info *nai;
1478 
1479 	len = sizeof(*ai) * (sc->sc_nalts + 1);
1480 	nai = malloc(len, M_USBDEV, M_NOWAIT);
1481 	if (nai == NULL) {
1482 		printf("uaudio_add_alt: no memory\n");
1483 		return;
1484 	}
1485 	/* Copy old data, if there was any */
1486 	if (sc->sc_nalts != 0) {
1487 		bcopy(sc->sc_alts, nai, sizeof(*ai) * (sc->sc_nalts));
1488 		free(sc->sc_alts, M_USBDEV);
1489 	}
1490 	sc->sc_alts = nai;
1491 	DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
1492 		    ai->alt, ai->encoding));
1493 	sc->sc_alts[sc->sc_nalts++] = *ai;
1494 }
1495 
1496 usbd_status
1497 uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
1498 		  int size, const usb_interface_descriptor_t *id)
1499 #define offs (*offsp)
1500 {
1501 	const struct usb_audio_streaming_interface_descriptor *asid;
1502 	const struct usb_audio_streaming_type1_descriptor *asf1d;
1503 	const usb_endpoint_descriptor_audio_t *ed;
1504 	const usb_endpoint_descriptor_audio_t *epdesc1;
1505 	const struct usb_audio_streaming_endpoint_descriptor *sed;
1506 	int format, chan, prec, enc;
1507 	int dir, type, sync;
1508 	struct as_info ai;
1509 	const char *format_str;
1510 
1511 	asid = (const void *)(buf + offs);
1512 	if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
1513 	    asid->bDescriptorSubtype != AS_GENERAL)
1514 		return (USBD_INVAL);
1515 	DPRINTF(("uaudio_process_as: asid: bTerminalLink=%d wFormatTag=%d\n",
1516 		 asid->bTerminalLink, UGETW(asid->wFormatTag)));
1517 	offs += asid->bLength;
1518 	if (offs > size)
1519 		return (USBD_INVAL);
1520 
1521 	asf1d = (const void *)(buf + offs);
1522 	if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
1523 	    asf1d->bDescriptorSubtype != FORMAT_TYPE)
1524 		return (USBD_INVAL);
1525 	offs += asf1d->bLength;
1526 	if (offs > size)
1527 		return (USBD_INVAL);
1528 
1529 	if (asf1d->bFormatType != FORMAT_TYPE_I) {
1530 		printf("%s: ignored setting with type %d format\n",
1531 		       sc->sc_dev.dv_xname, UGETW(asid->wFormatTag));
1532 		return (USBD_NORMAL_COMPLETION);
1533 	}
1534 
1535 	ed = (const void *)(buf + offs);
1536 	if (ed->bDescriptorType != UDESC_ENDPOINT)
1537 		return (USBD_INVAL);
1538 	DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
1539 		 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
1540 		 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
1541 		 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
1542 		 ed->bmAttributes, UGETW(ed->wMaxPacketSize),
1543 		 ed->bInterval, ed->bRefresh, ed->bSynchAddress));
1544 	offs += ed->bLength;
1545 	if (offs > size)
1546 		return (USBD_INVAL);
1547 	if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
1548 		return (USBD_INVAL);
1549 
1550 	dir = UE_GET_DIR(ed->bEndpointAddress);
1551 	type = UE_GET_ISO_TYPE(ed->bmAttributes);
1552 	if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
1553 	    dir == UE_DIR_IN && type == UE_ISO_ADAPT)
1554 		type = UE_ISO_ASYNC;
1555 
1556 	/* We can't handle endpoints that need a sync pipe yet. */
1557 	sync = FALSE;
1558 	/* bSynchAddress set to 0 indicates sync pipe is not needed. */
1559 	if (ed->bSynchAddress != 0) {
1560 		if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
1561 			sync = TRUE;
1562 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1563 			printf("%s: ignored input endpoint of type adaptive\n",
1564 			       sc->sc_dev.dv_xname);
1565 			return (USBD_NORMAL_COMPLETION);
1566 #endif
1567 		}
1568 		if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
1569 			sync = TRUE;
1570 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1571 			printf("%s: ignored output endpoint of type async\n",
1572 			       sc->sc_dev.dv_xname);
1573 			return (USBD_NORMAL_COMPLETION);
1574 #endif
1575 		}
1576 	}
1577 	if (sync && id->bNumEndpoints < 2) {
1578 		printf("%s: sync pipe needed, but no sync endpoint given\n",
1579 		       sc->sc_dev.dv_xname);
1580 		return (USBD_NORMAL_COMPLETION);
1581 	}
1582 
1583 	sed = (const void *)(buf + offs);
1584 	if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
1585 	    sed->bDescriptorSubtype != AS_GENERAL)
1586 		return (USBD_INVAL);
1587 	DPRINTF((" streaming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength));
1588 	offs += sed->bLength;
1589 	if (offs > size)
1590 		return (USBD_INVAL);
1591 
1592 	epdesc1 = NULL;
1593 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
1594 	if (sync) {
1595 		epdesc1 = (const void*)(buf + offs);
1596 		if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
1597 			return USBD_INVAL;
1598 		DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
1599 			 "bDescriptorType=%d bEndpointAddress=%d "
1600 			 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
1601 			 "bRefresh=%d bSynchAddress=%d\n",
1602 			 epdesc1->bLength, epdesc1->bDescriptorType,
1603 			 epdesc1->bEndpointAddress, epdesc1->bmAttributes,
1604 			 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
1605 			 epdesc1->bRefresh, epdesc1->bSynchAddress));
1606 		offs += epdesc1->bLength;
1607 		if (offs > size)
1608 			return USBD_INVAL;
1609 		if (epdesc1->bSynchAddress != 0) {
1610 			printf("%s: invalid endpoint: bSynchAddress=0\n",
1611 			       sc->sc_dev.dv_xname);
1612 			return USBD_INVAL;
1613 		}
1614 		if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
1615 			printf("%s: invalid endpoint: bmAttributes=0x%x\n",
1616 			       sc->sc_dev.dv_xname, epdesc1->bmAttributes);
1617 			return USBD_INVAL;
1618 		}
1619 		if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
1620 			printf("%s: invalid endpoint addresses: "
1621 			       "ep[0]->bSynchAddress=0x%x "
1622 			       "ep[1]->bEndpointAddress=0x%x\n",
1623 			       sc->sc_dev.dv_xname, ed->bSynchAddress,
1624 			       epdesc1->bEndpointAddress);
1625 			return USBD_INVAL;
1626 		}
1627 		/* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
1628 	}
1629 #endif
1630 
1631 	format = UGETW(asid->wFormatTag);
1632 	chan = asf1d->bNrChannels;
1633 	prec = asf1d->bBitResolution;
1634 	if (prec != 8 && prec != 16 && prec != 24) {
1635 		printf("%s: ignored setting with precision %d\n",
1636 		       sc->sc_dev.dv_xname, prec);
1637 		return (USBD_NORMAL_COMPLETION);
1638 	}
1639 	switch (format) {
1640 	case UA_FMT_PCM:
1641 		if (prec == 8) {
1642 			sc->sc_altflags |= HAS_8;
1643 		} else if (prec == 16) {
1644 			sc->sc_altflags |= HAS_16;
1645 		} else if (prec == 24) {
1646 			sc->sc_altflags |= HAS_24;
1647 		}
1648 		enc = AUDIO_ENCODING_SLINEAR_LE;
1649 		format_str = "pcm";
1650 		break;
1651 	case UA_FMT_PCM8:
1652 		enc = AUDIO_ENCODING_ULINEAR_LE;
1653 		sc->sc_altflags |= HAS_8U;
1654 		format_str = "pcm8";
1655 		break;
1656 	case UA_FMT_ALAW:
1657 		enc = AUDIO_ENCODING_ALAW;
1658 		sc->sc_altflags |= HAS_ALAW;
1659 		format_str = "alaw";
1660 		break;
1661 	case UA_FMT_MULAW:
1662 		enc = AUDIO_ENCODING_ULAW;
1663 		sc->sc_altflags |= HAS_MULAW;
1664 		format_str = "mulaw";
1665 		break;
1666 	case UA_FMT_IEEE_FLOAT:
1667 	default:
1668 		printf("%s: ignored setting with format %d\n",
1669 		       sc->sc_dev.dv_xname, format);
1670 		return (USBD_NORMAL_COMPLETION);
1671 	}
1672 #ifdef UAUDIO_DEBUG
1673 	printf("%s: %s: %dch, %d/%dbit, %s,", sc->sc_dev.dv_xname,
1674 	       dir == UE_DIR_IN ? "recording" : "playback",
1675 	       chan, prec, asf1d->bSubFrameSize * 8, format_str);
1676 	if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
1677 		printf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
1678 	} else {
1679 		int r;
1680 		printf(" %d", UA_GETSAMP(asf1d, 0));
1681 		for (r = 1; r < asf1d->bSamFreqType; r++)
1682 			printf(",%d", UA_GETSAMP(asf1d, r));
1683 		printf("Hz\n");
1684 	}
1685 #endif
1686 	ai.alt = id->bAlternateSetting;
1687 	ai.encoding = enc;
1688 	ai.attributes = sed->bmAttributes;
1689 	ai.idesc = id;
1690 	ai.edesc = ed;
1691 	ai.edesc1 = epdesc1;
1692 	ai.asf1desc = asf1d;
1693 	ai.sc_busy = 0;
1694 	uaudio_add_alt(sc, &ai);
1695 #ifdef UAUDIO_DEBUG
1696 	if (ai.attributes & UA_SED_FREQ_CONTROL)
1697 		DPRINTFN(1, ("uaudio_process_as:  FREQ_CONTROL\n"));
1698 	if (ai.attributes & UA_SED_PITCH_CONTROL)
1699 		DPRINTFN(1, ("uaudio_process_as:  PITCH_CONTROL\n"));
1700 #endif
1701 	sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD;
1702 
1703 	return (USBD_NORMAL_COMPLETION);
1704 }
1705 #undef offs
1706 
1707 usbd_status
1708 uaudio_identify_as(struct uaudio_softc *sc,
1709 		   const usb_config_descriptor_t *cdesc)
1710 {
1711 	const usb_interface_descriptor_t *id;
1712 	const char *buf;
1713 	int size, offs;
1714 
1715 	size = UGETW(cdesc->wTotalLength);
1716 	buf = (const char *)cdesc;
1717 
1718 	/* Locate the AudioStreaming interface descriptor. */
1719 	offs = 0;
1720 	id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
1721 	if (id == NULL)
1722 		return (USBD_INVAL);
1723 
1724 	/* Loop through all the alternate settings. */
1725 	while (offs <= size) {
1726 		DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
1727 		    id->bInterfaceNumber, offs));
1728 		switch (id->bNumEndpoints) {
1729 		case 0:
1730 			DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
1731 				     id->bAlternateSetting));
1732 			sc->sc_nullalt = id->bAlternateSetting;
1733 			break;
1734 		case 1:
1735 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
1736 		case 2:
1737 #endif
1738 			uaudio_process_as(sc, buf, &offs, size, id);
1739 			break;
1740 		default:
1741 			printf("%s: ignored audio interface with %d "
1742 			       "endpoints\n",
1743 			       sc->sc_dev.dv_xname, id->bNumEndpoints);
1744 			break;
1745 		}
1746 		id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
1747 		if (id == NULL)
1748 			break;
1749 	}
1750 	if (offs > size)
1751 		return (USBD_INVAL);
1752 	DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
1753 
1754 	if (sc->sc_mode == 0) {
1755 		printf("%s: no usable endpoint found\n",
1756 		       sc->sc_dev.dv_xname);
1757 		return (USBD_INVAL);
1758 	}
1759 
1760 	return (USBD_NORMAL_COMPLETION);
1761 }
1762 
1763 usbd_status
1764 uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
1765 {
1766 	struct io_terminal* iot;
1767 	const usb_interface_descriptor_t *id;
1768 	const struct usb_audio_control_descriptor *acdp;
1769 	const usb_descriptor_t *dp;
1770 	const struct usb_audio_output_terminal *pot;
1771 	struct terminal_list *tml;
1772 	const char *buf, *ibuf, *ibufend;
1773 	int size, offs, aclen, ndps, i, j;
1774 
1775 	size = UGETW(cdesc->wTotalLength);
1776 	buf = (char *)cdesc;
1777 
1778 	/* Locate the AudioControl interface descriptor. */
1779 	offs = 0;
1780 	id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
1781 	if (id == NULL)
1782 		return (USBD_INVAL);
1783 	if (offs + sizeof *acdp > size)
1784 		return (USBD_INVAL);
1785 	sc->sc_ac_iface = id->bInterfaceNumber;
1786 	DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface));
1787 
1788 	/* A class-specific AC interface header should follow. */
1789 	ibuf = buf + offs;
1790 	acdp = (const struct usb_audio_control_descriptor *)ibuf;
1791 	if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
1792 	    acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
1793 		return (USBD_INVAL);
1794 	aclen = UGETW(acdp->wTotalLength);
1795 	if (offs + aclen > size)
1796 		return (USBD_INVAL);
1797 
1798 	if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
1799 	     UGETW(acdp->bcdADC) != UAUDIO_VERSION)
1800 		return (USBD_INVAL);
1801 
1802 	sc->sc_audio_rev = UGETW(acdp->bcdADC);
1803 	DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n",
1804 		 sc->sc_audio_rev, aclen));
1805 
1806 	sc->sc_nullalt = -1;
1807 
1808 	/* Scan through all the AC specific descriptors */
1809 	ibufend = ibuf + aclen;
1810 	dp = (const usb_descriptor_t *)ibuf;
1811 	ndps = 0;
1812 	iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO);
1813 	if (iot == NULL) {
1814 		printf("%s: no memory\n", __func__);
1815 		return USBD_NOMEM;
1816 	}
1817 	for (;;) {
1818 		ibuf += dp->bLength;
1819 		if (ibuf >= ibufend)
1820 			break;
1821 		dp = (const usb_descriptor_t *)ibuf;
1822 		if (ibuf + dp->bLength > ibufend) {
1823 			free(iot, M_TEMP);
1824 			return (USBD_INVAL);
1825 		}
1826 		if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
1827 			printf("uaudio_identify_ac: skip desc type=0x%02x\n",
1828 			       dp->bDescriptorType);
1829 			continue;
1830 		}
1831 		i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId;
1832 		iot[i].d.desc = dp;
1833 		if (i > ndps)
1834 			ndps = i;
1835 	}
1836 	ndps++;
1837 
1838 	/* construct io_terminal */
1839 	for (i = 0; i < ndps; i++) {
1840 		dp = iot[i].d.desc;
1841 		if (dp == NULL)
1842 			continue;
1843 		if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT)
1844 			continue;
1845 		pot = iot[i].d.ot;
1846 		tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i);
1847 		if (tml != NULL)
1848 			free(tml, M_TEMP);
1849 	}
1850 
1851 #ifdef UAUDIO_DEBUG
1852 	for (i = 0; i < 256; i++) {
1853 		if (iot[i].d.desc == NULL)
1854 			continue;
1855 		printf("id %d:\t", i);
1856 		switch (iot[i].d.desc->bDescriptorSubtype) {
1857 		case UDESCSUB_AC_INPUT:
1858 			printf("AC_INPUT type=%s\n", uaudio_get_terminal_name
1859 			       (UGETW(iot[i].d.it->wTerminalType)));
1860 			break;
1861 		case UDESCSUB_AC_OUTPUT:
1862 			printf("AC_OUTPUT type=%s ", uaudio_get_terminal_name
1863 			       (UGETW(iot[i].d.ot->wTerminalType)));
1864 			printf("src=%d\n", iot[i].d.ot->bSourceId);
1865 			break;
1866 		case UDESCSUB_AC_MIXER:
1867 			printf("AC_MIXER src=");
1868 			for (j = 0; j < iot[i].d.mu->bNrInPins; j++)
1869 				printf("%d ", iot[i].d.mu->baSourceId[j]);
1870 			printf("\n");
1871 			break;
1872 		case UDESCSUB_AC_SELECTOR:
1873 			printf("AC_SELECTOR src=");
1874 			for (j = 0; j < iot[i].d.su->bNrInPins; j++)
1875 				printf("%d ", iot[i].d.su->baSourceId[j]);
1876 			printf("\n");
1877 			break;
1878 		case UDESCSUB_AC_FEATURE:
1879 			printf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId);
1880 			break;
1881 		case UDESCSUB_AC_PROCESSING:
1882 			printf("AC_PROCESSING src=");
1883 			for (j = 0; j < iot[i].d.pu->bNrInPins; j++)
1884 				printf("%d ", iot[i].d.pu->baSourceId[j]);
1885 			printf("\n");
1886 			break;
1887 		case UDESCSUB_AC_EXTENSION:
1888 			printf("AC_EXTENSION src=");
1889 			for (j = 0; j < iot[i].d.eu->bNrInPins; j++)
1890 				printf("%d ", iot[i].d.eu->baSourceId[j]);
1891 			printf("\n");
1892 			break;
1893 		default:
1894 			printf("unknown audio control (subtype=%d)\n",
1895 			       iot[i].d.desc->bDescriptorSubtype);
1896 		}
1897 		for (j = 0; j < iot[i].inputs_size; j++) {
1898 			int k;
1899 			printf("\tinput%d: ", j);
1900 			tml = iot[i].inputs[j];
1901 			if (tml == NULL) {
1902 				printf("NULL\n");
1903 				continue;
1904 			}
1905 			for (k = 0; k < tml->size; k++)
1906 				printf("%s ", uaudio_get_terminal_name
1907 				       (tml->terminals[k]));
1908 			printf("\n");
1909 		}
1910 		printf("\toutput: ");
1911 		tml = iot[i].output;
1912 		for (j = 0; j < tml->size; j++)
1913 			printf("%s ", uaudio_get_terminal_name(tml->terminals[j]));
1914 		printf("\n");
1915 	}
1916 #endif
1917 
1918 	for (i = 0; i < ndps; i++) {
1919 		dp = iot[i].d.desc;
1920 		if (dp == NULL)
1921 			continue;
1922 		DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n",
1923 			 i, dp->bDescriptorSubtype));
1924 		switch (dp->bDescriptorSubtype) {
1925 		case UDESCSUB_AC_HEADER:
1926 			printf("uaudio_identify_ac: unexpected AC header\n");
1927 			break;
1928 		case UDESCSUB_AC_INPUT:
1929 			uaudio_add_input(sc, iot, i);
1930 			break;
1931 		case UDESCSUB_AC_OUTPUT:
1932 			uaudio_add_output(sc, iot, i);
1933 			break;
1934 		case UDESCSUB_AC_MIXER:
1935 			uaudio_add_mixer(sc, iot, i);
1936 			break;
1937 		case UDESCSUB_AC_SELECTOR:
1938 			uaudio_add_selector(sc, iot, i);
1939 			break;
1940 		case UDESCSUB_AC_FEATURE:
1941 			uaudio_add_feature(sc, iot, i);
1942 			break;
1943 		case UDESCSUB_AC_PROCESSING:
1944 			uaudio_add_processing(sc, iot, i);
1945 			break;
1946 		case UDESCSUB_AC_EXTENSION:
1947 			uaudio_add_extension(sc, iot, i);
1948 			break;
1949 		default:
1950 			printf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n",
1951 			       dp->bDescriptorSubtype);
1952 			break;
1953 		}
1954 	}
1955 
1956 	/* delete io_terminal */
1957 	for (i = 0; i < 256; i++) {
1958 		if (iot[i].d.desc == NULL)
1959 			continue;
1960 		if (iot[i].inputs != NULL) {
1961 			for (j = 0; j < iot[i].inputs_size; j++) {
1962 				if (iot[i].inputs[j] != NULL)
1963 					free(iot[i].inputs[j], M_TEMP);
1964 			}
1965 			free(iot[i].inputs, M_TEMP);
1966 		}
1967 		if (iot[i].output != NULL)
1968 			free(iot[i].output, M_TEMP);
1969 		iot[i].d.desc = NULL;
1970 	}
1971 	free(iot, M_TEMP);
1972 
1973 	return (USBD_NORMAL_COMPLETION);
1974 }
1975 
1976 int
1977 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
1978 {
1979 	struct uaudio_softc *sc = addr;
1980 	struct mixerctl *mc;
1981 	int n, nctls, i;
1982 
1983 	DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index));
1984 	if (sc->sc_dying)
1985 		return (EIO);
1986 
1987 	n = mi->index;
1988 	nctls = sc->sc_nctls;
1989 
1990 	switch (n) {
1991 	case UAC_OUTPUT:
1992 		mi->type = AUDIO_MIXER_CLASS;
1993 		mi->mixer_class = UAC_OUTPUT;
1994 		mi->next = mi->prev = AUDIO_MIXER_LAST;
1995 		strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name));
1996 		return (0);
1997 	case UAC_INPUT:
1998 		mi->type = AUDIO_MIXER_CLASS;
1999 		mi->mixer_class = UAC_INPUT;
2000 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2001 		strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name));
2002 		return (0);
2003 	case UAC_EQUAL:
2004 		mi->type = AUDIO_MIXER_CLASS;
2005 		mi->mixer_class = UAC_EQUAL;
2006 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2007 		strlcpy(mi->label.name, AudioCequalization,
2008 		    sizeof(mi->label.name));
2009 		return (0);
2010 	case UAC_RECORD:
2011 		mi->type = AUDIO_MIXER_CLASS;
2012 		mi->mixer_class = UAC_RECORD;
2013 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2014 		strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name));
2015 		return 0;
2016 	default:
2017 		break;
2018 	}
2019 
2020 	n -= UAC_NCLASSES;
2021 	if (n < 0 || n >= nctls)
2022 		return (ENXIO);
2023 
2024 	mc = &sc->sc_ctls[n];
2025 	strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name));
2026 	mi->mixer_class = mc->class;
2027 	mi->next = mi->prev = AUDIO_MIXER_LAST;	/* XXX */
2028 	switch (mc->type) {
2029 	case MIX_ON_OFF:
2030 		mi->type = AUDIO_MIXER_ENUM;
2031 		mi->un.e.num_mem = 2;
2032 		strlcpy(mi->un.e.member[0].label.name, AudioNoff,
2033 		    sizeof(mi->un.e.member[0].label.name));
2034 		mi->un.e.member[0].ord = 0;
2035 		strlcpy(mi->un.e.member[1].label.name, AudioNon,
2036 		    sizeof(mi->un.e.member[1].label.name));
2037 		mi->un.e.member[1].ord = 1;
2038 		break;
2039 	case MIX_SELECTOR:
2040 		mi->type = AUDIO_MIXER_ENUM;
2041 		mi->un.e.num_mem = mc->maxval - mc->minval + 1;
2042 		for (i = 0; i <= mc->maxval - mc->minval; i++) {
2043 			snprintf(mi->un.e.member[i].label.name,
2044 				 sizeof(mi->un.e.member[i].label.name),
2045 				 "%d", i + mc->minval);
2046 			mi->un.e.member[i].ord = i + mc->minval;
2047 		}
2048 		break;
2049 	default:
2050 		mi->type = AUDIO_MIXER_VALUE;
2051 		strlcpy(mi->un.v.units.name, mc->ctlunit,
2052 		    sizeof(mi->un.v.units.name));
2053 		mi->un.v.num_channels = mc->nchan;
2054 		mi->un.v.delta = mc->delta;
2055 		break;
2056 	}
2057 	return (0);
2058 }
2059 
2060 int
2061 uaudio_open(void *addr, int flags)
2062 {
2063 	struct uaudio_softc *sc = addr;
2064 
2065 	DPRINTF(("uaudio_open: sc=%p\n", sc));
2066 	if (sc->sc_dying)
2067 		return (EIO);
2068 
2069 	if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY))
2070 		return (ENXIO);
2071 	if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD))
2072 		return (ENXIO);
2073 
2074 	return (0);
2075 }
2076 
2077 /*
2078  * Close function is called at splaudio().
2079  */
2080 void
2081 uaudio_close(void *addr)
2082 {
2083 	struct uaudio_softc *sc = addr;
2084 
2085 	if (sc->sc_playchan.altidx != -1)
2086 		uaudio_chan_close(sc, &sc->sc_playchan);
2087 	if (sc->sc_recchan.altidx != -1)
2088 		uaudio_chan_close(sc, &sc->sc_recchan);
2089 }
2090 
2091 int
2092 uaudio_drain(void *addr)
2093 {
2094 	struct uaudio_softc *sc = addr;
2095 
2096 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
2097 
2098 	return (0);
2099 }
2100 
2101 int
2102 uaudio_halt_out_dma(void *addr)
2103 {
2104 	struct uaudio_softc *sc = addr;
2105 
2106 	DPRINTF(("uaudio_halt_out_dma: enter\n"));
2107 	if (sc->sc_playchan.pipe != NULL) {
2108 		uaudio_chan_close(sc, &sc->sc_playchan);
2109 		sc->sc_playchan.pipe = NULL;
2110 		uaudio_chan_free_buffers(sc, &sc->sc_playchan);
2111 		sc->sc_playchan.intr = NULL;
2112 	}
2113 	return (0);
2114 }
2115 
2116 int
2117 uaudio_halt_in_dma(void *addr)
2118 {
2119 	struct uaudio_softc *sc = addr;
2120 
2121 	DPRINTF(("uaudio_halt_in_dma: enter\n"));
2122 	if (sc->sc_recchan.pipe != NULL) {
2123 		uaudio_chan_close(sc, &sc->sc_recchan);
2124 		sc->sc_recchan.pipe = NULL;
2125 		uaudio_chan_free_buffers(sc, &sc->sc_recchan);
2126 		sc->sc_recchan.intr = NULL;
2127 	}
2128 	return (0);
2129 }
2130 
2131 int
2132 uaudio_getdev(void *addr, struct audio_device *retp)
2133 {
2134 	struct uaudio_softc *sc = addr;
2135 
2136 	DPRINTF(("uaudio_mixer_getdev:\n"));
2137 	if (sc->sc_dying)
2138 		return (EIO);
2139 
2140 	*retp = uaudio_device;
2141 	return (0);
2142 }
2143 
2144 /*
2145  * Make sure the block size is large enough to hold all outstanding transfers.
2146  */
2147 int
2148 uaudio_round_blocksize(void *addr, int blk)
2149 {
2150 	struct uaudio_softc *sc = addr;
2151 	int bpf;
2152 
2153 	DPRINTF(("uaudio_round_blocksize: p.bpf=%d r.bpf=%d\n",
2154 		 sc->sc_playchan.bytes_per_frame,
2155 		 sc->sc_recchan.bytes_per_frame));
2156 	if (sc->sc_playchan.bytes_per_frame > sc->sc_recchan.bytes_per_frame) {
2157 		bpf = sc->sc_playchan.bytes_per_frame
2158 		    + sc->sc_playchan.sample_size;
2159 	} else {
2160 		bpf = sc->sc_recchan.bytes_per_frame
2161 		    + sc->sc_recchan.sample_size;
2162 	}
2163 	/* XXX */
2164 	bpf *= UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
2165 
2166 	bpf = (bpf + 15) &~ 15;
2167 
2168 	if (blk < bpf)
2169 		blk = bpf;
2170 
2171 #ifdef DIAGNOSTIC
2172 	if (blk <= 0) {
2173 		printf("uaudio_round_blocksize: blk=%d\n", blk);
2174 		blk = 512;
2175 	}
2176 #endif
2177 
2178 	DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk));
2179 	return (blk);
2180 }
2181 
2182 int
2183 uaudio_get_props(void *addr)
2184 {
2185 	return (AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT);
2186 
2187 }
2188 
2189 int
2190 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
2191 	   int wIndex, int len)
2192 {
2193 	usb_device_request_t req;
2194 	u_int8_t data[4];
2195 	usbd_status err;
2196 	int val;
2197 
2198 	if (wValue == -1)
2199 		return (0);
2200 
2201 	req.bmRequestType = type;
2202 	req.bRequest = which;
2203 	USETW(req.wValue, wValue);
2204 	USETW(req.wIndex, wIndex);
2205 	USETW(req.wLength, len);
2206 	DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
2207 		    "wIndex=0x%04x len=%d\n",
2208 		    type, which, wValue, wIndex, len));
2209 	err = usbd_do_request(sc->sc_udev, &req, data);
2210 	if (err) {
2211 		DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
2212 		return (-1);
2213 	}
2214 	switch (len) {
2215 	case 1:
2216 		val = data[0];
2217 		break;
2218 	case 2:
2219 		val = data[0] | (data[1] << 8);
2220 		break;
2221 	default:
2222 		DPRINTF(("uaudio_get: bad length=%d\n", len));
2223 		return (-1);
2224 	}
2225 	DPRINTFN(2,("uaudio_get: val=%d\n", val));
2226 	return (val);
2227 }
2228 
2229 void
2230 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
2231 	   int wIndex, int len, int val)
2232 {
2233 	usb_device_request_t req;
2234 	u_int8_t data[4];
2235 	usbd_status err;
2236 
2237 	if (wValue == -1)
2238 		return;
2239 
2240 	req.bmRequestType = type;
2241 	req.bRequest = which;
2242 	USETW(req.wValue, wValue);
2243 	USETW(req.wIndex, wIndex);
2244 	USETW(req.wLength, len);
2245 	switch (len) {
2246 	case 1:
2247 		data[0] = val;
2248 		break;
2249 	case 2:
2250 		data[0] = val;
2251 		data[1] = val >> 8;
2252 		break;
2253 	default:
2254 		return;
2255 	}
2256 	DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
2257 		    "wIndex=0x%04x len=%d, val=%d\n",
2258 		    type, which, wValue, wIndex, len, val & 0xffff));
2259 	err = usbd_do_request(sc->sc_udev, &req, data);
2260 #ifdef UAUDIO_DEBUG
2261 	if (err)
2262 		DPRINTF(("uaudio_set: err=%d\n", err));
2263 #endif
2264 }
2265 
2266 int
2267 uaudio_signext(int type, int val)
2268 {
2269 	if (!MIX_UNSIGNED(type)) {
2270 		if (MIX_SIZE(type) == 2)
2271 			val = (int16_t)val;
2272 		else
2273 			val = (int8_t)val;
2274 	}
2275 	return (val);
2276 }
2277 
2278 int
2279 uaudio_unsignext(int type, int val)
2280 {
2281 	if (!MIX_UNSIGNED(type)) {
2282 		if (MIX_SIZE(type) == 2)
2283 			val = (u_int16_t)val;
2284 		else
2285 			val = (u_int8_t)val;
2286 	}
2287 	return (val);
2288 }
2289 
2290 int
2291 uaudio_value2bsd(struct mixerctl *mc, int val)
2292 {
2293 	int range;
2294 	DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
2295 		     mc->type, val, mc->minval, mc->maxval));
2296 	if (mc->type == MIX_ON_OFF) {
2297 		val = (val != 0);
2298 	} else if (mc->type == MIX_SELECTOR) {
2299 		if (val < mc->minval || val > mc->maxval)
2300 			val = mc->minval;
2301 	} else {
2302 		range = mc->maxval - mc->minval;
2303 		if (range == 0)
2304 			val = 0;
2305 		else
2306 			val = 255 * (uaudio_signext(mc->type, val) -
2307 			    mc->minval) / range;
2308 	}
2309 	DPRINTFN(5, ("val'=%d\n", val));
2310 	return (val);
2311 }
2312 
2313 int
2314 uaudio_bsd2value(struct mixerctl *mc, int val)
2315 {
2316 	DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
2317 		    mc->type, val, mc->minval, mc->maxval));
2318 	if (mc->type == MIX_ON_OFF) {
2319 		val = (val != 0);
2320 	} else if (mc->type == MIX_SELECTOR) {
2321 		if (val < mc->minval || val > mc->maxval)
2322 			val = mc->minval;
2323 	} else
2324 		val = uaudio_unsignext(mc->type,
2325 		    val * (mc->maxval - mc->minval) / 255 + mc->minval);
2326 	DPRINTFN(5, ("val'=%d\n", val));
2327 	return (val);
2328 }
2329 
2330 int
2331 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2332 	       int chan)
2333 {
2334 	int val;
2335 
2336 	DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan));
2337 	val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
2338 			 mc->wIndex, MIX_SIZE(mc->type));
2339 	return (uaudio_value2bsd(mc, val));
2340 }
2341 
2342 void
2343 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2344 	       int chan, int val)
2345 {
2346 	val = uaudio_bsd2value(mc, val);
2347 	uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
2348 		   mc->wIndex, MIX_SIZE(mc->type), val);
2349 }
2350 
2351 int
2352 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
2353 {
2354 	struct uaudio_softc *sc = addr;
2355 	struct mixerctl *mc;
2356 	int i, n, vals[MIX_MAX_CHAN], val;
2357 
2358 	DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev));
2359 
2360 	if (sc->sc_dying)
2361 		return (EIO);
2362 
2363 	n = cp->dev - UAC_NCLASSES;
2364 	if (n < 0 || n >= sc->sc_nctls)
2365 		return (ENXIO);
2366 	mc = &sc->sc_ctls[n];
2367 
2368 	if (mc->type == MIX_ON_OFF) {
2369 		if (cp->type != AUDIO_MIXER_ENUM)
2370 			return (EINVAL);
2371 		cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2372 	} else if (mc->type == MIX_SELECTOR) {
2373 		if (cp->type != AUDIO_MIXER_ENUM)
2374 			return (EINVAL);
2375 		cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2376 	} else {
2377 		if (cp->type != AUDIO_MIXER_VALUE)
2378 			return (EINVAL);
2379 		if (cp->un.value.num_channels != 1 &&
2380 		    cp->un.value.num_channels != mc->nchan)
2381 			return (EINVAL);
2382 		for (i = 0; i < mc->nchan; i++)
2383 			vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
2384 		if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
2385 			for (val = 0, i = 0; i < mc->nchan; i++)
2386 				val += vals[i];
2387 			vals[0] = val / mc->nchan;
2388 		}
2389 		for (i = 0; i < cp->un.value.num_channels; i++)
2390 			cp->un.value.level[i] = vals[i];
2391 	}
2392 
2393 	return (0);
2394 }
2395 
2396 int
2397 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
2398 {
2399 	struct uaudio_softc *sc = addr;
2400 	struct mixerctl *mc;
2401 	int i, n, vals[MIX_MAX_CHAN];
2402 
2403 	DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev));
2404 	if (sc->sc_dying)
2405 		return (EIO);
2406 
2407 	n = cp->dev - UAC_NCLASSES;
2408 	if (n < 0 || n >= sc->sc_nctls)
2409 		return (ENXIO);
2410 	mc = &sc->sc_ctls[n];
2411 
2412 	if (mc->type == MIX_ON_OFF) {
2413 		if (cp->type != AUDIO_MIXER_ENUM)
2414 			return (EINVAL);
2415 		uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2416 	} else if (mc->type == MIX_SELECTOR) {
2417 		if (cp->type != AUDIO_MIXER_ENUM)
2418 			return (EINVAL);
2419 		uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2420 	} else {
2421 		if (cp->type != AUDIO_MIXER_VALUE)
2422 			return (EINVAL);
2423 		if (cp->un.value.num_channels == 1)
2424 			for (i = 0; i < mc->nchan; i++)
2425 				vals[i] = cp->un.value.level[0];
2426 		else if (cp->un.value.num_channels == mc->nchan)
2427 			for (i = 0; i < mc->nchan; i++)
2428 				vals[i] = cp->un.value.level[i];
2429 		else
2430 			return (EINVAL);
2431 		for (i = 0; i < mc->nchan; i++)
2432 			uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
2433 	}
2434 	return (0);
2435 }
2436 
2437 int
2438 uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
2439 		     void (*intr)(void *), void *arg,
2440 		     struct audio_params *param)
2441 {
2442 	struct uaudio_softc *sc = addr;
2443 	struct chan *ch = &sc->sc_recchan;
2444 	usbd_status err;
2445 	int i, s;
2446 
2447 	if (sc->sc_dying)
2448 		return (EIO);
2449 
2450 	DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
2451 		    "blksize=%d\n", sc, start, end, blksize));
2452 
2453 	uaudio_chan_set_param(ch, start, end, blksize);
2454 	DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
2455 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2456 		    ch->fraction));
2457 
2458 	err = uaudio_chan_alloc_buffers(sc, ch);
2459 	if (err)
2460 		return (EIO);
2461 
2462 	err = uaudio_chan_open(sc, ch);
2463 	if (err) {
2464 		uaudio_chan_free_buffers(sc, ch);
2465 		return (EIO);
2466 	}
2467 
2468 	ch->intr = intr;
2469 	ch->arg = arg;
2470 
2471 	s = splusb();
2472 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
2473 		uaudio_chan_rtransfer(ch);
2474 	splx(s);
2475 
2476 	return (0);
2477 }
2478 
2479 int
2480 uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
2481 		      void (*intr)(void *), void *arg,
2482 		      struct audio_params *param)
2483 {
2484 	struct uaudio_softc *sc = addr;
2485 	struct chan *ch = &sc->sc_playchan;
2486 	usbd_status err;
2487 	int i, s;
2488 
2489 	if (sc->sc_dying)
2490 		return (EIO);
2491 
2492 	DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
2493 		    "blksize=%d\n", sc, start, end, blksize));
2494 
2495 	uaudio_chan_set_param(ch, start, end, blksize);
2496 	DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
2497 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2498 		    ch->fraction));
2499 
2500 	err = uaudio_chan_alloc_buffers(sc, ch);
2501 	if (err)
2502 		return (EIO);
2503 
2504 	err = uaudio_chan_open(sc, ch);
2505 	if (err) {
2506 		uaudio_chan_free_buffers(sc, ch);
2507 		return (EIO);
2508 	}
2509 
2510 	ch->intr = intr;
2511 	ch->arg = arg;
2512 
2513 	s = splusb();
2514 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
2515 		uaudio_chan_ptransfer(ch);
2516 	splx(s);
2517 
2518 	return (0);
2519 }
2520 
2521 /* Set up a pipe for a channel. */
2522 usbd_status
2523 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
2524 {
2525 	struct as_info *as = &sc->sc_alts[ch->altidx];
2526 	int endpt = as->edesc->bEndpointAddress;
2527 	usbd_status err;
2528 
2529 	DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n",
2530 		 endpt, ch->sample_rate, as->alt));
2531 
2532 	/* Set alternate interface corresponding to the mode. */
2533 	err = usbd_set_interface(as->ifaceh, as->alt);
2534 	if (err)
2535 		return (err);
2536 
2537 	/*
2538 	 * If just one sampling rate is supported,
2539 	 * no need to call uaudio_set_speed().
2540 	 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request.
2541 	 */
2542 	if (as->asf1desc->bSamFreqType != 1) {
2543 		err = uaudio_set_speed(sc, endpt, ch->sample_rate);
2544 		if (err)
2545 			DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
2546 				 usbd_errstr(err)));
2547 	}
2548 
2549 	ch->pipe = 0;
2550 	ch->sync_pipe = 0;
2551 	DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt));
2552 	err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
2553 	if (err)
2554 		return err;
2555 	if (as->edesc1 != NULL) {
2556 		endpt = as->edesc1->bEndpointAddress;
2557 		DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt));
2558 		err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe);
2559 	}
2560 	return err;
2561 }
2562 
2563 void
2564 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
2565 {
2566 	struct as_info *as = &sc->sc_alts[ch->altidx];
2567 
2568 	as->sc_busy = 0;
2569 	if (sc->sc_nullalt >= 0) {
2570 		DPRINTF(("uaudio_chan_close: set null alt=%d\n",
2571 			 sc->sc_nullalt));
2572 		usbd_set_interface(as->ifaceh, sc->sc_nullalt);
2573 	}
2574 	if (ch->pipe) {
2575 		usbd_abort_pipe(ch->pipe);
2576 		usbd_close_pipe(ch->pipe);
2577 	}
2578 	if (ch->sync_pipe) {
2579 		usbd_abort_pipe(ch->sync_pipe);
2580 		usbd_close_pipe(ch->sync_pipe);
2581 	}
2582 }
2583 
2584 usbd_status
2585 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
2586 {
2587 	usbd_xfer_handle xfer;
2588 	void *buf;
2589 	int i, size;
2590 
2591 	size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
2592 	for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
2593 		xfer = usbd_alloc_xfer(sc->sc_udev);
2594 		if (xfer == 0)
2595 			goto bad;
2596 		ch->chanbufs[i].xfer = xfer;
2597 		buf = usbd_alloc_buffer(xfer, size);
2598 		if (buf == 0) {
2599 			i++;
2600 			goto bad;
2601 		}
2602 		ch->chanbufs[i].buffer = buf;
2603 		ch->chanbufs[i].chan = ch;
2604 	}
2605 
2606 	return (USBD_NORMAL_COMPLETION);
2607 
2608 bad:
2609 	while (--i >= 0)
2610 		/* implicit buffer free */
2611 		usbd_free_xfer(ch->chanbufs[i].xfer);
2612 	return (USBD_NOMEM);
2613 }
2614 
2615 void
2616 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
2617 {
2618 	int i;
2619 
2620 	for (i = 0; i < UAUDIO_NCHANBUFS; i++)
2621 		usbd_free_xfer(ch->chanbufs[i].xfer);
2622 }
2623 
2624 /* Called at splusb() */
2625 void
2626 uaudio_chan_ptransfer(struct chan *ch)
2627 {
2628 	struct chanbuf *cb;
2629 	int i, n, size, residue, total;
2630 
2631 	if (ch->sc->sc_dying)
2632 		return;
2633 
2634 	/* Pick the next channel buffer. */
2635 	cb = &ch->chanbufs[ch->curchanbuf];
2636 	if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2637 		ch->curchanbuf = 0;
2638 
2639 	/* Compute the size of each frame in the next transfer. */
2640 	residue = ch->residue;
2641 	total = 0;
2642 	for (i = 0; i < UAUDIO_NFRAMES; i++) {
2643 		size = ch->bytes_per_frame;
2644 		residue += ch->fraction;
2645 		if (residue >= USB_FRAMES_PER_SECOND) {
2646 			if ((ch->sc->sc_altflags & UA_NOFRAC) == 0)
2647 				size += ch->sample_size;
2648 			residue -= USB_FRAMES_PER_SECOND;
2649 		}
2650 		cb->sizes[i] = size;
2651 		total += size;
2652 	}
2653 	ch->residue = residue;
2654 	cb->size = total;
2655 
2656 	/*
2657 	 * Transfer data from upper layer buffer to channel buffer, taking
2658 	 * care of wrapping the upper layer buffer.
2659 	 */
2660 	n = min(total, ch->end - ch->cur);
2661 	memcpy(cb->buffer, ch->cur, n);
2662 	ch->cur += n;
2663 	if (ch->cur >= ch->end)
2664 		ch->cur = ch->start;
2665 	if (total > n) {
2666 		total -= n;
2667 		memcpy(cb->buffer + n, ch->cur, total);
2668 		ch->cur += total;
2669 	}
2670 
2671 #ifdef UAUDIO_DEBUG
2672 	if (uaudiodebug > 8) {
2673 		DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
2674 			 cb->buffer, ch->residue));
2675 		for (i = 0; i < UAUDIO_NFRAMES; i++) {
2676 			DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
2677 		}
2678 	}
2679 #endif
2680 
2681 	DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
2682 	/* Fill the request */
2683 	usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
2684 			     UAUDIO_NFRAMES, USBD_NO_COPY,
2685 			     uaudio_chan_pintr);
2686 
2687 	(void)usbd_transfer(cb->xfer);
2688 }
2689 
2690 void
2691 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
2692 		  usbd_status status)
2693 {
2694 	struct chanbuf *cb = priv;
2695 	struct chan *ch = cb->chan;
2696 	u_int32_t count;
2697 	int s;
2698 
2699 	/* Return if we are aborting. */
2700 	if (status == USBD_CANCELLED)
2701 		return;
2702 
2703 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2704 	DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
2705 		    count, ch->transferred));
2706 #ifdef DIAGNOSTIC
2707 	if (count != cb->size) {
2708 		printf("uaudio_chan_pintr: count(%d) != size(%d)\n",
2709 		       count, cb->size);
2710 	}
2711 #endif
2712 
2713 	ch->transferred += cb->size;
2714 	s = splaudio();
2715 	/* Call back to upper layer */
2716 	while (ch->transferred >= ch->blksize) {
2717 		ch->transferred -= ch->blksize;
2718 		DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n",
2719 			    ch->intr, ch->arg));
2720 		ch->intr(ch->arg);
2721 	}
2722 	splx(s);
2723 
2724 	/* start next transfer */
2725 	uaudio_chan_ptransfer(ch);
2726 }
2727 
2728 /* Called at splusb() */
2729 void
2730 uaudio_chan_rtransfer(struct chan *ch)
2731 {
2732 	struct chanbuf *cb;
2733 	int i, size, residue, total;
2734 
2735 	if (ch->sc->sc_dying)
2736 		return;
2737 
2738 	/* Pick the next channel buffer. */
2739 	cb = &ch->chanbufs[ch->curchanbuf];
2740 	if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2741 		ch->curchanbuf = 0;
2742 
2743 	/* Compute the size of each frame in the next transfer. */
2744 	residue = ch->residue;
2745 	total = 0;
2746 	for (i = 0; i < UAUDIO_NFRAMES; i++) {
2747 		size = ch->bytes_per_frame;
2748 		cb->sizes[i] = size;
2749 		cb->offsets[i] = total;
2750 		total += size;
2751 	}
2752 	ch->residue = residue;
2753 	cb->size = total;
2754 
2755 #ifdef UAUDIO_DEBUG
2756 	if (uaudiodebug > 8) {
2757 		DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
2758 			 cb->buffer, ch->residue));
2759 		for (i = 0; i < UAUDIO_NFRAMES; i++) {
2760 			DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
2761 		}
2762 	}
2763 #endif
2764 
2765 	DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
2766 	/* Fill the request */
2767 	usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
2768 			     UAUDIO_NFRAMES, USBD_NO_COPY,
2769 			     uaudio_chan_rintr);
2770 
2771 	(void)usbd_transfer(cb->xfer);
2772 }
2773 
2774 void
2775 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
2776 		  usbd_status status)
2777 {
2778 	struct chanbuf *cb = priv;
2779 	struct chan *ch = cb->chan;
2780 	u_int32_t count;
2781 	int s, i, n, frsize;
2782 
2783 	/* Return if we are aborting. */
2784 	if (status == USBD_CANCELLED)
2785 		return;
2786 
2787 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2788 	DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
2789 		    count, ch->transferred));
2790 
2791 	/* count < cb->size is normal for asynchronous source */
2792 #ifdef DIAGNOSTIC
2793 	if (count > cb->size) {
2794 		printf("uaudio_chan_rintr: count(%d) > size(%d)\n",
2795 		       count, cb->size);
2796 	}
2797 #endif
2798 
2799 	/*
2800 	 * Transfer data from channel buffer to upper layer buffer, taking
2801 	 * care of wrapping the upper layer buffer.
2802 	 */
2803 	for(i = 0; i < UAUDIO_NFRAMES; i++) {
2804 		frsize = cb->sizes[i];
2805 		n = min(frsize, ch->end - ch->cur);
2806 		memcpy(ch->cur, cb->buffer + cb->offsets[i], n);
2807 		ch->cur += n;
2808 		if (ch->cur >= ch->end)
2809 			ch->cur = ch->start;
2810 		if (frsize > n) {
2811 			memcpy(ch->cur, cb->buffer + cb->offsets[i] + n,
2812 			    frsize - n);
2813 			ch->cur += frsize - n;
2814 		}
2815 	}
2816 
2817 	/* Call back to upper layer */
2818 	ch->transferred += count;
2819 	s = splaudio();
2820 	while (ch->transferred >= ch->blksize) {
2821 		ch->transferred -= ch->blksize;
2822 		DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n",
2823 			    ch->intr, ch->arg));
2824 		ch->intr(ch->arg);
2825 	}
2826 	splx(s);
2827 
2828 	/* start next transfer */
2829 	uaudio_chan_rtransfer(ch);
2830 }
2831 
2832 void
2833 uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param,
2834     int maxpktsize)
2835 {
2836 	int samples_per_frame, sample_size;
2837 
2838 	ch->altidx = altidx;
2839 	sample_size = param->precision * param->factor * param->channels / 8;
2840 	samples_per_frame = param->sample_rate / USB_FRAMES_PER_SECOND;
2841 	ch->sample_size = sample_size;
2842 	ch->sample_rate = param->sample_rate;
2843 	if (maxpktsize == 0) {
2844 		ch->fraction = param->sample_rate % USB_FRAMES_PER_SECOND;
2845 		ch->bytes_per_frame = samples_per_frame * sample_size;
2846 	} else {
2847 		ch->fraction = 0;
2848 		ch->bytes_per_frame = maxpktsize;
2849 	}
2850 	ch->residue = 0;
2851 }
2852 
2853 void
2854 uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize)
2855 {
2856 	ch->start = start;
2857 	ch->end = end;
2858 	ch->cur = start;
2859 	ch->blksize = blksize;
2860 	ch->transferred = 0;
2861 
2862 	ch->curchanbuf = 0;
2863 }
2864 
2865 void
2866 uaudio_get_minmax_rates(int nalts, const struct as_info *alts,
2867 			const struct audio_params *p, int mode,
2868 			int enc, int pre,
2869 			u_long *min, u_long *max)
2870 {
2871 	const struct usb_audio_streaming_type1_descriptor *a1d;
2872 	int i, j;
2873 
2874 	*min = ULONG_MAX;
2875 	*max = 0;
2876 	for (i = 0; i < nalts; i++) {
2877 		a1d = alts[i].asf1desc;
2878 		if (alts[i].sc_busy)
2879 			continue;
2880 		if (p->channels != a1d->bNrChannels)
2881 			continue;
2882 		if (pre != a1d->bBitResolution)
2883 			continue;
2884 		if (enc != alts[i].encoding)
2885 			continue;
2886 		if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
2887 			continue;
2888 		if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2889 			DPRINTFN(2,("uaudio_get_minmax_rates: cont %d-%d\n",
2890 				    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
2891 			if (UA_SAMP_LO(a1d) < *min)
2892 				*min = UA_SAMP_LO(a1d);
2893 			if (UA_SAMP_HI(a1d) > *max)
2894 				*max = UA_SAMP_HI(a1d);
2895 		} else {
2896 			for (j = 0; j < a1d->bSamFreqType; j++) {
2897 				DPRINTFN(2,("uaudio_get_minmax_rates: disc #%d: %d\n",
2898 					    j, UA_GETSAMP(a1d, j)));
2899 				if (UA_GETSAMP(a1d, j) < *min)
2900 					*min = UA_GETSAMP(a1d, j);
2901 				if (UA_GETSAMP(a1d, j) > *max)
2902 					*max = UA_GETSAMP(a1d, j);
2903 			}
2904 		}
2905 	}
2906 }
2907 
2908 int
2909 uaudio_match_alt_sub(int nalts, const struct as_info *alts,
2910 		     const struct audio_params *p, int mode,
2911 		     int enc, int pre, u_long rate)
2912 {
2913 	const struct usb_audio_streaming_type1_descriptor *a1d;
2914 	int i, j;
2915 
2916 	DPRINTF(("uaudio_match_alt_sub: search for %luHz %dch\n",
2917 		 rate, p->channels));
2918 	for (i = 0; i < nalts; i++) {
2919 		a1d = alts[i].asf1desc;
2920 		if (alts[i].sc_busy)
2921 			continue;
2922 		if (p->channels != a1d->bNrChannels)
2923 			continue;
2924 		if (pre != a1d->bBitResolution)
2925 			continue;
2926 		if (enc != alts[i].encoding)
2927 			continue;
2928 		if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
2929 			continue;
2930 		if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2931 			DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n",
2932 				    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
2933 			if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d))
2934 				return i;
2935 		} else {
2936 			for (j = 0; j < a1d->bSamFreqType; j++) {
2937 				DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n",
2938 					    j, UA_GETSAMP(a1d, j)));
2939 				/* XXX allow for some slack */
2940 				if (UA_GETSAMP(a1d, j) == rate)
2941 					return i;
2942 			}
2943 		}
2944 	}
2945 	return -1;
2946 }
2947 
2948 int
2949 uaudio_match_alt_chan(int nalts, const struct as_info *alts,
2950 		      struct audio_params *p, int mode, int enc, int pre)
2951 {
2952 	int i, n;
2953 	u_long min, max;
2954 	u_long rate;
2955 
2956 	/* Exact match */
2957 	DPRINTF(("uaudio_match_alt_chan: examine %ldHz %dch %dbit.\n",
2958 		 p->sample_rate, p->channels, pre));
2959 	i = uaudio_match_alt_sub(nalts, alts, p, mode, enc, pre, p->sample_rate);
2960 	if (i >= 0)
2961 		return i;
2962 
2963 	uaudio_get_minmax_rates(nalts, alts, p, mode, enc, pre, &min, &max);
2964 	DPRINTF(("uaudio_match_alt_chan: min=%lu max=%lu\n", min, max));
2965 	if (max <= 0)
2966 		return -1;
2967 	/* Search for biggers */
2968 	n = 2;
2969 	while ((rate = p->sample_rate * n++) <= max) {
2970 		i = uaudio_match_alt_sub(nalts, alts, p, mode, enc, pre, rate);
2971 		if (i >= 0) {
2972 			p->sample_rate = rate;
2973 			return i;
2974 		}
2975 	}
2976 	if (p->sample_rate >= min) {
2977 		i = uaudio_match_alt_sub(nalts, alts, p, mode, enc, pre, max);
2978 		if (i >= 0) {
2979 			p->sample_rate = max;
2980 			return i;
2981 		}
2982 	} else {
2983 		i = uaudio_match_alt_sub(nalts, alts, p, mode, enc, pre, min);
2984 		if (i >= 0) {
2985 			p->sample_rate = min;
2986 			return i;
2987 		}
2988 	}
2989 	return -1;
2990 }
2991 
2992 int
2993 uaudio_match_alt(int nalts, const struct as_info *alts,
2994 		 struct audio_params *p, int mode, int enc, int pre)
2995 {
2996 	int i, n;
2997 
2998 	mode = mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN;
2999 	i = uaudio_match_alt_chan(nalts, alts, p, mode, enc, pre);
3000 	if (i >= 0)
3001 		return i;
3002 
3003 	for (n = p->channels + 1; n <= AUDIO_MAX_CHANNELS; n++) {
3004 		p->channels = n;
3005 		i = uaudio_match_alt_chan(nalts, alts, p, mode, enc, pre);
3006 		if (i >= 0)
3007 			return i;
3008 	}
3009 
3010 	if (p->channels != 2)
3011 		return -1;
3012 	p->channels = 1;
3013 	return uaudio_match_alt_chan(nalts, alts, p, mode, enc, pre);
3014 }
3015 
3016 int
3017 uaudio_set_params(void *addr, int setmode, int usemode,
3018 		  struct audio_params *play, struct audio_params *rec)
3019 {
3020 	struct uaudio_softc *sc = addr;
3021 	int flags = sc->sc_altflags;
3022 	int factor;
3023 	int enc, pre, i;
3024 	int paltidx=-1, raltidx=-1;
3025 	void (*swcode)(void *, u_char *buf, int cnt);
3026 	struct audio_params *p;
3027 	int mode;
3028 
3029 	if (sc->sc_dying)
3030 		return (EIO);
3031 
3032 	if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) ||
3033 	    ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL))
3034 		return (EBUSY);
3035 
3036 	if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
3037 		sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0;
3038 	if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
3039 		sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0;
3040 
3041 	/* Some uaudio devices are unidirectional.  Don't try to find a
3042 	   matching mode for the unsupported direction. */
3043 	setmode &= sc->sc_mode;
3044 
3045 	for (mode = AUMODE_RECORD; mode != -1;
3046 	     mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
3047 		if ((setmode & mode) == 0)
3048 			continue;
3049 
3050 		p = (mode == AUMODE_PLAY) ? play : rec;
3051 
3052 		factor = 1;
3053 		swcode = 0;
3054 		enc = p->encoding;
3055 		pre = p->precision;
3056 		switch (enc) {
3057 		case AUDIO_ENCODING_SLINEAR_BE:
3058 			/* FALLTHROUGH */
3059 		case AUDIO_ENCODING_SLINEAR_LE:
3060 			if (enc == AUDIO_ENCODING_SLINEAR_BE
3061 			    && pre == 16 && (flags & HAS_16)) {
3062 				swcode = swap_bytes;
3063 				enc = AUDIO_ENCODING_SLINEAR_LE;
3064 			} else if (pre == 8) {
3065 				if (flags & HAS_8) {
3066 					/* No conversion */
3067 				} else if (flags & HAS_8U) {
3068 					swcode = change_sign8;
3069 					enc = AUDIO_ENCODING_ULINEAR_LE;
3070 				} else if (flags & HAS_16) {
3071 					factor = 2;
3072 					pre = 16;
3073 					if (mode == AUMODE_PLAY)
3074 						swcode = linear8_to_linear16_le;
3075 					else
3076 						swcode = linear16_to_linear8_le;
3077 				}
3078 			}
3079 			break;
3080 		case AUDIO_ENCODING_ULINEAR_BE:
3081 			/* FALLTHROUGH */
3082 		case AUDIO_ENCODING_ULINEAR_LE:
3083 			if (pre == 16) {
3084 				if (enc == AUDIO_ENCODING_ULINEAR_LE)
3085 					swcode = change_sign16_le;
3086 				else if (mode == AUMODE_PLAY)
3087 					swcode = swap_bytes_change_sign16_le;
3088 				else
3089 					swcode = change_sign16_swap_bytes_le;
3090 				enc = AUDIO_ENCODING_SLINEAR_LE;
3091 			} else if (pre == 8) {
3092 				if (flags & HAS_8U) {
3093 					/* No conversion */
3094 				} else if (flags & HAS_8) {
3095 					swcode = change_sign8;
3096 					enc = AUDIO_ENCODING_SLINEAR_LE;
3097 				} else if (flags & HAS_16) {
3098 					factor = 2;
3099 					pre = 16;
3100 					enc = AUDIO_ENCODING_SLINEAR_LE;
3101 					if (mode == AUMODE_PLAY)
3102 						swcode = ulinear8_to_linear16_le;
3103 					else
3104 						swcode = linear16_to_ulinear8_le;
3105 				}
3106 			}
3107 			break;
3108 		case AUDIO_ENCODING_ULAW:
3109 			if (flags & HAS_MULAW)
3110 				break;
3111 			if (flags & HAS_16) {
3112 				if (mode == AUMODE_PLAY)
3113 					swcode = mulaw_to_slinear16_le;
3114 				else
3115 					swcode = slinear16_to_mulaw_le;
3116 				factor = 2;
3117 				enc = AUDIO_ENCODING_SLINEAR_LE;
3118 				pre = 16;
3119 			} else if (flags & HAS_8U) {
3120 				if (mode == AUMODE_PLAY)
3121 					swcode = mulaw_to_ulinear8;
3122 				else
3123 					swcode = ulinear8_to_mulaw;
3124 				enc = AUDIO_ENCODING_ULINEAR_LE;
3125 			} else if (flags & HAS_8) {
3126 				if (mode == AUMODE_PLAY)
3127 					swcode = mulaw_to_slinear8;
3128 				else
3129 					swcode = slinear8_to_mulaw;
3130 				enc = AUDIO_ENCODING_SLINEAR_LE;
3131 			} else
3132 				return (EINVAL);
3133 			break;
3134 		case AUDIO_ENCODING_ALAW:
3135 			if (flags & HAS_ALAW)
3136 				break;
3137 			if (flags & HAS_16) {
3138 				if (mode == AUMODE_PLAY)
3139 					swcode = alaw_to_slinear16_le;
3140 				else
3141 					swcode = slinear16_to_alaw_le;
3142 				factor = 2;
3143 				enc = AUDIO_ENCODING_SLINEAR_LE;
3144 				pre = 16;
3145 			} else if (flags & HAS_8U) {
3146 				if (mode == AUMODE_PLAY)
3147 					swcode = alaw_to_ulinear8;
3148 				else
3149 					swcode = ulinear8_to_alaw;
3150 				enc = AUDIO_ENCODING_ULINEAR_LE;
3151 			} else if (flags & HAS_8) {
3152 				if (mode == AUMODE_PLAY)
3153 					swcode = alaw_to_slinear8;
3154 				else
3155 					swcode = slinear8_to_alaw;
3156 				enc = AUDIO_ENCODING_SLINEAR_LE;
3157 			} else
3158 				return (EINVAL);
3159 			break;
3160 		default:
3161 			return (EINVAL);
3162 		}
3163 		/* XXX do some other conversions... */
3164 
3165 		DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n",
3166 			 p->channels, pre, enc, p->sample_rate));
3167 
3168 		i = uaudio_match_alt(sc->sc_nalts, sc->sc_alts, p, mode, enc, pre);
3169 		if (i < 0)
3170 			return (EINVAL);
3171 
3172 		p->sw_code = swcode;
3173 		p->factor  = factor;
3174 
3175 		if (mode == AUMODE_PLAY)
3176 			paltidx = i;
3177 		else
3178 			raltidx = i;
3179 	}
3180 
3181 	if ((setmode & AUMODE_PLAY)) {
3182 		/* XXX abort transfer if currently happening? */
3183 		uaudio_chan_init(&sc->sc_playchan, paltidx, play, 0);
3184 	}
3185 	if ((setmode & AUMODE_RECORD)) {
3186 		/* XXX abort transfer if currently happening? */
3187 		uaudio_chan_init(&sc->sc_recchan, raltidx, rec,
3188 		    UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize));
3189 	}
3190 
3191 	if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
3192 		sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1;
3193 	if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
3194 		sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1;
3195 
3196 	DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n",
3197 		 sc->sc_playchan.altidx, sc->sc_recchan.altidx,
3198 		 (sc->sc_playchan.altidx >= 0)
3199 		   ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting
3200 		   : -1,
3201 		 (sc->sc_recchan.altidx >= 0)
3202 		   ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting
3203 		   : -1));
3204 
3205 	return (0);
3206 }
3207 
3208 usbd_status
3209 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
3210 {
3211 	usb_device_request_t req;
3212 	u_int8_t data[3];
3213 
3214 	DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
3215 	req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
3216 	req.bRequest = SET_CUR;
3217 	USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
3218 	USETW(req.wIndex, endpt);
3219 	USETW(req.wLength, 3);
3220 	data[0] = speed;
3221 	data[1] = speed >> 8;
3222 	data[2] = speed >> 16;
3223 
3224 	return (usbd_do_request(sc->sc_udev, &req, data));
3225 }
3226