1 /* $OpenBSD: uaudio.c,v 1.92 2011/07/03 15:47:17 matthew Exp $ */ 2 /* $NetBSD: uaudio.c,v 1.90 2004/10/29 17:12:53 kent Exp $ */ 3 4 /* 5 * Copyright (c) 1999 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Lennart Augustsson (lennart@augustsson.net) at 10 * Carlstedt Research & Technology. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf 36 * http://www.usb.org/developers/devclass_docs/frmts10.pdf 37 * http://www.usb.org/developers/devclass_docs/termt10.pdf 38 */ 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/kernel.h> 43 #include <sys/malloc.h> 44 #include <sys/device.h> 45 #include <sys/ioctl.h> 46 #include <sys/tty.h> 47 #include <sys/file.h> 48 #include <sys/reboot.h> /* for bootverbose */ 49 #include <sys/selinfo.h> 50 #include <sys/proc.h> 51 #include <sys/vnode.h> 52 #include <sys/device.h> 53 #include <sys/poll.h> 54 55 #include <machine/bus.h> 56 57 #include <sys/audioio.h> 58 #include <dev/audio_if.h> 59 #include <dev/mulaw.h> 60 #include <dev/auconv.h> 61 62 #include <dev/usb/usb.h> 63 #include <dev/usb/usbdevs.h> 64 #include <dev/usb/usbdi.h> 65 #include <dev/usb/usbdi_util.h> 66 #include <dev/usb/usbdivar.h> 67 68 #include <dev/usb/uaudioreg.h> 69 70 /* #define UAUDIO_DEBUG */ 71 #ifdef UAUDIO_DEBUG 72 #define DPRINTF(x) do { if (uaudiodebug) printf x; } while (0) 73 #define DPRINTFN(n,x) do { if (uaudiodebug>(n)) printf x; } while (0) 74 int uaudiodebug = 0; 75 #else 76 #define DPRINTF(x) 77 #define DPRINTFN(n,x) 78 #endif 79 80 #define UAUDIO_NCHANBUFS 3 /* number of outstanding request */ 81 #define UAUDIO_MIN_FRAMES 2 /* ms of sound in each request */ 82 #define UAUDIO_MAX_FRAMES 16 83 #define UAUDIO_NSYNCBUFS 3 /* number of outstanding sync requests */ 84 85 #define UAUDIO_MAX_ALTS 32 /* max alt settings allowed by driver */ 86 87 #define MIX_MAX_CHAN 8 88 struct mixerctl { 89 u_int16_t wValue[MIX_MAX_CHAN]; /* using nchan */ 90 u_int16_t wIndex; 91 u_int8_t nchan; 92 u_int8_t type; 93 #define MIX_ON_OFF 1 94 #define MIX_SIGNED_16 2 95 #define MIX_UNSIGNED_16 3 96 #define MIX_SIGNED_8 4 97 #define MIX_SELECTOR 5 98 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1) 99 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16) 100 int minval, maxval; 101 u_int delta; 102 u_int8_t class; 103 char ctlname[MAX_AUDIO_DEV_LEN]; 104 char *ctlunit; 105 }; 106 #define MAKE(h,l) (((h) << 8) | (l)) 107 108 struct as_info { 109 u_int8_t alt; 110 u_int8_t encoding; 111 u_int8_t attributes; /* Copy of bmAttributes of 112 * usb_audio_streaming_endpoint_descriptor 113 */ 114 usbd_interface_handle ifaceh; 115 const usb_interface_descriptor_t *idesc; 116 const usb_endpoint_descriptor_audio_t *edesc; 117 const usb_endpoint_descriptor_audio_t *edesc1; 118 const struct usb_audio_streaming_type1_descriptor *asf1desc; 119 int sc_busy; /* currently used */ 120 }; 121 122 struct chan { 123 void (*intr)(void *); /* DMA completion intr handler */ 124 void *arg; /* arg for intr() */ 125 usbd_pipe_handle pipe; 126 usbd_pipe_handle sync_pipe; 127 128 u_int sample_size; 129 u_int sample_rate; 130 u_int bytes_per_frame; 131 u_int max_bytes_per_frame; 132 u_int fraction; /* fraction/frac_denom is the extra samples/frame */ 133 u_int frac_denom; /* denominator for fractional samples */ 134 u_int residue; /* accumulates the fractional samples */ 135 u_int nframes; /* # of frames per transfer */ 136 u_int nsync_frames; /* # of frames per sync transfer */ 137 u_int usb_fps; 138 u_int maxpktsize; 139 u_int reqms; /* usb request data duration, in ms */ 140 u_int hi_speed; 141 142 u_char *start; /* upper layer buffer start */ 143 u_char *end; /* upper layer buffer end */ 144 u_char *cur; /* current position in upper layer buffer */ 145 int blksize; /* chunk size to report up */ 146 int transferred; /* transferred bytes not reported up */ 147 148 int altidx; /* currently used altidx */ 149 150 int curchanbuf; 151 int cursyncbuf; 152 153 struct chanbuf { 154 struct chan *chan; 155 usbd_xfer_handle xfer; 156 u_char *buffer; 157 u_int16_t sizes[UAUDIO_MAX_FRAMES]; 158 u_int16_t offsets[UAUDIO_MAX_FRAMES]; 159 u_int16_t size; 160 } chanbufs[UAUDIO_NCHANBUFS]; 161 162 struct syncbuf { 163 struct chan *chan; 164 usbd_xfer_handle xfer; 165 u_char *buffer; 166 u_int16_t sizes[UAUDIO_MAX_FRAMES]; 167 u_int16_t offsets[UAUDIO_MAX_FRAMES]; 168 u_int16_t size; 169 } syncbufs[UAUDIO_NSYNCBUFS]; 170 171 struct uaudio_softc *sc; /* our softc */ 172 }; 173 174 #define UAUDIO_FLAG_BAD_AUDIO 0x0001 /* claims audio class, but isn't */ 175 #define UAUDIO_FLAG_NO_FRAC 0x0002 /* don't use fractional samples */ 176 #define UAUDIO_FLAG_NO_XU 0x0004 /* has broken extension unit */ 177 #define UAUDIO_FLAG_BAD_ADC 0x0008 /* bad audio spec version number */ 178 #define UAUDIO_FLAG_VENDOR_CLASS 0x0010 /* claims vendor class but works */ 179 #define UAUDIO_FLAG_DEPENDENT 0x0020 /* play and record params must equal */ 180 #define UAUDIO_FLAG_EMU0202 0x0040 181 182 struct uaudio_devs { 183 struct usb_devno uv_dev; 184 int flags; 185 } uaudio_devs[] = { 186 { { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70 }, 187 UAUDIO_FLAG_BAD_ADC } , 188 { { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495 }, 189 UAUDIO_FLAG_BAD_AUDIO }, 190 { { USB_VENDOR_CREATIVE, USB_PRODUCT_CREATIVE_EMU0202 }, 191 UAUDIO_FLAG_VENDOR_CLASS | UAUDIO_FLAG_EMU0202 | 192 UAUDIO_FLAG_DEPENDENT }, 193 { { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502 }, 194 UAUDIO_FLAG_NO_XU | UAUDIO_FLAG_BAD_ADC }, 195 { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMNBDLX }, 196 UAUDIO_FLAG_BAD_AUDIO }, 197 { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRONB }, 198 UAUDIO_FLAG_BAD_AUDIO }, 199 { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO4K }, 200 UAUDIO_FLAG_BAD_AUDIO }, 201 { { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMZOOM }, 202 UAUDIO_FLAG_BAD_AUDIO }, 203 { { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1 }, 204 UAUDIO_FLAG_NO_FRAC } 205 }; 206 #define uaudio_lookup(v, p) \ 207 ((struct uaudio_devs *)usb_lookup(uaudio_devs, v, p)) 208 209 struct uaudio_softc { 210 struct device sc_dev; /* base device */ 211 usbd_device_handle sc_udev; /* USB device */ 212 int sc_ac_iface; /* Audio Control interface */ 213 struct chan sc_playchan; /* play channel */ 214 struct chan sc_recchan; /* record channel */ 215 int sc_nullalt; 216 int sc_audio_rev; 217 struct as_info *sc_alts; /* alternate settings */ 218 int sc_nalts; /* # of alternate settings */ 219 int sc_altflags; 220 #define HAS_8 0x01 221 #define HAS_16 0x02 222 #define HAS_8U 0x04 223 #define HAS_ALAW 0x08 224 #define HAS_MULAW 0x10 225 #define UA_NOFRAC 0x20 /* don't do sample rate adjustment */ 226 #define HAS_24 0x40 227 int sc_mode; /* play/record capability */ 228 struct audio_encoding *sc_encs; 229 int sc_nencs; 230 struct mixerctl *sc_ctls; /* mixer controls */ 231 int sc_nctls; /* # of mixer controls */ 232 struct device *sc_audiodev; 233 char sc_dying; 234 int sc_quirks; 235 }; 236 237 struct terminal_list { 238 int size; 239 uint16_t terminals[1]; 240 }; 241 #define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \ 242 + sizeof(uint16_t) * (N)) 243 244 struct io_terminal { 245 union { 246 const usb_descriptor_t *desc; 247 const struct usb_audio_input_terminal *it; 248 const struct usb_audio_output_terminal *ot; 249 const struct usb_audio_mixer_unit *mu; 250 const struct usb_audio_selector_unit *su; 251 const struct usb_audio_feature_unit *fu; 252 const struct usb_audio_processing_unit *pu; 253 const struct usb_audio_extension_unit *eu; 254 } d; 255 int inputs_size; 256 struct terminal_list **inputs; /* list of source input terminals */ 257 struct terminal_list *output; /* list of destination output terminals */ 258 int direct; /* directly connected to an output terminal */ 259 }; 260 261 #define UAC_OUTPUT 0 262 #define UAC_INPUT 1 263 #define UAC_EQUAL 2 264 #define UAC_RECORD 3 265 #define UAC_NCLASSES 4 266 #ifdef UAUDIO_DEBUG 267 const char *uac_names[] = { 268 AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord, 269 }; 270 #endif 271 272 usbd_status uaudio_identify_ac 273 (struct uaudio_softc *, const usb_config_descriptor_t *); 274 usbd_status uaudio_identify_as 275 (struct uaudio_softc *, const usb_config_descriptor_t *); 276 usbd_status uaudio_process_as 277 (struct uaudio_softc *, const char *, int *, int, 278 const usb_interface_descriptor_t *); 279 280 void uaudio_add_alt(struct uaudio_softc *, const struct as_info *); 281 282 void uaudio_create_encodings(struct uaudio_softc *); 283 284 const usb_interface_descriptor_t *uaudio_find_iface 285 (const char *, int, int *, int, int); 286 287 void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *); 288 char *uaudio_id_name 289 (struct uaudio_softc *, const struct io_terminal *, int); 290 uByte uaudio_get_cluster_nchan 291 (int, const struct io_terminal *); 292 void uaudio_add_input 293 (struct uaudio_softc *, const struct io_terminal *, int); 294 void uaudio_add_output 295 (struct uaudio_softc *, const struct io_terminal *, int); 296 void uaudio_add_mixer 297 (struct uaudio_softc *, const struct io_terminal *, int); 298 void uaudio_add_selector 299 (struct uaudio_softc *, const struct io_terminal *, int); 300 #ifdef UAUDIO_DEBUG 301 const char *uaudio_get_terminal_name(int); 302 #endif 303 int uaudio_determine_class 304 (const struct io_terminal *, struct mixerctl *); 305 const char *uaudio_feature_name 306 (const struct io_terminal *, struct mixerctl *); 307 void uaudio_add_feature 308 (struct uaudio_softc *, const struct io_terminal *, int); 309 void uaudio_add_processing_updown 310 (struct uaudio_softc *, const struct io_terminal *, int); 311 void uaudio_add_processing 312 (struct uaudio_softc *, const struct io_terminal *, int); 313 void uaudio_add_extension 314 (struct uaudio_softc *, const struct io_terminal *, int); 315 struct terminal_list *uaudio_merge_terminal_list 316 (const struct io_terminal *); 317 struct terminal_list *uaudio_io_terminaltype 318 (int, struct io_terminal *, int); 319 usbd_status uaudio_identify 320 (struct uaudio_softc *, const usb_config_descriptor_t *); 321 322 int uaudio_signext(int, int); 323 int uaudio_unsignext(int, int); 324 int uaudio_value2bsd(struct mixerctl *, int); 325 int uaudio_bsd2value(struct mixerctl *, int); 326 int uaudio_get(struct uaudio_softc *, int, int, int, int, int); 327 int uaudio_ctl_get 328 (struct uaudio_softc *, int, struct mixerctl *, int); 329 void uaudio_set 330 (struct uaudio_softc *, int, int, int, int, int, int); 331 void uaudio_ctl_set 332 (struct uaudio_softc *, int, struct mixerctl *, int, int); 333 334 usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int); 335 void uaudio_set_speed_emu0202(struct chan *ch); 336 337 usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *); 338 void uaudio_chan_close(struct uaudio_softc *, struct chan *); 339 usbd_status uaudio_chan_alloc_buffers 340 (struct uaudio_softc *, struct chan *); 341 void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *); 342 void uaudio_chan_init 343 (struct chan *, int, int, const struct audio_params *); 344 void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int); 345 void uaudio_chan_ptransfer(struct chan *); 346 void uaudio_chan_pintr 347 (usbd_xfer_handle, usbd_private_handle, usbd_status); 348 void uaudio_chan_psync_transfer(struct chan *); 349 void uaudio_chan_psync_intr 350 (usbd_xfer_handle, usbd_private_handle, usbd_status); 351 352 void uaudio_chan_rtransfer(struct chan *); 353 void uaudio_chan_rintr 354 (usbd_xfer_handle, usbd_private_handle, usbd_status); 355 356 int uaudio_open(void *, int); 357 void uaudio_close(void *); 358 int uaudio_drain(void *); 359 int uaudio_query_encoding(void *, struct audio_encoding *); 360 void uaudio_get_minmax_rates 361 (int, const struct as_info *, const struct audio_params *, 362 int, int, int, u_long *, u_long *); 363 int uaudio_match_alt_rate(void *, int, int); 364 int uaudio_match_alt(void *, struct audio_params *, int); 365 int uaudio_set_params 366 (void *, int, int, struct audio_params *, struct audio_params *); 367 int uaudio_round_blocksize(void *, int); 368 int uaudio_trigger_output 369 (void *, void *, void *, int, void (*)(void *), void *, 370 struct audio_params *); 371 int uaudio_trigger_input 372 (void *, void *, void *, int, void (*)(void *), void *, 373 struct audio_params *); 374 int uaudio_halt_in_dma(void *); 375 int uaudio_halt_out_dma(void *); 376 int uaudio_getdev(void *, struct audio_device *); 377 int uaudio_mixer_set_port(void *, mixer_ctrl_t *); 378 int uaudio_mixer_get_port(void *, mixer_ctrl_t *); 379 int uaudio_query_devinfo(void *, mixer_devinfo_t *); 380 int uaudio_get_props(void *); 381 void uaudio_get_default_params(void *, int, struct audio_params *); 382 383 struct audio_hw_if uaudio_hw_if = { 384 uaudio_open, 385 uaudio_close, 386 uaudio_drain, 387 uaudio_query_encoding, 388 uaudio_set_params, 389 uaudio_round_blocksize, 390 NULL, 391 NULL, 392 NULL, 393 NULL, 394 NULL, 395 uaudio_halt_out_dma, 396 uaudio_halt_in_dma, 397 NULL, 398 uaudio_getdev, 399 NULL, 400 uaudio_mixer_set_port, 401 uaudio_mixer_get_port, 402 uaudio_query_devinfo, 403 NULL, 404 NULL, 405 NULL, 406 NULL, 407 uaudio_get_props, 408 uaudio_trigger_output, 409 uaudio_trigger_input, 410 uaudio_get_default_params 411 }; 412 413 struct audio_device uaudio_device = { 414 "USB audio", 415 "", 416 "uaudio" 417 }; 418 419 int uaudio_match(struct device *, void *, void *); 420 void uaudio_attach(struct device *, struct device *, void *); 421 int uaudio_detach(struct device *, int); 422 int uaudio_activate(struct device *, int); 423 424 struct cfdriver uaudio_cd = { 425 NULL, "uaudio", DV_DULL 426 }; 427 428 const struct cfattach uaudio_ca = { 429 sizeof(struct uaudio_softc), 430 uaudio_match, 431 uaudio_attach, 432 uaudio_detach, 433 uaudio_activate, 434 }; 435 436 int 437 uaudio_match(struct device *parent, void *match, void *aux) 438 { 439 struct usb_attach_arg *uaa = aux; 440 usb_interface_descriptor_t *id; 441 const usb_interface_descriptor_t *cd_id; 442 usb_config_descriptor_t *cdesc; 443 struct uaudio_devs *quirk; 444 const char *buf; 445 int flags = 0, size, offs; 446 447 if (uaa->iface == NULL || uaa->device == NULL) 448 return (UMATCH_NONE); 449 450 quirk = uaudio_lookup(uaa->vendor, uaa->product); 451 if (quirk) 452 flags = quirk->flags; 453 454 if (flags & UAUDIO_FLAG_BAD_AUDIO) 455 return (UMATCH_NONE); 456 457 id = usbd_get_interface_descriptor(uaa->iface); 458 if (id == NULL) 459 return (UMATCH_NONE); 460 461 if (!(id->bInterfaceClass == UICLASS_AUDIO || 462 ((flags & UAUDIO_FLAG_VENDOR_CLASS) && 463 id->bInterfaceClass == UICLASS_VENDOR))) 464 return (UMATCH_NONE); 465 466 if (id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL) 467 return (UMATCH_NONE); 468 469 cdesc = usbd_get_config_descriptor(uaa->device); 470 if (cdesc == NULL) 471 return (UMATCH_NONE); 472 473 size = UGETW(cdesc->wTotalLength); 474 buf = (const char *)cdesc; 475 476 offs = 0; 477 cd_id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM, 478 flags); 479 if (cd_id == NULL) 480 return (UMATCH_NONE); 481 482 offs = 0; 483 cd_id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL, 484 flags); 485 if (cd_id == NULL) 486 return (UMATCH_NONE); 487 488 return (UMATCH_VENDOR_PRODUCT_CONF_IFACE); 489 } 490 491 void 492 uaudio_attach(struct device *parent, struct device *self, void *aux) 493 { 494 struct uaudio_softc *sc = (struct uaudio_softc *)self; 495 struct usb_attach_arg *uaa = aux; 496 struct uaudio_devs *quirk; 497 usb_interface_descriptor_t *id; 498 usb_config_descriptor_t *cdesc; 499 usbd_status err; 500 int i, j, found; 501 502 sc->sc_udev = uaa->device; 503 504 quirk = uaudio_lookup(uaa->vendor, uaa->product); 505 if (quirk) 506 sc->sc_quirks = quirk->flags; 507 508 cdesc = usbd_get_config_descriptor(sc->sc_udev); 509 if (cdesc == NULL) { 510 printf("%s: failed to get configuration descriptor\n", 511 sc->sc_dev.dv_xname); 512 return; 513 } 514 515 err = uaudio_identify(sc, cdesc); 516 if (err) { 517 printf("%s: audio descriptors make no sense, error=%d\n", 518 sc->sc_dev.dv_xname, err); 519 return; 520 } 521 522 /* Pick up the AS interface. */ 523 for (i = 0; i < uaa->nifaces; i++) { 524 if (usbd_iface_claimed(sc->sc_udev, i)) 525 continue; 526 id = usbd_get_interface_descriptor(uaa->ifaces[i]); 527 if (id == NULL) 528 continue; 529 found = 0; 530 for (j = 0; j < sc->sc_nalts; j++) { 531 if (id->bInterfaceNumber == 532 sc->sc_alts[j].idesc->bInterfaceNumber) { 533 sc->sc_alts[j].ifaceh = uaa->ifaces[i]; 534 found = 1; 535 } 536 } 537 if (found) 538 usbd_claim_iface(sc->sc_udev, i); 539 } 540 541 for (j = 0; j < sc->sc_nalts; j++) { 542 if (sc->sc_alts[j].ifaceh == NULL) { 543 printf("%s: alt %d missing AS interface(s)\n", 544 sc->sc_dev.dv_xname, j); 545 return; 546 } 547 } 548 549 printf("%s: audio rev %d.%02x", sc->sc_dev.dv_xname, 550 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff); 551 552 sc->sc_playchan.sc = sc->sc_recchan.sc = sc; 553 sc->sc_playchan.altidx = -1; 554 sc->sc_recchan.altidx = -1; 555 556 if (sc->sc_quirks & UAUDIO_FLAG_NO_FRAC) 557 sc->sc_altflags |= UA_NOFRAC; 558 559 printf(", %d mixer controls\n", sc->sc_nctls); 560 561 uaudio_create_encodings(sc); 562 563 DPRINTF(("uaudio_attach: doing audio_attach_mi\n")); 564 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); 565 } 566 567 int 568 uaudio_activate(struct device *self, int act) 569 { 570 struct uaudio_softc *sc = (struct uaudio_softc *)self; 571 int rv = 0; 572 573 switch (act) { 574 case DVACT_DEACTIVATE: 575 if (sc->sc_audiodev != NULL) 576 rv = config_deactivate(sc->sc_audiodev); 577 sc->sc_dying = 1; 578 break; 579 } 580 return (rv); 581 } 582 583 int 584 uaudio_detach(struct device *self, int flags) 585 { 586 struct uaudio_softc *sc = (struct uaudio_softc *)self; 587 int rv = 0; 588 589 /* 590 * sc_alts may be NULL if uaudio_identify_as() failed, in 591 * which case uaudio_attach() didn't finish and there's 592 * nothing to detach. 593 */ 594 if (sc->sc_alts == NULL) 595 return (rv); 596 597 /* Wait for outstanding requests to complete. */ 598 uaudio_drain(sc); 599 600 if (sc->sc_audiodev != NULL) 601 rv = config_detach(sc->sc_audiodev, flags); 602 603 return (rv); 604 } 605 606 int 607 uaudio_query_encoding(void *addr, struct audio_encoding *fp) 608 { 609 struct uaudio_softc *sc = addr; 610 611 if (sc->sc_dying) 612 return (EIO); 613 614 if (sc->sc_nalts == 0 || sc->sc_altflags == 0) 615 return (ENXIO); 616 617 if (fp->index < 0 || fp->index >= sc->sc_nencs) 618 return (EINVAL); 619 620 *fp = sc->sc_encs[fp->index]; 621 622 return (0); 623 } 624 625 const usb_interface_descriptor_t * 626 uaudio_find_iface(const char *buf, int size, int *offsp, int subtype, int flags) 627 { 628 const usb_interface_descriptor_t *d; 629 630 while (*offsp < size) { 631 d = (const void *)(buf + *offsp); 632 *offsp += d->bLength; 633 if (d->bDescriptorType == UDESC_INTERFACE && 634 d->bInterfaceSubClass == subtype && 635 (d->bInterfaceClass == UICLASS_AUDIO || 636 (d->bInterfaceClass == UICLASS_VENDOR && 637 (flags & UAUDIO_FLAG_VENDOR_CLASS)))) 638 return (d); 639 } 640 return (NULL); 641 } 642 643 void 644 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc) 645 { 646 int res, range; 647 size_t len; 648 struct mixerctl *nmc; 649 650 if (mc->class < UAC_NCLASSES) { 651 DPRINTF(("%s: adding %s.%s\n", 652 __func__, uac_names[mc->class], mc->ctlname)); 653 } else { 654 DPRINTF(("%s: adding %s\n", __func__, mc->ctlname)); 655 } 656 len = sizeof(*mc) * (sc->sc_nctls + 1); 657 nmc = malloc(len, M_USBDEV, M_NOWAIT); 658 if (nmc == NULL) { 659 printf("uaudio_mixer_add_ctl: no memory\n"); 660 return; 661 } 662 /* Copy old data, if there was any */ 663 if (sc->sc_nctls != 0) { 664 bcopy(sc->sc_ctls, nmc, sizeof(*mc) * (sc->sc_nctls)); 665 free(sc->sc_ctls, M_USBDEV); 666 } 667 sc->sc_ctls = nmc; 668 669 mc->delta = 0; 670 if (mc->type == MIX_ON_OFF) { 671 mc->minval = 0; 672 mc->maxval = 1; 673 } else if (mc->type == MIX_SELECTOR) { 674 ; 675 } else { 676 /* Determine min and max values. */ 677 mc->minval = uaudio_signext(mc->type, 678 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE, 679 mc->wValue[0], mc->wIndex, 680 MIX_SIZE(mc->type))); 681 mc->maxval = uaudio_signext(mc->type, 682 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE, 683 mc->wValue[0], mc->wIndex, 684 MIX_SIZE(mc->type))); 685 range = mc->maxval - mc->minval; 686 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE, 687 mc->wValue[0], mc->wIndex, 688 MIX_SIZE(mc->type)); 689 if (res > 0 && range > 0) 690 mc->delta = (res * 255 + res - 1) / range; 691 } 692 693 sc->sc_ctls[sc->sc_nctls++] = *mc; 694 695 #ifdef UAUDIO_DEBUG 696 if (uaudiodebug > 2) { 697 int i; 698 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0])); 699 for (i = 1; i < mc->nchan; i++) 700 DPRINTF((",%04x", mc->wValue[i])); 701 DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' " 702 "min=%d max=%d\n", 703 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit, 704 mc->minval, mc->maxval)); 705 } 706 #endif 707 } 708 709 char * 710 uaudio_id_name(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 711 { 712 static char buf[32]; 713 snprintf(buf, sizeof(buf), "i%d", id); 714 return (buf); 715 } 716 717 uByte 718 uaudio_get_cluster_nchan(int id, const struct io_terminal *iot) 719 { 720 struct usb_audio_cluster r; 721 const usb_descriptor_t *dp; 722 int i; 723 724 for (i = 0; i < 25; i++) { /* avoid infinite loops */ 725 dp = iot[id].d.desc; 726 if (dp == 0) 727 goto bad; 728 switch (dp->bDescriptorSubtype) { 729 case UDESCSUB_AC_INPUT: 730 return (iot[id].d.it->bNrChannels); 731 case UDESCSUB_AC_OUTPUT: 732 id = iot[id].d.ot->bSourceId; 733 break; 734 case UDESCSUB_AC_MIXER: 735 r = *(struct usb_audio_cluster *) 736 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins]; 737 return (r.bNrChannels); 738 case UDESCSUB_AC_SELECTOR: 739 /* XXX This is not really right */ 740 id = iot[id].d.su->baSourceId[0]; 741 break; 742 case UDESCSUB_AC_FEATURE: 743 id = iot[id].d.fu->bSourceId; 744 break; 745 case UDESCSUB_AC_PROCESSING: 746 r = *(struct usb_audio_cluster *) 747 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins]; 748 return (r.bNrChannels); 749 case UDESCSUB_AC_EXTENSION: 750 r = *(struct usb_audio_cluster *) 751 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins]; 752 return (r.bNrChannels); 753 default: 754 goto bad; 755 } 756 } 757 bad: 758 printf("uaudio_get_cluster_nchan: bad data\n"); 759 return (0); 760 } 761 762 void 763 uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 764 { 765 #ifdef UAUDIO_DEBUG 766 const struct usb_audio_input_terminal *d = iot[id].d.it; 767 768 DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x " 769 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d " 770 "iChannelNames=%d iTerminal=%d\n", 771 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 772 d->bNrChannels, UGETW(d->wChannelConfig), 773 d->iChannelNames, d->iTerminal)); 774 #endif 775 } 776 777 void 778 uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 779 { 780 #ifdef UAUDIO_DEBUG 781 const struct usb_audio_output_terminal *d = iot[id].d.ot; 782 783 DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x " 784 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n", 785 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal, 786 d->bSourceId, d->iTerminal)); 787 #endif 788 } 789 790 void 791 uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 792 { 793 const struct usb_audio_mixer_unit *d = iot[id].d.mu; 794 struct usb_audio_mixer_unit_1 *d1; 795 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k; 796 uByte *bm; 797 struct mixerctl mix; 798 799 DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n", 800 d->bUnitId, d->bNrInPins)); 801 802 /* Compute the number of input channels */ 803 ichs = 0; 804 for (i = 0; i < d->bNrInPins; i++) 805 ichs += uaudio_get_cluster_nchan(d->baSourceId[i], iot); 806 807 /* and the number of output channels */ 808 d1 = (struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins]; 809 ochs = d1->bNrChannels; 810 DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs)); 811 812 bm = d1->bmControls; 813 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 814 uaudio_determine_class(&iot[id], &mix); 815 mix.type = MIX_SIGNED_16; 816 mix.ctlunit = AudioNvolume; 817 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1) 818 for (p = i = 0; i < d->bNrInPins; i++) { 819 chs = uaudio_get_cluster_nchan(d->baSourceId[i], iot); 820 mc = 0; 821 for (c = 0; c < chs; c++) { 822 mo = 0; 823 for (o = 0; o < ochs; o++) { 824 bno = (p + c) * ochs + o; 825 if (BIT(bno)) 826 mo++; 827 } 828 if (mo == 1) 829 mc++; 830 } 831 if (mc == chs && chs <= MIX_MAX_CHAN) { 832 k = 0; 833 for (c = 0; c < chs; c++) 834 for (o = 0; o < ochs; o++) { 835 bno = (p + c) * ochs + o; 836 if (BIT(bno)) 837 mix.wValue[k++] = 838 MAKE(p+c+1, o+1); 839 } 840 snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s", 841 d->bUnitId, uaudio_id_name(sc, iot, 842 d->baSourceId[i])); 843 mix.nchan = chs; 844 uaudio_mixer_add_ctl(sc, &mix); 845 } else { 846 /* XXX */ 847 } 848 #undef BIT 849 p += chs; 850 } 851 852 } 853 854 void 855 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 856 { 857 const struct usb_audio_selector_unit *d = iot[id].d.su; 858 struct mixerctl mix; 859 int i, wp; 860 861 DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n", 862 d->bUnitId, d->bNrInPins)); 863 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 864 mix.wValue[0] = MAKE(0, 0); 865 uaudio_determine_class(&iot[id], &mix); 866 mix.nchan = 1; 867 mix.type = MIX_SELECTOR; 868 mix.ctlunit = ""; 869 mix.minval = 1; 870 mix.maxval = d->bNrInPins; 871 wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId); 872 for (i = 1; i <= d->bNrInPins; i++) { 873 wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp, 874 "i%d", d->baSourceId[i - 1]); 875 if (wp > MAX_AUDIO_DEV_LEN - 1) 876 break; 877 } 878 uaudio_mixer_add_ctl(sc, &mix); 879 } 880 881 #ifdef UAUDIO_DEBUG 882 const char * 883 uaudio_get_terminal_name(int terminal_type) 884 { 885 static char buf[100]; 886 887 switch (terminal_type) { 888 /* USB terminal types */ 889 case UAT_UNDEFINED: return "UAT_UNDEFINED"; 890 case UAT_STREAM: return "UAT_STREAM"; 891 case UAT_VENDOR: return "UAT_VENDOR"; 892 /* input terminal types */ 893 case UATI_UNDEFINED: return "UATI_UNDEFINED"; 894 case UATI_MICROPHONE: return "UATI_MICROPHONE"; 895 case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE"; 896 case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE"; 897 case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE"; 898 case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY"; 899 case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR"; 900 /* output terminal types */ 901 case UATO_UNDEFINED: return "UATO_UNDEFINED"; 902 case UATO_SPEAKER: return "UATO_SPEAKER"; 903 case UATO_HEADPHONES: return "UATO_HEADPHONES"; 904 case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO"; 905 case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER"; 906 case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER"; 907 case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER"; 908 case UATO_SUBWOOFER: return "UATO_SUBWOOFER"; 909 /* bidir terminal types */ 910 case UATB_UNDEFINED: return "UATB_UNDEFINED"; 911 case UATB_HANDSET: return "UATB_HANDSET"; 912 case UATB_HEADSET: return "UATB_HEADSET"; 913 case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE"; 914 case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP"; 915 case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC"; 916 /* telephony terminal types */ 917 case UATT_UNDEFINED: return "UATT_UNDEFINED"; 918 case UATT_PHONELINE: return "UATT_PHONELINE"; 919 case UATT_TELEPHONE: return "UATT_TELEPHONE"; 920 case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE"; 921 /* external terminal types */ 922 case UATE_UNDEFINED: return "UATE_UNDEFINED"; 923 case UATE_ANALOGCONN: return "UATE_ANALOGCONN"; 924 case UATE_LINECONN: return "UATE_LINECONN"; 925 case UATE_LEGACYCONN: return "UATE_LEGACYCONN"; 926 case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC"; 927 case UATE_SPDIF: return "UATE_SPDIF"; 928 case UATE_1394DA: return "UATE_1394DA"; 929 case UATE_1394DV: return "UATE_1394DV"; 930 /* embedded function terminal types */ 931 case UATF_UNDEFINED: return "UATF_UNDEFINED"; 932 case UATF_CALIBNOISE: return "UATF_CALIBNOISE"; 933 case UATF_EQUNOISE: return "UATF_EQUNOISE"; 934 case UATF_CDPLAYER: return "UATF_CDPLAYER"; 935 case UATF_DAT: return "UATF_DAT"; 936 case UATF_DCC: return "UATF_DCC"; 937 case UATF_MINIDISK: return "UATF_MINIDISK"; 938 case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE"; 939 case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH"; 940 case UATF_VCRAUDIO: return "UATF_VCRAUDIO"; 941 case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO"; 942 case UATF_DVDAUDIO: return "UATF_DVDAUDIO"; 943 case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO"; 944 case UATF_SATELLITE: return "UATF_SATELLITE"; 945 case UATF_CABLETUNER: return "UATF_CABLETUNER"; 946 case UATF_DSS: return "UATF_DSS"; 947 case UATF_RADIORECV: return "UATF_RADIORECV"; 948 case UATF_RADIOXMIT: return "UATF_RADIOXMIT"; 949 case UATF_MULTITRACK: return "UATF_MULTITRACK"; 950 case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER"; 951 default: 952 snprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type); 953 return buf; 954 } 955 } 956 #endif 957 958 int 959 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix) 960 { 961 int terminal_type; 962 963 if (iot == NULL || iot->output == NULL) { 964 mix->class = UAC_OUTPUT; 965 return 0; 966 } 967 terminal_type = 0; 968 if (iot->output->size == 1) 969 terminal_type = iot->output->terminals[0]; 970 /* 971 * If the only output terminal is USB, 972 * the class is UAC_RECORD. 973 */ 974 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) { 975 mix->class = UAC_RECORD; 976 if (iot->inputs_size == 1 977 && iot->inputs[0] != NULL 978 && iot->inputs[0]->size == 1) 979 return iot->inputs[0]->terminals[0]; 980 else 981 return 0; 982 } 983 /* 984 * If the ultimate destination of the unit is just one output 985 * terminal and the unit is connected to the output terminal 986 * directly, the class is UAC_OUTPUT. 987 */ 988 if (terminal_type != 0 && iot->direct) { 989 mix->class = UAC_OUTPUT; 990 return terminal_type; 991 } 992 /* 993 * If the unit is connected to just one input terminal, 994 * the class is UAC_INPUT. 995 */ 996 if (iot->inputs_size == 1 && iot->inputs[0] != NULL 997 && iot->inputs[0]->size == 1) { 998 mix->class = UAC_INPUT; 999 return iot->inputs[0]->terminals[0]; 1000 } 1001 /* 1002 * Otherwise, the class is UAC_OUTPUT. 1003 */ 1004 mix->class = UAC_OUTPUT; 1005 return terminal_type; 1006 } 1007 1008 const char * 1009 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix) 1010 { 1011 int terminal_type; 1012 1013 terminal_type = uaudio_determine_class(iot, mix); 1014 if (mix->class == UAC_RECORD && terminal_type == 0) 1015 return AudioNmixerout; 1016 DPRINTF(("%s: terminal_type=%s\n", __func__, 1017 uaudio_get_terminal_name(terminal_type))); 1018 switch (terminal_type) { 1019 case UAT_STREAM: 1020 return AudioNdac; 1021 1022 case UATI_MICROPHONE: 1023 case UATI_DESKMICROPHONE: 1024 case UATI_PERSONALMICROPHONE: 1025 case UATI_OMNIMICROPHONE: 1026 case UATI_MICROPHONEARRAY: 1027 case UATI_PROCMICROPHONEARR: 1028 return AudioNmicrophone; 1029 1030 case UATO_SPEAKER: 1031 case UATO_DESKTOPSPEAKER: 1032 case UATO_ROOMSPEAKER: 1033 case UATO_COMMSPEAKER: 1034 return AudioNspeaker; 1035 1036 case UATO_HEADPHONES: 1037 return AudioNheadphone; 1038 1039 case UATO_SUBWOOFER: 1040 return AudioNlfe; 1041 1042 /* telephony terminal types */ 1043 case UATT_UNDEFINED: 1044 case UATT_PHONELINE: 1045 case UATT_TELEPHONE: 1046 case UATT_DOWNLINEPHONE: 1047 return "phone"; 1048 1049 case UATE_ANALOGCONN: 1050 case UATE_LINECONN: 1051 case UATE_LEGACYCONN: 1052 return AudioNline; 1053 1054 case UATE_DIGITALAUIFC: 1055 case UATE_SPDIF: 1056 case UATE_1394DA: 1057 case UATE_1394DV: 1058 return AudioNaux; 1059 1060 case UATF_CDPLAYER: 1061 return AudioNcd; 1062 1063 case UATF_SYNTHESIZER: 1064 return AudioNfmsynth; 1065 1066 case UATF_VIDEODISCAUDIO: 1067 case UATF_DVDAUDIO: 1068 case UATF_TVTUNERAUDIO: 1069 return AudioNvideo; 1070 1071 case UAT_UNDEFINED: 1072 case UAT_VENDOR: 1073 case UATI_UNDEFINED: 1074 /* output terminal types */ 1075 case UATO_UNDEFINED: 1076 case UATO_DISPLAYAUDIO: 1077 /* bidir terminal types */ 1078 case UATB_UNDEFINED: 1079 case UATB_HANDSET: 1080 case UATB_HEADSET: 1081 case UATB_SPEAKERPHONE: 1082 case UATB_SPEAKERPHONEESUP: 1083 case UATB_SPEAKERPHONEECANC: 1084 /* external terminal types */ 1085 case UATE_UNDEFINED: 1086 /* embedded function terminal types */ 1087 case UATF_UNDEFINED: 1088 case UATF_CALIBNOISE: 1089 case UATF_EQUNOISE: 1090 case UATF_DAT: 1091 case UATF_DCC: 1092 case UATF_MINIDISK: 1093 case UATF_ANALOGTAPE: 1094 case UATF_PHONOGRAPH: 1095 case UATF_VCRAUDIO: 1096 case UATF_SATELLITE: 1097 case UATF_CABLETUNER: 1098 case UATF_DSS: 1099 case UATF_RADIORECV: 1100 case UATF_RADIOXMIT: 1101 case UATF_MULTITRACK: 1102 case 0xffff: 1103 default: 1104 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type)); 1105 return AudioNmaster; 1106 } 1107 } 1108 1109 void 1110 uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 1111 { 1112 const struct usb_audio_feature_unit *d = iot[id].d.fu; 1113 uByte *ctls = (uByte *)d->bmaControls; 1114 int ctlsize = d->bControlSize; 1115 int nchan = (d->bLength - 7) / ctlsize; 1116 u_int fumask, mmask, cmask; 1117 struct mixerctl mix; 1118 int chan, ctl, i, unit; 1119 const char *mixername; 1120 1121 #define GET(i) (ctls[(i)*ctlsize] | \ 1122 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0)) 1123 1124 mmask = GET(0); 1125 /* Figure out what we can control */ 1126 for (cmask = 0, chan = 1; chan < nchan; chan++) { 1127 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n", 1128 chan, GET(chan))); 1129 cmask |= GET(chan); 1130 } 1131 1132 DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, " 1133 "%d channels, mmask=0x%04x, cmask=0x%04x\n", 1134 d->bUnitId, nchan, mmask, cmask)); 1135 1136 if (nchan > MIX_MAX_CHAN) 1137 nchan = MIX_MAX_CHAN; 1138 unit = d->bUnitId; 1139 mix.wIndex = MAKE(unit, sc->sc_ac_iface); 1140 for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) { 1141 fumask = FU_MASK(ctl); 1142 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n", 1143 ctl, fumask)); 1144 if (mmask & fumask) { 1145 mix.nchan = 1; 1146 mix.wValue[0] = MAKE(ctl, 0); 1147 } else if (cmask & fumask) { 1148 mix.nchan = nchan - 1; 1149 for (i = 1; i < nchan; i++) { 1150 if (GET(i) & fumask) 1151 mix.wValue[i-1] = MAKE(ctl, i); 1152 else 1153 mix.wValue[i-1] = -1; 1154 } 1155 } else { 1156 continue; 1157 } 1158 #undef GET 1159 mixername = uaudio_feature_name(&iot[id], &mix); 1160 switch (ctl) { 1161 case MUTE_CONTROL: 1162 mix.type = MIX_ON_OFF; 1163 mix.ctlunit = ""; 1164 snprintf(mix.ctlname, sizeof(mix.ctlname), 1165 "%s.%s", mixername, AudioNmute); 1166 break; 1167 case VOLUME_CONTROL: 1168 mix.type = MIX_SIGNED_16; 1169 mix.ctlunit = AudioNvolume; 1170 strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname)); 1171 break; 1172 case BASS_CONTROL: 1173 mix.type = MIX_SIGNED_8; 1174 mix.ctlunit = AudioNbass; 1175 snprintf(mix.ctlname, sizeof(mix.ctlname), 1176 "%s.%s", mixername, AudioNbass); 1177 break; 1178 case MID_CONTROL: 1179 mix.type = MIX_SIGNED_8; 1180 mix.ctlunit = AudioNmid; 1181 snprintf(mix.ctlname, sizeof(mix.ctlname), 1182 "%s.%s", mixername, AudioNmid); 1183 break; 1184 case TREBLE_CONTROL: 1185 mix.type = MIX_SIGNED_8; 1186 mix.ctlunit = AudioNtreble; 1187 snprintf(mix.ctlname, sizeof(mix.ctlname), 1188 "%s.%s", mixername, AudioNtreble); 1189 break; 1190 case GRAPHIC_EQUALIZER_CONTROL: 1191 continue; /* XXX don't add anything */ 1192 break; 1193 case AGC_CONTROL: 1194 mix.type = MIX_ON_OFF; 1195 mix.ctlunit = ""; 1196 snprintf(mix.ctlname, sizeof(mix.ctlname), "%s.%s", 1197 mixername, AudioNagc); 1198 break; 1199 case DELAY_CONTROL: 1200 mix.type = MIX_UNSIGNED_16; 1201 mix.ctlunit = "4 ms"; 1202 snprintf(mix.ctlname, sizeof(mix.ctlname), 1203 "%s.%s", mixername, AudioNdelay); 1204 break; 1205 case BASS_BOOST_CONTROL: 1206 mix.type = MIX_ON_OFF; 1207 mix.ctlunit = ""; 1208 snprintf(mix.ctlname, sizeof(mix.ctlname), 1209 "%s.%s", mixername, AudioNbassboost); 1210 break; 1211 case LOUDNESS_CONTROL: 1212 mix.type = MIX_ON_OFF; 1213 mix.ctlunit = ""; 1214 snprintf(mix.ctlname, sizeof(mix.ctlname), 1215 "%s.%s", mixername, AudioNloudness); 1216 break; 1217 } 1218 uaudio_mixer_add_ctl(sc, &mix); 1219 } 1220 } 1221 1222 void 1223 uaudio_add_processing_updown(struct uaudio_softc *sc, 1224 const struct io_terminal *iot, int id) 1225 { 1226 const struct usb_audio_processing_unit *d = iot[id].d.pu; 1227 const struct usb_audio_processing_unit_1 *d1 = 1228 (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins]; 1229 const struct usb_audio_processing_unit_updown *ud = 1230 (const struct usb_audio_processing_unit_updown *) 1231 &d1->bmControls[d1->bControlSize]; 1232 struct mixerctl mix; 1233 int i; 1234 1235 DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n", 1236 d->bUnitId, ud->bNrModes)); 1237 1238 if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) { 1239 DPRINTF(("uaudio_add_processing_updown: no mode select\n")); 1240 return; 1241 } 1242 1243 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1244 mix.nchan = 1; 1245 mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0); 1246 uaudio_determine_class(&iot[id], &mix); 1247 mix.type = MIX_ON_OFF; /* XXX */ 1248 mix.ctlunit = ""; 1249 snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId); 1250 1251 for (i = 0; i < ud->bNrModes; i++) { 1252 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n", 1253 i, UGETW(ud->waModes[i]))); 1254 /* XXX */ 1255 } 1256 uaudio_mixer_add_ctl(sc, &mix); 1257 } 1258 1259 void 1260 uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 1261 { 1262 const struct usb_audio_processing_unit *d = iot[id].d.pu; 1263 const struct usb_audio_processing_unit_1 *d1 = 1264 (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins]; 1265 int ptype = UGETW(d->wProcessType); 1266 struct mixerctl mix; 1267 1268 DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d " 1269 "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins)); 1270 1271 if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) { 1272 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1273 mix.nchan = 1; 1274 mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0); 1275 uaudio_determine_class(&iot[id], &mix); 1276 mix.type = MIX_ON_OFF; 1277 mix.ctlunit = ""; 1278 snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable", 1279 d->bUnitId, ptype); 1280 uaudio_mixer_add_ctl(sc, &mix); 1281 } 1282 1283 switch(ptype) { 1284 case UPDOWNMIX_PROCESS: 1285 uaudio_add_processing_updown(sc, iot, id); 1286 break; 1287 case DOLBY_PROLOGIC_PROCESS: 1288 case P3D_STEREO_EXTENDER_PROCESS: 1289 case REVERBATION_PROCESS: 1290 case CHORUS_PROCESS: 1291 case DYN_RANGE_COMP_PROCESS: 1292 default: 1293 #ifdef UAUDIO_DEBUG 1294 printf("uaudio_add_processing: unit %d, type=%d not impl.\n", 1295 d->bUnitId, ptype); 1296 #endif 1297 break; 1298 } 1299 } 1300 1301 void 1302 uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id) 1303 { 1304 const struct usb_audio_extension_unit *d = iot[id].d.eu; 1305 const struct usb_audio_extension_unit_1 *d1 = 1306 (const struct usb_audio_extension_unit_1 *)&d->baSourceId[d->bNrInPins]; 1307 struct mixerctl mix; 1308 1309 DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n", 1310 d->bUnitId, d->bNrInPins)); 1311 1312 if (sc->sc_quirks & UAUDIO_FLAG_NO_XU) 1313 return; 1314 1315 if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) { 1316 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface); 1317 mix.nchan = 1; 1318 mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0); 1319 uaudio_determine_class(&iot[id], &mix); 1320 mix.type = MIX_ON_OFF; 1321 mix.ctlunit = ""; 1322 snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable", 1323 d->bUnitId); 1324 uaudio_mixer_add_ctl(sc, &mix); 1325 } 1326 } 1327 1328 struct terminal_list* 1329 uaudio_merge_terminal_list(const struct io_terminal *iot) 1330 { 1331 struct terminal_list *tml; 1332 uint16_t *ptm; 1333 int i, len; 1334 1335 len = 0; 1336 if (iot->inputs == NULL) 1337 return NULL; 1338 for (i = 0; i < iot->inputs_size; i++) { 1339 if (iot->inputs[i] != NULL) 1340 len += iot->inputs[i]->size; 1341 } 1342 tml = malloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT); 1343 if (tml == NULL) { 1344 printf("uaudio_merge_terminal_list: no memory\n"); 1345 return NULL; 1346 } 1347 tml->size = 0; 1348 ptm = tml->terminals; 1349 for (i = 0; i < iot->inputs_size; i++) { 1350 if (iot->inputs[i] == NULL) 1351 continue; 1352 if (iot->inputs[i]->size > len) 1353 break; 1354 memcpy(ptm, iot->inputs[i]->terminals, 1355 iot->inputs[i]->size * sizeof(uint16_t)); 1356 tml->size += iot->inputs[i]->size; 1357 ptm += iot->inputs[i]->size; 1358 len -= iot->inputs[i]->size; 1359 } 1360 return tml; 1361 } 1362 1363 struct terminal_list * 1364 uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id) 1365 { 1366 struct terminal_list *tml; 1367 struct io_terminal *it; 1368 int src_id, i; 1369 1370 it = &iot[id]; 1371 if (it->output != NULL) { 1372 /* already has outtype? */ 1373 for (i = 0; i < it->output->size; i++) 1374 if (it->output->terminals[i] == outtype) 1375 return uaudio_merge_terminal_list(it); 1376 tml = malloc(TERMINAL_LIST_SIZE(it->output->size + 1), 1377 M_TEMP, M_NOWAIT); 1378 if (tml == NULL) { 1379 printf("uaudio_io_terminaltype: no memory\n"); 1380 return uaudio_merge_terminal_list(it); 1381 } 1382 memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size)); 1383 tml->terminals[it->output->size] = outtype; 1384 tml->size++; 1385 free(it->output, M_TEMP); 1386 it->output = tml; 1387 if (it->inputs != NULL) { 1388 for (i = 0; i < it->inputs_size; i++) 1389 if (it->inputs[i] != NULL) 1390 free(it->inputs[i], M_TEMP); 1391 free(it->inputs, M_TEMP); 1392 } 1393 it->inputs_size = 0; 1394 it->inputs = NULL; 1395 } else { /* end `iot[id] != NULL' */ 1396 it->inputs_size = 0; 1397 it->inputs = NULL; 1398 it->output = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT); 1399 if (it->output == NULL) { 1400 printf("uaudio_io_terminaltype: no memory\n"); 1401 return NULL; 1402 } 1403 it->output->terminals[0] = outtype; 1404 it->output->size = 1; 1405 it->direct = FALSE; 1406 } 1407 1408 switch (it->d.desc->bDescriptorSubtype) { 1409 case UDESCSUB_AC_INPUT: 1410 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); 1411 if (it->inputs == NULL) { 1412 printf("uaudio_io_terminaltype: no memory\n"); 1413 return NULL; 1414 } 1415 tml = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT); 1416 if (tml == NULL) { 1417 printf("uaudio_io_terminaltype: no memory\n"); 1418 free(it->inputs, M_TEMP); 1419 it->inputs = NULL; 1420 return NULL; 1421 } 1422 it->inputs[0] = tml; 1423 tml->terminals[0] = UGETW(it->d.it->wTerminalType); 1424 tml->size = 1; 1425 it->inputs_size = 1; 1426 return uaudio_merge_terminal_list(it); 1427 case UDESCSUB_AC_FEATURE: 1428 src_id = it->d.fu->bSourceId; 1429 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); 1430 if (it->inputs == NULL) { 1431 printf("uaudio_io_terminaltype: no memory\n"); 1432 return uaudio_io_terminaltype(outtype, iot, src_id); 1433 } 1434 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id); 1435 it->inputs_size = 1; 1436 return uaudio_merge_terminal_list(it); 1437 case UDESCSUB_AC_OUTPUT: 1438 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT); 1439 if (it->inputs == NULL) { 1440 printf("uaudio_io_terminaltype: no memory\n"); 1441 return NULL; 1442 } 1443 src_id = it->d.ot->bSourceId; 1444 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id); 1445 it->inputs_size = 1; 1446 iot[src_id].direct = TRUE; 1447 return NULL; 1448 case UDESCSUB_AC_MIXER: 1449 it->inputs_size = 0; 1450 it->inputs = malloc(sizeof(struct terminal_list *) 1451 * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT); 1452 if (it->inputs == NULL) { 1453 printf("uaudio_io_terminaltype: no memory\n"); 1454 return NULL; 1455 } 1456 for (i = 0; i < it->d.mu->bNrInPins; i++) { 1457 src_id = it->d.mu->baSourceId[i]; 1458 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1459 src_id); 1460 it->inputs_size++; 1461 } 1462 return uaudio_merge_terminal_list(it); 1463 case UDESCSUB_AC_SELECTOR: 1464 it->inputs_size = 0; 1465 it->inputs = malloc(sizeof(struct terminal_list *) 1466 * it->d.su->bNrInPins, M_TEMP, M_NOWAIT); 1467 if (it->inputs == NULL) { 1468 printf("uaudio_io_terminaltype: no memory\n"); 1469 return NULL; 1470 } 1471 for (i = 0; i < it->d.su->bNrInPins; i++) { 1472 src_id = it->d.su->baSourceId[i]; 1473 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1474 src_id); 1475 it->inputs_size++; 1476 } 1477 return uaudio_merge_terminal_list(it); 1478 case UDESCSUB_AC_PROCESSING: 1479 it->inputs_size = 0; 1480 it->inputs = malloc(sizeof(struct terminal_list *) 1481 * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT); 1482 if (it->inputs == NULL) { 1483 printf("uaudio_io_terminaltype: no memory\n"); 1484 return NULL; 1485 } 1486 for (i = 0; i < it->d.pu->bNrInPins; i++) { 1487 src_id = it->d.pu->baSourceId[i]; 1488 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1489 src_id); 1490 it->inputs_size++; 1491 } 1492 return uaudio_merge_terminal_list(it); 1493 case UDESCSUB_AC_EXTENSION: 1494 it->inputs_size = 0; 1495 it->inputs = malloc(sizeof(struct terminal_list *) 1496 * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT); 1497 if (it->inputs == NULL) { 1498 printf("uaudio_io_terminaltype: no memory\n"); 1499 return NULL; 1500 } 1501 for (i = 0; i < it->d.eu->bNrInPins; i++) { 1502 src_id = it->d.eu->baSourceId[i]; 1503 it->inputs[i] = uaudio_io_terminaltype(outtype, iot, 1504 src_id); 1505 it->inputs_size++; 1506 } 1507 return uaudio_merge_terminal_list(it); 1508 case UDESCSUB_AC_HEADER: 1509 default: 1510 return NULL; 1511 } 1512 } 1513 1514 usbd_status 1515 uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc) 1516 { 1517 usbd_status err; 1518 1519 err = uaudio_identify_ac(sc, cdesc); 1520 if (err) 1521 return (err); 1522 return (uaudio_identify_as(sc, cdesc)); 1523 } 1524 1525 void 1526 uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai) 1527 { 1528 size_t len; 1529 struct as_info *nai; 1530 1531 len = sizeof(*ai) * (sc->sc_nalts + 1); 1532 nai = malloc(len, M_USBDEV, M_NOWAIT); 1533 if (nai == NULL) { 1534 printf("uaudio_add_alt: no memory\n"); 1535 return; 1536 } 1537 /* Copy old data, if there was any */ 1538 if (sc->sc_nalts != 0) { 1539 bcopy(sc->sc_alts, nai, sizeof(*ai) * (sc->sc_nalts)); 1540 free(sc->sc_alts, M_USBDEV); 1541 } 1542 sc->sc_alts = nai; 1543 DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n", 1544 ai->alt, ai->encoding)); 1545 sc->sc_alts[sc->sc_nalts++] = *ai; 1546 } 1547 1548 void 1549 uaudio_create_encodings(struct uaudio_softc *sc) 1550 { 1551 int enc, encs[16], nencs, i, j; 1552 1553 nencs = 0; 1554 for (i = 0; i < sc->sc_nalts && nencs < 16; i++) { 1555 enc = (sc->sc_alts[i].asf1desc->bSubFrameSize << 16) | 1556 (sc->sc_alts[i].asf1desc->bBitResolution << 8) | 1557 sc->sc_alts[i].encoding; 1558 for (j = 0; j < nencs; j++) { 1559 if (encs[j] == enc) 1560 break; 1561 } 1562 if (j < nencs) 1563 continue; 1564 encs[j] = enc; 1565 nencs++; 1566 } 1567 1568 sc->sc_nencs = 0; 1569 sc->sc_encs = malloc(sizeof(struct audio_encoding) * nencs, 1570 M_USBDEV, M_NOWAIT); 1571 if (sc->sc_encs == NULL) { 1572 printf("%s: no memory\n", __func__); 1573 return; 1574 } 1575 sc->sc_nencs = nencs; 1576 1577 for (i = 0; i < sc->sc_nencs; i++) { 1578 sc->sc_encs[i].index = i; 1579 sc->sc_encs[i].encoding = encs[i] & 0xff; 1580 sc->sc_encs[i].precision = (encs[i] >> 8) & 0xff; 1581 sc->sc_encs[i].bps = (encs[i] >> 16) & 0xff; 1582 sc->sc_encs[i].msb = 1; 1583 sc->sc_encs[i].flags = 0; 1584 switch (sc->sc_encs[i].encoding) { 1585 case AUDIO_ENCODING_SLINEAR_LE: 1586 strlcpy(sc->sc_encs[i].name, 1587 sc->sc_encs[i].precision == 8 ? 1588 AudioEslinear : AudioEslinear_le, 1589 sizeof(sc->sc_encs[i].name)); 1590 break; 1591 case AUDIO_ENCODING_ULINEAR_LE: 1592 if (sc->sc_encs[i].precision != 8) { 1593 DPRINTF(("%s: invalid precision for ulinear: %d\n", 1594 __func__, sc->sc_encs[i].precision)); 1595 continue; 1596 } 1597 strlcpy(sc->sc_encs[i].name, AudioEulinear, 1598 sizeof(sc->sc_encs[i].name)); 1599 break; 1600 case AUDIO_ENCODING_ALAW: 1601 if (sc->sc_encs[i].precision != 8) { 1602 DPRINTF(("%s: invalid precision for alaw: %d\n", 1603 __func__, sc->sc_encs[i].precision)); 1604 continue; 1605 } 1606 strlcpy(sc->sc_encs[i].name, AudioEalaw, 1607 sizeof(sc->sc_encs[i].name)); 1608 break; 1609 case AUDIO_ENCODING_ULAW: 1610 if (sc->sc_encs[i].precision != 8) { 1611 DPRINTF(("%s: invalid precision for ulaw: %d\n", 1612 __func__, sc->sc_encs[i].precision)); 1613 continue; 1614 } 1615 strlcpy(sc->sc_encs[i].name, AudioEmulaw, 1616 sizeof(sc->sc_encs[i].name)); 1617 break; 1618 default: 1619 DPRINTF(("%s: unknown format\n", __func__)); 1620 break; 1621 } 1622 } 1623 } 1624 1625 usbd_status 1626 uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp, 1627 int size, const usb_interface_descriptor_t *id) 1628 #define offs (*offsp) 1629 { 1630 const struct usb_audio_streaming_interface_descriptor *asid; 1631 const struct usb_audio_streaming_type1_descriptor *asf1d; 1632 const usb_endpoint_descriptor_audio_t *ed; 1633 const usb_endpoint_descriptor_audio_t *sync_ed; 1634 const struct usb_audio_streaming_endpoint_descriptor *sed; 1635 int format, chan, prec, enc, bps; 1636 int dir, type, sync, sync_addr; 1637 struct as_info ai; 1638 const char *format_str; 1639 1640 asid = (const void *)(buf + offs); 1641 if (asid->bDescriptorType != UDESC_CS_INTERFACE || 1642 asid->bDescriptorSubtype != AS_GENERAL) 1643 return (USBD_INVAL); 1644 DPRINTF(("uaudio_process_as: asid: bTerminalLink=%d wFormatTag=%d\n", 1645 asid->bTerminalLink, UGETW(asid->wFormatTag))); 1646 offs += asid->bLength; 1647 if (offs > size) 1648 return (USBD_INVAL); 1649 1650 asf1d = (const void *)(buf + offs); 1651 if (asf1d->bDescriptorType != UDESC_CS_INTERFACE || 1652 asf1d->bDescriptorSubtype != FORMAT_TYPE) 1653 return (USBD_INVAL); 1654 offs += asf1d->bLength; 1655 if (offs > size) 1656 return (USBD_INVAL); 1657 1658 if (asf1d->bFormatType != FORMAT_TYPE_I) { 1659 printf("%s: ignored setting with type %d format\n", 1660 sc->sc_dev.dv_xname, UGETW(asid->wFormatTag)); 1661 return (USBD_NORMAL_COMPLETION); 1662 } 1663 1664 ed = (const void *)(buf + offs); 1665 if (ed->bDescriptorType != UDESC_ENDPOINT) 1666 return (USBD_INVAL); 1667 DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d " 1668 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d " 1669 "bInterval=%d bRefresh=%d bSynchAddress=%d\n", 1670 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress, 1671 ed->bmAttributes, UGETW(ed->wMaxPacketSize), 1672 ed->bInterval, ed->bRefresh, ed->bSynchAddress)); 1673 offs += ed->bLength; 1674 if (offs > size) 1675 return (USBD_INVAL); 1676 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS) 1677 return (USBD_INVAL); 1678 1679 dir = UE_GET_DIR(ed->bEndpointAddress); 1680 type = UE_GET_ISO_TYPE(ed->bmAttributes); 1681 1682 /* Check for sync endpoint. */ 1683 sync = FALSE; 1684 sync_addr = 0; 1685 if (id->bNumEndpoints > 1 && 1686 ((dir == UE_DIR_IN && type == UE_ISO_ADAPT) || 1687 (dir != UE_DIR_IN && type == UE_ISO_ASYNC))) 1688 sync = TRUE; 1689 1690 /* Check whether sync endpoint address is given. */ 1691 if (ed->bLength >= USB_ENDPOINT_DESCRIPTOR_AUDIO_SIZE) { 1692 /* bSynchAdress set to 0 indicates sync is not used. */ 1693 if (ed->bSynchAddress == 0) 1694 sync = FALSE; 1695 else 1696 sync_addr = ed->bSynchAddress; 1697 } 1698 1699 sed = (const void *)(buf + offs); 1700 if (sed->bDescriptorType != UDESC_CS_ENDPOINT || 1701 sed->bDescriptorSubtype != AS_GENERAL) 1702 return (USBD_INVAL); 1703 DPRINTF((" streaming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength)); 1704 offs += sed->bLength; 1705 if (offs > size) 1706 return (USBD_INVAL); 1707 1708 sync_ed = NULL; 1709 if (sync == TRUE) { 1710 sync_ed = (const void*)(buf + offs); 1711 if (sync_ed->bDescriptorType != UDESC_ENDPOINT) { 1712 printf("%s: sync ep descriptor wrong type\n", 1713 sc->sc_dev.dv_xname); 1714 return (USBD_NORMAL_COMPLETION); 1715 } 1716 DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d " 1717 "bDescriptorType=%d bEndpointAddress=%d " 1718 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d " 1719 "bRefresh=%d bSynchAddress=%d\n", 1720 sync_ed->bLength, sync_ed->bDescriptorType, 1721 sync_ed->bEndpointAddress, sync_ed->bmAttributes, 1722 UGETW(sync_ed->wMaxPacketSize), sync_ed->bInterval, 1723 sync_ed->bRefresh, sync_ed->bSynchAddress)); 1724 offs += sync_ed->bLength; 1725 if (offs > size) { 1726 printf("%s: sync ep descriptor too large\n", 1727 sc->sc_dev.dv_xname); 1728 return (USBD_NORMAL_COMPLETION); 1729 } 1730 if (dir == UE_GET_DIR(sync_ed->bEndpointAddress)) { 1731 printf("%s: sync ep wrong direction\n", 1732 sc->sc_dev.dv_xname); 1733 return (USBD_NORMAL_COMPLETION); 1734 } 1735 if (UE_GET_XFERTYPE(sync_ed->bmAttributes) != UE_ISOCHRONOUS) { 1736 printf("%s: sync ep wrong xfer type\n", 1737 sc->sc_dev.dv_xname); 1738 return (USBD_NORMAL_COMPLETION); 1739 } 1740 if (sync_ed->bLength >= 1741 USB_ENDPOINT_DESCRIPTOR_AUDIO_SIZE && 1742 sync_ed->bSynchAddress != 0) { 1743 printf("%s: sync ep bSynchAddress != 0\n", 1744 sc->sc_dev.dv_xname); 1745 return (USBD_NORMAL_COMPLETION); 1746 } 1747 if (sync_addr && sync_ed->bEndpointAddress != sync_addr) { 1748 printf("%s: sync ep address mismatch\n", 1749 sc->sc_dev.dv_xname); 1750 return (USBD_NORMAL_COMPLETION); 1751 } 1752 } 1753 if (sync_ed != NULL && dir == UE_DIR_IN) { 1754 printf("%s: sync pipe for recording not yet implemented\n", 1755 sc->sc_dev.dv_xname); 1756 return (USBD_NORMAL_COMPLETION); 1757 } 1758 1759 format = UGETW(asid->wFormatTag); 1760 chan = asf1d->bNrChannels; 1761 prec = asf1d->bBitResolution; 1762 bps = asf1d->bSubFrameSize; 1763 if ((prec != 8 && prec != 16 && prec != 24) || (bps < 1 || bps > 4)) { 1764 printf("%s: ignored setting with precision %d bps %d\n", 1765 sc->sc_dev.dv_xname, prec, bps); 1766 return (USBD_NORMAL_COMPLETION); 1767 } 1768 switch (format) { 1769 case UA_FMT_PCM: 1770 if (prec == 8) { 1771 sc->sc_altflags |= HAS_8; 1772 } else if (prec == 16) { 1773 sc->sc_altflags |= HAS_16; 1774 } else if (prec == 24) { 1775 sc->sc_altflags |= HAS_24; 1776 } 1777 enc = AUDIO_ENCODING_SLINEAR_LE; 1778 format_str = "pcm"; 1779 break; 1780 case UA_FMT_PCM8: 1781 enc = AUDIO_ENCODING_ULINEAR_LE; 1782 sc->sc_altflags |= HAS_8U; 1783 format_str = "pcm8"; 1784 break; 1785 case UA_FMT_ALAW: 1786 enc = AUDIO_ENCODING_ALAW; 1787 sc->sc_altflags |= HAS_ALAW; 1788 format_str = "alaw"; 1789 break; 1790 case UA_FMT_MULAW: 1791 enc = AUDIO_ENCODING_ULAW; 1792 sc->sc_altflags |= HAS_MULAW; 1793 format_str = "mulaw"; 1794 break; 1795 case UA_FMT_IEEE_FLOAT: 1796 default: 1797 printf("%s: ignored setting with format %d\n", 1798 sc->sc_dev.dv_xname, format); 1799 return (USBD_NORMAL_COMPLETION); 1800 } 1801 #ifdef UAUDIO_DEBUG 1802 printf("%s: %s: %d-ch %d-bit %d-byte %s,", sc->sc_dev.dv_xname, 1803 dir == UE_DIR_IN ? "recording" : "playback", 1804 chan, prec, bps, format_str); 1805 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 1806 printf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d)); 1807 } else { 1808 int r; 1809 printf(" %d", UA_GETSAMP(asf1d, 0)); 1810 for (r = 1; r < asf1d->bSamFreqType; r++) 1811 printf(",%d", UA_GETSAMP(asf1d, r)); 1812 printf("Hz\n"); 1813 } 1814 #endif 1815 ai.alt = id->bAlternateSetting; 1816 ai.encoding = enc; 1817 ai.attributes = sed->bmAttributes; 1818 ai.idesc = id; 1819 ai.edesc = ed; 1820 ai.edesc1 = sync_ed; 1821 ai.asf1desc = asf1d; 1822 ai.sc_busy = 0; 1823 if (sc->sc_nalts < UAUDIO_MAX_ALTS) 1824 uaudio_add_alt(sc, &ai); 1825 #ifdef UAUDIO_DEBUG 1826 if (ai.attributes & UA_SED_FREQ_CONTROL) 1827 DPRINTFN(1, ("uaudio_process_as: FREQ_CONTROL\n")); 1828 if (ai.attributes & UA_SED_PITCH_CONTROL) 1829 DPRINTFN(1, ("uaudio_process_as: PITCH_CONTROL\n")); 1830 #endif 1831 sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD; 1832 1833 return (USBD_NORMAL_COMPLETION); 1834 } 1835 #undef offs 1836 1837 usbd_status 1838 uaudio_identify_as(struct uaudio_softc *sc, 1839 const usb_config_descriptor_t *cdesc) 1840 { 1841 const usb_interface_descriptor_t *id; 1842 const char *buf; 1843 int size, offs; 1844 1845 size = UGETW(cdesc->wTotalLength); 1846 buf = (const char *)cdesc; 1847 1848 /* Locate the AudioStreaming interface descriptor. */ 1849 offs = 0; 1850 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM, 1851 sc->sc_quirks); 1852 if (id == NULL) 1853 return (USBD_INVAL); 1854 1855 /* Loop through all the alternate settings. */ 1856 while (offs <= size) { 1857 DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n", 1858 id->bInterfaceNumber, offs)); 1859 switch (id->bNumEndpoints) { 1860 case 0: 1861 DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n", 1862 id->bAlternateSetting)); 1863 sc->sc_nullalt = id->bAlternateSetting; 1864 break; 1865 case 1: 1866 case 2: 1867 uaudio_process_as(sc, buf, &offs, size, id); 1868 break; 1869 default: 1870 printf("%s: ignored audio interface with %d " 1871 "endpoints\n", 1872 sc->sc_dev.dv_xname, id->bNumEndpoints); 1873 break; 1874 } 1875 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM, 1876 sc->sc_quirks); 1877 if (id == NULL) 1878 break; 1879 } 1880 if (offs > size) 1881 return (USBD_INVAL); 1882 DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts)); 1883 1884 if (sc->sc_mode == 0) { 1885 printf("%s: no usable endpoint found\n", 1886 sc->sc_dev.dv_xname); 1887 return (USBD_INVAL); 1888 } 1889 1890 return (USBD_NORMAL_COMPLETION); 1891 } 1892 1893 usbd_status 1894 uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc) 1895 { 1896 struct io_terminal* iot; 1897 const usb_interface_descriptor_t *id; 1898 const struct usb_audio_control_descriptor *acdp; 1899 const usb_descriptor_t *dp; 1900 const struct usb_audio_output_terminal *pot; 1901 struct terminal_list *tml; 1902 const char *buf, *ibuf, *ibufend; 1903 int size, offs, aclen, ndps, i, j; 1904 1905 size = UGETW(cdesc->wTotalLength); 1906 buf = (char *)cdesc; 1907 1908 /* Locate the AudioControl interface descriptor. */ 1909 offs = 0; 1910 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL, 1911 sc->sc_quirks); 1912 if (id == NULL) 1913 return (USBD_INVAL); 1914 if (offs + sizeof *acdp > size) 1915 return (USBD_INVAL); 1916 sc->sc_ac_iface = id->bInterfaceNumber; 1917 DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface)); 1918 1919 /* A class-specific AC interface header should follow. */ 1920 ibuf = buf + offs; 1921 acdp = (const struct usb_audio_control_descriptor *)ibuf; 1922 if (acdp->bDescriptorType != UDESC_CS_INTERFACE || 1923 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER) 1924 return (USBD_INVAL); 1925 aclen = UGETW(acdp->wTotalLength); 1926 if (offs + aclen > size) 1927 return (USBD_INVAL); 1928 1929 if (!(sc->sc_quirks & UAUDIO_FLAG_BAD_ADC) && 1930 UGETW(acdp->bcdADC) != UAUDIO_VERSION) 1931 return (USBD_INVAL); 1932 1933 sc->sc_audio_rev = UGETW(acdp->bcdADC); 1934 DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n", 1935 sc->sc_audio_rev, aclen)); 1936 1937 sc->sc_nullalt = -1; 1938 1939 /* Scan through all the AC specific descriptors */ 1940 ibufend = ibuf + aclen; 1941 dp = (const usb_descriptor_t *)ibuf; 1942 ndps = 0; 1943 iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO); 1944 if (iot == NULL) { 1945 printf("%s: no memory\n", __func__); 1946 return USBD_NOMEM; 1947 } 1948 for (;;) { 1949 ibuf += dp->bLength; 1950 if (ibuf >= ibufend) 1951 break; 1952 dp = (const usb_descriptor_t *)ibuf; 1953 if (ibuf + dp->bLength > ibufend) { 1954 free(iot, M_TEMP); 1955 return (USBD_INVAL); 1956 } 1957 if (dp->bDescriptorType != UDESC_CS_INTERFACE) { 1958 printf("uaudio_identify_ac: skip desc type=0x%02x\n", 1959 dp->bDescriptorType); 1960 continue; 1961 } 1962 i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId; 1963 iot[i].d.desc = dp; 1964 if (i > ndps) 1965 ndps = i; 1966 } 1967 ndps++; 1968 1969 /* construct io_terminal */ 1970 for (i = 0; i < ndps; i++) { 1971 dp = iot[i].d.desc; 1972 if (dp == NULL) 1973 continue; 1974 if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT) 1975 continue; 1976 pot = iot[i].d.ot; 1977 tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i); 1978 if (tml != NULL) 1979 free(tml, M_TEMP); 1980 } 1981 1982 #ifdef UAUDIO_DEBUG 1983 for (i = 0; i < 256; i++) { 1984 if (iot[i].d.desc == NULL) 1985 continue; 1986 printf("id %d:\t", i); 1987 switch (iot[i].d.desc->bDescriptorSubtype) { 1988 case UDESCSUB_AC_INPUT: 1989 printf("AC_INPUT type=%s\n", uaudio_get_terminal_name 1990 (UGETW(iot[i].d.it->wTerminalType))); 1991 break; 1992 case UDESCSUB_AC_OUTPUT: 1993 printf("AC_OUTPUT type=%s ", uaudio_get_terminal_name 1994 (UGETW(iot[i].d.ot->wTerminalType))); 1995 printf("src=%d\n", iot[i].d.ot->bSourceId); 1996 break; 1997 case UDESCSUB_AC_MIXER: 1998 printf("AC_MIXER src="); 1999 for (j = 0; j < iot[i].d.mu->bNrInPins; j++) 2000 printf("%d ", iot[i].d.mu->baSourceId[j]); 2001 printf("\n"); 2002 break; 2003 case UDESCSUB_AC_SELECTOR: 2004 printf("AC_SELECTOR src="); 2005 for (j = 0; j < iot[i].d.su->bNrInPins; j++) 2006 printf("%d ", iot[i].d.su->baSourceId[j]); 2007 printf("\n"); 2008 break; 2009 case UDESCSUB_AC_FEATURE: 2010 printf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId); 2011 break; 2012 case UDESCSUB_AC_PROCESSING: 2013 printf("AC_PROCESSING src="); 2014 for (j = 0; j < iot[i].d.pu->bNrInPins; j++) 2015 printf("%d ", iot[i].d.pu->baSourceId[j]); 2016 printf("\n"); 2017 break; 2018 case UDESCSUB_AC_EXTENSION: 2019 printf("AC_EXTENSION src="); 2020 for (j = 0; j < iot[i].d.eu->bNrInPins; j++) 2021 printf("%d ", iot[i].d.eu->baSourceId[j]); 2022 printf("\n"); 2023 break; 2024 default: 2025 printf("unknown audio control (subtype=%d)\n", 2026 iot[i].d.desc->bDescriptorSubtype); 2027 } 2028 for (j = 0; j < iot[i].inputs_size; j++) { 2029 int k; 2030 printf("\tinput%d: ", j); 2031 tml = iot[i].inputs[j]; 2032 if (tml == NULL) { 2033 printf("NULL\n"); 2034 continue; 2035 } 2036 for (k = 0; k < tml->size; k++) 2037 printf("%s ", uaudio_get_terminal_name 2038 (tml->terminals[k])); 2039 printf("\n"); 2040 } 2041 printf("\toutput: "); 2042 tml = iot[i].output; 2043 for (j = 0; j < tml->size; j++) 2044 printf("%s ", uaudio_get_terminal_name(tml->terminals[j])); 2045 printf("\n"); 2046 } 2047 #endif 2048 2049 for (i = 0; i < ndps; i++) { 2050 dp = iot[i].d.desc; 2051 if (dp == NULL) 2052 continue; 2053 DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n", 2054 i, dp->bDescriptorSubtype)); 2055 switch (dp->bDescriptorSubtype) { 2056 case UDESCSUB_AC_HEADER: 2057 printf("uaudio_identify_ac: unexpected AC header\n"); 2058 break; 2059 case UDESCSUB_AC_INPUT: 2060 uaudio_add_input(sc, iot, i); 2061 break; 2062 case UDESCSUB_AC_OUTPUT: 2063 uaudio_add_output(sc, iot, i); 2064 break; 2065 case UDESCSUB_AC_MIXER: 2066 uaudio_add_mixer(sc, iot, i); 2067 break; 2068 case UDESCSUB_AC_SELECTOR: 2069 uaudio_add_selector(sc, iot, i); 2070 break; 2071 case UDESCSUB_AC_FEATURE: 2072 uaudio_add_feature(sc, iot, i); 2073 break; 2074 case UDESCSUB_AC_PROCESSING: 2075 uaudio_add_processing(sc, iot, i); 2076 break; 2077 case UDESCSUB_AC_EXTENSION: 2078 uaudio_add_extension(sc, iot, i); 2079 break; 2080 default: 2081 printf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n", 2082 dp->bDescriptorSubtype); 2083 break; 2084 } 2085 } 2086 2087 /* delete io_terminal */ 2088 for (i = 0; i < 256; i++) { 2089 if (iot[i].d.desc == NULL) 2090 continue; 2091 if (iot[i].inputs != NULL) { 2092 for (j = 0; j < iot[i].inputs_size; j++) { 2093 if (iot[i].inputs[j] != NULL) 2094 free(iot[i].inputs[j], M_TEMP); 2095 } 2096 free(iot[i].inputs, M_TEMP); 2097 } 2098 if (iot[i].output != NULL) 2099 free(iot[i].output, M_TEMP); 2100 iot[i].d.desc = NULL; 2101 } 2102 free(iot, M_TEMP); 2103 2104 return (USBD_NORMAL_COMPLETION); 2105 } 2106 2107 int 2108 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi) 2109 { 2110 struct uaudio_softc *sc = addr; 2111 struct mixerctl *mc; 2112 int n, nctls, i; 2113 2114 DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index)); 2115 if (sc->sc_dying) 2116 return (EIO); 2117 2118 n = mi->index; 2119 nctls = sc->sc_nctls; 2120 2121 switch (n) { 2122 case UAC_OUTPUT: 2123 mi->type = AUDIO_MIXER_CLASS; 2124 mi->mixer_class = UAC_OUTPUT; 2125 mi->next = mi->prev = AUDIO_MIXER_LAST; 2126 strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name)); 2127 return (0); 2128 case UAC_INPUT: 2129 mi->type = AUDIO_MIXER_CLASS; 2130 mi->mixer_class = UAC_INPUT; 2131 mi->next = mi->prev = AUDIO_MIXER_LAST; 2132 strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name)); 2133 return (0); 2134 case UAC_EQUAL: 2135 mi->type = AUDIO_MIXER_CLASS; 2136 mi->mixer_class = UAC_EQUAL; 2137 mi->next = mi->prev = AUDIO_MIXER_LAST; 2138 strlcpy(mi->label.name, AudioCequalization, 2139 sizeof(mi->label.name)); 2140 return (0); 2141 case UAC_RECORD: 2142 mi->type = AUDIO_MIXER_CLASS; 2143 mi->mixer_class = UAC_RECORD; 2144 mi->next = mi->prev = AUDIO_MIXER_LAST; 2145 strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name)); 2146 return 0; 2147 default: 2148 break; 2149 } 2150 2151 n -= UAC_NCLASSES; 2152 if (n < 0 || n >= nctls) 2153 return (ENXIO); 2154 2155 mc = &sc->sc_ctls[n]; 2156 strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name)); 2157 mi->mixer_class = mc->class; 2158 mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */ 2159 switch (mc->type) { 2160 case MIX_ON_OFF: 2161 mi->type = AUDIO_MIXER_ENUM; 2162 mi->un.e.num_mem = 2; 2163 strlcpy(mi->un.e.member[0].label.name, AudioNoff, 2164 sizeof(mi->un.e.member[0].label.name)); 2165 mi->un.e.member[0].ord = 0; 2166 strlcpy(mi->un.e.member[1].label.name, AudioNon, 2167 sizeof(mi->un.e.member[1].label.name)); 2168 mi->un.e.member[1].ord = 1; 2169 break; 2170 case MIX_SELECTOR: 2171 mi->type = AUDIO_MIXER_ENUM; 2172 mi->un.e.num_mem = mc->maxval - mc->minval + 1; 2173 for (i = 0; i <= mc->maxval - mc->minval; i++) { 2174 snprintf(mi->un.e.member[i].label.name, 2175 sizeof(mi->un.e.member[i].label.name), 2176 "%d", i + mc->minval); 2177 mi->un.e.member[i].ord = i + mc->minval; 2178 } 2179 break; 2180 default: 2181 mi->type = AUDIO_MIXER_VALUE; 2182 strlcpy(mi->un.v.units.name, mc->ctlunit, 2183 sizeof(mi->un.v.units.name)); 2184 mi->un.v.num_channels = mc->nchan; 2185 mi->un.v.delta = mc->delta; 2186 break; 2187 } 2188 return (0); 2189 } 2190 2191 int 2192 uaudio_open(void *addr, int flags) 2193 { 2194 struct uaudio_softc *sc = addr; 2195 2196 DPRINTF(("uaudio_open: sc=%p\n", sc)); 2197 if (sc->sc_dying) 2198 return (EIO); 2199 2200 if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY)) 2201 return (ENXIO); 2202 if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD)) 2203 return (ENXIO); 2204 2205 return (0); 2206 } 2207 2208 /* 2209 * Close function is called at splaudio(). 2210 */ 2211 void 2212 uaudio_close(void *addr) 2213 { 2214 struct uaudio_softc *sc = addr; 2215 2216 if (sc->sc_playchan.altidx != -1) 2217 uaudio_chan_close(sc, &sc->sc_playchan); 2218 if (sc->sc_recchan.altidx != -1) 2219 uaudio_chan_close(sc, &sc->sc_recchan); 2220 } 2221 2222 int 2223 uaudio_drain(void *addr) 2224 { 2225 struct uaudio_softc *sc = addr; 2226 struct chan *pchan = &sc->sc_playchan; 2227 struct chan *rchan = &sc->sc_recchan; 2228 int ms = 0; 2229 2230 /* Wait for outstanding requests to complete. */ 2231 if (pchan->altidx != -1 && sc->sc_alts[pchan->altidx].sc_busy) 2232 ms = max(ms, pchan->reqms); 2233 if (rchan->altidx != -1 && sc->sc_alts[rchan->altidx].sc_busy) 2234 ms = max(ms, rchan->reqms); 2235 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * ms); 2236 2237 return (0); 2238 } 2239 2240 int 2241 uaudio_halt_out_dma(void *addr) 2242 { 2243 struct uaudio_softc *sc = addr; 2244 2245 DPRINTF(("uaudio_halt_out_dma: enter\n")); 2246 if (sc->sc_playchan.pipe != NULL) { 2247 uaudio_chan_close(sc, &sc->sc_playchan); 2248 sc->sc_playchan.pipe = NULL; 2249 if (sc->sc_playchan.sync_pipe != NULL) 2250 sc->sc_playchan.sync_pipe = NULL; 2251 uaudio_chan_free_buffers(sc, &sc->sc_playchan); 2252 sc->sc_playchan.intr = NULL; 2253 } 2254 return (0); 2255 } 2256 2257 int 2258 uaudio_halt_in_dma(void *addr) 2259 { 2260 struct uaudio_softc *sc = addr; 2261 2262 DPRINTF(("uaudio_halt_in_dma: enter\n")); 2263 if (sc->sc_recchan.pipe != NULL) { 2264 uaudio_chan_close(sc, &sc->sc_recchan); 2265 sc->sc_recchan.pipe = NULL; 2266 if (sc->sc_recchan.sync_pipe != NULL) 2267 sc->sc_recchan.sync_pipe = NULL; 2268 uaudio_chan_free_buffers(sc, &sc->sc_recchan); 2269 sc->sc_recchan.intr = NULL; 2270 } 2271 return (0); 2272 } 2273 2274 int 2275 uaudio_getdev(void *addr, struct audio_device *retp) 2276 { 2277 struct uaudio_softc *sc = addr; 2278 2279 DPRINTF(("uaudio_mixer_getdev:\n")); 2280 if (sc->sc_dying) 2281 return (EIO); 2282 2283 *retp = uaudio_device; 2284 return (0); 2285 } 2286 2287 /* 2288 * Make sure the block size is large enough to hold at least 1 transfer. 2289 * Ideally, the block size should be a multiple of the transfer size. 2290 * Currently, the transfer size for play and record can differ, and there's 2291 * no way to round playback and record blocksizes separately. 2292 */ 2293 int 2294 uaudio_round_blocksize(void *addr, int blk) 2295 { 2296 struct uaudio_softc *sc = addr; 2297 int bpf, pbpf, rbpf; 2298 2299 DPRINTF(("uaudio_round_blocksize: p.mbpf=%d r.mbpf=%d\n", 2300 sc->sc_playchan.max_bytes_per_frame, 2301 sc->sc_recchan.max_bytes_per_frame)); 2302 2303 pbpf = rbpf = 0; 2304 if (sc->sc_mode & AUMODE_PLAY) { 2305 pbpf = (sc->sc_playchan.max_bytes_per_frame) * 2306 sc->sc_playchan.nframes; 2307 } 2308 if (sc->sc_mode & AUMODE_RECORD) { 2309 rbpf = (sc->sc_recchan.max_bytes_per_frame) * 2310 sc->sc_recchan.nframes; 2311 } 2312 bpf = max(pbpf, rbpf); 2313 2314 if (blk < bpf) 2315 blk = bpf; 2316 2317 #ifdef DIAGNOSTIC 2318 if (blk <= 0) { 2319 printf("uaudio_round_blocksize: blk=%d\n", blk); 2320 blk = 512; 2321 } 2322 #endif 2323 2324 DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk)); 2325 return (blk); 2326 } 2327 2328 int 2329 uaudio_get_props(void *addr) 2330 { 2331 struct uaudio_softc *sc = addr; 2332 int props = 0; 2333 2334 if (!(sc->sc_quirks & UAUDIO_FLAG_DEPENDENT)) 2335 props |= AUDIO_PROP_INDEPENDENT; 2336 2337 if ((sc->sc_mode & (AUMODE_PLAY | AUMODE_RECORD)) == 2338 (AUMODE_PLAY | AUMODE_RECORD)) 2339 props |= AUDIO_PROP_FULLDUPLEX; 2340 2341 return props; 2342 } 2343 2344 void 2345 uaudio_get_default_params(void *addr, int mode, struct audio_params *p) 2346 { 2347 struct uaudio_softc *sc = addr; 2348 int flags, alt; 2349 2350 /* try aucat(1) defaults: 44100 Hz stereo s16le */ 2351 p->sample_rate = 44100; 2352 p->encoding = AUDIO_ENCODING_SLINEAR_LE; 2353 p->precision = 16; 2354 p->bps = 2; 2355 p->msb = 1; 2356 p->channels = 2; 2357 p->sw_code = NULL; 2358 p->factor = 1; 2359 2360 /* If the device doesn't support the current mode, there's no 2361 * need to find better parameters. 2362 */ 2363 if (!(sc->sc_mode & mode)) 2364 return; 2365 2366 flags = sc->sc_altflags; 2367 if (flags & HAS_16) 2368 ; 2369 else if (flags & HAS_24) 2370 p->precision = 24; 2371 else { 2372 p->precision = 8; 2373 if (flags & HAS_8) 2374 ; 2375 else if (flags & HAS_8U) 2376 p->encoding = AUDIO_ENCODING_ULINEAR_LE; 2377 else if (flags & HAS_MULAW) 2378 p->encoding = AUDIO_ENCODING_ULAW; 2379 else if (flags & HAS_ALAW) 2380 p->encoding = AUDIO_ENCODING_ALAW; 2381 } 2382 2383 alt = uaudio_match_alt(sc, p, mode); 2384 if (alt != -1) 2385 p->bps = sc->sc_alts[alt].asf1desc->bSubFrameSize; 2386 } 2387 2388 int 2389 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue, 2390 int wIndex, int len) 2391 { 2392 usb_device_request_t req; 2393 u_int8_t data[4]; 2394 usbd_status err; 2395 int val; 2396 2397 if (wValue == -1) 2398 return (0); 2399 2400 req.bmRequestType = type; 2401 req.bRequest = which; 2402 USETW(req.wValue, wValue); 2403 USETW(req.wIndex, wIndex); 2404 USETW(req.wLength, len); 2405 DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x " 2406 "wIndex=0x%04x len=%d\n", 2407 type, which, wValue, wIndex, len)); 2408 err = usbd_do_request(sc->sc_udev, &req, data); 2409 if (err) { 2410 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err))); 2411 return (-1); 2412 } 2413 switch (len) { 2414 case 1: 2415 val = data[0]; 2416 break; 2417 case 2: 2418 val = data[0] | (data[1] << 8); 2419 break; 2420 default: 2421 DPRINTF(("uaudio_get: bad length=%d\n", len)); 2422 return (-1); 2423 } 2424 DPRINTFN(2,("uaudio_get: val=%d\n", val)); 2425 return (val); 2426 } 2427 2428 void 2429 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue, 2430 int wIndex, int len, int val) 2431 { 2432 usb_device_request_t req; 2433 u_int8_t data[4]; 2434 usbd_status err; 2435 2436 if (wValue == -1) 2437 return; 2438 2439 req.bmRequestType = type; 2440 req.bRequest = which; 2441 USETW(req.wValue, wValue); 2442 USETW(req.wIndex, wIndex); 2443 USETW(req.wLength, len); 2444 switch (len) { 2445 case 1: 2446 data[0] = val; 2447 break; 2448 case 2: 2449 data[0] = val; 2450 data[1] = val >> 8; 2451 break; 2452 default: 2453 return; 2454 } 2455 DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x " 2456 "wIndex=0x%04x len=%d, val=%d\n", 2457 type, which, wValue, wIndex, len, val & 0xffff)); 2458 err = usbd_do_request(sc->sc_udev, &req, data); 2459 #ifdef UAUDIO_DEBUG 2460 if (err) 2461 DPRINTF(("uaudio_set: err=%d\n", err)); 2462 #endif 2463 } 2464 2465 int 2466 uaudio_signext(int type, int val) 2467 { 2468 if (!MIX_UNSIGNED(type)) { 2469 if (MIX_SIZE(type) == 2) 2470 val = (int16_t)val; 2471 else 2472 val = (int8_t)val; 2473 } 2474 return (val); 2475 } 2476 2477 int 2478 uaudio_unsignext(int type, int val) 2479 { 2480 if (!MIX_UNSIGNED(type)) { 2481 if (MIX_SIZE(type) == 2) 2482 val = (u_int16_t)val; 2483 else 2484 val = (u_int8_t)val; 2485 } 2486 return (val); 2487 } 2488 2489 int 2490 uaudio_value2bsd(struct mixerctl *mc, int val) 2491 { 2492 int range; 2493 DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ", 2494 mc->type, val, mc->minval, mc->maxval)); 2495 if (mc->type == MIX_ON_OFF) { 2496 val = (val != 0); 2497 } else if (mc->type == MIX_SELECTOR) { 2498 if (val < mc->minval || val > mc->maxval) 2499 val = mc->minval; 2500 } else { 2501 range = mc->maxval - mc->minval; 2502 if (range == 0) 2503 val = 0; 2504 else 2505 val = 255 * (uaudio_signext(mc->type, val) - 2506 mc->minval) / range; 2507 } 2508 DPRINTFN(5, ("val'=%d\n", val)); 2509 return (val); 2510 } 2511 2512 int 2513 uaudio_bsd2value(struct mixerctl *mc, int val) 2514 { 2515 DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ", 2516 mc->type, val, mc->minval, mc->maxval)); 2517 if (mc->type == MIX_ON_OFF) { 2518 val = (val != 0); 2519 } else if (mc->type == MIX_SELECTOR) { 2520 if (val < mc->minval || val > mc->maxval) 2521 val = mc->minval; 2522 } else 2523 val = uaudio_unsignext(mc->type, 2524 val * (mc->maxval - mc->minval) / 255 + mc->minval); 2525 DPRINTFN(5, ("val'=%d\n", val)); 2526 return (val); 2527 } 2528 2529 int 2530 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc, 2531 int chan) 2532 { 2533 int val; 2534 2535 DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan)); 2536 val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan], 2537 mc->wIndex, MIX_SIZE(mc->type)); 2538 return (uaudio_value2bsd(mc, val)); 2539 } 2540 2541 void 2542 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc, 2543 int chan, int val) 2544 { 2545 val = uaudio_bsd2value(mc, val); 2546 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan], 2547 mc->wIndex, MIX_SIZE(mc->type), val); 2548 } 2549 2550 int 2551 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp) 2552 { 2553 struct uaudio_softc *sc = addr; 2554 struct mixerctl *mc; 2555 int i, n, vals[MIX_MAX_CHAN], val; 2556 2557 DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev)); 2558 2559 if (sc->sc_dying) 2560 return (EIO); 2561 2562 n = cp->dev - UAC_NCLASSES; 2563 if (n < 0 || n >= sc->sc_nctls) 2564 return (ENXIO); 2565 mc = &sc->sc_ctls[n]; 2566 2567 if (mc->type == MIX_ON_OFF) { 2568 if (cp->type != AUDIO_MIXER_ENUM) 2569 return (EINVAL); 2570 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0); 2571 } else if (mc->type == MIX_SELECTOR) { 2572 if (cp->type != AUDIO_MIXER_ENUM) 2573 return (EINVAL); 2574 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0); 2575 } else { 2576 if (cp->type != AUDIO_MIXER_VALUE) 2577 return (EINVAL); 2578 if (cp->un.value.num_channels != 1 && 2579 cp->un.value.num_channels != mc->nchan) 2580 return (EINVAL); 2581 for (i = 0; i < mc->nchan; i++) 2582 vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i); 2583 if (cp->un.value.num_channels == 1 && mc->nchan != 1) { 2584 for (val = 0, i = 0; i < mc->nchan; i++) 2585 val += vals[i]; 2586 vals[0] = val / mc->nchan; 2587 } 2588 for (i = 0; i < cp->un.value.num_channels; i++) 2589 cp->un.value.level[i] = vals[i]; 2590 } 2591 2592 return (0); 2593 } 2594 2595 int 2596 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp) 2597 { 2598 struct uaudio_softc *sc = addr; 2599 struct mixerctl *mc; 2600 int i, n, vals[MIX_MAX_CHAN]; 2601 2602 DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev)); 2603 if (sc->sc_dying) 2604 return (EIO); 2605 2606 n = cp->dev - UAC_NCLASSES; 2607 if (n < 0 || n >= sc->sc_nctls) 2608 return (ENXIO); 2609 mc = &sc->sc_ctls[n]; 2610 2611 if (mc->type == MIX_ON_OFF) { 2612 if (cp->type != AUDIO_MIXER_ENUM) 2613 return (EINVAL); 2614 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord); 2615 } else if (mc->type == MIX_SELECTOR) { 2616 if (cp->type != AUDIO_MIXER_ENUM) 2617 return (EINVAL); 2618 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord); 2619 } else { 2620 if (cp->type != AUDIO_MIXER_VALUE) 2621 return (EINVAL); 2622 if (cp->un.value.num_channels == 1) 2623 for (i = 0; i < mc->nchan; i++) 2624 vals[i] = cp->un.value.level[0]; 2625 else if (cp->un.value.num_channels == mc->nchan) 2626 for (i = 0; i < mc->nchan; i++) 2627 vals[i] = cp->un.value.level[i]; 2628 else 2629 return (EINVAL); 2630 for (i = 0; i < mc->nchan; i++) 2631 uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]); 2632 } 2633 return (0); 2634 } 2635 2636 int 2637 uaudio_trigger_input(void *addr, void *start, void *end, int blksize, 2638 void (*intr)(void *), void *arg, 2639 struct audio_params *param) 2640 { 2641 struct uaudio_softc *sc = addr; 2642 struct chan *ch = &sc->sc_recchan; 2643 usbd_status err; 2644 int i, s; 2645 2646 if (sc->sc_dying) 2647 return (EIO); 2648 2649 DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p " 2650 "blksize=%d\n", sc, start, end, blksize)); 2651 2652 uaudio_chan_set_param(ch, start, end, blksize); 2653 DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d " 2654 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 2655 ch->fraction)); 2656 2657 err = uaudio_chan_alloc_buffers(sc, ch); 2658 if (err) 2659 return (EIO); 2660 2661 err = uaudio_chan_open(sc, ch); 2662 if (err) { 2663 uaudio_chan_free_buffers(sc, ch); 2664 return (EIO); 2665 } 2666 2667 ch->intr = intr; 2668 ch->arg = arg; 2669 2670 s = splusb(); 2671 for (i = 0; i < UAUDIO_NCHANBUFS; i++) 2672 uaudio_chan_rtransfer(ch); 2673 splx(s); 2674 2675 return (0); 2676 } 2677 2678 int 2679 uaudio_trigger_output(void *addr, void *start, void *end, int blksize, 2680 void (*intr)(void *), void *arg, 2681 struct audio_params *param) 2682 { 2683 struct uaudio_softc *sc = addr; 2684 struct chan *ch = &sc->sc_playchan; 2685 usbd_status err; 2686 int i, s; 2687 2688 if (sc->sc_dying) 2689 return (EIO); 2690 2691 DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p " 2692 "blksize=%d\n", sc, start, end, blksize)); 2693 2694 uaudio_chan_set_param(ch, start, end, blksize); 2695 DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d " 2696 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, 2697 ch->fraction)); 2698 2699 err = uaudio_chan_alloc_buffers(sc, ch); 2700 if (err) 2701 return (EIO); 2702 2703 err = uaudio_chan_open(sc, ch); 2704 if (err) { 2705 uaudio_chan_free_buffers(sc, ch); 2706 return (EIO); 2707 } 2708 2709 ch->intr = intr; 2710 ch->arg = arg; 2711 2712 s = splusb(); 2713 for (i = 0; i < UAUDIO_NCHANBUFS; i++) 2714 uaudio_chan_ptransfer(ch); 2715 if (ch->sync_pipe) { 2716 for (i = 0; i < UAUDIO_NSYNCBUFS; i++) 2717 uaudio_chan_psync_transfer(ch); 2718 } 2719 splx(s); 2720 2721 return (0); 2722 } 2723 2724 /* Set up a pipe for a channel. */ 2725 usbd_status 2726 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch) 2727 { 2728 struct as_info *as = &sc->sc_alts[ch->altidx]; 2729 int endpt = as->edesc->bEndpointAddress; 2730 usbd_status err; 2731 2732 DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n", 2733 endpt, ch->sample_rate, as->alt)); 2734 2735 /* Set alternate interface corresponding to the mode. */ 2736 err = usbd_set_interface(as->ifaceh, as->alt); 2737 if (err) { 2738 DPRINTF(("%s: usbd_set_interface failed\n", __func__)); 2739 return (err); 2740 } 2741 2742 /* 2743 * If just one sampling rate is supported, 2744 * no need to call uaudio_set_speed(). 2745 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request. 2746 */ 2747 if (as->asf1desc->bSamFreqType != 1) { 2748 err = uaudio_set_speed(sc, endpt, ch->sample_rate); 2749 if (err) 2750 DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n", 2751 usbd_errstr(err))); 2752 } 2753 2754 if (sc->sc_quirks & UAUDIO_FLAG_EMU0202) 2755 uaudio_set_speed_emu0202(ch); 2756 2757 ch->pipe = 0; 2758 ch->sync_pipe = 0; 2759 DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt)); 2760 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe); 2761 if (err) { 2762 printf("%s: error creating pipe: err=%s endpt=0x%02x\n", 2763 __func__, usbd_errstr(err), endpt); 2764 return err; 2765 } 2766 if (as->edesc1 != NULL) { 2767 endpt = as->edesc1->bEndpointAddress; 2768 DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt)); 2769 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe); 2770 if (err) { 2771 printf("%s: error creating sync-pipe: err=%s endpt=0x%02x\n", 2772 __func__, usbd_errstr(err), endpt); 2773 } 2774 } 2775 return err; 2776 } 2777 2778 void 2779 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch) 2780 { 2781 struct as_info *as = &sc->sc_alts[ch->altidx]; 2782 2783 as->sc_busy = 0; 2784 if (sc->sc_nullalt >= 0) { 2785 DPRINTF(("uaudio_chan_close: set null alt=%d\n", 2786 sc->sc_nullalt)); 2787 usbd_set_interface(as->ifaceh, sc->sc_nullalt); 2788 } 2789 if (ch->pipe) { 2790 usbd_abort_pipe(ch->pipe); 2791 usbd_close_pipe(ch->pipe); 2792 } 2793 if (ch->sync_pipe) { 2794 usbd_abort_pipe(ch->sync_pipe); 2795 usbd_close_pipe(ch->sync_pipe); 2796 } 2797 } 2798 2799 usbd_status 2800 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch) 2801 { 2802 struct as_info *as = &sc->sc_alts[ch->altidx]; 2803 usbd_xfer_handle xfer; 2804 void *buf; 2805 int i, size; 2806 2807 DPRINTF(("%s: max_bytes_per_frame=%d nframes=%d\n", __func__, 2808 ch->max_bytes_per_frame, ch->nframes)); 2809 2810 size = ch->max_bytes_per_frame * ch->nframes; 2811 for (i = 0; i < UAUDIO_NCHANBUFS; i++) { 2812 xfer = usbd_alloc_xfer(sc->sc_udev); 2813 if (xfer == 0) 2814 goto bad; 2815 ch->chanbufs[i].xfer = xfer; 2816 buf = usbd_alloc_buffer(xfer, size); 2817 if (buf == 0) { 2818 i++; 2819 goto bad; 2820 } 2821 ch->chanbufs[i].buffer = buf; 2822 ch->chanbufs[i].chan = ch; 2823 } 2824 if (as->edesc1 != NULL) { 2825 size = (ch->hi_speed ? 4 : 3) * ch->nsync_frames; 2826 for (i = 0; i < UAUDIO_NSYNCBUFS; i++) { 2827 xfer = usbd_alloc_xfer(sc->sc_udev); 2828 if (xfer == 0) 2829 goto bad_sync; 2830 ch->syncbufs[i].xfer = xfer; 2831 buf = usbd_alloc_buffer(xfer, size); 2832 if (buf == 0) { 2833 i++; 2834 goto bad_sync; 2835 } 2836 ch->syncbufs[i].buffer = buf; 2837 ch->syncbufs[i].chan = ch; 2838 } 2839 } 2840 2841 return (USBD_NORMAL_COMPLETION); 2842 2843 bad: 2844 while (--i >= 0) 2845 /* implicit buffer free */ 2846 usbd_free_xfer(ch->chanbufs[i].xfer); 2847 return (USBD_NOMEM); 2848 2849 bad_sync: 2850 while (--i >= 0) 2851 /* implicit buffer free */ 2852 usbd_free_xfer(ch->syncbufs[i].xfer); 2853 return (USBD_NOMEM); 2854 2855 } 2856 2857 void 2858 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch) 2859 { 2860 struct as_info *as = &sc->sc_alts[ch->altidx]; 2861 int i; 2862 2863 for (i = 0; i < UAUDIO_NCHANBUFS; i++) 2864 usbd_free_xfer(ch->chanbufs[i].xfer); 2865 if (as->edesc1 != NULL) { 2866 for (i = 0; i < UAUDIO_NSYNCBUFS; i++) 2867 usbd_free_xfer(ch->syncbufs[i].xfer); 2868 } 2869 } 2870 2871 /* Called at splusb() */ 2872 void 2873 uaudio_chan_ptransfer(struct chan *ch) 2874 { 2875 struct chanbuf *cb; 2876 u_char *pos; 2877 int i, n, size, residue, total; 2878 int s; 2879 2880 if (ch->sc->sc_dying) 2881 return; 2882 2883 /* Pick the next channel buffer. */ 2884 cb = &ch->chanbufs[ch->curchanbuf]; 2885 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 2886 ch->curchanbuf = 0; 2887 2888 /* Compute the size of each frame in the next transfer. */ 2889 residue = ch->residue; 2890 total = 0; 2891 for (i = 0; i < ch->nframes; i++) { 2892 size = ch->bytes_per_frame; 2893 residue += ch->fraction; 2894 if (residue >= ch->frac_denom) { 2895 if ((ch->sc->sc_altflags & UA_NOFRAC) == 0) 2896 size += ch->sample_size; 2897 residue -= ch->frac_denom; 2898 } 2899 cb->sizes[i] = size; 2900 total += size; 2901 } 2902 ch->residue = residue; 2903 cb->size = total; 2904 2905 /* 2906 * Transfer data from upper layer buffer to channel buffer. Be sure 2907 * to let the upper layer know each time a block is moved, so it can 2908 * add more. 2909 */ 2910 pos = cb->buffer; 2911 while (total > 0) { 2912 n = min(total, ch->end - ch->cur); 2913 n = min(n, ch->blksize - ch->transferred); 2914 memcpy(pos, ch->cur, n); 2915 total -= n; 2916 pos += n; 2917 ch->cur += n; 2918 if (ch->cur >= ch->end) 2919 ch->cur = ch->start; 2920 2921 ch->transferred += n; 2922 /* Call back to upper layer */ 2923 if (ch->transferred >= ch->blksize) { 2924 DPRINTFN(5,("uaudio_chan_ptransfer: call %p(%p)\n", 2925 ch->intr, ch->arg)); 2926 s = splaudio(); 2927 ch->intr(ch->arg); 2928 splx(s); 2929 ch->transferred -= ch->blksize; 2930 } 2931 } 2932 2933 #ifdef UAUDIO_DEBUG 2934 if (uaudiodebug > 8) { 2935 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n", 2936 cb->buffer, ch->residue)); 2937 for (i = 0; i < ch->nframes; i++) { 2938 DPRINTF((" [%d] length %d\n", i, cb->sizes[i])); 2939 } 2940 } 2941 #endif 2942 2943 DPRINTFN(5,("uaudio_chan_ptransfer: transfer xfer=%p\n", cb->xfer)); 2944 /* Fill the request */ 2945 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, 2946 ch->nframes, USBD_NO_COPY, 2947 uaudio_chan_pintr); 2948 2949 (void)usbd_transfer(cb->xfer); 2950 } 2951 2952 void 2953 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv, 2954 usbd_status status) 2955 { 2956 struct chanbuf *cb = priv; 2957 struct chan *ch = cb->chan; 2958 u_int32_t count; 2959 2960 /* Return if we are aborting. */ 2961 if (status == USBD_CANCELLED) 2962 return; 2963 2964 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 2965 DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n", 2966 count, ch->transferred)); 2967 #ifdef DIAGNOSTIC 2968 if (count != cb->size) { 2969 printf("uaudio_chan_pintr: count(%d) != size(%d)\n", 2970 count, cb->size); 2971 } 2972 #endif 2973 2974 /* start next transfer */ 2975 uaudio_chan_ptransfer(ch); 2976 } 2977 2978 /* Called at splusb() */ 2979 void 2980 uaudio_chan_psync_transfer(struct chan *ch) 2981 { 2982 struct syncbuf *sb; 2983 int i, size, total = 0; 2984 2985 if (ch->sc->sc_dying) 2986 return; 2987 2988 /* Pick the next sync buffer. */ 2989 sb = &ch->syncbufs[ch->cursyncbuf]; 2990 if (++ch->cursyncbuf >= UAUDIO_NSYNCBUFS) 2991 ch->cursyncbuf = 0; 2992 2993 size = ch->hi_speed ? 4 : 3; 2994 for (i = 0; i < ch->nsync_frames; i++) { 2995 sb->sizes[i] = size; 2996 sb->offsets[i] = total; 2997 total += size; 2998 } 2999 sb->size = total; 3000 3001 DPRINTFN(5,("%s: transfer xfer=%p\n", __func__, sb->xfer)); 3002 /* Fill the request */ 3003 usbd_setup_isoc_xfer(sb->xfer, ch->sync_pipe, sb, sb->sizes, 3004 ch->nsync_frames, USBD_NO_COPY, uaudio_chan_psync_intr); 3005 3006 (void)usbd_transfer(sb->xfer); 3007 } 3008 3009 void 3010 uaudio_chan_psync_intr(usbd_xfer_handle xfer, usbd_private_handle priv, 3011 usbd_status status) 3012 { 3013 struct syncbuf *sb = priv; 3014 struct chan *ch = sb->chan; 3015 u_int32_t count, tmp; 3016 u_int32_t freq, freq_w, freq_f; 3017 int i, pos, size; 3018 3019 /* Return if we are aborting. */ 3020 if (status == USBD_CANCELLED) 3021 return; 3022 3023 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 3024 DPRINTFN(5,("%s: count=%d\n", __func__, count)); 3025 3026 size = ch->hi_speed ? 4 : 3; 3027 for (i = 0; count > 0 && i < ch->nsync_frames; i++) { 3028 if (sb->sizes[i] != size) 3029 continue; 3030 count -= size; 3031 pos = sb->offsets[i]; 3032 if (ch->hi_speed) { 3033 /* 16.16 (12.13) -> 16.16 (12.16) */ 3034 freq = sb->buffer[pos+3] << 24 | 3035 sb->buffer[pos+2] << 16 | 3036 sb->buffer[pos+1] << 8 | 3037 sb->buffer[pos]; 3038 } else { 3039 /* 10.14 (10.10) -> 16.16 (10.16) */ 3040 freq = sb->buffer[pos+2] << 18 | 3041 sb->buffer[pos+1] << 10 | 3042 sb->buffer[pos] << 2; 3043 } 3044 freq_w = (freq >> 16) & (ch->hi_speed ? 0x0fff : 0x03ff); 3045 freq_f = freq & 0xffff; 3046 DPRINTFN(5,("%s: freq = %d %d/%d\n", __func__, freq_w, freq_f, 3047 ch->frac_denom)); 3048 tmp = freq_w * ch->sample_size; 3049 if (tmp + (freq_f ? ch->sample_size : 0) > 3050 ch->max_bytes_per_frame) { 3051 DPRINTF(("%s: packet size request too large: %d/%d/%d\n", 3052 __func__, tmp, ch->max_bytes_per_frame, ch->maxpktsize)); 3053 } else { 3054 ch->bytes_per_frame = tmp; 3055 ch->fraction = freq_f; 3056 } 3057 } 3058 3059 /* start next transfer */ 3060 uaudio_chan_psync_transfer(ch); 3061 } 3062 3063 /* Called at splusb() */ 3064 void 3065 uaudio_chan_rtransfer(struct chan *ch) 3066 { 3067 struct chanbuf *cb; 3068 int i, size, residue, total; 3069 3070 if (ch->sc->sc_dying) 3071 return; 3072 3073 /* Pick the next channel buffer. */ 3074 cb = &ch->chanbufs[ch->curchanbuf]; 3075 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS) 3076 ch->curchanbuf = 0; 3077 3078 /* Compute the size of each frame in the next transfer. */ 3079 residue = ch->residue; 3080 total = 0; 3081 for (i = 0; i < ch->nframes; i++) { 3082 size = ch->bytes_per_frame; 3083 cb->sizes[i] = size; 3084 cb->offsets[i] = total; 3085 total += size; 3086 } 3087 ch->residue = residue; 3088 cb->size = total; 3089 3090 #ifdef UAUDIO_DEBUG 3091 if (uaudiodebug > 8) { 3092 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n", 3093 cb->buffer, ch->residue)); 3094 for (i = 0; i < ch->nframes; i++) { 3095 DPRINTF((" [%d] length %d\n", i, cb->sizes[i])); 3096 } 3097 } 3098 #endif 3099 3100 DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer)); 3101 /* Fill the request */ 3102 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, 3103 ch->nframes, USBD_NO_COPY, 3104 uaudio_chan_rintr); 3105 3106 (void)usbd_transfer(cb->xfer); 3107 } 3108 3109 void 3110 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv, 3111 usbd_status status) 3112 { 3113 struct chanbuf *cb = priv; 3114 struct chan *ch = cb->chan; 3115 u_int16_t pos; 3116 u_int32_t count; 3117 int s, i, n, frsize; 3118 3119 /* Return if we are aborting. */ 3120 if (status == USBD_CANCELLED) 3121 return; 3122 3123 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 3124 DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n", 3125 count, ch->transferred)); 3126 3127 /* count < cb->size is normal for asynchronous source */ 3128 #ifdef DIAGNOSTIC 3129 if (count > cb->size) { 3130 printf("uaudio_chan_rintr: count(%d) > size(%d)\n", 3131 count, cb->size); 3132 } 3133 #endif 3134 3135 /* 3136 * Transfer data from channel buffer to upper layer buffer, taking 3137 * care of wrapping the upper layer buffer. 3138 */ 3139 for (i = 0; i < ch->nframes; i++) { 3140 frsize = cb->sizes[i]; 3141 pos = cb->offsets[i]; 3142 while (frsize > 0) { 3143 n = min(frsize, ch->end - ch->cur); 3144 n = min(n, ch->blksize - ch->transferred); 3145 memcpy(ch->cur, cb->buffer + pos, n); 3146 frsize -= n; 3147 pos += n; 3148 ch->cur += n; 3149 if (ch->cur >= ch->end) 3150 ch->cur = ch->start; 3151 3152 ch->transferred += n; 3153 /* Call back to upper layer */ 3154 if (ch->transferred >= ch->blksize) { 3155 DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n", 3156 ch->intr, ch->arg)); 3157 s = splaudio(); 3158 ch->intr(ch->arg); 3159 splx(s); 3160 ch->transferred -= ch->blksize; 3161 } 3162 if (count < n) 3163 printf("%s: count < n\n", __func__); 3164 else 3165 count -= n; 3166 } 3167 } 3168 if (count != 0) { 3169 printf("%s: transfer count - frame total = %d\n", 3170 __func__, count); 3171 } 3172 3173 /* start next transfer */ 3174 uaudio_chan_rtransfer(ch); 3175 } 3176 3177 void 3178 uaudio_chan_init(struct chan *ch, int mode, int altidx, 3179 const struct audio_params *param) 3180 { 3181 struct as_info *ai = &ch->sc->sc_alts[altidx]; 3182 int samples_per_frame, ival, use_maxpkt = 0; 3183 3184 if (ai->attributes & UA_SED_MAXPACKETSONLY) { 3185 DPRINTF(("%s: alt %d needs maxpktsize packets\n", 3186 __func__, altidx)); 3187 use_maxpkt = 1; 3188 } 3189 if (mode == AUMODE_RECORD) { 3190 DPRINTF(("%s: using maxpktsize packets for record channel\n", 3191 __func__)); 3192 use_maxpkt = 1; 3193 } 3194 3195 ch->altidx = altidx; 3196 ch->maxpktsize = UGETW(ai->edesc->wMaxPacketSize); 3197 ch->sample_rate = param->sample_rate; 3198 ch->sample_size = param->channels * param->bps; 3199 ch->usb_fps = USB_FRAMES_PER_SECOND; 3200 ch->hi_speed = ch->sc->sc_udev->speed == USB_SPEED_HIGH; 3201 if (ch->hi_speed) { 3202 ch->usb_fps *= 8; 3203 /* 3204 * Polling interval is considered a frame, as opposed to 3205 * micro-frame being a frame. 3206 */ 3207 ival = ch->sc->sc_alts[altidx].edesc->bInterval; 3208 if (ival > 0 && ival <= 4) 3209 ch->usb_fps >>= (ival - 1); 3210 DPRINTF(("%s: detected USB high-speed with ival %d\n", 3211 __func__, ival)); 3212 } 3213 3214 /* 3215 * Use UAUDIO_MIN_FRAMES here, so uaudio_round_blocksize() can 3216 * make sure the blocksize duration will be > 1 USB frame. 3217 */ 3218 samples_per_frame = ch->sample_rate / ch->usb_fps; 3219 if (!use_maxpkt) { 3220 ch->fraction = ch->sample_rate % ch->usb_fps; 3221 if (samples_per_frame * ch->sample_size > ch->maxpktsize) { 3222 DPRINTF(("%s: packet size %d too big, max %d\n", 3223 __func__, ch->bytes_per_frame, ch->maxpktsize)); 3224 samples_per_frame = ch->maxpktsize / ch->sample_size; 3225 } 3226 ch->bytes_per_frame = samples_per_frame * ch->sample_size; 3227 ch->nframes = UAUDIO_MIN_FRAMES; 3228 } else { 3229 ch->fraction = 0; 3230 ch->bytes_per_frame = ch->maxpktsize; 3231 ch->nframes = UAUDIO_MIN_FRAMES * samples_per_frame * 3232 ch->sample_size / ch->maxpktsize; 3233 } 3234 if (ch->nframes > UAUDIO_MAX_FRAMES) 3235 ch->nframes = UAUDIO_MAX_FRAMES; 3236 else if (ch->nframes < 1) 3237 ch->nframes = 1; 3238 3239 ch->max_bytes_per_frame = ch->bytes_per_frame; 3240 if (!use_maxpkt) 3241 ch->max_bytes_per_frame += ch->sample_size; 3242 if (ch->max_bytes_per_frame > ch->maxpktsize) 3243 ch->max_bytes_per_frame = ch->maxpktsize; 3244 3245 ch->residue = 0; 3246 ch->frac_denom = ch->usb_fps; 3247 if (ai->edesc1 != NULL) { 3248 /* 3249 * The lower 16-bits of the sync request represent 3250 * fractional samples. Scale up the fraction here once 3251 * so all fractions are using the same denominator. 3252 */ 3253 ch->frac_denom = 1 << 16; 3254 ch->fraction = (ch->fraction * ch->frac_denom) / ch->usb_fps; 3255 3256 /* 3257 * Have to set nsync_frames somewhere. We can request 3258 * a lot of sync data; the device will reply when it's 3259 * ready, with empty frames meaning to keep using the 3260 * current rate. 3261 */ 3262 ch->nsync_frames = UAUDIO_MAX_FRAMES; 3263 } 3264 DPRINTF(("%s: residual sample fraction: %d/%d\n", __func__, 3265 ch->fraction, ch->frac_denom)); 3266 } 3267 3268 void 3269 uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize) 3270 { 3271 ch->start = start; 3272 ch->end = end; 3273 ch->cur = start; 3274 ch->transferred = 0; 3275 ch->curchanbuf = 0; 3276 ch->blksize = blksize; 3277 3278 /* 3279 * Recompute nframes based on blksize, but make sure nframes 3280 * is not longer in time duration than blksize. 3281 */ 3282 ch->nframes = ch->blksize * ch->usb_fps / 3283 (ch->bytes_per_frame * ch->usb_fps + 3284 ch->sample_size * ch->fraction); 3285 if (ch->nframes > UAUDIO_MAX_FRAMES) 3286 ch->nframes = UAUDIO_MAX_FRAMES; 3287 else if (ch->nframes < 1) 3288 ch->nframes = 1; 3289 3290 ch->reqms = ch->bytes_per_frame / ch->sample_size * 3291 ch->nframes * 1000 / ch->sample_rate; 3292 3293 DPRINTF(("%s: alt=%d blk=%d maxpkt=%u bpf=%u rate=%u nframes=%u reqms=%u\n", 3294 __func__, ch->altidx, ch->blksize, ch->maxpktsize, 3295 ch->bytes_per_frame, ch->sample_rate, ch->nframes, ch->reqms)); 3296 } 3297 3298 int 3299 uaudio_match_alt_rate(void *addr, int alt, int rate) 3300 { 3301 struct uaudio_softc *sc = addr; 3302 const struct usb_audio_streaming_type1_descriptor *a1d; 3303 int i, j, r; 3304 3305 a1d = sc->sc_alts[alt].asf1desc; 3306 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) { 3307 if ((UA_SAMP_LO(a1d) <= rate) && 3308 (UA_SAMP_HI(a1d) >= rate)) { 3309 return rate; 3310 } else { 3311 if (UA_SAMP_LO(a1d) > rate) 3312 return UA_SAMP_LO(a1d); 3313 else 3314 return UA_SAMP_HI(a1d); 3315 } 3316 } else { 3317 for (i = 0; i < 100; i++) { 3318 for (j = 0; j < a1d->bSamFreqType; j++) { 3319 r = UA_GETSAMP(a1d, j); 3320 if ((r - (500 * i) <= rate) && 3321 (r + (500 * i) >= rate)) 3322 return r; 3323 } 3324 } 3325 /* assumes rates are listed in order from lowest to highest */ 3326 if (rate < UA_GETSAMP(a1d, 0)) 3327 j = 0; 3328 else 3329 j = a1d->bSamFreqType - 1; 3330 return UA_GETSAMP(a1d, j); 3331 } 3332 DPRINTF(("%s: could not match rate\n", __func__)); 3333 return rate; 3334 } 3335 3336 int 3337 uaudio_match_alt(void *addr, struct audio_params *p, int mode) 3338 { 3339 struct uaudio_softc *sc = addr; 3340 const struct usb_audio_streaming_type1_descriptor *a1d; 3341 int i, j, dir, rate; 3342 int alts_eh, alts_ch, ualt; 3343 3344 DPRINTF(("%s: mode=%s rate=%d ch=%d pre=%d bps=%d enc=%d\n", 3345 __func__, mode == AUMODE_RECORD ? "rec" : "play", p->sample_rate, 3346 p->channels, p->precision, p->bps, p->encoding)); 3347 3348 alts_eh = 0; 3349 for (i = 0; i < sc->sc_nalts; i++) { 3350 dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress); 3351 if ((mode == AUMODE_RECORD && dir != UE_DIR_IN) || 3352 (mode == AUMODE_PLAY && dir == UE_DIR_IN)) 3353 continue; 3354 DPRINTFN(6,("%s: matched %s alt %d for direction\n", __func__, 3355 mode == AUMODE_RECORD ? "rec" : "play", i)); 3356 if (sc->sc_alts[i].encoding != p->encoding) 3357 continue; 3358 a1d = sc->sc_alts[i].asf1desc; 3359 if (a1d->bBitResolution != p->precision) 3360 continue; 3361 alts_eh |= 1 << i; 3362 DPRINTFN(6,("%s: matched %s alt %d for enc/pre\n", __func__, 3363 mode == AUMODE_RECORD ? "rec" : "play", i)); 3364 } 3365 if (alts_eh == 0) { 3366 DPRINTF(("%s: could not match dir/enc/prec\n", __func__)); 3367 return -1; 3368 } 3369 3370 alts_ch = 0; 3371 for (i = 0; i < 3; i++) { 3372 for (j = 0; j < sc->sc_nalts; j++) { 3373 if (!(alts_eh & (1 << j))) 3374 continue; 3375 a1d = sc->sc_alts[j].asf1desc; 3376 if (a1d->bNrChannels == p->channels) { 3377 alts_ch |= 1 << j; 3378 DPRINTFN(6,("%s: matched alt %d for channels\n", 3379 __func__, j)); 3380 } 3381 } 3382 if (alts_ch) 3383 break; 3384 if (p->channels == 2) 3385 p->channels = 1; 3386 else 3387 p->channels = 2; 3388 } 3389 if (!alts_ch) { 3390 /* just use the first alt that matched the encoding */ 3391 for (i = 0; i < sc->sc_nalts; i++) 3392 if (alts_eh & (1 << i)) 3393 break; 3394 alts_ch = 1 << i; 3395 a1d = sc->sc_alts[i].asf1desc; 3396 p->channels = a1d->bNrChannels; 3397 } 3398 3399 ualt = -1; 3400 for (i = 0; i < sc->sc_nalts; i++) { 3401 if (alts_ch & (1 << i)) { 3402 rate = uaudio_match_alt_rate(sc, i, p->sample_rate); 3403 if (rate - 50 <= p->sample_rate && 3404 rate + 50 >= p->sample_rate) { 3405 DPRINTFN(6,("%s: alt %d matched rate %d with %d\n", 3406 __func__, i, p->sample_rate, rate)); 3407 p->sample_rate = rate; 3408 break; 3409 } 3410 } 3411 } 3412 if (i < sc->sc_nalts) { 3413 ualt = i; 3414 } else { 3415 for (i = 0; i < sc->sc_nalts; i++) { 3416 if (alts_ch & (1 << i)) { 3417 ualt = i; 3418 p->sample_rate = uaudio_match_alt_rate(sc, 3419 i, p->sample_rate); 3420 break; 3421 } 3422 } 3423 } 3424 3425 return ualt; 3426 } 3427 3428 int 3429 uaudio_set_params(void *addr, int setmode, int usemode, 3430 struct audio_params *play, struct audio_params *rec) 3431 { 3432 struct uaudio_softc *sc = addr; 3433 int flags = sc->sc_altflags; 3434 int i; 3435 int paltidx = -1, raltidx = -1; 3436 struct audio_params *p; 3437 int mode; 3438 3439 if (sc->sc_dying) 3440 return (EIO); 3441 3442 if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) || 3443 ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL)) 3444 return (EBUSY); 3445 3446 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) 3447 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0; 3448 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) 3449 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0; 3450 3451 /* Some uaudio devices are unidirectional. Don't try to find a 3452 matching mode for the unsupported direction. */ 3453 setmode &= sc->sc_mode; 3454 3455 for (mode = AUMODE_RECORD; mode != -1; 3456 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 3457 if ((setmode & mode) == 0) 3458 continue; 3459 3460 p = (mode == AUMODE_PLAY) ? play : rec; 3461 3462 switch (p->precision) { 3463 case 24: 3464 if (!(flags & HAS_24)) { 3465 if (flags & HAS_16) 3466 p->precision = 16; 3467 else 3468 p->precision = 8; 3469 } 3470 break; 3471 case 16: 3472 if (!(flags & HAS_16)) { 3473 if (flags & HAS_24) 3474 p->precision = 24; 3475 else 3476 p->precision = 8; 3477 } 3478 break; 3479 case 8: 3480 if (!(flags & HAS_8) && !(flags & HAS_8U)) { 3481 if (flags & HAS_16) 3482 p->precision = 16; 3483 else 3484 p->precision = 24; 3485 } 3486 break; 3487 } 3488 3489 i = uaudio_match_alt(sc, p, mode); 3490 if (i < 0) { 3491 DPRINTF(("%s: uaudio_match_alt failed for %s\n", 3492 __func__, mode == AUMODE_RECORD ? "rec" : "play")); 3493 continue; 3494 } 3495 3496 p->sw_code = NULL; 3497 p->factor = 1; 3498 3499 p->bps = sc->sc_alts[i].asf1desc->bSubFrameSize; 3500 p->msb = 1; 3501 3502 if (mode == AUMODE_PLAY) 3503 paltidx = i; 3504 else 3505 raltidx = i; 3506 } 3507 3508 if (setmode & AUMODE_PLAY) { 3509 if (paltidx == -1) { 3510 DPRINTF(("%s: did not find alt for playback\n", 3511 __func__)); 3512 return (EINVAL); 3513 } 3514 /* XXX abort transfer if currently happening? */ 3515 uaudio_chan_init(&sc->sc_playchan, AUMODE_PLAY, paltidx, play); 3516 } 3517 if (setmode & AUMODE_RECORD) { 3518 if (raltidx == -1) { 3519 DPRINTF(("%s: did not find alt for recording\n", 3520 __func__)); 3521 return (EINVAL); 3522 } 3523 /* XXX abort transfer if currently happening? */ 3524 uaudio_chan_init(&sc->sc_recchan, AUMODE_RECORD, raltidx, rec); 3525 } 3526 3527 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1) 3528 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1; 3529 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1) 3530 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1; 3531 3532 DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n", 3533 sc->sc_playchan.altidx, sc->sc_recchan.altidx, 3534 (sc->sc_playchan.altidx >= 0) 3535 ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting 3536 : -1, 3537 (sc->sc_recchan.altidx >= 0) 3538 ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting 3539 : -1)); 3540 3541 return (0); 3542 } 3543 3544 usbd_status 3545 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed) 3546 { 3547 usb_device_request_t req; 3548 u_int8_t data[3]; 3549 3550 DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed)); 3551 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT; 3552 req.bRequest = SET_CUR; 3553 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0); 3554 USETW(req.wIndex, endpt); 3555 USETW(req.wLength, 3); 3556 data[0] = speed; 3557 data[1] = speed >> 8; 3558 data[2] = speed >> 16; 3559 3560 return (usbd_do_request(sc->sc_udev, &req, data)); 3561 } 3562 3563 void 3564 uaudio_set_speed_emu0202(struct chan *ch) 3565 { 3566 usb_device_request_t req; 3567 int rates[6] = { 44100, 48000, 88200, 96000, 176400, 192000 }; 3568 int i; 3569 u_int8_t data[1]; 3570 3571 for (i = 0; i < 6; i++) 3572 if (rates[i] >= ch->sample_rate) 3573 break; 3574 if (i >= 6) { 3575 DPRINTF(("%s: unhandled rate %d\n", __func__, ch->sample_rate)); 3576 i = 0; 3577 } 3578 3579 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 3580 req.bRequest = SET_CUR; 3581 USETW2(req.wValue, 0x03, 0); 3582 USETW2(req.wIndex, 12, ch->sc->sc_ac_iface); 3583 USETW(req.wLength, 1); 3584 data[0] = i; 3585 3586 usbd_do_request(ch->sc->sc_udev, &req, data); 3587 } 3588