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