1 /* $NetBSD: uaudio.c,v 1.49 2002/02/19 14:07:26 simonb Exp $ */ 2 3 /* 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (lennart@augustsson.net) at 9 * Carlstedt Research & Technology. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * USB audio specs: http://www.usb.org/developers/data/devclass/audio10.pdf 42 * http://www.usb.org/developers/data/devclass/frmts10.pdf 43 * http://www.usb.org/developers/data/devclass/termt10.pdf 44 */ 45 46 #include <sys/cdefs.h> 47 __KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.49 2002/02/19 14:07:26 simonb Exp $"); 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/kernel.h> 52 #include <sys/malloc.h> 53 #include <sys/device.h> 54 #include <sys/ioctl.h> 55 #include <sys/tty.h> 56 #include <sys/file.h> 57 #include <sys/reboot.h> /* for bootverbose */ 58 #include <sys/select.h> 59 #include <sys/proc.h> 60 #include <sys/vnode.h> 61 #include <sys/device.h> 62 #include <sys/poll.h> 63 64 #include <sys/audioio.h> 65 #include <dev/audio_if.h> 66 #include <dev/mulaw.h> 67 #include <dev/auconv.h> 68 69 #include <dev/usb/usb.h> 70 #include <dev/usb/usbdi.h> 71 #include <dev/usb/usbdi_util.h> 72 #include <dev/usb/usb_quirks.h> 73 74 #include <dev/usb/uaudioreg.h> 75 76 #ifdef UAUDIO_DEBUG 77 #define DPRINTF(x) if (uaudiodebug) logprintf x 78 #define DPRINTFN(n,x) if (uaudiodebug>(n)) logprintf x 79 int uaudiodebug = 0; 80 #else 81 #define DPRINTF(x) 82 #define DPRINTFN(n,x) 83 #endif 84 85 #define UAUDIO_NCHANBUFS 6 /* number of outstanding request */ 86 #define UAUDIO_NFRAMES 20 /* ms of sound in each request */ 87 88 89 #define MIX_MAX_CHAN 8 90 struct mixerctl { 91 u_int16_t wValue[MIX_MAX_CHAN]; /* using nchan */ 92 u_int16_t wIndex; 93 u_int8_t nchan; 94 u_int8_t type; 95 #define MIX_ON_OFF 1 96 #define MIX_SIGNED_16 2 97 #define MIX_UNSIGNED_16 3 98 #define MIX_SIGNED_8 4 99 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1) 100 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16) 101 int minval, maxval; 102 u_int delta; 103 u_int mul; 104 u_int8_t class; 105 char ctlname[MAX_AUDIO_DEV_LEN]; 106 char *ctlunit; 107 }; 108 #define MAKE(h,l) (((h) << 8) | (l)) 109 110 struct as_info { 111 u_int8_t alt; 112 u_int8_t encoding; 113 usbd_interface_handle ifaceh; 114 usb_interface_descriptor_t *idesc; 115 usb_endpoint_descriptor_audio_t *edesc; 116 struct usb_audio_streaming_type1_descriptor *asf1desc; 117 int sc_busy; /* currently used */ 118 }; 119 120 struct chan { 121 void (*intr)(void *); /* dma completion intr handler */ 122 void *arg; /* arg for intr() */ 123 usbd_pipe_handle pipe; 124 125 u_int sample_size; 126 u_int sample_rate; 127 u_int bytes_per_frame; 128 u_int fraction; /* fraction/1000 is the extra samples/frame */ 129 u_int residue; /* accumulates the fractional samples */ 130 131 u_char *start; /* upper layer buffer start */ 132 u_char *end; /* upper layer buffer end */ 133 u_char *cur; /* current position in upper layer buffer */ 134 int blksize; /* chunk size to report up */ 135 int transferred; /* transferred bytes not reported up */ 136 137 int altidx; /* currently used altidx */ 138 139 int curchanbuf; 140 struct chanbuf { 141 struct chan *chan; 142 usbd_xfer_handle xfer; 143 u_char *buffer; 144 u_int16_t sizes[UAUDIO_NFRAMES]; 145 u_int16_t size; 146 } chanbufs[UAUDIO_NCHANBUFS]; 147 148 struct uaudio_softc *sc; /* our softc */ 149 }; 150 151 struct uaudio_softc { 152 USBBASEDEVICE sc_dev; /* base device */ 153 usbd_device_handle sc_udev; /* USB device */ 154 155 int sc_ac_iface; /* Audio Control interface */ 156 usbd_interface_handle sc_ac_ifaceh; 157 158 struct chan sc_playchan; /* play channel */ 159 struct chan sc_recchan; /* record channel */ 160 161 int sc_nullalt; 162 163 int sc_audio_rev; 164 165 struct as_info *sc_alts; 166 int sc_nalts; 167 168 int sc_altflags; 169 #define HAS_8 0x01 170 #define HAS_16 0x02 171 #define HAS_8U 0x04 172 #define HAS_ALAW 0x08 173 #define HAS_MULAW 0x10 174 #define UA_NOFRAC 0x20 /* don't do sample rate adjustment */ 175 176 int sc_mode; /* play/record capability */ 177 178 struct mixerctl *sc_ctls; 179 int sc_nctls; 180 181 device_ptr_t sc_audiodev; 182 char sc_dying; 183 }; 184 185 #define UAC_OUTPUT 0 186 #define UAC_INPUT 1 187 #define UAC_EQUAL 2 188 189 Static usbd_status uaudio_identify_ac(struct uaudio_softc *sc, 190 usb_config_descriptor_t *cdesc); 191 Static usbd_status uaudio_identify_as(struct uaudio_softc *sc, 192 usb_config_descriptor_t *cdesc); 193 Static usbd_status uaudio_process_as(struct uaudio_softc *sc, 194 char *buf, int *offsp, int size, 195 usb_interface_descriptor_t *id); 196 197 Static void uaudio_add_alt(struct uaudio_softc *sc, 198 struct as_info *ai); 199 200 Static usb_interface_descriptor_t *uaudio_find_iface(char *buf, 201 int size, int *offsp, int subtype); 202 203 Static void uaudio_mixer_add_ctl(struct uaudio_softc *sc, 204 struct mixerctl *mp); 205 Static char *uaudio_id_name(struct uaudio_softc *sc, 206 usb_descriptor_t **dps, int id); 207 Static struct usb_audio_cluster uaudio_get_cluster(int id, 208 usb_descriptor_t **dps); 209 Static void uaudio_add_input(struct uaudio_softc *sc, 210 usb_descriptor_t *v, usb_descriptor_t **dps); 211 Static void uaudio_add_output(struct uaudio_softc *sc, 212 usb_descriptor_t *v, usb_descriptor_t **dps); 213 Static void uaudio_add_mixer(struct uaudio_softc *sc, 214 usb_descriptor_t *v, usb_descriptor_t **dps); 215 Static void uaudio_add_selector(struct uaudio_softc *sc, 216 usb_descriptor_t *v, usb_descriptor_t **dps); 217 Static void uaudio_add_feature(struct uaudio_softc *sc, 218 usb_descriptor_t *v, usb_descriptor_t **dps); 219 Static void uaudio_add_processing_updown(struct uaudio_softc *sc, 220 usb_descriptor_t *v, usb_descriptor_t **dps); 221 Static void uaudio_add_processing(struct uaudio_softc *sc, 222 usb_descriptor_t *v, usb_descriptor_t **dps); 223 Static void uaudio_add_extension(struct uaudio_softc *sc, 224 usb_descriptor_t *v, usb_descriptor_t **dps); 225 Static usbd_status uaudio_identify(struct uaudio_softc *sc, 226 usb_config_descriptor_t *cdesc); 227 228 Static int uaudio_signext(int type, int val); 229 Static int uaudio_value2bsd(struct mixerctl *mc, int val); 230 Static int uaudio_bsd2value(struct mixerctl *mc, int val); 231 Static int uaudio_get(struct uaudio_softc *sc, int type, 232 int which, int wValue, int wIndex, int len); 233 Static int uaudio_ctl_get(struct uaudio_softc *sc, int which, 234 struct mixerctl *mc, int chan); 235 Static void uaudio_set(struct uaudio_softc *sc, int type, 236 int which, int wValue, int wIndex, int l, int v); 237 Static void uaudio_ctl_set(struct uaudio_softc *sc, int which, 238 struct mixerctl *mc, int chan, int val); 239 240 Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int); 241 242 Static usbd_status uaudio_chan_open(struct uaudio_softc *sc, 243 struct chan *ch); 244 Static void uaudio_chan_close(struct uaudio_softc *sc, 245 struct chan *ch); 246 Static usbd_status uaudio_chan_alloc_buffers(struct uaudio_softc *, 247 struct chan *); 248 Static void uaudio_chan_free_buffers(struct uaudio_softc *, 249 struct chan *); 250 Static void uaudio_chan_set_param(struct chan *ch, 251 struct audio_params *param, u_char *start, 252 u_char *end, int blksize); 253 Static void uaudio_chan_ptransfer(struct chan *ch); 254 Static void uaudio_chan_pintr(usbd_xfer_handle xfer, 255 usbd_private_handle priv, usbd_status status); 256 257 Static void uaudio_chan_rtransfer(struct chan *ch); 258 Static void uaudio_chan_rintr(usbd_xfer_handle xfer, 259 usbd_private_handle priv, usbd_status status); 260 261 Static int uaudio_open(void *, int); 262 Static void uaudio_close(void *); 263 Static int uaudio_drain(void *); 264 Static int uaudio_query_encoding(void *, struct audio_encoding *); 265 Static int uaudio_set_params(void *, int, int, 266 struct audio_params *, struct audio_params *); 267 Static int uaudio_round_blocksize(void *, int); 268 Static int uaudio_trigger_output(void *, void *, void *, 269 int, void (*)(void *), void *, 270 struct audio_params *); 271 Static int uaudio_trigger_input (void *, void *, void *, 272 int, void (*)(void *), void *, 273 struct audio_params *); 274 Static int uaudio_halt_in_dma(void *); 275 Static int uaudio_halt_out_dma(void *); 276 Static int uaudio_getdev(void *, struct audio_device *); 277 Static int uaudio_mixer_set_port(void *, mixer_ctrl_t *); 278 Static int uaudio_mixer_get_port(void *, mixer_ctrl_t *); 279 Static int uaudio_query_devinfo(void *, mixer_devinfo_t *); 280 Static int uaudio_get_props(void *); 281 282 Static struct audio_hw_if uaudio_hw_if = { 283 uaudio_open, 284 uaudio_close, 285 uaudio_drain, 286 uaudio_query_encoding, 287 uaudio_set_params, 288 uaudio_round_blocksize, 289 NULL, 290 NULL, 291 NULL, 292 NULL, 293 NULL, 294 uaudio_halt_out_dma, 295 uaudio_halt_in_dma, 296 NULL, 297 uaudio_getdev, 298 NULL, 299 uaudio_mixer_set_port, 300 uaudio_mixer_get_port, 301 uaudio_query_devinfo, 302 NULL, 303 NULL, 304 NULL, 305 NULL, 306 uaudio_get_props, 307 uaudio_trigger_output, 308 uaudio_trigger_input, 309 NULL, 310 }; 311 312 Static struct audio_device uaudio_device = { 313 "USB audio", 314 "", 315 "uaudio" 316 }; 317 318 USB_DECLARE_DRIVER(uaudio); 319 320 USB_MATCH(uaudio) 321 { 322 USB_MATCH_START(uaudio, uaa); 323 usb_interface_descriptor_t *id; 324 325 if (uaa->iface == NULL) 326 return (UMATCH_NONE); 327 328 id = usbd_get_interface_descriptor(uaa->iface); 329 /* Trigger on the control interface. */ 330 if (id == NULL || 331 id->bInterfaceClass != UICLASS_AUDIO || 332 id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL || 333 (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO)) 334 return (UMATCH_NONE); 335 336 return (UMATCH_IFACECLASS_IFACESUBCLASS); 337 } 338 339 USB_ATTACH(uaudio) 340 { 341 USB_ATTACH_START(uaudio, sc, uaa); 342 usb_interface_descriptor_t *id; 343 usb_config_descriptor_t *cdesc; 344 char devinfo[1024]; 345 usbd_status err; 346 int i, j, found; 347 348 usbd_devinfo(uaa->device, 0, devinfo); 349 printf(": %s\n", devinfo); 350 351 sc->sc_udev = uaa->device; 352 353 cdesc = usbd_get_config_descriptor(sc->sc_udev); 354 if (cdesc == NULL) { 355 printf("%s: failed to get configuration descriptor\n", 356 USBDEVNAME(sc->sc_dev)); 357 USB_ATTACH_ERROR_RETURN; 358 } 359 360 err = uaudio_identify(sc, cdesc); 361 if (err) { 362 printf("%s: audio descriptors make no sense, error=%d\n", 363 USBDEVNAME(sc->sc_dev), err); 364 USB_ATTACH_ERROR_RETURN; 365 } 366 367 sc->sc_ac_ifaceh = uaa->iface; 368 /* Pick up the AS interface. */ 369 for (i = 0; i < uaa->nifaces; i++) { 370 if (uaa->ifaces[i] == NULL) 371 continue; 372 id = usbd_get_interface_descriptor(uaa->ifaces[i]); 373 if (id == NULL) 374 continue; 375 found = 0; 376 for (j = 0; j < sc->sc_nalts; j++) { 377 if (id->bInterfaceNumber == 378 sc->sc_alts[j].idesc->bInterfaceNumber) { 379 sc->sc_alts[j].ifaceh = uaa->ifaces[i]; 380 found = 1; 381 } 382 } 383 if (found) 384 uaa->ifaces[i] = NULL; 385 } 386 387 for (j = 0; j < sc->sc_nalts; j++) { 388 if (sc->sc_alts[j].ifaceh == NULL) { 389 printf("%s: alt %d missing AS interface(s)\n", 390 USBDEVNAME(sc->sc_dev), j); 391 USB_ATTACH_ERROR_RETURN; 392 } 393 } 394 395 printf("%s: audio rev %d.%02x\n", USBDEVNAME(sc->sc_dev), 396 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff); 397 398 sc->sc_playchan.sc = sc->sc_recchan.sc = sc; 399 400 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC) 401 sc->sc_altflags |= UA_NOFRAC; 402 403 #ifndef UAUDIO_DEBUG 404 if (bootverbose) 405 #endif 406 printf("%s: %d mixer controls\n", USBDEVNAME(sc->sc_dev), 407 sc->sc_nctls); 408 409 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, 410 USBDEV(sc->sc_dev)); 411 412 DPRINTF(("uaudio_attach: doing audio_attach_mi\n")); 413 #if defined(__OpenBSD__) 414 audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); 415 #else 416 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); 417 #endif 418 419 USB_ATTACH_SUCCESS_RETURN; 420 } 421 422 int 423 uaudio_activate(device_ptr_t self, enum devact act) 424 { 425 struct uaudio_softc *sc = (struct uaudio_softc *)self; 426 int rv = 0; 427 428 switch (act) { 429 case DVACT_ACTIVATE: 430 return (EOPNOTSUPP); 431 break; 432 433 case DVACT_DEACTIVATE: 434 if (sc->sc_audiodev != NULL) 435 rv = config_deactivate(sc->sc_audiodev); 436 sc->sc_dying = 1; 437 break; 438 } 439 return (rv); 440 } 441 442 int 443 uaudio_detach(device_ptr_t self, int flags) 444 { 445 struct uaudio_softc *sc = (struct uaudio_softc *)self; 446 int rv = 0; 447 448 /* Wait for outstanding requests to complete. */ 449 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); 450 451 if (sc->sc_audiodev != NULL) 452 rv = config_detach(sc->sc_audiodev, flags); 453 454 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 455 USBDEV(sc->sc_dev)); 456 457 return (rv); 458 } 459 460 int 461 uaudio_query_encoding(void *addr, struct audio_encoding *fp) 462 { 463 struct uaudio_softc *sc = addr; 464 int flags = sc->sc_altflags; 465 int idx; 466 467 if (sc->sc_dying) 468 return (EIO); 469 470 if (sc->sc_nalts == 0 || flags == 0) 471 return (ENXIO); 472 473 idx = fp->index; 474 switch (idx) { 475 case 0: 476 strcpy(fp->name, AudioEulinear); 477 fp->encoding = AUDIO_ENCODING_ULINEAR; 478 fp->precision = 8; 479 fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 480 return (0); 481 case 1: 482 strcpy(fp->name, AudioEmulaw); 483 fp->encoding = AUDIO_ENCODING_ULAW; 484 fp->precision = 8; 485 fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 486 return (0); 487 case 2: 488 strcpy(fp->name, AudioEalaw); 489 fp->encoding = AUDIO_ENCODING_ALAW; 490 fp->precision = 8; 491 fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 492 return (0); 493 case 3: 494 strcpy(fp->name, AudioEslinear); 495 fp->encoding = AUDIO_ENCODING_SLINEAR; 496 fp->precision = 8; 497 fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 498 return (0); 499 case 4: 500 strcpy(fp->name, AudioEslinear_le); 501 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 502 fp->precision = 16; 503 fp->flags = 0; 504 return (0); 505 case 5: 506 strcpy(fp->name, AudioEulinear_le); 507 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 508 fp->precision = 16; 509 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 510 return (0); 511 case 6: 512 strcpy(fp->name, AudioEslinear_be); 513 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 514 fp->precision = 16; 515 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 516 return (0); 517 case 7: 518 strcpy(fp->name, AudioEulinear_be); 519 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 520 fp->precision = 16; 521 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 522 return (0); 523 default: 524 return (EINVAL); 525 } 526 } 527 528 usb_interface_descriptor_t * 529 uaudio_find_iface(char *buf, int size, int *offsp, int subtype) 530 { 531 usb_interface_descriptor_t *d; 532 533 while (*offsp < size) { 534 d = (void *)(buf + *offsp); 535 *offsp += d->bLength; 536 if (d->bDescriptorType == UDESC_INTERFACE && 537 d->bInterfaceClass == UICLASS_AUDIO && 538 d->bInterfaceSubClass == subtype) 539 return (d); 540 } 541 return (NULL); 542 } 543 544 void 545 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc) 546 { 547 int res; 548 size_t len = sizeof(*mc) * (sc->sc_nctls + 1); 549 struct mixerctl *nmc = sc->sc_nctls == 0 ? 550 malloc(len, M_USBDEV, M_NOWAIT) : 551 realloc(sc->sc_ctls, len, M_USBDEV, M_NOWAIT); 552 553 if (nmc == NULL) { 554 printf("uaudio_mixer_add_ctl: no memory\n"); 555 return; 556 } 557 sc->sc_ctls = nmc; 558 559 mc->delta = 0; 560 if (mc->type != MIX_ON_OFF) { 561 /* Determine min and max values. */ 562 mc->minval = uaudio_signext(mc->type, 563 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE, 564 mc->wValue[0], mc->wIndex, 565 MIX_SIZE(mc->type))); 566 mc->maxval = 1 + uaudio_signext(mc->type, 567 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE, 568 mc->wValue[0], mc->wIndex, 569 MIX_SIZE(mc->type))); 570 mc->mul = mc->maxval - mc->minval; 571 if (mc->mul == 0) 572 mc->mul = 1; 573 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE, 574 mc->wValue[0], mc->wIndex, 575 MIX_SIZE(mc->type)); 576 if (res > 0) 577 mc->delta = (res * 256 + mc->mul/2) / mc->mul; 578 } else { 579 mc->minval = 0; 580 mc->maxval = 1; 581 } 582 583 sc->sc_ctls[sc->sc_nctls++] = *mc; 584 585 #ifdef UAUDIO_DEBUG 586 if (uaudiodebug > 2) { 587 int i; 588 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0])); 589 for (i = 1; i < mc->nchan; i++) 590 DPRINTF((",%04x", mc->wValue[i])); 591 DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' " 592 "min=%d max=%d\n", 593 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit, 594 mc->minval, mc->maxval)); 595 } 596 #endif 597 } 598 599 char * 600 uaudio_id_name(struct uaudio_softc *sc, usb_descriptor_t **dps, int id) 601 { 602 static char buf[32]; 603 sprintf(buf, "i%d", id); 604 return (buf); 605 } 606 607 struct usb_audio_cluster 608 uaudio_get_cluster(int id, usb_descriptor_t **dps) 609 { 610 struct usb_audio_cluster r; 611 usb_descriptor_t *dp; 612 int i; 613 614 for (i = 0; i < 25; i++) { /* avoid infinite loops */ 615 dp = dps[id]; 616 if (dp == 0) 617 goto bad; 618 switch (dp->bDescriptorSubtype) { 619 case UDESCSUB_AC_INPUT: 620 #define p ((struct usb_audio_input_terminal *)dp) 621 r.bNrChannels = p->bNrChannels; 622 USETW(r.wChannelConfig, UGETW(p->wChannelConfig)); 623 r.iChannelNames = p->iChannelNames; 624 #undef p 625 return (r); 626 case UDESCSUB_AC_OUTPUT: 627 #define p ((struct usb_audio_output_terminal *)dp) 628 id = p->bSourceId; 629 #undef p 630 break; 631 case UDESCSUB_AC_MIXER: 632 #define p ((struct usb_audio_mixer_unit *)dp) 633 r = *(struct usb_audio_cluster *) 634 &p->baSourceId[p->bNrInPins]; 635 #undef p 636 return (r); 637 case UDESCSUB_AC_SELECTOR: 638 /* XXX This is not really right */ 639 #define p ((struct usb_audio_selector_unit *)dp) 640 id = p->baSourceId[0]; 641 #undef p 642 break; 643 case UDESCSUB_AC_FEATURE: 644 #define p ((struct usb_audio_feature_unit *)dp) 645 id = p->bSourceId; 646 #undef p 647 break; 648 case UDESCSUB_AC_PROCESSING: 649 #define p ((struct usb_audio_processing_unit *)dp) 650 r = *(struct usb_audio_cluster *) 651 &p->baSourceId[p->bNrInPins]; 652 #undef p 653 return (r); 654 case UDESCSUB_AC_EXTENSION: 655 #define p ((struct usb_audio_extension_unit *)dp) 656 r = *(struct usb_audio_cluster *) 657 &p->baSourceId[p->bNrInPins]; 658 #undef p 659 return (r); 660 default: 661 goto bad; 662 } 663 } 664 bad: 665 printf("uaudio_get_cluster: bad data\n"); 666 memset(&r, 0, sizeof r); 667 return (r); 668 669 } 670 671 void 672 uaudio_add_input(struct uaudio_softc *sc, usb_descriptor_t *v, 673 usb_descriptor_t **dps) 674 { 675 #ifdef UAUDIO_DEBUG 676 struct usb_audio_input_terminal *d = 677 (struct usb_audio_input_terminal *)v; 678 679 DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x " 680 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d " 681 "iChannelNames=%d iTerminal=%d\n", 682 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 683 d->bNrChannels, UGETW(d->wChannelConfig), 684 d->iChannelNames, d->iTerminal)); 685 #endif 686 } 687 688 void 689 uaudio_add_output(struct uaudio_softc *sc, usb_descriptor_t *v, 690 usb_descriptor_t **dps) 691 { 692 #ifdef UAUDIO_DEBUG 693 struct usb_audio_output_terminal *d = 694 (struct usb_audio_output_terminal *)v; 695 696 DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x " 697 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n", 698 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 699 d->bSourceId, d->iTerminal)); 700 #endif 701 } 702 703 void 704 uaudio_add_mixer(struct uaudio_softc *sc, usb_descriptor_t *v, 705 usb_descriptor_t **dps) 706 { 707 struct usb_audio_mixer_unit *d = (struct usb_audio_mixer_unit *)v; 708 struct usb_audio_mixer_unit_1 *d1; 709 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k; 710 uByte *bm; 711 struct mixerctl mix; 712 713 DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n", 714 d->bUnitId, d->bNrInPins)); 715 716 /* Compute the number of input channels */ 717 ichs = 0; 718 for (i = 0; i < d->bNrInPins; i++) 719 ichs += uaudio_get_cluster(d->baSourceId[i], dps).bNrChannels; 720 721 /* and the number of output channels */ 722 d1 = (struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins]; 723 ochs = d1->bNrChannels; 724 DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs)); 725 726 bm = d1->bmControls; 727 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 728 mix.class = -1; 729 mix.type = MIX_SIGNED_16; 730 mix.ctlunit = AudioNvolume; 731 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1) 732 for (p = i = 0; i < d->bNrInPins; i++) { 733 chs = uaudio_get_cluster(d->baSourceId[i], dps).bNrChannels; 734 mc = 0; 735 for (c = 0; c < chs; c++) { 736 mo = 0; 737 for (o = 0; o < ochs; o++) { 738 bno = (p + c) * ochs + o; 739 if (BIT(bno)) 740 mo++; 741 } 742 if (mo == 1) 743 mc++; 744 } 745 if (mc == chs && chs <= MIX_MAX_CHAN) { 746 k = 0; 747 for (c = 0; c < chs; c++) 748 for (o = 0; o < ochs; o++) { 749 bno = (p + c) * ochs + o; 750 if (BIT(bno)) 751 mix.wValue[k++] = 752 MAKE(p+c+1, o+1); 753 } 754 sprintf(mix.ctlname, "mix%d-%s", d->bUnitId, 755 uaudio_id_name(sc, dps, d->baSourceId[i])); 756 mix.nchan = chs; 757 uaudio_mixer_add_ctl(sc, &mix); 758 } else { 759 /* XXX */ 760 } 761 #undef BIT 762 p += chs; 763 } 764 765 } 766 767 void 768 uaudio_add_selector(struct uaudio_softc *sc, usb_descriptor_t *v, 769 usb_descriptor_t **dps) 770 { 771 #ifdef UAUDIO_DEBUG 772 struct usb_audio_selector_unit *d = 773 (struct usb_audio_selector_unit *)v; 774 775 DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n", 776 d->bUnitId, d->bNrInPins)); 777 #endif 778 printf("uaudio_add_selector: NOT IMPLEMENTED\n"); 779 } 780 781 void 782 uaudio_add_feature(struct uaudio_softc *sc, usb_descriptor_t *v, 783 usb_descriptor_t **dps) 784 { 785 struct usb_audio_feature_unit *d = (struct usb_audio_feature_unit *)v; 786 uByte *ctls = d->bmaControls; 787 int ctlsize = d->bControlSize; 788 int nchan = (d->bLength - 7) / ctlsize; 789 int srcId = d->bSourceId; 790 u_int fumask, mmask, cmask; 791 struct mixerctl mix; 792 int chan, ctl, i, unit; 793 794 #define GET(i) (ctls[(i)*ctlsize] | \ 795 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0)) 796 797 mmask = GET(0); 798 /* Figure out what we can control */ 799 for (cmask = 0, chan = 1; chan < nchan; chan++) { 800 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n", 801 chan, GET(chan))); 802 cmask |= GET(chan); 803 } 804 805 DPRINTFN(1,("uaudio_add_feature: bUnitId=%d bSourceId=%d, " 806 "%d channels, mmask=0x%04x, cmask=0x%04x\n", 807 d->bUnitId, srcId, nchan, mmask, cmask)); 808 809 if (nchan > MIX_MAX_CHAN) 810 nchan = MIX_MAX_CHAN; 811 unit = d->bUnitId; 812 mix.wIndex = MAKE(unit, sc->sc_ac_iface); 813 for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) { 814 fumask = FU_MASK(ctl); 815 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n", 816 ctl, fumask)); 817 if (mmask & fumask) { 818 mix.nchan = 1; 819 mix.wValue[0] = MAKE(ctl, 0); 820 } else if (cmask & fumask) { 821 mix.nchan = nchan - 1; 822 for (i = 1; i < nchan; i++) { 823 if (GET(i) & fumask) 824 mix.wValue[i-1] = MAKE(ctl, i); 825 else 826 mix.wValue[i-1] = -1; 827 } 828 } else { 829 continue; 830 } 831 #undef GET 832 mix.class = -1; /* XXX */ 833 switch (ctl) { 834 case MUTE_CONTROL: 835 mix.type = MIX_ON_OFF; 836 sprintf(mix.ctlname, "fea%d-%s-%s", unit, 837 uaudio_id_name(sc, dps, srcId), 838 AudioNmute); 839 mix.ctlunit = ""; 840 break; 841 case VOLUME_CONTROL: 842 mix.type = MIX_SIGNED_16; 843 sprintf(mix.ctlname, "fea%d-%s-%s", unit, 844 uaudio_id_name(sc, dps, srcId), 845 AudioNmaster); 846 mix.ctlunit = AudioNvolume; 847 break; 848 case BASS_CONTROL: 849 mix.type = MIX_SIGNED_8; 850 sprintf(mix.ctlname, "fea%d-%s-%s", unit, 851 uaudio_id_name(sc, dps, srcId), 852 AudioNbass); 853 mix.ctlunit = AudioNbass; 854 break; 855 case MID_CONTROL: 856 mix.type = MIX_SIGNED_8; 857 sprintf(mix.ctlname, "fea%d-%s-%s", unit, 858 uaudio_id_name(sc, dps, srcId), 859 AudioNmid); 860 mix.ctlunit = AudioNmid; 861 break; 862 case TREBLE_CONTROL: 863 mix.type = MIX_SIGNED_8; 864 sprintf(mix.ctlname, "fea%d-%s-%s", unit, 865 uaudio_id_name(sc, dps, srcId), 866 AudioNtreble); 867 mix.ctlunit = AudioNtreble; 868 break; 869 case GRAPHIC_EQUALIZER_CONTROL: 870 continue; /* XXX don't add anything */ 871 break; 872 case AGC_CONTROL: 873 mix.type = MIX_ON_OFF; 874 sprintf(mix.ctlname, "fea%d-%s-%s", unit, 875 uaudio_id_name(sc, dps, srcId), 876 AudioNagc); 877 mix.ctlunit = ""; 878 break; 879 case DELAY_CONTROL: 880 mix.type = MIX_UNSIGNED_16; 881 sprintf(mix.ctlname, "fea%d-%s-%s", unit, 882 uaudio_id_name(sc, dps, srcId), 883 AudioNdelay); 884 mix.ctlunit = "4 ms"; 885 break; 886 case BASS_BOOST_CONTROL: 887 mix.type = MIX_ON_OFF; 888 sprintf(mix.ctlname, "fea%d-%s-%s", unit, 889 uaudio_id_name(sc, dps, srcId), 890 AudioNbassboost); 891 mix.ctlunit = ""; 892 break; 893 case LOUDNESS_CONTROL: 894 mix.type = MIX_ON_OFF; 895 sprintf(mix.ctlname, "fea%d-%s-%s", unit, 896 uaudio_id_name(sc, dps, srcId), 897 AudioNloudness); 898 mix.ctlunit = ""; 899 break; 900 } 901 uaudio_mixer_add_ctl(sc, &mix); 902 } 903 } 904 905 void 906 uaudio_add_processing_updown(struct uaudio_softc *sc, usb_descriptor_t *v, 907 usb_descriptor_t **dps) 908 { 909 struct usb_audio_processing_unit *d = 910 (struct usb_audio_processing_unit *)v; 911 struct usb_audio_processing_unit_1 *d1 = 912 (struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins]; 913 struct usb_audio_processing_unit_updown *ud = 914 (struct usb_audio_processing_unit_updown *) 915 &d1->bmControls[d1->bControlSize]; 916 struct mixerctl mix; 917 int i; 918 919 DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n", 920 d->bUnitId, ud->bNrModes)); 921 922 if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) { 923 DPRINTF(("uaudio_add_processing_updown: no mode select\n")); 924 return; 925 } 926 927 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 928 mix.nchan = 1; 929 mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0); 930 mix.class = -1; 931 mix.type = MIX_ON_OFF; /* XXX */ 932 mix.ctlunit = ""; 933 sprintf(mix.ctlname, "pro%d-mode", d->bUnitId); 934 935 for (i = 0; i < ud->bNrModes; i++) { 936 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n", 937 i, UGETW(ud->waModes[i]))); 938 /* XXX */ 939 } 940 uaudio_mixer_add_ctl(sc, &mix); 941 } 942 943 void 944 uaudio_add_processing(struct uaudio_softc *sc, usb_descriptor_t *v, 945 usb_descriptor_t **dps) 946 { 947 struct usb_audio_processing_unit *d = 948 (struct usb_audio_processing_unit *)v; 949 struct usb_audio_processing_unit_1 *d1 = 950 (struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins]; 951 int ptype = UGETW(d->wProcessType); 952 struct mixerctl mix; 953 954 DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d " 955 "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins)); 956 957 if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) { 958 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 959 mix.nchan = 1; 960 mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0); 961 mix.class = -1; 962 mix.type = MIX_ON_OFF; 963 mix.ctlunit = ""; 964 sprintf(mix.ctlname, "pro%d.%d-enable", d->bUnitId, ptype); 965 uaudio_mixer_add_ctl(sc, &mix); 966 } 967 968 switch(ptype) { 969 case UPDOWNMIX_PROCESS: 970 uaudio_add_processing_updown(sc, v, dps); 971 break; 972 case DOLBY_PROLOGIC_PROCESS: 973 case P3D_STEREO_EXTENDER_PROCESS: 974 case REVERBATION_PROCESS: 975 case CHORUS_PROCESS: 976 case DYN_RANGE_COMP_PROCESS: 977 default: 978 #ifdef UAUDIO_DEBUG 979 printf("uaudio_add_processing: unit %d, type=%d not impl.\n", 980 d->bUnitId, ptype); 981 #endif 982 break; 983 } 984 } 985 986 void 987 uaudio_add_extension(struct uaudio_softc *sc, usb_descriptor_t *v, 988 usb_descriptor_t **dps) 989 { 990 struct usb_audio_extension_unit *d = 991 (struct usb_audio_extension_unit *)v; 992 struct usb_audio_extension_unit_1 *d1 = 993 (struct usb_audio_extension_unit_1 *)&d->baSourceId[d->bNrInPins]; 994 struct mixerctl mix; 995 996 DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n", 997 d->bUnitId, d->bNrInPins)); 998 999 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU) 1000 return; 1001 1002 if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) { 1003 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1004 mix.nchan = 1; 1005 mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0); 1006 mix.class = -1; 1007 mix.type = MIX_ON_OFF; 1008 mix.ctlunit = ""; 1009 sprintf(mix.ctlname, "ext%d-enable", d->bUnitId); 1010 uaudio_mixer_add_ctl(sc, &mix); 1011 } 1012 } 1013 1014 usbd_status 1015 uaudio_identify(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc) 1016 { 1017 usbd_status err; 1018 1019 err = uaudio_identify_ac(sc, cdesc); 1020 if (err) 1021 return (err); 1022 return (uaudio_identify_as(sc, cdesc)); 1023 } 1024 1025 void 1026 uaudio_add_alt(struct uaudio_softc *sc, struct as_info *ai) 1027 { 1028 size_t len = sizeof(*ai) * (sc->sc_nalts + 1); 1029 struct as_info *nai = (sc->sc_nalts == 0) ? 1030 malloc(len, M_USBDEV, M_NOWAIT) : 1031 realloc(sc->sc_alts, len, M_USBDEV, M_NOWAIT); 1032 1033 if (nai == NULL) { 1034 printf("uaudio_add_alt: no memory\n"); 1035 return; 1036 } 1037 1038 sc->sc_alts = nai; 1039 DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n", 1040 ai->alt, ai->encoding)); 1041 sc->sc_alts[sc->sc_nalts++] = *ai; 1042 } 1043 1044 usbd_status 1045 uaudio_process_as(struct uaudio_softc *sc, char *buf, int *offsp, 1046 int size, usb_interface_descriptor_t *id) 1047 #define offs (*offsp) 1048 { 1049 struct usb_audio_streaming_interface_descriptor *asid; 1050 struct usb_audio_streaming_type1_descriptor *asf1d; 1051 usb_endpoint_descriptor_audio_t *ed; 1052 struct usb_audio_streaming_endpoint_descriptor *sed; 1053 int format, chan, prec, enc; 1054 int dir, type; 1055 struct as_info ai; 1056 1057 asid = (void *)(buf + offs); 1058 if (asid->bDescriptorType != UDESC_CS_INTERFACE || 1059 asid->bDescriptorSubtype != AS_GENERAL) 1060 return (USBD_INVAL); 1061 offs += asid->bLength; 1062 if (offs > size) 1063 return (USBD_INVAL); 1064 asf1d = (void *)(buf + offs); 1065 if (asf1d->bDescriptorType != UDESC_CS_INTERFACE || 1066 asf1d->bDescriptorSubtype != FORMAT_TYPE) 1067 return (USBD_INVAL); 1068 offs += asf1d->bLength; 1069 if (offs > size) 1070 return (USBD_INVAL); 1071 1072 if (asf1d->bFormatType != FORMAT_TYPE_I) { 1073 printf("%s: ignored setting with type %d format\n", 1074 USBDEVNAME(sc->sc_dev), UGETW(asid->wFormatTag)); 1075 return (USBD_NORMAL_COMPLETION); 1076 } 1077 1078 ed = (void *)(buf + offs); 1079 if (ed->bDescriptorType != UDESC_ENDPOINT) 1080 return (USBD_INVAL); 1081 DPRINTF(("uaudio_process_as: endpoint bLength=%d bDescriptorType=%d " 1082 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d " 1083 "bInterval=%d bRefresh=%d bSynchAddress=%d\n", 1084 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress, 1085 ed->bmAttributes, UGETW(ed->wMaxPacketSize), 1086 ed->bInterval, ed->bRefresh, ed->bSynchAddress)); 1087 offs += ed->bLength; 1088 if (offs > size) 1089 return (USBD_INVAL); 1090 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS) 1091 return (USBD_INVAL); 1092 1093 dir = UE_GET_DIR(ed->bEndpointAddress); 1094 type = UE_GET_ISO_TYPE(ed->bmAttributes); 1095 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) && 1096 dir == UE_DIR_IN && type == UE_ISO_ADAPT) 1097 type = UE_ISO_ASYNC; 1098 1099 /* We can't handle endpoints that need a sync pipe yet. */ 1100 if (dir == UE_DIR_IN ? type == UE_ISO_ADAPT : type == UE_ISO_ASYNC) { 1101 printf("%s: ignored %sput endpoint of type %s\n", 1102 USBDEVNAME(sc->sc_dev), 1103 dir == UE_DIR_IN ? "in" : "out", 1104 dir == UE_DIR_IN ? "adaptive" : "async"); 1105 return (USBD_NORMAL_COMPLETION); 1106 } 1107 1108 sed = (void *)(buf + offs); 1109 if (sed->bDescriptorType != UDESC_CS_ENDPOINT || 1110 sed->bDescriptorSubtype != AS_GENERAL) 1111 return (USBD_INVAL); 1112 offs += sed->bLength; 1113 if (offs > size) 1114 return (USBD_INVAL); 1115 1116 format = UGETW(asid->wFormatTag); 1117 chan = asf1d->bNrChannels; 1118 prec = asf1d->bBitResolution; 1119 if (prec != 8 && prec != 16) { 1120 #ifdef UAUDIO_DEBUG 1121 printf("%s: ignored setting with precision %d\n", 1122 USBDEVNAME(sc->sc_dev), prec); 1123 #endif 1124 return (USBD_NORMAL_COMPLETION); 1125 } 1126 switch (format) { 1127 case UA_FMT_PCM: 1128 sc->sc_altflags |= prec == 8 ? HAS_8 : HAS_16; 1129 enc = AUDIO_ENCODING_SLINEAR_LE; 1130 break; 1131 case UA_FMT_PCM8: 1132 enc = AUDIO_ENCODING_ULINEAR_LE; 1133 sc->sc_altflags |= HAS_8U; 1134 break; 1135 case UA_FMT_ALAW: 1136 enc = AUDIO_ENCODING_ALAW; 1137 sc->sc_altflags |= HAS_ALAW; 1138 break; 1139 case UA_FMT_MULAW: 1140 enc = AUDIO_ENCODING_ULAW; 1141 sc->sc_altflags |= HAS_MULAW; 1142 break; 1143 default: 1144 printf("%s: ignored setting with format %d\n", 1145 USBDEVNAME(sc->sc_dev), format); 1146 return (USBD_NORMAL_COMPLETION); 1147 } 1148 DPRINTFN(1,("uaudio_identify: alt=%d enc=%d chan=%d prec=%d\n", 1149 id->bAlternateSetting, enc, chan, prec)); 1150 ai.alt = id->bAlternateSetting; 1151 ai.encoding = enc; 1152 ai.idesc = id; 1153 ai.edesc = ed; 1154 ai.asf1desc = asf1d; 1155 uaudio_add_alt(sc, &ai); 1156 sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD; 1157 1158 return (USBD_NORMAL_COMPLETION); 1159 } 1160 #undef offs 1161 1162 usbd_status 1163 uaudio_identify_as(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc) 1164 { 1165 usb_interface_descriptor_t *id; 1166 usbd_status err; 1167 char *buf; 1168 int size, offs; 1169 1170 size = UGETW(cdesc->wTotalLength); 1171 buf = (char *)cdesc; 1172 1173 /* Locate the AudioStreaming interface descriptor. */ 1174 offs = 0; 1175 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM); 1176 if (id == NULL) 1177 return (USBD_INVAL); 1178 1179 /* Loop through all the alternate settings. */ 1180 while (offs <= size) { 1181 DPRINTFN(2, ("uaudio_identify: interface %d\n", 1182 id->bInterfaceNumber)); 1183 switch (id->bNumEndpoints) { 1184 case 0: 1185 DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n", 1186 id->bAlternateSetting)); 1187 sc->sc_nullalt = id->bAlternateSetting; 1188 break; 1189 case 1: 1190 err = uaudio_process_as(sc, buf, &offs, size, id); 1191 break; 1192 default: 1193 #ifdef UAUDIO_DEBUG 1194 printf("%s: ignored audio interface with %d " 1195 "endpoints\n", 1196 USBDEVNAME(sc->sc_dev), id->bNumEndpoints); 1197 #endif 1198 break; 1199 } 1200 id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM); 1201 if (id == NULL) 1202 break; 1203 } 1204 if (offs > size) 1205 return (USBD_INVAL); 1206 DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts)); 1207 1208 if ((sc->sc_mode & (AUMODE_PLAY | AUMODE_RECORD)) == 0) { 1209 printf("%s: no usable endpoint found\n", 1210 USBDEVNAME(sc->sc_dev)); 1211 return (USBD_INVAL); 1212 } 1213 1214 return (USBD_NORMAL_COMPLETION); 1215 } 1216 1217 usbd_status 1218 uaudio_identify_ac(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc) 1219 { 1220 usb_interface_descriptor_t *id; 1221 struct usb_audio_control_descriptor *acdp; 1222 usb_descriptor_t *dp, *dps[256]; 1223 char *buf, *ibuf, *ibufend; 1224 int size, offs, aclen, ndps, i; 1225 1226 size = UGETW(cdesc->wTotalLength); 1227 buf = (char *)cdesc; 1228 1229 /* Locate the AudioControl interface descriptor. */ 1230 offs = 0; 1231 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL); 1232 if (id == NULL) 1233 return (USBD_INVAL); 1234 if (offs + sizeof *acdp > size) 1235 return (USBD_INVAL); 1236 sc->sc_ac_iface = id->bInterfaceNumber; 1237 DPRINTFN(2,("uaudio_identify: AC interface is %d\n", sc->sc_ac_iface)); 1238 1239 /* A class-specific AC interface header should follow. */ 1240 ibuf = buf + offs; 1241 acdp = (struct usb_audio_control_descriptor *)ibuf; 1242 if (acdp->bDescriptorType != UDESC_CS_INTERFACE || 1243 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER) 1244 return (USBD_INVAL); 1245 aclen = UGETW(acdp->wTotalLength); 1246 if (offs + aclen > size) 1247 return (USBD_INVAL); 1248 1249 if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) && 1250 UGETW(acdp->bcdADC) != UAUDIO_VERSION) 1251 return (USBD_INVAL); 1252 1253 sc->sc_audio_rev = UGETW(acdp->bcdADC); 1254 DPRINTFN(2,("uaudio_identify: found AC header, vers=%03x, len=%d\n", 1255 sc->sc_audio_rev, aclen)); 1256 1257 sc->sc_nullalt = -1; 1258 1259 /* Scan through all the AC specific descriptors */ 1260 ibufend = ibuf + aclen; 1261 dp = (usb_descriptor_t *)ibuf; 1262 ndps = 0; 1263 memset(dps, 0, sizeof dps); 1264 for (;;) { 1265 ibuf += dp->bLength; 1266 if (ibuf >= ibufend) 1267 break; 1268 dp = (usb_descriptor_t *)ibuf; 1269 if (ibuf + dp->bLength > ibufend) 1270 return (USBD_INVAL); 1271 if (dp->bDescriptorType != UDESC_CS_INTERFACE) { 1272 printf("uaudio_identify: skip desc type=0x%02x\n", 1273 dp->bDescriptorType); 1274 continue; 1275 } 1276 i = ((struct usb_audio_input_terminal *)dp)->bTerminalId; 1277 dps[i] = dp; 1278 if (i > ndps) 1279 ndps = i; 1280 } 1281 ndps++; 1282 1283 for (i = 0; i < ndps; i++) { 1284 dp = dps[i]; 1285 if (dp == NULL) 1286 continue; 1287 DPRINTF(("uaudio_identify: subtype=%d\n", 1288 dp->bDescriptorSubtype)); 1289 switch (dp->bDescriptorSubtype) { 1290 case UDESCSUB_AC_HEADER: 1291 printf("uaudio_identify: unexpected AC header\n"); 1292 break; 1293 case UDESCSUB_AC_INPUT: 1294 uaudio_add_input(sc, dp, dps); 1295 break; 1296 case UDESCSUB_AC_OUTPUT: 1297 uaudio_add_output(sc, dp, dps); 1298 break; 1299 case UDESCSUB_AC_MIXER: 1300 uaudio_add_mixer(sc, dp, dps); 1301 break; 1302 case UDESCSUB_AC_SELECTOR: 1303 uaudio_add_selector(sc, dp, dps); 1304 break; 1305 case UDESCSUB_AC_FEATURE: 1306 uaudio_add_feature(sc, dp, dps); 1307 break; 1308 case UDESCSUB_AC_PROCESSING: 1309 uaudio_add_processing(sc, dp, dps); 1310 break; 1311 case UDESCSUB_AC_EXTENSION: 1312 uaudio_add_extension(sc, dp, dps); 1313 break; 1314 default: 1315 printf("uaudio_identify: bad AC desc subtype=0x%02x\n", 1316 dp->bDescriptorSubtype); 1317 break; 1318 } 1319 } 1320 return (USBD_NORMAL_COMPLETION); 1321 } 1322 1323 int 1324 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi) 1325 { 1326 struct uaudio_softc *sc = addr; 1327 struct mixerctl *mc; 1328 int n, nctls; 1329 1330 DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index)); 1331 if (sc->sc_dying) 1332 return (EIO); 1333 1334 n = mi->index; 1335 nctls = sc->sc_nctls; 1336 1337 if (n < 0 || n >= nctls) { 1338 switch (n - nctls) { 1339 case UAC_OUTPUT: 1340 mi->type = AUDIO_MIXER_CLASS; 1341 mi->mixer_class = nctls + UAC_OUTPUT; 1342 mi->next = mi->prev = AUDIO_MIXER_LAST; 1343 strcpy(mi->label.name, AudioCoutputs); 1344 return (0); 1345 case UAC_INPUT: 1346 mi->type = AUDIO_MIXER_CLASS; 1347 mi->mixer_class = nctls + UAC_INPUT; 1348 mi->next = mi->prev = AUDIO_MIXER_LAST; 1349 strcpy(mi->label.name, AudioCinputs); 1350 return (0); 1351 case UAC_EQUAL: 1352 mi->type = AUDIO_MIXER_CLASS; 1353 mi->mixer_class = nctls + UAC_EQUAL; 1354 mi->next = mi->prev = AUDIO_MIXER_LAST; 1355 strcpy(mi->label.name, AudioCequalization); 1356 return (0); 1357 default: 1358 return (ENXIO); 1359 } 1360 } 1361 mc = &sc->sc_ctls[n]; 1362 strncpy(mi->label.name, mc->ctlname, MAX_AUDIO_DEV_LEN); 1363 mi->mixer_class = mc->class; 1364 mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */ 1365 switch (mc->type) { 1366 case MIX_ON_OFF: 1367 mi->type = AUDIO_MIXER_ENUM; 1368 mi->un.e.num_mem = 2; 1369 strcpy(mi->un.e.member[0].label.name, AudioNoff); 1370 mi->un.e.member[0].ord = 0; 1371 strcpy(mi->un.e.member[1].label.name, AudioNon); 1372 mi->un.e.member[1].ord = 1; 1373 break; 1374 default: 1375 mi->type = AUDIO_MIXER_VALUE; 1376 strncpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN); 1377 mi->un.v.num_channels = mc->nchan; 1378 mi->un.v.delta = mc->delta; 1379 break; 1380 } 1381 return (0); 1382 } 1383 1384 int 1385 uaudio_open(void *addr, int flags) 1386 { 1387 struct uaudio_softc *sc = addr; 1388 1389 DPRINTF(("uaudio_open: sc=%p\n", sc)); 1390 if (sc->sc_dying) 1391 return (EIO); 1392 1393 if (sc->sc_mode == 0) 1394 return (ENXIO); 1395 1396 if (flags & FREAD) { 1397 if ((sc->sc_mode & AUMODE_RECORD) == 0) 1398 return (EACCES); 1399 sc->sc_recchan.intr = NULL; 1400 } 1401 1402 if (flags & FWRITE) { 1403 if ((sc->sc_mode & AUMODE_PLAY) == 0) 1404 return (EACCES); 1405 sc->sc_playchan.intr = NULL; 1406 } 1407 1408 return (0); 1409 } 1410 1411 /* 1412 * Close function is called at splaudio(). 1413 */ 1414 void 1415 uaudio_close(void *addr) 1416 { 1417 struct uaudio_softc *sc = addr; 1418 1419 DPRINTF(("uaudio_close: sc=%p\n", sc)); 1420 uaudio_halt_in_dma(sc); 1421 uaudio_halt_out_dma(sc); 1422 1423 sc->sc_playchan.intr = sc->sc_recchan.intr = NULL; 1424 } 1425 1426 int 1427 uaudio_drain(void *addr) 1428 { 1429 struct uaudio_softc *sc = addr; 1430 1431 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES); 1432 1433 return (0); 1434 } 1435 1436 int 1437 uaudio_halt_out_dma(void *addr) 1438 { 1439 struct uaudio_softc *sc = addr; 1440 1441 DPRINTF(("uaudio_halt_out_dma: enter\n")); 1442 if (sc->sc_playchan.pipe != NULL) { 1443 uaudio_chan_close(sc, &sc->sc_playchan); 1444 sc->sc_playchan.pipe = NULL; 1445 uaudio_chan_free_buffers(sc, &sc->sc_playchan); 1446 } 1447 return (0); 1448 } 1449 1450 int 1451 uaudio_halt_in_dma(void *addr) 1452 { 1453 struct uaudio_softc *sc = addr; 1454 1455 DPRINTF(("uaudio_halt_in_dma: enter\n")); 1456 if (sc->sc_recchan.pipe != NULL) { 1457 uaudio_chan_close(sc, &sc->sc_recchan); 1458 sc->sc_recchan.pipe = NULL; 1459 uaudio_chan_free_buffers(sc, &sc->sc_recchan); 1460 } 1461 return (0); 1462 } 1463 1464 int 1465 uaudio_getdev(void *addr, struct audio_device *retp) 1466 { 1467 struct uaudio_softc *sc = addr; 1468 1469 DPRINTF(("uaudio_mixer_getdev:\n")); 1470 if (sc->sc_dying) 1471 return (EIO); 1472 1473 *retp = uaudio_device; 1474 return (0); 1475 } 1476 1477 /* 1478 * Make sure the block size is large enough to hold all outstanding transfers. 1479 */ 1480 int 1481 uaudio_round_blocksize(void *addr, int blk) 1482 { 1483 struct uaudio_softc *sc = addr; 1484 int bpf; 1485 1486 if (sc->sc_playchan.bytes_per_frame > sc->sc_recchan.bytes_per_frame) { 1487 bpf = sc->sc_playchan.bytes_per_frame 1488 + sc->sc_playchan.sample_size; 1489 } else { 1490 bpf = sc->sc_recchan.bytes_per_frame 1491 + sc->sc_recchan.sample_size; 1492 } 1493 /* XXX */ 1494 bpf *= UAUDIO_NFRAMES * UAUDIO_NCHANBUFS; 1495 1496 bpf = (bpf + 15) &~ 15; 1497 1498 if (blk < bpf) 1499 blk = bpf; 1500 1501 #ifdef DIAGNOSTIC 1502 if (blk <= 0) { 1503 printf("uaudio_round_blocksize: blk=%d\n", blk); 1504 blk = 512; 1505 } 1506 #endif 1507 1508 DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk)); 1509 return (blk); 1510 } 1511 1512 int 1513 uaudio_get_props(void *addr) 1514 { 1515 return (AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT); 1516 1517 } 1518 1519 int 1520 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue, 1521 int wIndex, int len) 1522 { 1523 usb_device_request_t req; 1524 u_int8_t data[4]; 1525 usbd_status err; 1526 int val; 1527 1528 if (wValue == -1) 1529 return (0); 1530 1531 req.bmRequestType = type; 1532 req.bRequest = which; 1533 USETW(req.wValue, wValue); 1534 USETW(req.wIndex, wIndex); 1535 USETW(req.wLength, len); 1536 DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x " 1537 "wIndex=0x%04x len=%d\n", 1538 type, which, wValue, wIndex, len)); 1539 err = usbd_do_request(sc->sc_udev, &req, data); 1540 if (err) { 1541 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err))); 1542 return (-1); 1543 } 1544 switch (len) { 1545 case 1: 1546 val = data[0]; 1547 break; 1548 case 2: 1549 val = data[0] | (data[1] << 8); 1550 break; 1551 default: 1552 DPRINTF(("uaudio_get: bad length=%d\n", len)); 1553 return (-1); 1554 } 1555 DPRINTFN(2,("uaudio_get: val=%d\n", val)); 1556 return (val); 1557 } 1558 1559 void 1560 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue, 1561 int wIndex, int len, int val) 1562 { 1563 usb_device_request_t req; 1564 u_int8_t data[4]; 1565 usbd_status err; 1566 1567 if (wValue == -1) 1568 return; 1569 1570 req.bmRequestType = type; 1571 req.bRequest = which; 1572 USETW(req.wValue, wValue); 1573 USETW(req.wIndex, wIndex); 1574 USETW(req.wLength, len); 1575 switch (len) { 1576 case 1: 1577 data[0] = val; 1578 break; 1579 case 2: 1580 data[0] = val; 1581 data[1] = val >> 8; 1582 break; 1583 default: 1584 return; 1585 } 1586 DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x " 1587 "wIndex=0x%04x len=%d, val=%d\n", 1588 type, which, wValue, wIndex, len, val & 0xffff)); 1589 err = usbd_do_request(sc->sc_udev, &req, data); 1590 #ifdef UAUDIO_DEBUG 1591 if (err) 1592 DPRINTF(("uaudio_set: err=%d\n", err)); 1593 #endif 1594 } 1595 1596 int 1597 uaudio_signext(int type, int val) 1598 { 1599 if (!MIX_UNSIGNED(type)) { 1600 if (MIX_SIZE(type) == 2) 1601 val = (int16_t)val; 1602 else 1603 val = (int8_t)val; 1604 } 1605 return (val); 1606 } 1607 1608 int 1609 uaudio_value2bsd(struct mixerctl *mc, int val) 1610 { 1611 DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ", 1612 mc->type, val, mc->minval, mc->maxval)); 1613 if (mc->type == MIX_ON_OFF) 1614 val = (val != 0); 1615 else 1616 val = ((uaudio_signext(mc->type, val) - mc->minval) * 256 1617 + mc->mul/2) / mc->mul; 1618 DPRINTFN(5, ("val'=%d\n", val)); 1619 return (val); 1620 } 1621 1622 int 1623 uaudio_bsd2value(struct mixerctl *mc, int val) 1624 { 1625 DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ", 1626 mc->type, val, mc->minval, mc->maxval)); 1627 if (mc->type == MIX_ON_OFF) 1628 val = (val != 0); 1629 else 1630 val = (val + mc->delta/2) * mc->mul / 256 + mc->minval; 1631 DPRINTFN(5, ("val'=%d\n", val)); 1632 return (val); 1633 } 1634 1635 int 1636 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc, 1637 int chan) 1638 { 1639 int val; 1640 1641 DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan)); 1642 val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan], 1643 mc->wIndex, MIX_SIZE(mc->type)); 1644 return (uaudio_value2bsd(mc, val)); 1645 } 1646 1647 void 1648 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc, 1649 int chan, int val) 1650 { 1651 val = uaudio_bsd2value(mc, val); 1652 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan], 1653 mc->wIndex, MIX_SIZE(mc->type), val); 1654 } 1655 1656 int 1657 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp) 1658 { 1659 struct uaudio_softc *sc = addr; 1660 struct mixerctl *mc; 1661 int i, n, vals[MIX_MAX_CHAN], val; 1662 1663 DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev)); 1664 1665 if (sc->sc_dying) 1666 return (EIO); 1667 1668 n = cp->dev; 1669 if (n < 0 || n >= sc->sc_nctls) 1670 return (ENXIO); 1671 mc = &sc->sc_ctls[n]; 1672 1673 if (mc->type == MIX_ON_OFF) { 1674 if (cp->type != AUDIO_MIXER_ENUM) 1675 return (EINVAL); 1676 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0); 1677 } else { 1678 if (cp->type != AUDIO_MIXER_VALUE) 1679 return (EINVAL); 1680 if (cp->un.value.num_channels != 1 && 1681 cp->un.value.num_channels != mc->nchan) 1682 return (EINVAL); 1683 for (i = 0; i < mc->nchan; i++) 1684 vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i); 1685 if (cp->un.value.num_channels == 1 && mc->nchan != 1) { 1686 for (val = 0, i = 0; i < mc->nchan; i++) 1687 val += vals[i]; 1688 vals[0] = val / mc->nchan; 1689 } 1690 for (i = 0; i < cp->un.value.num_channels; i++) 1691 cp->un.value.level[i] = vals[i]; 1692 } 1693 1694 return (0); 1695 } 1696 1697 int 1698 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp) 1699 { 1700 struct uaudio_softc *sc = addr; 1701 struct mixerctl *mc; 1702 int i, n, vals[MIX_MAX_CHAN]; 1703 1704 DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev)); 1705 if (sc->sc_dying) 1706 return (EIO); 1707 1708 n = cp->dev; 1709 if (n < 0 || n >= sc->sc_nctls) 1710 return (ENXIO); 1711 mc = &sc->sc_ctls[n]; 1712 1713 if (mc->type == MIX_ON_OFF) { 1714 if (cp->type != AUDIO_MIXER_ENUM) 1715 return (EINVAL); 1716 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord); 1717 } else { 1718 if (cp->type != AUDIO_MIXER_VALUE) 1719 return (EINVAL); 1720 if (cp->un.value.num_channels == 1) 1721 for (i = 0; i < mc->nchan; i++) 1722 vals[i] = cp->un.value.level[0]; 1723 else if (cp->un.value.num_channels == mc->nchan) 1724 for (i = 0; i < mc->nchan; i++) 1725 vals[i] = cp->un.value.level[i]; 1726 else 1727 return (EINVAL); 1728 for (i = 0; i < mc->nchan; i++) 1729 uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]); 1730 } 1731 return (0); 1732 } 1733 1734 int 1735 uaudio_trigger_input(void *addr, void *start, void *end, int blksize, 1736 void (*intr)(void *), void *arg, 1737 struct audio_params *param) 1738 { 1739 struct uaudio_softc *sc = addr; 1740 struct chan *ch = &sc->sc_recchan; 1741 usbd_status err; 1742 int i, s; 1743 1744 if (sc->sc_dying) 1745 return (EIO); 1746 1747 DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p " 1748 "blksize=%d\n", sc, start, end, blksize)); 1749 1750 uaudio_chan_set_param(ch, param, start, end, blksize); 1751 DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d " 1752 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 1753 ch->fraction)); 1754 1755 err = uaudio_chan_alloc_buffers(sc, ch); 1756 if (err) 1757 return (EIO); 1758 1759 err = uaudio_chan_open(sc, ch); 1760 if (err) { 1761 uaudio_chan_free_buffers(sc, ch); 1762 return (EIO); 1763 } 1764 1765 ch->intr = intr; 1766 ch->arg = arg; 1767 1768 s = splusb(); 1769 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */ 1770 uaudio_chan_rtransfer(ch); 1771 splx(s); 1772 1773 return (0); 1774 } 1775 1776 int 1777 uaudio_trigger_output(void *addr, void *start, void *end, int blksize, 1778 void (*intr)(void *), void *arg, 1779 struct audio_params *param) 1780 { 1781 struct uaudio_softc *sc = addr; 1782 struct chan *ch = &sc->sc_playchan; 1783 usbd_status err; 1784 int i, s; 1785 1786 if (sc->sc_dying) 1787 return (EIO); 1788 1789 DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p " 1790 "blksize=%d\n", sc, start, end, blksize)); 1791 1792 uaudio_chan_set_param(ch, param, start, end, blksize); 1793 DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d " 1794 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 1795 ch->fraction)); 1796 1797 err = uaudio_chan_alloc_buffers(sc, ch); 1798 if (err) 1799 return (EIO); 1800 1801 err = uaudio_chan_open(sc, ch); 1802 if (err) { 1803 uaudio_chan_free_buffers(sc, ch); 1804 return (EIO); 1805 } 1806 1807 ch->intr = intr; 1808 ch->arg = arg; 1809 1810 s = splusb(); 1811 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */ 1812 uaudio_chan_ptransfer(ch); 1813 splx(s); 1814 1815 return (0); 1816 } 1817 1818 /* Set up a pipe for a channel. */ 1819 usbd_status 1820 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch) 1821 { 1822 struct as_info *as = &sc->sc_alts[ch->altidx]; 1823 int endpt = as->edesc->bEndpointAddress; 1824 usbd_status err; 1825 1826 DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n", 1827 endpt, ch->sample_rate, as->alt)); 1828 1829 /* Set alternate interface corresponding to the mode. */ 1830 err = usbd_set_interface(as->ifaceh, as->alt); 1831 if (err) 1832 return (err); 1833 1834 /* Some devices do not support this request, so ignore errors. */ 1835 #ifdef UAUDIO_DEBUG 1836 err = uaudio_set_speed(sc, endpt, ch->sample_rate); 1837 if (err) 1838 DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n", 1839 usbd_errstr(err))); 1840 #else 1841 (void)uaudio_set_speed(sc, endpt, ch->sample_rate); 1842 #endif 1843 1844 DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt)); 1845 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe); 1846 return (err); 1847 } 1848 1849 void 1850 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch) 1851 { 1852 struct as_info *as = &sc->sc_alts[ch->altidx]; 1853 1854 if (sc->sc_nullalt >= 0) { 1855 DPRINTF(("uaudio_chan_close: set null alt=%d\n", 1856 sc->sc_nullalt)); 1857 usbd_set_interface(as->ifaceh, sc->sc_nullalt); 1858 } 1859 usbd_abort_pipe(ch->pipe); 1860 usbd_close_pipe(ch->pipe); 1861 } 1862 1863 usbd_status 1864 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch) 1865 { 1866 usbd_xfer_handle xfer; 1867 void *buf; 1868 int i, size; 1869 1870 size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES; 1871 for (i = 0; i < UAUDIO_NCHANBUFS; i++) { 1872 xfer = usbd_alloc_xfer(sc->sc_udev); 1873 if (xfer == 0) 1874 goto bad; 1875 ch->chanbufs[i].xfer = xfer; 1876 buf = usbd_alloc_buffer(xfer, size); 1877 if (buf == 0) { 1878 i++; 1879 goto bad; 1880 } 1881 ch->chanbufs[i].buffer = buf; 1882 ch->chanbufs[i].chan = ch; 1883 } 1884 1885 return (USBD_NORMAL_COMPLETION); 1886 1887 bad: 1888 while (--i >= 0) 1889 /* implicit buffer free */ 1890 usbd_free_xfer(ch->chanbufs[i].xfer); 1891 return (USBD_NOMEM); 1892 } 1893 1894 void 1895 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch) 1896 { 1897 int i; 1898 1899 for (i = 0; i < UAUDIO_NCHANBUFS; i++) 1900 usbd_free_xfer(ch->chanbufs[i].xfer); 1901 } 1902 1903 /* Called at splusb() */ 1904 void 1905 uaudio_chan_ptransfer(struct chan *ch) 1906 { 1907 struct chanbuf *cb; 1908 int i, n, size, residue, total; 1909 1910 if (ch->sc->sc_dying) 1911 return; 1912 1913 /* Pick the next channel buffer. */ 1914 cb = &ch->chanbufs[ch->curchanbuf]; 1915 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 1916 ch->curchanbuf = 0; 1917 1918 /* Compute the size of each frame in the next transfer. */ 1919 residue = ch->residue; 1920 total = 0; 1921 for (i = 0; i < UAUDIO_NFRAMES; i++) { 1922 size = ch->bytes_per_frame; 1923 residue += ch->fraction; 1924 if (residue >= USB_FRAMES_PER_SECOND) { 1925 if ((ch->sc->sc_altflags & UA_NOFRAC) == 0) 1926 size += ch->sample_size; 1927 residue -= USB_FRAMES_PER_SECOND; 1928 } 1929 cb->sizes[i] = size; 1930 total += size; 1931 } 1932 ch->residue = residue; 1933 cb->size = total; 1934 1935 /* 1936 * Transfer data from upper layer buffer to channel buffer, taking 1937 * care of wrapping the upper layer buffer. 1938 */ 1939 n = min(total, ch->end - ch->cur); 1940 memcpy(cb->buffer, ch->cur, n); 1941 ch->cur += n; 1942 if (ch->cur >= ch->end) 1943 ch->cur = ch->start; 1944 if (total > n) { 1945 total -= n; 1946 memcpy(cb->buffer + n, ch->cur, total); 1947 ch->cur += total; 1948 } 1949 1950 #ifdef UAUDIO_DEBUG 1951 if (uaudiodebug > 8) { 1952 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n", 1953 cb->buffer, ch->residue)); 1954 for (i = 0; i < UAUDIO_NFRAMES; i++) { 1955 DPRINTF((" [%d] length %d\n", i, cb->sizes[i])); 1956 } 1957 } 1958 #endif 1959 1960 DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer)); 1961 /* Fill the request */ 1962 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, 1963 UAUDIO_NFRAMES, USBD_NO_COPY, 1964 uaudio_chan_pintr); 1965 1966 (void)usbd_transfer(cb->xfer); 1967 } 1968 1969 void 1970 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv, 1971 usbd_status status) 1972 { 1973 struct chanbuf *cb = priv; 1974 struct chan *ch = cb->chan; 1975 u_int32_t count; 1976 int s; 1977 1978 /* Return if we are aborting. */ 1979 if (status == USBD_CANCELLED) 1980 return; 1981 1982 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 1983 DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n", 1984 count, ch->transferred)); 1985 #ifdef DIAGNOSTIC 1986 if (count != cb->size) { 1987 printf("uaudio_chan_pintr: count(%d) != size(%d)\n", 1988 count, cb->size); 1989 } 1990 #endif 1991 1992 ch->transferred += cb->size; 1993 s = splaudio(); 1994 /* Call back to upper layer */ 1995 while (ch->transferred >= ch->blksize) { 1996 ch->transferred -= ch->blksize; 1997 DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n", 1998 ch->intr, ch->arg)); 1999 ch->intr(ch->arg); 2000 } 2001 splx(s); 2002 2003 /* start next transfer */ 2004 uaudio_chan_ptransfer(ch); 2005 } 2006 2007 /* Called at splusb() */ 2008 void 2009 uaudio_chan_rtransfer(struct chan *ch) 2010 { 2011 struct chanbuf *cb; 2012 int i, size, residue, total; 2013 2014 if (ch->sc->sc_dying) 2015 return; 2016 2017 /* Pick the next channel buffer. */ 2018 cb = &ch->chanbufs[ch->curchanbuf]; 2019 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 2020 ch->curchanbuf = 0; 2021 2022 /* Compute the size of each frame in the next transfer. */ 2023 residue = ch->residue; 2024 total = 0; 2025 for (i = 0; i < UAUDIO_NFRAMES; i++) { 2026 size = ch->bytes_per_frame; 2027 residue += ch->fraction; 2028 if (residue >= USB_FRAMES_PER_SECOND) { 2029 if ((ch->sc->sc_altflags & UA_NOFRAC) == 0) 2030 size += ch->sample_size; 2031 residue -= USB_FRAMES_PER_SECOND; 2032 } 2033 cb->sizes[i] = size; 2034 total += size; 2035 } 2036 ch->residue = residue; 2037 cb->size = total; 2038 2039 #ifdef UAUDIO_DEBUG 2040 if (uaudiodebug > 8) { 2041 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n", 2042 cb->buffer, ch->residue)); 2043 for (i = 0; i < UAUDIO_NFRAMES; i++) { 2044 DPRINTF((" [%d] length %d\n", i, cb->sizes[i])); 2045 } 2046 } 2047 #endif 2048 2049 DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer)); 2050 /* Fill the request */ 2051 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, 2052 UAUDIO_NFRAMES, USBD_NO_COPY, 2053 uaudio_chan_rintr); 2054 2055 (void)usbd_transfer(cb->xfer); 2056 } 2057 2058 void 2059 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv, 2060 usbd_status status) 2061 { 2062 struct chanbuf *cb = priv; 2063 struct chan *ch = cb->chan; 2064 u_int32_t count; 2065 int s, n; 2066 2067 /* Return if we are aborting. */ 2068 if (status == USBD_CANCELLED) 2069 return; 2070 2071 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 2072 DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n", 2073 count, ch->transferred)); 2074 2075 if (count < cb->size) { 2076 /* if the device fails to keep up, copy last byte */ 2077 u_char b = count ? cb->buffer[count-1] : 0; 2078 while (count < cb->size) 2079 cb->buffer[count++] = b; 2080 } 2081 2082 #ifdef DIAGNOSTIC 2083 if (count != cb->size) { 2084 printf("uaudio_chan_rintr: count(%d) != size(%d)\n", 2085 count, cb->size); 2086 } 2087 #endif 2088 2089 /* 2090 * Transfer data from channel buffer to upper layer buffer, taking 2091 * care of wrapping the upper layer buffer. 2092 */ 2093 n = min(count, ch->end - ch->cur); 2094 memcpy(ch->cur, cb->buffer, n); 2095 ch->cur += n; 2096 if (ch->cur >= ch->end) 2097 ch->cur = ch->start; 2098 if (count > n) { 2099 memcpy(ch->cur, cb->buffer + n, count - n); 2100 ch->cur += count - n; 2101 } 2102 2103 /* Call back to upper layer */ 2104 ch->transferred += cb->size; 2105 s = splaudio(); 2106 while (ch->transferred >= ch->blksize) { 2107 ch->transferred -= ch->blksize; 2108 DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n", 2109 ch->intr, ch->arg)); 2110 ch->intr(ch->arg); 2111 } 2112 splx(s); 2113 2114 /* start next transfer */ 2115 uaudio_chan_rtransfer(ch); 2116 } 2117 2118 void 2119 uaudio_chan_set_param(struct chan *ch, struct audio_params *param, 2120 u_char *start, u_char *end, int blksize) 2121 { 2122 int samples_per_frame, sample_size; 2123 2124 sample_size = param->precision * param->factor * param->channels / 8; 2125 samples_per_frame = param->sample_rate / USB_FRAMES_PER_SECOND; 2126 ch->fraction = param->sample_rate % USB_FRAMES_PER_SECOND; 2127 ch->sample_size = sample_size; 2128 ch->sample_rate = param->sample_rate; 2129 ch->bytes_per_frame = samples_per_frame * sample_size; 2130 ch->residue = 0; 2131 2132 ch->start = start; 2133 ch->end = end; 2134 ch->cur = start; 2135 ch->blksize = blksize; 2136 ch->transferred = 0; 2137 2138 ch->curchanbuf = 0; 2139 } 2140 2141 int 2142 uaudio_set_params(void *addr, int setmode, int usemode, 2143 struct audio_params *play, struct audio_params *rec) 2144 { 2145 struct uaudio_softc *sc = addr; 2146 int flags = sc->sc_altflags; 2147 int factor, precision; 2148 int enc, i, j; 2149 int paltidx=-1, raltidx=-1; 2150 void (*swcode)(void *, u_char *buf, int cnt); 2151 struct audio_params *p; 2152 int mode; 2153 2154 if (sc->sc_dying) 2155 return (EIO); 2156 2157 if ((mode == AUMODE_RECORD && sc->sc_recchan.pipe != NULL) 2158 || (mode == AUMODE_PLAY && sc->sc_playchan.pipe != NULL)) 2159 return (EBUSY); 2160 2161 if (usemode & AUMODE_PLAY && sc->sc_playchan.altidx != -1) 2162 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0; 2163 if (usemode & AUMODE_RECORD && sc->sc_recchan.altidx != -1) 2164 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0; 2165 2166 for (mode = AUMODE_RECORD; mode != -1; 2167 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 2168 if ((setmode & mode) == 0) 2169 continue; 2170 2171 if ((sc->sc_mode & mode) == 0) 2172 continue; 2173 2174 p = (mode == AUMODE_PLAY) ? play : rec; 2175 2176 factor = 1; 2177 swcode = 0; 2178 enc = p->encoding; 2179 precision = p->precision; 2180 switch (enc) { 2181 case AUDIO_ENCODING_SLINEAR_BE: 2182 if (p->precision == 16) { 2183 swcode = swap_bytes; 2184 enc = AUDIO_ENCODING_SLINEAR_LE; 2185 } else if (p->precision == 8 && !(flags & HAS_8)) { 2186 swcode = change_sign8; 2187 enc = AUDIO_ENCODING_ULINEAR_LE; 2188 } 2189 break; 2190 case AUDIO_ENCODING_SLINEAR_LE: 2191 if (p->precision == 8 && !(flags & HAS_8)) { 2192 swcode = change_sign8; 2193 enc = AUDIO_ENCODING_ULINEAR_LE; 2194 } 2195 break; 2196 case AUDIO_ENCODING_ULINEAR_BE: 2197 if (p->precision == 16) { 2198 if (mode == AUMODE_PLAY) 2199 swcode = swap_bytes_change_sign16_le; 2200 else 2201 swcode = change_sign16_swap_bytes_le; 2202 enc = AUDIO_ENCODING_SLINEAR_LE; 2203 } else if (p->precision == 8 && !(flags & HAS_8U)) { 2204 swcode = change_sign8; 2205 enc = AUDIO_ENCODING_SLINEAR_LE; 2206 } 2207 break; 2208 case AUDIO_ENCODING_ULINEAR_LE: 2209 if (p->precision == 16) { 2210 swcode = change_sign16_le; 2211 enc = AUDIO_ENCODING_SLINEAR_LE; 2212 } else if (p->precision == 8 && !(flags & HAS_8U)) { 2213 swcode = change_sign8; 2214 enc = AUDIO_ENCODING_SLINEAR_LE; 2215 } 2216 break; 2217 case AUDIO_ENCODING_ULAW: 2218 if (flags & HAS_MULAW) 2219 break; 2220 if (flags & HAS_16) { 2221 if (mode == AUMODE_PLAY) 2222 swcode = mulaw_to_slinear16_le; 2223 else 2224 swcode = slinear16_to_mulaw_le; 2225 factor = 2; 2226 enc = AUDIO_ENCODING_SLINEAR_LE; 2227 precision = 16; 2228 } else if (flags & HAS_8U) { 2229 if (mode == AUMODE_PLAY) 2230 swcode = mulaw_to_ulinear8; 2231 else 2232 swcode = ulinear8_to_mulaw; 2233 enc = AUDIO_ENCODING_ULINEAR_LE; 2234 } else if (flags & HAS_8) { 2235 if (mode == AUMODE_PLAY) 2236 swcode = mulaw_to_slinear8; 2237 else 2238 swcode = slinear8_to_mulaw; 2239 enc = AUDIO_ENCODING_SLINEAR_LE; 2240 } else 2241 return (EINVAL); 2242 break; 2243 case AUDIO_ENCODING_ALAW: 2244 if (flags & HAS_ALAW) 2245 break; 2246 if (mode == AUMODE_PLAY && (flags & HAS_16)) { 2247 swcode = alaw_to_slinear16_le; 2248 factor = 2; 2249 enc = AUDIO_ENCODING_SLINEAR_LE; 2250 precision = 16; 2251 } else if (flags & HAS_8U) { 2252 if (mode == AUMODE_PLAY) 2253 swcode = alaw_to_ulinear8; 2254 else 2255 swcode = ulinear8_to_alaw; 2256 enc = AUDIO_ENCODING_ULINEAR_LE; 2257 } else if (flags & HAS_8) { 2258 if (mode == AUMODE_PLAY) 2259 swcode = alaw_to_slinear8; 2260 else 2261 swcode = slinear8_to_alaw; 2262 enc = AUDIO_ENCODING_SLINEAR_LE; 2263 } else 2264 return (EINVAL); 2265 break; 2266 default: 2267 return (EINVAL); 2268 } 2269 /* XXX do some other conversions... */ 2270 2271 DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n", 2272 p->channels, p->precision, enc, p->sample_rate)); 2273 2274 for (i = 0; i < sc->sc_nalts; i++) { 2275 struct usb_audio_streaming_type1_descriptor *a1d = 2276 sc->sc_alts[i].asf1desc; 2277 if (sc->sc_alts[i].sc_busy) 2278 continue; 2279 2280 if (p->channels == a1d->bNrChannels && 2281 precision == a1d->bBitResolution && 2282 enc == sc->sc_alts[i].encoding && 2283 (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) == 2284 UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) { 2285 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 2286 DPRINTFN(2,("uaudio_set_params: cont %d-%d\n", 2287 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d))); 2288 if (UA_SAMP_LO(a1d) < p->sample_rate && 2289 p->sample_rate < UA_SAMP_HI(a1d)) 2290 goto found; 2291 } else { 2292 for (j = 0; j < a1d->bSamFreqType; j++) { 2293 DPRINTFN(2,("uaudio_set_params: disc #" 2294 "%d: %d\n", j, UA_GETSAMP(a1d, j))); 2295 /* XXX allow for some slack */ 2296 if (UA_GETSAMP(a1d, j) == 2297 p->sample_rate) 2298 goto found; 2299 } 2300 } 2301 } 2302 } 2303 return (EINVAL); 2304 2305 found: 2306 p->sw_code = swcode; 2307 p->factor = factor; 2308 if (usemode & mode) { 2309 if (mode == AUMODE_PLAY) { 2310 paltidx = i; 2311 sc->sc_alts[i].sc_busy = 1; 2312 } else { 2313 raltidx = i; 2314 sc->sc_alts[i].sc_busy = 1; 2315 } 2316 } 2317 } 2318 2319 if ((usemode & AUMODE_PLAY) && paltidx != sc->sc_playchan.altidx) { 2320 /* XXX abort transfer if currently happening? */ 2321 sc->sc_playchan.altidx = paltidx; 2322 } 2323 if ((usemode & AUMODE_RECORD) && raltidx != sc->sc_recchan.altidx) { 2324 /* XXX abort transfer if currently happening? */ 2325 sc->sc_recchan.altidx = raltidx; 2326 } 2327 2328 DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n", 2329 sc->sc_playchan.altidx, sc->sc_recchan.altidx, 2330 (sc->sc_playchan.altidx >= 0) 2331 ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting 2332 : -1, 2333 (sc->sc_recchan.altidx >= 0) 2334 ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting 2335 : -1)); 2336 2337 return (0); 2338 } 2339 2340 usbd_status 2341 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed) 2342 { 2343 usb_device_request_t req; 2344 u_int8_t data[3]; 2345 2346 DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed)); 2347 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT; 2348 req.bRequest = SET_CUR; 2349 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0); 2350 USETW(req.wIndex, endpt); 2351 USETW(req.wLength, 3); 2352 data[0] = speed; 2353 data[1] = speed >> 8; 2354 data[2] = speed >> 16; 2355 2356 return (usbd_do_request(sc->sc_udev, &req, data)); 2357 } 2358 2359