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