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