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