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