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