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