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 /* $DragonFly: src/sys/dev/sound/usb/uaudio.c,v 1.19 2008/01/05 14:02:38 swildner Exp $: */
6 * Copyright (c) 1999 The NetBSD Foundation, Inc.
9 * This code is derived from software contributed to The NetBSD Foundation
10 * by Lennart Augustsson (lennart@augustsson.net) at
11 * Carlstedt Research & Technology.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by the NetBSD
24 * Foundation, Inc. and its contributors.
25 * 4. Neither the name of The NetBSD Foundation nor the names of its
26 * contributors may be used to endorse or promote products derived
27 * from this software without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
30 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
33 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
43 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
44 * http://www.usb.org/developers/devclass_docs/frmts10.pdf
45 * http://www.usb.org/developers/devclass_docs/termt10.pdf
48 #include <sys/cdefs.h>
52 * $NetBSD: uaudio.c,v 1.94 2005/01/15 15:19:53 kent Exp $
53 * $NetBSD: uaudio.c,v 1.95 2005/01/16 06:02:19 dsainty Exp $
54 * $NetBSD: uaudio.c,v 1.96 2005/01/16 12:46:00 kent Exp $
55 * $NetBSD: uaudio.c,v 1.97 2005/02/24 08:19:38 martin Exp $
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/kernel.h>
61 #include <sys/malloc.h>
64 #include <sys/reboot.h> /* for bootverbose */
65 #include <sys/select.h>
67 #include <sys/module.h>
71 #include <sys/sysctl.h>
72 #include <sys/thread2.h>
74 #include <dev/sound/pcm/sound.h> /* XXXXX */
75 #include <dev/sound/chip.h>
76 #include "feeder_if.h"
78 #include <bus/usb/usb.h>
79 #include <bus/usb/usbdi.h>
80 #include <bus/usb/usbdi_util.h>
81 #include <bus/usb/usb_quirks.h>
83 #include <dev/sound/usb/uaudioreg.h>
84 #include <dev/sound/usb/uaudio.h>
86 /* #define USB_DEBUG */
87 /* #define UAUDIO_MULTIPLE_ENDPOINTS */
89 #define DPRINTF(x) do { if (uaudiodebug) kprintf x; } while (0)
90 #define DPRINTFN(n,x) do { if (uaudiodebug>(n)) kprintf x; } while (0)
92 SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
93 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW,
94 &uaudiodebug, 0, "uaudio debug level");
100 #define UAUDIO_NCHANBUFS 6 /* number of outstanding request */
101 #define UAUDIO_NFRAMES 20 /* ms of sound in each request */
104 #define MIX_MAX_CHAN 8
106 uint16_t wValue[MIX_MAX_CHAN]; /* using nchan */
111 #define MIX_SIGNED_16 2
112 #define MIX_UNSIGNED_16 3
113 #define MIX_SIGNED_8 4
114 #define MIX_SELECTOR 5
115 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
116 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
121 #define MAX_SELECTOR_INPUT_PIN 256
122 uint8_t slctrtype[MAX_SELECTOR_INPUT_PIN];
125 #define MAKE(h,l) (((h) << 8) | (l))
130 uint8_t attributes; /* Copy of bmAttributes of
131 * usb_audio_streaming_endpoint_descriptor
133 usbd_interface_handle ifaceh;
134 const usb_interface_descriptor_t *idesc;
135 const usb_endpoint_descriptor_audio_t *edesc;
136 const usb_endpoint_descriptor_audio_t *edesc1;
137 const struct usb_audio_streaming_type1_descriptor *asf1desc;
138 int sc_busy; /* currently used */
142 struct pcm_channel *pcm_ch;
143 usbd_pipe_handle pipe;
144 usbd_pipe_handle sync_pipe;
148 u_int bytes_per_frame;
149 u_int fraction; /* fraction/1000 is the extra samples/frame */
150 u_int residue; /* accumulates the fractional samples */
152 u_char *start; /* upper layer buffer start */
153 u_char *end; /* upper layer buffer end */
154 u_char *cur; /* current position in upper layer buffer */
155 int blksize; /* chunk size to report up */
156 int transferred; /* transferred bytes not reported up */
158 int altidx; /* currently used altidx */
163 usbd_xfer_handle xfer;
165 u_int16_t sizes[UAUDIO_NFRAMES];
166 u_int16_t offsets[UAUDIO_NFRAMES];
168 } chanbufs[UAUDIO_NCHANBUFS];
170 struct uaudio_softc *sc; /* our softc */
176 struct uaudio_softc {
177 device_t sc_dev; /* base device */
178 usbd_device_handle sc_udev; /* USB device */
179 int sc_ac_iface; /* Audio Control interface */
180 usbd_interface_handle sc_ac_ifaceh;
181 struct chan sc_playchan; /* play channel */
182 struct chan sc_recchan; /* record channel */
185 struct as_info *sc_alts; /* alternate settings */
186 int sc_nalts; /* # of alternate settings */
191 #define HAS_ALAW 0x08
192 #define HAS_MULAW 0x10
193 #define UA_NOFRAC 0x20 /* don't do sample rate adjustment */
196 int sc_mode; /* play/record capability */
197 struct mixerctl *sc_ctls; /* mixer controls */
198 int sc_nctls; /* # of mixer controls */
199 device_t sc_audiodev;
201 struct sbuf uaudio_sndstat;
202 int uaudio_sndstat_flag;
205 struct terminal_list {
207 uint16_t terminals[1];
209 #define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \
210 + sizeof(uint16_t) * (N))
214 const usb_descriptor_t *desc;
215 const struct usb_audio_input_terminal *it;
216 const struct usb_audio_output_terminal *ot;
217 const struct usb_audio_mixer_unit *mu;
218 const struct usb_audio_selector_unit *su;
219 const struct usb_audio_feature_unit *fu;
220 const struct usb_audio_processing_unit *pu;
221 const struct usb_audio_extension_unit *eu;
224 struct terminal_list **inputs; /* list of source input terminals */
225 struct terminal_list *output; /* list of destination output terminals */
226 int direct; /* directly connected to an output terminal */
233 #define UAC_NCLASSES 4
235 #define AudioCinputs "inputs"
236 #define AudioCoutputs "outputs"
237 #define AudioCrecord "record"
238 #define AudioCequalization "equalization"
239 static const char *uac_names[] = {
240 AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
244 static usbd_status uaudio_identify_ac
245 (struct uaudio_softc *, const usb_config_descriptor_t *);
246 static usbd_status uaudio_identify_as
247 (struct uaudio_softc *, const usb_config_descriptor_t *);
248 static usbd_status uaudio_process_as
249 (struct uaudio_softc *, const char *, int *, int,
250 const usb_interface_descriptor_t *);
252 static void uaudio_add_alt(struct uaudio_softc *, const struct as_info *);
254 static const usb_interface_descriptor_t *uaudio_find_iface
255 (const char *, int, int *, int);
257 static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
260 static void uaudio_dump_cluster(const struct usb_audio_cluster *);
262 static struct usb_audio_cluster uaudio_get_cluster
263 (int, const struct io_terminal *);
264 static void uaudio_add_input
265 (struct uaudio_softc *, const struct io_terminal *, int);
266 static void uaudio_add_output
267 (struct uaudio_softc *, const struct io_terminal *, int);
268 static void uaudio_add_mixer
269 (struct uaudio_softc *, const struct io_terminal *, int);
270 static void uaudio_add_selector
271 (struct uaudio_softc *, const struct io_terminal *, int);
273 static const char *uaudio_get_terminal_name(int);
275 static int uaudio_determine_class
276 (const struct io_terminal *, struct mixerctl *);
277 static int uaudio_feature_name(const struct io_terminal *,
279 static void uaudio_add_feature
280 (struct uaudio_softc *, const struct io_terminal *, int);
281 static void uaudio_add_processing_updown
282 (struct uaudio_softc *, const struct io_terminal *, int);
283 static void uaudio_add_processing
284 (struct uaudio_softc *, const struct io_terminal *, int);
285 static void uaudio_add_extension
286 (struct uaudio_softc *, const struct io_terminal *, int);
287 static struct terminal_list *uaudio_merge_terminal_list
288 (const struct io_terminal *);
289 static struct terminal_list *uaudio_io_terminaltype
290 (int, struct io_terminal *, int);
291 static usbd_status uaudio_identify
292 (struct uaudio_softc *, const usb_config_descriptor_t *);
294 static int uaudio_signext(int, int);
295 static int uaudio_bsd2value(struct mixerctl *, int);
296 static int uaudio_get(struct uaudio_softc *, int, int, int, int, int);
297 static void uaudio_set
298 (struct uaudio_softc *, int, int, int, int, int, int);
299 static void uaudio_ctl_set
300 (struct uaudio_softc *, int, struct mixerctl *, int, int);
302 static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
304 static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
305 static void uaudio_chan_close(struct uaudio_softc *, struct chan *);
306 static usbd_status uaudio_chan_alloc_buffers
307 (struct uaudio_softc *, struct chan *);
308 static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
310 static void uaudio_chan_ptransfer(struct chan *);
311 static void uaudio_chan_pintr
312 (usbd_xfer_handle, usbd_private_handle, usbd_status);
314 static void uaudio_chan_rtransfer(struct chan *);
315 static void uaudio_chan_rintr
316 (usbd_xfer_handle, usbd_private_handle, usbd_status);
318 static int audio_attach_mi(device_t);
319 static int uaudio_init_params(struct uaudio_softc * sc, struct chan *ch, int mode);
320 static int uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose);
322 /* for NetBSD compatibility */
323 #define AUMODE_PLAY 0x01
324 #define AUMODE_RECORD 0x02
326 #define AUDIO_PROP_FULLDUPLEX 0x01
328 #define AUDIO_ENCODING_ULAW 1
329 #define AUDIO_ENCODING_ALAW 2
330 #define AUDIO_ENCODING_SLINEAR_LE 6
331 #define AUDIO_ENCODING_SLINEAR_BE 7
332 #define AUDIO_ENCODING_ULINEAR_LE 8
333 #define AUDIO_ENCODING_ULINEAR_BE 9
335 static device_probe_t uaudio_match;
336 static device_attach_t uaudio_attach;
337 static device_detach_t uaudio_detach;
339 static devclass_t uaudio_devclass;
341 static kobj_method_t uaudio_methods[] = {
342 DEVMETHOD(device_probe, uaudio_match),
343 DEVMETHOD(device_attach, uaudio_attach),
344 DEVMETHOD(device_detach, uaudio_detach),
345 DEVMETHOD(device_suspend, bus_generic_suspend),
346 DEVMETHOD(device_resume, bus_generic_resume),
347 DEVMETHOD(device_shutdown, bus_generic_shutdown),
348 DEVMETHOD(bus_print_child, bus_generic_print_child),
352 static driver_t uaudio_driver = {
355 sizeof(struct uaudio_softc)
358 MODULE_DEPEND(uaudio, usb, 1, 1, 1);
361 uaudio_match(device_t self)
363 struct usb_attach_arg *uaa = device_get_ivars(self);
364 usb_interface_descriptor_t *id;
366 if (uaa->iface == NULL)
369 id = usbd_get_interface_descriptor(uaa->iface);
370 /* Trigger on the control interface. */
372 id->bInterfaceClass != UICLASS_AUDIO ||
373 id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
374 (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
377 return UMATCH_IFACECLASS_IFACESUBCLASS;
381 uaudio_attach(device_t self)
383 struct uaudio_softc *sc = device_get_softc(self);
384 struct usb_attach_arg *uaa = device_get_ivars(self);
385 usb_interface_descriptor_t *id;
386 usb_config_descriptor_t *cdesc;
391 usbd_devinfo(uaa->device, 0, devinfo);
393 device_set_desc_copy(self, devinfo);
395 sc->sc_udev = uaa->device;
397 cdesc = usbd_get_config_descriptor(sc->sc_udev);
399 kprintf("%s: failed to get configuration descriptor\n",
400 device_get_nameunit(sc->sc_dev));
404 err = uaudio_identify(sc, cdesc);
406 kprintf("%s: audio descriptors make no sense, error=%d\n",
407 device_get_nameunit(sc->sc_dev), err);
411 sc->sc_ac_ifaceh = uaa->iface;
412 /* Pick up the AS interface. */
413 for (i = 0; i < uaa->nifaces; i++) {
414 if (uaa->ifaces[i] == NULL)
416 id = usbd_get_interface_descriptor(uaa->ifaces[i]);
420 for (j = 0; j < sc->sc_nalts; j++) {
421 if (id->bInterfaceNumber ==
422 sc->sc_alts[j].idesc->bInterfaceNumber) {
423 sc->sc_alts[j].ifaceh = uaa->ifaces[i];
428 uaa->ifaces[i] = NULL;
431 for (j = 0; j < sc->sc_nalts; j++) {
432 if (sc->sc_alts[j].ifaceh == NULL) {
433 kprintf("%s: alt %d missing AS interface(s)\n",
434 device_get_nameunit(sc->sc_dev), j);
439 kprintf("%s: audio rev %d.%02x\n", device_get_nameunit(sc->sc_dev),
440 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
442 sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
443 sc->sc_playchan.altidx = -1;
444 sc->sc_recchan.altidx = -1;
446 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
447 sc->sc_altflags |= UA_NOFRAC;
452 kprintf("%s: %d mixer controls\n", device_get_nameunit(sc->sc_dev),
455 DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
457 if (audio_attach_mi(sc->sc_dev)) {
458 kprintf("audio_attach_mi failed\n");
466 uaudio_detach(device_t self)
468 struct uaudio_softc *sc = device_get_softc(self);
470 sbuf_delete(&(sc->uaudio_sndstat));
471 sc->uaudio_sndstat_flag = 0;
476 /* Wait for outstanding requests to complete. */
477 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
481 return bus_generic_detach(sc->sc_dev);
484 static const usb_interface_descriptor_t *
485 uaudio_find_iface(const char *buf, int size, int *offsp, int subtype)
487 const usb_interface_descriptor_t *d;
489 while (*offsp < size) {
490 d = (const void *)(buf + *offsp);
491 *offsp += d->bLength;
492 if (d->bDescriptorType == UDESC_INTERFACE &&
493 d->bInterfaceClass == UICLASS_AUDIO &&
494 d->bInterfaceSubClass == subtype)
501 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
505 struct mixerctl *nmc;
507 if (mc->class < UAC_NCLASSES) {
508 DPRINTF(("%s: adding %s.%d\n",
509 __func__, uac_names[mc->class], mc->ctl));
511 DPRINTF(("%s: adding %d\n", __func__, mc->ctl));
514 len = sizeof(*mc) * (sc->sc_nctls + 1);
515 nmc = kmalloc(len, M_USBDEV, M_NOWAIT);
517 kprintf("uaudio_mixer_add_ctl: no memory\n");
520 /* Copy old data, if there was any */
521 if (sc->sc_nctls != 0) {
522 memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls));
523 kfree(sc->sc_ctls, M_USBDEV);
528 if (mc->type == MIX_ON_OFF) {
531 } else if (mc->type == MIX_SELECTOR) {
534 /* Determine min and max values. */
535 mc->minval = uaudio_signext(mc->type,
536 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
537 mc->wValue[0], mc->wIndex,
538 MIX_SIZE(mc->type)));
539 mc->maxval = 1 + uaudio_signext(mc->type,
540 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
541 mc->wValue[0], mc->wIndex,
542 MIX_SIZE(mc->type)));
543 mc->mul = mc->maxval - mc->minval;
546 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
547 mc->wValue[0], mc->wIndex,
550 mc->delta = (res * 255 + mc->mul/2) / mc->mul;
553 sc->sc_ctls[sc->sc_nctls++] = *mc;
556 if (uaudiodebug > 2) {
558 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
559 for (i = 1; i < mc->nchan; i++)
560 DPRINTF((",%04x", mc->wValue[i]));
561 DPRINTF((" wIndex=%04x type=%d ctl='%d' "
563 mc->wIndex, mc->type, mc->ctl,
564 mc->minval, mc->maxval));
571 uaudio_dump_cluster(const struct usb_audio_cluster *cl)
573 static const char *channel_names[16] = {
574 "LEFT", "RIGHT", "CENTER", "LFE",
575 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER",
576 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP",
577 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15",
581 cc = UGETW(cl->wChannelConfig);
582 kprintf("cluster: bNrChannels=%u wChannelConfig=0x%.4x",
583 cl->bNrChannels, cc);
585 for (i = 0; cc != 0; i++) {
587 kprintf("%c%s", first ? '<' : ',', channel_names[i]);
592 kprintf("> iChannelNames=%u", cl->iChannelNames);
596 static struct usb_audio_cluster
597 uaudio_get_cluster(int id, const struct io_terminal *iot)
599 struct usb_audio_cluster r;
600 const usb_descriptor_t *dp;
603 for (i = 0; i < 25; i++) { /* avoid infinite loops */
607 switch (dp->bDescriptorSubtype) {
608 case UDESCSUB_AC_INPUT:
609 r.bNrChannels = iot[id].d.it->bNrChannels;
610 USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig));
611 r.iChannelNames = iot[id].d.it->iChannelNames;
613 case UDESCSUB_AC_OUTPUT:
614 id = iot[id].d.ot->bSourceId;
616 case UDESCSUB_AC_MIXER:
617 r = *(const struct usb_audio_cluster *)
618 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
620 case UDESCSUB_AC_SELECTOR:
621 /* XXX This is not really right */
622 id = iot[id].d.su->baSourceId[0];
624 case UDESCSUB_AC_FEATURE:
625 id = iot[id].d.fu->bSourceId;
627 case UDESCSUB_AC_PROCESSING:
628 r = *(const struct usb_audio_cluster *)
629 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
631 case UDESCSUB_AC_EXTENSION:
632 r = *(const struct usb_audio_cluster *)
633 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
640 kprintf("uaudio_get_cluster: bad data\n");
641 memset(&r, 0, sizeof r);
647 uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
650 const struct usb_audio_input_terminal *d = iot[id].d.it;
652 DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
653 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
654 "iChannelNames=%d iTerminal=%d\n",
655 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
656 d->bNrChannels, UGETW(d->wChannelConfig),
657 d->iChannelNames, d->iTerminal));
662 uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
665 const struct usb_audio_output_terminal *d;
668 DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
669 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
670 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
671 d->bSourceId, d->iTerminal));
676 uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
678 const struct usb_audio_mixer_unit *d = iot[id].d.mu;
679 const struct usb_audio_mixer_unit_1 *d1;
680 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
684 DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
685 d->bUnitId, d->bNrInPins));
687 /* Compute the number of input channels */
689 for (i = 0; i < d->bNrInPins; i++)
690 ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
692 /* and the number of output channels */
693 d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
694 ochs = d1->bNrChannels;
695 DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
698 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
699 uaudio_determine_class(&iot[id], &mix);
700 mix.type = MIX_SIGNED_16;
702 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
703 for (p = i = 0; i < d->bNrInPins; i++) {
704 chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
706 for (c = 0; c < chs; c++) {
708 for (o = 0; o < ochs; o++) {
709 bno = (p + c) * ochs + o;
716 if (mc == chs && chs <= MIX_MAX_CHAN) {
718 for (c = 0; c < chs; c++)
719 for (o = 0; o < ochs; o++) {
720 bno = (p + c) * ochs + o;
727 uaudio_mixer_add_ctl(sc, &mix);
738 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
740 const struct usb_audio_selector_unit *d;
743 struct mixerctl dummy;
746 DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
747 d->bUnitId, d->bNrInPins));
748 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
749 mix.wValue[0] = MAKE(0, 0);
750 uaudio_determine_class(&iot[id], &mix);
752 mix.type = MIX_SELECTOR;
753 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
755 mix.maxval = d->bNrInPins;
756 mix.mul = mix.maxval - mix.minval;
757 for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) {
758 mix.slctrtype[i] = SOUND_MIXER_NRDEVICES;
760 for (i = mix.minval; i <= mix.maxval; i++) {
761 mix.slctrtype[i - 1] = uaudio_feature_name(&iot[d->baSourceId[i - 1]], &dummy);
764 uaudio_mixer_add_ctl(sc, &mix);
769 uaudio_get_terminal_name(int terminal_type)
771 static char buf[100];
773 switch (terminal_type) {
774 /* USB terminal types */
775 case UAT_UNDEFINED: return "UAT_UNDEFINED";
776 case UAT_STREAM: return "UAT_STREAM";
777 case UAT_VENDOR: return "UAT_VENDOR";
778 /* input terminal types */
779 case UATI_UNDEFINED: return "UATI_UNDEFINED";
780 case UATI_MICROPHONE: return "UATI_MICROPHONE";
781 case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE";
782 case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE";
783 case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE";
784 case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY";
785 case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR";
786 /* output terminal types */
787 case UATO_UNDEFINED: return "UATO_UNDEFINED";
788 case UATO_SPEAKER: return "UATO_SPEAKER";
789 case UATO_HEADPHONES: return "UATO_HEADPHONES";
790 case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO";
791 case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER";
792 case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER";
793 case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER";
794 case UATO_SUBWOOFER: return "UATO_SUBWOOFER";
795 /* bidir terminal types */
796 case UATB_UNDEFINED: return "UATB_UNDEFINED";
797 case UATB_HANDSET: return "UATB_HANDSET";
798 case UATB_HEADSET: return "UATB_HEADSET";
799 case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE";
800 case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP";
801 case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC";
802 /* telephony terminal types */
803 case UATT_UNDEFINED: return "UATT_UNDEFINED";
804 case UATT_PHONELINE: return "UATT_PHONELINE";
805 case UATT_TELEPHONE: return "UATT_TELEPHONE";
806 case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE";
807 /* external terminal types */
808 case UATE_UNDEFINED: return "UATE_UNDEFINED";
809 case UATE_ANALOGCONN: return "UATE_ANALOGCONN";
810 case UATE_LINECONN: return "UATE_LINECONN";
811 case UATE_LEGACYCONN: return "UATE_LEGACYCONN";
812 case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC";
813 case UATE_SPDIF: return "UATE_SPDIF";
814 case UATE_1394DA: return "UATE_1394DA";
815 case UATE_1394DV: return "UATE_1394DV";
816 /* embedded function terminal types */
817 case UATF_UNDEFINED: return "UATF_UNDEFINED";
818 case UATF_CALIBNOISE: return "UATF_CALIBNOISE";
819 case UATF_EQUNOISE: return "UATF_EQUNOISE";
820 case UATF_CDPLAYER: return "UATF_CDPLAYER";
821 case UATF_DAT: return "UATF_DAT";
822 case UATF_DCC: return "UATF_DCC";
823 case UATF_MINIDISK: return "UATF_MINIDISK";
824 case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE";
825 case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH";
826 case UATF_VCRAUDIO: return "UATF_VCRAUDIO";
827 case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO";
828 case UATF_DVDAUDIO: return "UATF_DVDAUDIO";
829 case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO";
830 case UATF_SATELLITE: return "UATF_SATELLITE";
831 case UATF_CABLETUNER: return "UATF_CABLETUNER";
832 case UATF_DSS: return "UATF_DSS";
833 case UATF_RADIORECV: return "UATF_RADIORECV";
834 case UATF_RADIOXMIT: return "UATF_RADIOXMIT";
835 case UATF_MULTITRACK: return "UATF_MULTITRACK";
836 case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER";
838 ksnprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type);
845 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
849 if (iot == NULL || iot->output == NULL) {
850 mix->class = UAC_OUTPUT;
854 if (iot->output->size == 1)
855 terminal_type = iot->output->terminals[0];
857 * If the only output terminal is USB,
858 * the class is UAC_RECORD.
860 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
861 mix->class = UAC_RECORD;
862 if (iot->inputs_size == 1
863 && iot->inputs[0] != NULL
864 && iot->inputs[0]->size == 1)
865 return iot->inputs[0]->terminals[0];
870 * If the ultimate destination of the unit is just one output
871 * terminal and the unit is connected to the output terminal
872 * directly, the class is UAC_OUTPUT.
874 if (terminal_type != 0 && iot->direct) {
875 mix->class = UAC_OUTPUT;
876 return terminal_type;
879 * If the unit is connected to just one input terminal,
880 * the class is UAC_INPUT.
882 if (iot->inputs_size == 1 && iot->inputs[0] != NULL
883 && iot->inputs[0]->size == 1) {
884 mix->class = UAC_INPUT;
885 return iot->inputs[0]->terminals[0];
888 * Otherwise, the class is UAC_OUTPUT.
890 mix->class = UAC_OUTPUT;
891 return terminal_type;
895 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
899 terminal_type = uaudio_determine_class(iot, mix);
900 if (mix->class == UAC_RECORD && terminal_type == 0)
901 return SOUND_MIXER_IMIX;
902 DPRINTF(("%s: terminal_type=%s\n", __func__,
903 uaudio_get_terminal_name(terminal_type)));
904 switch (terminal_type) {
906 return SOUND_MIXER_PCM;
908 case UATI_MICROPHONE:
909 case UATI_DESKMICROPHONE:
910 case UATI_PERSONALMICROPHONE:
911 case UATI_OMNIMICROPHONE:
912 case UATI_MICROPHONEARRAY:
913 case UATI_PROCMICROPHONEARR:
914 return SOUND_MIXER_MIC;
917 case UATO_DESKTOPSPEAKER:
918 case UATO_ROOMSPEAKER:
919 case UATO_COMMSPEAKER:
920 return SOUND_MIXER_SPEAKER;
922 case UATE_ANALOGCONN:
924 case UATE_LEGACYCONN:
925 return SOUND_MIXER_LINE;
927 case UATE_DIGITALAUIFC:
931 return SOUND_MIXER_ALTPCM;
934 return SOUND_MIXER_CD;
936 case UATF_SYNTHESIZER:
937 return SOUND_MIXER_SYNTH;
939 case UATF_VIDEODISCAUDIO:
941 case UATF_TVTUNERAUDIO:
942 return SOUND_MIXER_VIDEO;
944 /* telephony terminal types */
948 case UATT_DOWNLINEPHONE:
949 return SOUND_MIXER_PHONEIN;
950 /* return SOUND_MIXER_PHONEOUT;*/
954 return SOUND_MIXER_RADIO;
959 /* output terminal types */
961 case UATO_DISPLAYAUDIO:
963 case UATO_HEADPHONES:
964 /* bidir terminal types */
968 case UATB_SPEAKERPHONE:
969 case UATB_SPEAKERPHONEESUP:
970 case UATB_SPEAKERPHONEECANC:
971 /* external terminal types */
973 /* embedded function terminal types */
975 case UATF_CALIBNOISE:
980 case UATF_ANALOGTAPE:
981 case UATF_PHONOGRAPH:
984 case UATF_CABLETUNER:
986 case UATF_MULTITRACK:
989 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
990 return SOUND_MIXER_VOLUME;
992 return SOUND_MIXER_VOLUME;
996 uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
998 const struct usb_audio_feature_unit *d;
1002 u_int fumask, mmask, cmask;
1003 struct mixerctl mix;
1004 int chan, ctl, i, unit;
1007 #define GET(i) (ctls[(i)*ctlsize] | \
1008 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
1010 ctls = d->bmaControls;
1011 ctlsize = d->bControlSize;
1012 nchan = (d->bLength - 7) / ctlsize;
1014 /* Figure out what we can control */
1015 for (cmask = 0, chan = 1; chan < nchan; chan++) {
1016 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
1021 if (nchan > MIX_MAX_CHAN)
1022 nchan = MIX_MAX_CHAN;
1024 mix.wIndex = MAKE(unit, sc->sc_ac_iface);
1025 for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
1026 fumask = FU_MASK(ctl);
1027 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
1029 if (mmask & fumask) {
1031 mix.wValue[0] = MAKE(ctl, 0);
1032 } else if (cmask & fumask) {
1033 mix.nchan = nchan - 1;
1034 for (i = 1; i < nchan; i++) {
1035 if (GET(i) & fumask)
1036 mix.wValue[i-1] = MAKE(ctl, i);
1038 mix.wValue[i-1] = -1;
1045 mixernumber = uaudio_feature_name(&iot[id], &mix);
1049 mix.type = MIX_ON_OFF;
1050 mix.ctl = SOUND_MIXER_NRDEVICES;
1052 case VOLUME_CONTROL:
1053 mix.type = MIX_SIGNED_16;
1054 mix.ctl = mixernumber;
1057 mix.type = MIX_SIGNED_8;
1058 mix.ctl = SOUND_MIXER_BASS;
1061 mix.type = MIX_SIGNED_8;
1062 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1064 case TREBLE_CONTROL:
1065 mix.type = MIX_SIGNED_8;
1066 mix.ctl = SOUND_MIXER_TREBLE;
1068 case GRAPHIC_EQUALIZER_CONTROL:
1069 continue; /* XXX don't add anything */
1072 mix.type = MIX_ON_OFF;
1073 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1076 mix.type = MIX_UNSIGNED_16;
1077 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1079 case BASS_BOOST_CONTROL:
1080 mix.type = MIX_ON_OFF;
1081 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1083 case LOUDNESS_CONTROL:
1084 mix.type = MIX_ON_OFF;
1085 mix.ctl = SOUND_MIXER_LOUD; /* Is this correct ? */
1088 uaudio_mixer_add_ctl(sc, &mix);
1093 uaudio_add_processing_updown(struct uaudio_softc *sc,
1094 const struct io_terminal *iot, int id)
1096 const struct usb_audio_processing_unit *d;
1097 const struct usb_audio_processing_unit_1 *d1;
1098 const struct usb_audio_processing_unit_updown *ud;
1099 struct mixerctl mix;
1103 d1 = (const struct usb_audio_processing_unit_1 *)
1104 &d->baSourceId[d->bNrInPins];
1105 ud = (const struct usb_audio_processing_unit_updown *)
1106 &d1->bmControls[d1->bControlSize];
1107 DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
1108 d->bUnitId, ud->bNrModes));
1110 if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
1111 DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
1115 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1117 mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
1118 uaudio_determine_class(&iot[id], &mix);
1119 mix.type = MIX_ON_OFF; /* XXX */
1121 for (i = 0; i < ud->bNrModes; i++) {
1122 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
1123 i, UGETW(ud->waModes[i])));
1126 uaudio_mixer_add_ctl(sc, &mix);
1130 uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1132 const struct usb_audio_processing_unit *d;
1133 const struct usb_audio_processing_unit_1 *d1;
1135 struct mixerctl mix;
1138 d1 = (const struct usb_audio_processing_unit_1 *)
1139 &d->baSourceId[d->bNrInPins];
1140 ptype = UGETW(d->wProcessType);
1141 DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
1142 "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
1144 if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
1145 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1147 mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
1148 uaudio_determine_class(&iot[id], &mix);
1149 mix.type = MIX_ON_OFF;
1150 uaudio_mixer_add_ctl(sc, &mix);
1154 case UPDOWNMIX_PROCESS:
1155 uaudio_add_processing_updown(sc, iot, id);
1157 case DOLBY_PROLOGIC_PROCESS:
1158 case P3D_STEREO_EXTENDER_PROCESS:
1159 case REVERBATION_PROCESS:
1160 case CHORUS_PROCESS:
1161 case DYN_RANGE_COMP_PROCESS:
1164 kprintf("uaudio_add_processing: unit %d, type=%d not impl.\n",
1172 uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1174 const struct usb_audio_extension_unit *d;
1175 const struct usb_audio_extension_unit_1 *d1;
1176 struct mixerctl mix;
1179 d1 = (const struct usb_audio_extension_unit_1 *)
1180 &d->baSourceId[d->bNrInPins];
1181 DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
1182 d->bUnitId, d->bNrInPins));
1184 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
1187 if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
1188 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1190 mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
1191 uaudio_determine_class(&iot[id], &mix);
1192 mix.type = MIX_ON_OFF;
1193 uaudio_mixer_add_ctl(sc, &mix);
1197 static struct terminal_list*
1198 uaudio_merge_terminal_list(const struct io_terminal *iot)
1200 struct terminal_list *tml;
1205 if (iot->inputs == NULL)
1207 for (i = 0; i < iot->inputs_size; i++) {
1208 if (iot->inputs[i] != NULL)
1209 len += iot->inputs[i]->size;
1211 tml = kmalloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT);
1213 kprintf("uaudio_merge_terminal_list: no memory\n");
1217 ptm = tml->terminals;
1218 for (i = 0; i < iot->inputs_size; i++) {
1219 if (iot->inputs[i] == NULL)
1221 if (iot->inputs[i]->size > len)
1223 memcpy(ptm, iot->inputs[i]->terminals,
1224 iot->inputs[i]->size * sizeof(uint16_t));
1225 tml->size += iot->inputs[i]->size;
1226 ptm += iot->inputs[i]->size;
1227 len -= iot->inputs[i]->size;
1232 static struct terminal_list *
1233 uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id)
1235 struct terminal_list *tml;
1236 struct io_terminal *it;
1240 if (it->output != NULL) {
1241 /* already has outtype? */
1242 for (i = 0; i < it->output->size; i++)
1243 if (it->output->terminals[i] == outtype)
1244 return uaudio_merge_terminal_list(it);
1245 tml = kmalloc(TERMINAL_LIST_SIZE(it->output->size + 1),
1248 kprintf("uaudio_io_terminaltype: no memory\n");
1249 return uaudio_merge_terminal_list(it);
1251 memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size));
1252 tml->terminals[it->output->size] = outtype;
1254 kfree(it->output, M_TEMP);
1256 if (it->inputs != NULL) {
1257 for (i = 0; i < it->inputs_size; i++)
1258 if (it->inputs[i] != NULL)
1259 kfree(it->inputs[i], M_TEMP);
1260 kfree(it->inputs, M_TEMP);
1262 it->inputs_size = 0;
1264 } else { /* end `iot[id] != NULL' */
1265 it->inputs_size = 0;
1267 it->output = kmalloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1268 if (it->output == NULL) {
1269 kprintf("uaudio_io_terminaltype: no memory\n");
1272 it->output->terminals[0] = outtype;
1273 it->output->size = 1;
1277 switch (it->d.desc->bDescriptorSubtype) {
1278 case UDESCSUB_AC_INPUT:
1279 it->inputs = kmalloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1280 if (it->inputs == NULL) {
1281 kprintf("uaudio_io_terminaltype: no memory\n");
1284 tml = kmalloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1286 kprintf("uaudio_io_terminaltype: no memory\n");
1287 kfree(it->inputs, M_TEMP);
1291 it->inputs[0] = tml;
1292 tml->terminals[0] = UGETW(it->d.it->wTerminalType);
1294 it->inputs_size = 1;
1295 return uaudio_merge_terminal_list(it);
1296 case UDESCSUB_AC_FEATURE:
1297 src_id = it->d.fu->bSourceId;
1298 it->inputs = kmalloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1299 if (it->inputs == NULL) {
1300 kprintf("uaudio_io_terminaltype: no memory\n");
1301 return uaudio_io_terminaltype(outtype, iot, src_id);
1303 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1304 it->inputs_size = 1;
1305 return uaudio_merge_terminal_list(it);
1306 case UDESCSUB_AC_OUTPUT:
1307 it->inputs = kmalloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1308 if (it->inputs == NULL) {
1309 kprintf("uaudio_io_terminaltype: no memory\n");
1312 src_id = it->d.ot->bSourceId;
1313 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1314 it->inputs_size = 1;
1315 iot[src_id].direct = TRUE;
1317 case UDESCSUB_AC_MIXER:
1318 it->inputs_size = 0;
1319 it->inputs = kmalloc(sizeof(struct terminal_list *)
1320 * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT);
1321 if (it->inputs == NULL) {
1322 kprintf("uaudio_io_terminaltype: no memory\n");
1325 for (i = 0; i < it->d.mu->bNrInPins; i++) {
1326 src_id = it->d.mu->baSourceId[i];
1327 it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1331 return uaudio_merge_terminal_list(it);
1332 case UDESCSUB_AC_SELECTOR:
1333 it->inputs_size = 0;
1334 it->inputs = kmalloc(sizeof(struct terminal_list *)
1335 * it->d.su->bNrInPins, M_TEMP, M_NOWAIT);
1336 if (it->inputs == NULL) {
1337 kprintf("uaudio_io_terminaltype: no memory\n");
1340 for (i = 0; i < it->d.su->bNrInPins; i++) {
1341 src_id = it->d.su->baSourceId[i];
1342 it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1346 return uaudio_merge_terminal_list(it);
1347 case UDESCSUB_AC_PROCESSING:
1348 it->inputs_size = 0;
1349 it->inputs = kmalloc(sizeof(struct terminal_list *)
1350 * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT);
1351 if (it->inputs == NULL) {
1352 kprintf("uaudio_io_terminaltype: no memory\n");
1355 for (i = 0; i < it->d.pu->bNrInPins; i++) {
1356 src_id = it->d.pu->baSourceId[i];
1357 it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1361 return uaudio_merge_terminal_list(it);
1362 case UDESCSUB_AC_EXTENSION:
1363 it->inputs_size = 0;
1364 it->inputs = kmalloc(sizeof(struct terminal_list *)
1365 * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT);
1366 if (it->inputs == NULL) {
1367 kprintf("uaudio_io_terminaltype: no memory\n");
1370 for (i = 0; i < it->d.eu->bNrInPins; i++) {
1371 src_id = it->d.eu->baSourceId[i];
1372 it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1376 return uaudio_merge_terminal_list(it);
1377 case UDESCSUB_AC_HEADER:
1384 uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
1388 err = uaudio_identify_ac(sc, cdesc);
1391 return uaudio_identify_as(sc, cdesc);
1395 uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai)
1398 struct as_info *nai;
1400 len = sizeof(*ai) * (sc->sc_nalts + 1);
1401 nai = kmalloc(len, M_USBDEV, M_NOWAIT);
1403 kprintf("uaudio_add_alt: no memory\n");
1406 /* Copy old data, if there was any */
1407 if (sc->sc_nalts != 0) {
1408 memcpy(nai, sc->sc_alts, sizeof(*ai) * (sc->sc_nalts));
1409 kfree(sc->sc_alts, M_USBDEV);
1412 DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
1413 ai->alt, ai->encoding));
1414 sc->sc_alts[sc->sc_nalts++] = *ai;
1418 uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
1419 int size, const usb_interface_descriptor_t *id)
1420 #define offs (*offsp)
1422 const struct usb_audio_streaming_interface_descriptor *asid;
1423 const struct usb_audio_streaming_type1_descriptor *asf1d;
1424 const usb_endpoint_descriptor_audio_t *ed;
1425 const usb_endpoint_descriptor_audio_t *epdesc1;
1426 const struct usb_audio_streaming_endpoint_descriptor *sed;
1427 int format, chan, prec, enc;
1428 int dir, type, sync;
1430 const char *format_str;
1432 asid = (const void *)(buf + offs);
1434 if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
1435 asid->bDescriptorSubtype != AS_GENERAL)
1437 DPRINTF(("uaudio_process_as: asid: bTerminakLink=%d wFormatTag=%d\n",
1438 asid->bTerminalLink, UGETW(asid->wFormatTag)));
1439 offs += asid->bLength;
1443 asf1d = (const void *)(buf + offs);
1444 if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
1445 asf1d->bDescriptorSubtype != FORMAT_TYPE)
1447 offs += asf1d->bLength;
1451 if (asf1d->bFormatType != FORMAT_TYPE_I) {
1452 kprintf("%s: ignored setting with type %d format\n",
1453 device_get_nameunit(sc->sc_dev), UGETW(asid->wFormatTag));
1454 return USBD_NORMAL_COMPLETION;
1457 ed = (const void *)(buf + offs);
1458 if (ed->bDescriptorType != UDESC_ENDPOINT)
1460 DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
1461 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
1462 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
1463 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
1464 ed->bmAttributes, UGETW(ed->wMaxPacketSize),
1465 ed->bInterval, ed->bRefresh, ed->bSynchAddress));
1466 offs += ed->bLength;
1469 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
1472 dir = UE_GET_DIR(ed->bEndpointAddress);
1473 type = UE_GET_ISO_TYPE(ed->bmAttributes);
1474 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
1475 dir == UE_DIR_IN && type == UE_ISO_ADAPT)
1476 type = UE_ISO_ASYNC;
1478 /* We can't handle endpoints that need a sync pipe yet. */
1480 if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
1482 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1483 kprintf("%s: ignored input endpoint of type adaptive\n",
1484 device_get_nameunit(sc->sc_dev));
1485 return USBD_NORMAL_COMPLETION;
1488 if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
1490 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1491 kprintf("%s: ignored output endpoint of type async\n",
1492 device_get_nameunit(sc->sc_dev));
1493 return USBD_NORMAL_COMPLETION;
1497 sed = (const void *)(buf + offs);
1498 if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
1499 sed->bDescriptorSubtype != AS_GENERAL)
1501 DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength));
1502 offs += sed->bLength;
1506 if (sync && id->bNumEndpoints <= 1) {
1507 kprintf("%s: a sync-pipe endpoint but no other endpoint\n",
1508 device_get_nameunit(sc->sc_dev));
1511 if (!sync && id->bNumEndpoints > 1) {
1512 kprintf("%s: non sync-pipe endpoint but multiple endpoints\n",
1513 device_get_nameunit(sc->sc_dev));
1517 if (id->bNumEndpoints > 1) {
1518 epdesc1 = (const void*)(buf + offs);
1519 if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
1521 DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
1522 "bDescriptorType=%d bEndpointAddress=%d "
1523 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
1524 "bRefresh=%d bSynchAddress=%d\n",
1525 epdesc1->bLength, epdesc1->bDescriptorType,
1526 epdesc1->bEndpointAddress, epdesc1->bmAttributes,
1527 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
1528 epdesc1->bRefresh, epdesc1->bSynchAddress));
1529 offs += epdesc1->bLength;
1532 if (epdesc1->bSynchAddress != 0) {
1533 kprintf("%s: invalid endpoint: bSynchAddress=0\n",
1534 device_get_nameunit(sc->sc_dev));
1537 if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
1538 kprintf("%s: invalid endpoint: bmAttributes=0x%x\n",
1539 device_get_nameunit(sc->sc_dev), epdesc1->bmAttributes);
1542 if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
1543 kprintf("%s: invalid endpoint addresses: "
1544 "ep[0]->bSynchAddress=0x%x "
1545 "ep[1]->bEndpointAddress=0x%x\n",
1546 device_get_nameunit(sc->sc_dev), ed->bSynchAddress,
1547 epdesc1->bEndpointAddress);
1550 /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
1553 format = UGETW(asid->wFormatTag);
1554 chan = asf1d->bNrChannels;
1555 prec = asf1d->bBitResolution;
1556 if (prec != 8 && prec != 16 && prec != 24 && prec != 32) {
1557 kprintf("%s: ignored setting with precision %d\n",
1558 device_get_nameunit(sc->sc_dev), prec);
1559 return USBD_NORMAL_COMPLETION;
1564 sc->sc_altflags |= HAS_8;
1565 } else if (prec == 16) {
1566 sc->sc_altflags |= HAS_16;
1567 } else if (prec == 24) {
1568 sc->sc_altflags |= HAS_24;
1569 } else if (prec == 32) {
1570 sc->sc_altflags |= HAS_32;
1572 enc = AUDIO_ENCODING_SLINEAR_LE;
1576 enc = AUDIO_ENCODING_ULINEAR_LE;
1577 sc->sc_altflags |= HAS_8U;
1578 format_str = "pcm8";
1581 enc = AUDIO_ENCODING_ALAW;
1582 sc->sc_altflags |= HAS_ALAW;
1583 format_str = "alaw";
1586 enc = AUDIO_ENCODING_ULAW;
1587 sc->sc_altflags |= HAS_MULAW;
1588 format_str = "mulaw";
1590 case UA_FMT_IEEE_FLOAT:
1592 kprintf("%s: ignored setting with format %d\n",
1593 device_get_nameunit(sc->sc_dev), format);
1594 return USBD_NORMAL_COMPLETION;
1597 kprintf("%s: %s: %dch, %d/%dbit, %s,", device_get_nameunit(sc->sc_dev),
1598 dir == UE_DIR_IN ? "recording" : "playback",
1599 chan, prec, asf1d->bSubFrameSize * 8, format_str);
1600 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
1601 kprintf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
1604 kprintf(" %d", UA_GETSAMP(asf1d, 0));
1605 for (r = 1; r < asf1d->bSamFreqType; r++)
1606 kprintf(",%d", UA_GETSAMP(asf1d, r));
1610 if (sc->uaudio_sndstat_flag != 0) {
1611 sbuf_printf(&(sc->uaudio_sndstat), "\n\t");
1612 sbuf_printf(&(sc->uaudio_sndstat),
1613 "mode %d:(%s) %dch, %d/%dbit, %s,",
1614 id->bAlternateSetting,
1615 dir == UE_DIR_IN ? "input" : "output",
1616 chan, prec, asf1d->bSubFrameSize * 8, format_str);
1617 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
1618 sbuf_printf(&(sc->uaudio_sndstat), " %d-%dHz",
1619 UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
1622 sbuf_printf(&(sc->uaudio_sndstat),
1623 " %d", UA_GETSAMP(asf1d, 0));
1624 for (r = 1; r < asf1d->bSamFreqType; r++)
1625 sbuf_printf(&(sc->uaudio_sndstat),
1626 ",%d", UA_GETSAMP(asf1d, r));
1627 sbuf_printf(&(sc->uaudio_sndstat), "Hz");
1631 ai.alt = id->bAlternateSetting;
1633 ai.attributes = sed->bmAttributes;
1636 ai.edesc1 = epdesc1;
1637 ai.asf1desc = asf1d;
1639 uaudio_add_alt(sc, &ai);
1641 if (ai.attributes & UA_SED_FREQ_CONTROL)
1642 DPRINTFN(1, ("uaudio_process_as: FREQ_CONTROL\n"));
1643 if (ai.attributes & UA_SED_PITCH_CONTROL)
1644 DPRINTFN(1, ("uaudio_process_as: PITCH_CONTROL\n"));
1646 sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD;
1648 return USBD_NORMAL_COMPLETION;
1653 uaudio_identify_as(struct uaudio_softc *sc,
1654 const usb_config_descriptor_t *cdesc)
1656 const usb_interface_descriptor_t *id;
1660 size = UGETW(cdesc->wTotalLength);
1661 buf = (const char *)cdesc;
1663 /* Locate the AudioStreaming interface descriptor. */
1665 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
1669 sc->uaudio_sndstat_flag = 0;
1670 if (sbuf_new(&(sc->uaudio_sndstat), NULL, 4096, SBUF_AUTOEXTEND) != NULL)
1671 sc->uaudio_sndstat_flag = 1;
1673 /* Loop through all the alternate settings. */
1674 while (offs <= size) {
1675 DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
1676 id->bInterfaceNumber, offs));
1677 switch (id->bNumEndpoints) {
1679 DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
1680 id->bAlternateSetting));
1681 sc->sc_nullalt = id->bAlternateSetting;
1684 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
1687 uaudio_process_as(sc, buf, &offs, size, id);
1690 kprintf("%s: ignored audio interface with %d "
1692 device_get_nameunit(sc->sc_dev), id->bNumEndpoints);
1695 id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
1700 sbuf_finish(&(sc->uaudio_sndstat));
1704 DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
1706 if (sc->sc_mode == 0) {
1707 kprintf("%s: no usable endpoint found\n",
1708 device_get_nameunit(sc->sc_dev));
1712 return USBD_NORMAL_COMPLETION;
1716 uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
1718 struct io_terminal* iot;
1719 const usb_interface_descriptor_t *id;
1720 const struct usb_audio_control_descriptor *acdp;
1721 const usb_descriptor_t *dp;
1722 const struct usb_audio_output_terminal *pot;
1723 struct terminal_list *tml;
1724 const char *buf, *ibuf, *ibufend;
1725 int size, offs, aclen, ndps, i, j;
1727 size = UGETW(cdesc->wTotalLength);
1728 buf = (const char *)cdesc;
1730 /* Locate the AudioControl interface descriptor. */
1732 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
1735 if (offs + sizeof *acdp > size)
1737 sc->sc_ac_iface = id->bInterfaceNumber;
1738 DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface));
1740 /* A class-specific AC interface header should follow. */
1742 acdp = (const struct usb_audio_control_descriptor *)ibuf;
1743 if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
1744 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
1746 aclen = UGETW(acdp->wTotalLength);
1747 if (offs + aclen > size)
1750 if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
1751 UGETW(acdp->bcdADC) != UAUDIO_VERSION)
1754 sc->sc_audio_rev = UGETW(acdp->bcdADC);
1755 DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n",
1756 sc->sc_audio_rev, aclen));
1758 sc->sc_nullalt = -1;
1760 /* Scan through all the AC specific descriptors */
1761 ibufend = ibuf + aclen;
1762 dp = (const usb_descriptor_t *)ibuf;
1764 iot = kmalloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO);
1766 kprintf("%s: no memory\n", __func__);
1770 ibuf += dp->bLength;
1771 if (ibuf >= ibufend)
1773 dp = (const usb_descriptor_t *)ibuf;
1774 if (ibuf + dp->bLength > ibufend) {
1778 if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
1779 kprintf("uaudio_identify_ac: skip desc type=0x%02x\n",
1780 dp->bDescriptorType);
1783 i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId;
1790 /* construct io_terminal */
1791 for (i = 0; i < ndps; i++) {
1795 if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT)
1798 tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i);
1804 for (i = 0; i < 256; i++) {
1805 struct usb_audio_cluster cluster;
1807 if (iot[i].d.desc == NULL)
1809 kprintf("id %d:\t", i);
1810 switch (iot[i].d.desc->bDescriptorSubtype) {
1811 case UDESCSUB_AC_INPUT:
1812 kprintf("AC_INPUT type=%s\n", uaudio_get_terminal_name
1813 (UGETW(iot[i].d.it->wTerminalType)));
1815 cluster = uaudio_get_cluster(i, iot);
1816 uaudio_dump_cluster(&cluster);
1819 case UDESCSUB_AC_OUTPUT:
1820 kprintf("AC_OUTPUT type=%s ", uaudio_get_terminal_name
1821 (UGETW(iot[i].d.ot->wTerminalType)));
1822 kprintf("src=%d\n", iot[i].d.ot->bSourceId);
1824 case UDESCSUB_AC_MIXER:
1825 kprintf("AC_MIXER src=");
1826 for (j = 0; j < iot[i].d.mu->bNrInPins; j++)
1827 kprintf("%d ", iot[i].d.mu->baSourceId[j]);
1829 cluster = uaudio_get_cluster(i, iot);
1830 uaudio_dump_cluster(&cluster);
1833 case UDESCSUB_AC_SELECTOR:
1834 kprintf("AC_SELECTOR src=");
1835 for (j = 0; j < iot[i].d.su->bNrInPins; j++)
1836 kprintf("%d ", iot[i].d.su->baSourceId[j]);
1839 case UDESCSUB_AC_FEATURE:
1840 kprintf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId);
1842 case UDESCSUB_AC_PROCESSING:
1843 kprintf("AC_PROCESSING src=");
1844 for (j = 0; j < iot[i].d.pu->bNrInPins; j++)
1845 kprintf("%d ", iot[i].d.pu->baSourceId[j]);
1847 cluster = uaudio_get_cluster(i, iot);
1848 uaudio_dump_cluster(&cluster);
1851 case UDESCSUB_AC_EXTENSION:
1852 kprintf("AC_EXTENSION src=");
1853 for (j = 0; j < iot[i].d.eu->bNrInPins; j++)
1854 kprintf("%d ", iot[i].d.eu->baSourceId[j]);
1856 cluster = uaudio_get_cluster(i, iot);
1857 uaudio_dump_cluster(&cluster);
1861 kprintf("unknown audio control (subtype=%d)\n",
1862 iot[i].d.desc->bDescriptorSubtype);
1864 for (j = 0; j < iot[i].inputs_size; j++) {
1866 kprintf("\tinput%d: ", j);
1867 tml = iot[i].inputs[j];
1872 for (k = 0; k < tml->size; k++)
1873 kprintf("%s ", uaudio_get_terminal_name
1874 (tml->terminals[k]));
1877 kprintf("\toutput: ");
1878 tml = iot[i].output;
1879 for (j = 0; j < tml->size; j++)
1880 kprintf("%s ", uaudio_get_terminal_name(tml->terminals[j]));
1885 for (i = 0; i < ndps; i++) {
1889 DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n",
1890 i, dp->bDescriptorSubtype));
1891 switch (dp->bDescriptorSubtype) {
1892 case UDESCSUB_AC_HEADER:
1893 kprintf("uaudio_identify_ac: unexpected AC header\n");
1895 case UDESCSUB_AC_INPUT:
1896 uaudio_add_input(sc, iot, i);
1898 case UDESCSUB_AC_OUTPUT:
1899 uaudio_add_output(sc, iot, i);
1901 case UDESCSUB_AC_MIXER:
1902 uaudio_add_mixer(sc, iot, i);
1904 case UDESCSUB_AC_SELECTOR:
1905 uaudio_add_selector(sc, iot, i);
1907 case UDESCSUB_AC_FEATURE:
1908 uaudio_add_feature(sc, iot, i);
1910 case UDESCSUB_AC_PROCESSING:
1911 uaudio_add_processing(sc, iot, i);
1913 case UDESCSUB_AC_EXTENSION:
1914 uaudio_add_extension(sc, iot, i);
1917 kprintf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n",
1918 dp->bDescriptorSubtype);
1923 /* delete io_terminal */
1924 for (i = 0; i < 256; i++) {
1925 if (iot[i].d.desc == NULL)
1927 if (iot[i].inputs != NULL) {
1928 for (j = 0; j < iot[i].inputs_size; j++) {
1929 if (iot[i].inputs[j] != NULL)
1930 kfree(iot[i].inputs[j], M_TEMP);
1932 kfree(iot[i].inputs, M_TEMP);
1934 if (iot[i].output != NULL)
1935 kfree(iot[i].output, M_TEMP);
1936 iot[i].d.desc = NULL;
1940 return USBD_NORMAL_COMPLETION;
1944 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
1945 int wIndex, int len)
1947 usb_device_request_t req;
1958 req.bmRequestType = type;
1959 req.bRequest = which;
1960 USETW(req.wValue, wValue);
1961 USETW(req.wIndex, wIndex);
1962 USETW(req.wLength, len);
1963 DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
1964 "wIndex=0x%04x len=%d\n",
1965 type, which, wValue, wIndex, len));
1966 err = usbd_do_request(sc->sc_udev, &req, data);
1968 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
1976 val = data[0] | (data[1] << 8);
1979 DPRINTF(("uaudio_get: bad length=%d\n", len));
1982 DPRINTFN(2,("uaudio_get: val=%d\n", val));
1987 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
1988 int wIndex, int len, int val)
1990 usb_device_request_t req;
2000 req.bmRequestType = type;
2001 req.bRequest = which;
2002 USETW(req.wValue, wValue);
2003 USETW(req.wIndex, wIndex);
2004 USETW(req.wLength, len);
2016 DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
2017 "wIndex=0x%04x len=%d, val=%d\n",
2018 type, which, wValue, wIndex, len, val & 0xffff));
2019 err = usbd_do_request(sc->sc_udev, &req, data);
2022 DPRINTF(("uaudio_set: err=%d\n", err));
2027 uaudio_signext(int type, int val)
2029 if (!MIX_UNSIGNED(type)) {
2030 if (MIX_SIZE(type) == 2)
2039 uaudio_bsd2value(struct mixerctl *mc, int val)
2041 DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
2042 mc->type, val, mc->minval, mc->maxval));
2043 if (mc->type == MIX_ON_OFF) {
2045 } else if (mc->type == MIX_SELECTOR) {
2046 if (val < mc->minval || val > mc->maxval)
2049 val = (val + mc->delta/2) * mc->mul / 255 + mc->minval;
2050 DPRINTFN(5, ("val'=%d\n", val));
2055 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2058 val = uaudio_bsd2value(mc, val);
2059 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
2060 mc->wIndex, MIX_SIZE(mc->type), val);
2063 /* Set up a pipe for a channel. */
2065 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
2074 as = &sc->sc_alts[ch->altidx];
2075 endpt = as->edesc->bEndpointAddress;
2076 DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n",
2077 endpt, ch->sample_rate, as->alt));
2079 /* Set alternate interface corresponding to the mode. */
2080 err = usbd_set_interface(as->ifaceh, as->alt);
2085 * If just one sampling rate is supported,
2086 * no need to call uaudio_set_speed().
2087 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request.
2089 if (as->asf1desc->bSamFreqType != 1) {
2090 err = uaudio_set_speed(sc, endpt, ch->sample_rate);
2092 DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
2098 DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt));
2099 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
2102 if (as->edesc1 != NULL) {
2103 endpt = as->edesc1->bEndpointAddress;
2104 DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt));
2105 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe);
2111 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
2118 as = &sc->sc_alts[ch->altidx];
2120 if (sc->sc_nullalt >= 0) {
2121 DPRINTF(("uaudio_chan_close: set null alt=%d\n",
2123 usbd_set_interface(as->ifaceh, sc->sc_nullalt);
2126 usbd_abort_pipe(ch->pipe);
2127 usbd_close_pipe(ch->pipe);
2129 if (ch->sync_pipe) {
2130 usbd_abort_pipe(ch->sync_pipe);
2131 usbd_close_pipe(ch->sync_pipe);
2136 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
2138 usbd_xfer_handle xfer;
2142 size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
2143 for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
2144 xfer = usbd_alloc_xfer(sc->sc_udev);
2147 ch->chanbufs[i].xfer = xfer;
2148 buf = usbd_alloc_buffer(xfer, size);
2153 ch->chanbufs[i].buffer = buf;
2154 ch->chanbufs[i].chan = ch;
2157 return USBD_NORMAL_COMPLETION;
2161 /* implicit buffer kfree */
2162 usbd_free_xfer(ch->chanbufs[i].xfer);
2167 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
2171 for (i = 0; i < UAUDIO_NCHANBUFS; i++)
2172 usbd_free_xfer(ch->chanbufs[i].xfer);
2175 /* Called at splusb() */
2177 uaudio_chan_ptransfer(struct chan *ch)
2180 int i, n, size, residue, total;
2182 if (ch->sc->sc_dying)
2185 /* Pick the next channel buffer. */
2186 cb = &ch->chanbufs[ch->curchanbuf];
2187 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2190 /* Compute the size of each frame in the next transfer. */
2191 residue = ch->residue;
2193 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2194 size = ch->bytes_per_frame;
2195 residue += ch->fraction;
2196 if (residue >= USB_FRAMES_PER_SECOND) {
2197 if ((ch->sc->sc_altflags & UA_NOFRAC) == 0)
2198 size += ch->sample_size;
2199 residue -= USB_FRAMES_PER_SECOND;
2201 cb->sizes[i] = size;
2204 ch->residue = residue;
2208 * Transfer data from upper layer buffer to channel buffer, taking
2209 * care of wrapping the upper layer buffer.
2211 n = min(total, ch->end - ch->cur);
2212 memcpy(cb->buffer, ch->cur, n);
2214 if (ch->cur >= ch->end)
2215 ch->cur = ch->start;
2218 memcpy(cb->buffer + n, ch->cur, total);
2223 if (uaudiodebug > 8) {
2224 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
2225 cb->buffer, ch->residue));
2226 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2227 DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
2232 DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
2233 /* Fill the request */
2234 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
2235 UAUDIO_NFRAMES, USBD_NO_COPY,
2238 (void)usbd_transfer(cb->xfer);
2242 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
2251 /* Return if we are aborting. */
2252 if (status == USBD_CANCELLED)
2255 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2256 DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
2257 count, ch->transferred));
2259 if (count != cb->size) {
2260 kprintf("uaudio_chan_pintr: count(%d) != size(%d)\n",
2265 ch->transferred += cb->size;
2268 chn_intr(ch->pcm_ch);
2271 /* start next transfer */
2272 uaudio_chan_ptransfer(ch);
2275 /* Called at splusb() */
2277 uaudio_chan_rtransfer(struct chan *ch)
2280 int i, size, residue, total;
2282 if (ch->sc->sc_dying)
2285 /* Pick the next channel buffer. */
2286 cb = &ch->chanbufs[ch->curchanbuf];
2287 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2290 /* Compute the size of each frame in the next transfer. */
2291 residue = ch->residue;
2293 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2294 size = ch->bytes_per_frame;
2295 cb->sizes[i] = size;
2296 cb->offsets[i] = total;
2299 ch->residue = residue;
2303 if (uaudiodebug > 8) {
2304 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
2305 cb->buffer, ch->residue));
2306 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2307 DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
2312 DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
2313 /* Fill the request */
2314 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
2315 UAUDIO_NFRAMES, USBD_NO_COPY,
2318 (void)usbd_transfer(cb->xfer);
2322 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
2325 struct chanbuf *cb = priv;
2326 struct chan *ch = cb->chan;
2330 /* Return if we are aborting. */
2331 if (status == USBD_CANCELLED)
2334 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2335 DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
2336 count, ch->transferred));
2338 /* count < cb->size is normal for asynchronous source */
2340 if (count > cb->size) {
2341 kprintf("uaudio_chan_rintr: count(%d) > size(%d)\n",
2347 * Transfer data from channel buffer to upper layer buffer, taking
2348 * care of wrapping the upper layer buffer.
2350 for(i = 0; i < UAUDIO_NFRAMES; i++) {
2351 frsize = cb->sizes[i];
2352 n = min(frsize, ch->end - ch->cur);
2353 memcpy(ch->cur, cb->buffer + cb->offsets[i], n);
2355 if (ch->cur >= ch->end)
2356 ch->cur = ch->start;
2358 memcpy(ch->cur, cb->buffer + cb->offsets[i] + n,
2360 ch->cur += frsize - n;
2364 /* Call back to upper layer */
2365 ch->transferred += count;
2368 chn_intr(ch->pcm_ch);
2371 /* start next transfer */
2372 uaudio_chan_rtransfer(ch);
2376 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
2378 usb_device_request_t req;
2381 DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
2382 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
2383 req.bRequest = SET_CUR;
2384 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
2385 USETW(req.wIndex, endpt);
2386 USETW(req.wLength, 3);
2388 data[1] = speed >> 8;
2389 data[2] = speed >> 16;
2391 return usbd_do_request(sc->sc_udev, &req, data);
2395 /************************************************************/
2397 uaudio_init_params(struct uaudio_softc *sc, struct chan *ch, int mode)
2400 int samples_per_frame, sample_size;
2402 if ((sc->sc_playchan.pipe != NULL) || (sc->sc_recchan.pipe != NULL))
2405 switch(ch->format & 0x000FFFFF) {
2407 enc = AUDIO_ENCODING_ULINEAR_LE;
2411 enc = AUDIO_ENCODING_SLINEAR_LE;
2414 case AFMT_A_LAW: /* ? */
2415 enc = AUDIO_ENCODING_ALAW;
2418 case AFMT_MU_LAW: /* ? */
2419 enc = AUDIO_ENCODING_ULAW;
2423 enc = AUDIO_ENCODING_SLINEAR_LE;
2427 enc = AUDIO_ENCODING_SLINEAR_BE;
2431 enc = AUDIO_ENCODING_ULINEAR_LE;
2435 enc = AUDIO_ENCODING_ULINEAR_BE;
2439 enc = AUDIO_ENCODING_SLINEAR_LE;
2443 enc = AUDIO_ENCODING_SLINEAR_BE;
2447 enc = AUDIO_ENCODING_ULINEAR_LE;
2451 enc = AUDIO_ENCODING_ULINEAR_BE;
2455 enc = AUDIO_ENCODING_SLINEAR_LE;
2459 enc = AUDIO_ENCODING_SLINEAR_BE;
2463 enc = AUDIO_ENCODING_ULINEAR_LE;
2467 enc = AUDIO_ENCODING_ULINEAR_BE;
2473 kprintf("Unknown format %x\n", ch->format);
2476 if (ch->format & AFMT_STEREO) {
2482 /* for (mode = ...... */
2483 for (i = 0; i < sc->sc_nalts; i++) {
2484 const struct usb_audio_streaming_type1_descriptor *a1d =
2485 sc->sc_alts[i].asf1desc;
2486 if (ch->channels == a1d->bNrChannels &&
2487 ch->precision == a1d->bBitResolution &&
2489 enc == sc->sc_alts[i].encoding) {
2491 enc == sc->sc_alts[i].encoding &&
2492 (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) ==
2493 UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) {
2495 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2496 DPRINTFN(2,("uaudio_set_params: cont %d-%d\n",
2497 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
2498 if (UA_SAMP_LO(a1d) <= ch->sample_rate &&
2499 ch->sample_rate <= UA_SAMP_HI(a1d)) {
2500 if (mode == AUMODE_PLAY)
2501 sc->sc_playchan.altidx = i;
2503 sc->sc_recchan.altidx = i;
2507 for (j = 0; j < a1d->bSamFreqType; j++) {
2508 DPRINTFN(2,("uaudio_set_params: disc #"
2509 "%d: %d\n", j, UA_GETSAMP(a1d, j)));
2510 /* XXX allow for some slack */
2511 if (UA_GETSAMP(a1d, j) ==
2513 if (mode == AUMODE_PLAY)
2514 sc->sc_playchan.altidx = i;
2516 sc->sc_recchan.altidx = i;
2523 /* return (EINVAL); */
2524 if (mode == AUMODE_PLAY)
2525 kprintf("uaudio: This device can't play in rate=%d.\n", ch->sample_rate);
2527 kprintf("uaudio: This device can't record in rate=%d.\n", ch->sample_rate);
2532 p->sw_code = swcode;
2534 if (usemode == mode)
2535 sc->sc_curaltidx = i;
2539 sample_size = ch->precision * ch->channels / 8;
2540 samples_per_frame = ch->sample_rate / USB_FRAMES_PER_SECOND;
2541 ch->fraction = ch->sample_rate % USB_FRAMES_PER_SECOND;
2542 ch->sample_size = sample_size;
2543 ch->bytes_per_frame = samples_per_frame * sample_size;
2546 ch->cur = ch->start;
2547 ch->transferred = 0;
2552 struct uaudio_conversion {
2554 uint8_t uaudio_prec;
2555 uint32_t freebsd_fmt;
2558 const struct uaudio_conversion const accepted_conversion[] = {
2559 {AUDIO_ENCODING_ULINEAR_LE, 8, AFMT_U8},
2560 {AUDIO_ENCODING_ULINEAR_LE, 16, AFMT_U16_LE},
2561 {AUDIO_ENCODING_ULINEAR_LE, 24, AFMT_U24_LE},
2562 {AUDIO_ENCODING_ULINEAR_LE, 32, AFMT_U32_LE},
2563 {AUDIO_ENCODING_ULINEAR_BE, 16, AFMT_U16_BE},
2564 {AUDIO_ENCODING_ULINEAR_BE, 24, AFMT_U24_BE},
2565 {AUDIO_ENCODING_ULINEAR_BE, 32, AFMT_U32_BE},
2566 {AUDIO_ENCODING_SLINEAR_LE, 8, AFMT_S8},
2567 {AUDIO_ENCODING_SLINEAR_LE, 16, AFMT_S16_LE},
2568 {AUDIO_ENCODING_SLINEAR_LE, 24, AFMT_S24_LE},
2569 {AUDIO_ENCODING_SLINEAR_LE, 32, AFMT_S32_LE},
2570 {AUDIO_ENCODING_SLINEAR_BE, 16, AFMT_S16_BE},
2571 {AUDIO_ENCODING_SLINEAR_BE, 24, AFMT_S24_BE},
2572 {AUDIO_ENCODING_SLINEAR_BE, 32, AFMT_S32_BE},
2573 {AUDIO_ENCODING_ALAW, 8, AFMT_A_LAW},
2574 {AUDIO_ENCODING_ULAW, 8, AFMT_MU_LAW},
2579 uaudio_query_formats(device_t dev, int reqdir, unsigned maxfmt, struct pcmchan_caps *cap)
2581 struct uaudio_softc *sc;
2582 const struct usb_audio_streaming_type1_descriptor *asf1d;
2583 const struct uaudio_conversion *iterator;
2584 unsigned fmtcount, foundcount;
2586 uint8_t format, numchan, subframesize, prec, dir, iscontinuous;
2587 int freq, freq_min, freq_max;
2588 char *numchannel_descr;
2589 char freq_descr[64];
2592 sc = device_get_softc(dev);
2596 cap->minspeed = cap->maxspeed = 0;
2597 foundcount = fmtcount = 0;
2599 for (i = 0; i < sc->sc_nalts; i++) {
2600 dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
2602 if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY))
2605 asf1d = sc->sc_alts[i].asf1desc;
2606 format = sc->sc_alts[i].encoding;
2608 numchan = asf1d->bNrChannels;
2609 subframesize = asf1d->bSubFrameSize;
2610 prec = asf1d->bBitResolution; /* precision */
2611 iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS;
2614 ksnprintf(freq_descr, sizeof(freq_descr), "continous min %d max %d", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
2616 ksnprintf(freq_descr, sizeof(freq_descr), "fixed frequency (%d listed formats)", asf1d->bSamFreqType);
2619 numchannel_descr = " (mono)";
2620 else if (numchan == 2)
2621 numchannel_descr = " (stereo)";
2623 numchannel_descr = "";
2626 device_printf(dev, "uaudio_query_formats: found a native %s channel%s %s %dbit %dbytes/subframe X %d channels = %d bytes per sample\n",
2627 (dir==UE_DIR_OUT)?"playback":"record",
2628 numchannel_descr, freq_descr,
2629 prec, subframesize, numchan, subframesize*numchan);
2632 * Now start rejecting the ones that don't map to FreeBSD
2635 if (numchan != 1 && numchan != 2)
2638 for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++)
2639 if (iterator->uaudio_fmt == format && iterator->uaudio_prec == prec)
2642 if (iterator->uaudio_fmt == 0)
2645 fmt = iterator->freebsd_fmt;
2652 if (fmtcount >= maxfmt)
2655 cap->fmtlist[fmtcount++] = fmt;
2658 freq_min = UA_SAMP_LO(asf1d);
2659 freq_max = UA_SAMP_HI(asf1d);
2661 if (cap->minspeed == 0 || freq_min < cap->minspeed)
2662 cap->minspeed = freq_min;
2663 if (cap->maxspeed == 0)
2664 cap->maxspeed = cap->minspeed;
2665 if (freq_max > cap->maxspeed)
2666 cap->maxspeed = freq_max;
2668 for (r = 0; r < asf1d->bSamFreqType; r++) {
2669 freq = UA_GETSAMP(asf1d, r);
2670 if (cap->minspeed == 0 || freq < cap->minspeed)
2671 cap->minspeed = freq;
2672 if (cap->maxspeed == 0)
2673 cap->maxspeed = cap->minspeed;
2674 if (freq > cap->maxspeed)
2675 cap->maxspeed = freq;
2679 cap->fmtlist[fmtcount] = 0;
2684 uaudio_chan_set_param_pcm_dma_buff(device_t dev, u_char *start, u_char *end,
2685 struct pcm_channel *pc, int dir)
2687 struct uaudio_softc *sc;
2690 sc = device_get_softc(dev);
2691 #ifndef NO_RECORDING
2692 if (dir == PCMDIR_PLAY)
2693 ch = &sc->sc_playchan;
2695 ch = &sc->sc_recchan;
2697 ch = &sc->sc_playchan;
2709 uaudio_chan_set_param_blocksize(device_t dev, u_int32_t blocksize, int dir)
2711 struct uaudio_softc *sc;
2714 sc = device_get_softc(dev);
2715 #ifndef NO_RECORDING
2716 if (dir == PCMDIR_PLAY)
2717 ch = &sc->sc_playchan;
2719 ch = &sc->sc_recchan;
2721 ch = &sc->sc_playchan;
2724 ch->blksize = blocksize;
2730 uaudio_chan_set_param_speed(device_t dev, u_int32_t speed, int reqdir)
2732 const struct uaudio_conversion *iterator;
2733 struct uaudio_softc *sc;
2735 int i, r, score, hiscore, bestspeed;
2737 sc = device_get_softc(dev);
2738 #ifndef NO_RECORDING
2739 if (reqdir == PCMDIR_PLAY)
2740 ch = &sc->sc_playchan;
2742 ch = &sc->sc_recchan;
2744 ch = &sc->sc_playchan;
2747 * We are successful if we find an endpoint that matches our selected format and it
2748 * supports the requested speed.
2752 for (i = 0; i < sc->sc_nalts; i++) {
2753 int dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
2754 int format = sc->sc_alts[i].encoding;
2755 const struct usb_audio_streaming_type1_descriptor *asf1d = sc->sc_alts[i].asf1desc;
2756 int iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS;
2758 if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY))
2761 for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++)
2762 if (iterator->uaudio_fmt != format || iterator->freebsd_fmt != (ch->format&0xfffffff))
2765 if (speed >= UA_SAMP_LO(asf1d) && speed <= UA_SAMP_HI(asf1d)) {
2766 ch->sample_rate = speed;
2768 } else if (speed < UA_SAMP_LO(asf1d)) {
2769 score = 0xfff * speed / UA_SAMP_LO(asf1d);
2770 if (score > hiscore) {
2771 bestspeed = UA_SAMP_LO(asf1d);
2774 } else if (speed < UA_SAMP_HI(asf1d)) {
2775 score = 0xfff * UA_SAMP_HI(asf1d) / speed;
2776 if (score > hiscore) {
2777 bestspeed = UA_SAMP_HI(asf1d);
2783 for (r = 0; r < asf1d->bSamFreqType; r++) {
2784 if (speed == UA_GETSAMP(asf1d, r)) {
2785 ch->sample_rate = speed;
2788 if (speed > UA_GETSAMP(asf1d, r))
2789 score = 0xfff * UA_GETSAMP(asf1d, r) / speed;
2791 score = 0xfff * speed / UA_GETSAMP(asf1d, r);
2792 if (score > hiscore) {
2793 bestspeed = UA_GETSAMP(asf1d, r);
2798 if (bestspeed != 1) {
2799 ch->sample_rate = bestspeed;
2807 uaudio_chan_getptr(device_t dev, int dir)
2809 struct uaudio_softc *sc;
2813 sc = device_get_softc(dev);
2814 #ifndef NO_RECORDING
2815 if (dir == PCMDIR_PLAY)
2816 ch = &sc->sc_playchan;
2818 ch = &sc->sc_recchan;
2820 ch = &sc->sc_playchan;
2823 ptr = ch->cur - ch->start;
2829 uaudio_chan_set_param_format(device_t dev, u_int32_t format, int dir)
2831 struct uaudio_softc *sc;
2834 sc = device_get_softc(dev);
2835 #ifndef NO_RECORDING
2836 if (dir == PCMDIR_PLAY)
2837 ch = &sc->sc_playchan;
2839 ch = &sc->sc_recchan;
2841 ch = &sc->sc_playchan;
2844 ch->format = format;
2850 uaudio_halt_out_dma(device_t dev)
2852 struct uaudio_softc *sc;
2854 sc = device_get_softc(dev);
2856 DPRINTF(("uaudio_halt_out_dma: enter\n"));
2857 if (sc->sc_playchan.pipe != NULL) {
2858 uaudio_chan_close(sc, &sc->sc_playchan);
2859 sc->sc_playchan.pipe = 0;
2860 uaudio_chan_free_buffers(sc, &sc->sc_playchan);
2866 uaudio_halt_in_dma(device_t dev)
2868 struct uaudio_softc *sc;
2870 sc = device_get_softc(dev);
2875 DPRINTF(("uaudio_halt_in_dma: enter\n"));
2876 if (sc->sc_recchan.pipe != NULL) {
2877 uaudio_chan_close(sc, &sc->sc_recchan);
2878 sc->sc_recchan.pipe = NULL;
2879 uaudio_chan_free_buffers(sc, &sc->sc_recchan);
2880 /* sc->sc_recchan.intr = NULL; */
2886 uaudio_trigger_input(device_t dev)
2888 struct uaudio_softc *sc;
2893 sc = device_get_softc(dev);
2894 ch = &sc->sc_recchan;
2899 /* uaudio_chan_set_param(ch, start, end, blksize) */
2900 if (uaudio_init_params(sc, ch, AUMODE_RECORD))
2903 err = uaudio_chan_alloc_buffers(sc, ch);
2907 err = uaudio_chan_open(sc, ch);
2909 uaudio_chan_free_buffers(sc, ch);
2917 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
2918 uaudio_chan_rtransfer(ch);
2925 uaudio_trigger_output(device_t dev)
2927 struct uaudio_softc *sc;
2932 sc = device_get_softc(dev);
2933 ch = &sc->sc_playchan;
2938 if (uaudio_init_params(sc, ch, AUMODE_PLAY))
2941 err = uaudio_chan_alloc_buffers(sc, ch);
2945 err = uaudio_chan_open(sc, ch);
2947 uaudio_chan_free_buffers(sc, ch);
2952 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
2953 uaudio_chan_ptransfer(ch);
2960 uaudio_query_mix_info(device_t dev)
2964 struct uaudio_softc *sc;
2965 struct mixerctl *mc;
2967 sc = device_get_softc(dev);
2968 for (i=0; i < sc->sc_nctls; i++) {
2969 mc = &sc->sc_ctls[i];
2970 if (mc->ctl != SOUND_MIXER_NRDEVICES) {
2971 /* Set device mask bits.
2972 See /usr/include/machine/soundcard.h */
2973 mask |= (1 << mc->ctl);
2980 uaudio_query_recsrc_info(device_t dev)
2982 int i, rec_selector_id;
2984 struct uaudio_softc *sc;
2985 struct mixerctl *mc;
2987 sc = device_get_softc(dev);
2988 rec_selector_id = -1;
2989 for (i=0; i < sc->sc_nctls; i++) {
2990 mc = &sc->sc_ctls[i];
2991 if (mc->ctl == SOUND_MIXER_NRDEVICES &&
2992 mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
2993 if (rec_selector_id == -1) {
2994 rec_selector_id = i;
2996 kprintf("There are many selectors. Can't recognize which selector is a record source selector.\n");
3001 if (rec_selector_id == -1)
3003 mc = &sc->sc_ctls[rec_selector_id];
3004 for (i = mc->minval; i <= mc->maxval; i++) {
3005 if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES)
3007 mask |= 1 << mc->slctrtype[i - 1];
3013 uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
3016 struct uaudio_softc *sc;
3017 struct mixerctl *mc;
3019 sc = device_get_softc(dev);
3020 for (i=0; i < sc->sc_nctls; i++) {
3021 mc = &sc->sc_ctls[i];
3022 if (mc->ctl == type) {
3023 if (mc->nchan == 2) {
3025 uaudio_ctl_set(sc, SET_CUR, mc, 1, (int)(right*255)/100);
3027 /* set Left or Mono */
3028 uaudio_ctl_set(sc, SET_CUR, mc, 0, (int)(left*255)/100);
3035 uaudio_mixer_setrecsrc(device_t dev, u_int32_t src)
3037 int i, rec_selector_id;
3038 struct uaudio_softc *sc;
3039 struct mixerctl *mc;
3041 sc = device_get_softc(dev);
3042 rec_selector_id = -1;
3043 for (i=0; i < sc->sc_nctls; i++) {
3044 mc = &sc->sc_ctls[i];
3045 if (mc->ctl == SOUND_MIXER_NRDEVICES &&
3046 mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
3047 if (rec_selector_id == -1) {
3048 rec_selector_id = i;
3050 return src; /* Can't recognize which selector is record source selector */
3054 if (rec_selector_id == -1)
3056 mc = &sc->sc_ctls[rec_selector_id];
3057 for (i = mc->minval; i <= mc->maxval; i++) {
3058 if (src != (1 << mc->slctrtype[i - 1]))
3060 uaudio_ctl_set(sc, SET_CUR, mc, 0, i);
3061 return (1 << mc->slctrtype[i - 1]);
3063 uaudio_ctl_set(sc, SET_CUR, mc, 0, mc->minval);
3064 return (1 << mc->slctrtype[mc->minval - 1]);
3068 uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
3070 struct snddev_info *d;
3071 struct snddev_channel *sce;
3072 struct pcm_channel *c;
3073 struct pcm_feeder *f;
3075 device_t pa_dev = device_get_parent(dev);
3076 struct uaudio_softc *sc = device_get_softc(pa_dev);
3081 d = device_get_softc(dev);
3085 snd_mtxlock(d->lock);
3086 if (SLIST_EMPTY(&d->channels)) {
3087 sbuf_printf(s, " (mixer only)");
3088 snd_mtxunlock(d->lock);
3092 SLIST_FOREACH(sce, &d->channels, link) {
3094 if (c->direction == PCMDIR_PLAY) {
3095 if (c->flags & CHN_F_VIRTUAL)
3102 sbuf_printf(s, " (%dp/%dr/%dv channels%s%s)",
3103 d->playcount, d->reccount, d->vchancount,
3104 (d->flags & SD_F_SIMPLEX)? "" : " duplex",
3106 (device_get_unit(dev) == snd_unit)? " default" : ""
3112 if (sc->uaudio_sndstat_flag != 0) {
3113 sbuf_cat(s, sbuf_data(&(sc->uaudio_sndstat)));
3117 snd_mtxunlock(d->lock);
3121 SLIST_FOREACH(sce, &d->channels, link) {
3123 sbuf_printf(s, "\n\t");
3125 KASSERT(c->bufhard != NULL && c->bufsoft != NULL,
3126 ("hosed pcm channel setup"));
3128 /* it would be better to indent child channels */
3129 sbuf_printf(s, "%s[%s]: ", c->parentchannel? c->parentchannel->name : "", c->name);
3130 sbuf_printf(s, "spd %d", c->speed);
3131 if (c->speed != sndbuf_getspd(c->bufhard))
3132 sbuf_printf(s, "/%d", sndbuf_getspd(c->bufhard));
3133 sbuf_printf(s, ", fmt 0x%08x", c->format);
3134 if (c->format != sndbuf_getfmt(c->bufhard))
3135 sbuf_printf(s, "/0x%08x", sndbuf_getfmt(c->bufhard));
3136 sbuf_printf(s, ", flags 0x%08x, 0x%08x", c->flags, c->feederflags);
3138 sbuf_printf(s, ", pid %d", c->pid);
3139 sbuf_printf(s, "\n\t");
3141 sbuf_printf(s, "interrupts %d, ", c->interrupts);
3142 if (c->direction == PCMDIR_REC)
3143 sbuf_printf(s, "overruns %d, hfree %d, sfree %d",
3144 c->xruns, sndbuf_getfree(c->bufhard), sndbuf_getfree(c->bufsoft));
3146 sbuf_printf(s, "underruns %d, ready %d",
3147 c->xruns, sndbuf_getready(c->bufsoft));
3148 sbuf_printf(s, "\n\t");
3150 sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "hardware" : "userland");
3151 sbuf_printf(s, " -> ");
3153 while (f->source != NULL)
3156 sbuf_printf(s, "%s", f->class->name);
3157 if (f->desc->type == FEEDER_FMT)
3158 sbuf_printf(s, "(0x%08x -> 0x%08x)", f->desc->in, f->desc->out);
3159 if (f->desc->type == FEEDER_RATE)
3160 sbuf_printf(s, "(%d -> %d)", FEEDER_GET(f, FEEDRATE_SRC), FEEDER_GET(f, FEEDRATE_DST));
3161 if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER)
3162 sbuf_printf(s, "(0x%08x)", f->desc->out);
3163 sbuf_printf(s, " -> ");
3166 sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "userland" : "hardware");
3168 snd_mtxunlock(d->lock);
3174 uaudio_sndstat_register(device_t dev)
3176 struct snddev_info *d = device_get_softc(dev);
3177 sndstat_register(dev, d->status, uaudio_sndstat_prepare_pcm);
3181 audio_attach_mi(device_t dev)
3184 struct sndcard_func *func;
3186 /* Attach the children. */
3188 func = kmalloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO);
3191 func->func = SCF_PCM;
3192 child = device_add_child(dev, "pcm", -1);
3193 device_set_ivars(child, func);
3195 bus_generic_attach(dev);
3197 return 0; /* XXXXX */
3200 DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, usbd_driver_load, 0);
3201 MODULE_VERSION(uaudio, 1);