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