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