1 /* $NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $ */ 2 /* $FreeBSD$ */ 3 4 /*- 5 * Copyright (c) 1999 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Lennart Augustsson (lennart@augustsson.net) at 10 * Carlstedt Research & Technology. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 /* 42 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf 43 * http://www.usb.org/developers/devclass_docs/frmts10.pdf 44 * http://www.usb.org/developers/devclass_docs/termt10.pdf 45 */ 46 47 #include <sys/cdefs.h> 48 #if defined(__NetBSD__) || defined(__OpenBSD__) 49 __KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $"); 50 #endif 51 52 /* 53 * Also merged: 54 * $NetBSD: uaudio.c,v 1.94 2005/01/15 15:19:53 kent Exp $ 55 * $NetBSD: uaudio.c,v 1.95 2005/01/16 06:02:19 dsainty Exp $ 56 * $NetBSD: uaudio.c,v 1.96 2005/01/16 12:46:00 kent Exp $ 57 * $NetBSD: uaudio.c,v 1.97 2005/02/24 08:19:38 martin Exp $ 58 * $NetBSD: uaudio.c,v 1.102 2006/04/14 17:00:55 christos Exp $ 59 * $NetBSD: uaudio.c,v 1.103 2006/05/11 19:09:25 mrg Exp $ 60 * $NetBSD: uaudio.c,v 1.105 2006/10/04 16:00:15 christos Exp $ 61 */ 62 63 #include <sys/param.h> 64 #include <sys/systm.h> 65 #include <sys/kernel.h> 66 #include <sys/malloc.h> 67 #if defined(__NetBSD__) || defined(__OpenBSD__) 68 #include <sys/device.h> 69 #include <sys/ioctl.h> 70 #endif 71 #include <sys/tty.h> 72 #include <sys/file.h> 73 #include <sys/reboot.h> /* for bootverbose */ 74 #include <sys/select.h> 75 #include <sys/proc.h> 76 #if defined(__NetBSD__) || defined(__OpenBSD__) 77 #include <sys/device.h> 78 #elif defined(__FreeBSD__) 79 #include <sys/module.h> 80 #include <sys/bus.h> 81 #include <sys/conf.h> 82 #endif 83 #include <sys/poll.h> 84 #if defined(__FreeBSD__) 85 #include <sys/sysctl.h> 86 #include <sys/sbuf.h> 87 #endif 88 89 #if defined(__NetBSD__) || defined(__OpenBSD__) 90 #include <sys/audioio.h> 91 #include <dev/audio_if.h> 92 #include <dev/audiovar.h> 93 #include <dev/mulaw.h> 94 #include <dev/auconv.h> 95 #elif defined(__FreeBSD__) 96 #include <dev/sound/pcm/sound.h> /* XXXXX */ 97 #include <dev/sound/chip.h> 98 #include "feeder_if.h" 99 #endif 100 101 #include <dev/usb/usb.h> 102 #include <dev/usb/usbdi.h> 103 #include <dev/usb/usbdi_util.h> 104 #include <dev/usb/usb_quirks.h> 105 106 #if defined(__NetBSD__) || defined(__OpenBSD__) 107 #include <dev/usb/uaudioreg.h> 108 #elif defined(__FreeBSD__) 109 #include <dev/sound/usb/uaudioreg.h> 110 #include <dev/sound/usb/uaudio.h> 111 #endif 112 113 #if defined(__NetBSD__) || defined(__OpenBSD__) 114 /* #define UAUDIO_DEBUG */ 115 #else 116 /* #define USB_DEBUG */ 117 #endif 118 /* #define UAUDIO_MULTIPLE_ENDPOINTS */ 119 #ifdef USB_DEBUG 120 #define DPRINTF(x) do { if (uaudiodebug) logprintf x; } while (0) 121 #define DPRINTFN(n,x) do { if (uaudiodebug>(n)) logprintf x; } while (0) 122 int uaudiodebug = 0; 123 #if defined(__FreeBSD__) 124 SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio"); 125 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW, 126 &uaudiodebug, 0, "uaudio debug level"); 127 #endif 128 #else 129 #define DPRINTF(x) 130 #define DPRINTFN(n,x) 131 #endif 132 133 #define UAUDIO_NCHANBUFS 6 /* number of outstanding request */ 134 #if defined(__NetBSD__) || defined(__OpenBSD__) 135 #define UAUDIO_NFRAMES 10 /* ms of sound in each request */ 136 #elif defined(__FreeBSD__) 137 #define UAUDIO_NFRAMES 20 /* ms of sound in each request */ 138 #endif 139 140 141 #define MIX_MAX_CHAN 8 142 struct mixerctl { 143 uint16_t wValue[MIX_MAX_CHAN]; /* using nchan */ 144 uint16_t wIndex; 145 uint8_t nchan; 146 uint8_t type; 147 #define MIX_ON_OFF 1 148 #define MIX_SIGNED_16 2 149 #define MIX_UNSIGNED_16 3 150 #define MIX_SIGNED_8 4 151 #define MIX_SELECTOR 5 152 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1) 153 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16) 154 int minval, maxval; 155 u_int delta; 156 u_int mul; 157 #if defined(__FreeBSD__) /* XXXXX */ 158 unsigned ctl; 159 #define MAX_SELECTOR_INPUT_PIN 256 160 uint8_t slctrtype[MAX_SELECTOR_INPUT_PIN]; 161 #endif 162 uint8_t class; 163 #if !defined(__FreeBSD__) 164 char ctlname[MAX_AUDIO_DEV_LEN]; 165 char *ctlunit; 166 #endif 167 }; 168 #define MAKE(h,l) (((h) << 8) | (l)) 169 170 struct as_info { 171 uint8_t alt; 172 uint8_t encoding; 173 uint8_t attributes; /* Copy of bmAttributes of 174 * usb_audio_streaming_endpoint_descriptor 175 */ 176 usbd_interface_handle ifaceh; 177 const usb_interface_descriptor_t *idesc; 178 const usb_endpoint_descriptor_audio_t *edesc; 179 const usb_endpoint_descriptor_audio_t *edesc1; 180 const struct usb_audio_streaming_type1_descriptor *asf1desc; 181 int sc_busy; /* currently used */ 182 }; 183 184 struct chan { 185 #if defined(__NetBSD__) || defined(__OpenBSD__) 186 void (*intr)(void *); /* DMA completion intr handler */ 187 void *arg; /* arg for intr() */ 188 #else 189 struct pcm_channel *pcm_ch; 190 #endif 191 usbd_pipe_handle pipe; 192 usbd_pipe_handle sync_pipe; 193 194 u_int sample_size; 195 u_int sample_rate; 196 u_int bytes_per_frame; 197 u_int fraction; /* fraction/1000 is the extra samples/frame */ 198 u_int residue; /* accumulates the fractional samples */ 199 200 u_char *start; /* upper layer buffer start */ 201 u_char *end; /* upper layer buffer end */ 202 u_char *cur; /* current position in upper layer buffer */ 203 int blksize; /* chunk size to report up */ 204 int transferred; /* transferred bytes not reported up */ 205 206 int altidx; /* currently used altidx */ 207 208 int curchanbuf; 209 struct chanbuf { 210 struct chan *chan; 211 usbd_xfer_handle xfer; 212 u_char *buffer; 213 u_int16_t sizes[UAUDIO_NFRAMES]; 214 u_int16_t offsets[UAUDIO_NFRAMES]; 215 u_int16_t size; 216 } chanbufs[UAUDIO_NCHANBUFS]; 217 218 struct uaudio_softc *sc; /* our softc */ 219 #if defined(__FreeBSD__) 220 u_int32_t format; 221 int precision; 222 int channels; 223 #endif 224 }; 225 226 struct uaudio_softc { 227 device_t sc_dev; /* base device */ 228 usbd_device_handle sc_udev; /* USB device */ 229 int sc_ac_iface; /* Audio Control interface */ 230 usbd_interface_handle sc_ac_ifaceh; 231 struct chan sc_playchan; /* play channel */ 232 struct chan sc_recchan; /* record channel */ 233 int sc_nullalt; 234 int sc_audio_rev; 235 struct as_info *sc_alts; /* alternate settings */ 236 int sc_nalts; /* # of alternate settings */ 237 int sc_altflags; 238 #define HAS_8 0x01 239 #define HAS_16 0x02 240 #define HAS_8U 0x04 241 #define HAS_ALAW 0x08 242 #define HAS_MULAW 0x10 243 #define UA_NOFRAC 0x20 /* don't do sample rate adjustment */ 244 #define HAS_24 0x40 245 #define HAS_32 0x80 246 int sc_mode; /* play/record capability */ 247 struct mixerctl *sc_ctls; /* mixer controls */ 248 int sc_nctls; /* # of mixer controls */ 249 device_t sc_audiodev; 250 char sc_dying; 251 #if defined(__FreeBSD__) 252 struct sbuf uaudio_sndstat; 253 int uaudio_sndstat_flag; 254 int async; 255 #endif 256 int sc_vendor; 257 int sc_product; 258 int sc_release; 259 }; 260 261 struct terminal_list { 262 int size; 263 uint16_t terminals[1]; 264 }; 265 #define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \ 266 + sizeof(uint16_t) * (N)) 267 268 struct io_terminal { 269 union { 270 const usb_descriptor_t *desc; 271 const struct usb_audio_input_terminal *it; 272 const struct usb_audio_output_terminal *ot; 273 const struct usb_audio_mixer_unit *mu; 274 const struct usb_audio_selector_unit *su; 275 const struct usb_audio_feature_unit *fu; 276 const struct usb_audio_processing_unit *pu; 277 const struct usb_audio_extension_unit *eu; 278 } d; 279 int inputs_size; 280 struct terminal_list **inputs; /* list of source input terminals */ 281 struct terminal_list *output; /* list of destination output terminals */ 282 int direct; /* directly connected to an output terminal */ 283 }; 284 285 #define UAC_OUTPUT 0 286 #define UAC_INPUT 1 287 #define UAC_EQUAL 2 288 #define UAC_RECORD 3 289 #define UAC_NCLASSES 4 290 #ifdef USB_DEBUG 291 #if defined(__FreeBSD__) 292 #define AudioCinputs "inputs" 293 #define AudioCoutputs "outputs" 294 #define AudioCrecord "record" 295 #define AudioCequalization "equalization" 296 #endif 297 static const char *uac_names[] = { 298 AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord, 299 }; 300 #endif 301 302 static usbd_status uaudio_identify_ac 303 (struct uaudio_softc *, const usb_config_descriptor_t *); 304 static usbd_status uaudio_identify_as 305 (struct uaudio_softc *, const usb_config_descriptor_t *); 306 static usbd_status uaudio_process_as 307 (struct uaudio_softc *, const char *, int *, int, 308 const usb_interface_descriptor_t *); 309 310 static void uaudio_add_alt(struct uaudio_softc *, const struct as_info *); 311 312 static const usb_interface_descriptor_t *uaudio_find_iface 313 (const char *, int, int *, int); 314 315 static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *); 316 317 #if defined(__NetBSD__) || defined(__OpenBSD__) 318 static char *uaudio_id_name 319 (struct uaudio_softc *, const struct io_terminal *, int); 320 #endif 321 322 #ifdef USB_DEBUG 323 static void uaudio_dump_cluster(const struct usb_audio_cluster *); 324 #endif 325 static struct usb_audio_cluster uaudio_get_cluster 326 (int, const struct io_terminal *); 327 static void uaudio_add_input 328 (struct uaudio_softc *, const struct io_terminal *, int); 329 static void uaudio_add_output 330 (struct uaudio_softc *, const struct io_terminal *, int); 331 static void uaudio_add_mixer 332 (struct uaudio_softc *, const struct io_terminal *, int); 333 static void uaudio_add_selector 334 (struct uaudio_softc *, const struct io_terminal *, int); 335 #ifdef USB_DEBUG 336 static const char *uaudio_get_terminal_name(int); 337 #endif 338 static int uaudio_determine_class 339 (const struct io_terminal *, struct mixerctl *); 340 #if defined(__FreeBSD__) 341 static const int uaudio_feature_name(const struct io_terminal *, 342 struct mixerctl *); 343 #else 344 static const char *uaudio_feature_name 345 (const struct io_terminal *, struct mixerctl *); 346 #endif 347 static void uaudio_add_feature 348 (struct uaudio_softc *, const struct io_terminal *, int); 349 static void uaudio_add_processing_updown 350 (struct uaudio_softc *, const struct io_terminal *, int); 351 static void uaudio_add_processing 352 (struct uaudio_softc *, const struct io_terminal *, int); 353 static void uaudio_add_extension 354 (struct uaudio_softc *, const struct io_terminal *, int); 355 static struct terminal_list *uaudio_merge_terminal_list 356 (const struct io_terminal *); 357 static struct terminal_list *uaudio_io_terminaltype 358 (int, struct io_terminal *, int); 359 static usbd_status uaudio_identify 360 (struct uaudio_softc *, const usb_config_descriptor_t *); 361 362 static int uaudio_signext(int, int); 363 #if defined(__NetBSD__) || defined(__OpenBSD__) 364 static int uaudio_value2bsd(struct mixerctl *, int); 365 #endif 366 static int uaudio_bsd2value(struct mixerctl *, int); 367 static int uaudio_get(struct uaudio_softc *, int, int, int, int, int); 368 #if defined(__NetBSD__) || defined(__OpenBSD__) 369 static int uaudio_ctl_get 370 (struct uaudio_softc *, int, struct mixerctl *, int); 371 #endif 372 static void uaudio_set 373 (struct uaudio_softc *, int, int, int, int, int, int); 374 static void uaudio_ctl_set 375 (struct uaudio_softc *, int, struct mixerctl *, int, int); 376 377 static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int); 378 379 static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *); 380 static void uaudio_chan_close(struct uaudio_softc *, struct chan *); 381 static usbd_status uaudio_chan_alloc_buffers 382 (struct uaudio_softc *, struct chan *); 383 static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *); 384 385 #if defined(__NetBSD__) || defined(__OpenBSD__) 386 static void uaudio_chan_init 387 (struct chan *, int, const struct audio_params *, int); 388 static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int); 389 #endif 390 391 static void uaudio_chan_ptransfer(struct chan *); 392 static void uaudio_chan_pintr 393 (usbd_xfer_handle, usbd_private_handle, usbd_status); 394 395 static void uaudio_chan_rtransfer(struct chan *); 396 static void uaudio_chan_rintr 397 (usbd_xfer_handle, usbd_private_handle, usbd_status); 398 399 #if defined(__NetBSD__) || defined(__OpenBSD__) 400 static int uaudio_open(void *, int); 401 static void uaudio_close(void *); 402 static int uaudio_drain(void *); 403 static int uaudio_query_encoding(void *, struct audio_encoding *); 404 static void uaudio_get_minmax_rates 405 (int, const struct as_info *, const struct audio_params *, 406 int, u_long *, u_long *); 407 static int uaudio_match_alt_sub 408 (int, const struct as_info *, const struct audio_params *, int, u_long); 409 static int uaudio_match_alt_chan 410 (int, const struct as_info *, struct audio_params *, int); 411 static int uaudio_match_alt 412 (int, const struct as_info *, struct audio_params *, int); 413 static int uaudio_set_params 414 (void *, int, int, struct audio_params *, struct audio_params *); 415 static int uaudio_round_blocksize(void *, int); 416 static int uaudio_trigger_output 417 (void *, void *, void *, int, void (*)(void *), void *, 418 struct audio_params *); 419 static int uaudio_trigger_input 420 (void *, void *, void *, int, void (*)(void *), void *, 421 struct audio_params *); 422 static int uaudio_halt_in_dma(void *); 423 static int uaudio_halt_out_dma(void *); 424 static int uaudio_getdev(void *, struct audio_device *); 425 static int uaudio_mixer_set_port(void *, mixer_ctrl_t *); 426 static int uaudio_mixer_get_port(void *, mixer_ctrl_t *); 427 static int uaudio_query_devinfo(void *, mixer_devinfo_t *); 428 static int uaudio_get_props(void *); 429 430 static const struct audio_hw_if uaudio_hw_if = { 431 uaudio_open, 432 uaudio_close, 433 uaudio_drain, 434 uaudio_query_encoding, 435 uaudio_set_params, 436 uaudio_round_blocksize, 437 NULL, 438 NULL, 439 NULL, 440 NULL, 441 NULL, 442 uaudio_halt_out_dma, 443 uaudio_halt_in_dma, 444 NULL, 445 uaudio_getdev, 446 NULL, 447 uaudio_mixer_set_port, 448 uaudio_mixer_get_port, 449 uaudio_query_devinfo, 450 NULL, 451 NULL, 452 NULL, 453 NULL, 454 uaudio_get_props, 455 uaudio_trigger_output, 456 uaudio_trigger_input, 457 NULL, 458 }; 459 460 static struct audio_device uaudio_device = { 461 "USB audio", 462 "", 463 "uaudio" 464 }; 465 466 #elif defined(__FreeBSD__) 467 static int audio_attach_mi(device_t); 468 static int uaudio_init_params(struct uaudio_softc * sc, struct chan *ch, int mode); 469 static int uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose); 470 471 /* for NetBSD compatibirity */ 472 #define AUMODE_PLAY 0x01 473 #define AUMODE_RECORD 0x02 474 475 #define AUDIO_PROP_FULLDUPLEX 0x01 476 477 #define AUDIO_ENCODING_ULAW 1 478 #define AUDIO_ENCODING_ALAW 2 479 #define AUDIO_ENCODING_SLINEAR_LE 6 480 #define AUDIO_ENCODING_SLINEAR_BE 7 481 #define AUDIO_ENCODING_ULINEAR_LE 8 482 #define AUDIO_ENCODING_ULINEAR_BE 9 483 484 #endif /* FreeBSD */ 485 486 487 #if defined(__NetBSD__) || defined(__OpenBSD__) 488 489 USB_DECLARE_DRIVER(uaudio); 490 491 #elif defined(__FreeBSD__) 492 493 USB_DECLARE_DRIVER_INIT(uaudio, 494 DEVMETHOD(device_suspend, bus_generic_suspend), 495 DEVMETHOD(device_resume, bus_generic_resume), 496 DEVMETHOD(device_shutdown, bus_generic_shutdown), 497 DEVMETHOD(bus_print_child, bus_generic_print_child) 498 ); 499 #endif 500 501 502 USB_MATCH(uaudio) 503 { 504 USB_MATCH_START(uaudio, uaa); 505 usb_interface_descriptor_t *id; 506 507 if (uaa->iface == NULL) 508 return UMATCH_NONE; 509 510 id = usbd_get_interface_descriptor(uaa->iface); 511 /* Trigger on the control interface. */ 512 if (id == NULL || 513 id->bInterfaceClass != UICLASS_AUDIO || 514 id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL || 515 (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO)) 516 return UMATCH_NONE; 517 518 return UMATCH_IFACECLASS_IFACESUBCLASS; 519 } 520 521 USB_ATTACH(uaudio) 522 { 523 USB_ATTACH_START(uaudio, sc, uaa); 524 usb_interface_descriptor_t *id; 525 usb_config_descriptor_t *cdesc; 526 char devinfo[1024]; 527 usbd_status err; 528 int i, j, found; 529 530 #if defined(__FreeBSD__) 531 usbd_devinfo(uaa->device, 0, devinfo); 532 USB_ATTACH_SETUP; 533 #else 534 usbd_devinfo(uaa->device, 0, devinfo, sizeof(devinfo)); 535 printf(": %s\n", devinfo); 536 #endif 537 538 sc->sc_udev = uaa->device; 539 sc->sc_vendor = uaa->vendor; 540 sc->sc_product = uaa->product; 541 sc->sc_release = uaa->release; 542 #if defined(__FreeBSD__) 543 if (resource_int_value(device_get_name(sc->sc_dev), 544 device_get_unit(sc->sc_dev), "async", &i) == 0 && i != 0) 545 sc->async = 1; 546 else 547 sc->async = 0; 548 #endif 549 550 cdesc = usbd_get_config_descriptor(sc->sc_udev); 551 if (cdesc == NULL) { 552 printf("%s: failed to get configuration descriptor\n", 553 device_get_nameunit(sc->sc_dev)); 554 USB_ATTACH_ERROR_RETURN; 555 } 556 557 err = uaudio_identify(sc, cdesc); 558 if (err) { 559 printf("%s: audio descriptors make no sense, error=%d\n", 560 device_get_nameunit(sc->sc_dev), err); 561 USB_ATTACH_ERROR_RETURN; 562 } 563 564 sc->sc_ac_ifaceh = uaa->iface; 565 /* Pick up the AS interface. */ 566 for (i = 0; i < uaa->nifaces; i++) { 567 if (uaa->ifaces[i] == NULL) 568 continue; 569 id = usbd_get_interface_descriptor(uaa->ifaces[i]); 570 if (id == NULL) 571 continue; 572 found = 0; 573 for (j = 0; j < sc->sc_nalts; j++) { 574 if (id->bInterfaceNumber == 575 sc->sc_alts[j].idesc->bInterfaceNumber) { 576 sc->sc_alts[j].ifaceh = uaa->ifaces[i]; 577 found = 1; 578 } 579 } 580 if (found) 581 uaa->ifaces[i] = NULL; 582 } 583 584 for (j = 0; j < sc->sc_nalts; j++) { 585 if (sc->sc_alts[j].ifaceh == NULL) { 586 printf("%s: alt %d missing AS interface(s)\n", 587 device_get_nameunit(sc->sc_dev), j); 588 USB_ATTACH_ERROR_RETURN; 589 } 590 } 591 592 printf("%s: audio rev %d.%02x\n", device_get_nameunit(sc->sc_dev), 593 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff); 594 595 sc->sc_playchan.sc = sc->sc_recchan.sc = sc; 596 sc->sc_playchan.altidx = -1; 597 sc->sc_recchan.altidx = -1; 598 599 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC) 600 sc->sc_altflags |= UA_NOFRAC; 601 602 #ifndef USB_DEBUG 603 if (bootverbose) 604 #endif 605 printf("%s: %d mixer controls\n", device_get_nameunit(sc->sc_dev), 606 sc->sc_nctls); 607 608 #if !defined(__FreeBSD__) 609 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 610 USBDEV(sc->sc_dev)); 611 #endif 612 613 DPRINTF(("uaudio_attach: doing audio_attach_mi\n")); 614 #if defined(__OpenBSD__) 615 audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); 616 #elif defined(__NetBSD__) 617 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); 618 #elif defined(__FreeBSD__) 619 sc->sc_dying = 0; 620 if (audio_attach_mi(sc->sc_dev)) { 621 printf("audio_attach_mi failed\n"); 622 USB_ATTACH_ERROR_RETURN; 623 } 624 #endif 625 626 #if defined(__FreeBSD__) 627 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->sc_dev), 628 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), 629 OID_AUTO, "async", CTLFLAG_RW, &sc->async, 0, 630 "Asynchronous USB request"); 631 #endif 632 633 USB_ATTACH_SUCCESS_RETURN; 634 } 635 636 #if defined(__NetBSD__) || defined(__OpenBSD__) 637 int 638 uaudio_activate(device_t self, enum devact act) 639 { 640 struct uaudio_softc *sc; 641 int rv; 642 643 sc = (struct uaudio_softc *)self; 644 rv = 0; 645 switch (act) { 646 case DVACT_ACTIVATE: 647 return EOPNOTSUPP; 648 649 case DVACT_DEACTIVATE: 650 if (sc->sc_audiodev != NULL) 651 rv = config_deactivate(sc->sc_audiodev); 652 sc->sc_dying = 1; 653 break; 654 } 655 return rv; 656 } 657 #endif 658 659 #if defined(__NetBSD__) || defined(__OpenBSD__) 660 int 661 uaudio_detach(device_t self, int flags) 662 { 663 struct uaudio_softc *sc; 664 int rv; 665 666 sc = (struct uaudio_softc *)self; 667 rv = 0; 668 /* Wait for outstanding requests to complete. */ 669 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); 670 671 if (sc->sc_audiodev != NULL) 672 rv = config_detach(sc->sc_audiodev, flags); 673 674 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 675 USBDEV(sc->sc_dev)); 676 677 return rv; 678 } 679 #elif defined(__FreeBSD__) 680 681 USB_DETACH(uaudio) 682 { 683 struct sndcard_func *func; 684 device_t *devlist = NULL; 685 int err, i, devcount; 686 687 USB_DETACH_START(uaudio, sc); 688 689 sbuf_delete(&(sc->uaudio_sndstat)); 690 sc->uaudio_sndstat_flag = 0; 691 692 sc->sc_dying = 1; 693 694 #if 0 /* XXX */ 695 /* Wait for outstanding requests to complete. */ 696 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); 697 #endif 698 699 err = bus_generic_detach(sc->sc_dev); 700 701 if (err == 0) { 702 device_get_children(sc->sc_dev, &devlist, &devcount); 703 for (i = 0; devlist != NULL && i < devcount; i++) { 704 func = device_get_ivars(devlist[i]); 705 if (func != NULL && func->func == SCF_PCM && 706 func->varinfo == NULL) { 707 device_set_ivars(devlist[i], NULL); 708 free(func, M_DEVBUF); 709 device_delete_child(sc->sc_dev, devlist[i]); 710 } 711 } 712 if (devlist != NULL) 713 free(devlist, M_TEMP); 714 } 715 716 return err; 717 } 718 #endif 719 720 #if defined(__NetBSD__) || defined(__OpenBSD__) 721 static int 722 uaudio_query_encoding(void *addr, struct audio_encoding *fp) 723 { 724 struct uaudio_softc *sc; 725 int flags; 726 int idx; 727 728 sc = addr; 729 flags = sc->sc_altflags; 730 if (sc->sc_dying) 731 return EIO; 732 733 if (sc->sc_nalts == 0 || flags == 0) 734 return ENXIO; 735 736 idx = fp->index; 737 switch (idx) { 738 case 0: 739 strlcpy(fp->name, AudioEulinear, sizeof(fp->name)); 740 fp->encoding = AUDIO_ENCODING_ULINEAR; 741 fp->precision = 8; 742 fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 743 return (0); 744 case 1: 745 strlcpy(fp->name, AudioEmulaw, sizeof(fp->name)); 746 fp->encoding = AUDIO_ENCODING_ULAW; 747 fp->precision = 8; 748 fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 749 return (0); 750 case 2: 751 strlcpy(fp->name, AudioEalaw, sizeof(fp->name)); 752 fp->encoding = AUDIO_ENCODING_ALAW; 753 fp->precision = 8; 754 fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 755 return (0); 756 case 3: 757 strlcpy(fp->name, AudioEslinear, sizeof(fp->name)); 758 fp->encoding = AUDIO_ENCODING_SLINEAR; 759 fp->precision = 8; 760 fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 761 return (0); 762 case 4: 763 strlcpy(fp->name, AudioEslinear_le, sizeof(fp->name)); 764 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 765 fp->precision = 16; 766 fp->flags = 0; 767 return (0); 768 case 5: 769 strlcpy(fp->name, AudioEulinear_le, sizeof(fp->name)); 770 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 771 fp->precision = 16; 772 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 773 return (0); 774 case 6: 775 strlcpy(fp->name, AudioEslinear_be, sizeof(fp->name)); 776 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 777 fp->precision = 16; 778 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 779 return (0); 780 case 7: 781 strlcpy(fp->name, AudioEulinear_be, sizeof(fp->name)); 782 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 783 fp->precision = 16; 784 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 785 return (0); 786 default: 787 return (EINVAL); 788 } 789 } 790 #endif 791 792 static const usb_interface_descriptor_t * 793 uaudio_find_iface(const char *buf, int size, int *offsp, int subtype) 794 { 795 const usb_interface_descriptor_t *d; 796 797 while (*offsp < size) { 798 d = (const void *)(buf + *offsp); 799 *offsp += d->bLength; 800 if (d->bDescriptorType == UDESC_INTERFACE && 801 d->bInterfaceClass == UICLASS_AUDIO && 802 d->bInterfaceSubClass == subtype) 803 return d; 804 } 805 return NULL; 806 } 807 808 static void 809 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc) 810 { 811 int res; 812 size_t len; 813 struct mixerctl *nmc; 814 815 #if defined(__FreeBSD__) 816 if (mc->class < UAC_NCLASSES) { 817 DPRINTF(("%s: adding %s.%d\n", 818 __func__, uac_names[mc->class], mc->ctl)); 819 } else { 820 DPRINTF(("%s: adding %d\n", __func__, mc->ctl)); 821 } 822 #else 823 if (mc->class < UAC_NCLASSES) { 824 DPRINTF(("%s: adding %s.%s\n", 825 __func__, uac_names[mc->class], mc->ctlname)); 826 } else { 827 DPRINTF(("%s: adding %s\n", __func__, mc->ctlname)); 828 } 829 #endif 830 len = sizeof(*mc) * (sc->sc_nctls + 1); 831 nmc = malloc(len, M_USBDEV, M_NOWAIT); 832 if (nmc == NULL) { 833 printf("uaudio_mixer_add_ctl: no memory\n"); 834 return; 835 } 836 /* Copy old data, if there was any */ 837 if (sc->sc_nctls != 0) { 838 memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls)); 839 free(sc->sc_ctls, M_USBDEV); 840 } 841 sc->sc_ctls = nmc; 842 843 mc->delta = 0; 844 if (mc->type == MIX_ON_OFF) { 845 mc->minval = 0; 846 mc->maxval = 1; 847 } else if (mc->type == MIX_SELECTOR) { 848 ; 849 } else { 850 /* Determine min and max values. */ 851 mc->minval = uaudio_signext(mc->type, 852 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE, 853 mc->wValue[0], mc->wIndex, 854 MIX_SIZE(mc->type))); 855 mc->maxval = 1 + uaudio_signext(mc->type, 856 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE, 857 mc->wValue[0], mc->wIndex, 858 MIX_SIZE(mc->type))); 859 mc->mul = mc->maxval - mc->minval; 860 if (mc->mul == 0) 861 mc->mul = 1; 862 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE, 863 mc->wValue[0], mc->wIndex, 864 MIX_SIZE(mc->type)); 865 if (res > 0) 866 mc->delta = (res * 255 + mc->mul/2) / mc->mul; 867 } 868 869 sc->sc_ctls[sc->sc_nctls++] = *mc; 870 871 #ifdef USB_DEBUG 872 if (uaudiodebug > 2) { 873 int i; 874 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0])); 875 for (i = 1; i < mc->nchan; i++) 876 DPRINTF((",%04x", mc->wValue[i])); 877 #if defined(__FreeBSD__) 878 DPRINTF((" wIndex=%04x type=%d ctl='%d' " 879 "min=%d max=%d\n", 880 mc->wIndex, mc->type, mc->ctl, 881 mc->minval, mc->maxval)); 882 #else 883 DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' " 884 "min=%d max=%d\n", 885 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit, 886 mc->minval, mc->maxval)); 887 #endif 888 } 889 #endif 890 } 891 892 #if defined(__NetBSD__) || defined(__OpenBSD__) 893 static char * 894 uaudio_id_name(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 895 { 896 static char buf[32]; 897 898 snprintf(buf, sizeof(buf), "i%d", id); 899 return buf; 900 } 901 #endif 902 903 #ifdef USB_DEBUG 904 static void 905 uaudio_dump_cluster(const struct usb_audio_cluster *cl) 906 { 907 static const char *channel_names[16] = { 908 "LEFT", "RIGHT", "CENTER", "LFE", 909 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER", 910 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP", 911 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15", 912 }; 913 int cc, i, first; 914 915 cc = UGETW(cl->wChannelConfig); 916 logprintf("cluster: bNrChannels=%u wChannelConfig=0x%.4x", 917 cl->bNrChannels, cc); 918 first = TRUE; 919 for (i = 0; cc != 0; i++) { 920 if (cc & 1) { 921 logprintf("%c%s", first ? '<' : ',', channel_names[i]); 922 first = FALSE; 923 } 924 cc = cc >> 1; 925 } 926 logprintf("> iChannelNames=%u", cl->iChannelNames); 927 } 928 #endif 929 930 static struct usb_audio_cluster 931 uaudio_get_cluster(int id, const struct io_terminal *iot) 932 { 933 struct usb_audio_cluster r; 934 const usb_descriptor_t *dp; 935 int i; 936 937 for (i = 0; i < 25; i++) { /* avoid infinite loops */ 938 dp = iot[id].d.desc; 939 if (dp == 0) 940 goto bad; 941 switch (dp->bDescriptorSubtype) { 942 case UDESCSUB_AC_INPUT: 943 r.bNrChannels = iot[id].d.it->bNrChannels; 944 USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig)); 945 r.iChannelNames = iot[id].d.it->iChannelNames; 946 return r; 947 case UDESCSUB_AC_OUTPUT: 948 id = iot[id].d.ot->bSourceId; 949 break; 950 case UDESCSUB_AC_MIXER: 951 r = *(const struct usb_audio_cluster *) 952 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins]; 953 return r; 954 case UDESCSUB_AC_SELECTOR: 955 /* XXX This is not really right */ 956 id = iot[id].d.su->baSourceId[0]; 957 break; 958 case UDESCSUB_AC_FEATURE: 959 id = iot[id].d.fu->bSourceId; 960 break; 961 case UDESCSUB_AC_PROCESSING: 962 r = *(const struct usb_audio_cluster *) 963 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins]; 964 return r; 965 case UDESCSUB_AC_EXTENSION: 966 r = *(const struct usb_audio_cluster *) 967 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins]; 968 return r; 969 default: 970 goto bad; 971 } 972 } 973 bad: 974 printf("uaudio_get_cluster: bad data\n"); 975 memset(&r, 0, sizeof r); 976 return r; 977 978 } 979 980 static void 981 uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 982 { 983 #ifdef USB_DEBUG 984 const struct usb_audio_input_terminal *d = iot[id].d.it; 985 986 DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x " 987 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d " 988 "iChannelNames=%d iTerminal=%d\n", 989 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 990 d->bNrChannels, UGETW(d->wChannelConfig), 991 d->iChannelNames, d->iTerminal)); 992 #endif 993 } 994 995 static void 996 uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 997 { 998 #ifdef USB_DEBUG 999 const struct usb_audio_output_terminal *d; 1000 1001 d = iot[id].d.ot; 1002 DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x " 1003 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n", 1004 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 1005 d->bSourceId, d->iTerminal)); 1006 #endif 1007 } 1008 1009 static void 1010 uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 1011 { 1012 const struct usb_audio_mixer_unit *d = iot[id].d.mu; 1013 const struct usb_audio_mixer_unit_1 *d1; 1014 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k; 1015 const uByte *bm; 1016 struct mixerctl mix; 1017 1018 DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n", 1019 d->bUnitId, d->bNrInPins)); 1020 1021 /* Compute the number of input channels */ 1022 ichs = 0; 1023 for (i = 0; i < d->bNrInPins; i++) 1024 ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels; 1025 1026 /* and the number of output channels */ 1027 d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins]; 1028 ochs = d1->bNrChannels; 1029 DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs)); 1030 1031 bm = d1->bmControls; 1032 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1033 uaudio_determine_class(&iot[id], &mix); 1034 mix.type = MIX_SIGNED_16; 1035 #if !defined(__FreeBSD__) /* XXXXX */ 1036 mix.ctlunit = AudioNvolume; 1037 #endif 1038 1039 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1) 1040 for (p = i = 0; i < d->bNrInPins; i++) { 1041 chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels; 1042 mc = 0; 1043 for (c = 0; c < chs; c++) { 1044 mo = 0; 1045 for (o = 0; o < ochs; o++) { 1046 bno = (p + c) * ochs + o; 1047 if (BIT(bno)) 1048 mo++; 1049 } 1050 if (mo == 1) 1051 mc++; 1052 } 1053 if (mc == chs && chs <= MIX_MAX_CHAN) { 1054 k = 0; 1055 for (c = 0; c < chs; c++) 1056 for (o = 0; o < ochs; o++) { 1057 bno = (p + c) * ochs + o; 1058 if (BIT(bno)) 1059 mix.wValue[k++] = 1060 MAKE(p+c+1, o+1); 1061 } 1062 #if !defined(__FreeBSD__) 1063 snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s", 1064 d->bUnitId, uaudio_id_name(sc, iot, 1065 d->baSourceId[i])); 1066 #endif 1067 mix.nchan = chs; 1068 uaudio_mixer_add_ctl(sc, &mix); 1069 } else { 1070 /* XXX */ 1071 } 1072 #undef BIT 1073 p += chs; 1074 } 1075 1076 } 1077 1078 static void 1079 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 1080 { 1081 const struct usb_audio_selector_unit *d; 1082 struct mixerctl mix; 1083 #if !defined(__FreeBSD__) 1084 int i, wp; 1085 #else 1086 int i; 1087 struct mixerctl dummy; 1088 #endif 1089 1090 d = iot[id].d.su; 1091 DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n", 1092 d->bUnitId, d->bNrInPins)); 1093 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1094 mix.wValue[0] = MAKE(0, 0); 1095 uaudio_determine_class(&iot[id], &mix); 1096 mix.nchan = 1; 1097 mix.type = MIX_SELECTOR; 1098 #if defined(__FreeBSD__) 1099 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ 1100 mix.minval = 1; 1101 mix.maxval = d->bNrInPins; 1102 mix.mul = mix.maxval - mix.minval; 1103 for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) { 1104 mix.slctrtype[i] = SOUND_MIXER_NRDEVICES; 1105 } 1106 for (i = mix.minval; i <= mix.maxval; i++) { 1107 mix.slctrtype[i - 1] = uaudio_feature_name(&iot[d->baSourceId[i - 1]], &dummy); 1108 } 1109 #else 1110 mix.ctlunit = ""; 1111 mix.minval = 1; 1112 mix.maxval = d->bNrInPins; 1113 mix.mul = mix.maxval - mix.minval; 1114 wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId); 1115 for (i = 1; i <= d->bNrInPins; i++) { 1116 wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp, 1117 "i%d", d->baSourceId[i - 1]); 1118 if (wp > MAX_AUDIO_DEV_LEN - 1) 1119 break; 1120 } 1121 #endif 1122 uaudio_mixer_add_ctl(sc, &mix); 1123 } 1124 1125 #ifdef USB_DEBUG 1126 static const char * 1127 uaudio_get_terminal_name(int terminal_type) 1128 { 1129 static char buf[100]; 1130 1131 switch (terminal_type) { 1132 /* USB terminal types */ 1133 case UAT_UNDEFINED: return "UAT_UNDEFINED"; 1134 case UAT_STREAM: return "UAT_STREAM"; 1135 case UAT_VENDOR: return "UAT_VENDOR"; 1136 /* input terminal types */ 1137 case UATI_UNDEFINED: return "UATI_UNDEFINED"; 1138 case UATI_MICROPHONE: return "UATI_MICROPHONE"; 1139 case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE"; 1140 case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE"; 1141 case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE"; 1142 case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY"; 1143 case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR"; 1144 /* output terminal types */ 1145 case UATO_UNDEFINED: return "UATO_UNDEFINED"; 1146 case UATO_SPEAKER: return "UATO_SPEAKER"; 1147 case UATO_HEADPHONES: return "UATO_HEADPHONES"; 1148 case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO"; 1149 case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER"; 1150 case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER"; 1151 case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER"; 1152 case UATO_SUBWOOFER: return "UATO_SUBWOOFER"; 1153 /* bidir terminal types */ 1154 case UATB_UNDEFINED: return "UATB_UNDEFINED"; 1155 case UATB_HANDSET: return "UATB_HANDSET"; 1156 case UATB_HEADSET: return "UATB_HEADSET"; 1157 case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE"; 1158 case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP"; 1159 case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC"; 1160 /* telephony terminal types */ 1161 case UATT_UNDEFINED: return "UATT_UNDEFINED"; 1162 case UATT_PHONELINE: return "UATT_PHONELINE"; 1163 case UATT_TELEPHONE: return "UATT_TELEPHONE"; 1164 case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE"; 1165 /* external terminal types */ 1166 case UATE_UNDEFINED: return "UATE_UNDEFINED"; 1167 case UATE_ANALOGCONN: return "UATE_ANALOGCONN"; 1168 case UATE_LINECONN: return "UATE_LINECONN"; 1169 case UATE_LEGACYCONN: return "UATE_LEGACYCONN"; 1170 case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC"; 1171 case UATE_SPDIF: return "UATE_SPDIF"; 1172 case UATE_1394DA: return "UATE_1394DA"; 1173 case UATE_1394DV: return "UATE_1394DV"; 1174 /* embedded function terminal types */ 1175 case UATF_UNDEFINED: return "UATF_UNDEFINED"; 1176 case UATF_CALIBNOISE: return "UATF_CALIBNOISE"; 1177 case UATF_EQUNOISE: return "UATF_EQUNOISE"; 1178 case UATF_CDPLAYER: return "UATF_CDPLAYER"; 1179 case UATF_DAT: return "UATF_DAT"; 1180 case UATF_DCC: return "UATF_DCC"; 1181 case UATF_MINIDISK: return "UATF_MINIDISK"; 1182 case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE"; 1183 case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH"; 1184 case UATF_VCRAUDIO: return "UATF_VCRAUDIO"; 1185 case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO"; 1186 case UATF_DVDAUDIO: return "UATF_DVDAUDIO"; 1187 case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO"; 1188 case UATF_SATELLITE: return "UATF_SATELLITE"; 1189 case UATF_CABLETUNER: return "UATF_CABLETUNER"; 1190 case UATF_DSS: return "UATF_DSS"; 1191 case UATF_RADIORECV: return "UATF_RADIORECV"; 1192 case UATF_RADIOXMIT: return "UATF_RADIOXMIT"; 1193 case UATF_MULTITRACK: return "UATF_MULTITRACK"; 1194 case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER"; 1195 default: 1196 snprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type); 1197 return buf; 1198 } 1199 } 1200 #endif 1201 1202 static int 1203 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix) 1204 { 1205 int terminal_type; 1206 1207 if (iot == NULL || iot->output == NULL) { 1208 mix->class = UAC_OUTPUT; 1209 return 0; 1210 } 1211 terminal_type = 0; 1212 if (iot->output->size == 1) 1213 terminal_type = iot->output->terminals[0]; 1214 /* 1215 * If the only output terminal is USB, 1216 * the class is UAC_RECORD. 1217 */ 1218 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) { 1219 mix->class = UAC_RECORD; 1220 if (iot->inputs_size == 1 1221 && iot->inputs[0] != NULL 1222 && iot->inputs[0]->size == 1) 1223 return iot->inputs[0]->terminals[0]; 1224 else 1225 return 0; 1226 } 1227 /* 1228 * If the ultimate destination of the unit is just one output 1229 * terminal and the unit is connected to the output terminal 1230 * directly, the class is UAC_OUTPUT. 1231 */ 1232 if (terminal_type != 0 && iot->direct) { 1233 mix->class = UAC_OUTPUT; 1234 return terminal_type; 1235 } 1236 /* 1237 * If the unit is connected to just one input terminal, 1238 * the class is UAC_INPUT. 1239 */ 1240 if (iot->inputs_size == 1 && iot->inputs[0] != NULL 1241 && iot->inputs[0]->size == 1) { 1242 mix->class = UAC_INPUT; 1243 return iot->inputs[0]->terminals[0]; 1244 } 1245 /* 1246 * Otherwise, the class is UAC_OUTPUT. 1247 */ 1248 mix->class = UAC_OUTPUT; 1249 return terminal_type; 1250 } 1251 1252 #if defined(__FreeBSD__) 1253 const int 1254 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix) 1255 { 1256 int terminal_type; 1257 1258 terminal_type = uaudio_determine_class(iot, mix); 1259 if (mix->class == UAC_RECORD && terminal_type == 0) 1260 return SOUND_MIXER_IMIX; 1261 DPRINTF(("%s: terminal_type=%s\n", __func__, 1262 uaudio_get_terminal_name(terminal_type))); 1263 switch (terminal_type) { 1264 case UAT_STREAM: 1265 return SOUND_MIXER_PCM; 1266 1267 case UATI_MICROPHONE: 1268 case UATI_DESKMICROPHONE: 1269 case UATI_PERSONALMICROPHONE: 1270 case UATI_OMNIMICROPHONE: 1271 case UATI_MICROPHONEARRAY: 1272 case UATI_PROCMICROPHONEARR: 1273 return SOUND_MIXER_MIC; 1274 1275 case UATO_SPEAKER: 1276 case UATO_DESKTOPSPEAKER: 1277 case UATO_ROOMSPEAKER: 1278 case UATO_COMMSPEAKER: 1279 return SOUND_MIXER_SPEAKER; 1280 1281 case UATE_ANALOGCONN: 1282 case UATE_LINECONN: 1283 case UATE_LEGACYCONN: 1284 return SOUND_MIXER_LINE; 1285 1286 case UATE_DIGITALAUIFC: 1287 case UATE_SPDIF: 1288 case UATE_1394DA: 1289 case UATE_1394DV: 1290 return SOUND_MIXER_ALTPCM; 1291 1292 case UATF_CDPLAYER: 1293 return SOUND_MIXER_CD; 1294 1295 case UATF_SYNTHESIZER: 1296 return SOUND_MIXER_SYNTH; 1297 1298 case UATF_VIDEODISCAUDIO: 1299 case UATF_DVDAUDIO: 1300 case UATF_TVTUNERAUDIO: 1301 return SOUND_MIXER_VIDEO; 1302 1303 /* telephony terminal types */ 1304 case UATT_UNDEFINED: 1305 case UATT_PHONELINE: 1306 case UATT_TELEPHONE: 1307 case UATT_DOWNLINEPHONE: 1308 return SOUND_MIXER_PHONEIN; 1309 /* return SOUND_MIXER_PHONEOUT;*/ 1310 1311 case UATF_RADIORECV: 1312 case UATF_RADIOXMIT: 1313 return SOUND_MIXER_RADIO; 1314 1315 case UAT_UNDEFINED: 1316 case UAT_VENDOR: 1317 case UATI_UNDEFINED: 1318 /* output terminal types */ 1319 case UATO_UNDEFINED: 1320 case UATO_DISPLAYAUDIO: 1321 case UATO_SUBWOOFER: 1322 case UATO_HEADPHONES: 1323 /* bidir terminal types */ 1324 case UATB_UNDEFINED: 1325 case UATB_HANDSET: 1326 case UATB_HEADSET: 1327 case UATB_SPEAKERPHONE: 1328 case UATB_SPEAKERPHONEESUP: 1329 case UATB_SPEAKERPHONEECANC: 1330 /* external terminal types */ 1331 case UATE_UNDEFINED: 1332 /* embedded function terminal types */ 1333 case UATF_UNDEFINED: 1334 case UATF_CALIBNOISE: 1335 case UATF_EQUNOISE: 1336 case UATF_DAT: 1337 case UATF_DCC: 1338 case UATF_MINIDISK: 1339 case UATF_ANALOGTAPE: 1340 case UATF_PHONOGRAPH: 1341 case UATF_VCRAUDIO: 1342 case UATF_SATELLITE: 1343 case UATF_CABLETUNER: 1344 case UATF_DSS: 1345 case UATF_MULTITRACK: 1346 case 0xffff: 1347 default: 1348 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type)); 1349 return SOUND_MIXER_VOLUME; 1350 } 1351 return SOUND_MIXER_VOLUME; 1352 } 1353 #else 1354 static const char * 1355 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix) 1356 { 1357 int terminal_type; 1358 1359 terminal_type = uaudio_determine_class(iot, mix); 1360 if (mix->class == UAC_RECORD && terminal_type == 0) 1361 return AudioNmixerout; 1362 DPRINTF(("%s: terminal_type=%s\n", __func__, 1363 uaudio_get_terminal_name(terminal_type))); 1364 switch (terminal_type) { 1365 case UAT_STREAM: 1366 return AudioNdac; 1367 1368 case UATI_MICROPHONE: 1369 case UATI_DESKMICROPHONE: 1370 case UATI_PERSONALMICROPHONE: 1371 case UATI_OMNIMICROPHONE: 1372 case UATI_MICROPHONEARRAY: 1373 case UATI_PROCMICROPHONEARR: 1374 return AudioNmicrophone; 1375 1376 case UATO_SPEAKER: 1377 case UATO_DESKTOPSPEAKER: 1378 case UATO_ROOMSPEAKER: 1379 case UATO_COMMSPEAKER: 1380 return AudioNspeaker; 1381 1382 case UATO_HEADPHONES: 1383 return AudioNheadphone; 1384 1385 case UATO_SUBWOOFER: 1386 return AudioNlfe; 1387 1388 /* telephony terminal types */ 1389 case UATT_UNDEFINED: 1390 case UATT_PHONELINE: 1391 case UATT_TELEPHONE: 1392 case UATT_DOWNLINEPHONE: 1393 return "phone"; 1394 1395 case UATE_ANALOGCONN: 1396 case UATE_LINECONN: 1397 case UATE_LEGACYCONN: 1398 return AudioNline; 1399 1400 case UATE_DIGITALAUIFC: 1401 case UATE_SPDIF: 1402 case UATE_1394DA: 1403 case UATE_1394DV: 1404 return AudioNaux; 1405 1406 case UATF_CDPLAYER: 1407 return AudioNcd; 1408 1409 case UATF_SYNTHESIZER: 1410 return AudioNfmsynth; 1411 1412 case UATF_VIDEODISCAUDIO: 1413 case UATF_DVDAUDIO: 1414 case UATF_TVTUNERAUDIO: 1415 return AudioNvideo; 1416 1417 case UAT_UNDEFINED: 1418 case UAT_VENDOR: 1419 case UATI_UNDEFINED: 1420 /* output terminal types */ 1421 case UATO_UNDEFINED: 1422 case UATO_DISPLAYAUDIO: 1423 /* bidir terminal types */ 1424 case UATB_UNDEFINED: 1425 case UATB_HANDSET: 1426 case UATB_HEADSET: 1427 case UATB_SPEAKERPHONE: 1428 case UATB_SPEAKERPHONEESUP: 1429 case UATB_SPEAKERPHONEECANC: 1430 /* external terminal types */ 1431 case UATE_UNDEFINED: 1432 /* embedded function terminal types */ 1433 case UATF_UNDEFINED: 1434 case UATF_CALIBNOISE: 1435 case UATF_EQUNOISE: 1436 case UATF_DAT: 1437 case UATF_DCC: 1438 case UATF_MINIDISK: 1439 case UATF_ANALOGTAPE: 1440 case UATF_PHONOGRAPH: 1441 case UATF_VCRAUDIO: 1442 case UATF_SATELLITE: 1443 case UATF_CABLETUNER: 1444 case UATF_DSS: 1445 case UATF_RADIORECV: 1446 case UATF_RADIOXMIT: 1447 case UATF_MULTITRACK: 1448 case 0xffff: 1449 default: 1450 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type)); 1451 return AudioNmaster; 1452 } 1453 return AudioNmaster; 1454 } 1455 #endif 1456 1457 static void 1458 uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 1459 { 1460 const struct usb_audio_feature_unit *d; 1461 const uByte *ctls; 1462 int ctlsize; 1463 int nchan; 1464 u_int fumask, mmask, cmask; 1465 struct mixerctl mix; 1466 int chan, ctl, i, unit; 1467 #if defined(__FreeBSD__) 1468 int mixernumber; 1469 #else 1470 const char *mixername; 1471 #endif 1472 1473 #define GET(i) (ctls[(i)*ctlsize] | \ 1474 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0)) 1475 d = iot[id].d.fu; 1476 ctls = d->bmaControls; 1477 ctlsize = d->bControlSize; 1478 nchan = (d->bLength - 7) / ctlsize; 1479 mmask = GET(0); 1480 /* Figure out what we can control */ 1481 for (cmask = 0, chan = 1; chan < nchan; chan++) { 1482 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n", 1483 chan, GET(chan))); 1484 cmask |= GET(chan); 1485 } 1486 1487 #if !defined(__FreeBSD__) 1488 DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, " 1489 "%d channels, mmask=0x%04x, cmask=0x%04x\n", 1490 d->bUnitId, nchan, mmask, cmask)); 1491 #endif 1492 1493 if (nchan > MIX_MAX_CHAN) 1494 nchan = MIX_MAX_CHAN; 1495 unit = d->bUnitId; 1496 mix.wIndex = MAKE(unit, sc->sc_ac_iface); 1497 for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) { 1498 fumask = FU_MASK(ctl); 1499 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n", 1500 ctl, fumask)); 1501 if (mmask & fumask) { 1502 mix.nchan = 1; 1503 mix.wValue[0] = MAKE(ctl, 0); 1504 } else if (cmask & fumask) { 1505 mix.nchan = nchan - 1; 1506 for (i = 1; i < nchan; i++) { 1507 if (GET(i) & fumask) 1508 mix.wValue[i-1] = MAKE(ctl, i); 1509 else 1510 mix.wValue[i-1] = -1; 1511 } 1512 } else { 1513 continue; 1514 } 1515 #undef GET 1516 1517 #if defined(__FreeBSD__) 1518 mixernumber = uaudio_feature_name(&iot[id], &mix); 1519 #else 1520 mixername = uaudio_feature_name(&iot[id], &mix); 1521 #endif 1522 switch (ctl) { 1523 case MUTE_CONTROL: 1524 mix.type = MIX_ON_OFF; 1525 #if defined(__FreeBSD__) 1526 mix.ctl = SOUND_MIXER_NRDEVICES; 1527 #else 1528 mix.ctlunit = ""; 1529 snprintf(mix.ctlname, sizeof(mix.ctlname), 1530 "%s.%s", mixername, AudioNmute); 1531 #endif 1532 break; 1533 case VOLUME_CONTROL: 1534 mix.type = MIX_SIGNED_16; 1535 #if defined(__FreeBSD__) 1536 mix.ctl = mixernumber; 1537 #else 1538 mix.ctlunit = AudioNvolume; 1539 strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname)); 1540 #endif 1541 break; 1542 case BASS_CONTROL: 1543 mix.type = MIX_SIGNED_8; 1544 #if defined(__FreeBSD__) 1545 mix.ctl = SOUND_MIXER_BASS; 1546 #else 1547 mix.ctlunit = AudioNbass; 1548 snprintf(mix.ctlname, sizeof(mix.ctlname), 1549 "%s.%s", mixername, AudioNbass); 1550 #endif 1551 break; 1552 case MID_CONTROL: 1553 mix.type = MIX_SIGNED_8; 1554 #if defined(__FreeBSD__) 1555 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ 1556 #else 1557 mix.ctlunit = AudioNmid; 1558 snprintf(mix.ctlname, sizeof(mix.ctlname), 1559 "%s.%s", mixername, AudioNmid); 1560 #endif 1561 break; 1562 case TREBLE_CONTROL: 1563 mix.type = MIX_SIGNED_8; 1564 #if defined(__FreeBSD__) 1565 mix.ctl = SOUND_MIXER_TREBLE; 1566 #else 1567 mix.ctlunit = AudioNtreble; 1568 snprintf(mix.ctlname, sizeof(mix.ctlname), 1569 "%s.%s", mixername, AudioNtreble); 1570 #endif 1571 break; 1572 case GRAPHIC_EQUALIZER_CONTROL: 1573 continue; /* XXX don't add anything */ 1574 break; 1575 case AGC_CONTROL: 1576 mix.type = MIX_ON_OFF; 1577 #if defined(__FreeBSD__) 1578 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ 1579 #else 1580 mix.ctlunit = ""; 1581 snprintf(mix.ctlname, sizeof(mix.ctlname), "%s.%s", 1582 mixername, AudioNagc); 1583 #endif 1584 break; 1585 case DELAY_CONTROL: 1586 mix.type = MIX_UNSIGNED_16; 1587 #if defined(__FreeBSD__) 1588 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ 1589 #else 1590 mix.ctlunit = "4 ms"; 1591 snprintf(mix.ctlname, sizeof(mix.ctlname), 1592 "%s.%s", mixername, AudioNdelay); 1593 #endif 1594 break; 1595 case BASS_BOOST_CONTROL: 1596 mix.type = MIX_ON_OFF; 1597 #if defined(__FreeBSD__) 1598 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */ 1599 #else 1600 mix.ctlunit = ""; 1601 snprintf(mix.ctlname, sizeof(mix.ctlname), 1602 "%s.%s", mixername, AudioNbassboost); 1603 #endif 1604 break; 1605 case LOUDNESS_CONTROL: 1606 mix.type = MIX_ON_OFF; 1607 #if defined(__FreeBSD__) 1608 mix.ctl = SOUND_MIXER_LOUD; /* Is this correct ? */ 1609 #else 1610 mix.ctlunit = ""; 1611 snprintf(mix.ctlname, sizeof(mix.ctlname), 1612 "%s.%s", mixername, AudioNloudness); 1613 #endif 1614 break; 1615 } 1616 uaudio_mixer_add_ctl(sc, &mix); 1617 } 1618 } 1619 1620 static void 1621 uaudio_add_processing_updown(struct uaudio_softc *sc, 1622 const struct io_terminal *iot, int id) 1623 { 1624 const struct usb_audio_processing_unit *d; 1625 const struct usb_audio_processing_unit_1 *d1; 1626 const struct usb_audio_processing_unit_updown *ud; 1627 struct mixerctl mix; 1628 int i; 1629 1630 d = iot[id].d.pu; 1631 d1 = (const struct usb_audio_processing_unit_1 *) 1632 &d->baSourceId[d->bNrInPins]; 1633 ud = (const struct usb_audio_processing_unit_updown *) 1634 &d1->bmControls[d1->bControlSize]; 1635 DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n", 1636 d->bUnitId, ud->bNrModes)); 1637 1638 if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) { 1639 DPRINTF(("uaudio_add_processing_updown: no mode select\n")); 1640 return; 1641 } 1642 1643 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1644 mix.nchan = 1; 1645 mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0); 1646 uaudio_determine_class(&iot[id], &mix); 1647 mix.type = MIX_ON_OFF; /* XXX */ 1648 #if !defined(__FreeBSD__) 1649 mix.ctlunit = ""; 1650 snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId); 1651 #endif 1652 1653 for (i = 0; i < ud->bNrModes; i++) { 1654 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n", 1655 i, UGETW(ud->waModes[i]))); 1656 /* XXX */ 1657 } 1658 uaudio_mixer_add_ctl(sc, &mix); 1659 } 1660 1661 static void 1662 uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 1663 { 1664 const struct usb_audio_processing_unit *d; 1665 const struct usb_audio_processing_unit_1 *d1; 1666 int ptype; 1667 struct mixerctl mix; 1668 1669 d = iot[id].d.pu; 1670 d1 = (const struct usb_audio_processing_unit_1 *) 1671 &d->baSourceId[d->bNrInPins]; 1672 ptype = UGETW(d->wProcessType); 1673 DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d " 1674 "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins)); 1675 1676 if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) { 1677 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1678 mix.nchan = 1; 1679 mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0); 1680 uaudio_determine_class(&iot[id], &mix); 1681 mix.type = MIX_ON_OFF; 1682 #if !defined(__FreeBSD__) 1683 mix.ctlunit = ""; 1684 snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable", 1685 d->bUnitId, ptype); 1686 #endif 1687 uaudio_mixer_add_ctl(sc, &mix); 1688 } 1689 1690 switch(ptype) { 1691 case UPDOWNMIX_PROCESS: 1692 uaudio_add_processing_updown(sc, iot, id); 1693 break; 1694 case DOLBY_PROLOGIC_PROCESS: 1695 case P3D_STEREO_EXTENDER_PROCESS: 1696 case REVERBATION_PROCESS: 1697 case CHORUS_PROCESS: 1698 case DYN_RANGE_COMP_PROCESS: 1699 default: 1700 #ifdef USB_DEBUG 1701 printf("uaudio_add_processing: unit %d, type=%d not impl.\n", 1702 d->bUnitId, ptype); 1703 #endif 1704 break; 1705 } 1706 } 1707 1708 static void 1709 uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 1710 { 1711 const struct usb_audio_extension_unit *d; 1712 const struct usb_audio_extension_unit_1 *d1; 1713 struct mixerctl mix; 1714 1715 d = iot[id].d.eu; 1716 d1 = (const struct usb_audio_extension_unit_1 *) 1717 &d->baSourceId[d->bNrInPins]; 1718 DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n", 1719 d->bUnitId, d->bNrInPins)); 1720 1721 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU) 1722 return; 1723 1724 if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) { 1725 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1726 mix.nchan = 1; 1727 mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0); 1728 uaudio_determine_class(&iot[id], &mix); 1729 mix.type = MIX_ON_OFF; 1730 #if !defined(__FreeBSD__) 1731 mix.ctlunit = ""; 1732 snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable", 1733 d->bUnitId); 1734 #endif 1735 uaudio_mixer_add_ctl(sc, &mix); 1736 } 1737 } 1738 1739 static struct terminal_list* 1740 uaudio_merge_terminal_list(const struct io_terminal *iot) 1741 { 1742 struct terminal_list *tml; 1743 uint16_t *ptm; 1744 int i, len; 1745 1746 len = 0; 1747 if (iot->inputs == NULL) 1748 return NULL; 1749 for (i = 0; i < iot->inputs_size; i++) { 1750 if (iot->inputs[i] != NULL) 1751 len += iot->inputs[i]->size; 1752 } 1753 tml = malloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT); 1754 if (tml == NULL) { 1755 printf("uaudio_merge_terminal_list: no memory\n"); 1756 return NULL; 1757 } 1758 tml->size = 0; 1759 ptm = tml->terminals; 1760 for (i = 0; i < iot->inputs_size; i++) { 1761 if (iot->inputs[i] == NULL) 1762 continue; 1763 if (iot->inputs[i]->size > len) 1764 break; 1765 memcpy(ptm, iot->inputs[i]->terminals, 1766 iot->inputs[i]->size * sizeof(uint16_t)); 1767 tml->size += iot->inputs[i]->size; 1768 ptm += iot->inputs[i]->size; 1769 len -= iot->inputs[i]->size; 1770 } 1771 return tml; 1772 } 1773 1774 static struct terminal_list * 1775 uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) 1776 { 1777 struct terminal_list *tml; 1778 struct io_terminal *it; 1779 int src_id, i; 1780 1781 it = &iot[id]; 1782 if (it->output != NULL) { 1783 /* already has outtype? */ 1784 for (i = 0; i < it->output->size; i++) 1785 if (it->output->terminals[i] == outtype) 1786 return uaudio_merge_terminal_list(it); 1787 tml = malloc(TERMINAL_LIST_SIZE(it->output->size + 1), 1788 M_TEMP, M_NOWAIT); 1789 if (tml == NULL) { 1790 printf("uaudio_io_terminaltype: no memory\n"); 1791 return uaudio_merge_terminal_list(it); 1792 } 1793 memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size)); 1794 tml->terminals[it->output->size] = outtype; 1795 tml->size++; 1796 free(it->output, M_TEMP); 1797 it->output = tml; 1798 if (it->inputs != NULL) { 1799 for (i = 0; i < it->inputs_size; i++) 1800 if (it->inputs[i] != NULL) 1801 free(it->inputs[i], M_TEMP); 1802 free(it->inputs, M_TEMP); 1803 } 1804 it->inputs_size = 0; 1805 it->inputs = NULL; 1806 } else { /* end `iot[id] != NULL' */ 1807 it->inputs_size = 0; 1808 it->inputs = NULL; 1809 it->output = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT); 1810 if (it->output == NULL) { 1811 printf("uaudio_io_terminaltype: no memory\n"); 1812 return NULL; 1813 } 1814 it->output->terminals[0] = outtype; 1815 it->output->size = 1; 1816 it->direct = FALSE; 1817 } 1818 1819 switch (it->d.desc->bDescriptorSubtype) { 1820 case UDESCSUB_AC_INPUT: 1821 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); 1822 if (it->inputs == NULL) { 1823 printf("uaudio_io_terminaltype: no memory\n"); 1824 return NULL; 1825 } 1826 tml = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT); 1827 if (tml == NULL) { 1828 printf("uaudio_io_terminaltype: no memory\n"); 1829 free(it->inputs, M_TEMP); 1830 it->inputs = NULL; 1831 return NULL; 1832 } 1833 it->inputs[0] = tml; 1834 tml->terminals[0] = UGETW(it->d.it->wTerminalType); 1835 tml->size = 1; 1836 it->inputs_size = 1; 1837 return uaudio_merge_terminal_list(it); 1838 case UDESCSUB_AC_FEATURE: 1839 src_id = it->d.fu->bSourceId; 1840 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); 1841 if (it->inputs == NULL) { 1842 printf("uaudio_io_terminaltype: no memory\n"); 1843 return uaudio_io_terminaltype(outtype, iot, src_id); 1844 } 1845 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id); 1846 it->inputs_size = 1; 1847 return uaudio_merge_terminal_list(it); 1848 case UDESCSUB_AC_OUTPUT: 1849 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); 1850 if (it->inputs == NULL) { 1851 printf("uaudio_io_terminaltype: no memory\n"); 1852 return NULL; 1853 } 1854 src_id = it->d.ot->bSourceId; 1855 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id); 1856 it->inputs_size = 1; 1857 iot[src_id].direct = TRUE; 1858 return NULL; 1859 case UDESCSUB_AC_MIXER: 1860 it->inputs_size = 0; 1861 it->inputs = malloc(sizeof(struct terminal_list *) 1862 * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT); 1863 if (it->inputs == NULL) { 1864 printf("uaudio_io_terminaltype: no memory\n"); 1865 return NULL; 1866 } 1867 for (i = 0; i < it->d.mu->bNrInPins; i++) { 1868 src_id = it->d.mu->baSourceId[i]; 1869 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1870 src_id); 1871 it->inputs_size++; 1872 } 1873 return uaudio_merge_terminal_list(it); 1874 case UDESCSUB_AC_SELECTOR: 1875 it->inputs_size = 0; 1876 it->inputs = malloc(sizeof(struct terminal_list *) 1877 * it->d.su->bNrInPins, M_TEMP, M_NOWAIT); 1878 if (it->inputs == NULL) { 1879 printf("uaudio_io_terminaltype: no memory\n"); 1880 return NULL; 1881 } 1882 for (i = 0; i < it->d.su->bNrInPins; i++) { 1883 src_id = it->d.su->baSourceId[i]; 1884 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1885 src_id); 1886 it->inputs_size++; 1887 } 1888 return uaudio_merge_terminal_list(it); 1889 case UDESCSUB_AC_PROCESSING: 1890 it->inputs_size = 0; 1891 it->inputs = malloc(sizeof(struct terminal_list *) 1892 * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT); 1893 if (it->inputs == NULL) { 1894 printf("uaudio_io_terminaltype: no memory\n"); 1895 return NULL; 1896 } 1897 for (i = 0; i < it->d.pu->bNrInPins; i++) { 1898 src_id = it->d.pu->baSourceId[i]; 1899 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1900 src_id); 1901 it->inputs_size++; 1902 } 1903 return uaudio_merge_terminal_list(it); 1904 case UDESCSUB_AC_EXTENSION: 1905 it->inputs_size = 0; 1906 it->inputs = malloc(sizeof(struct terminal_list *) 1907 * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT); 1908 if (it->inputs == NULL) { 1909 printf("uaudio_io_terminaltype: no memory\n"); 1910 return NULL; 1911 } 1912 for (i = 0; i < it->d.eu->bNrInPins; i++) { 1913 src_id = it->d.eu->baSourceId[i]; 1914 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1915 src_id); 1916 it->inputs_size++; 1917 } 1918 return uaudio_merge_terminal_list(it); 1919 case UDESCSUB_AC_HEADER: 1920 default: 1921 return NULL; 1922 } 1923 } 1924 1925 static usbd_status 1926 uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc) 1927 { 1928 usbd_status err; 1929 1930 err = uaudio_identify_ac(sc, cdesc); 1931 if (err) 1932 return err; 1933 return uaudio_identify_as(sc, cdesc); 1934 } 1935 1936 static void 1937 uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai) 1938 { 1939 size_t len; 1940 struct as_info *nai; 1941 1942 len = sizeof(*ai) * (sc->sc_nalts + 1); 1943 nai = malloc(len, M_USBDEV, M_NOWAIT); 1944 if (nai == NULL) { 1945 printf("uaudio_add_alt: no memory\n"); 1946 return; 1947 } 1948 /* Copy old data, if there was any */ 1949 if (sc->sc_nalts != 0) { 1950 memcpy(nai, sc->sc_alts, sizeof(*ai) * (sc->sc_nalts)); 1951 free(sc->sc_alts, M_USBDEV); 1952 } 1953 sc->sc_alts = nai; 1954 DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n", 1955 ai->alt, ai->encoding)); 1956 sc->sc_alts[sc->sc_nalts++] = *ai; 1957 } 1958 1959 static usbd_status 1960 uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp, 1961 int size, const usb_interface_descriptor_t *id) 1962 #define offs (*offsp) 1963 { 1964 const struct usb_audio_streaming_interface_descriptor *asid; 1965 const struct usb_audio_streaming_type1_descriptor *asf1d; 1966 const usb_endpoint_descriptor_audio_t *ed; 1967 const usb_endpoint_descriptor_audio_t *epdesc1; 1968 const struct usb_audio_streaming_endpoint_descriptor *sed; 1969 int format, chan, prec, enc; 1970 int dir, type, sync; 1971 struct as_info ai; 1972 const char *format_str; 1973 1974 asid = (const void *)(buf + offs); 1975 1976 if (asid->bDescriptorType != UDESC_CS_INTERFACE || 1977 asid->bDescriptorSubtype != AS_GENERAL) 1978 return USBD_INVAL; 1979 DPRINTF(("uaudio_process_as: asid: bTerminakLink=%d wFormatTag=%d\n", 1980 asid->bTerminalLink, UGETW(asid->wFormatTag))); 1981 offs += asid->bLength; 1982 if (offs > size) 1983 return USBD_INVAL; 1984 1985 asf1d = (const void *)(buf + offs); 1986 if (asf1d->bDescriptorType != UDESC_CS_INTERFACE || 1987 asf1d->bDescriptorSubtype != FORMAT_TYPE) 1988 return USBD_INVAL; 1989 offs += asf1d->bLength; 1990 if (offs > size) 1991 return USBD_INVAL; 1992 1993 if (asf1d->bFormatType != FORMAT_TYPE_I) { 1994 printf("%s: ignored setting with type %d format\n", 1995 device_get_nameunit(sc->sc_dev), UGETW(asid->wFormatTag)); 1996 return USBD_NORMAL_COMPLETION; 1997 } 1998 1999 ed = (const void *)(buf + offs); 2000 if (ed->bDescriptorType != UDESC_ENDPOINT) 2001 return USBD_INVAL; 2002 DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d " 2003 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d " 2004 "bInterval=%d bRefresh=%d bSynchAddress=%d\n", 2005 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress, 2006 ed->bmAttributes, UGETW(ed->wMaxPacketSize), 2007 ed->bInterval, ed->bRefresh, ed->bSynchAddress)); 2008 offs += ed->bLength; 2009 if (offs > size) 2010 return USBD_INVAL; 2011 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS) 2012 return USBD_INVAL; 2013 2014 dir = UE_GET_DIR(ed->bEndpointAddress); 2015 type = UE_GET_ISO_TYPE(ed->bmAttributes); 2016 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) && 2017 dir == UE_DIR_IN && type == UE_ISO_ADAPT) 2018 type = UE_ISO_ASYNC; 2019 2020 /* We can't handle endpoints that need a sync pipe yet. */ 2021 sync = FALSE; 2022 if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) { 2023 sync = TRUE; 2024 #ifndef UAUDIO_MULTIPLE_ENDPOINTS 2025 printf("%s: ignored input endpoint of type adaptive\n", 2026 device_get_nameunit(sc->sc_dev)); 2027 return USBD_NORMAL_COMPLETION; 2028 #endif 2029 } 2030 if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) { 2031 sync = TRUE; 2032 #ifndef UAUDIO_MULTIPLE_ENDPOINTS 2033 printf("%s: ignored output endpoint of type async\n", 2034 device_get_nameunit(sc->sc_dev)); 2035 return USBD_NORMAL_COMPLETION; 2036 #endif 2037 } 2038 2039 sed = (const void *)(buf + offs); 2040 if (sed->bDescriptorType != UDESC_CS_ENDPOINT || 2041 sed->bDescriptorSubtype != AS_GENERAL) 2042 return USBD_INVAL; 2043 DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength)); 2044 offs += sed->bLength; 2045 if (offs > size) 2046 return USBD_INVAL; 2047 2048 #ifdef UAUDIO_MULTIPLE_ENDPOINTS 2049 if (sync && id->bNumEndpoints <= 1) { 2050 printf("%s: a sync-pipe endpoint but no other endpoint\n", 2051 device_get_nameunit(sc->sc_dev)); 2052 return USBD_INVAL; 2053 } 2054 #endif 2055 if (!sync && id->bNumEndpoints > 1) { 2056 printf("%s: non sync-pipe endpoint but multiple endpoints\n", 2057 device_get_nameunit(sc->sc_dev)); 2058 return USBD_INVAL; 2059 } 2060 epdesc1 = NULL; 2061 if (id->bNumEndpoints > 1) { 2062 epdesc1 = (const void*)(buf + offs); 2063 if (epdesc1->bDescriptorType != UDESC_ENDPOINT) 2064 return USBD_INVAL; 2065 DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d " 2066 "bDescriptorType=%d bEndpointAddress=%d " 2067 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d " 2068 "bRefresh=%d bSynchAddress=%d\n", 2069 epdesc1->bLength, epdesc1->bDescriptorType, 2070 epdesc1->bEndpointAddress, epdesc1->bmAttributes, 2071 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval, 2072 epdesc1->bRefresh, epdesc1->bSynchAddress)); 2073 offs += epdesc1->bLength; 2074 if (offs > size) 2075 return USBD_INVAL; 2076 if (epdesc1->bSynchAddress != 0) { 2077 printf("%s: invalid endpoint: bSynchAddress=0\n", 2078 device_get_nameunit(sc->sc_dev)); 2079 return USBD_INVAL; 2080 } 2081 if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) { 2082 printf("%s: invalid endpoint: bmAttributes=0x%x\n", 2083 device_get_nameunit(sc->sc_dev), epdesc1->bmAttributes); 2084 return USBD_INVAL; 2085 } 2086 if (epdesc1->bEndpointAddress != ed->bSynchAddress) { 2087 printf("%s: invalid endpoint addresses: " 2088 "ep[0]->bSynchAddress=0x%x " 2089 "ep[1]->bEndpointAddress=0x%x\n", 2090 device_get_nameunit(sc->sc_dev), ed->bSynchAddress, 2091 epdesc1->bEndpointAddress); 2092 return USBD_INVAL; 2093 } 2094 /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */ 2095 } 2096 2097 format = UGETW(asid->wFormatTag); 2098 chan = asf1d->bNrChannels; 2099 prec = asf1d->bBitResolution; 2100 if (prec != 8 && prec != 16 && prec != 24 && prec != 32) { 2101 printf("%s: ignored setting with precision %d\n", 2102 device_get_nameunit(sc->sc_dev), prec); 2103 return USBD_NORMAL_COMPLETION; 2104 } 2105 switch (format) { 2106 case UA_FMT_PCM: 2107 if (prec == 8) { 2108 sc->sc_altflags |= HAS_8; 2109 } else if (prec == 16) { 2110 sc->sc_altflags |= HAS_16; 2111 } else if (prec == 24) { 2112 sc->sc_altflags |= HAS_24; 2113 } else if (prec == 32) { 2114 sc->sc_altflags |= HAS_32; 2115 } 2116 enc = AUDIO_ENCODING_SLINEAR_LE; 2117 format_str = "pcm"; 2118 break; 2119 case UA_FMT_PCM8: 2120 enc = AUDIO_ENCODING_ULINEAR_LE; 2121 sc->sc_altflags |= HAS_8U; 2122 format_str = "pcm8"; 2123 break; 2124 case UA_FMT_ALAW: 2125 enc = AUDIO_ENCODING_ALAW; 2126 sc->sc_altflags |= HAS_ALAW; 2127 format_str = "alaw"; 2128 break; 2129 case UA_FMT_MULAW: 2130 enc = AUDIO_ENCODING_ULAW; 2131 sc->sc_altflags |= HAS_MULAW; 2132 format_str = "mulaw"; 2133 break; 2134 case UA_FMT_IEEE_FLOAT: 2135 default: 2136 printf("%s: ignored setting with format %d\n", 2137 device_get_nameunit(sc->sc_dev), format); 2138 return USBD_NORMAL_COMPLETION; 2139 } 2140 #ifdef USB_DEBUG 2141 printf("%s: %s: %dch, %d/%dbit, %s,", device_get_nameunit(sc->sc_dev), 2142 dir == UE_DIR_IN ? "recording" : "playback", 2143 chan, prec, asf1d->bSubFrameSize * 8, format_str); 2144 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 2145 printf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d)); 2146 } else { 2147 int r; 2148 printf(" %d", UA_GETSAMP(asf1d, 0)); 2149 for (r = 1; r < asf1d->bSamFreqType; r++) 2150 printf(",%d", UA_GETSAMP(asf1d, r)); 2151 printf("Hz\n"); 2152 } 2153 #endif 2154 #if defined(__FreeBSD__) 2155 if (sc->uaudio_sndstat_flag != 0) { 2156 sbuf_printf(&(sc->uaudio_sndstat), "\n\t"); 2157 sbuf_printf(&(sc->uaudio_sndstat), 2158 "mode %d:(%s) %dch, %d/%dbit, %s,", 2159 id->bAlternateSetting, 2160 dir == UE_DIR_IN ? "input" : "output", 2161 chan, prec, asf1d->bSubFrameSize * 8, format_str); 2162 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 2163 sbuf_printf(&(sc->uaudio_sndstat), " %d-%dHz", 2164 UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d)); 2165 } else { 2166 int r; 2167 sbuf_printf(&(sc->uaudio_sndstat), 2168 " %d", UA_GETSAMP(asf1d, 0)); 2169 for (r = 1; r < asf1d->bSamFreqType; r++) 2170 sbuf_printf(&(sc->uaudio_sndstat), 2171 ",%d", UA_GETSAMP(asf1d, r)); 2172 sbuf_printf(&(sc->uaudio_sndstat), "Hz"); 2173 } 2174 } 2175 #endif 2176 ai.alt = id->bAlternateSetting; 2177 ai.encoding = enc; 2178 ai.attributes = sed->bmAttributes; 2179 ai.idesc = id; 2180 ai.edesc = ed; 2181 ai.edesc1 = epdesc1; 2182 ai.asf1desc = asf1d; 2183 ai.sc_busy = 0; 2184 ai.ifaceh = NULL; 2185 uaudio_add_alt(sc, &ai); 2186 #ifdef USB_DEBUG 2187 if (ai.attributes & UA_SED_FREQ_CONTROL) 2188 DPRINTFN(1, ("uaudio_process_as: FREQ_CONTROL\n")); 2189 if (ai.attributes & UA_SED_PITCH_CONTROL) 2190 DPRINTFN(1, ("uaudio_process_as: PITCH_CONTROL\n")); 2191 #endif 2192 sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD; 2193 2194 return USBD_NORMAL_COMPLETION; 2195 } 2196 #undef offs 2197 2198 static usbd_status 2199 uaudio_identify_as(struct uaudio_softc *sc, 2200 const usb_config_descriptor_t *cdesc) 2201 { 2202 const usb_interface_descriptor_t *id; 2203 const char *buf; 2204 int size, offs; 2205 2206 size = UGETW(cdesc->wTotalLength); 2207 buf = (const char *)cdesc; 2208 2209 /* Locate the AudioStreaming interface descriptor. */ 2210 offs = 0; 2211 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM); 2212 if (id == NULL) 2213 return USBD_INVAL; 2214 2215 #if defined(__FreeBSD__) 2216 sc->uaudio_sndstat_flag = 0; 2217 if (sbuf_new(&(sc->uaudio_sndstat), NULL, 4096, SBUF_AUTOEXTEND) != NULL) 2218 sc->uaudio_sndstat_flag = 1; 2219 #endif 2220 /* Loop through all the alternate settings. */ 2221 while (offs <= size) { 2222 DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n", 2223 id->bInterfaceNumber, offs)); 2224 switch (id->bNumEndpoints) { 2225 case 0: 2226 DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n", 2227 id->bAlternateSetting)); 2228 sc->sc_nullalt = id->bAlternateSetting; 2229 break; 2230 case 1: 2231 #ifdef UAUDIO_MULTIPLE_ENDPOINTS 2232 case 2: 2233 #endif 2234 uaudio_process_as(sc, buf, &offs, size, id); 2235 break; 2236 default: 2237 printf("%s: ignored audio interface with %d " 2238 "endpoints\n", 2239 device_get_nameunit(sc->sc_dev), id->bNumEndpoints); 2240 break; 2241 } 2242 id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM); 2243 if (id == NULL) 2244 break; 2245 } 2246 #if defined(__FreeBSD__) 2247 sbuf_finish(&(sc->uaudio_sndstat)); 2248 #endif 2249 if (offs > size) 2250 return USBD_INVAL; 2251 DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts)); 2252 2253 if (sc->sc_mode == 0) { 2254 printf("%s: no usable endpoint found\n", 2255 device_get_nameunit(sc->sc_dev)); 2256 return USBD_INVAL; 2257 } 2258 2259 return USBD_NORMAL_COMPLETION; 2260 } 2261 2262 static usbd_status 2263 uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc) 2264 { 2265 struct io_terminal* iot; 2266 const usb_interface_descriptor_t *id; 2267 const struct usb_audio_control_descriptor *acdp; 2268 const usb_descriptor_t *dp; 2269 const struct usb_audio_output_terminal *pot; 2270 struct terminal_list *tml; 2271 const char *buf, *ibuf, *ibufend; 2272 int size, offs, aclen, ndps, i, j; 2273 2274 size = UGETW(cdesc->wTotalLength); 2275 buf = (const char *)cdesc; 2276 2277 /* Locate the AudioControl interface descriptor. */ 2278 offs = 0; 2279 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL); 2280 if (id == NULL) 2281 return USBD_INVAL; 2282 if (offs + sizeof *acdp > size) 2283 return USBD_INVAL; 2284 sc->sc_ac_iface = id->bInterfaceNumber; 2285 DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface)); 2286 2287 /* A class-specific AC interface header should follow. */ 2288 ibuf = buf + offs; 2289 acdp = (const struct usb_audio_control_descriptor *)ibuf; 2290 if (acdp->bDescriptorType != UDESC_CS_INTERFACE || 2291 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER) 2292 return USBD_INVAL; 2293 aclen = UGETW(acdp->wTotalLength); 2294 if (offs + aclen > size) 2295 return USBD_INVAL; 2296 2297 if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) && 2298 UGETW(acdp->bcdADC) != UAUDIO_VERSION) 2299 return USBD_INVAL; 2300 2301 sc->sc_audio_rev = UGETW(acdp->bcdADC); 2302 DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n", 2303 sc->sc_audio_rev, aclen)); 2304 2305 sc->sc_nullalt = -1; 2306 2307 /* Scan through all the AC specific descriptors */ 2308 ibufend = ibuf + aclen; 2309 dp = (const usb_descriptor_t *)ibuf; 2310 ndps = 0; 2311 iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO); 2312 if (iot == NULL) { 2313 printf("%s: no memory\n", __func__); 2314 return USBD_NOMEM; 2315 } 2316 for (;;) { 2317 ibuf += dp->bLength; 2318 if (ibuf >= ibufend) 2319 break; 2320 dp = (const usb_descriptor_t *)ibuf; 2321 if (ibuf + dp->bLength > ibufend) { 2322 free(iot, M_TEMP); 2323 return USBD_INVAL; 2324 } 2325 if (dp->bDescriptorType != UDESC_CS_INTERFACE) { 2326 printf("uaudio_identify_ac: skip desc type=0x%02x\n", 2327 dp->bDescriptorType); 2328 continue; 2329 } 2330 i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId; 2331 iot[i].d.desc = dp; 2332 if (i > ndps) 2333 ndps = i; 2334 } 2335 ndps++; 2336 2337 /* construct io_terminal */ 2338 for (i = 0; i < ndps; i++) { 2339 dp = iot[i].d.desc; 2340 if (dp == NULL) 2341 continue; 2342 if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT) 2343 continue; 2344 pot = iot[i].d.ot; 2345 tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i); 2346 if (tml != NULL) 2347 free(tml, M_TEMP); 2348 } 2349 2350 #ifdef USB_DEBUG 2351 for (i = 0; i < 256; i++) { 2352 struct usb_audio_cluster cluster; 2353 2354 if (iot[i].d.desc == NULL) 2355 continue; 2356 logprintf("id %d:\t", i); 2357 switch (iot[i].d.desc->bDescriptorSubtype) { 2358 case UDESCSUB_AC_INPUT: 2359 logprintf("AC_INPUT type=%s\n", uaudio_get_terminal_name 2360 (UGETW(iot[i].d.it->wTerminalType))); 2361 logprintf("\t"); 2362 cluster = uaudio_get_cluster(i, iot); 2363 uaudio_dump_cluster(&cluster); 2364 logprintf("\n"); 2365 break; 2366 case UDESCSUB_AC_OUTPUT: 2367 logprintf("AC_OUTPUT type=%s ", uaudio_get_terminal_name 2368 (UGETW(iot[i].d.ot->wTerminalType))); 2369 logprintf("src=%d\n", iot[i].d.ot->bSourceId); 2370 break; 2371 case UDESCSUB_AC_MIXER: 2372 logprintf("AC_MIXER src="); 2373 for (j = 0; j < iot[i].d.mu->bNrInPins; j++) 2374 logprintf("%d ", iot[i].d.mu->baSourceId[j]); 2375 logprintf("\n\t"); 2376 cluster = uaudio_get_cluster(i, iot); 2377 uaudio_dump_cluster(&cluster); 2378 logprintf("\n"); 2379 break; 2380 case UDESCSUB_AC_SELECTOR: 2381 logprintf("AC_SELECTOR src="); 2382 for (j = 0; j < iot[i].d.su->bNrInPins; j++) 2383 logprintf("%d ", iot[i].d.su->baSourceId[j]); 2384 logprintf("\n"); 2385 break; 2386 case UDESCSUB_AC_FEATURE: 2387 logprintf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId); 2388 break; 2389 case UDESCSUB_AC_PROCESSING: 2390 logprintf("AC_PROCESSING src="); 2391 for (j = 0; j < iot[i].d.pu->bNrInPins; j++) 2392 logprintf("%d ", iot[i].d.pu->baSourceId[j]); 2393 logprintf("\n\t"); 2394 cluster = uaudio_get_cluster(i, iot); 2395 uaudio_dump_cluster(&cluster); 2396 logprintf("\n"); 2397 break; 2398 case UDESCSUB_AC_EXTENSION: 2399 logprintf("AC_EXTENSION src="); 2400 for (j = 0; j < iot[i].d.eu->bNrInPins; j++) 2401 logprintf("%d ", iot[i].d.eu->baSourceId[j]); 2402 logprintf("\n\t"); 2403 cluster = uaudio_get_cluster(i, iot); 2404 uaudio_dump_cluster(&cluster); 2405 logprintf("\n"); 2406 break; 2407 default: 2408 logprintf("unknown audio control (subtype=%d)\n", 2409 iot[i].d.desc->bDescriptorSubtype); 2410 } 2411 for (j = 0; j < iot[i].inputs_size; j++) { 2412 int k; 2413 logprintf("\tinput%d: ", j); 2414 tml = iot[i].inputs[j]; 2415 if (tml == NULL) { 2416 logprintf("NULL\n"); 2417 continue; 2418 } 2419 for (k = 0; k < tml->size; k++) 2420 logprintf("%s ", uaudio_get_terminal_name 2421 (tml->terminals[k])); 2422 logprintf("\n"); 2423 } 2424 logprintf("\toutput: "); 2425 tml = iot[i].output; 2426 for (j = 0; j < tml->size; j++) 2427 logprintf("%s ", uaudio_get_terminal_name(tml->terminals[j])); 2428 logprintf("\n"); 2429 } 2430 #endif 2431 2432 for (i = 0; i < ndps; i++) { 2433 dp = iot[i].d.desc; 2434 if (dp == NULL) 2435 continue; 2436 DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n", 2437 i, dp->bDescriptorSubtype)); 2438 switch (dp->bDescriptorSubtype) { 2439 case UDESCSUB_AC_HEADER: 2440 printf("uaudio_identify_ac: unexpected AC header\n"); 2441 break; 2442 case UDESCSUB_AC_INPUT: 2443 uaudio_add_input(sc, iot, i); 2444 break; 2445 case UDESCSUB_AC_OUTPUT: 2446 uaudio_add_output(sc, iot, i); 2447 break; 2448 case UDESCSUB_AC_MIXER: 2449 uaudio_add_mixer(sc, iot, i); 2450 break; 2451 case UDESCSUB_AC_SELECTOR: 2452 uaudio_add_selector(sc, iot, i); 2453 break; 2454 case UDESCSUB_AC_FEATURE: 2455 uaudio_add_feature(sc, iot, i); 2456 break; 2457 case UDESCSUB_AC_PROCESSING: 2458 uaudio_add_processing(sc, iot, i); 2459 break; 2460 case UDESCSUB_AC_EXTENSION: 2461 uaudio_add_extension(sc, iot, i); 2462 break; 2463 default: 2464 printf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n", 2465 dp->bDescriptorSubtype); 2466 break; 2467 } 2468 } 2469 2470 /* delete io_terminal */ 2471 for (i = 0; i < 256; i++) { 2472 if (iot[i].d.desc == NULL) 2473 continue; 2474 if (iot[i].inputs != NULL) { 2475 for (j = 0; j < iot[i].inputs_size; j++) { 2476 if (iot[i].inputs[j] != NULL) 2477 free(iot[i].inputs[j], M_TEMP); 2478 } 2479 free(iot[i].inputs, M_TEMP); 2480 } 2481 if (iot[i].output != NULL) 2482 free(iot[i].output, M_TEMP); 2483 iot[i].d.desc = NULL; 2484 } 2485 free(iot, M_TEMP); 2486 2487 return USBD_NORMAL_COMPLETION; 2488 } 2489 2490 #if defined(__NetBSD__) || defined(__OpenBSD__) 2491 static int 2492 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi) 2493 { 2494 struct uaudio_softc *sc; 2495 struct mixerctl *mc; 2496 int n, nctls, i; 2497 2498 sc = addr; 2499 DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index)); 2500 if (sc->sc_dying) 2501 return EIO; 2502 2503 n = mi->index; 2504 nctls = sc->sc_nctls; 2505 2506 switch (n) { 2507 case UAC_OUTPUT: 2508 mi->type = AUDIO_MIXER_CLASS; 2509 mi->mixer_class = UAC_OUTPUT; 2510 mi->next = mi->prev = AUDIO_MIXER_LAST; 2511 strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name)); 2512 return 0; 2513 case UAC_INPUT: 2514 mi->type = AUDIO_MIXER_CLASS; 2515 mi->mixer_class = UAC_INPUT; 2516 mi->next = mi->prev = AUDIO_MIXER_LAST; 2517 strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name)); 2518 return 0; 2519 case UAC_EQUAL: 2520 mi->type = AUDIO_MIXER_CLASS; 2521 mi->mixer_class = UAC_EQUAL; 2522 mi->next = mi->prev = AUDIO_MIXER_LAST; 2523 strlcpy(mi->label.name, AudioCequalization, 2524 sizeof(mi->label.name)); 2525 return 0; 2526 case UAC_RECORD: 2527 mi->type = AUDIO_MIXER_CLASS; 2528 mi->mixer_class = UAC_RECORD; 2529 mi->next = mi->prev = AUDIO_MIXER_LAST; 2530 strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name)); 2531 return 0; 2532 default: 2533 break; 2534 } 2535 2536 n -= UAC_NCLASSES; 2537 if (n < 0 || n >= nctls) 2538 return ENXIO; 2539 2540 mc = &sc->sc_ctls[n]; 2541 strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name)); 2542 mi->mixer_class = mc->class; 2543 mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */ 2544 switch (mc->type) { 2545 case MIX_ON_OFF: 2546 mi->type = AUDIO_MIXER_ENUM; 2547 mi->un.e.num_mem = 2; 2548 strlcpy(mi->un.e.member[0].label.name, AudioNoff, 2549 sizeof(mi->un.e.member[0].label.name)); 2550 mi->un.e.member[0].ord = 0; 2551 strlcpy(mi->un.e.member[1].label.name, AudioNon, 2552 sizeof(mi->un.e.member[1].label.name)); 2553 mi->un.e.member[1].ord = 1; 2554 break; 2555 case MIX_SELECTOR: 2556 mi->type = AUDIO_MIXER_ENUM; 2557 mi->un.e.num_mem = mc->maxval - mc->minval + 1; 2558 for (i = 0; i <= mc->maxval - mc->minval; i++) { 2559 snprintf(mi->un.e.member[i].label.name, 2560 sizeof(mi->un.e.member[i].label.name), 2561 "%d", i + mc->minval); 2562 mi->un.e.member[i].ord = i + mc->minval; 2563 } 2564 break; 2565 default: 2566 mi->type = AUDIO_MIXER_VALUE; 2567 strlcpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN); 2568 mi->un.v.num_channels = mc->nchan; 2569 mi->un.v.delta = mc->delta; 2570 break; 2571 } 2572 return 0; 2573 } 2574 2575 static int 2576 uaudio_open(void *addr, int flags) 2577 { 2578 struct uaudio_softc *sc; 2579 2580 sc = addr; 2581 DPRINTF(("uaudio_open: sc=%p\n", sc)); 2582 if (sc->sc_dying) 2583 return EIO; 2584 2585 if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY)) 2586 return EACCES; 2587 if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD)) 2588 return EACCES; 2589 2590 return 0; 2591 } 2592 2593 /* 2594 * Close function is called at splaudio(). 2595 */ 2596 static void 2597 uaudio_close(void *addr) 2598 { 2599 } 2600 2601 static int 2602 uaudio_drain(void *addr) 2603 { 2604 struct uaudio_softc *sc; 2605 2606 sc = addr; 2607 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); 2608 2609 return 0; 2610 } 2611 2612 static int 2613 uaudio_halt_out_dma(void *addr) 2614 { 2615 struct uaudio_softc *sc; 2616 2617 sc = addr; 2618 if (sc->sc_dying) 2619 return EIO; 2620 2621 DPRINTF(("uaudio_halt_out_dma: enter\n")); 2622 if (sc->sc_playchan.pipe != NULL) { 2623 uaudio_chan_close(sc, &sc->sc_playchan); 2624 sc->sc_playchan.pipe = NULL; 2625 uaudio_chan_free_buffers(sc, &sc->sc_playchan); 2626 sc->sc_playchan.intr = NULL; 2627 } 2628 return 0; 2629 } 2630 2631 static int 2632 uaudio_halt_in_dma(void *addr) 2633 { 2634 struct uaudio_softc *sc; 2635 2636 DPRINTF(("uaudio_halt_in_dma: enter\n")); 2637 sc = addr; 2638 if (sc->sc_recchan.pipe != NULL) { 2639 uaudio_chan_close(sc, &sc->sc_recchan); 2640 sc->sc_recchan.pipe = NULL; 2641 uaudio_chan_free_buffers(sc, &sc->sc_recchan); 2642 sc->sc_recchan.intr = NULL; 2643 } 2644 return 0; 2645 } 2646 2647 static int 2648 uaudio_getdev(void *addr, struct audio_device *retp) 2649 { 2650 struct uaudio_softc *sc; 2651 2652 DPRINTF(("uaudio_mixer_getdev:\n")); 2653 sc = addr; 2654 if (sc->sc_dying) 2655 return EIO; 2656 2657 *retp = uaudio_device; 2658 return 0; 2659 } 2660 2661 /* 2662 * Make sure the block size is large enough to hold all outstanding transfers. 2663 */ 2664 static int 2665 uaudio_round_blocksize(void *addr, int blk) 2666 { 2667 struct uaudio_softc *sc; 2668 int b; 2669 2670 sc = addr; 2671 DPRINTF(("uaudio_round_blocksize: blk=%d mode=%s\n", blk, 2672 mode == AUMODE_PLAY ? "AUMODE_PLAY" : "AUMODE_RECORD")); 2673 2674 /* chan.bytes_per_frame can be 0. */ 2675 if (mode == AUMODE_PLAY || sc->sc_recchan.bytes_per_frame <= 0) { 2676 b = param->sample_rate * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS; 2677 2678 /* 2679 * This does not make accurate value in the case 2680 * of b % USB_FRAMES_PER_SECOND != 0 2681 */ 2682 b /= USB_FRAMES_PER_SECOND; 2683 2684 b *= param->precision / 8 * param->channels; 2685 } else { 2686 /* 2687 * use wMaxPacketSize in bytes_per_frame. 2688 * See uaudio_set_params() and uaudio_chan_init() 2689 */ 2690 b = sc->sc_recchan.bytes_per_frame 2691 * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS; 2692 } 2693 2694 if (b <= 0) 2695 b = 1; 2696 blk = blk <= b ? b : blk / b * b; 2697 2698 #ifdef DIAGNOSTIC 2699 if (blk <= 0) { 2700 printf("uaudio_round_blocksize: blk=%d\n", blk); 2701 blk = 512; 2702 } 2703 #endif 2704 2705 DPRINTF(("uaudio_round_blocksize: resultant blk=%d\n", blk)); 2706 return blk; 2707 } 2708 2709 static int 2710 uaudio_get_props(void *addr) 2711 { 2712 return AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT; 2713 2714 } 2715 #endif /* NetBSD or OpenBSD */ 2716 2717 static int 2718 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue, 2719 int wIndex, int len) 2720 { 2721 usb_device_request_t req; 2722 uint8_t data[4]; 2723 usbd_status err; 2724 int val; 2725 2726 #if defined(__FreeBSD__) 2727 if (sc->sc_dying) 2728 return EIO; 2729 #endif 2730 2731 if (wValue == -1) 2732 return 0; 2733 2734 req.bmRequestType = type; 2735 req.bRequest = which; 2736 USETW(req.wValue, wValue); 2737 USETW(req.wIndex, wIndex); 2738 USETW(req.wLength, len); 2739 DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x " 2740 "wIndex=0x%04x len=%d\n", 2741 type, which, wValue, wIndex, len)); 2742 #if defined(__FreeBSD__) 2743 if (sc->async != 0) 2744 err = usbd_do_request_async(sc->sc_udev, &req, data); 2745 else 2746 #endif 2747 err = usbd_do_request(sc->sc_udev, &req, data); 2748 if (err) { 2749 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err))); 2750 return -1; 2751 } 2752 switch (len) { 2753 case 1: 2754 val = data[0]; 2755 break; 2756 case 2: 2757 val = data[0] | (data[1] << 8); 2758 break; 2759 default: 2760 DPRINTF(("uaudio_get: bad length=%d\n", len)); 2761 return -1; 2762 } 2763 DPRINTFN(2,("uaudio_get: val=%d\n", val)); 2764 return val; 2765 } 2766 2767 static void 2768 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue, 2769 int wIndex, int len, int val) 2770 { 2771 usb_device_request_t req; 2772 uint8_t data[4]; 2773 usbd_status err; 2774 2775 #if defined(__FreeBSD__) 2776 if (sc->sc_dying) 2777 return; 2778 #endif 2779 2780 if (wValue == -1) 2781 return; 2782 2783 req.bmRequestType = type; 2784 req.bRequest = which; 2785 USETW(req.wValue, wValue); 2786 USETW(req.wIndex, wIndex); 2787 USETW(req.wLength, len); 2788 switch (len) { 2789 case 1: 2790 data[0] = val; 2791 break; 2792 case 2: 2793 data[0] = val; 2794 data[1] = val >> 8; 2795 break; 2796 default: 2797 return; 2798 } 2799 DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x " 2800 "wIndex=0x%04x len=%d, val=%d\n", 2801 type, which, wValue, wIndex, len, val & 0xffff)); 2802 #if defined(__FreeBSD__) 2803 if (sc->async != 0) 2804 err = usbd_do_request_async(sc->sc_udev, &req, data); 2805 else 2806 #endif 2807 err = usbd_do_request(sc->sc_udev, &req, data); 2808 #ifdef USB_DEBUG 2809 if (err) 2810 DPRINTF(("uaudio_set: err=%d\n", err)); 2811 #endif 2812 } 2813 2814 static int 2815 uaudio_signext(int type, int val) 2816 { 2817 if (!MIX_UNSIGNED(type)) { 2818 if (MIX_SIZE(type) == 2) 2819 val = (int16_t)val; 2820 else 2821 val = (int8_t)val; 2822 } 2823 return val; 2824 } 2825 2826 #if defined(__NetBSD__) || defined(__OpenBSD__) 2827 static int 2828 uaudio_value2bsd(struct mixerctl *mc, int val) 2829 { 2830 DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ", 2831 mc->type, val, mc->minval, mc->maxval)); 2832 if (mc->type == MIX_ON_OFF) { 2833 val = (val != 0); 2834 } else if (mc->type == MIX_SELECTOR) { 2835 if (val < mc->minval || val > mc->maxval) 2836 val = mc->minval; 2837 } else 2838 val = ((uaudio_signext(mc->type, val) - mc->minval) * 255 2839 + mc->mul/2) / mc->mul; 2840 DPRINTFN(5, ("val'=%d\n", val)); 2841 return val; 2842 } 2843 #endif 2844 2845 int 2846 uaudio_bsd2value(struct mixerctl *mc, int val) 2847 { 2848 DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ", 2849 mc->type, val, mc->minval, mc->maxval)); 2850 if (mc->type == MIX_ON_OFF) { 2851 val = (val != 0); 2852 } else if (mc->type == MIX_SELECTOR) { 2853 if (val < mc->minval || val > mc->maxval) 2854 val = mc->minval; 2855 } else 2856 val = (val + mc->delta/2) * mc->mul / 255 + mc->minval; 2857 DPRINTFN(5, ("val'=%d\n", val)); 2858 return val; 2859 } 2860 2861 #if defined(__NetBSD__) || defined(__OpenBSD__) 2862 static int 2863 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc, 2864 int chan) 2865 { 2866 int val; 2867 2868 DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan)); 2869 val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan], 2870 mc->wIndex, MIX_SIZE(mc->type)); 2871 return uaudio_value2bsd(mc, val); 2872 } 2873 #endif 2874 2875 static void 2876 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc, 2877 int chan, int val) 2878 { 2879 val = uaudio_bsd2value(mc, val); 2880 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan], 2881 mc->wIndex, MIX_SIZE(mc->type), val); 2882 } 2883 2884 #if defined(__NetBSD__) || defined(__OpenBSD__) 2885 static int 2886 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp) 2887 { 2888 struct uaudio_softc *sc; 2889 struct mixerctl *mc; 2890 int i, n, vals[MIX_MAX_CHAN], val; 2891 2892 DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev)); 2893 sc = addr; 2894 if (sc->sc_dying) 2895 return EIO; 2896 2897 n = cp->dev - UAC_NCLASSES; 2898 if (n < 0 || n >= sc->sc_nctls) 2899 return ENXIO; 2900 mc = &sc->sc_ctls[n]; 2901 2902 if (mc->type == MIX_ON_OFF) { 2903 if (cp->type != AUDIO_MIXER_ENUM) 2904 return EINVAL; 2905 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0); 2906 } else if (mc->type == MIX_SELECTOR) { 2907 if (cp->type != AUDIO_MIXER_ENUM) 2908 return EINVAL; 2909 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0); 2910 } else { 2911 if (cp->type != AUDIO_MIXER_VALUE) 2912 return (EINVAL); 2913 if (cp->un.value.num_channels != 1 && 2914 cp->un.value.num_channels != mc->nchan) 2915 return EINVAL; 2916 for (i = 0; i < mc->nchan; i++) 2917 vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i); 2918 if (cp->un.value.num_channels == 1 && mc->nchan != 1) { 2919 for (val = 0, i = 0; i < mc->nchan; i++) 2920 val += vals[i]; 2921 vals[0] = val / mc->nchan; 2922 } 2923 for (i = 0; i < cp->un.value.num_channels; i++) 2924 cp->un.value.level[i] = vals[i]; 2925 } 2926 2927 return 0; 2928 } 2929 2930 static int 2931 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp) 2932 { 2933 struct uaudio_softc *sc; 2934 struct mixerctl *mc; 2935 int i, n, vals[MIX_MAX_CHAN]; 2936 2937 DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev)); 2938 sc = addr; 2939 if (sc->sc_dying) 2940 return EIO; 2941 2942 n = cp->dev - UAC_NCLASSES; 2943 if (n < 0 || n >= sc->sc_nctls) 2944 return ENXIO; 2945 mc = &sc->sc_ctls[n]; 2946 2947 if (mc->type == MIX_ON_OFF) { 2948 if (cp->type != AUDIO_MIXER_ENUM) 2949 return EINVAL; 2950 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord); 2951 } else if (mc->type == MIX_SELECTOR) { 2952 if (cp->type != AUDIO_MIXER_ENUM) 2953 return EINVAL; 2954 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord); 2955 } else { 2956 if (cp->type != AUDIO_MIXER_VALUE) 2957 return EINVAL; 2958 if (cp->un.value.num_channels == 1) 2959 for (i = 0; i < mc->nchan; i++) 2960 vals[i] = cp->un.value.level[0]; 2961 else if (cp->un.value.num_channels == mc->nchan) 2962 for (i = 0; i < mc->nchan; i++) 2963 vals[i] = cp->un.value.level[i]; 2964 else 2965 return EINVAL; 2966 for (i = 0; i < mc->nchan; i++) 2967 uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]); 2968 } 2969 return 0; 2970 } 2971 2972 static int 2973 uaudio_trigger_input(void *addr, void *start, void *end, int blksize, 2974 void (*intr)(void *), void *arg, 2975 struct audio_params *param) 2976 { 2977 struct uaudio_softc *sc; 2978 struct chan *ch; 2979 usbd_status err; 2980 int i, s; 2981 2982 sc = addr; 2983 if (sc->sc_dying) 2984 return EIO; 2985 2986 DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p " 2987 "blksize=%d\n", sc, start, end, blksize)); 2988 ch = &sc->sc_recchan; 2989 uaudio_chan_set_param(ch, start, end, blksize); 2990 DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d " 2991 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 2992 ch->fraction)); 2993 2994 err = uaudio_chan_alloc_buffers(sc, ch); 2995 if (err) 2996 return EIO; 2997 2998 err = uaudio_chan_open(sc, ch); 2999 if (err) { 3000 uaudio_chan_free_buffers(sc, ch); 3001 return EIO; 3002 } 3003 3004 ch->intr = intr; 3005 ch->arg = arg; 3006 3007 s = splusb(); 3008 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */ 3009 uaudio_chan_rtransfer(ch); 3010 splx(s); 3011 3012 return 0; 3013 } 3014 3015 static int 3016 uaudio_trigger_output(void *addr, void *start, void *end, int blksize, 3017 void (*intr)(void *), void *arg, 3018 struct audio_params *param) 3019 { 3020 struct uaudio_softc *sc; 3021 struct chan *ch; 3022 usbd_status err; 3023 int i, s; 3024 3025 sc = addr; 3026 if (sc->sc_dying) 3027 return EIO; 3028 3029 DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p " 3030 "blksize=%d\n", sc, start, end, blksize)); 3031 ch = &sc->sc_playchan; 3032 uaudio_chan_set_param(ch, start, end, blksize); 3033 DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d " 3034 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 3035 ch->fraction)); 3036 3037 err = uaudio_chan_alloc_buffers(sc, ch); 3038 if (err) 3039 return EIO; 3040 3041 err = uaudio_chan_open(sc, ch); 3042 if (err) { 3043 uaudio_chan_free_buffers(sc, ch); 3044 return EIO; 3045 } 3046 3047 ch->intr = intr; 3048 ch->arg = arg; 3049 3050 s = splusb(); 3051 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */ 3052 uaudio_chan_ptransfer(ch); 3053 splx(s); 3054 3055 return 0; 3056 } 3057 #endif /* NetBSD or OpenBSD */ 3058 3059 /* Set up a pipe for a channel. */ 3060 static usbd_status 3061 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch) 3062 { 3063 struct as_info *as; 3064 int endpt; 3065 #if defined(__FreeBSD__) 3066 int locked; 3067 #endif 3068 usbd_status err; 3069 3070 #if defined(__FreeBSD__) 3071 if (sc->sc_dying) 3072 return EIO; 3073 #endif 3074 3075 as = &sc->sc_alts[ch->altidx]; 3076 endpt = as->edesc->bEndpointAddress; 3077 DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n", 3078 endpt, ch->sample_rate, as->alt)); 3079 3080 #if defined(__FreeBSD__) 3081 locked = (ch->pcm_ch != NULL && mtx_owned(ch->pcm_ch->lock)) ? 1 : 0; 3082 if (locked) 3083 CHN_UNLOCK(ch->pcm_ch); 3084 #endif 3085 /* Set alternate interface corresponding to the mode. */ 3086 err = usbd_set_interface(as->ifaceh, as->alt); 3087 #if defined(__FreeBSD__) 3088 if (locked) 3089 CHN_LOCK(ch->pcm_ch); 3090 #endif 3091 if (err) 3092 return err; 3093 3094 /* 3095 * If just one sampling rate is supported, 3096 * no need to call uaudio_set_speed(). 3097 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request. 3098 */ 3099 if (as->asf1desc->bSamFreqType != 1) { 3100 err = uaudio_set_speed(sc, endpt, ch->sample_rate); 3101 if (err) { 3102 DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n", 3103 usbd_errstr(err))); 3104 } 3105 } 3106 3107 ch->pipe = 0; 3108 ch->sync_pipe = 0; 3109 DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt)); 3110 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe); 3111 if (err) 3112 return err; 3113 if (as->edesc1 != NULL) { 3114 endpt = as->edesc1->bEndpointAddress; 3115 DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt)); 3116 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe); 3117 } 3118 return err; 3119 } 3120 3121 static void 3122 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch) 3123 { 3124 struct as_info *as; 3125 #if defined(__FreeBSD__) 3126 int locked; 3127 3128 if (sc->sc_dying) 3129 return ; 3130 #endif 3131 3132 as = &sc->sc_alts[ch->altidx]; 3133 as->sc_busy = 0; 3134 #if defined(__FreeBSD__) 3135 locked = (ch->pcm_ch != NULL && mtx_owned(ch->pcm_ch->lock)) ? 1 : 0; 3136 if (locked) 3137 CHN_UNLOCK(ch->pcm_ch); 3138 #endif 3139 if (sc->sc_nullalt >= 0) { 3140 DPRINTF(("uaudio_chan_close: set null alt=%d\n", 3141 sc->sc_nullalt)); 3142 /* 3143 * The interface will be initialized later again, so an 3144 * error does not hurt. 3145 */ 3146 (void)usbd_set_interface(as->ifaceh, sc->sc_nullalt); 3147 } 3148 if (ch->pipe) { 3149 usbd_abort_pipe(ch->pipe); 3150 usbd_close_pipe(ch->pipe); 3151 } 3152 if (ch->sync_pipe) { 3153 usbd_abort_pipe(ch->sync_pipe); 3154 usbd_close_pipe(ch->sync_pipe); 3155 } 3156 #if defined(__FreeBSD__) 3157 if (locked) 3158 CHN_LOCK(ch->pcm_ch); 3159 #endif 3160 } 3161 3162 static usbd_status 3163 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch) 3164 { 3165 usbd_xfer_handle xfer; 3166 void *buf; 3167 int i, size; 3168 3169 size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES; 3170 for (i = 0; i < UAUDIO_NCHANBUFS; i++) { 3171 xfer = usbd_alloc_xfer(sc->sc_udev); 3172 if (xfer == 0) 3173 goto bad; 3174 ch->chanbufs[i].xfer = xfer; 3175 buf = usbd_alloc_buffer(xfer, size); 3176 if (buf == 0) { 3177 i++; 3178 goto bad; 3179 } 3180 ch->chanbufs[i].buffer = buf; 3181 ch->chanbufs[i].chan = ch; 3182 } 3183 3184 return USBD_NORMAL_COMPLETION; 3185 3186 bad: 3187 while (--i >= 0) 3188 /* implicit buffer free */ 3189 usbd_free_xfer(ch->chanbufs[i].xfer); 3190 return USBD_NOMEM; 3191 } 3192 3193 static void 3194 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch) 3195 { 3196 int i; 3197 3198 for (i = 0; i < UAUDIO_NCHANBUFS; i++) 3199 usbd_free_xfer(ch->chanbufs[i].xfer); 3200 } 3201 3202 /* Called at splusb() */ 3203 static void 3204 uaudio_chan_ptransfer(struct chan *ch) 3205 { 3206 struct chanbuf *cb; 3207 int i, n, size, residue, total; 3208 3209 if (ch->sc->sc_dying) 3210 return; 3211 3212 /* Pick the next channel buffer. */ 3213 cb = &ch->chanbufs[ch->curchanbuf]; 3214 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 3215 ch->curchanbuf = 0; 3216 3217 /* Compute the size of each frame in the next transfer. */ 3218 residue = ch->residue; 3219 total = 0; 3220 for (i = 0; i < UAUDIO_NFRAMES; i++) { 3221 size = ch->bytes_per_frame; 3222 residue += ch->fraction; 3223 if (residue >= USB_FRAMES_PER_SECOND) { 3224 if ((ch->sc->sc_altflags & UA_NOFRAC) == 0) 3225 size += ch->sample_size; 3226 residue -= USB_FRAMES_PER_SECOND; 3227 } 3228 cb->sizes[i] = size; 3229 total += size; 3230 } 3231 ch->residue = residue; 3232 cb->size = total; 3233 3234 /* 3235 * Transfer data from upper layer buffer to channel buffer, taking 3236 * care of wrapping the upper layer buffer. 3237 */ 3238 n = min(total, ch->end - ch->cur); 3239 memcpy(cb->buffer, ch->cur, n); 3240 ch->cur += n; 3241 if (ch->cur >= ch->end) 3242 ch->cur = ch->start; 3243 if (total > n) { 3244 total -= n; 3245 memcpy(cb->buffer + n, ch->cur, total); 3246 ch->cur += total; 3247 } 3248 3249 #ifdef USB_DEBUG 3250 if (uaudiodebug > 8) { 3251 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n", 3252 cb->buffer, ch->residue)); 3253 for (i = 0; i < UAUDIO_NFRAMES; i++) { 3254 DPRINTF((" [%d] length %d\n", i, cb->sizes[i])); 3255 } 3256 } 3257 #endif 3258 3259 DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer)); 3260 /* Fill the request */ 3261 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, 3262 UAUDIO_NFRAMES, USBD_NO_COPY, 3263 uaudio_chan_pintr); 3264 3265 (void)usbd_transfer(cb->xfer); 3266 } 3267 3268 static void 3269 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv, 3270 usbd_status status) 3271 { 3272 struct chanbuf *cb; 3273 struct chan *ch; 3274 u_int32_t count; 3275 int s; 3276 3277 cb = priv; 3278 ch = cb->chan; 3279 /* Return if we are aborting. */ 3280 if (status == USBD_CANCELLED) 3281 return; 3282 3283 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 3284 DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n", 3285 count, ch->transferred)); 3286 #ifdef DIAGNOSTIC 3287 if (count != cb->size) { 3288 printf("uaudio_chan_pintr: count(%d) != size(%d)\n", 3289 count, cb->size); 3290 } 3291 #endif 3292 3293 ch->transferred += cb->size; 3294 #if defined(__FreeBSD__) 3295 /* s = spltty(); */ 3296 s = splhigh(); 3297 chn_intr(ch->pcm_ch); 3298 splx(s); 3299 #else 3300 s = splaudio(); 3301 /* Call back to upper layer */ 3302 while (ch->transferred >= ch->blksize) { 3303 ch->transferred -= ch->blksize; 3304 DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n", 3305 ch->intr, ch->arg)); 3306 ch->intr(ch->arg); 3307 } 3308 splx(s); 3309 #endif 3310 3311 /* start next transfer */ 3312 uaudio_chan_ptransfer(ch); 3313 } 3314 3315 /* Called at splusb() */ 3316 static void 3317 uaudio_chan_rtransfer(struct chan *ch) 3318 { 3319 struct chanbuf *cb; 3320 int i, size, residue, total; 3321 3322 if (ch->sc->sc_dying) 3323 return; 3324 3325 /* Pick the next channel buffer. */ 3326 cb = &ch->chanbufs[ch->curchanbuf]; 3327 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 3328 ch->curchanbuf = 0; 3329 3330 /* Compute the size of each frame in the next transfer. */ 3331 residue = ch->residue; 3332 total = 0; 3333 for (i = 0; i < UAUDIO_NFRAMES; i++) { 3334 size = ch->bytes_per_frame; 3335 cb->sizes[i] = size; 3336 cb->offsets[i] = total; 3337 total += size; 3338 } 3339 ch->residue = residue; 3340 cb->size = total; 3341 3342 #ifdef USB_DEBUG 3343 if (uaudiodebug > 8) { 3344 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n", 3345 cb->buffer, ch->residue)); 3346 for (i = 0; i < UAUDIO_NFRAMES; i++) { 3347 DPRINTF((" [%d] length %d\n", i, cb->sizes[i])); 3348 } 3349 } 3350 #endif 3351 3352 DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer)); 3353 /* Fill the request */ 3354 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, 3355 UAUDIO_NFRAMES, USBD_NO_COPY, 3356 uaudio_chan_rintr); 3357 3358 (void)usbd_transfer(cb->xfer); 3359 } 3360 3361 static void 3362 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv, 3363 usbd_status status) 3364 { 3365 struct chanbuf *cb = priv; 3366 struct chan *ch = cb->chan; 3367 u_int32_t count; 3368 int s, i, n, frsize; 3369 3370 /* Return if we are aborting. */ 3371 if (status == USBD_CANCELLED) 3372 return; 3373 3374 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 3375 DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n", 3376 count, ch->transferred)); 3377 3378 /* count < cb->size is normal for asynchronous source */ 3379 #ifdef DIAGNOSTIC 3380 if (count > cb->size) { 3381 printf("uaudio_chan_rintr: count(%d) > size(%d)\n", 3382 count, cb->size); 3383 } 3384 #endif 3385 3386 /* 3387 * Transfer data from channel buffer to upper layer buffer, taking 3388 * care of wrapping the upper layer buffer. 3389 */ 3390 for(i = 0; i < UAUDIO_NFRAMES; i++) { 3391 frsize = cb->sizes[i]; 3392 n = min(frsize, ch->end - ch->cur); 3393 memcpy(ch->cur, cb->buffer + cb->offsets[i], n); 3394 ch->cur += n; 3395 if (ch->cur >= ch->end) 3396 ch->cur = ch->start; 3397 if (frsize > n) { 3398 memcpy(ch->cur, cb->buffer + cb->offsets[i] + n, 3399 frsize - n); 3400 ch->cur += frsize - n; 3401 } 3402 } 3403 3404 /* Call back to upper layer */ 3405 ch->transferred += count; 3406 #if defined(__FreeBSD__) 3407 s = spltty(); 3408 chn_intr(ch->pcm_ch); 3409 splx(s); 3410 #else 3411 s = splaudio(); 3412 while (ch->transferred >= ch->blksize) { 3413 ch->transferred -= ch->blksize; 3414 DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n", 3415 ch->intr, ch->arg)); 3416 ch->intr(ch->arg); 3417 } 3418 splx(s); 3419 #endif 3420 3421 /* start next transfer */ 3422 uaudio_chan_rtransfer(ch); 3423 } 3424 3425 #if defined(__NetBSD__) || defined(__OpenBSD__) 3426 static void 3427 uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param, 3428 int maxpktsize) 3429 { 3430 int samples_per_frame, sample_size; 3431 3432 ch->altidx = altidx; 3433 sample_size = param->precision * param->factor * param->hw_channels / 8; 3434 samples_per_frame = param->hw_sample_rate / USB_FRAMES_PER_SECOND; 3435 ch->sample_size = sample_size; 3436 ch->sample_rate = param->hw_sample_rate; 3437 if (maxpktsize == 0) { 3438 ch->fraction = param->hw_sample_rate % USB_FRAMES_PER_SECOND; 3439 ch->bytes_per_frame = samples_per_frame * sample_size; 3440 } else { 3441 ch->fraction = 0; 3442 ch->bytes_per_frame = maxpktsize; 3443 } 3444 ch->residue = 0; 3445 } 3446 3447 static void 3448 uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize) 3449 { 3450 ch->start = start; 3451 ch->end = end; 3452 ch->cur = start; 3453 ch->blksize = blksize; 3454 ch->transferred = 0; 3455 ch->curchanbuf = 0; 3456 } 3457 3458 static void 3459 uaudio_get_minmax_rates(int nalts, const struct as_info *alts, 3460 const struct audio_params *p, int mode, 3461 u_long *min, u_long *max) 3462 { 3463 const struct usb_audio_streaming_type1_descriptor *a1d; 3464 int i, j; 3465 3466 *min = ULONG_MAX; 3467 *max = 0; 3468 for (i = 0; i < nalts; i++) { 3469 a1d = alts[i].asf1desc; 3470 if (alts[i].sc_busy) 3471 continue; 3472 if (p->hw_channels != a1d->bNrChannels) 3473 continue; 3474 if (p->hw_precision != a1d->bBitResolution) 3475 continue; 3476 if (p->hw_encoding != alts[i].encoding) 3477 continue; 3478 if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress)) 3479 continue; 3480 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 3481 DPRINTFN(2,("uaudio_get_minmax_rates: cont %d-%d\n", 3482 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d))); 3483 if (UA_SAMP_LO(a1d) < *min) 3484 *min = UA_SAMP_LO(a1d); 3485 if (UA_SAMP_HI(a1d) > *max) 3486 *max = UA_SAMP_HI(a1d); 3487 } else { 3488 for (j = 0; j < a1d->bSamFreqType; j++) { 3489 DPRINTFN(2,("uaudio_get_minmax_rates: disc #%d: %d\n", 3490 j, UA_GETSAMP(a1d, j))); 3491 if (UA_GETSAMP(a1d, j) < *min) 3492 *min = UA_GETSAMP(a1d, j); 3493 if (UA_GETSAMP(a1d, j) > *max) 3494 *max = UA_GETSAMP(a1d, j); 3495 } 3496 } 3497 } 3498 } 3499 3500 static int 3501 uaudio_match_alt_sub(int nalts, const struct as_info *alts, 3502 const struct audio_params *p, int mode, u_long rate) 3503 { 3504 const struct usb_audio_streaming_type1_descriptor *a1d; 3505 int i, j; 3506 3507 DPRINTF(("uaudio_match_alt_sub: search for %luHz %dch\n", 3508 rate, p->hw_channels)); 3509 for (i = 0; i < nalts; i++) { 3510 a1d = alts[i].asf1desc; 3511 if (alts[i].sc_busy) 3512 continue; 3513 if (p->hw_channels != a1d->bNrChannels) 3514 continue; 3515 if (p->hw_precision != a1d->bBitResolution) 3516 continue; 3517 if (p->hw_encoding != alts[i].encoding) 3518 continue; 3519 if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress)) 3520 continue; 3521 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 3522 DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n", 3523 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d))); 3524 if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d)) 3525 return i; 3526 } else { 3527 for (j = 0; j < a1d->bSamFreqType; j++) { 3528 DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n", 3529 j, UA_GETSAMP(a1d, j))); 3530 /* XXX allow for some slack */ 3531 if (UA_GETSAMP(a1d, j) == rate) 3532 return i; 3533 } 3534 } 3535 } 3536 return -1; 3537 } 3538 3539 static int 3540 uaudio_match_alt_chan(int nalts, const struct as_info *alts, 3541 struct audio_params *p, int mode) 3542 { 3543 int i, n; 3544 u_long min, max; 3545 u_long rate; 3546 3547 /* Exact match */ 3548 DPRINTF(("uaudio_match_alt_chan: examine %ldHz %dch %dbit.\n", 3549 p->sample_rate, p->hw_channels, p->hw_precision)); 3550 i = uaudio_match_alt_sub(nalts, alts, p, mode, p->sample_rate); 3551 if (i >= 0) 3552 return i; 3553 3554 uaudio_get_minmax_rates(nalts, alts, p, mode, &min, &max); 3555 DPRINTF(("uaudio_match_alt_chan: min=%lu max=%lu\n", min, max)); 3556 if (max <= 0) 3557 return -1; 3558 /* Search for biggers */ 3559 n = 2; 3560 while ((rate = p->sample_rate * n++) <= max) { 3561 i = uaudio_match_alt_sub(nalts, alts, p, mode, rate); 3562 if (i >= 0) { 3563 p->hw_sample_rate = rate; 3564 return i; 3565 } 3566 } 3567 if (p->sample_rate >= min) { 3568 i = uaudio_match_alt_sub(nalts, alts, p, mode, max); 3569 if (i >= 0) { 3570 p->hw_sample_rate = max; 3571 return i; 3572 } 3573 } else { 3574 i = uaudio_match_alt_sub(nalts, alts, p, mode, min); 3575 if (i >= 0) { 3576 p->hw_sample_rate = min; 3577 return i; 3578 } 3579 } 3580 return -1; 3581 } 3582 3583 static int 3584 uaudio_match_alt(int nalts, const struct as_info *alts, 3585 struct audio_params *p, int mode) 3586 { 3587 int i, n; 3588 3589 mode = mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN; 3590 i = uaudio_match_alt_chan(nalts, alts, p, mode); 3591 if (i >= 0) 3592 return i; 3593 3594 for (n = p->channels + 1; n <= AUDIO_MAX_CHANNELS; n++) { 3595 p->hw_channels = n; 3596 i = uaudio_match_alt_chan(nalts, alts, p, mode); 3597 if (i >= 0) 3598 return i; 3599 } 3600 3601 if (p->channels != 2) 3602 return -1; 3603 p->hw_channels = 1; 3604 return uaudio_match_alt_chan(nalts, alts, p, mode); 3605 } 3606 3607 static int 3608 uaudio_set_params(void *addr, int setmode, int usemode, 3609 struct audio_params *play, struct audio_params *rec) 3610 { 3611 struct uaudio_softc *sc; 3612 int flags; 3613 int factor; 3614 int enc, i; 3615 int paltidx, raltidx; 3616 void (*swcode)(void *, u_char *buf, int cnt); 3617 struct audio_params *p; 3618 int mode; 3619 3620 sc = addr; 3621 flags = sc->sc_altflags; 3622 paltidx = -1; 3623 raltidx = -1; 3624 if (sc->sc_dying) 3625 return EIO; 3626 3627 if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) || 3628 ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL)) 3629 return EBUSY; 3630 3631 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) 3632 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0; 3633 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) 3634 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0; 3635 3636 /* Some uaudio devices are unidirectional. Don't try to find a 3637 matching mode for the unsupported direction. */ 3638 setmode &= sc->sc_mode; 3639 3640 for (mode = AUMODE_RECORD; mode != -1; 3641 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 3642 if ((setmode & mode) == 0) 3643 continue; 3644 3645 p = (mode == AUMODE_PLAY) ? play : rec; 3646 3647 factor = 1; 3648 swcode = 0; 3649 enc = p->encoding; 3650 switch (enc) { 3651 case AUDIO_ENCODING_SLINEAR_BE: 3652 /* FALLTHROUGH */ 3653 case AUDIO_ENCODING_SLINEAR_LE: 3654 if (enc == AUDIO_ENCODING_SLINEAR_BE 3655 && p->precision == 16 && (flags & HAS_16)) { 3656 swcode = swap_bytes; 3657 enc = AUDIO_ENCODING_SLINEAR_LE; 3658 } else if (p->precision == 8) { 3659 if (flags & HAS_8) { 3660 /* No conversion */ 3661 } else if (flags & HAS_8U) { 3662 swcode = change_sign8; 3663 enc = AUDIO_ENCODING_ULINEAR_LE; 3664 } else if (flags & HAS_16) { 3665 factor = 2; 3666 p->hw_precision = 16; 3667 if (mode == AUMODE_PLAY) 3668 swcode = linear8_to_linear16_le; 3669 else 3670 swcode = linear16_to_linear8_le; 3671 } 3672 } 3673 break; 3674 case AUDIO_ENCODING_ULINEAR_BE: 3675 /* FALLTHROUGH */ 3676 case AUDIO_ENCODING_ULINEAR_LE: 3677 if (p->precision == 16) { 3678 if (enc == AUDIO_ENCODING_ULINEAR_LE) 3679 swcode = change_sign16_le; 3680 else if (mode == AUMODE_PLAY) 3681 swcode = swap_bytes_change_sign16_le; 3682 else 3683 swcode = change_sign16_swap_bytes_le; 3684 enc = AUDIO_ENCODING_SLINEAR_LE; 3685 } else if (p->precision == 8) { 3686 if (flags & HAS_8U) { 3687 /* No conversion */ 3688 } else if (flags & HAS_8) { 3689 swcode = change_sign8; 3690 enc = AUDIO_ENCODING_SLINEAR_LE; 3691 } else if (flags & HAS_16) { 3692 factor = 2; 3693 p->hw_precision = 16; 3694 enc = AUDIO_ENCODING_SLINEAR_LE; 3695 if (mode == AUMODE_PLAY) 3696 swcode = ulinear8_to_slinear16_le; 3697 else 3698 swcode = slinear16_to_ulinear8_le; 3699 } 3700 } 3701 break; 3702 case AUDIO_ENCODING_ULAW: 3703 if (flags & HAS_MULAW) 3704 break; 3705 if (flags & HAS_16) { 3706 if (mode == AUMODE_PLAY) 3707 swcode = mulaw_to_slinear16_le; 3708 else 3709 swcode = slinear16_to_mulaw_le; 3710 factor = 2; 3711 enc = AUDIO_ENCODING_SLINEAR_LE; 3712 p->hw_precision = 16; 3713 } else if (flags & HAS_8U) { 3714 if (mode == AUMODE_PLAY) 3715 swcode = mulaw_to_ulinear8; 3716 else 3717 swcode = ulinear8_to_mulaw; 3718 enc = AUDIO_ENCODING_ULINEAR_LE; 3719 } else if (flags & HAS_8) { 3720 if (mode == AUMODE_PLAY) 3721 swcode = mulaw_to_slinear8; 3722 else 3723 swcode = slinear8_to_mulaw; 3724 enc = AUDIO_ENCODING_SLINEAR_LE; 3725 } else 3726 return (EINVAL); 3727 break; 3728 case AUDIO_ENCODING_ALAW: 3729 if (flags & HAS_ALAW) 3730 break; 3731 if (mode == AUMODE_PLAY && (flags & HAS_16)) { 3732 swcode = alaw_to_slinear16_le; 3733 factor = 2; 3734 enc = AUDIO_ENCODING_SLINEAR_LE; 3735 p->hw_precision = 16; 3736 } else if (flags & HAS_8U) { 3737 if (mode == AUMODE_PLAY) 3738 swcode = alaw_to_ulinear8; 3739 else 3740 swcode = ulinear8_to_alaw; 3741 enc = AUDIO_ENCODING_ULINEAR_LE; 3742 } else if (flags & HAS_8) { 3743 if (mode == AUMODE_PLAY) 3744 swcode = alaw_to_slinear8; 3745 else 3746 swcode = slinear8_to_alaw; 3747 enc = AUDIO_ENCODING_SLINEAR_LE; 3748 } else 3749 return (EINVAL); 3750 break; 3751 default: 3752 return (EINVAL); 3753 } 3754 /* XXX do some other conversions... */ 3755 3756 DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n", 3757 p->channels, p->hw_precision, enc, p->sample_rate)); 3758 3759 p->hw_encoding = enc; 3760 i = uaudio_match_alt(sc->sc_nalts, sc->sc_alts, p, mode); 3761 if (i < 0) 3762 return (EINVAL); 3763 3764 p->sw_code = swcode; 3765 p->factor = factor; 3766 3767 if (mode == AUMODE_PLAY) 3768 paltidx = i; 3769 else 3770 raltidx = i; 3771 } 3772 3773 if ((setmode & AUMODE_PLAY)) { 3774 /* XXX abort transfer if currently happening? */ 3775 uaudio_chan_init(&sc->sc_playchan, paltidx, play, 0); 3776 } 3777 if ((setmode & AUMODE_RECORD)) { 3778 /* XXX abort transfer if currently happening? */ 3779 uaudio_chan_init(&sc->sc_recchan, raltidx, rec, 3780 UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize)); 3781 } 3782 3783 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) 3784 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1; 3785 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) 3786 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1; 3787 3788 DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n", 3789 sc->sc_playchan.altidx, sc->sc_recchan.altidx, 3790 (sc->sc_playchan.altidx >= 0) 3791 ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting 3792 : -1, 3793 (sc->sc_recchan.altidx >= 0) 3794 ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting 3795 : -1)); 3796 3797 return 0; 3798 } 3799 #endif /* NetBSD or OpenBSD */ 3800 3801 static usbd_status 3802 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed) 3803 { 3804 usb_device_request_t req; 3805 uint8_t data[3]; 3806 3807 DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed)); 3808 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT; 3809 req.bRequest = SET_CUR; 3810 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0); 3811 USETW(req.wIndex, endpt); 3812 USETW(req.wLength, 3); 3813 data[0] = speed; 3814 data[1] = speed >> 8; 3815 data[2] = speed >> 16; 3816 3817 #if defined(__FreeBSD__) 3818 if (sc->async != 0) 3819 return usbd_do_request_async(sc->sc_udev, &req, data); 3820 #endif 3821 return usbd_do_request(sc->sc_udev, &req, data); 3822 } 3823 3824 3825 #if defined(__FreeBSD__) 3826 /************************************************************/ 3827 int 3828 uaudio_init_params(struct uaudio_softc *sc, struct chan *ch, int mode) 3829 { 3830 int i, j, enc; 3831 int samples_per_frame, sample_size; 3832 3833 if ((sc->sc_playchan.pipe != NULL) || (sc->sc_recchan.pipe != NULL)) 3834 return (-1); 3835 3836 switch(ch->format & 0x000FFFFF) { 3837 case AFMT_U8: 3838 enc = AUDIO_ENCODING_ULINEAR_LE; 3839 ch->precision = 8; 3840 break; 3841 case AFMT_S8: 3842 enc = AUDIO_ENCODING_SLINEAR_LE; 3843 ch->precision = 8; 3844 break; 3845 case AFMT_A_LAW: /* ? */ 3846 enc = AUDIO_ENCODING_ALAW; 3847 ch->precision = 8; 3848 break; 3849 case AFMT_MU_LAW: /* ? */ 3850 enc = AUDIO_ENCODING_ULAW; 3851 ch->precision = 8; 3852 break; 3853 case AFMT_S16_LE: 3854 enc = AUDIO_ENCODING_SLINEAR_LE; 3855 ch->precision = 16; 3856 break; 3857 case AFMT_S16_BE: 3858 enc = AUDIO_ENCODING_SLINEAR_BE; 3859 ch->precision = 16; 3860 break; 3861 case AFMT_U16_LE: 3862 enc = AUDIO_ENCODING_ULINEAR_LE; 3863 ch->precision = 16; 3864 break; 3865 case AFMT_U16_BE: 3866 enc = AUDIO_ENCODING_ULINEAR_BE; 3867 ch->precision = 16; 3868 break; 3869 case AFMT_S24_LE: 3870 enc = AUDIO_ENCODING_SLINEAR_LE; 3871 ch->precision = 24; 3872 break; 3873 case AFMT_S24_BE: 3874 enc = AUDIO_ENCODING_SLINEAR_BE; 3875 ch->precision = 24; 3876 break; 3877 case AFMT_U24_LE: 3878 enc = AUDIO_ENCODING_ULINEAR_LE; 3879 ch->precision = 24; 3880 break; 3881 case AFMT_U24_BE: 3882 enc = AUDIO_ENCODING_ULINEAR_BE; 3883 ch->precision = 24; 3884 break; 3885 case AFMT_S32_LE: 3886 enc = AUDIO_ENCODING_SLINEAR_LE; 3887 ch->precision = 32; 3888 break; 3889 case AFMT_S32_BE: 3890 enc = AUDIO_ENCODING_SLINEAR_BE; 3891 ch->precision = 32; 3892 break; 3893 case AFMT_U32_LE: 3894 enc = AUDIO_ENCODING_ULINEAR_LE; 3895 ch->precision = 32; 3896 break; 3897 case AFMT_U32_BE: 3898 enc = AUDIO_ENCODING_ULINEAR_BE; 3899 ch->precision = 32; 3900 break; 3901 default: 3902 enc = 0; 3903 ch->precision = 16; 3904 printf("Unknown format %x\n", ch->format); 3905 } 3906 3907 if (ch->format & AFMT_STEREO) { 3908 ch->channels = 2; 3909 } else { 3910 ch->channels = 1; 3911 } 3912 3913 /* for (mode = ...... */ 3914 for (i = 0; i < sc->sc_nalts; i++) { 3915 const struct usb_audio_streaming_type1_descriptor *a1d = 3916 sc->sc_alts[i].asf1desc; 3917 if (ch->channels == a1d->bNrChannels && 3918 ch->precision == a1d->bBitResolution && 3919 #if 0 3920 enc == sc->sc_alts[i].encoding) { 3921 #else 3922 enc == sc->sc_alts[i].encoding && 3923 (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) == 3924 UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) { 3925 #endif 3926 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 3927 DPRINTFN(2,("uaudio_set_params: cont %d-%d\n", 3928 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d))); 3929 if (UA_SAMP_LO(a1d) <= ch->sample_rate && 3930 ch->sample_rate <= UA_SAMP_HI(a1d)) { 3931 if (mode == AUMODE_PLAY) 3932 sc->sc_playchan.altidx = i; 3933 else 3934 sc->sc_recchan.altidx = i; 3935 goto found; 3936 } 3937 } else { 3938 for (j = 0; j < a1d->bSamFreqType; j++) { 3939 DPRINTFN(2,("uaudio_set_params: disc #" 3940 "%d: %d\n", j, UA_GETSAMP(a1d, j))); 3941 /* XXX allow for some slack */ 3942 if (UA_GETSAMP(a1d, j) == 3943 ch->sample_rate) { 3944 if (mode == AUMODE_PLAY) 3945 sc->sc_playchan.altidx = i; 3946 else 3947 sc->sc_recchan.altidx = i; 3948 goto found; 3949 } 3950 } 3951 } 3952 } 3953 } 3954 /* return (EINVAL); */ 3955 if (mode == AUMODE_PLAY) 3956 printf("uaudio: This device can't play in rate=%d.\n", ch->sample_rate); 3957 else 3958 printf("uaudio: This device can't record in rate=%d.\n", ch->sample_rate); 3959 return (-1); 3960 3961 found: 3962 #if 0 /* XXX */ 3963 p->sw_code = swcode; 3964 p->factor = factor; 3965 if (usemode == mode) 3966 sc->sc_curaltidx = i; 3967 #endif 3968 /* } */ 3969 3970 sample_size = ch->precision * ch->channels / 8; 3971 samples_per_frame = ch->sample_rate / USB_FRAMES_PER_SECOND; 3972 ch->fraction = ch->sample_rate % USB_FRAMES_PER_SECOND; 3973 ch->sample_size = sample_size; 3974 ch->bytes_per_frame = samples_per_frame * sample_size; 3975 ch->residue = 0; 3976 3977 ch->cur = ch->start; 3978 ch->transferred = 0; 3979 ch->curchanbuf = 0; 3980 return (0); 3981 } 3982 3983 struct uaudio_conversion { 3984 uint8_t uaudio_fmt; 3985 uint8_t uaudio_prec; 3986 uint32_t freebsd_fmt; 3987 }; 3988 3989 const struct uaudio_conversion const accepted_conversion[] = { 3990 {AUDIO_ENCODING_ULINEAR_LE, 8, AFMT_U8}, 3991 {AUDIO_ENCODING_ULINEAR_LE, 16, AFMT_U16_LE}, 3992 {AUDIO_ENCODING_ULINEAR_LE, 24, AFMT_U24_LE}, 3993 {AUDIO_ENCODING_ULINEAR_LE, 32, AFMT_U32_LE}, 3994 {AUDIO_ENCODING_ULINEAR_BE, 16, AFMT_U16_BE}, 3995 {AUDIO_ENCODING_ULINEAR_BE, 24, AFMT_U24_BE}, 3996 {AUDIO_ENCODING_ULINEAR_BE, 32, AFMT_U32_BE}, 3997 {AUDIO_ENCODING_SLINEAR_LE, 8, AFMT_S8}, 3998 {AUDIO_ENCODING_SLINEAR_LE, 16, AFMT_S16_LE}, 3999 {AUDIO_ENCODING_SLINEAR_LE, 24, AFMT_S24_LE}, 4000 {AUDIO_ENCODING_SLINEAR_LE, 32, AFMT_S32_LE}, 4001 {AUDIO_ENCODING_SLINEAR_BE, 16, AFMT_S16_BE}, 4002 {AUDIO_ENCODING_SLINEAR_BE, 24, AFMT_S24_BE}, 4003 {AUDIO_ENCODING_SLINEAR_BE, 32, AFMT_S32_BE}, 4004 {AUDIO_ENCODING_ALAW, 8, AFMT_A_LAW}, 4005 {AUDIO_ENCODING_ULAW, 8, AFMT_MU_LAW}, 4006 {0,0,0} 4007 }; 4008 4009 unsigned 4010 uaudio_query_formats(device_t dev, int reqdir, unsigned maxfmt, struct pcmchan_caps *cap) 4011 { 4012 struct uaudio_softc *sc; 4013 const struct usb_audio_streaming_type1_descriptor *asf1d; 4014 const struct uaudio_conversion *iterator; 4015 unsigned fmtcount, foundcount; 4016 u_int32_t fmt; 4017 uint8_t format, numchan, subframesize, prec, dir, iscontinuous; 4018 int freq, freq_min, freq_max; 4019 char *numchannel_descr; 4020 char freq_descr[64]; 4021 int i,r; 4022 4023 sc = device_get_softc(dev); 4024 if (sc == NULL) 4025 return 0; 4026 4027 cap->minspeed = cap->maxspeed = 0; 4028 foundcount = fmtcount = 0; 4029 4030 for (i = 0; i < sc->sc_nalts; i++) { 4031 dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress); 4032 4033 if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY)) 4034 continue; 4035 4036 asf1d = sc->sc_alts[i].asf1desc; 4037 format = sc->sc_alts[i].encoding; 4038 4039 numchan = asf1d->bNrChannels; 4040 subframesize = asf1d->bSubFrameSize; 4041 prec = asf1d->bBitResolution; /* precision */ 4042 iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS; 4043 4044 if (iscontinuous) 4045 snprintf(freq_descr, sizeof(freq_descr), "continous min %d max %d", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d)); 4046 else 4047 snprintf(freq_descr, sizeof(freq_descr), "fixed frequency (%d listed formats)", asf1d->bSamFreqType); 4048 4049 if (numchan == 1) 4050 numchannel_descr = " (mono)"; 4051 else if (numchan == 2) 4052 numchannel_descr = " (stereo)"; 4053 else 4054 numchannel_descr = ""; 4055 4056 if (bootverbose) { 4057 device_printf(dev, "uaudio_query_formats: found a native %s channel%s %s %dbit %dbytes/subframe X %d channels = %d bytes per sample\n", 4058 (dir==UE_DIR_OUT)?"playback":"record", 4059 numchannel_descr, freq_descr, 4060 prec, subframesize, numchan, subframesize*numchan); 4061 } 4062 /* 4063 * Now start rejecting the ones that don't map to FreeBSD 4064 */ 4065 4066 if (numchan != 1 && numchan != 2) 4067 continue; 4068 4069 for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++) 4070 if (iterator->uaudio_fmt == format && iterator->uaudio_prec == prec) 4071 break; 4072 4073 if (iterator->uaudio_fmt == 0) 4074 continue; 4075 4076 fmt = iterator->freebsd_fmt; 4077 4078 if (numchan == 2) 4079 fmt |= AFMT_STEREO; 4080 4081 foundcount++; 4082 4083 if (fmtcount >= maxfmt) 4084 continue; 4085 4086 cap->fmtlist[fmtcount++] = fmt; 4087 4088 if (iscontinuous) { 4089 freq_min = UA_SAMP_LO(asf1d); 4090 freq_max = UA_SAMP_HI(asf1d); 4091 4092 if (cap->minspeed == 0 || freq_min < cap->minspeed) 4093 cap->minspeed = freq_min; 4094 if (cap->maxspeed == 0) 4095 cap->maxspeed = cap->minspeed; 4096 if (freq_max > cap->maxspeed) 4097 cap->maxspeed = freq_max; 4098 } else { 4099 for (r = 0; r < asf1d->bSamFreqType; r++) { 4100 freq = UA_GETSAMP(asf1d, r); 4101 if (cap->minspeed == 0 || freq < cap->minspeed) 4102 cap->minspeed = freq; 4103 if (cap->maxspeed == 0) 4104 cap->maxspeed = cap->minspeed; 4105 if (freq > cap->maxspeed) 4106 cap->maxspeed = freq; 4107 } 4108 } 4109 } 4110 cap->fmtlist[fmtcount] = 0; 4111 return foundcount; 4112 } 4113 4114 void 4115 uaudio_chan_set_param_pcm_dma_buff(device_t dev, u_char *start, u_char *end, 4116 struct pcm_channel *pc, int dir) 4117 { 4118 struct uaudio_softc *sc; 4119 struct chan *ch; 4120 4121 sc = device_get_softc(dev); 4122 #ifndef NO_RECORDING 4123 if (dir == PCMDIR_PLAY) 4124 ch = &sc->sc_playchan; 4125 else 4126 ch = &sc->sc_recchan; 4127 #else 4128 ch = &sc->sc_playchan; 4129 #endif 4130 4131 ch->start = start; 4132 ch->end = end; 4133 4134 ch->pcm_ch = pc; 4135 4136 return; 4137 } 4138 4139 void 4140 uaudio_chan_set_param_blocksize(device_t dev, u_int32_t blocksize, int dir) 4141 { 4142 struct uaudio_softc *sc; 4143 struct chan *ch; 4144 4145 sc = device_get_softc(dev); 4146 #ifndef NO_RECORDING 4147 if (dir == PCMDIR_PLAY) 4148 ch = &sc->sc_playchan; 4149 else 4150 ch = &sc->sc_recchan; 4151 #else 4152 ch = &sc->sc_playchan; 4153 #endif 4154 4155 ch->blksize = blocksize; 4156 4157 return; 4158 } 4159 4160 int 4161 uaudio_chan_set_param_speed(device_t dev, u_int32_t speed, int reqdir) 4162 { 4163 const struct uaudio_conversion *iterator; 4164 struct uaudio_softc *sc; 4165 struct chan *ch; 4166 int i, r, score, hiscore, bestspeed; 4167 4168 sc = device_get_softc(dev); 4169 #ifndef NO_RECORDING 4170 if (reqdir == PCMDIR_PLAY) 4171 ch = &sc->sc_playchan; 4172 else 4173 ch = &sc->sc_recchan; 4174 #else 4175 ch = &sc->sc_playchan; 4176 #endif 4177 /* 4178 * We are successful if we find an endpoint that matches our selected format and it 4179 * supports the requested speed. 4180 */ 4181 hiscore = 0; 4182 bestspeed = 1; 4183 for (i = 0; i < sc->sc_nalts; i++) { 4184 int dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress); 4185 int format = sc->sc_alts[i].encoding; 4186 const struct usb_audio_streaming_type1_descriptor *asf1d = sc->sc_alts[i].asf1desc; 4187 int iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS; 4188 4189 if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY)) 4190 continue; 4191 4192 for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++) 4193 if (iterator->uaudio_fmt != format || iterator->freebsd_fmt != (ch->format&0xfffffff)) 4194 continue; 4195 if (iscontinuous) { 4196 if (speed >= UA_SAMP_LO(asf1d) && speed <= UA_SAMP_HI(asf1d)) { 4197 ch->sample_rate = speed; 4198 return speed; 4199 } else if (speed < UA_SAMP_LO(asf1d)) { 4200 score = 0xfff * speed / UA_SAMP_LO(asf1d); 4201 if (score > hiscore) { 4202 bestspeed = UA_SAMP_LO(asf1d); 4203 hiscore = score; 4204 } 4205 } else if (speed > UA_SAMP_HI(asf1d)) { 4206 score = 0xfff * UA_SAMP_HI(asf1d) / speed; 4207 if (score > hiscore) { 4208 bestspeed = UA_SAMP_HI(asf1d); 4209 hiscore = score; 4210 } 4211 } 4212 continue; 4213 } 4214 for (r = 0; r < asf1d->bSamFreqType; r++) { 4215 if (speed == UA_GETSAMP(asf1d, r)) { 4216 ch->sample_rate = speed; 4217 return speed; 4218 } 4219 if (speed > UA_GETSAMP(asf1d, r)) 4220 score = 0xfff * UA_GETSAMP(asf1d, r) / speed; 4221 else 4222 score = 0xfff * speed / UA_GETSAMP(asf1d, r); 4223 if (score > hiscore) { 4224 bestspeed = UA_GETSAMP(asf1d, r); 4225 hiscore = score; 4226 } 4227 } 4228 } 4229 if (bestspeed != 1) { 4230 ch->sample_rate = bestspeed; 4231 return bestspeed; 4232 } 4233 4234 return 0; 4235 } 4236 4237 int 4238 uaudio_chan_getptr(device_t dev, int dir) 4239 { 4240 struct uaudio_softc *sc; 4241 struct chan *ch; 4242 int ptr; 4243 4244 sc = device_get_softc(dev); 4245 #ifndef NO_RECORDING 4246 if (dir == PCMDIR_PLAY) 4247 ch = &sc->sc_playchan; 4248 else 4249 ch = &sc->sc_recchan; 4250 #else 4251 ch = &sc->sc_playchan; 4252 #endif 4253 4254 ptr = ch->cur - ch->start; 4255 4256 return ptr; 4257 } 4258 4259 void 4260 uaudio_chan_set_param_format(device_t dev, u_int32_t format, int dir) 4261 { 4262 struct uaudio_softc *sc; 4263 struct chan *ch; 4264 4265 sc = device_get_softc(dev); 4266 #ifndef NO_RECORDING 4267 if (dir == PCMDIR_PLAY) 4268 ch = &sc->sc_playchan; 4269 else 4270 ch = &sc->sc_recchan; 4271 #else 4272 ch = &sc->sc_playchan; 4273 #endif 4274 4275 ch->format = format; 4276 4277 return; 4278 } 4279 4280 int 4281 uaudio_halt_out_dma(device_t dev) 4282 { 4283 struct uaudio_softc *sc; 4284 4285 sc = device_get_softc(dev); 4286 4287 DPRINTF(("uaudio_halt_out_dma: enter\n")); 4288 if (sc->sc_playchan.pipe != NULL) { 4289 uaudio_chan_close(sc, &sc->sc_playchan); 4290 sc->sc_playchan.pipe = 0; 4291 uaudio_chan_free_buffers(sc, &sc->sc_playchan); 4292 } 4293 return (0); 4294 } 4295 4296 int 4297 uaudio_halt_in_dma(device_t dev) 4298 { 4299 struct uaudio_softc *sc; 4300 4301 sc = device_get_softc(dev); 4302 4303 if (sc->sc_dying) 4304 return (EIO); 4305 4306 DPRINTF(("uaudio_halt_in_dma: enter\n")); 4307 if (sc->sc_recchan.pipe != NULL) { 4308 uaudio_chan_close(sc, &sc->sc_recchan); 4309 sc->sc_recchan.pipe = NULL; 4310 uaudio_chan_free_buffers(sc, &sc->sc_recchan); 4311 /* sc->sc_recchan.intr = NULL; */ 4312 } 4313 return (0); 4314 } 4315 4316 int 4317 uaudio_trigger_input(device_t dev) 4318 { 4319 struct uaudio_softc *sc; 4320 struct chan *ch; 4321 usbd_status err; 4322 int i, s; 4323 4324 sc = device_get_softc(dev); 4325 ch = &sc->sc_recchan; 4326 4327 if (sc->sc_dying) 4328 return (EIO); 4329 4330 /* uaudio_chan_set_param(ch, start, end, blksize) */ 4331 if (uaudio_init_params(sc, ch, AUMODE_RECORD)) 4332 return (EIO); 4333 4334 err = uaudio_chan_alloc_buffers(sc, ch); 4335 if (err) 4336 return (EIO); 4337 4338 err = uaudio_chan_open(sc, ch); 4339 if (err) { 4340 uaudio_chan_free_buffers(sc, ch); 4341 return (EIO); 4342 } 4343 4344 /* ch->intr = intr; 4345 ch->arg = arg; */ 4346 4347 s = splusb(); 4348 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */ 4349 uaudio_chan_rtransfer(ch); 4350 splx(s); 4351 4352 return (0); 4353 } 4354 4355 int 4356 uaudio_trigger_output(device_t dev) 4357 { 4358 struct uaudio_softc *sc; 4359 struct chan *ch; 4360 usbd_status err; 4361 int i, s; 4362 4363 sc = device_get_softc(dev); 4364 ch = &sc->sc_playchan; 4365 4366 if (sc->sc_dying) 4367 return (EIO); 4368 4369 if (uaudio_init_params(sc, ch, AUMODE_PLAY)) 4370 return (EIO); 4371 4372 err = uaudio_chan_alloc_buffers(sc, ch); 4373 if (err) 4374 return (EIO); 4375 4376 err = uaudio_chan_open(sc, ch); 4377 if (err) { 4378 uaudio_chan_free_buffers(sc, ch); 4379 return (EIO); 4380 } 4381 4382 s = splusb(); 4383 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */ 4384 uaudio_chan_ptransfer(ch); 4385 splx(s); 4386 4387 return (0); 4388 } 4389 4390 u_int32_t 4391 uaudio_query_mix_info(device_t dev) 4392 { 4393 int i; 4394 u_int32_t mask = 0; 4395 struct uaudio_softc *sc; 4396 struct mixerctl *mc; 4397 4398 sc = device_get_softc(dev); 4399 for (i=0; i < sc->sc_nctls; i++) { 4400 mc = &sc->sc_ctls[i]; 4401 if (mc->ctl != SOUND_MIXER_NRDEVICES) { 4402 /* Set device mask bits. 4403 See /usr/include/machine/soundcard.h */ 4404 mask |= (1 << mc->ctl); 4405 } 4406 } 4407 return mask; 4408 } 4409 4410 u_int32_t 4411 uaudio_query_recsrc_info(device_t dev) 4412 { 4413 int i, rec_selector_id; 4414 u_int32_t mask = 0; 4415 struct uaudio_softc *sc; 4416 struct mixerctl *mc; 4417 4418 sc = device_get_softc(dev); 4419 rec_selector_id = -1; 4420 for (i=0; i < sc->sc_nctls; i++) { 4421 mc = &sc->sc_ctls[i]; 4422 if (mc->ctl == SOUND_MIXER_NRDEVICES && 4423 mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) { 4424 if (rec_selector_id == -1) { 4425 rec_selector_id = i; 4426 } else { 4427 printf("There are many selectors. Can't recognize which selector is a record source selector.\n"); 4428 return mask; 4429 } 4430 } 4431 } 4432 if (rec_selector_id == -1) 4433 return mask; 4434 mc = &sc->sc_ctls[rec_selector_id]; 4435 for (i = mc->minval; i <= mc->maxval; i++) { 4436 if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES) 4437 continue; 4438 mask |= 1 << mc->slctrtype[i - 1]; 4439 } 4440 return mask; 4441 } 4442 4443 void 4444 uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right) 4445 { 4446 int i; 4447 struct uaudio_softc *sc; 4448 struct mixerctl *mc; 4449 4450 sc = device_get_softc(dev); 4451 for (i=0; i < sc->sc_nctls; i++) { 4452 mc = &sc->sc_ctls[i]; 4453 if (mc->ctl == type) { 4454 if (mc->nchan == 2) { 4455 /* set Right */ 4456 uaudio_ctl_set(sc, SET_CUR, mc, 1, (int)(right*255)/100); 4457 } 4458 /* set Left or Mono */ 4459 uaudio_ctl_set(sc, SET_CUR, mc, 0, (int)(left*255)/100); 4460 } 4461 } 4462 return; 4463 } 4464 4465 u_int32_t 4466 uaudio_mixer_setrecsrc(device_t dev, u_int32_t src) 4467 { 4468 int i, rec_selector_id; 4469 struct uaudio_softc *sc; 4470 struct mixerctl *mc; 4471 4472 sc = device_get_softc(dev); 4473 rec_selector_id = -1; 4474 for (i=0; i < sc->sc_nctls; i++) { 4475 mc = &sc->sc_ctls[i]; 4476 if (mc->ctl == SOUND_MIXER_NRDEVICES && 4477 mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) { 4478 if (rec_selector_id == -1) { 4479 rec_selector_id = i; 4480 } else { 4481 return src; /* Can't recognize which selector is record source selector */ 4482 } 4483 } 4484 } 4485 if (rec_selector_id == -1) 4486 return src; 4487 mc = &sc->sc_ctls[rec_selector_id]; 4488 for (i = mc->minval; i <= mc->maxval; i++) { 4489 if (src != (1 << mc->slctrtype[i - 1])) 4490 continue; 4491 uaudio_ctl_set(sc, SET_CUR, mc, 0, i); 4492 return (1 << mc->slctrtype[i - 1]); 4493 } 4494 uaudio_ctl_set(sc, SET_CUR, mc, 0, mc->minval); 4495 return (1 << mc->slctrtype[mc->minval - 1]); 4496 } 4497 4498 static int 4499 uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) 4500 { 4501 struct snddev_info *d; 4502 struct snddev_channel *sce; 4503 struct pcm_channel *c; 4504 struct pcm_feeder *f; 4505 int pc, rc, vc; 4506 device_t pa_dev = device_get_parent(dev); 4507 struct uaudio_softc *sc = device_get_softc(pa_dev); 4508 4509 if (verbose < 1) 4510 return 0; 4511 4512 d = device_get_softc(dev); 4513 if (!d) 4514 return ENXIO; 4515 4516 snd_mtxlock(d->lock); 4517 if (SLIST_EMPTY(&d->channels)) { 4518 sbuf_printf(s, " (mixer only)"); 4519 snd_mtxunlock(d->lock); 4520 return 0; 4521 } 4522 pc = rc = vc = 0; 4523 SLIST_FOREACH(sce, &d->channels, link) { 4524 c = sce->channel; 4525 if (c->direction == PCMDIR_PLAY) { 4526 if (c->flags & CHN_F_VIRTUAL) 4527 vc++; 4528 else 4529 pc++; 4530 } else 4531 rc++; 4532 } 4533 sbuf_printf(s, " (%dp/%dr/%dv channels%s%s)", 4534 d->playcount, d->reccount, d->vchancount, 4535 (d->flags & SD_F_SIMPLEX)? "" : " duplex", 4536 #ifdef USING_DEVFS 4537 (device_get_unit(dev) == snd_unit)? " default" : "" 4538 #else 4539 "" 4540 #endif 4541 ); 4542 4543 if (sc->uaudio_sndstat_flag != 0) { 4544 sbuf_cat(s, sbuf_data(&(sc->uaudio_sndstat))); 4545 } 4546 4547 if (verbose <= 1) { 4548 snd_mtxunlock(d->lock); 4549 return 0; 4550 } 4551 4552 SLIST_FOREACH(sce, &d->channels, link) { 4553 c = sce->channel; 4554 sbuf_printf(s, "\n\t"); 4555 4556 KASSERT(c->bufhard != NULL && c->bufsoft != NULL, 4557 ("hosed pcm channel setup")); 4558 4559 /* it would be better to indent child channels */ 4560 sbuf_printf(s, "%s[%s]: ", c->parentchannel? c->parentchannel->name : "", c->name); 4561 sbuf_printf(s, "spd %d", c->speed); 4562 if (c->speed != sndbuf_getspd(c->bufhard)) 4563 sbuf_printf(s, "/%d", sndbuf_getspd(c->bufhard)); 4564 sbuf_printf(s, ", fmt 0x%08x", c->format); 4565 if (c->format != sndbuf_getfmt(c->bufhard)) 4566 sbuf_printf(s, "/0x%08x", sndbuf_getfmt(c->bufhard)); 4567 sbuf_printf(s, ", flags 0x%08x, 0x%08x", c->flags, c->feederflags); 4568 if (c->pid != -1) 4569 sbuf_printf(s, ", pid %d", c->pid); 4570 sbuf_printf(s, "\n\t"); 4571 4572 sbuf_printf(s, "interrupts %d, ", c->interrupts); 4573 if (c->direction == PCMDIR_REC) 4574 sbuf_printf(s, "overruns %d, feed %u, hfree %d, sfree %d [b:%d/%d/%d|bs:%d/%d/%d]", 4575 c->xruns, c->feedcount, sndbuf_getfree(c->bufhard), sndbuf_getfree(c->bufsoft), 4576 sndbuf_getsize(c->bufhard), sndbuf_getblksz(c->bufhard), 4577 sndbuf_getblkcnt(c->bufhard), 4578 sndbuf_getsize(c->bufsoft), sndbuf_getblksz(c->bufsoft), 4579 sndbuf_getblkcnt(c->bufsoft)); 4580 else 4581 sbuf_printf(s, "underruns %d, feed %u, ready %d [b:%d/%d/%d|bs:%d/%d/%d]", 4582 c->xruns, c->feedcount, sndbuf_getready(c->bufsoft), 4583 sndbuf_getsize(c->bufhard), sndbuf_getblksz(c->bufhard), 4584 sndbuf_getblkcnt(c->bufhard), 4585 sndbuf_getsize(c->bufsoft), sndbuf_getblksz(c->bufsoft), 4586 sndbuf_getblkcnt(c->bufsoft)); 4587 sbuf_printf(s, "\n\t"); 4588 4589 sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "hardware" : "userland"); 4590 sbuf_printf(s, " -> "); 4591 f = c->feeder; 4592 while (f->source != NULL) 4593 f = f->source; 4594 while (f != NULL) { 4595 sbuf_printf(s, "%s", f->class->name); 4596 if (f->desc->type == FEEDER_FMT) 4597 sbuf_printf(s, "(0x%08x -> 0x%08x)", f->desc->in, f->desc->out); 4598 if (f->desc->type == FEEDER_RATE) 4599 sbuf_printf(s, "(%d -> %d)", FEEDER_GET(f, FEEDRATE_SRC), FEEDER_GET(f, FEEDRATE_DST)); 4600 if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER) 4601 sbuf_printf(s, "(0x%08x)", f->desc->out); 4602 sbuf_printf(s, " -> "); 4603 f = f->parent; 4604 } 4605 sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "userland" : "hardware"); 4606 } 4607 snd_mtxunlock(d->lock); 4608 4609 return 0; 4610 } 4611 4612 void 4613 uaudio_sndstat_register(device_t dev) 4614 { 4615 struct snddev_info *d = device_get_softc(dev); 4616 sndstat_register(dev, d->status, uaudio_sndstat_prepare_pcm); 4617 } 4618 4619 int 4620 uaudio_get_vendor(device_t dev) 4621 { 4622 struct uaudio_softc *sc = device_get_softc(dev); 4623 4624 if (sc == NULL) 4625 return 0; 4626 4627 return sc->sc_vendor; 4628 } 4629 4630 int 4631 uaudio_get_product(device_t dev) 4632 { 4633 struct uaudio_softc *sc = device_get_softc(dev); 4634 4635 if (sc == NULL) 4636 return 0; 4637 4638 return sc->sc_product; 4639 } 4640 4641 int 4642 uaudio_get_release(device_t dev) 4643 { 4644 struct uaudio_softc *sc = device_get_softc(dev); 4645 4646 if (sc == NULL) 4647 return 0; 4648 4649 return sc->sc_release; 4650 } 4651 4652 static int 4653 audio_attach_mi(device_t dev) 4654 { 4655 device_t child; 4656 struct sndcard_func *func; 4657 4658 /* Attach the children. */ 4659 /* PCM Audio */ 4660 func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); 4661 if (func == NULL) 4662 return (ENOMEM); 4663 func->func = SCF_PCM; 4664 child = device_add_child(dev, "pcm", -1); 4665 device_set_ivars(child, func); 4666 4667 bus_generic_attach(dev); 4668 4669 return 0; /* XXXXX */ 4670 } 4671 4672 DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, usbd_driver_load, 0); 4673 MODULE_VERSION(uaudio, 1); 4674 4675 #endif 4676