1 /* $NetBSD: uaudio.c,v 1.41 2001/01/23 14:04:13 augustss Exp $ */
2 /* $FreeBSD: src/sys/dev/sound/usb/uaudio.c,v 1.6.2.2 2002/11/06 21:18:17 joe Exp $: */
3 /* $DragonFly: src/sys/dev/sound/usb/uaudio.c,v 1.10 2006/12/22 23:26:25 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/data/devclass/audio10.pdf
44 * http://www.usb.org/developers/data/devclass/frmts10.pdf
45 * http://www.usb.org/developers/data/devclass/termt10.pdf
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
51 #include <sys/malloc.h>
52 #if defined(__NetBSD__) || defined(__OpenBSD__)
53 #include <sys/device.h>
54 #include <sys/ioctl.h>
58 #include <sys/reboot.h> /* for bootverbose */
59 #include <sys/select.h>
61 #if defined(__NetBSD__) || defined(__OpenBSD__)
62 #include <sys/device.h>
63 #elif defined(__DragonFly__)
64 #include <sys/module.h>
69 #include <sys/sysctl.h>
70 #include <sys/thread2.h>
72 #if defined(__NetBSD__) || defined(__OpenBSD__)
73 #include <sys/audioio.h>
74 #include <dev/audio_if.h>
75 #include <dev/mulaw.h>
76 #include <dev/auconv.h>
77 #elif defined(__DragonFly__)
78 #include <dev/sound/pcm/sound.h> /* XXXXX */
79 #include <dev/sound/chip.h>
82 #include <bus/usb/usb.h>
83 #include <bus/usb/usbdi.h>
84 #include <bus/usb/usbdi_util.h>
85 #include <bus/usb/usb_quirks.h>
87 #include <dev/sound/usb/uaudioreg.h>
88 #include <dev/sound/usb/uaudio.h>
91 #define DPRINTF(x) if (uaudiodebug) logprintf x
92 #define DPRINTFN(n,x) if (uaudiodebug>(n)) logprintf x
94 SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
95 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW,
96 &uaudiodebug, 0, "uaudio debug level");
102 #define UAUDIO_NCHANBUFS 6 /* number of outstanding request */
103 #define UAUDIO_NFRAMES 20 /* ms of sound in each request */
106 #define MIX_MAX_CHAN 8
108 u_int16_t wValue[MIX_MAX_CHAN]; /* using nchan */
113 #define MIX_SIGNED_16 2
114 #define MIX_UNSIGNED_16 3
115 #define MIX_SIGNED_8 4
116 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
117 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
121 #if defined(__DragonFly__) /* XXXXX */
125 char ctlname[MAX_AUDIO_DEV_LEN];
129 #define MAKE(h,l) (((h) << 8) | (l))
134 usbd_interface_handle ifaceh;
135 usb_interface_descriptor_t *idesc;
136 usb_endpoint_descriptor_audio_t *edesc;
137 struct usb_audio_streaming_type1_descriptor *asf1desc;
141 int terminal; /* terminal id */
142 #if defined(__NetBSD__) || defined(__OpenBSD__)
143 void (*intr)(void *); /* dma completion intr handler */
144 void *arg; /* arg for intr() */
146 struct pcm_channel *pcm_ch;
148 usbd_pipe_handle pipe;
149 int dir; /* direction */
153 u_int bytes_per_frame;
154 u_int fraction; /* fraction/1000 is the extra samples/frame */
155 u_int residue; /* accumulates the fractional samples */
157 u_char *start; /* upper layer buffer start */
158 u_char *end; /* upper layer buffer end */
159 u_char *cur; /* current position in upper layer buffer */
160 int blksize; /* chunk size to report up */
161 int transferred; /* transferred bytes not reported up */
163 char nofrac; /* don't do sample rate adjustment */
168 usbd_xfer_handle xfer;
170 u_int16_t sizes[UAUDIO_NFRAMES];
172 } chanbufs[UAUDIO_NCHANBUFS];
174 struct uaudio_softc *sc; /* our softc */
175 #if defined(__DragonFly__)
182 struct uaudio_softc {
183 USBBASEDEVICE sc_dev; /* base device */
184 usbd_device_handle sc_udev; /* USB device */
186 char sc_dead; /* The device is dead -- kill it */
188 int sc_ac_iface; /* Audio Control interface */
189 usbd_interface_handle sc_ac_ifaceh;
199 struct as_info *sc_alts;
207 #define HAS_ALAW 0x08
208 #define HAS_MULAW 0x10
210 struct mixerctl *sc_ctls;
213 device_ptr_t sc_audiodev;
221 Static usbd_status uaudio_identify_ac(struct uaudio_softc *sc,
222 usb_config_descriptor_t *cdesc);
223 Static usbd_status uaudio_identify_as(struct uaudio_softc *sc,
224 usb_config_descriptor_t *cdesc);
225 Static usbd_status uaudio_process_as(struct uaudio_softc *sc,
226 char *buf, int *offsp, int size,
227 usb_interface_descriptor_t *id);
229 Static void uaudio_add_alt(struct uaudio_softc *sc,
232 Static usb_interface_descriptor_t *uaudio_find_iface(char *buf,
233 int size, int *offsp, int subtype);
235 Static void uaudio_mixer_add_ctl(struct uaudio_softc *sc,
236 struct mixerctl *mp);
238 #if defined(__NetBSD__) || defined(__OpenBSD__)
239 Static char *uaudio_id_name(struct uaudio_softc *sc,
240 usb_descriptor_t **dps, int id);
243 Static struct usb_audio_cluster uaudio_get_cluster(int id,
244 usb_descriptor_t **dps);
245 Static void uaudio_add_input(struct uaudio_softc *sc,
246 usb_descriptor_t *v, usb_descriptor_t **dps);
247 Static void uaudio_add_output(struct uaudio_softc *sc,
248 usb_descriptor_t *v, usb_descriptor_t **dps);
249 Static void uaudio_add_mixer(struct uaudio_softc *sc,
250 usb_descriptor_t *v, usb_descriptor_t **dps);
251 Static void uaudio_add_selector(struct uaudio_softc *sc,
252 usb_descriptor_t *v, usb_descriptor_t **dps);
253 Static void uaudio_add_feature(struct uaudio_softc *sc,
254 usb_descriptor_t *v, usb_descriptor_t **dps);
255 Static void uaudio_add_processing_updown(struct uaudio_softc *sc,
256 usb_descriptor_t *v, usb_descriptor_t **dps);
257 Static void uaudio_add_processing(struct uaudio_softc *sc,
258 usb_descriptor_t *v, usb_descriptor_t **dps);
259 Static void uaudio_add_extension(struct uaudio_softc *sc,
260 usb_descriptor_t *v, usb_descriptor_t **dps);
261 Static usbd_status uaudio_identify(struct uaudio_softc *sc,
262 usb_config_descriptor_t *cdesc);
264 Static int uaudio_signext(int type, int val);
265 #if defined(__NetBSD__) || defined(__OpenBSD__)
266 Static int uaudio_value2bsd(struct mixerctl *mc, int val);
268 Static int uaudio_bsd2value(struct mixerctl *mc, int val);
269 Static int uaudio_get(struct uaudio_softc *sc, int type,
270 int which, int wValue, int wIndex, int len);
271 #if defined(__NetBSD__) || defined(__OpenBSD__)
272 Static int uaudio_ctl_get(struct uaudio_softc *sc, int which,
273 struct mixerctl *mc, int chan);
275 Static void uaudio_set(struct uaudio_softc *sc, int type,
276 int which, int wValue, int wIndex, int l, int v);
277 Static void uaudio_ctl_set(struct uaudio_softc *sc, int which,
278 struct mixerctl *mc, int chan, int val);
280 Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
282 Static usbd_status uaudio_chan_open(struct uaudio_softc *sc,
284 Static void uaudio_chan_close(struct uaudio_softc *sc,
286 Static usbd_status uaudio_chan_alloc_buffers(struct uaudio_softc *,
288 Static void uaudio_chan_free_buffers(struct uaudio_softc *,
291 #if defined(__NetBSD__) || defined(__OpenBSD__)
292 Static void uaudio_chan_set_param(struct chan *ch,
293 struct audio_params *param, u_char *start,
294 u_char *end, int blksize);
297 Static void uaudio_chan_ptransfer(struct chan *ch);
298 Static void uaudio_chan_pintr(usbd_xfer_handle xfer,
299 usbd_private_handle priv, usbd_status status);
301 Static void uaudio_chan_rtransfer(struct chan *ch);
302 Static void uaudio_chan_rintr(usbd_xfer_handle xfer,
303 usbd_private_handle priv, usbd_status status);
305 #if defined(__NetBSD__) || defined(__OpenBSD__)
306 Static int uaudio_open(void *, int);
307 Static void uaudio_close(void *);
308 Static int uaudio_drain(void *);
309 Static int uaudio_query_encoding(void *, struct audio_encoding *);
310 Static int uaudio_set_params(void *, int, int,
311 struct audio_params *, struct audio_params *);
312 Static int uaudio_round_blocksize(void *, int);
313 Static int uaudio_trigger_output(void *, void *, void *,
314 int, void (*)(void *), void *,
315 struct audio_params *);
316 Static int uaudio_trigger_input (void *, void *, void *,
317 int, void (*)(void *), void *,
318 struct audio_params *);
319 Static int uaudio_halt_in_dma(void *);
320 Static int uaudio_halt_out_dma(void *);
321 Static int uaudio_getdev(void *, struct audio_device *);
322 Static int uaudio_mixer_set_port(void *, mixer_ctrl_t *);
323 Static int uaudio_mixer_get_port(void *, mixer_ctrl_t *);
324 Static int uaudio_query_devinfo(void *, mixer_devinfo_t *);
325 Static int uaudio_get_props(void *);
327 Static struct audio_hw_if uaudio_hw_if = {
331 uaudio_query_encoding,
333 uaudio_round_blocksize,
344 uaudio_mixer_set_port,
345 uaudio_mixer_get_port,
346 uaudio_query_devinfo,
352 uaudio_trigger_output,
353 uaudio_trigger_input,
356 Static struct audio_device uaudio_device = {
362 #elif defined(__DragonFly__)
363 Static int audio_attach_mi(device_t);
364 Static void uaudio_init_params(struct uaudio_softc * sc, struct chan *ch);
366 /* for NetBSD compatibirity */
367 #define AUMODE_PLAY 0x01
368 #define AUMODE_RECORD 0x02
370 #define AUDIO_PROP_FULLDUPLEX 0x01
372 #define AUDIO_ENCODING_ULAW 1
373 #define AUDIO_ENCODING_ALAW 2
374 #define AUDIO_ENCODING_SLINEAR_LE 6
375 #define AUDIO_ENCODING_SLINEAR_BE 7
376 #define AUDIO_ENCODING_ULINEAR_LE 8
377 #define AUDIO_ENCODING_ULINEAR_BE 9
382 #if defined(__NetBSD__) || defined(__OpenBSD__)
384 USB_DECLARE_DRIVER(uaudio);
386 #elif defined(__DragonFly__)
388 USB_DECLARE_DRIVER_INIT(uaudio,
389 DEVMETHOD(device_suspend, bus_generic_suspend),
390 DEVMETHOD(device_resume, bus_generic_resume),
391 DEVMETHOD(device_shutdown, bus_generic_shutdown),
392 DEVMETHOD(bus_print_child, bus_generic_print_child)
399 USB_MATCH_START(uaudio, uaa);
400 usb_interface_descriptor_t *id;
402 if (uaa->iface == NULL)
403 return (UMATCH_NONE);
405 id = usbd_get_interface_descriptor(uaa->iface);
406 /* Trigger on the control interface. */
408 id->bInterfaceClass != UICLASS_AUDIO ||
409 id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
410 (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
411 return (UMATCH_NONE);
413 return (UMATCH_IFACECLASS_IFACESUBCLASS);
418 USB_ATTACH_START(uaudio, sc, uaa);
419 usb_interface_descriptor_t *id;
420 usb_config_descriptor_t *cdesc;
425 usbd_devinfo(uaa->device, 0, devinfo);
428 #if !defined(__DragonFly__)
429 kprintf(": %s\n", devinfo);
432 sc->sc_udev = uaa->device;
434 cdesc = usbd_get_config_descriptor(sc->sc_udev);
436 kprintf("%s: failed to get configuration descriptor\n",
437 USBDEVNAME(sc->sc_dev));
438 USB_ATTACH_ERROR_RETURN;
441 err = uaudio_identify(sc, cdesc);
443 kprintf("%s: audio descriptors make no sense, error=%d\n",
444 USBDEVNAME(sc->sc_dev), err);
445 USB_ATTACH_ERROR_RETURN;
448 sc->sc_ac_ifaceh = uaa->iface;
449 /* Pick up the AS interface. */
450 for (i = 0; i < uaa->nifaces; i++) {
451 if (uaa->ifaces[i] == NULL)
453 id = usbd_get_interface_descriptor(uaa->ifaces[i]);
457 for (j = 0; j < sc->sc_nalts; j++) {
458 if (id->bInterfaceNumber ==
459 sc->sc_alts[j].idesc->bInterfaceNumber) {
460 sc->sc_alts[j].ifaceh = uaa->ifaces[i];
465 uaa->ifaces[i] = NULL;
468 for (j = 0; j < sc->sc_nalts; j++) {
469 if (sc->sc_alts[j].ifaceh == NULL) {
470 kprintf("%s: alt %d missing AS interface(s)\n",
471 USBDEVNAME(sc->sc_dev), j);
472 USB_ATTACH_ERROR_RETURN;
476 kprintf("%s: audio rev %d.%02x\n", USBDEVNAME(sc->sc_dev),
477 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
481 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
482 sc->sc_chan.nofrac = 1;
487 kprintf("%s: %d mixer controls\n", USBDEVNAME(sc->sc_dev),
490 #if !defined(__DragonFly__)
491 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
495 DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
496 #if defined(__OpenBSD__)
497 audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
498 #elif defined(__NetBSD__)
499 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
500 #elif defined(__DragonFly__)
502 if (audio_attach_mi(sc->sc_dev)) {
503 kprintf("audio_attach_mi failed\n");
504 USB_ATTACH_ERROR_RETURN;
508 USB_ATTACH_SUCCESS_RETURN;
511 #if defined(__NetBSD__) || defined(__OpenBSD__)
513 uaudio_activate(device_ptr_t self, enum devact act)
515 struct uaudio_softc *sc = (struct uaudio_softc *)self;
523 case DVACT_DEACTIVATE:
524 if (sc->sc_audiodev != NULL)
525 rv = config_deactivate(sc->sc_audiodev);
533 #if defined(__NetBSD__) || defined(__OpenBSD__)
535 uaudio_detach(device_ptr_t self, int flags)
537 struct uaudio_softc *sc = (struct uaudio_softc *)self;
540 /* Wait for outstanding requests to complete. */
541 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
543 if (sc->sc_audiodev != NULL)
544 rv = config_detach(sc->sc_audiodev, flags);
546 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
551 #elif defined(__DragonFly__)
555 USB_DETACH_START(uaudio, sc);
560 /* Wait for outstanding requests to complete. */
561 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
565 return bus_generic_detach(sc->sc_dev);
569 #if defined(__NetBSD__) || defined(__OpenBSD__)
571 uaudio_query_encoding(void *addr, struct audio_encoding *fp)
573 struct uaudio_softc *sc = addr;
574 int flags = sc->sc_altflags;
580 if (sc->sc_nalts == 0 || flags == 0)
586 strcpy(fp->name, AudioEulinear);
587 fp->encoding = AUDIO_ENCODING_ULINEAR;
589 fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
592 strcpy(fp->name, AudioEmulaw);
593 fp->encoding = AUDIO_ENCODING_ULAW;
595 fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
598 strcpy(fp->name, AudioEalaw);
599 fp->encoding = AUDIO_ENCODING_ALAW;
601 fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
604 strcpy(fp->name, AudioEslinear);
605 fp->encoding = AUDIO_ENCODING_SLINEAR;
607 fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
610 strcpy(fp->name, AudioEslinear_le);
611 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
616 strcpy(fp->name, AudioEulinear_le);
617 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
619 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
622 strcpy(fp->name, AudioEslinear_be);
623 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
625 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
628 strcpy(fp->name, AudioEulinear_be);
629 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
631 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
639 usb_interface_descriptor_t *
640 uaudio_find_iface(char *buf, int size, int *offsp, int subtype)
642 usb_interface_descriptor_t *d;
644 while (*offsp < size) {
645 d = (void *)(buf + *offsp);
646 *offsp += d->bLength;
647 if (d->bDescriptorType == UDESC_INTERFACE &&
648 d->bInterfaceClass == UICLASS_AUDIO &&
649 d->bInterfaceSubClass == subtype)
656 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
659 size_t len = sizeof(*mc) * (sc->sc_nctls + 1);
660 struct mixerctl *nmc = sc->sc_nctls == 0 ?
661 kmalloc(len, M_USBDEV, M_NOWAIT) :
662 krealloc(sc->sc_ctls, len, M_USBDEV, M_NOWAIT);
665 kprintf("uaudio_mixer_add_ctl: no memory\n");
671 if (mc->type != MIX_ON_OFF) {
672 /* Determine min and max values. */
673 mc->minval = uaudio_signext(mc->type,
674 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
675 mc->wValue[0], mc->wIndex,
676 MIX_SIZE(mc->type)));
677 mc->maxval = 1 + uaudio_signext(mc->type,
678 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
679 mc->wValue[0], mc->wIndex,
680 MIX_SIZE(mc->type)));
681 mc->mul = mc->maxval - mc->minval;
684 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
685 mc->wValue[0], mc->wIndex,
688 mc->delta = (res * 256 + mc->mul/2) / mc->mul;
694 sc->sc_ctls[sc->sc_nctls++] = *mc;
697 if (uaudiodebug > 2) {
699 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
700 for (i = 1; i < mc->nchan; i++)
701 DPRINTF((",%04x", mc->wValue[i]));
702 #if defined(__DragonFly__)
703 DPRINTF((" wIndex=%04x type=%d "
705 mc->wIndex, mc->type,
706 mc->minval, mc->maxval));
708 DPRINTF((" wIndex=%04x type=%d ctl='%d' unit='%s'"
710 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
711 mc->minval, mc->maxval));
717 #if defined(__NetBSD__) || defined(__OpenBSD__)
719 uaudio_id_name(struct uaudio_softc *sc, usb_descriptor_t **dps, int id)
722 ksprintf(buf, "i%d", id);
727 struct usb_audio_cluster
728 uaudio_get_cluster(int id, usb_descriptor_t **dps)
730 struct usb_audio_cluster r;
731 usb_descriptor_t *dp;
734 for (i = 0; i < 25; i++) { /* avoid infinite loops */
738 switch (dp->bDescriptorSubtype) {
739 case UDESCSUB_AC_INPUT:
740 #define p ((struct usb_audio_input_terminal *)dp)
741 r.bNrChannels = p->bNrChannels;
742 USETW(r.wChannelConfig, UGETW(p->wChannelConfig));
743 r.iChannelNames = p->iChannelNames;
746 case UDESCSUB_AC_OUTPUT:
747 #define p ((struct usb_audio_output_terminal *)dp)
751 case UDESCSUB_AC_MIXER:
752 #define p ((struct usb_audio_mixer_unit *)dp)
753 r = *(struct usb_audio_cluster *)
754 &p->baSourceId[p->bNrInPins];
757 case UDESCSUB_AC_SELECTOR:
758 /* XXX This is not really right */
759 #define p ((struct usb_audio_selector_unit *)dp)
760 id = p->baSourceId[0];
763 case UDESCSUB_AC_FEATURE:
764 #define p ((struct usb_audio_feature_unit *)dp)
768 case UDESCSUB_AC_PROCESSING:
769 #define p ((struct usb_audio_processing_unit *)dp)
770 r = *(struct usb_audio_cluster *)
771 &p->baSourceId[p->bNrInPins];
774 case UDESCSUB_AC_EXTENSION:
775 #define p ((struct usb_audio_extension_unit *)dp)
776 r = *(struct usb_audio_cluster *)
777 &p->baSourceId[p->bNrInPins];
785 kprintf("uaudio_get_cluster: bad data\n");
786 memset(&r, 0, sizeof r);
792 uaudio_add_input(struct uaudio_softc *sc, usb_descriptor_t *v,
793 usb_descriptor_t **dps)
796 struct usb_audio_input_terminal *d =
797 (struct usb_audio_input_terminal *)v;
799 DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
800 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
801 "iChannelNames=%d iTerminal=%d\n",
802 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
803 d->bNrChannels, UGETW(d->wChannelConfig),
804 d->iChannelNames, d->iTerminal));
809 uaudio_add_output(struct uaudio_softc *sc, usb_descriptor_t *v,
810 usb_descriptor_t **dps)
813 struct usb_audio_output_terminal *d =
814 (struct usb_audio_output_terminal *)v;
816 DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
817 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
818 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
819 d->bSourceId, d->iTerminal));
824 uaudio_add_mixer(struct uaudio_softc *sc, usb_descriptor_t *v,
825 usb_descriptor_t **dps)
827 struct usb_audio_mixer_unit *d = (struct usb_audio_mixer_unit *)v;
828 struct usb_audio_mixer_unit_1 *d1;
829 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
833 DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
834 d->bUnitId, d->bNrInPins));
836 /* Compute the number of input channels */
838 for (i = 0; i < d->bNrInPins; i++)
839 ichs += uaudio_get_cluster(d->baSourceId[i], dps).bNrChannels;
841 /* and the number of output channels */
842 d1 = (struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
843 ochs = d1->bNrChannels;
844 DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
847 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
848 #if !defined(__DragonFly__)
851 mix.type = MIX_SIGNED_16;
852 #if !defined(__DragonFly__) /* XXXXX */
853 mix.ctlunit = AudioNvolume;
856 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
857 for (p = i = 0; i < d->bNrInPins; i++) {
858 chs = uaudio_get_cluster(d->baSourceId[i], dps).bNrChannels;
860 for (c = 0; c < chs; c++) {
862 for (o = 0; o < ochs; o++) {
863 bno = (p + c) * ochs + o;
870 if (mc == chs && chs <= MIX_MAX_CHAN) {
872 for (c = 0; c < chs; c++)
873 for (o = 0; o < ochs; o++) {
874 bno = (p + c) * ochs + o;
879 #if !defined(__DragonFly__)
880 ksprintf(mix.ctlname, "mix%d-%s", d->bUnitId,
881 uaudio_id_name(sc, dps, d->baSourceId[i]));
884 uaudio_mixer_add_ctl(sc, &mix);
895 uaudio_add_selector(struct uaudio_softc *sc, usb_descriptor_t *v,
896 usb_descriptor_t **dps)
899 struct usb_audio_selector_unit *d =
900 (struct usb_audio_selector_unit *)v;
902 DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
903 d->bUnitId, d->bNrInPins));
905 kprintf("uaudio_add_selector: NOT IMPLEMENTED\n");
909 uaudio_add_feature(struct uaudio_softc *sc, usb_descriptor_t *v,
910 usb_descriptor_t **dps)
912 struct usb_audio_feature_unit *d = (struct usb_audio_feature_unit *)v;
913 uByte *ctls = d->bmaControls;
914 int ctlsize = d->bControlSize;
915 int nchan = (d->bLength - 7) / ctlsize;
916 #if !defined(__DragonFly__)
917 int srcId = d->bSourceId;
919 u_int fumask, mmask, cmask;
921 int chan, ctl, i, unit;
923 #define GET(i) (ctls[(i)*ctlsize] | \
924 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
927 /* Figure out what we can control */
928 for (cmask = 0, chan = 1; chan < nchan; chan++) {
929 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
934 #if !defined(__DragonFly__)
935 DPRINTFN(1,("uaudio_add_feature: bUnitId=%d bSourceId=%d, "
936 "%d channels, mmask=0x%04x, cmask=0x%04x\n",
937 d->bUnitId, srcId, nchan, mmask, cmask));
940 if (nchan > MIX_MAX_CHAN)
941 nchan = MIX_MAX_CHAN;
943 mix.wIndex = MAKE(unit, sc->sc_ac_iface);
944 for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
945 fumask = FU_MASK(ctl);
946 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
948 if (mmask & fumask) {
950 mix.wValue[0] = MAKE(ctl, 0);
951 } else if (cmask & fumask) {
952 mix.nchan = nchan - 1;
953 for (i = 1; i < nchan; i++) {
955 mix.wValue[i-1] = MAKE(ctl, i);
957 mix.wValue[i-1] = -1;
964 #if !defined(__DragonFly__)
965 mix.class = -1; /* XXX */
969 mix.type = MIX_ON_OFF;
970 #if defined(__DragonFly__)
971 mix.ctl = SOUND_MIXER_NRDEVICES;
973 ksprintf(mix.ctlname, "fea%d-%s-%s", unit,
974 uaudio_id_name(sc, dps, srcId),
980 mix.type = MIX_SIGNED_16;
981 #if defined(__DragonFly__)
982 /* mix.ctl = SOUND_MIXER_VOLUME; */
983 mix.ctl = SOUND_MIXER_PCM;
985 ksprintf(mix.ctlname, "fea%d-%s-%s", unit,
986 uaudio_id_name(sc, dps, srcId),
988 mix.ctlunit = AudioNvolume;
992 mix.type = MIX_SIGNED_8;
993 #if defined(__DragonFly__)
994 mix.ctl = SOUND_MIXER_BASS;
996 ksprintf(mix.ctlname, "fea%d-%s-%s", unit,
997 uaudio_id_name(sc, dps, srcId),
999 mix.ctlunit = AudioNbass;
1003 mix.type = MIX_SIGNED_8;
1004 #if defined(__DragonFly__)
1005 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1007 ksprintf(mix.ctlname, "fea%d-%s-%s", unit,
1008 uaudio_id_name(sc, dps, srcId),
1010 mix.ctlunit = AudioNmid;
1013 case TREBLE_CONTROL:
1014 mix.type = MIX_SIGNED_8;
1015 #if defined(__DragonFly__)
1016 mix.ctl = SOUND_MIXER_TREBLE;
1018 ksprintf(mix.ctlname, "fea%d-%s-%s", unit,
1019 uaudio_id_name(sc, dps, srcId),
1021 mix.ctlunit = AudioNtreble;
1024 case GRAPHIC_EQUALIZER_CONTROL:
1025 continue; /* XXX don't add anything */
1028 mix.type = MIX_ON_OFF;
1029 #if defined(__DragonFly__)
1030 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1032 ksprintf(mix.ctlname, "fea%d-%s-%s", unit,
1033 uaudio_id_name(sc, dps, srcId),
1039 mix.type = MIX_UNSIGNED_16;
1040 #if defined(__DragonFly__)
1041 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1043 ksprintf(mix.ctlname, "fea%d-%s-%s", unit,
1044 uaudio_id_name(sc, dps, srcId),
1046 mix.ctlunit = "4 ms";
1049 case BASS_BOOST_CONTROL:
1050 mix.type = MIX_ON_OFF;
1051 #if defined(__DragonFly__)
1052 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1054 ksprintf(mix.ctlname, "fea%d-%s-%s", unit,
1055 uaudio_id_name(sc, dps, srcId),
1060 case LOUDNESS_CONTROL:
1061 mix.type = MIX_ON_OFF;
1062 #if defined(__DragonFly__)
1063 mix.ctl = SOUND_MIXER_LOUD; /* Is this correct ? */
1065 ksprintf(mix.ctlname, "fea%d-%s-%s", unit,
1066 uaudio_id_name(sc, dps, srcId),
1072 uaudio_mixer_add_ctl(sc, &mix);
1077 uaudio_add_processing_updown(struct uaudio_softc *sc, usb_descriptor_t *v,
1078 usb_descriptor_t **dps)
1080 struct usb_audio_processing_unit *d =
1081 (struct usb_audio_processing_unit *)v;
1082 struct usb_audio_processing_unit_1 *d1 =
1083 (struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
1084 struct usb_audio_processing_unit_updown *ud =
1085 (struct usb_audio_processing_unit_updown *)
1086 &d1->bmControls[d1->bControlSize];
1087 struct mixerctl mix;
1090 DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
1091 d->bUnitId, ud->bNrModes));
1093 if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
1094 DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
1098 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1100 mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
1101 #if !defined(__DragonFly__)
1104 mix.type = MIX_ON_OFF; /* XXX */
1105 #if !defined(__DragonFly__)
1107 ksprintf(mix.ctlname, "pro%d-mode", d->bUnitId);
1110 for (i = 0; i < ud->bNrModes; i++) {
1111 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
1112 i, UGETW(ud->waModes[i])));
1115 uaudio_mixer_add_ctl(sc, &mix);
1119 uaudio_add_processing(struct uaudio_softc *sc, usb_descriptor_t *v,
1120 usb_descriptor_t **dps)
1122 struct usb_audio_processing_unit *d =
1123 (struct usb_audio_processing_unit *)v;
1124 struct usb_audio_processing_unit_1 *d1 =
1125 (struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
1126 int ptype = UGETW(d->wProcessType);
1127 struct mixerctl mix;
1129 DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
1130 "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
1132 if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
1133 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1135 mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
1136 #if !defined(__DragonFly__)
1139 mix.type = MIX_ON_OFF;
1140 #if !defined(__DragonFly__)
1142 ksprintf(mix.ctlname, "pro%d.%d-enable", d->bUnitId, ptype);
1144 uaudio_mixer_add_ctl(sc, &mix);
1148 case UPDOWNMIX_PROCESS:
1149 uaudio_add_processing_updown(sc, v, dps);
1151 case DOLBY_PROLOGIC_PROCESS:
1152 case P3D_STEREO_EXTENDER_PROCESS:
1153 case REVERBATION_PROCESS:
1154 case CHORUS_PROCESS:
1155 case DYN_RANGE_COMP_PROCESS:
1158 kprintf("uaudio_add_processing: unit %d, type=%d not impl.\n",
1166 uaudio_add_extension(struct uaudio_softc *sc, usb_descriptor_t *v,
1167 usb_descriptor_t **dps)
1169 struct usb_audio_extension_unit *d =
1170 (struct usb_audio_extension_unit *)v;
1171 struct usb_audio_extension_unit_1 *d1 =
1172 (struct usb_audio_extension_unit_1 *)&d->baSourceId[d->bNrInPins];
1173 struct mixerctl mix;
1175 DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
1176 d->bUnitId, d->bNrInPins));
1178 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
1181 if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
1182 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1184 mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
1185 #if !defined(__DragonFly__)
1188 mix.type = MIX_ON_OFF;
1189 #if !defined(__DragonFly__)
1191 ksprintf(mix.ctlname, "ext%d-enable", d->bUnitId);
1193 uaudio_mixer_add_ctl(sc, &mix);
1198 uaudio_identify(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc)
1202 err = uaudio_identify_ac(sc, cdesc);
1205 return (uaudio_identify_as(sc, cdesc));
1209 uaudio_add_alt(struct uaudio_softc *sc, struct as_info *ai)
1211 size_t len = sizeof(*ai) * (sc->sc_nalts + 1);
1212 struct as_info *nai = sc->sc_nalts == 0 ?
1213 kmalloc(len, M_USBDEV, M_NOWAIT) :
1214 krealloc(sc->sc_alts, len, M_USBDEV, M_NOWAIT);
1217 kprintf("uaudio_add_alt: no memory\n");
1222 DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
1223 ai->alt, ai->encoding));
1224 sc->sc_alts[sc->sc_nalts++] = *ai;
1228 uaudio_process_as(struct uaudio_softc *sc, char *buf, int *offsp,
1229 int size, usb_interface_descriptor_t *id)
1230 #define offs (*offsp)
1232 struct usb_audio_streaming_interface_descriptor *asid;
1233 struct usb_audio_streaming_type1_descriptor *asf1d;
1234 usb_endpoint_descriptor_audio_t *ed;
1235 struct usb_audio_streaming_endpoint_descriptor *sed;
1236 int format, chan, prec, enc;
1240 asid = (void *)(buf + offs);
1241 if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
1242 asid->bDescriptorSubtype != AS_GENERAL)
1243 return (USBD_INVAL);
1244 offs += asid->bLength;
1246 return (USBD_INVAL);
1247 asf1d = (void *)(buf + offs);
1248 if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
1249 asf1d->bDescriptorSubtype != FORMAT_TYPE)
1250 return (USBD_INVAL);
1251 offs += asf1d->bLength;
1253 return (USBD_INVAL);
1255 if (asf1d->bFormatType != FORMAT_TYPE_I) {
1256 kprintf("%s: ignored setting with type %d format\n",
1257 USBDEVNAME(sc->sc_dev), UGETW(asid->wFormatTag));
1258 return (USBD_NORMAL_COMPLETION);
1261 ed = (void *)(buf + offs);
1262 if (ed->bDescriptorType != UDESC_ENDPOINT)
1263 return (USBD_INVAL);
1264 DPRINTF(("uaudio_process_as: endpoint bLength=%d bDescriptorType=%d "
1265 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
1266 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
1267 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
1268 ed->bmAttributes, UGETW(ed->wMaxPacketSize),
1269 ed->bInterval, ed->bRefresh, ed->bSynchAddress));
1270 offs += ed->bLength;
1272 return (USBD_INVAL);
1273 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
1274 return (USBD_INVAL);
1276 dir = UE_GET_DIR(ed->bEndpointAddress);
1277 type = UE_GET_ISO_TYPE(ed->bmAttributes);
1278 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
1279 dir == UE_DIR_IN && type == UE_ISO_ADAPT)
1280 type = UE_ISO_ASYNC;
1282 /* We can't handle endpoints that need a sync pipe yet. */
1283 if (dir == UE_DIR_IN ? type == UE_ISO_ADAPT : type == UE_ISO_ASYNC) {
1284 kprintf("%s: ignored %sput endpoint of type %s\n",
1285 USBDEVNAME(sc->sc_dev),
1286 dir == UE_DIR_IN ? "in" : "out",
1287 dir == UE_DIR_IN ? "adaptive" : "async");
1288 return (USBD_NORMAL_COMPLETION);
1291 sed = (void *)(buf + offs);
1292 if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
1293 sed->bDescriptorSubtype != AS_GENERAL)
1294 return (USBD_INVAL);
1295 offs += sed->bLength;
1297 return (USBD_INVAL);
1299 format = UGETW(asid->wFormatTag);
1300 chan = asf1d->bNrChannels;
1301 prec = asf1d->bBitResolution;
1302 if (prec != 8 && prec != 16) {
1304 kprintf("%s: ignored setting with precision %d\n",
1305 USBDEVNAME(sc->sc_dev), prec);
1307 return (USBD_NORMAL_COMPLETION);
1311 sc->sc_altflags |= prec == 8 ? HAS_8 : HAS_16;
1312 enc = AUDIO_ENCODING_SLINEAR_LE;
1315 enc = AUDIO_ENCODING_ULINEAR_LE;
1316 sc->sc_altflags |= HAS_8U;
1319 enc = AUDIO_ENCODING_ALAW;
1320 sc->sc_altflags |= HAS_ALAW;
1323 enc = AUDIO_ENCODING_ULAW;
1324 sc->sc_altflags |= HAS_MULAW;
1327 kprintf("%s: ignored setting with format %d\n",
1328 USBDEVNAME(sc->sc_dev), format);
1329 return (USBD_NORMAL_COMPLETION);
1331 DPRINTFN(1,("uaudio_identify: alt=%d enc=%d chan=%d prec=%d\n",
1332 id->bAlternateSetting, enc, chan, prec));
1333 ai.alt = id->bAlternateSetting;
1337 ai.asf1desc = asf1d;
1338 uaudio_add_alt(sc, &ai);
1339 sc->sc_chan.terminal = asid->bTerminalLink; /* XXX */
1340 sc->sc_chan.dir |= dir == UE_DIR_OUT ? AUMODE_PLAY : AUMODE_RECORD;
1341 return (USBD_NORMAL_COMPLETION);
1346 uaudio_identify_as(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc)
1348 usb_interface_descriptor_t *id;
1353 size = UGETW(cdesc->wTotalLength);
1354 buf = (char *)cdesc;
1356 /* Locate the AudioStreaming interface descriptor. */
1358 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
1360 return (USBD_INVAL);
1362 sc->sc_chan.terminal = -1;
1363 sc->sc_chan.dir = 0;
1365 /* Loop through all the alternate settings. */
1366 while (offs <= size) {
1367 DPRINTFN(2, ("uaudio_identify: interface %d\n",
1368 id->bInterfaceNumber));
1369 switch (id->bNumEndpoints) {
1371 DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
1372 id->bAlternateSetting));
1373 sc->sc_nullalt = id->bAlternateSetting;
1376 err = uaudio_process_as(sc, buf, &offs, size, id);
1380 kprintf("%s: ignored audio interface with %d "
1382 USBDEVNAME(sc->sc_dev), id->bNumEndpoints);
1386 id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
1391 return (USBD_INVAL);
1392 DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
1393 if (sc->sc_chan.terminal < 0) {
1394 kprintf("%s: no useable endpoint found\n",
1395 USBDEVNAME(sc->sc_dev));
1396 return (USBD_INVAL);
1399 #ifndef NO_RECORDING
1400 if (sc->sc_chan.dir == (AUMODE_PLAY | AUMODE_RECORD))
1401 sc->sc_props |= AUDIO_PROP_FULLDUPLEX;
1403 return (USBD_NORMAL_COMPLETION);
1407 uaudio_identify_ac(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc)
1409 usb_interface_descriptor_t *id;
1410 struct usb_audio_control_descriptor *acdp;
1411 usb_descriptor_t *dp, *dps[256];
1412 char *buf, *ibuf, *ibufend;
1413 int size, offs, aclen, ndps, i;
1415 size = UGETW(cdesc->wTotalLength);
1416 buf = (char *)cdesc;
1418 /* Locate the AudioControl interface descriptor. */
1420 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
1422 return (USBD_INVAL);
1423 if (offs + sizeof *acdp > size)
1424 return (USBD_INVAL);
1425 sc->sc_ac_iface = id->bInterfaceNumber;
1426 DPRINTFN(2,("uaudio_identify: AC interface is %d\n", sc->sc_ac_iface));
1428 /* A class-specific AC interface header should follow. */
1430 acdp = (struct usb_audio_control_descriptor *)ibuf;
1431 if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
1432 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
1433 return (USBD_INVAL);
1434 aclen = UGETW(acdp->wTotalLength);
1435 if (offs + aclen > size)
1436 return (USBD_INVAL);
1438 if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
1439 UGETW(acdp->bcdADC) != UAUDIO_VERSION)
1440 return (USBD_INVAL);
1442 sc->sc_audio_rev = UGETW(acdp->bcdADC);
1443 DPRINTFN(2,("uaudio_identify: found AC header, vers=%03x, len=%d\n",
1444 sc->sc_audio_rev, aclen));
1446 sc->sc_nullalt = -1;
1448 /* Scan through all the AC specific descriptors */
1449 ibufend = ibuf + aclen;
1450 dp = (usb_descriptor_t *)ibuf;
1452 memset(dps, 0, sizeof dps);
1454 ibuf += dp->bLength;
1455 if (ibuf >= ibufend)
1457 dp = (usb_descriptor_t *)ibuf;
1458 if (ibuf + dp->bLength > ibufend)
1459 return (USBD_INVAL);
1460 if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
1461 kprintf("uaudio_identify: skip desc type=0x%02x\n",
1462 dp->bDescriptorType);
1465 i = ((struct usb_audio_input_terminal *)dp)->bTerminalId;
1472 for (i = 0; i < ndps; i++) {
1476 DPRINTF(("uaudio_identify: subtype=%d\n",
1477 dp->bDescriptorSubtype));
1478 switch (dp->bDescriptorSubtype) {
1479 case UDESCSUB_AC_HEADER:
1480 kprintf("uaudio_identify: unexpected AC header\n");
1482 case UDESCSUB_AC_INPUT:
1483 uaudio_add_input(sc, dp, dps);
1485 case UDESCSUB_AC_OUTPUT:
1486 uaudio_add_output(sc, dp, dps);
1488 case UDESCSUB_AC_MIXER:
1489 uaudio_add_mixer(sc, dp, dps);
1491 case UDESCSUB_AC_SELECTOR:
1492 uaudio_add_selector(sc, dp, dps);
1494 case UDESCSUB_AC_FEATURE:
1495 uaudio_add_feature(sc, dp, dps);
1497 case UDESCSUB_AC_PROCESSING:
1498 uaudio_add_processing(sc, dp, dps);
1500 case UDESCSUB_AC_EXTENSION:
1501 uaudio_add_extension(sc, dp, dps);
1504 kprintf("uaudio_identify: bad AC desc subtype=0x%02x\n",
1505 dp->bDescriptorSubtype);
1509 return (USBD_NORMAL_COMPLETION);
1512 #if defined(__NetBSD__) || defined(__OpenBSD__)
1514 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
1516 struct uaudio_softc *sc = addr;
1517 struct mixerctl *mc;
1520 DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index));
1525 nctls = sc->sc_nctls;
1527 if (n < 0 || n >= nctls) {
1528 switch (n - nctls) {
1530 mi->type = AUDIO_MIXER_CLASS;
1531 mi->mixer_class = nctls + UAC_OUTPUT;
1532 mi->next = mi->prev = AUDIO_MIXER_LAST;
1533 strcpy(mi->label.name, AudioCoutputs);
1536 mi->type = AUDIO_MIXER_CLASS;
1537 mi->mixer_class = nctls + UAC_INPUT;
1538 mi->next = mi->prev = AUDIO_MIXER_LAST;
1539 strcpy(mi->label.name, AudioCinputs);
1542 mi->type = AUDIO_MIXER_CLASS;
1543 mi->mixer_class = nctls + UAC_EQUAL;
1544 mi->next = mi->prev = AUDIO_MIXER_LAST;
1545 strcpy(mi->label.name, AudioCequalization);
1551 mc = &sc->sc_ctls[n];
1552 strncpy(mi->label.name, mc->ctlname, MAX_AUDIO_DEV_LEN);
1553 mi->mixer_class = mc->class;
1554 mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */
1557 mi->type = AUDIO_MIXER_ENUM;
1558 mi->un.e.num_mem = 2;
1559 strcpy(mi->un.e.member[0].label.name, AudioNoff);
1560 mi->un.e.member[0].ord = 0;
1561 strcpy(mi->un.e.member[1].label.name, AudioNon);
1562 mi->un.e.member[1].ord = 1;
1565 mi->type = AUDIO_MIXER_VALUE;
1566 strncpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN);
1567 mi->un.v.num_channels = mc->nchan;
1568 mi->un.v.delta = mc->delta;
1575 uaudio_open(void *addr, int flags)
1577 struct uaudio_softc *sc = addr;
1579 DPRINTF(("uaudio_open: sc=%p\n", sc));
1583 if (sc->sc_chan.terminal < 0)
1586 if ((flags & FREAD) && !(sc->sc_chan.dir & AUMODE_RECORD))
1588 if ((flags & FWRITE) && !(sc->sc_chan.dir & AUMODE_PLAY))
1591 sc->sc_chan.intr = 0;
1597 * Close function is called from a critical section.
1600 uaudio_close(void *addr)
1602 struct uaudio_softc *sc = addr;
1607 DPRINTF(("uaudio_close: sc=%p\n", sc));
1608 uaudio_halt_in_dma(sc);
1609 uaudio_halt_out_dma(sc);
1611 sc->sc_chan.intr = 0;
1615 uaudio_drain(void *addr)
1617 struct uaudio_softc *sc = addr;
1622 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
1628 uaudio_halt_out_dma(void *addr)
1630 struct uaudio_softc *sc = addr;
1635 DPRINTF(("uaudio_halt_out_dma: enter\n"));
1636 if (sc->sc_chan.pipe != NULL) {
1637 uaudio_chan_close(sc, &sc->sc_chan);
1638 sc->sc_chan.pipe = 0;
1639 uaudio_chan_free_buffers(sc, &sc->sc_chan);
1645 uaudio_halt_in_dma(void *addr)
1647 struct uaudio_softc *sc = addr;
1649 DPRINTF(("uaudio_halt_in_dma: enter\n"));
1650 if (sc->sc_chan.pipe != NULL) {
1651 uaudio_chan_close(sc, &sc->sc_chan);
1652 sc->sc_chan.pipe = 0;
1653 uaudio_chan_free_buffers(sc, &sc->sc_chan);
1659 uaudio_getdev(void *addr, struct audio_device *retp)
1661 struct uaudio_softc *sc = addr;
1663 DPRINTF(("uaudio_mixer_getdev:\n"));
1667 *retp = uaudio_device;
1672 * Make sure the block size is large enough to hold all outstanding transfers.
1675 uaudio_round_blocksize(void *addr, int blk)
1677 struct uaudio_softc *sc = addr;
1683 bpf = sc->sc_chan.bytes_per_frame + sc->sc_chan.sample_size;
1685 bpf *= UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
1687 bpf = (bpf + 15) &~ 15;
1694 kprintf("uaudio_round_blocksize: blk=%d\n", blk);
1699 DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk));
1704 uaudio_get_props(void *addr)
1706 struct uaudio_softc *sc = addr;
1708 return (sc->sc_props);
1710 #endif /* NetBSD or OpenBSD */
1714 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
1715 int wIndex, int len)
1717 usb_device_request_t req;
1728 req.bmRequestType = type;
1729 req.bRequest = which;
1730 USETW(req.wValue, wValue);
1731 USETW(req.wIndex, wIndex);
1732 USETW(req.wLength, len);
1733 DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
1734 "wIndex=0x%04x len=%d\n",
1735 type, which, wValue, wIndex, len));
1736 err = usbd_do_request(sc->sc_udev, &req, &data);
1738 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
1746 val = data[0] | (data[1] << 8);
1749 DPRINTF(("uaudio_get: bad length=%d\n", len));
1752 DPRINTFN(2,("uaudio_get: val=%d\n", val));
1757 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
1758 int wIndex, int len, int val)
1760 usb_device_request_t req;
1770 req.bmRequestType = type;
1771 req.bRequest = which;
1772 USETW(req.wValue, wValue);
1773 USETW(req.wIndex, wIndex);
1774 USETW(req.wLength, len);
1786 DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
1787 "wIndex=0x%04x len=%d, val=%d\n",
1788 type, which, wValue, wIndex, len, val & 0xffff));
1789 err = usbd_do_request(sc->sc_udev, &req, &data);
1792 DPRINTF(("uaudio_set: err=%d\n", err));
1797 uaudio_signext(int type, int val)
1799 if (!MIX_UNSIGNED(type)) {
1800 if (MIX_SIZE(type) == 2)
1808 #if defined(__NetBSD__) || defined(__OpenBSD__)
1810 uaudio_value2bsd(struct mixerctl *mc, int val)
1812 DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
1813 mc->type, val, mc->minval, mc->maxval));
1814 if (mc->type == MIX_ON_OFF)
1817 val = ((uaudio_signext(mc->type, val) - mc->minval) * 256
1818 + mc->mul/2) / mc->mul;
1819 DPRINTFN(5, ("val'=%d\n", val));
1825 uaudio_bsd2value(struct mixerctl *mc, int val)
1827 DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
1828 mc->type, val, mc->minval, mc->maxval));
1829 if (mc->type == MIX_ON_OFF)
1832 val = (val + mc->delta/2) * mc->mul / 256 + mc->minval;
1833 DPRINTFN(5, ("val'=%d\n", val));
1837 #if defined(__NetBSD__) || defined(__OpenBSD__)
1839 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
1844 DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan));
1845 val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
1846 mc->wIndex, MIX_SIZE(mc->type));
1847 return (uaudio_value2bsd(mc, val));
1852 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
1855 val = uaudio_bsd2value(mc, val);
1856 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
1857 mc->wIndex, MIX_SIZE(mc->type), val);
1860 #if defined(__NetBSD__) || defined(__OpenBSD__)
1862 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
1864 struct uaudio_softc *sc = addr;
1865 struct mixerctl *mc;
1866 int i, n, vals[MIX_MAX_CHAN], val;
1868 DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev));
1874 if (n < 0 || n >= sc->sc_nctls)
1876 mc = &sc->sc_ctls[n];
1878 if (mc->type == MIX_ON_OFF) {
1879 if (cp->type != AUDIO_MIXER_ENUM)
1881 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
1883 if (cp->type != AUDIO_MIXER_VALUE)
1885 if (cp->un.value.num_channels != 1 &&
1886 cp->un.value.num_channels != mc->nchan)
1888 for (i = 0; i < mc->nchan; i++)
1889 vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
1890 if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
1891 for (val = 0, i = 0; i < mc->nchan; i++)
1893 vals[0] = val / mc->nchan;
1895 for (i = 0; i < cp->un.value.num_channels; i++)
1896 cp->un.value.level[i] = vals[i];
1903 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
1905 struct uaudio_softc *sc = addr;
1906 struct mixerctl *mc;
1907 int i, n, vals[MIX_MAX_CHAN];
1909 DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev));
1914 if (n < 0 || n >= sc->sc_nctls)
1916 mc = &sc->sc_ctls[n];
1918 if (mc->type == MIX_ON_OFF) {
1919 if (cp->type != AUDIO_MIXER_ENUM)
1921 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
1923 if (cp->type != AUDIO_MIXER_VALUE)
1925 if (cp->un.value.num_channels == 1)
1926 for (i = 0; i < mc->nchan; i++)
1927 vals[i] = cp->un.value.level[0];
1928 else if (cp->un.value.num_channels == mc->nchan)
1929 for (i = 0; i < mc->nchan; i++)
1930 vals[i] = cp->un.value.level[i];
1933 for (i = 0; i < mc->nchan; i++)
1934 uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
1940 uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
1941 void (*intr)(void *), void *arg,
1942 struct audio_params *param)
1944 struct uaudio_softc *sc = addr;
1945 struct chan *ch = &sc->sc_chan;
1952 DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
1953 "blksize=%d\n", sc, start, end, blksize));
1955 uaudio_chan_set_param(ch, param, start, end, blksize);
1956 DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
1957 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
1960 err = uaudio_chan_alloc_buffers(sc, ch);
1964 err = uaudio_chan_open(sc, ch);
1966 uaudio_chan_free_buffers(sc, ch);
1970 sc->sc_chan.intr = intr;
1971 sc->sc_chan.arg = arg;
1974 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
1975 uaudio_chan_rtransfer(ch);
1982 uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
1983 void (*intr)(void *), void *arg,
1984 struct audio_params *param)
1986 struct uaudio_softc *sc = addr;
1987 struct chan *ch = &sc->sc_chan;
1994 DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
1995 "blksize=%d\n", sc, start, end, blksize));
1997 uaudio_chan_set_param(ch, param, start, end, blksize);
1998 DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
1999 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2002 err = uaudio_chan_alloc_buffers(sc, ch);
2006 err = uaudio_chan_open(sc, ch);
2008 uaudio_chan_free_buffers(sc, ch);
2012 sc->sc_chan.intr = intr;
2013 sc->sc_chan.arg = arg;
2016 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
2017 uaudio_chan_ptransfer(ch);
2022 #endif /* NetBSD or OpenBSD */
2024 /* Set up a pipe for a channel. */
2026 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
2028 struct as_info *as = &sc->sc_alts[sc->sc_curaltidx];
2029 int endpt = as->edesc->bEndpointAddress;
2035 DPRINTF(("uaudio_open_chan: endpt=0x%02x, speed=%d, alt=%d\n",
2036 endpt, ch->sample_rate, as->alt));
2038 /* Set alternate interface corresponding to the mode. */
2039 err = usbd_set_interface(as->ifaceh, as->alt);
2043 /* Some devices do not support this request, so ignore errors. */
2045 err = uaudio_set_speed(sc, endpt, ch->sample_rate);
2047 DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
2050 (void)uaudio_set_speed(sc, endpt, ch->sample_rate);
2053 DPRINTF(("uaudio_open_chan: create pipe to 0x%02x\n", endpt));
2054 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
2059 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
2061 struct as_info *as = &sc->sc_alts[sc->sc_curaltidx];
2066 if (sc->sc_nullalt >= 0) {
2067 DPRINTF(("uaudio_close_chan: set null alt=%d\n",
2069 usbd_set_interface(as->ifaceh, sc->sc_nullalt);
2071 usbd_abort_pipe(ch->pipe);
2072 usbd_close_pipe(ch->pipe);
2076 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
2078 usbd_xfer_handle xfer;
2082 size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
2083 for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
2084 xfer = usbd_alloc_xfer(sc->sc_udev);
2087 ch->chanbufs[i].xfer = xfer;
2088 buf = usbd_alloc_buffer(xfer, size);
2093 ch->chanbufs[i].buffer = buf;
2094 ch->chanbufs[i].chan = ch;
2097 return (USBD_NORMAL_COMPLETION);
2101 /* implicit buffer free */
2102 usbd_free_xfer(ch->chanbufs[i].xfer);
2103 return (USBD_NOMEM);
2107 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
2111 for (i = 0; i < UAUDIO_NCHANBUFS; i++)
2112 usbd_free_xfer(ch->chanbufs[i].xfer);
2115 /* Called from a critical section. */
2117 uaudio_chan_ptransfer(struct chan *ch)
2120 int i, n, size, residue, total;
2122 if (ch->sc->sc_dying)
2125 /* Pick the next channel buffer. */
2126 cb = &ch->chanbufs[ch->curchanbuf];
2127 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2130 /* Compute the size of each frame in the next transfer. */
2131 residue = ch->residue;
2133 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2134 size = ch->bytes_per_frame;
2135 residue += ch->fraction;
2136 if (residue >= USB_FRAMES_PER_SECOND) {
2138 size += ch->sample_size;
2139 residue -= USB_FRAMES_PER_SECOND;
2141 cb->sizes[i] = size;
2144 ch->residue = residue;
2148 * Transfer data from upper layer buffer to channel buffer, taking
2149 * care of wrapping the upper layer buffer.
2151 n = min(total, ch->end - ch->cur);
2152 memcpy(cb->buffer, ch->cur, n);
2154 if (ch->cur >= ch->end)
2155 ch->cur = ch->start;
2158 memcpy(cb->buffer + n, ch->cur, total);
2163 if (uaudiodebug > 8) {
2164 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
2165 cb->buffer, ch->residue));
2166 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2167 DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
2172 DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
2173 /* Fill the request */
2174 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
2175 UAUDIO_NFRAMES, USBD_NO_COPY,
2178 (void)usbd_transfer(cb->xfer);
2182 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
2185 struct chanbuf *cb = priv;
2186 struct chan *ch = cb->chan;
2189 /* Return if we are aborting. */
2190 if (status == USBD_CANCELLED)
2193 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2194 DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
2195 count, ch->transferred));
2197 if (count != cb->size) {
2198 kprintf("uaudio_chan_pintr: count(%d) != size(%d)\n",
2203 ch->transferred += cb->size;
2205 chn_intr(ch->pcm_ch);
2208 /* start next transfer */
2209 uaudio_chan_ptransfer(ch);
2212 /* Called from a critical section. */
2214 uaudio_chan_rtransfer(struct chan *ch)
2217 int i, size, residue, total;
2219 if (ch->sc->sc_dying)
2222 /* Pick the next channel buffer. */
2223 cb = &ch->chanbufs[ch->curchanbuf];
2224 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2227 /* Compute the size of each frame in the next transfer. */
2228 residue = ch->residue;
2230 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2231 size = ch->bytes_per_frame;
2232 residue += ch->fraction;
2233 if (residue >= USB_FRAMES_PER_SECOND) {
2235 size += ch->sample_size;
2236 residue -= USB_FRAMES_PER_SECOND;
2238 cb->sizes[i] = size;
2241 ch->residue = residue;
2245 if (uaudiodebug > 8) {
2246 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
2247 cb->buffer, ch->residue));
2248 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2249 DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
2254 DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
2255 /* Fill the request */
2256 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
2257 UAUDIO_NFRAMES, USBD_NO_COPY,
2260 (void)usbd_transfer(cb->xfer);
2264 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
2267 struct chanbuf *cb = priv;
2268 struct chan *ch = cb->chan;
2272 /* Return if we are aborting. */
2273 if (status == USBD_CANCELLED)
2276 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2277 DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
2278 count, ch->transferred));
2280 if (count < cb->size) {
2281 /* if the device fails to keep up, copy last byte */
2282 u_char b = count ? cb->buffer[count-1] : 0;
2283 while (count < cb->size)
2284 cb->buffer[count++] = b;
2288 if (count != cb->size) {
2289 kprintf("uaudio_chan_rintr: count(%d) != size(%d)\n",
2295 * Transfer data from channel buffer to upper layer buffer, taking
2296 * care of wrapping the upper layer buffer.
2298 n = min(count, ch->end - ch->cur);
2299 memcpy(ch->cur, cb->buffer, n);
2301 if (ch->cur >= ch->end)
2302 ch->cur = ch->start;
2304 memcpy(ch->cur, cb->buffer + n, count - n);
2305 ch->cur += count - n;
2308 /* Call back to upper layer */
2309 ch->transferred += cb->size;
2311 chn_intr(ch->pcm_ch);
2314 /* start next transfer */
2315 uaudio_chan_rtransfer(ch);
2318 #if defined(__NetBSD__) || defined(__OpenBSD__)
2320 uaudio_chan_set_param(struct chan *ch, struct audio_params *param,
2321 u_char *start, u_char *end, int blksize)
2323 int samples_per_frame, sample_size;
2325 sample_size = param->precision * param->channels / 8;
2326 samples_per_frame = param->sample_rate / USB_FRAMES_PER_SECOND;
2327 ch->fraction = param->sample_rate % USB_FRAMES_PER_SECOND;
2328 ch->sample_size = sample_size;
2329 ch->sample_rate = param->sample_rate;
2330 ch->bytes_per_frame = samples_per_frame * sample_size;
2336 ch->blksize = blksize;
2337 ch->transferred = 0;
2343 uaudio_set_params(void *addr, int setmode, int usemode,
2344 struct audio_params *play, struct audio_params *rec)
2346 struct uaudio_softc *sc = addr;
2347 int flags = sc->sc_altflags;
2350 void (*swcode)(void *, u_char *buf, int cnt);
2351 struct audio_params *p;
2357 if (sc->sc_chan.pipe != NULL)
2360 for (mode = AUMODE_RECORD; mode != -1;
2361 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
2362 if ((setmode & mode) == 0)
2364 if ((sc->sc_chan.dir & mode) == 0)
2367 p = mode == AUMODE_PLAY ? play : rec;
2373 case AUDIO_ENCODING_SLINEAR_BE:
2374 if (p->precision == 16) {
2375 swcode = swap_bytes;
2376 enc = AUDIO_ENCODING_SLINEAR_LE;
2377 } else if (p->precision == 8 && !(flags & HAS_8)) {
2378 swcode = change_sign8;
2379 enc = AUDIO_ENCODING_ULINEAR_LE;
2382 case AUDIO_ENCODING_SLINEAR_LE:
2383 if (p->precision == 8 && !(flags & HAS_8)) {
2384 swcode = change_sign8;
2385 enc = AUDIO_ENCODING_ULINEAR_LE;
2388 case AUDIO_ENCODING_ULINEAR_BE:
2389 if (p->precision == 16) {
2390 if (mode == AUMODE_PLAY)
2391 swcode = swap_bytes_change_sign16_le;
2393 swcode = change_sign16_swap_bytes_le;
2394 enc = AUDIO_ENCODING_SLINEAR_LE;
2395 } else if (p->precision == 8 && !(flags & HAS_8U)) {
2396 swcode = change_sign8;
2397 enc = AUDIO_ENCODING_SLINEAR_LE;
2400 case AUDIO_ENCODING_ULINEAR_LE:
2401 if (p->precision == 16) {
2402 swcode = change_sign16_le;
2403 enc = AUDIO_ENCODING_SLINEAR_LE;
2404 } else if (p->precision == 8 && !(flags & HAS_8U)) {
2405 swcode = change_sign8;
2406 enc = AUDIO_ENCODING_SLINEAR_LE;
2409 case AUDIO_ENCODING_ULAW:
2410 if (!(flags & HAS_MULAW)) {
2411 if (mode == AUMODE_PLAY &&
2413 swcode = mulaw_to_slinear16_le;
2415 enc = AUDIO_ENCODING_SLINEAR_LE;
2416 } else if (flags & HAS_8U) {
2417 if (mode == AUMODE_PLAY)
2418 swcode = mulaw_to_ulinear8;
2420 swcode = ulinear8_to_mulaw;
2421 enc = AUDIO_ENCODING_ULINEAR_LE;
2422 } else if (flags & HAS_8) {
2423 if (mode == AUMODE_PLAY)
2424 swcode = mulaw_to_slinear8;
2426 swcode = slinear8_to_mulaw;
2427 enc = AUDIO_ENCODING_SLINEAR_LE;
2432 case AUDIO_ENCODING_ALAW:
2433 if (!(flags & HAS_ALAW)) {
2434 if (mode == AUMODE_PLAY &&
2436 swcode = alaw_to_slinear16_le;
2438 enc = AUDIO_ENCODING_SLINEAR_LE;
2439 } else if (flags & HAS_8U) {
2440 if (mode == AUMODE_PLAY)
2441 swcode = alaw_to_ulinear8;
2443 swcode = ulinear8_to_alaw;
2444 enc = AUDIO_ENCODING_ULINEAR_LE;
2445 } else if (flags & HAS_8) {
2446 if (mode == AUMODE_PLAY)
2447 swcode = alaw_to_slinear8;
2449 swcode = slinear8_to_alaw;
2450 enc = AUDIO_ENCODING_SLINEAR_LE;
2458 /* XXX do some other conversions... */
2460 DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n",
2461 p->channels, p->precision, enc, p->sample_rate));
2463 for (i = 0; i < sc->sc_nalts; i++) {
2464 struct usb_audio_streaming_type1_descriptor *a1d =
2465 sc->sc_alts[i].asf1desc;
2466 if (p->channels == a1d->bNrChannels &&
2467 p->precision == a1d->bBitResolution &&
2468 enc == sc->sc_alts[i].encoding &&
2469 (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) ==
2470 UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) {
2471 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2472 DPRINTFN(2,("uaudio_set_params: cont %d-%d\n",
2473 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
2474 if (UA_SAMP_LO(a1d) < p->sample_rate &&
2475 p->sample_rate < UA_SAMP_HI(a1d))
2478 for (j = 0; j < a1d->bSamFreqType; j++) {
2479 DPRINTFN(2,("uaudio_set_params: disc #"
2480 "%d: %d\n", j, UA_GETSAMP(a1d, j)));
2481 /* XXX allow for some slack */
2482 if (UA_GETSAMP(a1d, j) ==
2492 p->sw_code = swcode;
2494 if (usemode == mode)
2495 sc->sc_curaltidx = i;
2498 DPRINTF(("uaudio_set_params: use altidx=%d, altno=%d\n",
2500 sc->sc_alts[sc->sc_curaltidx].idesc->bAlternateSetting));
2504 #endif /* NetBSD or OpenBSD */
2507 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
2509 usb_device_request_t req;
2512 DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
2513 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
2514 req.bRequest = SET_CUR;
2515 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
2516 USETW(req.wIndex, endpt);
2517 USETW(req.wLength, 3);
2519 data[1] = speed >> 8;
2520 data[2] = speed >> 16;
2522 return (usbd_do_request(sc->sc_udev, &req, &data));
2526 #if defined(__DragonFly__)
2527 /************************************************************/
2529 uaudio_init_params(struct uaudio_softc *sc, struct chan *ch)
2532 int samples_per_frame, sample_size;
2534 switch(ch->format & 0x0000FFFF) {
2536 enc = AUDIO_ENCODING_ULINEAR_LE;
2540 enc = AUDIO_ENCODING_SLINEAR_LE;
2543 case AFMT_A_LAW: /* ? */
2544 enc = AUDIO_ENCODING_ALAW;
2547 case AFMT_MU_LAW: /* ? */
2548 enc = AUDIO_ENCODING_ULAW;
2552 enc = AUDIO_ENCODING_SLINEAR_LE;
2556 enc = AUDIO_ENCODING_SLINEAR_BE;
2560 enc = AUDIO_ENCODING_ULINEAR_LE;
2564 enc = AUDIO_ENCODING_ULINEAR_BE;
2570 kprintf("Unknown format %x\n", ch->format);
2573 if (ch->format & AFMT_STEREO) {
2579 /* for (mode = ...... */
2580 for (i = 0; i < sc->sc_nalts; i++) {
2581 struct usb_audio_streaming_type1_descriptor *a1d =
2582 sc->sc_alts[i].asf1desc;
2583 if (ch->channels == a1d->bNrChannels &&
2584 ch->precision == a1d->bBitResolution &&
2586 enc == sc->sc_alts[i].encoding) {
2588 enc == sc->sc_alts[i].encoding &&
2589 (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) ==
2590 UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) {
2592 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2593 DPRINTFN(2,("uaudio_set_params: cont %d-%d\n",
2594 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
2595 if (UA_SAMP_LO(a1d) < ch->sample_rate &&
2596 ch->sample_rate < UA_SAMP_HI(a1d)) {
2597 sc->sc_curaltidx = i;
2601 for (j = 0; j < a1d->bSamFreqType; j++) {
2602 DPRINTFN(2,("uaudio_set_params: disc #"
2603 "%d: %d\n", j, UA_GETSAMP(a1d, j)));
2604 /* XXX allow for some slack */
2605 if (UA_GETSAMP(a1d, j) ==
2607 sc->sc_curaltidx = i;
2614 /* return (EINVAL); */
2618 p->sw_code = swcode;
2620 if (usemode == mode)
2621 sc->sc_curaltidx = i;
2625 sample_size = ch->precision * ch->channels / 8;
2626 samples_per_frame = ch->sample_rate / USB_FRAMES_PER_SECOND;
2627 ch->fraction = ch->sample_rate % USB_FRAMES_PER_SECOND;
2628 ch->sample_size = sample_size;
2629 ch->bytes_per_frame = samples_per_frame * sample_size;
2632 ch->cur = ch->start;
2633 ch->transferred = 0;
2638 uaudio_query_formats(device_t dev, u_int32_t *pfmt, u_int32_t *rfmt)
2643 struct uaudio_softc *sc;
2645 struct usb_audio_streaming_type1_descriptor *a1d;
2647 sc = device_get_softc(dev);
2649 for (i = 0; i < sc->sc_nalts; i++) {
2651 a1d = sc->sc_alts[i].asf1desc;
2652 prec = a1d->bBitResolution; /* precision */
2654 switch (sc->sc_alts[i].encoding) {
2655 case AUDIO_ENCODING_ULINEAR_LE:
2658 } else if (prec == 16) {
2662 case AUDIO_ENCODING_SLINEAR_LE:
2665 } else if (prec == 16) {
2669 case AUDIO_ENCODING_ULINEAR_BE:
2674 case AUDIO_ENCODING_SLINEAR_BE:
2679 case AUDIO_ENCODING_ALAW:
2684 case AUDIO_ENCODING_ULAW:
2692 if (a1d->bNrChannels == 2) { /* stereo/mono */
2694 } else if (a1d->bNrChannels != 1) {
2700 dir= UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
2701 if (dir == UE_DIR_OUT) {
2703 } else if (dir == UE_DIR_IN) {
2708 if ((pn > 8*2) || (rn > 8*2))
2717 uaudio_chan_set_param_pcm_dma_buff(device_t dev, u_char *start, u_char *end,
2718 struct pcm_channel *pc)
2720 struct uaudio_softc *sc;
2723 sc = device_get_softc(dev);
2735 uaudio_chan_set_param_blocksize(device_t dev, u_int32_t blocksize)
2737 struct uaudio_softc *sc;
2740 sc = device_get_softc(dev);
2743 ch->blksize = blocksize;
2749 uaudio_chan_set_param_speed(device_t dev, u_int32_t speed)
2751 struct uaudio_softc *sc;
2754 sc = device_get_softc(dev);
2757 ch->sample_rate = speed;
2763 uaudio_chan_getptr(device_t dev)
2765 struct uaudio_softc *sc;
2769 sc = device_get_softc(dev);
2772 ptr = ch->cur - ch->start;
2778 uaudio_chan_set_param_format(device_t dev, u_int32_t format)
2780 struct uaudio_softc *sc;
2783 sc = device_get_softc(dev);
2786 ch->format = format;
2792 uaudio_halt_out_dma(device_t dev)
2794 struct uaudio_softc *sc;
2796 sc = device_get_softc(dev);
2798 DPRINTF(("uaudio_halt_out_dma: enter\n"));
2799 if (sc->sc_chan.pipe != NULL) {
2800 uaudio_chan_close(sc, &sc->sc_chan);
2801 sc->sc_chan.pipe = 0;
2802 uaudio_chan_free_buffers(sc, &sc->sc_chan);
2808 uaudio_trigger_output(device_t dev)
2810 struct uaudio_softc *sc;
2815 sc = device_get_softc(dev);
2821 uaudio_init_params(sc, ch);
2823 err = uaudio_chan_alloc_buffers(sc, ch);
2827 err = uaudio_chan_open(sc, ch);
2829 uaudio_chan_free_buffers(sc, ch);
2834 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
2835 uaudio_chan_ptransfer(ch);
2842 uaudio_query_mix_info(device_t dev)
2846 struct uaudio_softc *sc;
2847 struct mixerctl *mc;
2849 sc = device_get_softc(dev);
2850 for (i=0; i < sc->sc_nctls; i++) {
2851 mc = &sc->sc_ctls[i];
2852 if (mc->ctl != SOUND_MIXER_NRDEVICES) {
2853 /* Set device mask bits.
2854 See /usr/include/machine/soundcard.h */
2855 mask |= (1 << mc->ctl);
2862 uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
2865 struct uaudio_softc *sc;
2866 struct mixerctl *mc;
2868 sc = device_get_softc(dev);
2869 for (i=0; i < sc->sc_nctls; i++) {
2870 mc = &sc->sc_ctls[i];
2871 if (mc->ctl == type) {
2872 if (mc->nchan == 2) {
2874 uaudio_ctl_set(sc, SET_CUR, mc, 1, (int)(right*256)/100);
2876 /* set Left or Mono */
2877 uaudio_ctl_set(sc, SET_CUR, mc, 0, (int)(left*256)/100);
2884 audio_attach_mi(device_t dev)
2887 struct sndcard_func *func;
2889 /* Attach the children. */
2891 func = kmalloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT);
2894 bzero(func, sizeof(*func));
2895 func->func = SCF_PCM;
2896 child = device_add_child(dev, "pcm", -1);
2897 device_set_ivars(child, func);
2899 bus_generic_attach(dev);
2901 return 0; /* XXXXX */
2904 DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, usbd_driver_load, 0);
2905 MODULE_VERSION(uaudio, 1);