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