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