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