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