xref: /netbsd-src/sys/dev/usb/uaudio.c (revision de1dfb1250df962f1ff3a011772cf58e605aed11)
1 /*	$NetBSD: uaudio.c,v 1.77 2004/07/16 22:39:23 mycroft Exp $	*/
2 
3 /*
4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Lennart Augustsson (lennart@augustsson.net) at
9  * Carlstedt Research & Technology.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *        This product includes software developed by the NetBSD
22  *        Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
42  *                  http://www.usb.org/developers/devclass_docs/frmts10.pdf
43  *                  http://www.usb.org/developers/devclass_docs/termt10.pdf
44  */
45 
46 #include <sys/cdefs.h>
47 __KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.77 2004/07/16 22:39:23 mycroft Exp $");
48 
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/kernel.h>
52 #include <sys/malloc.h>
53 #include <sys/device.h>
54 #include <sys/ioctl.h>
55 #include <sys/tty.h>
56 #include <sys/file.h>
57 #include <sys/reboot.h>		/* for bootverbose */
58 #include <sys/select.h>
59 #include <sys/proc.h>
60 #include <sys/vnode.h>
61 #include <sys/device.h>
62 #include <sys/poll.h>
63 
64 #include <sys/audioio.h>
65 #include <dev/audio_if.h>
66 #include <dev/audiovar.h>
67 #include <dev/mulaw.h>
68 #include <dev/auconv.h>
69 
70 #include <dev/usb/usb.h>
71 #include <dev/usb/usbdi.h>
72 #include <dev/usb/usbdi_util.h>
73 #include <dev/usb/usb_quirks.h>
74 
75 #include <dev/usb/uaudioreg.h>
76 
77 #ifdef UAUDIO_DEBUG
78 #define DPRINTF(x)	if (uaudiodebug) logprintf x
79 #define DPRINTFN(n,x)	if (uaudiodebug>(n)) logprintf x
80 int	uaudiodebug = 0;
81 #else
82 #define DPRINTF(x)
83 #define DPRINTFN(n,x)
84 #endif
85 
86 #define UAUDIO_NCHANBUFS 6	/* number of outstanding request */
87 #define UAUDIO_NFRAMES   10	/* ms of sound in each request */
88 
89 
90 #define MIX_MAX_CHAN 8
91 struct mixerctl {
92 	u_int16_t	wValue[MIX_MAX_CHAN]; /* using nchan */
93 	u_int16_t	wIndex;
94 	u_int8_t	nchan;
95 	u_int8_t	type;
96 #define MIX_ON_OFF	1
97 #define MIX_SIGNED_16	2
98 #define MIX_UNSIGNED_16	3
99 #define MIX_SIGNED_8	4
100 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
101 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
102 	int		minval, maxval;
103 	u_int		delta;
104 	u_int		mul;
105 	u_int8_t	class;
106 	char		ctlname[MAX_AUDIO_DEV_LEN];
107 	char		*ctlunit;
108 };
109 #define MAKE(h,l) (((h) << 8) | (l))
110 
111 struct as_info {
112 	u_int8_t	alt;
113 	u_int8_t	encoding;
114 	u_int8_t	attributes; /* Copy of bmAttributes of
115 				     * usb_audio_streaming_endpoint_descriptor
116 				     */
117 	usbd_interface_handle	ifaceh;
118 	usb_interface_descriptor_t *idesc;
119 	usb_endpoint_descriptor_audio_t *edesc;
120 	struct usb_audio_streaming_type1_descriptor *asf1desc;
121 	int		sc_busy;	/* currently used */
122 };
123 
124 struct chan {
125 	void	(*intr)(void *);	/* DMA completion intr handler */
126 	void	*arg;		/* arg for intr() */
127 	usbd_pipe_handle pipe;
128 
129 	u_int	sample_size;
130 	u_int	sample_rate;
131 	u_int	bytes_per_frame;
132 	u_int	fraction;	/* fraction/1000 is the extra samples/frame */
133 	u_int	residue;	/* accumulates the fractional samples */
134 
135 	u_char	*start;		/* upper layer buffer start */
136 	u_char	*end;		/* upper layer buffer end */
137 	u_char	*cur;		/* current position in upper layer buffer */
138 	int	blksize;	/* chunk size to report up */
139 	int	transferred;	/* transferred bytes not reported up */
140 
141 	int	altidx;		/* currently used altidx */
142 
143 	int	curchanbuf;
144 	struct chanbuf {
145 		struct chan	*chan;
146 		usbd_xfer_handle xfer;
147 		u_char		*buffer;
148 		u_int16_t	sizes[UAUDIO_NFRAMES];
149 		u_int16_t	offsets[UAUDIO_NFRAMES];
150 		u_int16_t	size;
151 	} chanbufs[UAUDIO_NCHANBUFS];
152 
153 	struct uaudio_softc *sc; /* our softc */
154 };
155 
156 struct uaudio_softc {
157 	USBBASEDEVICE sc_dev;		/* base device */
158 	usbd_device_handle sc_udev;	/* USB device */
159 
160 	int	sc_ac_iface;	/* Audio Control interface */
161 	usbd_interface_handle	sc_ac_ifaceh;
162 
163 	struct chan sc_playchan;	/* play channel */
164 	struct chan sc_recchan;		/* record channel */
165 
166 	int	sc_nullalt;
167 
168 	int	sc_audio_rev;
169 
170 	struct as_info *sc_alts;
171 	int	sc_nalts;
172 
173 	int	sc_altflags;
174 #define HAS_8		0x01
175 #define HAS_16		0x02
176 #define HAS_8U		0x04
177 #define HAS_ALAW	0x08
178 #define HAS_MULAW	0x10
179 #define UA_NOFRAC	0x20		/* don't do sample rate adjustment */
180 #define HAS_24		0x40
181 
182 	int	sc_mode;		/* play/record capability */
183 
184 	struct mixerctl *sc_ctls;
185 	int	sc_nctls;
186 
187 	device_ptr_t sc_audiodev;
188 	char	sc_dying;
189 };
190 
191 #define UAC_OUTPUT 0
192 #define UAC_INPUT  1
193 #define UAC_EQUAL  2
194 #define UAC_NCLASSES 3
195 
196 Static usbd_status	uaudio_identify_ac(struct uaudio_softc *sc,
197 					   usb_config_descriptor_t *cdesc);
198 Static usbd_status	uaudio_identify_as(struct uaudio_softc *sc,
199 					   usb_config_descriptor_t *cdesc);
200 Static usbd_status	uaudio_process_as(struct uaudio_softc *sc,
201 			    char *buf, int *offsp, int size,
202 			    usb_interface_descriptor_t *id);
203 
204 Static void		uaudio_add_alt(struct uaudio_softc *sc,
205 				       struct as_info *ai);
206 Static void		uaudio_mixer_alias_ctl(struct uaudio_softc *sc,
207 			     struct mixerctl *mp, const char *ctl);
208 
209 Static usb_interface_descriptor_t *uaudio_find_iface(char *buf,
210 			    int size, int *offsp, int subtype);
211 
212 Static void		uaudio_mixer_add_ctl(struct uaudio_softc *sc,
213 					     struct mixerctl *mp);
214 Static char		*uaudio_id_name(struct uaudio_softc *sc,
215 					usb_descriptor_t **dps, int id);
216 Static struct usb_audio_cluster uaudio_get_cluster(int id,
217 						   usb_descriptor_t **dps);
218 Static void		uaudio_add_input(struct uaudio_softc *sc,
219 			    usb_descriptor_t *v, usb_descriptor_t **dps);
220 Static void		uaudio_add_output(struct uaudio_softc *sc,
221 			    usb_descriptor_t *v, usb_descriptor_t **dps);
222 Static void		uaudio_add_mixer(struct uaudio_softc *sc,
223 			    usb_descriptor_t *v, usb_descriptor_t **dps);
224 Static void		uaudio_add_selector(struct uaudio_softc *sc,
225 			    usb_descriptor_t *v, usb_descriptor_t **dps);
226 Static void		uaudio_add_feature(struct uaudio_softc *sc,
227 			    usb_descriptor_t *v, usb_descriptor_t **dps);
228 Static void		uaudio_add_processing_updown(struct uaudio_softc *sc,
229 			    usb_descriptor_t *v, usb_descriptor_t **dps);
230 Static void		uaudio_add_processing(struct uaudio_softc *sc,
231 			    usb_descriptor_t *v, usb_descriptor_t **dps);
232 Static void		uaudio_add_extension(struct uaudio_softc *sc,
233 			    usb_descriptor_t *v, usb_descriptor_t **dps);
234 Static usbd_status	uaudio_identify(struct uaudio_softc *sc,
235 			    usb_config_descriptor_t *cdesc);
236 
237 Static int		uaudio_signext(int type, int val);
238 Static int		uaudio_value2bsd(struct mixerctl *mc, int val);
239 Static int		uaudio_bsd2value(struct mixerctl *mc, int val);
240 Static int		uaudio_get(struct uaudio_softc *sc, int type,
241 			    int which, int wValue, int wIndex, int len);
242 Static int		uaudio_ctl_get(struct uaudio_softc *sc, int which,
243 			    struct mixerctl *mc, int chan);
244 Static void		uaudio_set(struct uaudio_softc *sc, int type,
245 			    int which, int wValue, int wIndex, int l, int v);
246 Static void		uaudio_ctl_set(struct uaudio_softc *sc, int which,
247 			    struct mixerctl *mc, int chan, int val);
248 
249 Static usbd_status	uaudio_set_speed(struct uaudio_softc *, int, u_int);
250 
251 Static usbd_status	uaudio_chan_open(struct uaudio_softc *sc,
252 					 struct chan *ch);
253 Static void		uaudio_chan_close(struct uaudio_softc *sc,
254 					  struct chan *ch);
255 Static usbd_status	uaudio_chan_alloc_buffers(struct uaudio_softc *,
256 						  struct chan *);
257 Static void		uaudio_chan_free_buffers(struct uaudio_softc *,
258 						 struct chan *);
259 Static void		uaudio_chan_init(struct chan *, int,
260 					 const struct audio_params *, int);
261 Static void		uaudio_chan_set_param(struct chan *ch, u_char *start,
262 			    u_char *end, int blksize);
263 Static void		uaudio_chan_ptransfer(struct chan *ch);
264 Static void		uaudio_chan_pintr(usbd_xfer_handle xfer,
265 			    usbd_private_handle priv, usbd_status status);
266 
267 Static void		uaudio_chan_rtransfer(struct chan *ch);
268 Static void		uaudio_chan_rintr(usbd_xfer_handle xfer,
269 			    usbd_private_handle priv, usbd_status status);
270 
271 Static int		uaudio_open(void *, int);
272 Static void		uaudio_close(void *);
273 Static int		uaudio_drain(void *);
274 Static int		uaudio_query_encoding(void *, struct audio_encoding *);
275 Static void		uaudio_get_minmax_rates(int, const struct as_info *,
276 						const struct audio_params *,
277 						int, u_long *, u_long *);
278 Static int		uaudio_match_alt_sub(int, const struct as_info *,
279 					     const struct audio_params *,
280 					     int, u_long);
281 Static int		uaudio_match_alt_chan(int, const struct as_info *,
282 					      struct audio_params *, int);
283 Static int		uaudio_match_alt(int, const struct as_info *,
284 					 struct audio_params *, int);
285 Static int		uaudio_set_params(void *, int, int,
286 			    struct audio_params *, struct audio_params *);
287 Static int		uaudio_round_blocksize(void *, int);
288 Static int		uaudio_trigger_output(void *, void *, void *,
289 					      int, void (*)(void *), void *,
290 					      struct audio_params *);
291 Static int		uaudio_trigger_input (void *, void *, void *,
292 					      int, void (*)(void *), void *,
293 					      struct audio_params *);
294 Static int		uaudio_halt_in_dma(void *);
295 Static int		uaudio_halt_out_dma(void *);
296 Static int		uaudio_getdev(void *, struct audio_device *);
297 Static int		uaudio_mixer_set_port(void *, mixer_ctrl_t *);
298 Static int		uaudio_mixer_get_port(void *, mixer_ctrl_t *);
299 Static int		uaudio_query_devinfo(void *, mixer_devinfo_t *);
300 Static int		uaudio_get_props(void *);
301 
302 Static struct audio_hw_if uaudio_hw_if = {
303 	uaudio_open,
304 	uaudio_close,
305 	uaudio_drain,
306 	uaudio_query_encoding,
307 	uaudio_set_params,
308 	uaudio_round_blocksize,
309 	NULL,
310 	NULL,
311 	NULL,
312 	NULL,
313 	NULL,
314 	uaudio_halt_out_dma,
315 	uaudio_halt_in_dma,
316 	NULL,
317 	uaudio_getdev,
318 	NULL,
319 	uaudio_mixer_set_port,
320 	uaudio_mixer_get_port,
321 	uaudio_query_devinfo,
322 	NULL,
323 	NULL,
324 	NULL,
325 	NULL,
326 	uaudio_get_props,
327 	uaudio_trigger_output,
328 	uaudio_trigger_input,
329 	NULL,
330 };
331 
332 Static struct audio_device uaudio_device = {
333 	"USB audio",
334 	"",
335 	"uaudio"
336 };
337 
338 USB_DECLARE_DRIVER(uaudio);
339 
340 USB_MATCH(uaudio)
341 {
342 	USB_MATCH_START(uaudio, uaa);
343 	usb_interface_descriptor_t *id;
344 
345 	if (uaa->iface == NULL)
346 		return (UMATCH_NONE);
347 
348 	id = usbd_get_interface_descriptor(uaa->iface);
349 	/* Trigger on the control interface. */
350 	if (id == NULL ||
351 	    id->bInterfaceClass != UICLASS_AUDIO ||
352 	    id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
353 	    (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
354 		return (UMATCH_NONE);
355 
356 	return (UMATCH_IFACECLASS_IFACESUBCLASS);
357 }
358 
359 USB_ATTACH(uaudio)
360 {
361 	USB_ATTACH_START(uaudio, sc, uaa);
362 	usb_interface_descriptor_t *id;
363 	usb_config_descriptor_t *cdesc;
364 	char devinfo[1024];
365 	usbd_status err;
366 	int i, j, found;
367 
368 	usbd_devinfo(uaa->device, 0, devinfo, sizeof(devinfo));
369 	printf(": %s\n", devinfo);
370 
371 	sc->sc_udev = uaa->device;
372 
373 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
374 	if (cdesc == NULL) {
375 		printf("%s: failed to get configuration descriptor\n",
376 		       USBDEVNAME(sc->sc_dev));
377 		USB_ATTACH_ERROR_RETURN;
378 	}
379 
380 	err = uaudio_identify(sc, cdesc);
381 	if (err) {
382 		printf("%s: audio descriptors make no sense, error=%d\n",
383 		       USBDEVNAME(sc->sc_dev), err);
384 		USB_ATTACH_ERROR_RETURN;
385 	}
386 
387 	sc->sc_ac_ifaceh = uaa->iface;
388 	/* Pick up the AS interface. */
389 	for (i = 0; i < uaa->nifaces; i++) {
390 		if (uaa->ifaces[i] == NULL)
391 			continue;
392 		id = usbd_get_interface_descriptor(uaa->ifaces[i]);
393 		if (id == NULL)
394 			continue;
395 		found = 0;
396 		for (j = 0; j < sc->sc_nalts; j++) {
397 			if (id->bInterfaceNumber ==
398 			    sc->sc_alts[j].idesc->bInterfaceNumber) {
399 				sc->sc_alts[j].ifaceh = uaa->ifaces[i];
400 				found = 1;
401 			}
402 		}
403 		if (found)
404 			uaa->ifaces[i] = NULL;
405 	}
406 
407 	for (j = 0; j < sc->sc_nalts; j++) {
408 		if (sc->sc_alts[j].ifaceh == NULL) {
409 			printf("%s: alt %d missing AS interface(s)\n",
410 			    USBDEVNAME(sc->sc_dev), j);
411 			USB_ATTACH_ERROR_RETURN;
412 		}
413 	}
414 
415 	printf("%s: audio rev %d.%02x\n", USBDEVNAME(sc->sc_dev),
416 	       sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
417 
418 	sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
419 	sc->sc_playchan.altidx = -1;
420 	sc->sc_recchan.altidx = -1;
421 
422 	if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
423 		sc->sc_altflags |= UA_NOFRAC;
424 
425 #ifndef UAUDIO_DEBUG
426 	if (bootverbose)
427 #endif
428 		printf("%s: %d mixer controls\n", USBDEVNAME(sc->sc_dev),
429 		    sc->sc_nctls);
430 
431 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
432 			   USBDEV(sc->sc_dev));
433 
434 	DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
435 #if defined(__OpenBSD__)
436 	audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
437 #else
438 	sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
439 #endif
440 
441 	USB_ATTACH_SUCCESS_RETURN;
442 }
443 
444 int
445 uaudio_activate(device_ptr_t self, enum devact act)
446 {
447 	struct uaudio_softc *sc = (struct uaudio_softc *)self;
448 	int rv = 0;
449 
450 	switch (act) {
451 	case DVACT_ACTIVATE:
452 		return (EOPNOTSUPP);
453 		break;
454 
455 	case DVACT_DEACTIVATE:
456 		if (sc->sc_audiodev != NULL)
457 			rv = config_deactivate(sc->sc_audiodev);
458 		sc->sc_dying = 1;
459 		break;
460 	}
461 	return (rv);
462 }
463 
464 int
465 uaudio_detach(device_ptr_t self, int flags)
466 {
467 	struct uaudio_softc *sc = (struct uaudio_softc *)self;
468 	int rv = 0;
469 
470 	/* Wait for outstanding requests to complete. */
471 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
472 
473 	if (sc->sc_audiodev != NULL)
474 		rv = config_detach(sc->sc_audiodev, flags);
475 
476 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
477 			   USBDEV(sc->sc_dev));
478 
479 	return (rv);
480 }
481 
482 int
483 uaudio_query_encoding(void *addr, struct audio_encoding *fp)
484 {
485 	struct uaudio_softc *sc = addr;
486 	int flags = sc->sc_altflags;
487 	int idx;
488 
489 	if (sc->sc_dying)
490 		return (EIO);
491 
492 	if (sc->sc_nalts == 0 || flags == 0)
493 		return (ENXIO);
494 
495 	idx = fp->index;
496 	switch (idx) {
497 	case 0:
498 		strlcpy(fp->name, AudioEulinear, sizeof(fp->name));
499 		fp->encoding = AUDIO_ENCODING_ULINEAR;
500 		fp->precision = 8;
501 		fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
502 		return (0);
503 	case 1:
504 		strlcpy(fp->name, AudioEmulaw, sizeof(fp->name));
505 		fp->encoding = AUDIO_ENCODING_ULAW;
506 		fp->precision = 8;
507 		fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
508 		return (0);
509 	case 2:
510 		strlcpy(fp->name, AudioEalaw, sizeof(fp->name));
511 		fp->encoding = AUDIO_ENCODING_ALAW;
512 		fp->precision = 8;
513 		fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
514 		return (0);
515 	case 3:
516 		strlcpy(fp->name, AudioEslinear, sizeof(fp->name));
517 		fp->encoding = AUDIO_ENCODING_SLINEAR;
518 		fp->precision = 8;
519 		fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
520 		return (0);
521 	case 4:
522 		strlcpy(fp->name, AudioEslinear_le, sizeof(fp->name));
523 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
524 		fp->precision = 16;
525 		fp->flags = 0;
526 		return (0);
527 	case 5:
528 		strlcpy(fp->name, AudioEulinear_le, sizeof(fp->name));
529 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
530 		fp->precision = 16;
531 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
532 		return (0);
533 	case 6:
534 		strlcpy(fp->name, AudioEslinear_be, sizeof(fp->name));
535 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
536 		fp->precision = 16;
537 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
538 		return (0);
539 	case 7:
540 		strlcpy(fp->name, AudioEulinear_be, sizeof(fp->name));
541 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
542 		fp->precision = 16;
543 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
544 		return (0);
545 	default:
546 		return (EINVAL);
547 	}
548 }
549 
550 usb_interface_descriptor_t *
551 uaudio_find_iface(char *buf, int size, int *offsp, int subtype)
552 {
553 	usb_interface_descriptor_t *d;
554 
555 	while (*offsp < size) {
556 		d = (void *)(buf + *offsp);
557 		*offsp += d->bLength;
558 		if (d->bDescriptorType == UDESC_INTERFACE &&
559 		    d->bInterfaceClass == UICLASS_AUDIO &&
560 		    d->bInterfaceSubClass == subtype)
561 			return (d);
562 	}
563 	return (NULL);
564 }
565 
566 void
567 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
568 {
569 	int res;
570 	size_t len = sizeof(*mc) * (sc->sc_nctls + 1);
571 	struct mixerctl *nmc = sc->sc_nctls == 0 ?
572 	    malloc(len, M_USBDEV, M_NOWAIT) :
573 	    realloc(sc->sc_ctls, len, M_USBDEV, M_NOWAIT);
574 
575 	if (nmc == NULL) {
576 		printf("uaudio_mixer_add_ctl: no memory\n");
577 		return;
578 	}
579 	sc->sc_ctls = nmc;
580 
581 	mc->delta = 0;
582 	if (mc->type != MIX_ON_OFF) {
583 		/* Determine min and max values. */
584 		mc->minval = uaudio_signext(mc->type,
585 			uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
586 				   mc->wValue[0], mc->wIndex,
587 				   MIX_SIZE(mc->type)));
588 		mc->maxval = 1 + uaudio_signext(mc->type,
589 			uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
590 				   mc->wValue[0], mc->wIndex,
591 				   MIX_SIZE(mc->type)));
592 		mc->mul = mc->maxval - mc->minval;
593 		if (mc->mul == 0)
594 			mc->mul = 1;
595 		res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
596 				 mc->wValue[0], mc->wIndex,
597 				 MIX_SIZE(mc->type));
598 		if (res > 0)
599 			mc->delta = (res * 255 + mc->mul/2) / mc->mul;
600 	} else {
601 		mc->minval = 0;
602 		mc->maxval = 1;
603 	}
604 
605 	sc->sc_ctls[sc->sc_nctls++] = *mc;
606 
607 #ifdef UAUDIO_DEBUG
608 	if (uaudiodebug > 2) {
609 		int i;
610 		DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
611 		for (i = 1; i < mc->nchan; i++)
612 			DPRINTF((",%04x", mc->wValue[i]));
613 		DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' "
614 			 "min=%d max=%d\n",
615 			 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
616 			 mc->minval, mc->maxval));
617 	}
618 #endif
619 }
620 
621 void
622 uaudio_mixer_alias_ctl(struct uaudio_softc *sc, struct mixerctl *mc,
623 		     const char *name)
624 {
625 	/* XXX mark as alias? */
626 	strlcpy(mc->ctlname, name, sizeof(mc->ctlname));
627 	uaudio_mixer_add_ctl(sc, mc);
628 }
629 
630 char *
631 uaudio_id_name(struct uaudio_softc *sc, usb_descriptor_t **dps, int id)
632 {
633 	static char buf[32];
634 	snprintf(buf, sizeof(buf), "i%d", id);
635 	return (buf);
636 }
637 
638 struct usb_audio_cluster
639 uaudio_get_cluster(int id, usb_descriptor_t **dps)
640 {
641 	struct usb_audio_cluster r;
642 	usb_descriptor_t *dp;
643 	int i;
644 
645 	for (i = 0; i < 25; i++) { /* avoid infinite loops */
646 		dp = dps[id];
647 		if (dp == 0)
648 			goto bad;
649 		switch (dp->bDescriptorSubtype) {
650 		case UDESCSUB_AC_INPUT:
651 #define p ((struct usb_audio_input_terminal *)dp)
652 			r.bNrChannels = p->bNrChannels;
653 			USETW(r.wChannelConfig, UGETW(p->wChannelConfig));
654 			r.iChannelNames = p->iChannelNames;
655 #undef p
656 			return (r);
657 		case UDESCSUB_AC_OUTPUT:
658 #define p ((struct usb_audio_output_terminal *)dp)
659 			id = p->bSourceId;
660 #undef p
661 			break;
662 		case UDESCSUB_AC_MIXER:
663 #define p ((struct usb_audio_mixer_unit *)dp)
664 			r = *(struct usb_audio_cluster *)
665 				&p->baSourceId[p->bNrInPins];
666 #undef p
667 			return (r);
668 		case UDESCSUB_AC_SELECTOR:
669 			/* XXX This is not really right */
670 #define p ((struct usb_audio_selector_unit *)dp)
671 			id = p->baSourceId[0];
672 #undef p
673 			break;
674 		case UDESCSUB_AC_FEATURE:
675 #define p ((struct usb_audio_feature_unit *)dp)
676 			id = p->bSourceId;
677 #undef p
678 			break;
679 		case UDESCSUB_AC_PROCESSING:
680 #define p ((struct usb_audio_processing_unit *)dp)
681 			r = *(struct usb_audio_cluster *)
682 				&p->baSourceId[p->bNrInPins];
683 #undef p
684 			return (r);
685 		case UDESCSUB_AC_EXTENSION:
686 #define p ((struct usb_audio_extension_unit *)dp)
687 			r = *(struct usb_audio_cluster *)
688 				&p->baSourceId[p->bNrInPins];
689 #undef p
690 			return (r);
691 		default:
692 			goto bad;
693 		}
694 	}
695  bad:
696 	printf("uaudio_get_cluster: bad data\n");
697 	memset(&r, 0, sizeof r);
698 	return (r);
699 
700 }
701 
702 void
703 uaudio_add_input(struct uaudio_softc *sc, usb_descriptor_t *v,
704 		 usb_descriptor_t **dps)
705 {
706 #ifdef UAUDIO_DEBUG
707 	struct usb_audio_input_terminal *d =
708 		(struct usb_audio_input_terminal *)v;
709 
710 	DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
711 		    "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
712 		    "iChannelNames=%d iTerminal=%d\n",
713 		    d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
714 		    d->bNrChannels, UGETW(d->wChannelConfig),
715 		    d->iChannelNames, d->iTerminal));
716 #endif
717 }
718 
719 void
720 uaudio_add_output(struct uaudio_softc *sc, usb_descriptor_t *v,
721 		  usb_descriptor_t **dps)
722 {
723 #ifdef UAUDIO_DEBUG
724 	struct usb_audio_output_terminal *d =
725 		(struct usb_audio_output_terminal *)v;
726 
727 	DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
728 		    "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
729 		    d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
730 		    d->bSourceId, d->iTerminal));
731 #endif
732 }
733 
734 void
735 uaudio_add_mixer(struct uaudio_softc *sc, usb_descriptor_t *v,
736 		 usb_descriptor_t **dps)
737 {
738 	struct usb_audio_mixer_unit *d = (struct usb_audio_mixer_unit *)v;
739 	struct usb_audio_mixer_unit_1 *d1;
740 	int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
741 	uByte *bm;
742 	struct mixerctl mix;
743 
744 	DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
745 		    d->bUnitId, d->bNrInPins));
746 
747 	/* Compute the number of input channels */
748 	ichs = 0;
749 	for (i = 0; i < d->bNrInPins; i++)
750 		ichs += uaudio_get_cluster(d->baSourceId[i], dps).bNrChannels;
751 
752 	/* and the number of output channels */
753 	d1 = (struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
754 	ochs = d1->bNrChannels;
755 	DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
756 
757 	bm = d1->bmControls;
758 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
759 	mix.class = -1;
760 	mix.type = MIX_SIGNED_16;
761 	mix.ctlunit = AudioNvolume;
762 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
763 	for (p = i = 0; i < d->bNrInPins; i++) {
764 		chs = uaudio_get_cluster(d->baSourceId[i], dps).bNrChannels;
765 		mc = 0;
766 		for (c = 0; c < chs; c++) {
767 			mo = 0;
768 			for (o = 0; o < ochs; o++) {
769 				bno = (p + c) * ochs + o;
770 				if (BIT(bno))
771 					mo++;
772 			}
773 			if (mo == 1)
774 				mc++;
775 		}
776 		if (mc == chs && chs <= MIX_MAX_CHAN) {
777 			k = 0;
778 			for (c = 0; c < chs; c++)
779 				for (o = 0; o < ochs; o++) {
780 					bno = (p + c) * ochs + o;
781 					if (BIT(bno))
782 						mix.wValue[k++] =
783 							MAKE(p+c+1, o+1);
784 				}
785 			snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s",
786 			    d->bUnitId, uaudio_id_name(sc, dps,
787 			    d->baSourceId[i]));
788 			mix.nchan = chs;
789 			uaudio_mixer_add_ctl(sc, &mix);
790 		} else {
791 			/* XXX */
792 		}
793 #undef BIT
794 		p += chs;
795 	}
796 
797 }
798 
799 void
800 uaudio_add_selector(struct uaudio_softc *sc, usb_descriptor_t *v,
801 		    usb_descriptor_t **dps)
802 {
803 #ifdef UAUDIO_DEBUG
804 	struct usb_audio_selector_unit *d =
805 		(struct usb_audio_selector_unit *)v;
806 
807 	DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
808 		    d->bUnitId, d->bNrInPins));
809 #endif
810 	printf("uaudio_add_selector: NOT IMPLEMENTED\n");
811 }
812 
813 void
814 uaudio_add_feature(struct uaudio_softc *sc, usb_descriptor_t *v,
815 		   usb_descriptor_t **dps)
816 {
817 	struct usb_audio_feature_unit *d = (struct usb_audio_feature_unit *)v;
818 	uByte *ctls = d->bmaControls;
819 	int ctlsize = d->bControlSize;
820 	int nchan = (d->bLength - 7) / ctlsize;
821 	int srcId = d->bSourceId;
822 	u_int fumask, mmask, cmask;
823 	struct mixerctl mix;
824 	int chan, ctl, i, unit;
825 
826 #define GET(i) (ctls[(i)*ctlsize] | \
827 		(ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
828 
829 	mmask = GET(0);
830 	/* Figure out what we can control */
831 	for (cmask = 0, chan = 1; chan < nchan; chan++) {
832 		DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
833 			    chan, GET(chan)));
834 		cmask |= GET(chan);
835 	}
836 
837 	DPRINTFN(1,("uaudio_add_feature: bUnitId=%d bSourceId=%d, "
838 		    "%d channels, mmask=0x%04x, cmask=0x%04x\n",
839 		    d->bUnitId, srcId, nchan, mmask, cmask));
840 
841 	if (nchan > MIX_MAX_CHAN)
842 		nchan = MIX_MAX_CHAN;
843 	unit = d->bUnitId;
844 	mix.wIndex = MAKE(unit, sc->sc_ac_iface);
845 	for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
846 		fumask = FU_MASK(ctl);
847 		DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
848 			    ctl, fumask));
849 		if (mmask & fumask) {
850 			mix.nchan = 1;
851 			mix.wValue[0] = MAKE(ctl, 0);
852 		} else if (cmask & fumask) {
853 			mix.nchan = nchan - 1;
854 			for (i = 1; i < nchan; i++) {
855 				if (GET(i) & fumask)
856 					mix.wValue[i-1] = MAKE(ctl, i);
857 				else
858 					mix.wValue[i-1] = -1;
859 			}
860 		} else {
861 			continue;
862 		}
863 #undef GET
864 		mix.class = UAC_OUTPUT;	/* XXX we don't really know this */
865 		switch (ctl) {
866 		case MUTE_CONTROL:
867 			mix.type = MIX_ON_OFF;
868 			mix.ctlunit = "";
869 			uaudio_mixer_alias_ctl(sc, &mix, AudioNmute);
870 			snprintf(mix.ctlname, sizeof(mix.ctlname),
871 			    "fea%d-%s-%s", unit, uaudio_id_name(sc, dps, srcId),
872 			    AudioNmute);
873 			break;
874 		case VOLUME_CONTROL:
875 			mix.type = MIX_SIGNED_16;
876 			mix.ctlunit = AudioNvolume;
877 			uaudio_mixer_alias_ctl(sc, &mix, AudioNmaster);
878 			snprintf(mix.ctlname, sizeof(mix.ctlname),
879 			    "fea%d-%s-%s", unit, uaudio_id_name(sc, dps, srcId),
880 			    AudioNmaster);
881 			break;
882 		case BASS_CONTROL:
883 			mix.type = MIX_SIGNED_8;
884 			mix.ctlunit = AudioNbass;
885 			uaudio_mixer_alias_ctl(sc, &mix, AudioNbass);
886 			snprintf(mix.ctlname, sizeof(mix.ctlname),
887 			    "fea%d-%s-%s", unit, uaudio_id_name(sc, dps, srcId),
888 			    AudioNbass);
889 			break;
890 		case MID_CONTROL:
891 			mix.type = MIX_SIGNED_8;
892 			mix.ctlunit = AudioNmid;
893 			snprintf(mix.ctlname, sizeof(mix.ctlname),
894 			    "fea%d-%s-%s", unit, uaudio_id_name(sc, dps, srcId),
895 			    AudioNmid);
896 			break;
897 		case TREBLE_CONTROL:
898 			mix.type = MIX_SIGNED_8;
899 			mix.ctlunit = AudioNtreble;
900 			uaudio_mixer_alias_ctl(sc, &mix, AudioNtreble);
901 			snprintf(mix.ctlname, sizeof(mix.ctlname),
902 			    "fea%d-%s-%s", unit, uaudio_id_name(sc, dps, srcId),
903 			    AudioNtreble);
904 			break;
905 		case GRAPHIC_EQUALIZER_CONTROL:
906 			continue; /* XXX don't add anything */
907 			break;
908 		case AGC_CONTROL:
909 			mix.type = MIX_ON_OFF;
910 			snprintf(mix.ctlname, sizeof(mix.ctlname),
911 			    "fea%d-%s-%s", unit, uaudio_id_name(sc, dps, srcId),
912 			    AudioNagc);
913 			mix.ctlunit = "";
914 			break;
915 		case DELAY_CONTROL:
916 			mix.type = MIX_UNSIGNED_16;
917 			snprintf(mix.ctlname, sizeof(mix.ctlname),
918 			    "fea%d-%s-%s", unit, uaudio_id_name(sc, dps, srcId),
919 			    AudioNdelay);
920 			mix.ctlunit = "4 ms";
921 			break;
922 		case BASS_BOOST_CONTROL:
923 			mix.type = MIX_ON_OFF;
924 			snprintf(mix.ctlname, sizeof(mix.ctlname),
925 			    "fea%d-%s-%s", unit, uaudio_id_name(sc, dps, srcId),
926 			    AudioNbassboost);
927 			mix.ctlunit = "";
928 			break;
929 		case LOUDNESS_CONTROL:
930 			mix.type = MIX_ON_OFF;
931 			snprintf(mix.ctlname, sizeof(mix.ctlname),
932 			    "fea%d-%s-%s", unit, uaudio_id_name(sc, dps, srcId),
933 			    AudioNloudness);
934 			mix.ctlunit = "";
935 			break;
936 		}
937 		uaudio_mixer_add_ctl(sc, &mix);
938 	}
939 }
940 
941 void
942 uaudio_add_processing_updown(struct uaudio_softc *sc, usb_descriptor_t *v,
943 			     usb_descriptor_t **dps)
944 {
945 	struct usb_audio_processing_unit *d =
946 	    (struct usb_audio_processing_unit *)v;
947 	struct usb_audio_processing_unit_1 *d1 =
948 	    (struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
949 	struct usb_audio_processing_unit_updown *ud =
950 	    (struct usb_audio_processing_unit_updown *)
951 		&d1->bmControls[d1->bControlSize];
952 	struct mixerctl mix;
953 	int i;
954 
955 	DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
956 		    d->bUnitId, ud->bNrModes));
957 
958 	if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
959 		DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
960 		return;
961 	}
962 
963 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
964 	mix.nchan = 1;
965 	mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
966 	mix.class = -1;
967 	mix.type = MIX_ON_OFF;	/* XXX */
968 	mix.ctlunit = "";
969 	snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId);
970 
971 	for (i = 0; i < ud->bNrModes; i++) {
972 		DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
973 			    i, UGETW(ud->waModes[i])));
974 		/* XXX */
975 	}
976 	uaudio_mixer_add_ctl(sc, &mix);
977 }
978 
979 void
980 uaudio_add_processing(struct uaudio_softc *sc, usb_descriptor_t *v,
981 		      usb_descriptor_t **dps)
982 {
983 	struct usb_audio_processing_unit *d =
984 	    (struct usb_audio_processing_unit *)v;
985 	struct usb_audio_processing_unit_1 *d1 =
986 	    (struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
987 	int ptype = UGETW(d->wProcessType);
988 	struct mixerctl mix;
989 
990 	DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
991 		    "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
992 
993 	if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
994 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
995 		mix.nchan = 1;
996 		mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
997 		mix.class = -1;
998 		mix.type = MIX_ON_OFF;
999 		mix.ctlunit = "";
1000 		snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable",
1001 		    d->bUnitId, ptype);
1002 		uaudio_mixer_add_ctl(sc, &mix);
1003 	}
1004 
1005 	switch(ptype) {
1006 	case UPDOWNMIX_PROCESS:
1007 		uaudio_add_processing_updown(sc, v, dps);
1008 		break;
1009 	case DOLBY_PROLOGIC_PROCESS:
1010 	case P3D_STEREO_EXTENDER_PROCESS:
1011 	case REVERBATION_PROCESS:
1012 	case CHORUS_PROCESS:
1013 	case DYN_RANGE_COMP_PROCESS:
1014 	default:
1015 #ifdef UAUDIO_DEBUG
1016 		printf("uaudio_add_processing: unit %d, type=%d not impl.\n",
1017 		       d->bUnitId, ptype);
1018 #endif
1019 		break;
1020 	}
1021 }
1022 
1023 void
1024 uaudio_add_extension(struct uaudio_softc *sc, usb_descriptor_t *v,
1025 		     usb_descriptor_t **dps)
1026 {
1027 	struct usb_audio_extension_unit *d =
1028 	    (struct usb_audio_extension_unit *)v;
1029 	struct usb_audio_extension_unit_1 *d1 =
1030 	    (struct usb_audio_extension_unit_1 *)&d->baSourceId[d->bNrInPins];
1031 	struct mixerctl mix;
1032 
1033 	DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
1034 		    d->bUnitId, d->bNrInPins));
1035 
1036 	if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
1037 		return;
1038 
1039 	if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
1040 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1041 		mix.nchan = 1;
1042 		mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
1043 		mix.class = -1;
1044 		mix.type = MIX_ON_OFF;
1045 		mix.ctlunit = "";
1046 		snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable",
1047 		    d->bUnitId);
1048 		uaudio_mixer_add_ctl(sc, &mix);
1049 	}
1050 }
1051 
1052 usbd_status
1053 uaudio_identify(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc)
1054 {
1055 	usbd_status err;
1056 
1057 	err = uaudio_identify_ac(sc, cdesc);
1058 	if (err)
1059 		return (err);
1060 	return (uaudio_identify_as(sc, cdesc));
1061 }
1062 
1063 void
1064 uaudio_add_alt(struct uaudio_softc *sc, struct as_info *ai)
1065 {
1066 	size_t len = sizeof(*ai) * (sc->sc_nalts + 1);
1067 	struct as_info *nai = (sc->sc_nalts == 0) ?
1068 	    malloc(len, M_USBDEV, M_NOWAIT) :
1069 	    realloc(sc->sc_alts, len, M_USBDEV, M_NOWAIT);
1070 
1071 	if (nai == NULL) {
1072 		printf("uaudio_add_alt: no memory\n");
1073 		return;
1074 	}
1075 
1076 	sc->sc_alts = nai;
1077 	DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
1078 		    ai->alt, ai->encoding));
1079 	sc->sc_alts[sc->sc_nalts++] = *ai;
1080 }
1081 
1082 usbd_status
1083 uaudio_process_as(struct uaudio_softc *sc, char *buf, int *offsp,
1084 		  int size, usb_interface_descriptor_t *id)
1085 #define offs (*offsp)
1086 {
1087 	struct usb_audio_streaming_interface_descriptor *asid;
1088 	struct usb_audio_streaming_type1_descriptor *asf1d;
1089 	usb_endpoint_descriptor_audio_t *ed;
1090 	struct usb_audio_streaming_endpoint_descriptor *sed;
1091 	int format, chan, prec, enc;
1092 	int dir, type;
1093 	struct as_info ai;
1094 
1095 	asid = (void *)(buf + offs);
1096 	if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
1097 	    asid->bDescriptorSubtype != AS_GENERAL)
1098 		return (USBD_INVAL);
1099 	offs += asid->bLength;
1100 	if (offs > size)
1101 		return (USBD_INVAL);
1102 	asf1d = (void *)(buf + offs);
1103 	if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
1104 	    asf1d->bDescriptorSubtype != FORMAT_TYPE)
1105 		return (USBD_INVAL);
1106 	offs += asf1d->bLength;
1107 	if (offs > size)
1108 		return (USBD_INVAL);
1109 
1110 	if (asf1d->bFormatType != FORMAT_TYPE_I) {
1111 		printf("%s: ignored setting with type %d format\n",
1112 		       USBDEVNAME(sc->sc_dev), UGETW(asid->wFormatTag));
1113 		return (USBD_NORMAL_COMPLETION);
1114 	}
1115 
1116 	ed = (void *)(buf + offs);
1117 	if (ed->bDescriptorType != UDESC_ENDPOINT)
1118 		return (USBD_INVAL);
1119 	DPRINTF(("uaudio_process_as: endpoint bLength=%d bDescriptorType=%d "
1120 		 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
1121 		 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
1122 		 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
1123 		 ed->bmAttributes, UGETW(ed->wMaxPacketSize),
1124 		 ed->bInterval, ed->bRefresh, ed->bSynchAddress));
1125 	offs += ed->bLength;
1126 	if (offs > size)
1127 		return (USBD_INVAL);
1128 	if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
1129 		return (USBD_INVAL);
1130 
1131 	dir = UE_GET_DIR(ed->bEndpointAddress);
1132 	type = UE_GET_ISO_TYPE(ed->bmAttributes);
1133 	if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
1134 	    dir == UE_DIR_IN && type == UE_ISO_ADAPT)
1135 		type = UE_ISO_ASYNC;
1136 
1137 	/* We can't handle endpoints that need a sync pipe yet. */
1138 	if (dir == UE_DIR_IN ? type == UE_ISO_ADAPT : type == UE_ISO_ASYNC) {
1139 		printf("%s: ignored %sput endpoint of type %s\n",
1140 		       USBDEVNAME(sc->sc_dev),
1141 		       dir == UE_DIR_IN ? "in" : "out",
1142 		       dir == UE_DIR_IN ? "adaptive" : "async");
1143 		return (USBD_NORMAL_COMPLETION);
1144 	}
1145 
1146 	sed = (void *)(buf + offs);
1147 	if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
1148 	    sed->bDescriptorSubtype != AS_GENERAL)
1149 		return (USBD_INVAL);
1150 	offs += sed->bLength;
1151 	if (offs > size)
1152 		return (USBD_INVAL);
1153 
1154 	format = UGETW(asid->wFormatTag);
1155 	chan = asf1d->bNrChannels;
1156 	prec = asf1d->bBitResolution;
1157 	if (prec != 8 && prec != 16 && prec != 24) {
1158 		printf("%s: ignored setting with precision %d\n",
1159 		       USBDEVNAME(sc->sc_dev), prec);
1160 		return (USBD_NORMAL_COMPLETION);
1161 	}
1162 	switch (format) {
1163 	case UA_FMT_PCM:
1164 		if (prec == 8) {
1165 			sc->sc_altflags |= HAS_8;
1166 		} else if (prec == 16) {
1167 			sc->sc_altflags |= HAS_16;
1168 		} else if (prec == 24) {
1169 			sc->sc_altflags |= HAS_24;
1170 		}
1171 		enc = AUDIO_ENCODING_SLINEAR_LE;
1172 		break;
1173 	case UA_FMT_PCM8:
1174 		enc = AUDIO_ENCODING_ULINEAR_LE;
1175 		sc->sc_altflags |= HAS_8U;
1176 		break;
1177 	case UA_FMT_ALAW:
1178 		enc = AUDIO_ENCODING_ALAW;
1179 		sc->sc_altflags |= HAS_ALAW;
1180 		break;
1181 	case UA_FMT_MULAW:
1182 		enc = AUDIO_ENCODING_ULAW;
1183 		sc->sc_altflags |= HAS_MULAW;
1184 		break;
1185 	default:
1186 		printf("%s: ignored setting with format %d\n",
1187 		       USBDEVNAME(sc->sc_dev), format);
1188 		return (USBD_NORMAL_COMPLETION);
1189 	}
1190 	DPRINTFN(1, ("uaudio_process_as: alt=%d enc=%d chan=%d prec=%d\n",
1191 		     id->bAlternateSetting, enc, chan, prec));
1192 	ai.alt = id->bAlternateSetting;
1193 	ai.encoding = enc;
1194 	ai.attributes = sed->bmAttributes;
1195 	ai.idesc = id;
1196 	ai.edesc = ed;
1197 	ai.asf1desc = asf1d;
1198 	ai.sc_busy = 0;
1199 	uaudio_add_alt(sc, &ai);
1200 #ifdef UAUDIO_DEBUG
1201 	{
1202 		int j;
1203 		if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
1204 			DPRINTFN(1, ("uaudio_process_as:  rate=%d-%d\n",
1205 				     UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d)));
1206 		} else {
1207 			DPRINTFN(1, ("uaudio_process_as: "));
1208 			for (j = 0; j < asf1d->bSamFreqType; j++)
1209 				DPRINTFN(1, (" %d", UA_GETSAMP(asf1d, j)));
1210 			DPRINTFN(1, ("\n"));
1211 		}
1212 		if (ai.attributes & UA_SED_FREQ_CONTROL)
1213 			DPRINTFN(1, ("uaudio_process_as:  FREQ_CONTROL\n"));
1214 		if (ai.attributes & UA_SED_PITCH_CONTROL)
1215 			DPRINTFN(1, ("uaudio_process_as:  PITCH_CONTROL\n"));
1216 	}
1217 #endif
1218 	sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD;
1219 
1220 	return (USBD_NORMAL_COMPLETION);
1221 }
1222 #undef offs
1223 
1224 usbd_status
1225 uaudio_identify_as(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc)
1226 {
1227 	usb_interface_descriptor_t *id;
1228 	char *buf;
1229 	int size, offs;
1230 
1231 	size = UGETW(cdesc->wTotalLength);
1232 	buf = (char *)cdesc;
1233 
1234 	/* Locate the AudioStreaming interface descriptor. */
1235 	offs = 0;
1236 	id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
1237 	if (id == NULL)
1238 		return (USBD_INVAL);
1239 
1240 	/* Loop through all the alternate settings. */
1241 	while (offs <= size) {
1242 		DPRINTFN(2, ("uaudio_identify: interface %d\n",
1243 		    id->bInterfaceNumber));
1244 		switch (id->bNumEndpoints) {
1245 		case 0:
1246 			DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
1247 				     id->bAlternateSetting));
1248 			sc->sc_nullalt = id->bAlternateSetting;
1249 			break;
1250 		case 1:
1251 			uaudio_process_as(sc, buf, &offs, size, id);
1252 			break;
1253 		default:
1254 #ifdef UAUDIO_DEBUG
1255 			printf("%s: ignored audio interface with %d "
1256 			       "endpoints\n",
1257 			       USBDEVNAME(sc->sc_dev), id->bNumEndpoints);
1258 #endif
1259 			break;
1260 		}
1261 		id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
1262 		if (id == NULL)
1263 			break;
1264 	}
1265 	if (offs > size)
1266 		return (USBD_INVAL);
1267 	DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
1268 
1269 	if (sc->sc_mode == 0) {
1270 		printf("%s: no usable endpoint found\n",
1271 		       USBDEVNAME(sc->sc_dev));
1272 		return (USBD_INVAL);
1273 	}
1274 
1275 	return (USBD_NORMAL_COMPLETION);
1276 }
1277 
1278 usbd_status
1279 uaudio_identify_ac(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc)
1280 {
1281 	usb_interface_descriptor_t *id;
1282 	struct usb_audio_control_descriptor *acdp;
1283 	usb_descriptor_t *dp, *dps[256];
1284 	char *buf, *ibuf, *ibufend;
1285 	int size, offs, aclen, ndps, i;
1286 
1287 	size = UGETW(cdesc->wTotalLength);
1288 	buf = (char *)cdesc;
1289 
1290 	/* Locate the AudioControl interface descriptor. */
1291 	offs = 0;
1292 	id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
1293 	if (id == NULL)
1294 		return (USBD_INVAL);
1295 	if (offs + sizeof *acdp > size)
1296 		return (USBD_INVAL);
1297 	sc->sc_ac_iface = id->bInterfaceNumber;
1298 	DPRINTFN(2,("uaudio_identify: AC interface is %d\n", sc->sc_ac_iface));
1299 
1300 	/* A class-specific AC interface header should follow. */
1301 	ibuf = buf + offs;
1302 	acdp = (struct usb_audio_control_descriptor *)ibuf;
1303 	if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
1304 	    acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
1305 		return (USBD_INVAL);
1306 	aclen = UGETW(acdp->wTotalLength);
1307 	if (offs + aclen > size)
1308 		return (USBD_INVAL);
1309 
1310 	if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
1311 	     UGETW(acdp->bcdADC) != UAUDIO_VERSION)
1312 		return (USBD_INVAL);
1313 
1314 	sc->sc_audio_rev = UGETW(acdp->bcdADC);
1315 	DPRINTFN(2,("uaudio_identify: found AC header, vers=%03x, len=%d\n",
1316 		 sc->sc_audio_rev, aclen));
1317 
1318 	sc->sc_nullalt = -1;
1319 
1320 	/* Scan through all the AC specific descriptors */
1321 	ibufend = ibuf + aclen;
1322 	dp = (usb_descriptor_t *)ibuf;
1323 	ndps = 0;
1324 	memset(dps, 0, sizeof dps);
1325 	for (;;) {
1326 		ibuf += dp->bLength;
1327 		if (ibuf >= ibufend)
1328 			break;
1329 		dp = (usb_descriptor_t *)ibuf;
1330 		if (ibuf + dp->bLength > ibufend)
1331 			return (USBD_INVAL);
1332 		if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
1333 			printf("uaudio_identify: skip desc type=0x%02x\n",
1334 			       dp->bDescriptorType);
1335 			continue;
1336 		}
1337 		i = ((struct usb_audio_input_terminal *)dp)->bTerminalId;
1338 		dps[i] = dp;
1339 		if (i > ndps)
1340 			ndps = i;
1341 	}
1342 	ndps++;
1343 
1344 	for (i = 0; i < ndps; i++) {
1345 		dp = dps[i];
1346 		if (dp == NULL)
1347 			continue;
1348 		DPRINTF(("uaudio_identify: subtype=%d\n",
1349 			 dp->bDescriptorSubtype));
1350 		switch (dp->bDescriptorSubtype) {
1351 		case UDESCSUB_AC_HEADER:
1352 			printf("uaudio_identify: unexpected AC header\n");
1353 			break;
1354 		case UDESCSUB_AC_INPUT:
1355 			uaudio_add_input(sc, dp, dps);
1356 			break;
1357 		case UDESCSUB_AC_OUTPUT:
1358 			uaudio_add_output(sc, dp, dps);
1359 			break;
1360 		case UDESCSUB_AC_MIXER:
1361 			uaudio_add_mixer(sc, dp, dps);
1362 			break;
1363 		case UDESCSUB_AC_SELECTOR:
1364 			uaudio_add_selector(sc, dp, dps);
1365 			break;
1366 		case UDESCSUB_AC_FEATURE:
1367 			uaudio_add_feature(sc, dp, dps);
1368 			break;
1369 		case UDESCSUB_AC_PROCESSING:
1370 			uaudio_add_processing(sc, dp, dps);
1371 			break;
1372 		case UDESCSUB_AC_EXTENSION:
1373 			uaudio_add_extension(sc, dp, dps);
1374 			break;
1375 		default:
1376 			printf("uaudio_identify: bad AC desc subtype=0x%02x\n",
1377 			       dp->bDescriptorSubtype);
1378 			break;
1379 		}
1380 	}
1381 	return (USBD_NORMAL_COMPLETION);
1382 }
1383 
1384 int
1385 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
1386 {
1387 	struct uaudio_softc *sc = addr;
1388 	struct mixerctl *mc;
1389 	int n, nctls;
1390 
1391 	DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index));
1392 	if (sc->sc_dying)
1393 		return (EIO);
1394 
1395 	n = mi->index;
1396 	nctls = sc->sc_nctls;
1397 
1398 	switch (n) {
1399 	case UAC_OUTPUT:
1400 		mi->type = AUDIO_MIXER_CLASS;
1401 		mi->mixer_class = UAC_OUTPUT;
1402 		mi->next = mi->prev = AUDIO_MIXER_LAST;
1403 		strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name));
1404 		return (0);
1405 	case UAC_INPUT:
1406 		mi->type = AUDIO_MIXER_CLASS;
1407 		mi->mixer_class = UAC_INPUT;
1408 		mi->next = mi->prev = AUDIO_MIXER_LAST;
1409 		strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name));
1410 		return (0);
1411 	case UAC_EQUAL:
1412 		mi->type = AUDIO_MIXER_CLASS;
1413 		mi->mixer_class = UAC_EQUAL;
1414 		mi->next = mi->prev = AUDIO_MIXER_LAST;
1415 		strlcpy(mi->label.name, AudioCequalization,
1416 		    sizeof(mi->label.name));
1417 		return (0);
1418 	default:
1419 		break;
1420 	}
1421 
1422 	n -= UAC_NCLASSES;
1423 	if (n < 0 || n >= nctls)
1424 		return (ENXIO);
1425 
1426 	mc = &sc->sc_ctls[n];
1427 	strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name));
1428 	mi->mixer_class = mc->class;
1429 	mi->next = mi->prev = AUDIO_MIXER_LAST;	/* XXX */
1430 	switch (mc->type) {
1431 	case MIX_ON_OFF:
1432 		mi->type = AUDIO_MIXER_ENUM;
1433 		mi->un.e.num_mem = 2;
1434 		strlcpy(mi->un.e.member[0].label.name, AudioNoff,
1435 		    sizeof(mi->un.e.member[0].label.name));
1436 		mi->un.e.member[0].ord = 0;
1437 		strlcpy(mi->un.e.member[1].label.name, AudioNon,
1438 		    sizeof(mi->un.e.member[1].label.name));
1439 		mi->un.e.member[1].ord = 1;
1440 		break;
1441 	default:
1442 		mi->type = AUDIO_MIXER_VALUE;
1443 		strncpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN);
1444 		mi->un.v.num_channels = mc->nchan;
1445 		mi->un.v.delta = mc->delta;
1446 		break;
1447 	}
1448 	return (0);
1449 }
1450 
1451 int
1452 uaudio_open(void *addr, int flags)
1453 {
1454 	struct uaudio_softc *sc = addr;
1455 
1456 	DPRINTF(("uaudio_open: sc=%p\n", sc));
1457 	if (sc->sc_dying)
1458 		return (EIO);
1459 
1460 	if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY))
1461 		return (EACCES);
1462 	if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD))
1463 		return (EACCES);
1464 
1465 	return (0);
1466 }
1467 
1468 /*
1469  * Close function is called at splaudio().
1470  */
1471 void
1472 uaudio_close(void *addr)
1473 {
1474 }
1475 
1476 int
1477 uaudio_drain(void *addr)
1478 {
1479 	struct uaudio_softc *sc = addr;
1480 
1481 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
1482 
1483 	return (0);
1484 }
1485 
1486 int
1487 uaudio_halt_out_dma(void *addr)
1488 {
1489 	struct uaudio_softc *sc = addr;
1490 
1491 	DPRINTF(("uaudio_halt_out_dma: enter\n"));
1492 	if (sc->sc_playchan.pipe != NULL) {
1493 		uaudio_chan_close(sc, &sc->sc_playchan);
1494 		sc->sc_playchan.pipe = NULL;
1495 		uaudio_chan_free_buffers(sc, &sc->sc_playchan);
1496 		sc->sc_playchan.intr = NULL;
1497 	}
1498 	return (0);
1499 }
1500 
1501 int
1502 uaudio_halt_in_dma(void *addr)
1503 {
1504 	struct uaudio_softc *sc = addr;
1505 
1506 	DPRINTF(("uaudio_halt_in_dma: enter\n"));
1507 	if (sc->sc_recchan.pipe != NULL) {
1508 		uaudio_chan_close(sc, &sc->sc_recchan);
1509 		sc->sc_recchan.pipe = NULL;
1510 		uaudio_chan_free_buffers(sc, &sc->sc_recchan);
1511 		sc->sc_recchan.intr = NULL;
1512 	}
1513 	return (0);
1514 }
1515 
1516 int
1517 uaudio_getdev(void *addr, struct audio_device *retp)
1518 {
1519 	struct uaudio_softc *sc = addr;
1520 
1521 	DPRINTF(("uaudio_mixer_getdev:\n"));
1522 	if (sc->sc_dying)
1523 		return (EIO);
1524 
1525 	*retp = uaudio_device;
1526 	return (0);
1527 }
1528 
1529 /*
1530  * Make sure the block size is large enough to hold all outstanding transfers.
1531  */
1532 int
1533 uaudio_round_blocksize(void *addr, int blk)
1534 {
1535 	struct uaudio_softc *sc = addr;
1536 	int bpf;
1537 
1538 	DPRINTF(("uaudio_round_blocksize: p.bpf=%d r.bpf=%d\n",
1539 		 sc->sc_playchan.bytes_per_frame,
1540 		 sc->sc_recchan.bytes_per_frame));
1541 	if (sc->sc_playchan.bytes_per_frame > sc->sc_recchan.bytes_per_frame) {
1542 		bpf = sc->sc_playchan.bytes_per_frame
1543 		    + sc->sc_playchan.sample_size;
1544 	} else {
1545 		bpf = sc->sc_recchan.bytes_per_frame
1546 		    + sc->sc_recchan.sample_size;
1547 	}
1548 	/* XXX */
1549 	bpf *= UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
1550 
1551 	bpf = (bpf + 15) &~ 15;
1552 
1553 	if (blk < bpf)
1554 		blk = bpf;
1555 
1556 #ifdef DIAGNOSTIC
1557 	if (blk <= 0) {
1558 		printf("uaudio_round_blocksize: blk=%d\n", blk);
1559 		blk = 512;
1560 	}
1561 #endif
1562 
1563 	DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk));
1564 	return (blk);
1565 }
1566 
1567 int
1568 uaudio_get_props(void *addr)
1569 {
1570 	return (AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT);
1571 
1572 }
1573 
1574 int
1575 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
1576 	   int wIndex, int len)
1577 {
1578 	usb_device_request_t req;
1579 	u_int8_t data[4];
1580 	usbd_status err;
1581 	int val;
1582 
1583 	if (wValue == -1)
1584 		return (0);
1585 
1586 	req.bmRequestType = type;
1587 	req.bRequest = which;
1588 	USETW(req.wValue, wValue);
1589 	USETW(req.wIndex, wIndex);
1590 	USETW(req.wLength, len);
1591 	DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
1592 		    "wIndex=0x%04x len=%d\n",
1593 		    type, which, wValue, wIndex, len));
1594 	err = usbd_do_request(sc->sc_udev, &req, data);
1595 	if (err) {
1596 		DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
1597 		return (-1);
1598 	}
1599 	switch (len) {
1600 	case 1:
1601 		val = data[0];
1602 		break;
1603 	case 2:
1604 		val = data[0] | (data[1] << 8);
1605 		break;
1606 	default:
1607 		DPRINTF(("uaudio_get: bad length=%d\n", len));
1608 		return (-1);
1609 	}
1610 	DPRINTFN(2,("uaudio_get: val=%d\n", val));
1611 	return (val);
1612 }
1613 
1614 void
1615 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
1616 	   int wIndex, int len, int val)
1617 {
1618 	usb_device_request_t req;
1619 	u_int8_t data[4];
1620 	usbd_status err;
1621 
1622 	if (wValue == -1)
1623 		return;
1624 
1625 	req.bmRequestType = type;
1626 	req.bRequest = which;
1627 	USETW(req.wValue, wValue);
1628 	USETW(req.wIndex, wIndex);
1629 	USETW(req.wLength, len);
1630 	switch (len) {
1631 	case 1:
1632 		data[0] = val;
1633 		break;
1634 	case 2:
1635 		data[0] = val;
1636 		data[1] = val >> 8;
1637 		break;
1638 	default:
1639 		return;
1640 	}
1641 	DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
1642 		    "wIndex=0x%04x len=%d, val=%d\n",
1643 		    type, which, wValue, wIndex, len, val & 0xffff));
1644 	err = usbd_do_request(sc->sc_udev, &req, data);
1645 #ifdef UAUDIO_DEBUG
1646 	if (err)
1647 		DPRINTF(("uaudio_set: err=%d\n", err));
1648 #endif
1649 }
1650 
1651 int
1652 uaudio_signext(int type, int val)
1653 {
1654 	if (!MIX_UNSIGNED(type)) {
1655 		if (MIX_SIZE(type) == 2)
1656 			val = (int16_t)val;
1657 		else
1658 			val = (int8_t)val;
1659 	}
1660 	return (val);
1661 }
1662 
1663 int
1664 uaudio_value2bsd(struct mixerctl *mc, int val)
1665 {
1666 	DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
1667 		     mc->type, val, mc->minval, mc->maxval));
1668 	if (mc->type == MIX_ON_OFF)
1669 		val = (val != 0);
1670 	else
1671 		val = ((uaudio_signext(mc->type, val) - mc->minval) * 255
1672 			+ mc->mul/2) / mc->mul;
1673 	DPRINTFN(5, ("val'=%d\n", val));
1674 	return (val);
1675 }
1676 
1677 int
1678 uaudio_bsd2value(struct mixerctl *mc, int val)
1679 {
1680 	DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
1681 		    mc->type, val, mc->minval, mc->maxval));
1682 	if (mc->type == MIX_ON_OFF)
1683 		val = (val != 0);
1684 	else
1685 		val = (val + mc->delta/2) * mc->mul / 255 + mc->minval;
1686 	DPRINTFN(5, ("val'=%d\n", val));
1687 	return (val);
1688 }
1689 
1690 int
1691 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
1692 	       int chan)
1693 {
1694 	int val;
1695 
1696 	DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan));
1697 	val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
1698 			 mc->wIndex, MIX_SIZE(mc->type));
1699 	return (uaudio_value2bsd(mc, val));
1700 }
1701 
1702 void
1703 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
1704 	       int chan, int val)
1705 {
1706 	val = uaudio_bsd2value(mc, val);
1707 	uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
1708 		   mc->wIndex, MIX_SIZE(mc->type), val);
1709 }
1710 
1711 int
1712 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
1713 {
1714 	struct uaudio_softc *sc = addr;
1715 	struct mixerctl *mc;
1716 	int i, n, vals[MIX_MAX_CHAN], val;
1717 
1718 	DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev));
1719 
1720 	if (sc->sc_dying)
1721 		return (EIO);
1722 
1723 	n = cp->dev - UAC_NCLASSES;
1724 	if (n < 0 || n >= sc->sc_nctls)
1725 		return (ENXIO);
1726 	mc = &sc->sc_ctls[n];
1727 
1728 	if (mc->type == MIX_ON_OFF) {
1729 		if (cp->type != AUDIO_MIXER_ENUM)
1730 			return (EINVAL);
1731 		cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
1732 	} else {
1733 		if (cp->type != AUDIO_MIXER_VALUE)
1734 			return (EINVAL);
1735 		if (cp->un.value.num_channels != 1 &&
1736 		    cp->un.value.num_channels != mc->nchan)
1737 			return (EINVAL);
1738 		for (i = 0; i < mc->nchan; i++)
1739 			vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
1740 		if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
1741 			for (val = 0, i = 0; i < mc->nchan; i++)
1742 				val += vals[i];
1743 			vals[0] = val / mc->nchan;
1744 		}
1745 		for (i = 0; i < cp->un.value.num_channels; i++)
1746 			cp->un.value.level[i] = vals[i];
1747 	}
1748 
1749 	return (0);
1750 }
1751 
1752 int
1753 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
1754 {
1755 	struct uaudio_softc *sc = addr;
1756 	struct mixerctl *mc;
1757 	int i, n, vals[MIX_MAX_CHAN];
1758 
1759 	DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev));
1760 	if (sc->sc_dying)
1761 		return (EIO);
1762 
1763 	n = cp->dev - UAC_NCLASSES;
1764 	if (n < 0 || n >= sc->sc_nctls)
1765 		return (ENXIO);
1766 	mc = &sc->sc_ctls[n];
1767 
1768 	if (mc->type == MIX_ON_OFF) {
1769 		if (cp->type != AUDIO_MIXER_ENUM)
1770 			return (EINVAL);
1771 		uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
1772 	} else {
1773 		if (cp->type != AUDIO_MIXER_VALUE)
1774 			return (EINVAL);
1775 		if (cp->un.value.num_channels == 1)
1776 			for (i = 0; i < mc->nchan; i++)
1777 				vals[i] = cp->un.value.level[0];
1778 		else if (cp->un.value.num_channels == mc->nchan)
1779 			for (i = 0; i < mc->nchan; i++)
1780 				vals[i] = cp->un.value.level[i];
1781 		else
1782 			return (EINVAL);
1783 		for (i = 0; i < mc->nchan; i++)
1784 			uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
1785 	}
1786 	return (0);
1787 }
1788 
1789 int
1790 uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
1791 		     void (*intr)(void *), void *arg,
1792 		     struct audio_params *param)
1793 {
1794 	struct uaudio_softc *sc = addr;
1795 	struct chan *ch = &sc->sc_recchan;
1796 	usbd_status err;
1797 	int i, s;
1798 
1799 	if (sc->sc_dying)
1800 		return (EIO);
1801 
1802 	DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
1803 		    "blksize=%d\n", sc, start, end, blksize));
1804 
1805 	uaudio_chan_set_param(ch, start, end, blksize);
1806 	DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
1807 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
1808 		    ch->fraction));
1809 
1810 	err = uaudio_chan_alloc_buffers(sc, ch);
1811 	if (err)
1812 		return (EIO);
1813 
1814 	err = uaudio_chan_open(sc, ch);
1815 	if (err) {
1816 		uaudio_chan_free_buffers(sc, ch);
1817 		return (EIO);
1818 	}
1819 
1820 	ch->intr = intr;
1821 	ch->arg = arg;
1822 
1823 	s = splusb();
1824 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
1825 		uaudio_chan_rtransfer(ch);
1826 	splx(s);
1827 
1828 	return (0);
1829 }
1830 
1831 int
1832 uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
1833 		      void (*intr)(void *), void *arg,
1834 		      struct audio_params *param)
1835 {
1836 	struct uaudio_softc *sc = addr;
1837 	struct chan *ch = &sc->sc_playchan;
1838 	usbd_status err;
1839 	int i, s;
1840 
1841 	if (sc->sc_dying)
1842 		return (EIO);
1843 
1844 	DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
1845 		    "blksize=%d\n", sc, start, end, blksize));
1846 
1847 	uaudio_chan_set_param(ch, start, end, blksize);
1848 	DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
1849 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
1850 		    ch->fraction));
1851 
1852 	err = uaudio_chan_alloc_buffers(sc, ch);
1853 	if (err)
1854 		return (EIO);
1855 
1856 	err = uaudio_chan_open(sc, ch);
1857 	if (err) {
1858 		uaudio_chan_free_buffers(sc, ch);
1859 		return (EIO);
1860 	}
1861 
1862 	ch->intr = intr;
1863 	ch->arg = arg;
1864 
1865 	s = splusb();
1866 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
1867 		uaudio_chan_ptransfer(ch);
1868 	splx(s);
1869 
1870 	return (0);
1871 }
1872 
1873 /* Set up a pipe for a channel. */
1874 usbd_status
1875 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
1876 {
1877 	struct as_info *as = &sc->sc_alts[ch->altidx];
1878 	int endpt = as->edesc->bEndpointAddress;
1879 	usbd_status err;
1880 
1881 	DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n",
1882 		 endpt, ch->sample_rate, as->alt));
1883 
1884 	/* Set alternate interface corresponding to the mode. */
1885 	err = usbd_set_interface(as->ifaceh, as->alt);
1886 	if (err)
1887 		return (err);
1888 
1889 	/* Some devices do not support this request, so ignore errors. */
1890 #ifdef UAUDIO_DEBUG
1891 	err = uaudio_set_speed(sc, endpt, ch->sample_rate);
1892 	if (err)
1893 		DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
1894 			 usbd_errstr(err)));
1895 #else
1896 	(void)uaudio_set_speed(sc, endpt, ch->sample_rate);
1897 #endif
1898 
1899 	DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt));
1900 	err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
1901 	return (err);
1902 }
1903 
1904 void
1905 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
1906 {
1907 	struct as_info *as = &sc->sc_alts[ch->altidx];
1908 
1909 	as->sc_busy = 0;
1910 	if (sc->sc_nullalt >= 0) {
1911 		DPRINTF(("uaudio_chan_close: set null alt=%d\n",
1912 			 sc->sc_nullalt));
1913 		usbd_set_interface(as->ifaceh, sc->sc_nullalt);
1914 	}
1915 	usbd_abort_pipe(ch->pipe);
1916 	usbd_close_pipe(ch->pipe);
1917 }
1918 
1919 usbd_status
1920 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
1921 {
1922 	usbd_xfer_handle xfer;
1923 	void *buf;
1924 	int i, size;
1925 
1926 	size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
1927 	for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
1928 		xfer = usbd_alloc_xfer(sc->sc_udev);
1929 		if (xfer == 0)
1930 			goto bad;
1931 		ch->chanbufs[i].xfer = xfer;
1932 		buf = usbd_alloc_buffer(xfer, size);
1933 		if (buf == 0) {
1934 			i++;
1935 			goto bad;
1936 		}
1937 		ch->chanbufs[i].buffer = buf;
1938 		ch->chanbufs[i].chan = ch;
1939 	}
1940 
1941 	return (USBD_NORMAL_COMPLETION);
1942 
1943 bad:
1944 	while (--i >= 0)
1945 		/* implicit buffer free */
1946 		usbd_free_xfer(ch->chanbufs[i].xfer);
1947 	return (USBD_NOMEM);
1948 }
1949 
1950 void
1951 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
1952 {
1953 	int i;
1954 
1955 	for (i = 0; i < UAUDIO_NCHANBUFS; i++)
1956 		usbd_free_xfer(ch->chanbufs[i].xfer);
1957 }
1958 
1959 /* Called at splusb() */
1960 void
1961 uaudio_chan_ptransfer(struct chan *ch)
1962 {
1963 	struct chanbuf *cb;
1964 	int i, n, size, residue, total;
1965 
1966 	if (ch->sc->sc_dying)
1967 		return;
1968 
1969 	/* Pick the next channel buffer. */
1970 	cb = &ch->chanbufs[ch->curchanbuf];
1971 	if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
1972 		ch->curchanbuf = 0;
1973 
1974 	/* Compute the size of each frame in the next transfer. */
1975 	residue = ch->residue;
1976 	total = 0;
1977 	for (i = 0; i < UAUDIO_NFRAMES; i++) {
1978 		size = ch->bytes_per_frame;
1979 		residue += ch->fraction;
1980 		if (residue >= USB_FRAMES_PER_SECOND) {
1981 			if ((ch->sc->sc_altflags & UA_NOFRAC) == 0)
1982 				size += ch->sample_size;
1983 			residue -= USB_FRAMES_PER_SECOND;
1984 		}
1985 		cb->sizes[i] = size;
1986 		total += size;
1987 	}
1988 	ch->residue = residue;
1989 	cb->size = total;
1990 
1991 	/*
1992 	 * Transfer data from upper layer buffer to channel buffer, taking
1993 	 * care of wrapping the upper layer buffer.
1994 	 */
1995 	n = min(total, ch->end - ch->cur);
1996 	memcpy(cb->buffer, ch->cur, n);
1997 	ch->cur += n;
1998 	if (ch->cur >= ch->end)
1999 		ch->cur = ch->start;
2000 	if (total > n) {
2001 		total -= n;
2002 		memcpy(cb->buffer + n, ch->cur, total);
2003 		ch->cur += total;
2004 	}
2005 
2006 #ifdef UAUDIO_DEBUG
2007 	if (uaudiodebug > 8) {
2008 		DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
2009 			 cb->buffer, ch->residue));
2010 		for (i = 0; i < UAUDIO_NFRAMES; i++) {
2011 			DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
2012 		}
2013 	}
2014 #endif
2015 
2016 	DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
2017 	/* Fill the request */
2018 	usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
2019 			     UAUDIO_NFRAMES, USBD_NO_COPY,
2020 			     uaudio_chan_pintr);
2021 
2022 	(void)usbd_transfer(cb->xfer);
2023 }
2024 
2025 void
2026 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
2027 		  usbd_status status)
2028 {
2029 	struct chanbuf *cb = priv;
2030 	struct chan *ch = cb->chan;
2031 	u_int32_t count;
2032 	int s;
2033 
2034 	/* Return if we are aborting. */
2035 	if (status == USBD_CANCELLED)
2036 		return;
2037 
2038 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2039 	DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
2040 		    count, ch->transferred));
2041 #ifdef DIAGNOSTIC
2042 	if (count != cb->size) {
2043 		printf("uaudio_chan_pintr: count(%d) != size(%d)\n",
2044 		       count, cb->size);
2045 	}
2046 #endif
2047 
2048 	ch->transferred += cb->size;
2049 	s = splaudio();
2050 	/* Call back to upper layer */
2051 	while (ch->transferred >= ch->blksize) {
2052 		ch->transferred -= ch->blksize;
2053 		DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n",
2054 			    ch->intr, ch->arg));
2055 		ch->intr(ch->arg);
2056 	}
2057 	splx(s);
2058 
2059 	/* start next transfer */
2060 	uaudio_chan_ptransfer(ch);
2061 }
2062 
2063 /* Called at splusb() */
2064 void
2065 uaudio_chan_rtransfer(struct chan *ch)
2066 {
2067 	struct chanbuf *cb;
2068 	int i, size, residue, total;
2069 
2070 	if (ch->sc->sc_dying)
2071 		return;
2072 
2073 	/* Pick the next channel buffer. */
2074 	cb = &ch->chanbufs[ch->curchanbuf];
2075 	if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2076 		ch->curchanbuf = 0;
2077 
2078 	/* Compute the size of each frame in the next transfer. */
2079 	residue = ch->residue;
2080 	total = 0;
2081 	for (i = 0; i < UAUDIO_NFRAMES; i++) {
2082 		size = ch->bytes_per_frame;
2083 		cb->sizes[i] = size;
2084 		cb->offsets[i] = total;
2085 		total += size;
2086 	}
2087 	ch->residue = residue;
2088 	cb->size = total;
2089 
2090 #ifdef UAUDIO_DEBUG
2091 	if (uaudiodebug > 8) {
2092 		DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
2093 			 cb->buffer, ch->residue));
2094 		for (i = 0; i < UAUDIO_NFRAMES; i++) {
2095 			DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
2096 		}
2097 	}
2098 #endif
2099 
2100 	DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
2101 	/* Fill the request */
2102 	usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
2103 			     UAUDIO_NFRAMES, USBD_NO_COPY,
2104 			     uaudio_chan_rintr);
2105 
2106 	(void)usbd_transfer(cb->xfer);
2107 }
2108 
2109 void
2110 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
2111 		  usbd_status status)
2112 {
2113 	struct chanbuf *cb = priv;
2114 	struct chan *ch = cb->chan;
2115 	u_int32_t count;
2116 	int s, i, n, frsize;
2117 
2118 	/* Return if we are aborting. */
2119 	if (status == USBD_CANCELLED)
2120 		return;
2121 
2122 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2123 	DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
2124 		    count, ch->transferred));
2125 
2126 	/* count < cb->size is normal for asynchronous source */
2127 #ifdef DIAGNOSTIC
2128 	if (count > cb->size) {
2129 		printf("uaudio_chan_rintr: count(%d) > size(%d)\n",
2130 		       count, cb->size);
2131 	}
2132 #endif
2133 
2134 	/*
2135 	 * Transfer data from channel buffer to upper layer buffer, taking
2136 	 * care of wrapping the upper layer buffer.
2137 	 */
2138 	for(i = 0; i < UAUDIO_NFRAMES; i++) {
2139 		frsize = cb->sizes[i];
2140 		n = min(frsize, ch->end - ch->cur);
2141 		memcpy(ch->cur, cb->buffer + cb->offsets[i], n);
2142 		ch->cur += n;
2143 		if (ch->cur >= ch->end)
2144 			ch->cur = ch->start;
2145 		if (frsize > n) {
2146 			memcpy(ch->cur, cb->buffer + cb->offsets[i] + n,
2147 			    frsize - n);
2148 			ch->cur += frsize - n;
2149 		}
2150 	}
2151 
2152 	/* Call back to upper layer */
2153 	ch->transferred += count;
2154 	s = splaudio();
2155 	while (ch->transferred >= ch->blksize) {
2156 		ch->transferred -= ch->blksize;
2157 		DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n",
2158 			    ch->intr, ch->arg));
2159 		ch->intr(ch->arg);
2160 	}
2161 	splx(s);
2162 
2163 	/* start next transfer */
2164 	uaudio_chan_rtransfer(ch);
2165 }
2166 
2167 void
2168 uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param,
2169     int maxpktsize)
2170 {
2171 	int samples_per_frame, sample_size;
2172 
2173 	ch->altidx = altidx;
2174 	sample_size = param->precision * param->factor * param->hw_channels / 8;
2175 	samples_per_frame = param->hw_sample_rate / USB_FRAMES_PER_SECOND;
2176 	ch->sample_size = sample_size;
2177 	ch->sample_rate = param->hw_sample_rate;
2178 	if (maxpktsize == 0) {
2179 		ch->fraction = param->hw_sample_rate % USB_FRAMES_PER_SECOND;
2180 		ch->bytes_per_frame = samples_per_frame * sample_size;
2181 	} else {
2182 		ch->fraction = 0;
2183 		ch->bytes_per_frame = maxpktsize;
2184 	}
2185 	ch->residue = 0;
2186 }
2187 
2188 void
2189 uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize)
2190 {
2191 	ch->start = start;
2192 	ch->end = end;
2193 	ch->cur = start;
2194 	ch->blksize = blksize;
2195 	ch->transferred = 0;
2196 
2197 	ch->curchanbuf = 0;
2198 }
2199 
2200 void
2201 uaudio_get_minmax_rates(int nalts, const struct as_info *alts,
2202 			const struct audio_params *p, int mode,
2203 			u_long *min, u_long *max)
2204 {
2205 	int i, j;
2206 	struct usb_audio_streaming_type1_descriptor *a1d;
2207 
2208 	*min = ULONG_MAX;
2209 	*max = 0;
2210 	for (i = 0; i < nalts; i++) {
2211 		a1d = alts[i].asf1desc;
2212 		if (alts[i].sc_busy)
2213 			continue;
2214 		if (p->hw_channels != a1d->bNrChannels)
2215 			continue;
2216 		if (p->hw_precision != a1d->bBitResolution)
2217 			continue;
2218 		if (p->hw_encoding != alts[i].encoding)
2219 			continue;
2220 		if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
2221 			continue;
2222 		if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2223 			DPRINTFN(2,("uaudio_get_minmax_rates: cont %d-%d\n",
2224 				    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
2225 			if (UA_SAMP_LO(a1d) < *min)
2226 				*min = UA_SAMP_LO(a1d);
2227 			if (UA_SAMP_HI(a1d) > *max)
2228 				*max = UA_SAMP_HI(a1d);
2229 		} else {
2230 			for (j = 0; j < a1d->bSamFreqType; j++) {
2231 				DPRINTFN(2,("uaudio_get_minmax_rates: disc #%d: %d\n",
2232 					    j, UA_GETSAMP(a1d, j)));
2233 				if (UA_GETSAMP(a1d, j) < *min)
2234 					*min = UA_GETSAMP(a1d, j);
2235 				if (UA_GETSAMP(a1d, j) > *max)
2236 					*max = UA_GETSAMP(a1d, j);
2237 			}
2238 		}
2239 	}
2240 }
2241 
2242 int
2243 uaudio_match_alt_sub(int nalts, const struct as_info *alts,
2244 		     const struct audio_params *p, int mode, u_long rate)
2245 {
2246 	int i, j;
2247 	struct usb_audio_streaming_type1_descriptor *a1d;
2248 
2249 	DPRINTF(("uaudio_match_alt_sub: search for %luHz %dch\n",
2250 		 rate, p->hw_channels));
2251 	for (i = 0; i < nalts; i++) {
2252 		a1d = alts[i].asf1desc;
2253 		if (alts[i].sc_busy)
2254 			continue;
2255 		if (p->hw_channels != a1d->bNrChannels)
2256 			continue;
2257 		if (p->hw_precision != a1d->bBitResolution)
2258 			continue;
2259 		if (p->hw_encoding != alts[i].encoding)
2260 			continue;
2261 		if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
2262 			continue;
2263 		if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2264 			DPRINTFN(2,("uaudio_match_alt_sub: cont %d-%d\n",
2265 				    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
2266 			if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d))
2267 				return i;
2268 		} else {
2269 			for (j = 0; j < a1d->bSamFreqType; j++) {
2270 				DPRINTFN(2,("uaudio_match_alt_sub: disc #%d: %d\n",
2271 					    j, UA_GETSAMP(a1d, j)));
2272 				/* XXX allow for some slack */
2273 				if (UA_GETSAMP(a1d, j) == rate)
2274 					return i;
2275 			}
2276 		}
2277 	}
2278 	return -1;
2279 }
2280 
2281 int
2282 uaudio_match_alt_chan(int nalts, const struct as_info *alts,
2283 		      struct audio_params *p, int mode)
2284 {
2285 	int i, n;
2286 	u_long min, max;
2287 	u_long rate;
2288 
2289 	/* Exact match */
2290 	DPRINTF(("uaudio_match_alt_chan: examine %ldHz %dch %dbit.\n",
2291 		 p->sample_rate, p->hw_channels, p->hw_precision));
2292 	i = uaudio_match_alt_sub(nalts, alts, p, mode, p->sample_rate);
2293 	if (i >= 0)
2294 		return i;
2295 
2296 	uaudio_get_minmax_rates(nalts, alts, p, mode, &min, &max);
2297 	DPRINTF(("uaudio_match_alt_chan: min=%lu max=%lu\n", min, max));
2298 	if (max <= 0)
2299 		return -1;
2300 	/* Search for biggers */
2301 	n = 2;
2302 	while ((rate = p->sample_rate * n++) <= max) {
2303 		i = uaudio_match_alt_sub(nalts, alts, p, mode, rate);
2304 		if (i >= 0) {
2305 			p->hw_sample_rate = rate;
2306 			return i;
2307 		}
2308 	}
2309 	if (p->sample_rate >= min) {
2310 		i = uaudio_match_alt_sub(nalts, alts, p, mode, max);
2311 		if (i >= 0) {
2312 			p->hw_sample_rate = max;
2313 			return i;
2314 		}
2315 	} else {
2316 		i = uaudio_match_alt_sub(nalts, alts, p, mode, min);
2317 		if (i >= 0) {
2318 			p->hw_sample_rate = min;
2319 			return i;
2320 		}
2321 	}
2322 	return -1;
2323 }
2324 
2325 int
2326 uaudio_match_alt(int nalts, const struct as_info *alts,
2327 		 struct audio_params *p, int mode)
2328 {
2329 	int i, n;
2330 
2331 	mode = mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN;
2332 	i = uaudio_match_alt_chan(nalts, alts, p, mode);
2333 	if (i >= 0)
2334 		return i;
2335 
2336 	for (n = p->channels + 1; n <= AUDIO_MAX_CHANNELS; n++) {
2337 		p->hw_channels = n;
2338 		i = uaudio_match_alt_chan(nalts, alts, p, mode);
2339 		if (i >= 0)
2340 			return i;
2341 	}
2342 
2343 	if (p->channels != 2)
2344 		return -1;
2345 	p->hw_channels = 1;
2346 	return uaudio_match_alt_chan(nalts, alts, p, mode);
2347 }
2348 
2349 int
2350 uaudio_set_params(void *addr, int setmode, int usemode,
2351 		  struct audio_params *play, struct audio_params *rec)
2352 {
2353 	struct uaudio_softc *sc = addr;
2354 	int flags = sc->sc_altflags;
2355 	int factor;
2356 	int enc, i;
2357 	int paltidx=-1, raltidx=-1;
2358 	void (*swcode)(void *, u_char *buf, int cnt);
2359 	struct audio_params *p;
2360 	int mode;
2361 
2362 	if (sc->sc_dying)
2363 		return (EIO);
2364 
2365 	if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) ||
2366 	    ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL))
2367 		return (EBUSY);
2368 
2369 	if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
2370 		sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0;
2371 	if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
2372 		sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0;
2373 
2374 	/* Some uaudio devices are unidirectional.  Don't try to find a
2375 	   matching mode for the unsupported direction. */
2376 	setmode &= sc->sc_mode;
2377 
2378 	for (mode = AUMODE_RECORD; mode != -1;
2379 	     mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
2380 		if ((setmode & mode) == 0)
2381 			continue;
2382 
2383 		p = (mode == AUMODE_PLAY) ? play : rec;
2384 
2385 		factor = 1;
2386 		swcode = 0;
2387 		enc = p->encoding;
2388 		switch (enc) {
2389 		case AUDIO_ENCODING_SLINEAR_BE:
2390 			/* FALLTHROUGH */
2391 		case AUDIO_ENCODING_SLINEAR_LE:
2392 			if (enc == AUDIO_ENCODING_SLINEAR_BE
2393 			    && p->precision == 16 && (flags & HAS_16)) {
2394 				swcode = swap_bytes;
2395 				enc = AUDIO_ENCODING_SLINEAR_LE;
2396 			} else if (p->precision == 8) {
2397 				if (flags & HAS_8) {
2398 					/* No conversion */
2399 				} else if (flags & HAS_8U) {
2400 					swcode = change_sign8;
2401 					enc = AUDIO_ENCODING_ULINEAR_LE;
2402 				} else if (flags & HAS_16) {
2403 					factor = 2;
2404 					p->hw_precision = 16;
2405 					if (mode == AUMODE_PLAY)
2406 						swcode = linear8_to_linear16_le;
2407 					else
2408 						swcode = linear16_to_linear8_le;
2409 				}
2410 			}
2411 			break;
2412 		case AUDIO_ENCODING_ULINEAR_BE:
2413 			/* FALLTHROUGH */
2414 		case AUDIO_ENCODING_ULINEAR_LE:
2415 			if (p->precision == 16) {
2416 				if (enc == AUDIO_ENCODING_ULINEAR_LE)
2417 					swcode = change_sign16_le;
2418 				else if (mode == AUMODE_PLAY)
2419 					swcode = swap_bytes_change_sign16_le;
2420 				else
2421 					swcode = change_sign16_swap_bytes_le;
2422 				enc = AUDIO_ENCODING_SLINEAR_LE;
2423 			} else if (p->precision == 8) {
2424 				if (flags & HAS_8U) {
2425 					/* No conversion */
2426 				} else if (flags & HAS_8) {
2427 					swcode = change_sign8;
2428 					enc = AUDIO_ENCODING_SLINEAR_LE;
2429 				} else if (flags & HAS_16) {
2430 					factor = 2;
2431 					p->hw_precision = 16;
2432 					enc = AUDIO_ENCODING_SLINEAR_LE;
2433 					if (mode == AUMODE_PLAY)
2434 						swcode = ulinear8_to_slinear16_le;
2435 					else
2436 						swcode = slinear16_to_ulinear8_le;
2437 				}
2438 			}
2439 			break;
2440 		case AUDIO_ENCODING_ULAW:
2441 			if (flags & HAS_MULAW)
2442 				break;
2443 			if (flags & HAS_16) {
2444 				if (mode == AUMODE_PLAY)
2445 					swcode = mulaw_to_slinear16_le;
2446 				else
2447 					swcode = slinear16_to_mulaw_le;
2448 				factor = 2;
2449 				enc = AUDIO_ENCODING_SLINEAR_LE;
2450 				p->hw_precision = 16;
2451 			} else if (flags & HAS_8U) {
2452 				if (mode == AUMODE_PLAY)
2453 					swcode = mulaw_to_ulinear8;
2454 				else
2455 					swcode = ulinear8_to_mulaw;
2456 				enc = AUDIO_ENCODING_ULINEAR_LE;
2457 			} else if (flags & HAS_8) {
2458 				if (mode == AUMODE_PLAY)
2459 					swcode = mulaw_to_slinear8;
2460 				else
2461 					swcode = slinear8_to_mulaw;
2462 				enc = AUDIO_ENCODING_SLINEAR_LE;
2463 			} else
2464 				return (EINVAL);
2465 			break;
2466 		case AUDIO_ENCODING_ALAW:
2467 			if (flags & HAS_ALAW)
2468 				break;
2469 			if (mode == AUMODE_PLAY && (flags & HAS_16)) {
2470 				swcode = alaw_to_slinear16_le;
2471 				factor = 2;
2472 				enc = AUDIO_ENCODING_SLINEAR_LE;
2473 				p->hw_precision = 16;
2474 			} else if (flags & HAS_8U) {
2475 				if (mode == AUMODE_PLAY)
2476 					swcode = alaw_to_ulinear8;
2477 				else
2478 					swcode = ulinear8_to_alaw;
2479 				enc = AUDIO_ENCODING_ULINEAR_LE;
2480 			} else if (flags & HAS_8) {
2481 				if (mode == AUMODE_PLAY)
2482 					swcode = alaw_to_slinear8;
2483 				else
2484 					swcode = slinear8_to_alaw;
2485 				enc = AUDIO_ENCODING_SLINEAR_LE;
2486 			} else
2487 				return (EINVAL);
2488 			break;
2489 		default:
2490 			return (EINVAL);
2491 		}
2492 		/* XXX do some other conversions... */
2493 
2494 		DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n",
2495 			 p->channels, p->hw_precision, enc, p->sample_rate));
2496 
2497 		p->hw_encoding = enc;
2498 		i = uaudio_match_alt(sc->sc_nalts, sc->sc_alts, p, mode);
2499 		if (i < 0)
2500 			return (EINVAL);
2501 
2502 		p->sw_code = swcode;
2503 		p->factor  = factor;
2504 
2505 		if (mode == AUMODE_PLAY)
2506 			paltidx = i;
2507 		else
2508 			raltidx = i;
2509 	}
2510 
2511 	if ((setmode & AUMODE_PLAY)) {
2512 		/* XXX abort transfer if currently happening? */
2513 		uaudio_chan_init(&sc->sc_playchan, paltidx, play, 0);
2514 	}
2515 	if ((setmode & AUMODE_RECORD)) {
2516 		/* XXX abort transfer if currently happening? */
2517 		uaudio_chan_init(&sc->sc_recchan, raltidx, rec,
2518 		    UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize));
2519 	}
2520 
2521 	if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
2522 		sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1;
2523 	if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
2524 		sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1;
2525 
2526 	DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n",
2527 		 sc->sc_playchan.altidx, sc->sc_recchan.altidx,
2528 		 (sc->sc_playchan.altidx >= 0)
2529 		   ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting
2530 		   : -1,
2531 		 (sc->sc_recchan.altidx >= 0)
2532 		   ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting
2533 		   : -1));
2534 
2535 	return (0);
2536 }
2537 
2538 usbd_status
2539 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
2540 {
2541 	usb_device_request_t req;
2542 	u_int8_t data[3];
2543 
2544 	DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
2545 	req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
2546 	req.bRequest = SET_CUR;
2547 	USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
2548 	USETW(req.wIndex, endpt);
2549 	USETW(req.wLength, 3);
2550 	data[0] = speed;
2551 	data[1] = speed >> 8;
2552 	data[2] = speed >> 16;
2553 
2554 	return (usbd_do_request(sc->sc_udev, &req, data));
2555 }
2556