1 /* $OpenBSD: audio.c,v 1.114 2011/07/03 15:47:16 matthew Exp $ */ 2 /* $NetBSD: audio.c,v 1.119 1999/11/09 16:50:47 augustss Exp $ */ 3 4 /* 5 * Copyright (c) 1991-1993 Regents of the University of California. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the Computer Systems 19 * Engineering Group at Lawrence Berkeley Laboratory. 20 * 4. Neither the name of the University nor of the Laboratory may be used 21 * to endorse or promote products derived from this software without 22 * specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 /* 38 * This is a (partially) SunOS-compatible /dev/audio driver for NetBSD. 39 * 40 * This code tries to do something half-way sensible with 41 * half-duplex hardware, such as with the SoundBlaster hardware. With 42 * half-duplex hardware allowing O_RDWR access doesn't really make 43 * sense. However, closing and opening the device to "turn around the 44 * line" is relatively expensive and costs a card reset (which can 45 * take some time, at least for the SoundBlaster hardware). Instead 46 * we allow O_RDWR access, and provide an ioctl to set the "mode", 47 * i.e. playing or recording. 48 * 49 * If you write to a half-duplex device in record mode, the data is 50 * tossed. If you read from the device in play mode, you get silence 51 * filled buffers at the rate at which samples are naturally 52 * generated. 53 * 54 * If you try to set both play and record mode on a half-duplex 55 * device, playing takes precedence. 56 */ 57 58 /* 59 * Todo: 60 * - Add softaudio() isr processing for wakeup, poll, signals, 61 * and silence fill. 62 */ 63 64 #include <sys/param.h> 65 #include <sys/ioctl.h> 66 #include <sys/fcntl.h> 67 #include <sys/vnode.h> 68 #include <sys/selinfo.h> 69 #include <sys/poll.h> 70 #include <sys/malloc.h> 71 #include <sys/proc.h> 72 #include <sys/systm.h> 73 #include <sys/syslog.h> 74 #include <sys/kernel.h> 75 #include <sys/signalvar.h> 76 #include <sys/conf.h> 77 #include <sys/audioio.h> 78 #include <sys/device.h> 79 #include <sys/workq.h> 80 81 #include <dev/audio_if.h> 82 #include <dev/audiovar.h> 83 84 #include <dev/rndvar.h> 85 86 #include <machine/endian.h> 87 88 #include "wskbd.h" /* NWSKBD (mixer tuning using keyboard) */ 89 90 #ifdef AUDIO_DEBUG 91 #define DPRINTF(x) if (audiodebug) printf x 92 #define DPRINTFN(n,x) if (audiodebug>(n)) printf x 93 int audiodebug = 0; 94 #else 95 #define DPRINTF(x) 96 #define DPRINTFN(n,x) 97 #endif 98 99 #define ROUNDSIZE(x) x &= -16 /* round to nice boundary */ 100 101 int audio_blk_ms = AUDIO_BLK_MS; 102 103 int audiosetinfo(struct audio_softc *, struct audio_info *); 104 int audiogetinfo(struct audio_softc *, struct audio_info *); 105 int audiogetbufinfo(struct audio_softc *, struct audio_bufinfo *, int); 106 int audio_open(dev_t, struct audio_softc *, int, int, struct proc *); 107 int audio_close(dev_t, int, int, struct proc *); 108 int audio_read(dev_t, struct uio *, int); 109 int audio_write(dev_t, struct uio *, int); 110 int audio_ioctl(dev_t, u_long, caddr_t, int, struct proc *); 111 int audio_poll(dev_t, int, struct proc *); 112 paddr_t audio_mmap(dev_t, off_t, int); 113 114 int mixer_open(dev_t, struct audio_softc *, int, int, struct proc *); 115 int mixer_close(dev_t, int, int, struct proc *); 116 int mixer_ioctl(dev_t, u_long, caddr_t, int, struct proc *); 117 static void mixer_remove(struct audio_softc *, struct proc *p); 118 static void mixer_signal(struct audio_softc *); 119 120 void audio_init_record(struct audio_softc *); 121 void audio_init_play(struct audio_softc *); 122 int audiostartr(struct audio_softc *); 123 int audiostartp(struct audio_softc *); 124 void audio_rint(void *); 125 void audio_pint(void *); 126 int audio_check_params(struct audio_params *); 127 128 void audio_set_blksize(struct audio_softc *, int, int); 129 void audio_calc_blksize(struct audio_softc *, int); 130 void audio_fill_silence(struct audio_params *, u_char *, u_char *, int); 131 int audio_silence_copyout(struct audio_softc *, int, struct uio *); 132 133 void audio_init_ringbuffer(struct audio_ringbuffer *); 134 int audio_initbufs(struct audio_softc *); 135 void audio_calcwater(struct audio_softc *); 136 static __inline int audio_sleep_timo(int *, char *, int); 137 static __inline int audio_sleep(int *, char *); 138 static __inline void audio_wakeup(int *); 139 void audio_selwakeup(struct audio_softc *sc, int play); 140 int audio_drain(struct audio_softc *); 141 void audio_clear(struct audio_softc *); 142 static __inline void audio_pint_silence(struct audio_softc *, struct audio_ringbuffer *, u_char *, int); 143 144 int audio_quiesce(struct audio_softc *); 145 void audio_resume(struct audio_softc *); 146 void audio_resume_to(void *); 147 void audio_resume_task(void *, void *); 148 149 int audio_alloc_ring(struct audio_softc *, struct audio_ringbuffer *, int, int); 150 void audio_free_ring(struct audio_softc *, struct audio_ringbuffer *); 151 152 int audioprint(void *, const char *); 153 154 int audioprobe(struct device *, void *, void *); 155 void audioattach(struct device *, struct device *, void *); 156 int audiodetach(struct device *, int); 157 int audioactivate(struct device *, int); 158 159 struct portname { 160 char *name; 161 int mask; 162 }; 163 static struct portname itable[] = { 164 { AudioNmicrophone, AUDIO_MICROPHONE }, 165 { AudioNline, AUDIO_LINE_IN }, 166 { AudioNcd, AUDIO_CD }, 167 { 0 } 168 }; 169 static struct portname otable[] = { 170 { AudioNspeaker, AUDIO_SPEAKER }, 171 { AudioNheadphone, AUDIO_HEADPHONE }, 172 { AudioNline, AUDIO_LINE_OUT }, 173 { 0 } 174 }; 175 struct gainpref { 176 char *class, *device; 177 }; 178 static struct gainpref ipreftab[] = { 179 { AudioCinputs, AudioNvolume }, 180 { AudioCinputs, AudioNinput }, 181 { AudioCinputs, AudioNrecord }, 182 { AudioCrecord, AudioNvolume }, 183 { AudioCrecord, AudioNrecord }, 184 { NULL, NULL} 185 }; 186 static struct gainpref opreftab[] = { 187 { AudioCoutputs, AudioNoutput }, 188 { AudioCoutputs, AudioNdac }, 189 { AudioCinputs, AudioNdac }, 190 { AudioCoutputs, AudioNmaster }, 191 { NULL, NULL} 192 }; 193 static struct gainpref mpreftab[] = { 194 { AudioCoutputs, AudioNmonitor }, 195 { AudioCmonitor, AudioNmonitor }, 196 { NULL, NULL} 197 }; 198 199 void au_gain_match(struct audio_softc *, struct gainpref *, 200 mixer_devinfo_t *, mixer_devinfo_t *, int *, int *); 201 void au_check_ports(struct audio_softc *, struct au_mixer_ports *, 202 mixer_devinfo_t *, mixer_devinfo_t *, 203 char *, char *, struct portname *); 204 int au_set_gain(struct audio_softc *, struct au_mixer_ports *, 205 int, int); 206 void au_get_gain(struct audio_softc *, struct au_mixer_ports *, 207 u_int *, u_char *); 208 int au_set_port(struct audio_softc *, struct au_mixer_ports *, 209 u_int); 210 int au_get_port(struct audio_softc *, struct au_mixer_ports *); 211 int au_set_mute(struct audio_softc *, struct au_mixer_ports *, u_char); 212 int au_get_mute(struct audio_softc *, struct au_mixer_ports *, u_char *); 213 int au_get_lr_value(struct audio_softc *, mixer_ctrl_t *, 214 int *, int *r); 215 int au_set_lr_value(struct audio_softc *, mixer_ctrl_t *, 216 int, int); 217 int au_portof(struct audio_softc *, char *); 218 219 220 /* The default audio mode: 8 kHz mono ulaw */ 221 struct audio_params audio_default = 222 { 8000, AUDIO_ENCODING_ULAW, 8, 1, 1, 1, 0, 1 }; 223 224 struct cfattach audio_ca = { 225 sizeof(struct audio_softc), audioprobe, audioattach, 226 audiodetach, audioactivate 227 }; 228 229 struct cfdriver audio_cd = { 230 NULL, "audio", DV_DULL 231 }; 232 233 void filt_audiowdetach(struct knote *); 234 int filt_audiowrite(struct knote *, long); 235 236 struct filterops audiowrite_filtops = 237 { 1, NULL, filt_audiowdetach, filt_audiowrite}; 238 239 void filt_audiordetach(struct knote *); 240 int filt_audioread(struct knote *, long); 241 242 struct filterops audioread_filtops = 243 { 1, NULL, filt_audiordetach, filt_audioread}; 244 245 #if NWSKBD > 0 246 /* Mixer manipulation using keyboard */ 247 int wskbd_set_mixervolume(long, int); 248 #endif 249 250 int 251 audioprobe(struct device *parent, void *match, void *aux) 252 { 253 struct audio_attach_args *sa = aux; 254 255 DPRINTF(("audioprobe: type=%d sa=%p hw=%p\n", 256 sa->type, sa, sa->hwif)); 257 return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0; 258 } 259 260 void 261 audioattach(struct device *parent, struct device *self, void *aux) 262 { 263 struct audio_softc *sc = (void *)self; 264 struct audio_attach_args *sa = aux; 265 struct audio_hw_if *hwp = sa->hwif; 266 void *hdlp = sa->hdl; 267 int error; 268 mixer_devinfo_t mi, cl; 269 int ipref, opref, mpref; 270 271 printf("\n"); 272 273 #ifdef DIAGNOSTIC 274 if (hwp == 0 || 275 hwp->open == 0 || 276 hwp->close == 0 || 277 hwp->query_encoding == 0 || 278 hwp->set_params == 0 || 279 (hwp->start_output == 0 && hwp->trigger_output == 0) || 280 (hwp->start_input == 0 && hwp->trigger_input == 0) || 281 hwp->halt_output == 0 || 282 hwp->halt_input == 0 || 283 hwp->getdev == 0 || 284 hwp->set_port == 0 || 285 hwp->get_port == 0 || 286 hwp->query_devinfo == 0 || 287 hwp->get_props == 0) { 288 printf("audio: missing method\n"); 289 sc->hw_if = 0; 290 return; 291 } 292 #endif 293 294 sc->hw_if = hwp; 295 sc->hw_hdl = hdlp; 296 sc->sc_dev = parent; 297 sc->sc_async_mixer = NULL; 298 299 error = audio_alloc_ring(sc, &sc->sc_pr, AUMODE_PLAY, AU_RING_SIZE); 300 if (error) { 301 sc->hw_if = 0; 302 printf("audio: could not allocate play buffer\n"); 303 return; 304 } 305 error = audio_alloc_ring(sc, &sc->sc_rr, AUMODE_RECORD, AU_RING_SIZE); 306 if (error) { 307 audio_free_ring(sc, &sc->sc_pr); 308 sc->hw_if = 0; 309 printf("audio: could not allocate record buffer\n"); 310 return; 311 } 312 313 /* 314 * Set default softc params 315 */ 316 317 if (hwp->get_default_params) { 318 hwp->get_default_params(hdlp, AUMODE_PLAY, &sc->sc_pparams); 319 hwp->get_default_params(hdlp, AUMODE_RECORD, &sc->sc_rparams); 320 } else { 321 sc->sc_pparams = audio_default; 322 sc->sc_rparams = audio_default; 323 } 324 325 /* Set up some default values */ 326 sc->sc_rr.blkset = sc->sc_pr.blkset = 0; 327 audio_calc_blksize(sc, AUMODE_RECORD); 328 audio_calc_blksize(sc, AUMODE_PLAY); 329 audio_init_ringbuffer(&sc->sc_rr); 330 audio_init_ringbuffer(&sc->sc_pr); 331 audio_calcwater(sc); 332 333 ipref = opref = mpref = -1; 334 sc->sc_inports.index = -1; 335 sc->sc_inports.nports = 0; 336 sc->sc_inports.isenum = 0; 337 sc->sc_inports.allports = 0; 338 sc->sc_inports.master = -1; 339 sc->sc_outports.index = -1; 340 sc->sc_outports.nports = 0; 341 sc->sc_outports.isenum = 0; 342 sc->sc_outports.allports = 0; 343 sc->sc_outports.master = -1; 344 sc->sc_monitor_port = -1; 345 for(mi.index = 0; ; mi.index++) { 346 if (hwp->query_devinfo(hdlp, &mi) != 0) 347 break; 348 if (mi.type == AUDIO_MIXER_CLASS) 349 continue; 350 cl.index = mi.mixer_class; 351 if (hwp->query_devinfo(hdlp, &cl) != 0) 352 continue; 353 354 au_gain_match(sc, ipreftab, &cl, &mi, &sc->sc_inports.master, &ipref); 355 au_gain_match(sc, opreftab, &cl, &mi, &sc->sc_outports.master, &opref); 356 au_gain_match(sc, mpreftab, &cl, &mi, &sc->sc_monitor_port, &mpref); 357 358 au_check_ports(sc, &sc->sc_inports, &cl, &mi, 359 AudioCrecord, AudioNsource, itable); 360 au_check_ports(sc, &sc->sc_outports, &cl, &mi, 361 AudioCoutputs, AudioNselect, otable); 362 } 363 DPRINTF(("audio_attach: inputs ports=0x%x, output ports=0x%x\n", 364 sc->sc_inports.allports, sc->sc_outports.allports)); 365 366 timeout_set(&sc->sc_resume_to, audio_resume_to, sc); 367 } 368 369 int 370 audioactivate(struct device *self, int act) 371 { 372 struct audio_softc *sc = (struct audio_softc *)self; 373 374 switch (act) { 375 case DVACT_QUIESCE: 376 audio_quiesce(sc); 377 break; 378 case DVACT_SUSPEND: 379 break; 380 case DVACT_RESUME: 381 audio_resume(sc); 382 break; 383 case DVACT_DEACTIVATE: 384 sc->sc_dying = 1; 385 break; 386 } 387 return (0); 388 } 389 390 int 391 audiodetach(struct device *self, int flags) 392 { 393 struct audio_softc *sc = (struct audio_softc *)self; 394 int maj, mn; 395 int s; 396 397 DPRINTF(("audio_detach: sc=%p flags=%d\n", sc, flags)); 398 399 sc->sc_dying = 1; 400 401 timeout_del(&sc->sc_resume_to); 402 wakeup(&sc->sc_quiesce); 403 wakeup(&sc->sc_wchan); 404 wakeup(&sc->sc_rchan); 405 s = splaudio(); 406 if (--sc->sc_refcnt >= 0) { 407 if (tsleep(&sc->sc_refcnt, PZERO, "auddet", hz * 120)) 408 printf("audiodetach: %s didn't detach\n", 409 sc->dev.dv_xname); 410 } 411 splx(s); 412 413 /* free resources */ 414 audio_free_ring(sc, &sc->sc_pr); 415 audio_free_ring(sc, &sc->sc_rr); 416 417 /* locate the major number */ 418 for (maj = 0; maj < nchrdev; maj++) 419 if (cdevsw[maj].d_open == audioopen) 420 break; 421 422 /* Nuke the vnodes for any open instances (calls close). */ 423 mn = self->dv_unit; 424 vdevgone(maj, mn | SOUND_DEVICE, mn | SOUND_DEVICE, VCHR); 425 vdevgone(maj, mn | AUDIO_DEVICE, mn | AUDIO_DEVICE, VCHR); 426 vdevgone(maj, mn | AUDIOCTL_DEVICE, mn | AUDIOCTL_DEVICE, VCHR); 427 vdevgone(maj, mn | MIXER_DEVICE, mn | MIXER_DEVICE, VCHR); 428 429 return (0); 430 } 431 432 int 433 au_portof(struct audio_softc *sc, char *name) 434 { 435 mixer_devinfo_t mi; 436 437 for(mi.index = 0; 438 sc->hw_if->query_devinfo(sc->hw_hdl, &mi) == 0; 439 mi.index++) 440 if (strcmp(mi.label.name, name) == 0) 441 return mi.index; 442 return -1; 443 } 444 445 void 446 au_check_ports(struct audio_softc *sc, struct au_mixer_ports *ports, 447 mixer_devinfo_t *cl, mixer_devinfo_t *mi, char *cname, char *mname, 448 struct portname *tbl) 449 { 450 int i, j; 451 452 if (strcmp(cl->label.name, cname) != 0 || 453 strcmp(mi->label.name, mname) != 0) 454 return; 455 if (mi->type == AUDIO_MIXER_ENUM) { 456 ports->index = mi->index; 457 for(i = 0; tbl[i].name; i++) { 458 for(j = 0; j < mi->un.e.num_mem; j++) { 459 if (strcmp(mi->un.e.member[j].label.name, 460 tbl[i].name) == 0) { 461 ports->aumask[ports->nports] = tbl[i].mask; 462 ports->misel [ports->nports] = mi->un.e.member[j].ord; 463 ports->miport[ports->nports++] = 464 au_portof(sc, mi->un.e.member[j].label.name); 465 ports->allports |= tbl[i].mask; 466 } 467 } 468 } 469 ports->isenum = 1; 470 } else if (mi->type == AUDIO_MIXER_SET) { 471 ports->index = mi->index; 472 for(i = 0; tbl[i].name; i++) { 473 for(j = 0; j < mi->un.s.num_mem; j++) { 474 if (strcmp(mi->un.s.member[j].label.name, 475 tbl[i].name) == 0) { 476 ports->aumask[ports->nports] = tbl[i].mask; 477 ports->misel [ports->nports] = mi->un.s.member[j].mask; 478 ports->miport[ports->nports++] = 479 au_portof(sc, mi->un.s.member[j].label.name); 480 ports->allports |= tbl[i].mask; 481 } 482 } 483 } 484 } 485 } 486 487 /* 488 * check if the given (class, device) is better 489 * than the current setting (*index), if so, set the 490 * current setting. 491 */ 492 void 493 au_gain_match(struct audio_softc *sc, struct gainpref *tbl, 494 mixer_devinfo_t *cls, mixer_devinfo_t *dev, int *index, int *pref) 495 { 496 int i; 497 498 for (i = *pref + 1; tbl[i].class != NULL; i++) { 499 if (strcmp(tbl[i].class, cls->label.name) == 0 && 500 strcmp(tbl[i].device, dev->label.name) == 0) { 501 if (*pref < i) { 502 DPRINTF(("au_gain_match: found %s.%s\n", 503 cls->label.name, dev->label.name)); 504 *index = dev->index; 505 *pref = i; 506 } 507 break; 508 } 509 } 510 } 511 512 /* 513 * Called from hardware driver. This is where the MI audio driver gets 514 * probed/attached to the hardware driver. 515 */ 516 struct device * 517 audio_attach_mi(struct audio_hw_if *ahwp, void *hdlp, struct device *dev) 518 { 519 struct audio_attach_args arg; 520 521 #ifdef DIAGNOSTIC 522 if (ahwp == NULL) { 523 printf ("audio_attach_mi: NULL\n"); 524 return 0; 525 } 526 #endif 527 528 arg.type = AUDIODEV_TYPE_AUDIO; 529 arg.hwif = ahwp; 530 arg.hdl = hdlp; 531 return config_found(dev, &arg, audioprint); 532 } 533 534 int 535 audioprint(void *aux, const char *pnp) 536 { 537 struct audio_attach_args *arg = aux; 538 const char *type; 539 540 if (pnp != NULL) { 541 switch (arg->type) { 542 case AUDIODEV_TYPE_AUDIO: 543 type = "audio"; 544 break; 545 case AUDIODEV_TYPE_OPL: 546 type = "opl"; 547 break; 548 case AUDIODEV_TYPE_MPU: 549 type = "mpu"; 550 break; 551 default: 552 panic("audioprint: unknown type %d", arg->type); 553 } 554 printf("%s at %s", type, pnp); 555 } 556 return (UNCONF); 557 } 558 559 #ifdef AUDIO_DEBUG 560 void audio_printsc(struct audio_softc *); 561 void audio_print_params(char *, struct audio_params *); 562 563 void 564 audio_printsc(struct audio_softc *sc) 565 { 566 printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if); 567 printf("open 0x%x mode 0x%x\n", sc->sc_open, sc->sc_mode); 568 printf("rchan 0x%x wchan 0x%x ", sc->sc_rchan, sc->sc_wchan); 569 printf("rring used 0x%x pring used=%d\n", sc->sc_rr.used, sc->sc_pr.used); 570 printf("rbus 0x%x pbus 0x%x ", sc->sc_rbus, sc->sc_pbus); 571 printf("pblksz %d, rblksz %d", sc->sc_pr.blksize, sc->sc_rr.blksize); 572 printf("hiwat %d lowat %d\n", sc->sc_pr.usedhigh, sc->sc_pr.usedlow); 573 } 574 575 void 576 audio_print_params(char *s, struct audio_params *p) 577 { 578 printf("audio: %s sr=%ld, enc=%d, chan=%d, prec=%d bps=%d\n", s, 579 p->sample_rate, p->encoding, p->channels, p->precision, p->bps); 580 } 581 #endif 582 583 int 584 audio_alloc_ring(struct audio_softc *sc, struct audio_ringbuffer *r, 585 int direction, int bufsize) 586 { 587 struct audio_hw_if *hw = sc->hw_if; 588 void *hdl = sc->hw_hdl; 589 /* 590 * Alloc DMA play and record buffers 591 */ 592 if (bufsize < AUMINBUF) 593 bufsize = AUMINBUF; 594 ROUNDSIZE(bufsize); 595 if (hw->round_buffersize) 596 bufsize = hw->round_buffersize(hdl, direction, bufsize); 597 r->bufsize = bufsize; 598 if (hw->allocm) 599 r->start = hw->allocm(hdl, direction, r->bufsize, M_DEVBUF, 600 M_WAITOK); 601 else 602 r->start = malloc(bufsize, M_DEVBUF, M_WAITOK); 603 if (r->start == 0) 604 return ENOMEM; 605 return 0; 606 } 607 608 void 609 audio_free_ring(struct audio_softc *sc, struct audio_ringbuffer *r) 610 { 611 if (sc->hw_if->freem) { 612 sc->hw_if->freem(sc->hw_hdl, r->start, M_DEVBUF); 613 } else { 614 free(r->start, M_DEVBUF); 615 } 616 } 617 618 int 619 audioopen(dev_t dev, int flags, int ifmt, struct proc *p) 620 { 621 int unit = AUDIOUNIT(dev); 622 struct audio_softc *sc; 623 int error; 624 625 if (unit >= audio_cd.cd_ndevs || 626 (sc = audio_cd.cd_devs[unit]) == NULL) 627 return ENXIO; 628 629 if (sc->sc_dying) 630 return (EIO); 631 632 if (!sc->hw_if) 633 return (ENXIO); 634 635 sc->sc_refcnt ++; 636 switch (AUDIODEV(dev)) { 637 case SOUND_DEVICE: 638 case AUDIO_DEVICE: 639 case AUDIOCTL_DEVICE: 640 error = audio_open(dev, sc, flags, ifmt, p); 641 break; 642 case MIXER_DEVICE: 643 error = mixer_open(dev, sc, flags, ifmt, p); 644 break; 645 default: 646 error = ENXIO; 647 break; 648 } 649 650 if (--sc->sc_refcnt < 0) 651 wakeup(&sc->sc_refcnt); 652 653 return (error); 654 } 655 656 int 657 audioclose(dev_t dev, int flags, int ifmt, struct proc *p) 658 { 659 660 switch (AUDIODEV(dev)) { 661 case SOUND_DEVICE: 662 case AUDIO_DEVICE: 663 return (audio_close(dev, flags, ifmt, p)); 664 case MIXER_DEVICE: 665 return (mixer_close(dev, flags, ifmt, p)); 666 case AUDIOCTL_DEVICE: 667 return 0; 668 default: 669 return (ENXIO); 670 } 671 } 672 673 int 674 audioread(dev_t dev, struct uio *uio, int ioflag) 675 { 676 int unit = AUDIOUNIT(dev); 677 struct audio_softc *sc; 678 int error; 679 680 if (unit >= audio_cd.cd_ndevs || 681 (sc = audio_cd.cd_devs[unit]) == NULL) 682 return ENXIO; 683 684 if (sc->sc_dying) 685 return (EIO); 686 687 sc->sc_refcnt ++; 688 switch (AUDIODEV(dev)) { 689 case SOUND_DEVICE: 690 case AUDIO_DEVICE: 691 error = audio_read(dev, uio, ioflag); 692 break; 693 case AUDIOCTL_DEVICE: 694 case MIXER_DEVICE: 695 error = ENODEV; 696 break; 697 default: 698 error = ENXIO; 699 break; 700 } 701 702 if (--sc->sc_refcnt < 0) 703 wakeup(&sc->sc_refcnt); 704 return (error); 705 } 706 707 int 708 audiowrite(dev_t dev, struct uio *uio, int ioflag) 709 { 710 int unit = AUDIOUNIT(dev); 711 struct audio_softc *sc; 712 int error; 713 714 if (unit >= audio_cd.cd_ndevs || 715 (sc = audio_cd.cd_devs[unit]) == NULL) 716 return ENXIO; 717 718 if (sc->sc_dying) 719 return (EIO); 720 721 sc->sc_refcnt ++; 722 switch (AUDIODEV(dev)) { 723 case SOUND_DEVICE: 724 case AUDIO_DEVICE: 725 error = audio_write(dev, uio, ioflag); 726 break; 727 case AUDIOCTL_DEVICE: 728 case MIXER_DEVICE: 729 error = ENODEV; 730 break; 731 default: 732 error = ENXIO; 733 break; 734 } 735 736 if (--sc->sc_refcnt < 0) 737 wakeup(&sc->sc_refcnt); 738 return (error); 739 } 740 741 int 742 audioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 743 { 744 int unit = AUDIOUNIT(dev); 745 struct audio_softc *sc; 746 int error; 747 748 if (unit >= audio_cd.cd_ndevs || 749 (sc = audio_cd.cd_devs[unit]) == NULL) 750 return ENXIO; 751 752 if (sc->sc_dying) 753 return (EIO); 754 755 sc->sc_refcnt ++; 756 switch (AUDIODEV(dev)) { 757 case SOUND_DEVICE: 758 case AUDIO_DEVICE: 759 case AUDIOCTL_DEVICE: 760 error = audio_ioctl(dev, cmd, addr, flag, p); 761 break; 762 case MIXER_DEVICE: 763 error = mixer_ioctl(dev, cmd, addr, flag, p); 764 break; 765 default: 766 error = ENXIO; 767 break; 768 } 769 770 if (--sc->sc_refcnt < 0) 771 wakeup(&sc->sc_refcnt); 772 return (error); 773 } 774 775 int 776 audiopoll(dev_t dev, int events, struct proc *p) 777 { 778 int unit = AUDIOUNIT(dev); 779 struct audio_softc *sc; 780 int error; 781 782 if (unit >= audio_cd.cd_ndevs || 783 (sc = audio_cd.cd_devs[unit]) == NULL) 784 return POLLERR; 785 786 if (sc->sc_dying) 787 return POLLERR; 788 789 sc->sc_refcnt ++; 790 switch (AUDIODEV(dev)) { 791 case SOUND_DEVICE: 792 case AUDIO_DEVICE: 793 error = audio_poll(dev, events, p); 794 break; 795 case AUDIOCTL_DEVICE: 796 case MIXER_DEVICE: 797 error = 0; 798 break; 799 default: 800 error = 0; 801 break; 802 } 803 804 if (--sc->sc_refcnt < 0) 805 wakeup(&sc->sc_refcnt); 806 return (error); 807 } 808 809 paddr_t 810 audiommap(dev_t dev, off_t off, int prot) 811 { 812 int unit = AUDIOUNIT(dev); 813 struct audio_softc *sc; 814 int ret; 815 816 if (unit >= audio_cd.cd_ndevs || 817 (sc = audio_cd.cd_devs[unit]) == NULL) 818 return (-1); 819 820 if (sc->sc_dying) 821 return (-1); 822 823 sc->sc_refcnt ++; 824 switch (AUDIODEV(dev)) { 825 case SOUND_DEVICE: 826 case AUDIO_DEVICE: 827 ret = audio_mmap(dev, off, prot); 828 break; 829 case AUDIOCTL_DEVICE: 830 case MIXER_DEVICE: 831 ret = -1; 832 break; 833 default: 834 ret = -1; 835 break; 836 } 837 838 if (--sc->sc_refcnt < 0) 839 wakeup(&sc->sc_refcnt); 840 return (ret); 841 } 842 843 /* 844 * Audio driver 845 */ 846 void 847 audio_init_ringbuffer(struct audio_ringbuffer *rp) 848 { 849 int nblks; 850 int blksize = rp->blksize; 851 852 if (blksize < AUMINBLK) 853 blksize = AUMINBLK; 854 nblks = rp->bufsize / blksize; 855 if (nblks < AUMINNOBLK) { 856 nblks = AUMINNOBLK; 857 blksize = rp->bufsize / nblks; 858 ROUNDSIZE(blksize); 859 } 860 DPRINTF(("audio_init_ringbuffer: blksize=%d\n", blksize)); 861 rp->blksize = blksize; 862 rp->maxblks = nblks; 863 rp->used = 0; 864 rp->end = rp->start + nblks * blksize; 865 rp->inp = rp->outp = rp->start; 866 rp->stamp = 0; 867 rp->stamp_last = 0; 868 rp->drops = 0; 869 rp->pdrops = 0; 870 rp->mmapped = 0; 871 } 872 873 int 874 audio_initbufs(struct audio_softc *sc) 875 { 876 struct audio_hw_if *hw = sc->hw_if; 877 int error; 878 879 DPRINTF(("audio_initbufs: mode=0x%x\n", sc->sc_mode)); 880 audio_init_ringbuffer(&sc->sc_rr); 881 if (hw->init_input && (sc->sc_mode & AUMODE_RECORD)) { 882 error = hw->init_input(sc->hw_hdl, sc->sc_rr.start, 883 sc->sc_rr.end - sc->sc_rr.start); 884 if (error) 885 return error; 886 } 887 888 audio_init_ringbuffer(&sc->sc_pr); 889 sc->sc_sil_count = 0; 890 if (hw->init_output && (sc->sc_mode & AUMODE_PLAY)) { 891 error = hw->init_output(sc->hw_hdl, sc->sc_pr.start, 892 sc->sc_pr.end - sc->sc_pr.start); 893 if (error) 894 return error; 895 } 896 897 #ifdef AUDIO_INTR_TIME 898 sc->sc_pnintr = 0; 899 sc->sc_pblktime = (u_long)( 900 (u_long)sc->sc_pr.blksize * 100000 / 901 (u_long)(sc->sc_pparams.bps * 902 sc->sc_pparams.channels * 903 sc->sc_pparams.sample_rate)) * 10; 904 DPRINTF(("audio: play blktime = %lu for %d\n", 905 sc->sc_pblktime, sc->sc_pr.blksize)); 906 sc->sc_rnintr = 0; 907 sc->sc_rblktime = (u_long)( 908 (u_long)sc->sc_rr.blksize * 100000 / 909 (u_long)(sc->sc_rparams.bps * 910 sc->sc_rparams.channels * 911 sc->sc_rparams.sample_rate)) * 10; 912 DPRINTF(("audio: record blktime = %lu for %d\n", 913 sc->sc_rblktime, sc->sc_rr.blksize)); 914 #endif 915 916 return 0; 917 } 918 919 void 920 audio_calcwater(struct audio_softc *sc) 921 { 922 int hiwat, lowat; 923 924 hiwat = (sc->sc_pr.end - sc->sc_pr.start) / sc->sc_pr.blksize; 925 lowat = hiwat * 3 / 4; 926 if (lowat == hiwat) 927 lowat = hiwat - 1; 928 sc->sc_pr.usedhigh = hiwat * sc->sc_pr.blksize; 929 sc->sc_pr.usedlow = lowat * sc->sc_pr.blksize; 930 sc->sc_rr.usedhigh = sc->sc_rr.end - sc->sc_rr.start; 931 sc->sc_rr.usedlow = 0; 932 } 933 934 static __inline int 935 audio_sleep_timo(int *chan, char *label, int timo) 936 { 937 int st; 938 939 if (!label) 940 label = "audio"; 941 942 DPRINTFN(3, ("audio_sleep_timo: chan=%p, label=%s, timo=%d\n", 943 chan, label, timo)); 944 *chan = 1; 945 st = tsleep(chan, PWAIT | PCATCH, label, timo); 946 *chan = 0; 947 #ifdef AUDIO_DEBUG 948 if (st != 0) 949 printf("audio_sleep: woke up st=%d\n", st); 950 #endif 951 return (st); 952 } 953 954 static __inline int 955 audio_sleep(int *chan, char *label) 956 { 957 return audio_sleep_timo(chan, label, 0); 958 } 959 960 /* call at splaudio() */ 961 static __inline void 962 audio_wakeup(int *chan) 963 { 964 DPRINTFN(3, ("audio_wakeup: chan=%p, *chan=%d\n", chan, *chan)); 965 if (*chan) { 966 wakeup(chan); 967 *chan = 0; 968 } 969 } 970 971 int 972 audio_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt, 973 struct proc *p) 974 { 975 int error; 976 int mode; 977 struct audio_info ai; 978 979 DPRINTF(("audio_open: dev=0x%x flags=0x%x sc=%p hdl=%p\n", dev, flags, sc, sc->hw_hdl)); 980 981 if (ISDEVAUDIOCTL(dev)) 982 return 0; 983 984 if ((sc->sc_open & (AUOPEN_READ|AUOPEN_WRITE)) != 0) 985 return (EBUSY); 986 987 error = sc->hw_if->open(sc->hw_hdl, flags); 988 if (error) 989 return (error); 990 991 sc->sc_async_audio = 0; 992 sc->sc_rchan = 0; 993 sc->sc_wchan = 0; 994 sc->sc_sil_count = 0; 995 sc->sc_rbus = 0; 996 sc->sc_pbus = 0; 997 sc->sc_eof = 0; 998 sc->sc_playdrop = 0; 999 1000 sc->sc_full_duplex = 0; 1001 /* doesn't always work right on SB. 1002 (flags & (FWRITE|FREAD)) == (FWRITE|FREAD) && 1003 (sc->hw_if->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX); 1004 */ 1005 1006 mode = 0; 1007 if (flags & FREAD) { 1008 sc->sc_open |= AUOPEN_READ; 1009 mode |= AUMODE_RECORD; 1010 } 1011 if (flags & FWRITE) { 1012 sc->sc_open |= AUOPEN_WRITE; 1013 mode |= AUMODE_PLAY | AUMODE_PLAY_ALL; 1014 } 1015 1016 /* 1017 * Multiplex device: /dev/audio (default) and /dev/sound (last) 1018 * The /dev/audio is always (re)set to the default parameters. 1019 * For the other devices, you get what they were last set to. 1020 */ 1021 if (ISDEVAUDIO(dev)) { 1022 /* /dev/audio */ 1023 if (sc->hw_if->get_default_params) { 1024 sc->hw_if->get_default_params(sc->hw_hdl, AUMODE_PLAY, 1025 &sc->sc_pparams); 1026 sc->hw_if->get_default_params(sc->hw_hdl, AUMODE_RECORD, 1027 &sc->sc_rparams); 1028 } else { 1029 sc->sc_rparams = audio_default; 1030 sc->sc_pparams = audio_default; 1031 } 1032 } 1033 #ifdef DIAGNOSTIC 1034 /* 1035 * Sample rate and precision are supposed to be set to proper 1036 * default values by the hardware driver, so that it may give 1037 * us these values. 1038 */ 1039 if (sc->sc_rparams.precision == 0 || sc->sc_pparams.precision == 0) { 1040 printf("audio_open: 0 precision\n"); 1041 error = EINVAL; 1042 goto bad; 1043 } 1044 #endif 1045 1046 AUDIO_INITINFO(&ai); 1047 ai.record.sample_rate = sc->sc_rparams.sample_rate; 1048 ai.record.encoding = sc->sc_rparams.encoding; 1049 ai.record.channels = sc->sc_rparams.channels; 1050 ai.record.precision = sc->sc_rparams.precision; 1051 ai.record.bps = sc->sc_rparams.bps; 1052 ai.record.msb = sc->sc_rparams.msb; 1053 ai.record.pause = 0; 1054 ai.play.sample_rate = sc->sc_pparams.sample_rate; 1055 ai.play.encoding = sc->sc_pparams.encoding; 1056 ai.play.channels = sc->sc_pparams.channels; 1057 ai.play.precision = sc->sc_pparams.precision; 1058 ai.play.bps = sc->sc_pparams.bps; 1059 ai.play.msb = sc->sc_pparams.msb; 1060 ai.play.pause = 0; 1061 ai.mode = mode; 1062 sc->sc_rr.blkset = sc->sc_pr.blkset = 0; /* Block sizes not set yet */ 1063 sc->sc_pr.blksize = sc->sc_rr.blksize = 0; /* force recalculation */ 1064 error = audiosetinfo(sc, &ai); 1065 if (error) 1066 goto bad; 1067 1068 DPRINTF(("audio_open: done sc_mode = 0x%x\n", sc->sc_mode)); 1069 1070 return 0; 1071 1072 bad: 1073 sc->hw_if->close(sc->hw_hdl); 1074 sc->sc_open = 0; 1075 sc->sc_mode = 0; 1076 sc->sc_full_duplex = 0; 1077 return error; 1078 } 1079 1080 /* 1081 * Must be called from task context. 1082 */ 1083 void 1084 audio_init_record(struct audio_softc *sc) 1085 { 1086 int s = splaudio(); 1087 1088 if (sc->hw_if->speaker_ctl && 1089 (!sc->sc_full_duplex || (sc->sc_mode & AUMODE_PLAY) == 0)) 1090 sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_OFF); 1091 splx(s); 1092 } 1093 1094 /* 1095 * Must be called from task context. 1096 */ 1097 void 1098 audio_init_play(struct audio_softc *sc) 1099 { 1100 int s = splaudio(); 1101 1102 sc->sc_wstamp = sc->sc_pr.stamp; 1103 if (sc->hw_if->speaker_ctl) 1104 sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_ON); 1105 splx(s); 1106 } 1107 1108 int 1109 audio_drain(struct audio_softc *sc) 1110 { 1111 int error, drops; 1112 struct audio_ringbuffer *cb = &sc->sc_pr; 1113 int s; 1114 1115 DPRINTF(("audio_drain: enter busy=%d used=%d\n", 1116 sc->sc_pbus, sc->sc_pr.used)); 1117 if (sc->sc_pr.mmapped || sc->sc_pr.used <= 0) 1118 return 0; 1119 if (!sc->sc_pbus) { 1120 /* We've never started playing, probably because the 1121 * block was too short. Pad it and start now. 1122 */ 1123 int cc; 1124 u_char *inp = cb->inp; 1125 1126 cc = cb->blksize - (inp - cb->start) % cb->blksize; 1127 if (sc->sc_pparams.sw_code) { 1128 int ncc = cc / sc->sc_pparams.factor; 1129 audio_fill_silence(&sc->sc_pparams, cb->start, inp, ncc); 1130 sc->sc_pparams.sw_code(sc->hw_hdl, inp, ncc); 1131 } else 1132 audio_fill_silence(&sc->sc_pparams, cb->start, inp, cc); 1133 inp += cc; 1134 if (inp >= cb->end) 1135 inp = cb->start; 1136 s = splaudio(); 1137 cb->used += cc; 1138 cb->inp = inp; 1139 error = audiostartp(sc); 1140 splx(s); 1141 if (error) 1142 return error; 1143 } 1144 /* 1145 * Play until a silence block has been played, then we 1146 * know all has been drained. 1147 * XXX This should be done some other way to avoid 1148 * playing silence. 1149 */ 1150 drops = cb->drops; 1151 error = 0; 1152 s = splaudio(); 1153 while (cb->drops == drops && !error) { 1154 DPRINTF(("audio_drain: used=%d, drops=%ld\n", sc->sc_pr.used, cb->drops)); 1155 /* 1156 * When the process is exiting, it ignores all signals and 1157 * we can't interrupt this sleep, so we set a timeout just in case. 1158 */ 1159 error = audio_sleep_timo(&sc->sc_wchan, "aud_dr", 30*hz); 1160 if (sc->sc_dying) 1161 error = EIO; 1162 } 1163 splx(s); 1164 return error; 1165 } 1166 1167 int 1168 audio_quiesce(struct audio_softc *sc) 1169 { 1170 sc->sc_quiesce = AUDIO_QUIESCE_START; 1171 1172 while (sc->sc_pbus && !sc->sc_pqui) 1173 audio_sleep(&sc->sc_wchan, "audpqui"); 1174 while (sc->sc_rbus && !sc->sc_rqui) 1175 audio_sleep(&sc->sc_rchan, "audrqui"); 1176 1177 sc->sc_quiesce = AUDIO_QUIESCE_SILENT; 1178 1179 au_get_mute(sc, &sc->sc_outports, &sc->sc_mute); 1180 au_set_mute(sc, &sc->sc_outports, 1); 1181 1182 if (sc->sc_pbus) 1183 sc->hw_if->halt_output(sc->hw_hdl); 1184 if (sc->sc_rbus) 1185 sc->hw_if->halt_input(sc->hw_hdl); 1186 1187 return 0; 1188 } 1189 1190 void 1191 audio_resume(struct audio_softc *sc) 1192 { 1193 timeout_add_msec(&sc->sc_resume_to, 1500); 1194 } 1195 1196 void 1197 audio_resume_to(void *v) 1198 { 1199 struct audio_softc *sc = v; 1200 workq_queue_task(NULL, &sc->sc_resume_task, 0, 1201 audio_resume_task, sc, 0); 1202 } 1203 1204 void 1205 audio_resume_task(void *arg1, void *arg2) 1206 { 1207 struct audio_softc *sc = arg1; 1208 int setmode = 0; 1209 1210 sc->sc_pqui = sc->sc_rqui = 0; 1211 1212 au_set_mute(sc, &sc->sc_outports, sc->sc_mute); 1213 1214 if (sc->sc_pbus) 1215 setmode |= AUMODE_PLAY; 1216 if (sc->sc_rbus) 1217 setmode |= AUMODE_RECORD; 1218 1219 if (setmode) { 1220 sc->hw_if->set_params(sc->hw_hdl, setmode, 1221 sc->sc_mode & (AUMODE_PLAY | AUMODE_RECORD), 1222 &sc->sc_pparams, &sc->sc_rparams); 1223 } 1224 1225 if (sc->sc_pbus) { 1226 if (sc->hw_if->trigger_output) 1227 sc->hw_if->trigger_output(sc->hw_hdl, sc->sc_pr.start, 1228 sc->sc_pr.end, sc->sc_pr.blksize, 1229 audio_pint, (void *)sc, &sc->sc_pparams); 1230 else 1231 sc->hw_if->start_output(sc->hw_hdl, sc->sc_pr.outp, 1232 sc->sc_pr.blksize, audio_pint, (void *)sc); 1233 } 1234 if (sc->sc_rbus) { 1235 if (sc->hw_if->trigger_input) 1236 sc->hw_if->trigger_input(sc->hw_hdl, sc->sc_rr.start, 1237 sc->sc_rr.end, sc->sc_rr.blksize, 1238 audio_rint, (void *)sc, &sc->sc_rparams); 1239 else 1240 sc->hw_if->start_input(sc->hw_hdl, sc->sc_rr.inp, 1241 sc->sc_rr.blksize, audio_rint, (void *)sc); 1242 } 1243 1244 sc->sc_quiesce = 0; 1245 wakeup(&sc->sc_quiesce); 1246 } 1247 1248 /* 1249 * Close an audio chip. 1250 */ 1251 /* ARGSUSED */ 1252 int 1253 audio_close(dev_t dev, int flags, int ifmt, struct proc *p) 1254 { 1255 int unit = AUDIOUNIT(dev); 1256 struct audio_softc *sc = audio_cd.cd_devs[unit]; 1257 struct audio_hw_if *hw = sc->hw_if; 1258 int s; 1259 1260 DPRINTF(("audio_close: unit=%d flags=0x%x\n", unit, flags)); 1261 1262 s = splaudio(); 1263 /* Stop recording. */ 1264 if ((flags & FREAD) && sc->sc_rbus) { 1265 /* 1266 * XXX Some drivers (e.g. SB) use the same routine 1267 * to halt input and output so don't halt input if 1268 * in full duplex mode. These drivers should be fixed. 1269 */ 1270 if (!sc->sc_full_duplex || sc->hw_if->halt_input != sc->hw_if->halt_output) 1271 sc->hw_if->halt_input(sc->hw_hdl); 1272 sc->sc_rbus = 0; 1273 } 1274 /* 1275 * Block until output drains, but allow ^C interrupt. 1276 */ 1277 sc->sc_pr.usedlow = sc->sc_pr.blksize; /* avoid excessive wakeups */ 1278 /* 1279 * If there is pending output, let it drain (unless 1280 * the output is paused). 1281 */ 1282 if ((flags & FWRITE) && sc->sc_pbus) { 1283 if (!sc->sc_pr.pause && !audio_drain(sc) && hw->drain) 1284 (void)hw->drain(sc->hw_hdl); 1285 sc->hw_if->halt_output(sc->hw_hdl); 1286 sc->sc_pbus = 0; 1287 } 1288 1289 hw->close(sc->hw_hdl); 1290 1291 /* 1292 * If flags has neither read nor write then reset both 1293 * directions. Encountered when someone runs revoke(2). 1294 */ 1295 1296 if ((flags & FREAD) || ((flags & (FREAD|FWRITE)) == 0)) { 1297 sc->sc_open &= ~AUOPEN_READ; 1298 sc->sc_mode &= ~AUMODE_RECORD; 1299 } 1300 if ((flags & FWRITE) || ((flags & (FREAD|FWRITE)) == 0)) { 1301 sc->sc_open &= ~AUOPEN_WRITE; 1302 sc->sc_mode &= ~(AUMODE_PLAY|AUMODE_PLAY_ALL); 1303 } 1304 1305 sc->sc_async_audio = 0; 1306 sc->sc_full_duplex = 0; 1307 splx(s); 1308 DPRINTF(("audio_close: done\n")); 1309 1310 return (0); 1311 } 1312 1313 int 1314 audio_read(dev_t dev, struct uio *uio, int ioflag) 1315 { 1316 int unit = AUDIOUNIT(dev); 1317 struct audio_softc *sc = audio_cd.cd_devs[unit]; 1318 struct audio_ringbuffer *cb = &sc->sc_rr; 1319 u_char *outp; 1320 int error, s, cc, n, resid; 1321 1322 if (cb->mmapped) 1323 return EINVAL; 1324 1325 DPRINTFN(1,("audio_read: cc=%d mode=%d\n", 1326 uio->uio_resid, sc->sc_mode)); 1327 1328 /* 1329 * Block if fully quiesced. Don't block when quiesce 1330 * has started, as the buffer position may still need 1331 * to advance. 1332 */ 1333 while (sc->sc_quiesce == AUDIO_QUIESCE_SILENT) 1334 tsleep(&sc->sc_quiesce, 0, "aud_qrd", 0); 1335 1336 error = 0; 1337 /* 1338 * If hardware is half-duplex and currently playing, return 1339 * silence blocks based on the number of blocks we have output. 1340 */ 1341 if (!sc->sc_full_duplex && 1342 (sc->sc_mode & AUMODE_PLAY)) { 1343 while (uio->uio_resid > 0 && !error) { 1344 s = splaudio(); 1345 for(;;) { 1346 cc = sc->sc_pr.stamp - sc->sc_wstamp; 1347 if (cc > 0) 1348 break; 1349 DPRINTF(("audio_read: stamp=%lu, wstamp=%lu\n", 1350 sc->sc_pr.stamp, sc->sc_wstamp)); 1351 if (ioflag & IO_NDELAY) { 1352 splx(s); 1353 return EWOULDBLOCK; 1354 } 1355 error = audio_sleep(&sc->sc_rchan, "aud_hr"); 1356 if (sc->sc_dying) 1357 error = EIO; 1358 if (error) { 1359 splx(s); 1360 return error; 1361 } 1362 } 1363 splx(s); 1364 1365 if (uio->uio_resid < cc / sc->sc_rparams.factor) 1366 cc = uio->uio_resid * sc->sc_rparams.factor; 1367 DPRINTFN(1, ("audio_read: reading in write mode, cc=%d\n", cc)); 1368 error = audio_silence_copyout(sc, 1369 cc / sc->sc_rparams.factor, uio); 1370 sc->sc_wstamp += cc; 1371 } 1372 return (error); 1373 } 1374 while (uio->uio_resid > 0) { 1375 s = splaudio(); 1376 while (cb->used <= 0) { 1377 if (!sc->sc_rbus && !sc->sc_rr.pause) { 1378 error = audiostartr(sc); 1379 if (error) { 1380 splx(s); 1381 return error; 1382 } 1383 } 1384 if (ioflag & IO_NDELAY) { 1385 splx(s); 1386 return (EWOULDBLOCK); 1387 } 1388 DPRINTFN(2, ("audio_read: sleep used=%d\n", cb->used)); 1389 error = audio_sleep(&sc->sc_rchan, "aud_rd"); 1390 if (sc->sc_dying) 1391 error = EIO; 1392 if (error) { 1393 splx(s); 1394 return error; 1395 } 1396 } 1397 resid = uio->uio_resid * sc->sc_rparams.factor; 1398 outp = cb->outp; 1399 cc = cb->used - cb->usedlow; /* maximum to read */ 1400 n = cb->end - outp; 1401 if (cc > n) 1402 cc = n; /* don't read beyond end of buffer */ 1403 1404 if (cc > resid) 1405 cc = resid; /* and no more than we want */ 1406 cb->used -= cc; 1407 cb->outp += cc; 1408 if (cb->outp >= cb->end) 1409 cb->outp = cb->start; 1410 splx(s); 1411 DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp, cc)); 1412 if (sc->sc_rparams.sw_code) 1413 sc->sc_rparams.sw_code(sc->hw_hdl, outp, cc); 1414 error = uiomove(outp, cc / sc->sc_rparams.factor, uio); 1415 if (error) 1416 return error; 1417 } 1418 return 0; 1419 } 1420 1421 void 1422 audio_clear(struct audio_softc *sc) 1423 { 1424 int s = splaudio(); 1425 1426 if (sc->sc_rbus) { 1427 audio_wakeup(&sc->sc_rchan); 1428 sc->hw_if->halt_input(sc->hw_hdl); 1429 sc->sc_rbus = 0; 1430 } 1431 if (sc->sc_pbus) { 1432 audio_wakeup(&sc->sc_wchan); 1433 sc->hw_if->halt_output(sc->hw_hdl); 1434 sc->sc_pbus = 0; 1435 } 1436 splx(s); 1437 } 1438 1439 void 1440 audio_set_blksize(struct audio_softc *sc, int mode, int fpb) { 1441 struct audio_hw_if *hw = sc->hw_if; 1442 struct audio_params *parm; 1443 struct audio_ringbuffer *rb; 1444 int bs, fs, maxbs; 1445 1446 if (mode == AUMODE_PLAY) { 1447 parm = &sc->sc_pparams; 1448 rb = &sc->sc_pr; 1449 } else { 1450 parm = &sc->sc_rparams; 1451 rb = &sc->sc_rr; 1452 } 1453 1454 fs = parm->channels * parm->bps; 1455 bs = fpb * fs; 1456 maxbs = rb->bufsize / 2; 1457 if (bs > maxbs) 1458 bs = (maxbs / fs) * fs; 1459 1460 ROUNDSIZE(bs); 1461 if (hw->round_blocksize) 1462 bs = hw->round_blocksize(sc->hw_hdl, bs); 1463 rb->blksize = bs; 1464 1465 DPRINTF(("audio_set_blksize: %s blksize=%d\n", 1466 mode == AUMODE_PLAY ? "play" : "record", bs)); 1467 } 1468 1469 void 1470 audio_calc_blksize(struct audio_softc *sc, int mode) 1471 { 1472 struct audio_params *param; 1473 1474 if (mode == AUMODE_PLAY) { 1475 if (sc->sc_pr.blkset) 1476 return; 1477 param = &sc->sc_pparams; 1478 } else { 1479 if (sc->sc_rr.blkset) 1480 return; 1481 param = &sc->sc_rparams; 1482 } 1483 audio_set_blksize(sc, mode, param->sample_rate * audio_blk_ms / 1000); 1484 } 1485 1486 void 1487 audio_fill_silence(struct audio_params *params, u_char *start, u_char *p, int n) 1488 { 1489 size_t rounderr; 1490 int i, nsamples; 1491 u_char auzero[4] = {0, 0, 0, 0}; 1492 1493 /* 1494 * p may point the middle of a sample; round it to the 1495 * beginning of the sample, so we overwrite partially written 1496 * ones. 1497 */ 1498 rounderr = (p - start) % params->bps; 1499 p -= rounderr; 1500 n += rounderr; 1501 nsamples = n / params->bps; 1502 1503 switch (params->encoding) { 1504 case AUDIO_ENCODING_SLINEAR_LE: 1505 case AUDIO_ENCODING_SLINEAR_BE: 1506 break; 1507 case AUDIO_ENCODING_ULAW: 1508 auzero[0] = 0x7f; 1509 break; 1510 case AUDIO_ENCODING_ALAW: 1511 auzero[0] = 0x55; 1512 break; 1513 case AUDIO_ENCODING_ULINEAR_LE: 1514 if (params->msb == 1) 1515 auzero[params->bps - 1] = 0x80; 1516 else 1517 auzero[params->bps - 1] = 1 << ((params->precision + 7) % NBBY); 1518 break; 1519 case AUDIO_ENCODING_ULINEAR_BE: 1520 if (params->msb == 1) 1521 auzero[0] = 0x80; 1522 else 1523 auzero[0] = 1 << ((params->precision + 7) % NBBY); 1524 break; 1525 case AUDIO_ENCODING_MPEG_L1_STREAM: 1526 case AUDIO_ENCODING_MPEG_L1_PACKETS: 1527 case AUDIO_ENCODING_MPEG_L1_SYSTEM: 1528 case AUDIO_ENCODING_MPEG_L2_STREAM: 1529 case AUDIO_ENCODING_MPEG_L2_PACKETS: 1530 case AUDIO_ENCODING_MPEG_L2_SYSTEM: 1531 case AUDIO_ENCODING_ADPCM: /* is this right XXX */ 1532 break; 1533 default: 1534 DPRINTF(("audio: bad encoding %d\n", params->encoding)); 1535 break; 1536 } 1537 while (--nsamples >= 0) { 1538 for (i = 0; i < params->bps; i++) 1539 *p++ = auzero[i]; 1540 } 1541 } 1542 1543 int 1544 audio_silence_copyout(struct audio_softc *sc, int n, struct uio *uio) 1545 { 1546 int error; 1547 int k; 1548 u_char zerobuf[128]; 1549 1550 audio_fill_silence(&sc->sc_rparams, zerobuf, zerobuf, sizeof zerobuf); 1551 1552 error = 0; 1553 while (n > 0 && uio->uio_resid > 0 && !error) { 1554 k = min(n, min(uio->uio_resid, sizeof zerobuf)); 1555 error = uiomove(zerobuf, k, uio); 1556 n -= k; 1557 } 1558 return (error); 1559 } 1560 1561 int 1562 audio_write(dev_t dev, struct uio *uio, int ioflag) 1563 { 1564 int unit = AUDIOUNIT(dev); 1565 struct audio_softc *sc = audio_cd.cd_devs[unit]; 1566 struct audio_ringbuffer *cb = &sc->sc_pr; 1567 u_char *inp; 1568 int error, s, n, cc, resid, avail; 1569 1570 DPRINTFN(2, ("audio_write: sc=%p(unit=%d) count=%d used=%d(hi=%d)\n", sc, unit, 1571 uio->uio_resid, sc->sc_pr.used, sc->sc_pr.usedhigh)); 1572 1573 if (cb->mmapped) 1574 return EINVAL; 1575 1576 /* 1577 * Block if fully quiesced. Don't block when quiesce 1578 * has started, as the buffer position may still need 1579 * to advance. 1580 */ 1581 while (sc->sc_quiesce == AUDIO_QUIESCE_SILENT) 1582 tsleep(&sc->sc_quiesce, 0, "aud_qwr", 0); 1583 1584 if (uio->uio_resid == 0) { 1585 sc->sc_eof++; 1586 return 0; 1587 } 1588 1589 /* 1590 * If half-duplex and currently recording, throw away data. 1591 */ 1592 if (!sc->sc_full_duplex && 1593 (sc->sc_mode & AUMODE_RECORD)) { 1594 uio->uio_offset += uio->uio_resid; 1595 uio->uio_resid = 0; 1596 DPRINTF(("audio_write: half-dpx read busy\n")); 1597 return (0); 1598 } 1599 1600 if (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) { 1601 n = min(sc->sc_playdrop, uio->uio_resid * sc->sc_pparams.factor); 1602 DPRINTF(("audio_write: playdrop %d\n", n)); 1603 uio->uio_offset += n / sc->sc_pparams.factor; 1604 uio->uio_resid -= n / sc->sc_pparams.factor; 1605 sc->sc_playdrop -= n; 1606 if (uio->uio_resid == 0) 1607 return 0; 1608 } 1609 1610 DPRINTFN(1, ("audio_write: sr=%ld, enc=%d, prec=%d, chan=%d, sw=%p, fact=%d\n", 1611 sc->sc_pparams.sample_rate, sc->sc_pparams.encoding, 1612 sc->sc_pparams.precision, sc->sc_pparams.channels, 1613 sc->sc_pparams.sw_code, sc->sc_pparams.factor)); 1614 1615 while (uio->uio_resid > 0) { 1616 s = splaudio(); 1617 while (cb->used >= cb->usedhigh) { 1618 DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d hiwat=%d\n", 1619 cb->used, cb->usedlow, cb->usedhigh)); 1620 if (ioflag & IO_NDELAY) { 1621 splx(s); 1622 return (EWOULDBLOCK); 1623 } 1624 error = audio_sleep(&sc->sc_wchan, "aud_wr"); 1625 if (sc->sc_dying) 1626 error = EIO; 1627 if (error) { 1628 splx(s); 1629 return error; 1630 } 1631 } 1632 resid = uio->uio_resid * sc->sc_pparams.factor; 1633 avail = cb->end - cb->inp; 1634 inp = cb->inp; 1635 cc = cb->usedhigh - cb->used; 1636 if (cc > resid) 1637 cc = resid; 1638 if (cc > avail) 1639 cc = avail; 1640 cb->inp += cc; 1641 if (cb->inp >= cb->end) 1642 cb->inp = cb->start; 1643 cb->used += cc; 1644 /* 1645 * This is a very suboptimal way of keeping track of 1646 * silence in the buffer, but it is simple. 1647 */ 1648 sc->sc_sil_count = 0; 1649 if (!sc->sc_pbus && !cb->pause && cb->used >= cb->blksize) { 1650 error = audiostartp(sc); 1651 if (error) { 1652 splx(s); 1653 return error; 1654 } 1655 } 1656 splx(s); 1657 cc /= sc->sc_pparams.factor; 1658 DPRINTFN(1, ("audio_write: uiomove cc=%d inp=%p, left=%d\n", 1659 cc, inp, uio->uio_resid)); 1660 error = uiomove(inp, cc, uio); 1661 if (error) 1662 return 0; 1663 if (sc->sc_pparams.sw_code) { 1664 sc->sc_pparams.sw_code(sc->hw_hdl, inp, cc); 1665 DPRINTFN(1, ("audio_write: expanded cc=%d\n", cc)); 1666 } 1667 } 1668 return 0; 1669 } 1670 1671 int 1672 audio_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 1673 { 1674 int unit = AUDIOUNIT(dev); 1675 struct audio_softc *sc = audio_cd.cd_devs[unit]; 1676 struct audio_hw_if *hw = sc->hw_if; 1677 struct audio_offset *ao; 1678 struct audio_info ai; 1679 int error = 0, s, offs, fd; 1680 int rbus, pbus; 1681 1682 /* 1683 * Block if fully quiesced. Don't block when quiesce 1684 * has started, as the buffer position may still need 1685 * to advance. An ioctl may be used to determine how 1686 * much to read or write. 1687 */ 1688 while (sc->sc_quiesce == AUDIO_QUIESCE_SILENT) 1689 tsleep(&sc->sc_quiesce, 0, "aud_qio", 0); 1690 1691 DPRINTF(("audio_ioctl(%d,'%c',%d)\n", 1692 IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff)); 1693 switch (cmd) { 1694 case FIONBIO: 1695 /* All handled in the upper FS layer. */ 1696 break; 1697 1698 case FIOASYNC: 1699 if (*(int *)addr) { 1700 if (sc->sc_async_audio) 1701 return (EBUSY); 1702 sc->sc_async_audio = p; 1703 DPRINTF(("audio_ioctl: FIOASYNC %p\n", p)); 1704 } else 1705 sc->sc_async_audio = 0; 1706 break; 1707 1708 case AUDIO_FLUSH: 1709 DPRINTF(("AUDIO_FLUSH\n")); 1710 rbus = sc->sc_rbus; 1711 pbus = sc->sc_pbus; 1712 audio_clear(sc); 1713 s = splaudio(); 1714 error = audio_initbufs(sc); 1715 if (error) { 1716 splx(s); 1717 return error; 1718 } 1719 sc->sc_rr.pause = 0; 1720 sc->sc_pr.pause = 0; 1721 if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_pbus && pbus) 1722 error = audiostartp(sc); 1723 if (!error && 1724 (sc->sc_mode & AUMODE_RECORD) && !sc->sc_rbus && rbus) 1725 error = audiostartr(sc); 1726 splx(s); 1727 break; 1728 1729 /* 1730 * Number of read (write) samples dropped. We don't know where or 1731 * when they were dropped. 1732 * 1733 * The audio_ringbuffer->drops count is the number of buffer 1734 * sample size bytes. Convert it to userland sample size bytes, 1735 * then convert to samples. There is no easy way to get the 1736 * buffer sample size, but the userland sample size can be 1737 * calculated with userland channels and userland precision. 1738 * 1739 * original formula: 1740 * sc->sc_rr.drops / 1741 * sc->sc_rparams.factor / 1742 * (sc->sc_rparams.channels * sc->sc_rparams.bps) 1743 */ 1744 case AUDIO_RERROR: 1745 *(int *)addr = sc->sc_rr.drops / 1746 (sc->sc_rparams.factor * sc->sc_rparams.channels * 1747 sc->sc_rparams.bps); 1748 break; 1749 1750 case AUDIO_PERROR: 1751 *(int *)addr = sc->sc_pr.drops / 1752 (sc->sc_pparams.factor * sc->sc_pparams.channels * 1753 sc->sc_pparams.bps); 1754 break; 1755 1756 /* 1757 * Offsets into buffer. 1758 */ 1759 case AUDIO_GETIOFFS: 1760 s = splaudio(); 1761 /* figure out where next DMA will start */ 1762 ao = (struct audio_offset *)addr; 1763 ao->samples = sc->sc_rr.stamp / sc->sc_rparams.factor; 1764 ao->deltablks = (sc->sc_rr.stamp - sc->sc_rr.stamp_last) / sc->sc_rr.blksize; 1765 sc->sc_rr.stamp_last = sc->sc_rr.stamp; 1766 ao->offset = (sc->sc_rr.inp - sc->sc_rr.start) / sc->sc_rparams.factor; 1767 splx(s); 1768 break; 1769 1770 case AUDIO_GETOOFFS: 1771 s = splaudio(); 1772 /* figure out where next DMA will start */ 1773 ao = (struct audio_offset *)addr; 1774 offs = sc->sc_pr.outp - sc->sc_pr.start + sc->sc_pr.blksize; 1775 if (sc->sc_pr.start + offs >= sc->sc_pr.end) 1776 offs = 0; 1777 ao->samples = sc->sc_pr.stamp / sc->sc_pparams.factor; 1778 ao->deltablks = (sc->sc_pr.stamp - sc->sc_pr.stamp_last) / sc->sc_pr.blksize; 1779 sc->sc_pr.stamp_last = sc->sc_pr.stamp; 1780 ao->offset = offs / sc->sc_pparams.factor; 1781 splx(s); 1782 break; 1783 1784 /* 1785 * How many bytes will elapse until mike hears the first 1786 * sample of what we write next? 1787 */ 1788 case AUDIO_WSEEK: 1789 *(u_long *)addr = sc->sc_pr.used / sc->sc_pparams.factor; 1790 break; 1791 1792 case AUDIO_SETINFO: 1793 DPRINTF(("AUDIO_SETINFO mode=0x%x\n", sc->sc_mode)); 1794 error = audiosetinfo(sc, (struct audio_info *)addr); 1795 break; 1796 1797 case AUDIO_GETINFO: 1798 DPRINTF(("AUDIO_GETINFO\n")); 1799 error = audiogetinfo(sc, (struct audio_info *)addr); 1800 break; 1801 1802 case AUDIO_DRAIN: 1803 DPRINTF(("AUDIO_DRAIN\n")); 1804 error = audio_drain(sc); 1805 if (!error && hw->drain) 1806 error = hw->drain(sc->hw_hdl); 1807 break; 1808 1809 case AUDIO_GETDEV: 1810 DPRINTF(("AUDIO_GETDEV\n")); 1811 error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr); 1812 break; 1813 1814 case AUDIO_GETENC: 1815 DPRINTF(("AUDIO_GETENC\n")); 1816 /* Pass read/write info down to query_encoding */ 1817 ((struct audio_encoding *)addr)->flags = sc->sc_open; 1818 error = hw->query_encoding(sc->hw_hdl, (struct audio_encoding *)addr); 1819 break; 1820 1821 case AUDIO_GETFD: 1822 DPRINTF(("AUDIO_GETFD\n")); 1823 *(int *)addr = sc->sc_full_duplex; 1824 break; 1825 1826 case AUDIO_SETFD: 1827 DPRINTF(("AUDIO_SETFD\n")); 1828 fd = *(int *)addr; 1829 if (hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX) { 1830 if (hw->setfd) 1831 error = hw->setfd(sc->hw_hdl, fd); 1832 else 1833 error = 0; 1834 if (!error) { 1835 sc->sc_full_duplex = fd; 1836 if (fd) { 1837 AUDIO_INITINFO(&ai); 1838 ai.mode = sc->sc_mode | 1839 (AUMODE_PLAY | AUMODE_RECORD); 1840 error = audiosetinfo(sc, &ai); 1841 } 1842 } 1843 } else { 1844 if (fd) 1845 error = ENOTTY; 1846 else 1847 error = 0; 1848 } 1849 break; 1850 1851 case AUDIO_GETPROPS: 1852 DPRINTF(("AUDIO_GETPROPS\n")); 1853 *(int *)addr = hw->get_props(sc->hw_hdl); 1854 break; 1855 1856 case AUDIO_GETPRINFO: 1857 DPRINTF(("AUDIO_GETPRINFO\n")); 1858 error = audiogetbufinfo(sc, (struct audio_bufinfo *)addr, 1859 AUMODE_PLAY); 1860 break; 1861 1862 case AUDIO_GETRRINFO: 1863 DPRINTF(("AUDIO_GETRRINFO\n")); 1864 error = audiogetbufinfo(sc, (struct audio_bufinfo *)addr, 1865 AUMODE_RECORD); 1866 break; 1867 1868 default: 1869 DPRINTF(("audio_ioctl: unknown ioctl\n")); 1870 error = ENOTTY; 1871 break; 1872 } 1873 DPRINTF(("audio_ioctl(%d,'%c',%d) result %d\n", 1874 IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff, error)); 1875 return (error); 1876 } 1877 1878 void 1879 audio_selwakeup(struct audio_softc *sc, int play) 1880 { 1881 struct selinfo *si; 1882 1883 si = play? &sc->sc_wsel : &sc->sc_rsel; 1884 1885 audio_wakeup(play? &sc->sc_wchan : &sc->sc_rchan); 1886 selwakeup(si); 1887 if (sc->sc_async_audio) 1888 psignal(sc->sc_async_audio, SIGIO); 1889 } 1890 1891 #define AUDIO_FILTREAD(sc) ( \ 1892 (!sc->sc_full_duplex && (sc->sc_mode & AUMODE_PLAY)) ? \ 1893 sc->sc_pr.stamp > sc->sc_wstamp : sc->sc_rr.used > sc->sc_rr.usedlow) 1894 1895 #define AUDIO_FILTWRITE(sc) ( \ 1896 (!sc->sc_full_duplex && (sc->sc_mode & AUMODE_RECORD)) || \ 1897 (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) || \ 1898 (sc->sc_pr.used < (sc->sc_pr.usedlow + sc->sc_pr.blksize))) 1899 1900 int 1901 audio_poll(dev_t dev, int events, struct proc *p) 1902 { 1903 int unit = AUDIOUNIT(dev); 1904 struct audio_softc *sc = audio_cd.cd_devs[unit]; 1905 int revents = 0, s = splaudio(); 1906 1907 DPRINTF(("audio_poll: events=0x%x mode=%d\n", events, sc->sc_mode)); 1908 1909 if (events & (POLLIN | POLLRDNORM)) { 1910 if (AUDIO_FILTREAD(sc)) 1911 revents |= events & (POLLIN | POLLRDNORM); 1912 } 1913 if (events & (POLLOUT | POLLWRNORM)) { 1914 if (AUDIO_FILTWRITE(sc)) 1915 revents |= events & (POLLOUT | POLLWRNORM); 1916 } 1917 if (revents == 0) { 1918 if (events & (POLLIN | POLLRDNORM)) 1919 selrecord(p, &sc->sc_rsel); 1920 if (events & (POLLOUT | POLLWRNORM)) 1921 selrecord(p, &sc->sc_wsel); 1922 } 1923 splx(s); 1924 return (revents); 1925 } 1926 1927 paddr_t 1928 audio_mmap(dev_t dev, off_t off, int prot) 1929 { 1930 int s; 1931 int unit = AUDIOUNIT(dev); 1932 struct audio_softc *sc = audio_cd.cd_devs[unit]; 1933 struct audio_hw_if *hw = sc->hw_if; 1934 struct audio_ringbuffer *cb; 1935 1936 DPRINTF(("audio_mmap: off=%d, prot=%d\n", off, prot)); 1937 1938 if (!(hw->get_props(sc->hw_hdl) & AUDIO_PROP_MMAP) || !hw->mappage) 1939 return -1; 1940 #if 0 1941 /* XXX 1942 * The idea here was to use the protection to determine if 1943 * we are mapping the read or write buffer, but it fails. 1944 * The VM system is broken in (at least) two ways. 1945 * 1) If you map memory VM_PROT_WRITE you SIGSEGV 1946 * when writing to it, so VM_PROT_READ|VM_PROT_WRITE 1947 * has to be used for mmapping the play buffer. 1948 * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE 1949 * audio_mmap will get called at some point with VM_PROT_READ 1950 * only. 1951 * So, alas, we always map the play buffer for now. 1952 */ 1953 if (prot == (VM_PROT_READ|VM_PROT_WRITE) || 1954 prot == VM_PROT_WRITE) 1955 cb = &sc->sc_pr; 1956 else if (prot == VM_PROT_READ) 1957 cb = &sc->sc_rr; 1958 else 1959 return -1; 1960 #else 1961 cb = &sc->sc_pr; 1962 #endif 1963 1964 if ((u_int)off >= cb->bufsize) 1965 return -1; 1966 if (!cb->mmapped) { 1967 cb->mmapped = 1; 1968 if (cb == &sc->sc_pr) { 1969 audio_fill_silence(&sc->sc_pparams, cb->start, cb->start, cb->bufsize); 1970 s = splaudio(); 1971 if (!sc->sc_pbus && !sc->sc_pr.pause) 1972 (void)audiostartp(sc); 1973 splx(s); 1974 } else { 1975 s = splaudio(); 1976 if (!sc->sc_rbus && !sc->sc_rr.pause) 1977 (void)audiostartr(sc); 1978 splx(s); 1979 } 1980 } 1981 1982 return hw->mappage(sc->hw_hdl, cb->start, off, prot); 1983 } 1984 1985 int 1986 audiostartr(struct audio_softc *sc) 1987 { 1988 int error; 1989 1990 DPRINTF(("audiostartr: start=%p used=%d(hi=%d) mmapped=%d\n", 1991 sc->sc_rr.start, sc->sc_rr.used, sc->sc_rr.usedhigh, 1992 sc->sc_rr.mmapped)); 1993 1994 if (sc->hw_if->trigger_input) 1995 error = sc->hw_if->trigger_input(sc->hw_hdl, sc->sc_rr.start, 1996 sc->sc_rr.end, sc->sc_rr.blksize, 1997 audio_rint, (void *)sc, &sc->sc_rparams); 1998 else 1999 error = sc->hw_if->start_input(sc->hw_hdl, sc->sc_rr.start, 2000 sc->sc_rr.blksize, audio_rint, (void *)sc); 2001 if (error) { 2002 DPRINTF(("audiostartr failed: %d\n", error)); 2003 return error; 2004 } 2005 sc->sc_rbus = 1; 2006 return 0; 2007 } 2008 2009 int 2010 audiostartp(struct audio_softc *sc) 2011 { 2012 int error; 2013 2014 DPRINTF(("audiostartp: start=%p used=%d(hi=%d) mmapped=%d\n", 2015 sc->sc_pr.start, sc->sc_pr.used, sc->sc_pr.usedhigh, 2016 sc->sc_pr.mmapped)); 2017 2018 if (!sc->sc_pr.mmapped && sc->sc_pr.used < sc->sc_pr.blksize) 2019 return 0; 2020 2021 if (sc->hw_if->trigger_output) 2022 error = sc->hw_if->trigger_output(sc->hw_hdl, sc->sc_pr.start, 2023 sc->sc_pr.end, sc->sc_pr.blksize, 2024 audio_pint, (void *)sc, &sc->sc_pparams); 2025 else 2026 error = sc->hw_if->start_output(sc->hw_hdl, sc->sc_pr.outp, 2027 sc->sc_pr.blksize, audio_pint, (void *)sc); 2028 if (error) { 2029 DPRINTF(("audiostartp failed: %d\n", error)); 2030 return error; 2031 } 2032 sc->sc_pbus = 1; 2033 return 0; 2034 } 2035 2036 /* 2037 * When the play interrupt routine finds that the write isn't keeping 2038 * the buffer filled it will insert silence in the buffer to make up 2039 * for this. The part of the buffer that is filled with silence 2040 * is kept track of in a very approximate way: it starts at sc_sil_start 2041 * and extends sc_sil_count bytes. If there is already silence in 2042 * the requested area nothing is done; so when the whole buffer is 2043 * silent nothing happens. When the writer starts again sc_sil_count 2044 * is set to 0. 2045 */ 2046 /* XXX 2047 * Putting silence into the output buffer should not really be done 2048 * at splaudio, but there is no softaudio level to do it at yet. 2049 */ 2050 static __inline void 2051 audio_pint_silence(struct audio_softc *sc, struct audio_ringbuffer *cb, 2052 u_char *inp, int cc) 2053 { 2054 u_char *s, *e, *p, *q; 2055 2056 if (sc->sc_sil_count > 0) { 2057 s = sc->sc_sil_start; /* start of silence */ 2058 e = s + sc->sc_sil_count; /* end of silence, may be beyond end */ 2059 p = inp; /* adjusted pointer to area to fill */ 2060 if (p < s) 2061 p += cb->end - cb->start; 2062 q = p+cc; 2063 /* Check if there is already silence. */ 2064 if (!(s <= p && p < e && 2065 s <= q && q <= e)) { 2066 if (s <= p) 2067 sc->sc_sil_count = max(sc->sc_sil_count, q-s); 2068 DPRINTFN(5, ("audio_pint_silence: fill cc=%d inp=%p, count=%d size=%d\n", 2069 cc, inp, sc->sc_sil_count, (int)(cb->end - cb->start))); 2070 2071 if (sc->sc_pparams.sw_code) { 2072 int ncc = cc / sc->sc_pparams.factor; 2073 audio_fill_silence(&sc->sc_pparams, cb->start, inp, ncc); 2074 sc->sc_pparams.sw_code(sc->hw_hdl, inp, ncc); 2075 } else 2076 audio_fill_silence(&sc->sc_pparams, cb->start, inp, cc); 2077 2078 } else { 2079 DPRINTFN(5, ("audio_pint_silence: already silent cc=%d inp=%p\n", cc, inp)); 2080 2081 } 2082 } else { 2083 sc->sc_sil_start = inp; 2084 sc->sc_sil_count = cc; 2085 DPRINTFN(5, ("audio_pint_silence: start fill %p %d\n", 2086 inp, cc)); 2087 2088 if (sc->sc_pparams.sw_code) { 2089 int ncc = cc / sc->sc_pparams.factor; 2090 audio_fill_silence(&sc->sc_pparams, cb->start, inp, ncc); 2091 sc->sc_pparams.sw_code(sc->hw_hdl, inp, ncc); 2092 } else 2093 audio_fill_silence(&sc->sc_pparams, cb->start, inp, cc); 2094 2095 } 2096 } 2097 2098 /* 2099 * Called from HW driver module on completion of dma output. 2100 * Start output of new block, wrap in ring buffer if needed. 2101 * If no more buffers to play, output zero instead. 2102 * Do a wakeup if necessary. 2103 */ 2104 void 2105 audio_pint(void *v) 2106 { 2107 struct audio_softc *sc = v; 2108 struct audio_hw_if *hw = sc->hw_if; 2109 struct audio_ringbuffer *cb = &sc->sc_pr; 2110 u_char *inp; 2111 int cc; 2112 int blksize; 2113 int error; 2114 2115 if (!sc->sc_open) 2116 return; /* ignore interrupt if not open */ 2117 2118 if (sc->sc_pqui) 2119 return; 2120 2121 blksize = cb->blksize; 2122 2123 add_audio_randomness((long)cb); 2124 2125 cb->outp += blksize; 2126 if (cb->outp >= cb->end) 2127 cb->outp = cb->start; 2128 cb->stamp += blksize; 2129 if (cb->mmapped) { 2130 DPRINTFN(5, ("audio_pint: mmapped outp=%p cc=%d inp=%p\n", 2131 cb->outp, blksize, cb->inp)); 2132 if (!hw->trigger_output) 2133 (void)hw->start_output(sc->hw_hdl, cb->outp, 2134 blksize, audio_pint, (void *)sc); 2135 return; 2136 } 2137 2138 #ifdef AUDIO_INTR_TIME 2139 { 2140 struct timeval tv; 2141 u_long t; 2142 microtime(&tv); 2143 t = tv.tv_usec + 1000000 * tv.tv_sec; 2144 if (sc->sc_pnintr) { 2145 long lastdelta, totdelta; 2146 lastdelta = t - sc->sc_plastintr - sc->sc_pblktime; 2147 if (lastdelta > sc->sc_pblktime / 3) { 2148 printf("audio: play interrupt(%d) off relative by %ld us (%lu)\n", 2149 sc->sc_pnintr, lastdelta, sc->sc_pblktime); 2150 } 2151 totdelta = t - sc->sc_pfirstintr - sc->sc_pblktime * sc->sc_pnintr; 2152 if (totdelta > sc->sc_pblktime) { 2153 printf("audio: play interrupt(%d) off absolute by %ld us (%lu) (LOST)\n", 2154 sc->sc_pnintr, totdelta, sc->sc_pblktime); 2155 sc->sc_pnintr++; /* avoid repeated messages */ 2156 } 2157 } else 2158 sc->sc_pfirstintr = t; 2159 sc->sc_plastintr = t; 2160 sc->sc_pnintr++; 2161 } 2162 #endif 2163 2164 cb->used -= blksize; 2165 if (cb->used < blksize) { 2166 /* we don't have a full block to use */ 2167 inp = cb->inp; 2168 cc = blksize - (inp - cb->start) % blksize; 2169 if (cb->pause) 2170 cb->pdrops += cc; 2171 else { 2172 cb->drops += cc; 2173 sc->sc_playdrop += cc; 2174 } 2175 audio_pint_silence(sc, cb, inp, cc); 2176 inp += cc; 2177 if (inp >= cb->end) 2178 inp = cb->start; 2179 cb->inp = inp; 2180 cb->used += cc; 2181 2182 /* Clear next block so we keep ahead of the DMA. */ 2183 if (cb->used + cc < cb->usedhigh) 2184 audio_pint_silence(sc, cb, inp, blksize); 2185 } 2186 2187 DPRINTFN(5, ("audio_pint: outp=%p cc=%d\n", cb->outp, blksize)); 2188 if (!hw->trigger_output) { 2189 error = hw->start_output(sc->hw_hdl, cb->outp, blksize, 2190 audio_pint, (void *)sc); 2191 if (error) { 2192 /* XXX does this really help? */ 2193 DPRINTF(("audio_pint restart failed: %d\n", error)); 2194 audio_clear(sc); 2195 } 2196 } 2197 2198 DPRINTFN(2, ("audio_pint: mode=%d pause=%d used=%d lowat=%d\n", 2199 sc->sc_mode, cb->pause, cb->used, cb->usedlow)); 2200 if ((sc->sc_mode & AUMODE_PLAY) && !cb->pause && 2201 cb->used <= cb->usedlow) 2202 audio_selwakeup(sc, 1); 2203 2204 /* Possible to return one or more "phantom blocks" now. */ 2205 if (!sc->sc_full_duplex && sc->sc_rchan) 2206 audio_selwakeup(sc, 0); 2207 2208 /* 2209 * If quiesce requested, halt output when the ring buffer position 2210 * is at the beginning, because when the hardware is resumed, it's 2211 * buffer position is reset to the beginning. This will put 2212 * hardware and software positions in sync across a suspend cycle. 2213 */ 2214 if (sc->sc_quiesce == AUDIO_QUIESCE_START && cb->outp == cb->start) { 2215 sc->sc_pqui = 1; 2216 audio_wakeup(&sc->sc_wchan); 2217 } 2218 } 2219 2220 /* 2221 * Called from HW driver module on completion of dma input. 2222 * Mark it as input in the ring buffer (fiddle pointers). 2223 * Do a wakeup if necessary. 2224 */ 2225 void 2226 audio_rint(void *v) 2227 { 2228 struct audio_softc *sc = v; 2229 struct audio_hw_if *hw = sc->hw_if; 2230 struct audio_ringbuffer *cb = &sc->sc_rr; 2231 int blksize; 2232 int error; 2233 2234 if (!sc->sc_open) 2235 return; /* ignore interrupt if not open */ 2236 2237 if (sc->sc_rqui) 2238 return; 2239 2240 add_audio_randomness((long)cb); 2241 2242 blksize = cb->blksize; 2243 2244 cb->inp += blksize; 2245 if (cb->inp >= cb->end) 2246 cb->inp = cb->start; 2247 cb->stamp += blksize; 2248 if (cb->mmapped) { 2249 DPRINTFN(2, ("audio_rint: mmapped inp=%p cc=%d\n", 2250 cb->inp, blksize)); 2251 if (!hw->trigger_input) 2252 (void)hw->start_input(sc->hw_hdl, cb->inp, blksize, 2253 audio_rint, (void *)sc); 2254 return; 2255 } 2256 2257 #ifdef AUDIO_INTR_TIME 2258 { 2259 struct timeval tv; 2260 u_long t; 2261 microtime(&tv); 2262 t = tv.tv_usec + 1000000 * tv.tv_sec; 2263 if (sc->sc_rnintr) { 2264 long lastdelta, totdelta; 2265 lastdelta = t - sc->sc_rlastintr - sc->sc_rblktime; 2266 if (lastdelta > sc->sc_rblktime / 5) { 2267 printf("audio: record interrupt(%d) off relative by %ld us (%lu)\n", 2268 sc->sc_rnintr, lastdelta, sc->sc_rblktime); 2269 } 2270 totdelta = t - sc->sc_rfirstintr - sc->sc_rblktime * sc->sc_rnintr; 2271 if (totdelta > sc->sc_rblktime / 2) { 2272 sc->sc_rnintr++; 2273 printf("audio: record interrupt(%d) off absolute by %ld us (%lu)\n", 2274 sc->sc_rnintr, totdelta, sc->sc_rblktime); 2275 sc->sc_rnintr++; /* avoid repeated messages */ 2276 } 2277 } else 2278 sc->sc_rfirstintr = t; 2279 sc->sc_rlastintr = t; 2280 sc->sc_rnintr++; 2281 } 2282 #endif 2283 2284 cb->used += blksize; 2285 if (cb->pause) { 2286 DPRINTFN(1, ("audio_rint: pdrops %lu\n", cb->pdrops)); 2287 cb->pdrops += blksize; 2288 cb->outp += blksize; 2289 if (cb->outp >= cb->end) 2290 cb->outp = cb->start; 2291 cb->used -= blksize; 2292 } else if (cb->used >= cb->usedhigh) { 2293 DPRINTFN(1, ("audio_rint: drops %lu\n", cb->drops)); 2294 cb->drops += blksize; 2295 cb->outp += blksize; 2296 if (cb->outp >= cb->end) 2297 cb->outp = cb->start; 2298 cb->used -= blksize; 2299 } 2300 2301 DPRINTFN(2, ("audio_rint: inp=%p cc=%d used=%d\n", 2302 cb->inp, blksize, cb->used)); 2303 if (!hw->trigger_input) { 2304 error = hw->start_input(sc->hw_hdl, cb->inp, blksize, 2305 audio_rint, (void *)sc); 2306 if (error) { 2307 /* XXX does this really help? */ 2308 DPRINTF(("audio_rint: restart failed: %d\n", error)); 2309 audio_clear(sc); 2310 } 2311 } 2312 2313 audio_selwakeup(sc, 0); 2314 2315 /* 2316 * If quiesce requested, halt input when the ring buffer position 2317 * is at the beginning, because when the hardware is resumed, it's 2318 * buffer position is reset to the beginning. This will put 2319 * hardware and software positions in sync across a suspend cycle. 2320 */ 2321 if (sc->sc_quiesce == AUDIO_QUIESCE_START && cb->inp == cb->start) { 2322 sc->sc_rqui = 1; 2323 audio_wakeup(&sc->sc_rchan); 2324 } 2325 } 2326 2327 int 2328 audio_check_params(struct audio_params *p) 2329 { 2330 if (p->channels < 1 || p->channels > 12) 2331 return (EINVAL); 2332 2333 if (p->precision < 8 || p->precision > 32) 2334 return (EINVAL); 2335 2336 if (p->encoding == AUDIO_ENCODING_PCM16) { 2337 if (p->precision == 8) 2338 p->encoding = AUDIO_ENCODING_ULINEAR; 2339 else 2340 p->encoding = AUDIO_ENCODING_SLINEAR; 2341 } else if (p->encoding == AUDIO_ENCODING_PCM8) { 2342 if (p->precision == 8) 2343 p->encoding = AUDIO_ENCODING_ULINEAR; 2344 else 2345 return EINVAL; 2346 } 2347 2348 if (p->encoding == AUDIO_ENCODING_SLINEAR) 2349 #if BYTE_ORDER == LITTLE_ENDIAN 2350 p->encoding = AUDIO_ENCODING_SLINEAR_LE; 2351 #else 2352 p->encoding = AUDIO_ENCODING_SLINEAR_BE; 2353 #endif 2354 if (p->encoding == AUDIO_ENCODING_ULINEAR) 2355 #if BYTE_ORDER == LITTLE_ENDIAN 2356 p->encoding = AUDIO_ENCODING_ULINEAR_LE; 2357 #else 2358 p->encoding = AUDIO_ENCODING_ULINEAR_BE; 2359 #endif 2360 2361 switch (p->encoding) { 2362 case AUDIO_ENCODING_ULAW: 2363 case AUDIO_ENCODING_ALAW: 2364 case AUDIO_ENCODING_ADPCM: 2365 if (p->precision != 8) 2366 p->precision = 8; 2367 break; 2368 case AUDIO_ENCODING_SLINEAR_LE: 2369 case AUDIO_ENCODING_SLINEAR_BE: 2370 case AUDIO_ENCODING_ULINEAR_LE: 2371 case AUDIO_ENCODING_ULINEAR_BE: 2372 case AUDIO_ENCODING_MPEG_L1_STREAM: 2373 case AUDIO_ENCODING_MPEG_L1_PACKETS: 2374 case AUDIO_ENCODING_MPEG_L1_SYSTEM: 2375 case AUDIO_ENCODING_MPEG_L2_STREAM: 2376 case AUDIO_ENCODING_MPEG_L2_PACKETS: 2377 case AUDIO_ENCODING_MPEG_L2_SYSTEM: 2378 break; 2379 default: 2380 return (EINVAL); 2381 } 2382 2383 return (0); 2384 } 2385 2386 int 2387 au_set_lr_value(struct audio_softc *sc, mixer_ctrl_t *ct, int l, int r) 2388 { 2389 ct->type = AUDIO_MIXER_VALUE; 2390 ct->un.value.num_channels = 2; 2391 ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l; 2392 ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r; 2393 if (sc->hw_if->set_port(sc->hw_hdl, ct) == 0) 2394 return 0; 2395 ct->un.value.num_channels = 1; 2396 ct->un.value.level[AUDIO_MIXER_LEVEL_MONO] = (l+r)/2; 2397 return sc->hw_if->set_port(sc->hw_hdl, ct); 2398 } 2399 2400 int 2401 au_get_mute(struct audio_softc *sc, struct au_mixer_ports *ports, u_char *mute) 2402 { 2403 mixer_devinfo_t mi; 2404 mixer_ctrl_t ct; 2405 int error; 2406 2407 *mute = 0; 2408 2409 /* if no master, silently ignore request */ 2410 if (ports->master == -1) 2411 return 0; 2412 2413 mi.index = ports->master; 2414 error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi); 2415 if (error != 0) 2416 return error; 2417 2418 /* master mute control should be the next device, if it exists */ 2419 if (mi.next < 0) 2420 return 0; 2421 2422 ct.dev = mi.next; 2423 ct.type = AUDIO_MIXER_ENUM; 2424 error = sc->hw_if->get_port(sc->hw_hdl, &ct); 2425 if (error != 0) 2426 return error; 2427 2428 *mute = ct.un.ord; 2429 2430 return error; 2431 } 2432 2433 int 2434 au_set_mute(struct audio_softc *sc, struct au_mixer_ports *ports, u_char mute) 2435 { 2436 mixer_devinfo_t mi; 2437 mixer_ctrl_t ct; 2438 int error; 2439 2440 /* if no master, silently ignore request */ 2441 if (ports->master == -1) 2442 return 0; 2443 2444 mi.index = ports->master; 2445 error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi); 2446 if (error != 0) 2447 return error; 2448 2449 /* master mute control should be the next device, if it exists */ 2450 if (mi.next < 0) 2451 return 0; 2452 2453 ct.dev = mi.next; 2454 ct.type = AUDIO_MIXER_ENUM; 2455 error = sc->hw_if->get_port(sc->hw_hdl, &ct); 2456 if (error != 0) 2457 return error; 2458 2459 DPRINTF(("au_set_mute: mute (old): %d, mute (new): %d\n", 2460 ct.un.ord, mute)); 2461 2462 ct.un.ord = (mute != 0 ? 1 : 0); 2463 error = sc->hw_if->set_port(sc->hw_hdl, &ct); 2464 2465 if (!error) 2466 mixer_signal(sc); 2467 return error; 2468 } 2469 2470 int 2471 au_set_gain(struct audio_softc *sc, struct au_mixer_ports *ports, int gain, 2472 int balance) 2473 { 2474 mixer_ctrl_t ct; 2475 int i, error; 2476 int l, r; 2477 u_int mask; 2478 int nset; 2479 2480 /* XXX silently adjust to within limits or return EINVAL ? */ 2481 if (gain > AUDIO_MAX_GAIN) 2482 gain = AUDIO_MAX_GAIN; 2483 else if (gain < AUDIO_MIN_GAIN) 2484 gain = AUDIO_MIN_GAIN; 2485 2486 if (balance == AUDIO_MID_BALANCE) { 2487 l = r = gain; 2488 } else if (balance < AUDIO_MID_BALANCE) { 2489 r = gain; 2490 l = (balance * gain) / AUDIO_MID_BALANCE; 2491 } else { 2492 l = gain; 2493 r = ((AUDIO_RIGHT_BALANCE - balance) * gain) 2494 / AUDIO_MID_BALANCE; 2495 } 2496 DPRINTF(("au_set_gain: gain=%d balance=%d, l=%d r=%d\n", 2497 gain, balance, l, r)); 2498 2499 if (ports->index == -1) { 2500 usemaster: 2501 if (ports->master == -1) 2502 return 0; /* just ignore it silently */ 2503 ct.dev = ports->master; 2504 error = au_set_lr_value(sc, &ct, l, r); 2505 } else { 2506 ct.dev = ports->index; 2507 if (ports->isenum) { 2508 ct.type = AUDIO_MIXER_ENUM; 2509 error = sc->hw_if->get_port(sc->hw_hdl, &ct); 2510 if (error) 2511 return error; 2512 for(i = 0; i < ports->nports; i++) { 2513 if (ports->misel[i] == ct.un.ord) { 2514 ct.dev = ports->miport[i]; 2515 if (ct.dev == -1 || 2516 au_set_lr_value(sc, &ct, l, r)) 2517 goto usemaster; 2518 else 2519 break; 2520 } 2521 } 2522 } else { 2523 ct.type = AUDIO_MIXER_SET; 2524 error = sc->hw_if->get_port(sc->hw_hdl, &ct); 2525 if (error) 2526 return error; 2527 mask = ct.un.mask; 2528 nset = 0; 2529 for(i = 0; i < ports->nports; i++) { 2530 if (ports->misel[i] & mask) { 2531 ct.dev = ports->miport[i]; 2532 if (ct.dev != -1 && 2533 au_set_lr_value(sc, &ct, l, r) == 0) 2534 nset++; 2535 } 2536 } 2537 if (nset == 0) 2538 goto usemaster; 2539 } 2540 } 2541 if (!error) 2542 mixer_signal(sc); 2543 return error; 2544 } 2545 2546 int 2547 au_get_lr_value(struct audio_softc *sc, mixer_ctrl_t *ct, int *l, int *r) 2548 { 2549 int error; 2550 2551 ct->un.value.num_channels = 2; 2552 if (sc->hw_if->get_port(sc->hw_hdl, ct) == 0) { 2553 *l = ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 2554 *r = ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 2555 } else { 2556 ct->un.value.num_channels = 1; 2557 error = sc->hw_if->get_port(sc->hw_hdl, ct); 2558 if (error) 2559 return error; 2560 *r = *l = ct->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 2561 } 2562 return 0; 2563 } 2564 2565 void 2566 au_get_gain(struct audio_softc *sc, struct au_mixer_ports *ports, u_int *pgain, 2567 u_char *pbalance) 2568 { 2569 mixer_ctrl_t ct; 2570 int i, l, r, n; 2571 int lgain = AUDIO_MAX_GAIN/2, rgain = AUDIO_MAX_GAIN/2; 2572 2573 if (ports->index == -1) { 2574 usemaster: 2575 if (ports->master == -1) 2576 goto bad; 2577 ct.dev = ports->master; 2578 ct.type = AUDIO_MIXER_VALUE; 2579 if (au_get_lr_value(sc, &ct, &lgain, &rgain)) 2580 goto bad; 2581 } else { 2582 ct.dev = ports->index; 2583 if (ports->isenum) { 2584 ct.type = AUDIO_MIXER_ENUM; 2585 if (sc->hw_if->get_port(sc->hw_hdl, &ct)) 2586 goto bad; 2587 ct.type = AUDIO_MIXER_VALUE; 2588 for(i = 0; i < ports->nports; i++) { 2589 if (ports->misel[i] == ct.un.ord) { 2590 ct.dev = ports->miport[i]; 2591 if (ct.dev == -1 || 2592 au_get_lr_value(sc, &ct, 2593 &lgain, &rgain)) 2594 goto usemaster; 2595 else 2596 break; 2597 } 2598 } 2599 } else { 2600 ct.type = AUDIO_MIXER_SET; 2601 if (sc->hw_if->get_port(sc->hw_hdl, &ct)) 2602 goto bad; 2603 ct.type = AUDIO_MIXER_VALUE; 2604 lgain = rgain = n = 0; 2605 for(i = 0; i < ports->nports; i++) { 2606 if (ports->misel[i] & ct.un.mask) { 2607 ct.dev = ports->miport[i]; 2608 if (ct.dev == -1 || 2609 au_get_lr_value(sc, &ct, &l, &r)) 2610 goto usemaster; 2611 else { 2612 lgain += l; 2613 rgain += r; 2614 n++; 2615 } 2616 } 2617 } 2618 if (n != 0) { 2619 lgain /= n; 2620 rgain /= n; 2621 } 2622 } 2623 } 2624 bad: 2625 if (lgain == rgain) { /* handles lgain==rgain==0 */ 2626 *pgain = lgain; 2627 *pbalance = AUDIO_MID_BALANCE; 2628 } else if (lgain < rgain) { 2629 *pgain = rgain; 2630 *pbalance = (AUDIO_MID_BALANCE * lgain) / rgain; 2631 } else /* lgain > rgain */ { 2632 *pgain = lgain; 2633 *pbalance = AUDIO_RIGHT_BALANCE - 2634 (AUDIO_MID_BALANCE * rgain) / lgain; 2635 } 2636 } 2637 2638 int 2639 au_set_port(struct audio_softc *sc, struct au_mixer_ports *ports, u_int port) 2640 { 2641 mixer_ctrl_t ct; 2642 int i, error; 2643 2644 if (port == 0) /* allow this special case */ 2645 return 0; 2646 2647 if (ports->index == -1) 2648 return EINVAL; 2649 ct.dev = ports->index; 2650 if (ports->isenum) { 2651 if (port & (port-1)) 2652 return EINVAL; /* Only one port allowed */ 2653 ct.type = AUDIO_MIXER_ENUM; 2654 error = EINVAL; 2655 for(i = 0; i < ports->nports; i++) 2656 if (ports->aumask[i] == port) { 2657 ct.un.ord = ports->misel[i]; 2658 error = sc->hw_if->set_port(sc->hw_hdl, &ct); 2659 break; 2660 } 2661 } else { 2662 ct.type = AUDIO_MIXER_SET; 2663 ct.un.mask = 0; 2664 for(i = 0; i < ports->nports; i++) 2665 if (ports->aumask[i] & port) 2666 ct.un.mask |= ports->misel[i]; 2667 if (port != 0 && ct.un.mask == 0) 2668 error = EINVAL; 2669 else 2670 error = sc->hw_if->set_port(sc->hw_hdl, &ct); 2671 } 2672 if (!error) 2673 mixer_signal(sc); 2674 return error; 2675 } 2676 2677 int 2678 au_get_port(struct audio_softc *sc, struct au_mixer_ports *ports) 2679 { 2680 mixer_ctrl_t ct; 2681 int i, aumask; 2682 2683 if (ports->index == -1) 2684 return 0; 2685 ct.dev = ports->index; 2686 ct.type = ports->isenum ? AUDIO_MIXER_ENUM : AUDIO_MIXER_SET; 2687 if (sc->hw_if->get_port(sc->hw_hdl, &ct)) 2688 return 0; 2689 aumask = 0; 2690 if (ports->isenum) { 2691 for(i = 0; i < ports->nports; i++) 2692 if (ct.un.ord == ports->misel[i]) 2693 aumask = ports->aumask[i]; 2694 } else { 2695 for(i = 0; i < ports->nports; i++) 2696 if (ct.un.mask & ports->misel[i]) 2697 aumask |= ports->aumask[i]; 2698 } 2699 return aumask; 2700 } 2701 2702 int 2703 audiosetinfo(struct audio_softc *sc, struct audio_info *ai) 2704 { 2705 struct audio_prinfo *r = &ai->record, *p = &ai->play; 2706 int cleared; 2707 int s, setmode, modechange = 0; 2708 int error; 2709 struct audio_hw_if *hw = sc->hw_if; 2710 struct audio_params pp, rp; 2711 int np, nr; 2712 unsigned int blks; 2713 int oldpblksize, oldrblksize; 2714 int rbus, pbus; 2715 int fpb; 2716 int fs; 2717 u_int gain; 2718 u_char balance; 2719 2720 if (hw == 0) /* HW has not attached */ 2721 return(ENXIO); 2722 2723 rbus = sc->sc_rbus; 2724 pbus = sc->sc_pbus; 2725 error = 0; 2726 cleared = 0; 2727 2728 pp = sc->sc_pparams; /* Temporary encoding storage in */ 2729 rp = sc->sc_rparams; /* case setting the modes fails. */ 2730 nr = np = 0; 2731 2732 if (p->sample_rate != ~0) { 2733 pp.sample_rate = p->sample_rate; 2734 np++; 2735 } 2736 if (r->sample_rate != ~0) { 2737 rp.sample_rate = r->sample_rate; 2738 nr++; 2739 } 2740 if (p->encoding != ~0) { 2741 pp.encoding = p->encoding; 2742 np++; 2743 } 2744 if (r->encoding != ~0) { 2745 rp.encoding = r->encoding; 2746 nr++; 2747 } 2748 if (p->precision != ~0) { 2749 pp.precision = p->precision; 2750 np++; 2751 } 2752 if (r->precision != ~0) { 2753 rp.precision = r->precision; 2754 nr++; 2755 } 2756 if (p->bps != ~0) { 2757 pp.bps = p->bps; 2758 np++; 2759 } 2760 if (r->bps != ~0) { 2761 rp.bps = r->bps; 2762 nr++; 2763 } 2764 if (p->msb != ~0) { 2765 pp.msb = p->msb; 2766 np++; 2767 } 2768 if (r->msb != ~0) { 2769 rp.msb = r->msb; 2770 nr++; 2771 } 2772 if (p->channels != ~0) { 2773 pp.channels = p->channels; 2774 np++; 2775 } 2776 if (r->channels != ~0) { 2777 rp.channels = r->channels; 2778 nr++; 2779 } 2780 #ifdef AUDIO_DEBUG 2781 if (audiodebug && nr) 2782 audio_print_params("Setting record params", &rp); 2783 if (audiodebug && np) 2784 audio_print_params("Setting play params", &pp); 2785 #endif 2786 if (nr && (error = audio_check_params(&rp))) 2787 return error; 2788 if (np && (error = audio_check_params(&pp))) 2789 return error; 2790 setmode = 0; 2791 if (nr) { 2792 if (!cleared) 2793 audio_clear(sc); 2794 modechange = cleared = 1; 2795 rp.sw_code = 0; 2796 rp.factor = 1; 2797 setmode |= AUMODE_RECORD; 2798 } 2799 if (np) { 2800 if (!cleared) 2801 audio_clear(sc); 2802 modechange = cleared = 1; 2803 pp.sw_code = 0; 2804 pp.factor = 1; 2805 setmode |= AUMODE_PLAY; 2806 } 2807 2808 if (ai->mode != ~0) { 2809 if (!cleared) 2810 audio_clear(sc); 2811 modechange = cleared = 1; 2812 sc->sc_mode = ai->mode; 2813 if (sc->sc_mode & AUMODE_PLAY_ALL) 2814 sc->sc_mode |= AUMODE_PLAY; 2815 if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_full_duplex) 2816 /* Play takes precedence */ 2817 sc->sc_mode &= ~AUMODE_RECORD; 2818 } 2819 2820 if (modechange) { 2821 int indep = hw->get_props(sc->hw_hdl) & AUDIO_PROP_INDEPENDENT; 2822 if (!indep) { 2823 if (setmode == AUMODE_RECORD) 2824 pp = rp; 2825 else 2826 rp = pp; 2827 } 2828 error = hw->set_params(sc->hw_hdl, setmode, 2829 sc->sc_mode & (AUMODE_PLAY | AUMODE_RECORD), &pp, &rp); 2830 if (error) 2831 return (error); 2832 if (!indep) { 2833 if (setmode == AUMODE_RECORD) { 2834 pp.sample_rate = rp.sample_rate; 2835 pp.encoding = rp.encoding; 2836 pp.channels = rp.channels; 2837 pp.precision = rp.precision; 2838 pp.bps = rp.bps; 2839 pp.msb = rp.msb; 2840 } else if (setmode == AUMODE_PLAY) { 2841 rp.sample_rate = pp.sample_rate; 2842 rp.encoding = pp.encoding; 2843 rp.channels = pp.channels; 2844 rp.precision = pp.precision; 2845 rp.bps = pp.bps; 2846 rp.msb = pp.msb; 2847 } 2848 } 2849 sc->sc_rparams = rp; 2850 sc->sc_pparams = pp; 2851 } 2852 2853 oldpblksize = sc->sc_pr.blksize; 2854 oldrblksize = sc->sc_rr.blksize; 2855 2856 /* 2857 * allow old-style blocksize changes, for compatibility; 2858 * individual play/record block sizes have precedence 2859 */ 2860 if (ai->blocksize != ~0) { 2861 if (r->block_size == ~0) 2862 r->block_size = ai->blocksize; 2863 if (p->block_size == ~0) 2864 p->block_size = ai->blocksize; 2865 } 2866 if (r->block_size != ~0) { 2867 sc->sc_rr.blkset = 0; 2868 if (!cleared) 2869 audio_clear(sc); 2870 cleared = 1; 2871 nr++; 2872 } 2873 if (p->block_size != ~0) { 2874 sc->sc_pr.blkset = 0; 2875 if (!cleared) 2876 audio_clear(sc); 2877 cleared = 1; 2878 np++; 2879 } 2880 if (nr) { 2881 if (r->block_size == ~0 || r->block_size == 0) { 2882 fpb = rp.sample_rate * audio_blk_ms / 1000; 2883 } else { 2884 fs = rp.channels * rp.bps; 2885 fpb = (r->block_size * rp.factor) / fs; 2886 } 2887 if (sc->sc_rr.blkset == 0) 2888 audio_set_blksize(sc, AUMODE_RECORD, fpb); 2889 } 2890 if (np) { 2891 if (p->block_size == ~0 || p->block_size == 0) { 2892 fpb = pp.sample_rate * audio_blk_ms / 1000; 2893 } else { 2894 fs = pp.channels * pp.bps; 2895 fpb = (p->block_size * pp.factor) / fs; 2896 } 2897 if (sc->sc_pr.blkset == 0) 2898 audio_set_blksize(sc, AUMODE_PLAY, fpb); 2899 } 2900 if (r->block_size != ~0 && r->block_size != 0) 2901 sc->sc_rr.blkset = 1; 2902 if (p->block_size != ~0 && p->block_size != 0) 2903 sc->sc_pr.blkset = 1; 2904 2905 #ifdef AUDIO_DEBUG 2906 if (audiodebug > 1 && nr) 2907 audio_print_params("After setting record params", &sc->sc_rparams); 2908 if (audiodebug > 1 && np) 2909 audio_print_params("After setting play params", &sc->sc_pparams); 2910 #endif 2911 2912 if (p->port != ~0) { 2913 if (!cleared) 2914 audio_clear(sc); 2915 cleared = 1; 2916 2917 error = au_set_port(sc, &sc->sc_outports, p->port); 2918 if (error) 2919 return(error); 2920 } 2921 if (r->port != ~0) { 2922 if (!cleared) 2923 audio_clear(sc); 2924 cleared = 1; 2925 2926 error = au_set_port(sc, &sc->sc_inports, r->port); 2927 if (error) 2928 return(error); 2929 } 2930 if (p->gain != ~0) { 2931 au_get_gain(sc, &sc->sc_outports, &gain, &balance); 2932 error = au_set_gain(sc, &sc->sc_outports, p->gain, balance); 2933 if (error) 2934 return(error); 2935 } 2936 if ((r->gain != ~0) && (r->port != 0)) { 2937 au_get_gain(sc, &sc->sc_inports, &gain, &balance); 2938 error = au_set_gain(sc, &sc->sc_inports, r->gain, balance); 2939 if (error) 2940 return(error); 2941 } 2942 2943 if (p->balance != (u_char)~0) { 2944 au_get_gain(sc, &sc->sc_outports, &gain, &balance); 2945 error = au_set_gain(sc, &sc->sc_outports, gain, p->balance); 2946 if (error) 2947 return(error); 2948 } 2949 if ((r->balance != (u_char)~0) && (r->port != 0)) { 2950 au_get_gain(sc, &sc->sc_inports, &gain, &balance); 2951 error = au_set_gain(sc, &sc->sc_inports, gain, r->balance); 2952 if (error) 2953 return(error); 2954 } 2955 2956 if (ai->output_muted != (u_char)~0) { 2957 error = au_set_mute(sc, &sc->sc_outports, ai->output_muted); 2958 if (error) 2959 return(error); 2960 } 2961 2962 if (ai->monitor_gain != ~0 && 2963 sc->sc_monitor_port != -1) { 2964 mixer_ctrl_t ct; 2965 2966 ct.dev = sc->sc_monitor_port; 2967 ct.type = AUDIO_MIXER_VALUE; 2968 ct.un.value.num_channels = 1; 2969 ct.un.value.level[AUDIO_MIXER_LEVEL_MONO] = ai->monitor_gain; 2970 error = sc->hw_if->set_port(sc->hw_hdl, &ct); 2971 if (error) 2972 return(error); 2973 } 2974 2975 if (ai->mode != ~0) { 2976 if (sc->sc_mode & AUMODE_PLAY) 2977 audio_init_play(sc); 2978 if (sc->sc_mode & AUMODE_RECORD) 2979 audio_init_record(sc); 2980 } 2981 2982 if (hw->commit_settings) { 2983 error = hw->commit_settings(sc->hw_hdl); 2984 if (error) 2985 return (error); 2986 } 2987 2988 if (cleared) { 2989 s = splaudio(); 2990 error = audio_initbufs(sc); 2991 if (error) goto err; 2992 if (sc->sc_pr.blksize != oldpblksize || 2993 sc->sc_rr.blksize != oldrblksize) 2994 audio_calcwater(sc); 2995 if ((sc->sc_mode & AUMODE_PLAY) && 2996 pbus && !sc->sc_pbus && !sc->sc_pr.pause) 2997 error = audiostartp(sc); 2998 if (!error && 2999 (sc->sc_mode & AUMODE_RECORD) && 3000 rbus && !sc->sc_rbus && !sc->sc_rr.pause) 3001 error = audiostartr(sc); 3002 err: 3003 splx(s); 3004 if (error) 3005 return error; 3006 } 3007 3008 /* Change water marks after initializing the buffers. */ 3009 if (ai->hiwat != ~0) { 3010 blks = ai->hiwat; 3011 if (blks > sc->sc_pr.maxblks) 3012 blks = sc->sc_pr.maxblks; 3013 if (blks < 2) 3014 blks = 2; 3015 sc->sc_pr.usedhigh = blks * sc->sc_pr.blksize; 3016 } 3017 if (ai->lowat != ~0) { 3018 blks = ai->lowat; 3019 if (blks > sc->sc_pr.maxblks - 1) 3020 blks = sc->sc_pr.maxblks - 1; 3021 sc->sc_pr.usedlow = blks * sc->sc_pr.blksize; 3022 } 3023 if (ai->hiwat != ~0 || ai->lowat != ~0) { 3024 if (sc->sc_pr.usedlow > sc->sc_pr.usedhigh - sc->sc_pr.blksize) 3025 sc->sc_pr.usedlow = sc->sc_pr.usedhigh - sc->sc_pr.blksize; 3026 } 3027 3028 if (p->pause != (u_char)~0) { 3029 sc->sc_pr.pause = p->pause; 3030 if (!p->pause && !sc->sc_pbus && (sc->sc_mode & AUMODE_PLAY)) { 3031 s = splaudio(); 3032 error = audiostartp(sc); 3033 splx(s); 3034 if (error) 3035 return error; 3036 } 3037 } 3038 if (r->pause != (u_char)~0) { 3039 sc->sc_rr.pause = r->pause; 3040 if (!r->pause && !sc->sc_rbus && (sc->sc_mode & AUMODE_RECORD)) { 3041 s = splaudio(); 3042 error = audiostartr(sc); 3043 splx(s); 3044 if (error) 3045 return error; 3046 } 3047 } 3048 3049 return (0); 3050 } 3051 3052 int 3053 audiogetinfo(struct audio_softc *sc, struct audio_info *ai) 3054 { 3055 struct audio_prinfo *r = &ai->record, *p = &ai->play; 3056 struct audio_hw_if *hw = sc->hw_if; 3057 3058 if (hw == 0) /* HW has not attached */ 3059 return(ENXIO); 3060 3061 p->sample_rate = sc->sc_pparams.sample_rate; 3062 r->sample_rate = sc->sc_rparams.sample_rate; 3063 p->channels = sc->sc_pparams.channels; 3064 r->channels = sc->sc_rparams.channels; 3065 p->precision = sc->sc_pparams.precision; 3066 r->precision = sc->sc_rparams.precision; 3067 p->bps = sc->sc_pparams.bps; 3068 r->bps = sc->sc_rparams.bps; 3069 p->msb = sc->sc_pparams.msb; 3070 r->msb = sc->sc_rparams.msb; 3071 p->encoding = sc->sc_pparams.encoding; 3072 r->encoding = sc->sc_rparams.encoding; 3073 3074 r->port = au_get_port(sc, &sc->sc_inports); 3075 p->port = au_get_port(sc, &sc->sc_outports); 3076 3077 r->avail_ports = sc->sc_inports.allports; 3078 p->avail_ports = sc->sc_outports.allports; 3079 3080 au_get_gain(sc, &sc->sc_inports, &r->gain, &r->balance); 3081 au_get_gain(sc, &sc->sc_outports, &p->gain, &p->balance); 3082 3083 if (sc->sc_monitor_port != -1) { 3084 mixer_ctrl_t ct; 3085 3086 ct.dev = sc->sc_monitor_port; 3087 ct.type = AUDIO_MIXER_VALUE; 3088 ct.un.value.num_channels = 1; 3089 if (sc->hw_if->get_port(sc->hw_hdl, &ct)) 3090 ai->monitor_gain = 0; 3091 else 3092 ai->monitor_gain = 3093 ct.un.value.level[AUDIO_MIXER_LEVEL_MONO]; 3094 } else 3095 ai->monitor_gain = 0; 3096 3097 au_get_mute(sc, &sc->sc_outports, &ai->output_muted); 3098 3099 p->seek = sc->sc_pr.used / sc->sc_pparams.factor; 3100 r->seek = sc->sc_rr.used / sc->sc_rparams.factor; 3101 3102 p->samples = sc->sc_pr.stamp - sc->sc_pr.drops; 3103 r->samples = sc->sc_rr.stamp - sc->sc_rr.drops; 3104 3105 p->eof = sc->sc_eof; 3106 r->eof = 0; 3107 3108 p->pause = sc->sc_pr.pause; 3109 r->pause = sc->sc_rr.pause; 3110 3111 p->error = sc->sc_pr.drops != 0; 3112 r->error = sc->sc_rr.drops != 0; 3113 3114 p->waiting = r->waiting = 0; /* open never hangs */ 3115 3116 p->open = (sc->sc_open & AUOPEN_WRITE) != 0; 3117 r->open = (sc->sc_open & AUOPEN_READ) != 0; 3118 3119 p->active = sc->sc_pbus; 3120 r->active = sc->sc_rbus; 3121 3122 p->buffer_size = sc->sc_pr.bufsize / sc->sc_pparams.factor; 3123 r->buffer_size = sc->sc_rr.bufsize / sc->sc_rparams.factor; 3124 3125 r->block_size = sc->sc_rr.blksize / sc->sc_rparams.factor; 3126 p->block_size = sc->sc_pr.blksize / sc->sc_pparams.factor; 3127 if (p->block_size != 0) { 3128 ai->hiwat = sc->sc_pr.usedhigh / sc->sc_pr.blksize; 3129 ai->lowat = sc->sc_pr.usedlow / sc->sc_pr.blksize; 3130 } else { 3131 ai->hiwat = ai->lowat = 0; 3132 } 3133 ai->blocksize = p->block_size; /* for compatibility, remove this */ 3134 ai->mode = sc->sc_mode; 3135 3136 return (0); 3137 } 3138 3139 int 3140 audiogetbufinfo(struct audio_softc *sc, struct audio_bufinfo *info, int mode) 3141 { 3142 struct audio_ringbuffer *buf; 3143 int factor; 3144 3145 factor = 1; 3146 if (mode == AUMODE_PLAY) { 3147 buf = &sc->sc_pr; 3148 factor = sc->sc_pparams.factor; 3149 } else { 3150 buf = &sc->sc_rr; 3151 factor = sc->sc_rparams.factor; 3152 } 3153 3154 info->seek = buf->used / factor; 3155 info->blksize = buf->blksize / factor; 3156 if (buf->blksize != 0) { 3157 info->hiwat = buf->usedhigh / buf->blksize; 3158 info->lowat = buf->usedlow / buf->blksize; 3159 } else { 3160 info->hiwat = 0; 3161 info->lowat = 0; 3162 } 3163 3164 return (0); 3165 } 3166 3167 3168 /* 3169 * Mixer driver 3170 */ 3171 int 3172 mixer_open(dev_t dev, struct audio_softc *sc, int flags, int ifmt, 3173 struct proc *p) 3174 { 3175 DPRINTF(("mixer_open: dev=0x%x flags=0x%x sc=%p\n", dev, flags, sc)); 3176 3177 return (0); 3178 } 3179 3180 /* 3181 * Remove a process from those to be signalled on mixer activity. 3182 */ 3183 static void 3184 mixer_remove(struct audio_softc *sc, struct proc *p) 3185 { 3186 struct mixer_asyncs **pm, *m; 3187 3188 for(pm = &sc->sc_async_mixer; *pm; pm = &(*pm)->next) { 3189 if ((*pm)->proc == p) { 3190 m = *pm; 3191 *pm = m->next; 3192 free(m, M_DEVBUF); 3193 return; 3194 } 3195 } 3196 } 3197 3198 /* 3199 * Signal all processes waiting for the mixer. 3200 */ 3201 static void 3202 mixer_signal(struct audio_softc *sc) 3203 { 3204 struct mixer_asyncs *m; 3205 3206 for(m = sc->sc_async_mixer; m; m = m->next) 3207 psignal(m->proc, SIGIO); 3208 } 3209 3210 /* 3211 * Close a mixer device 3212 */ 3213 /* ARGSUSED */ 3214 int 3215 mixer_close(dev_t dev, int flags, int ifmt, struct proc *p) 3216 { 3217 int unit = AUDIOUNIT(dev); 3218 struct audio_softc *sc = audio_cd.cd_devs[unit]; 3219 3220 DPRINTF(("mixer_close: unit %d\n", AUDIOUNIT(dev))); 3221 3222 mixer_remove(sc, p); 3223 3224 return (0); 3225 } 3226 3227 int 3228 mixer_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 3229 { 3230 int unit = AUDIOUNIT(dev); 3231 struct audio_softc *sc = audio_cd.cd_devs[unit]; 3232 struct audio_hw_if *hw = sc->hw_if; 3233 int error = EINVAL; 3234 3235 DPRINTF(("mixer_ioctl(%d,'%c',%d)\n", 3236 IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff)); 3237 3238 /* Block when fully quiesced. No need to block earlier. */ 3239 while (sc->sc_quiesce == AUDIO_QUIESCE_SILENT) 3240 tsleep(&sc->sc_quiesce, 0, "aud_qmi", 0); 3241 3242 switch (cmd) { 3243 case FIOASYNC: 3244 mixer_remove(sc, p); /* remove old entry */ 3245 if (*(int *)addr) { 3246 struct mixer_asyncs *ma; 3247 ma = malloc(sizeof (struct mixer_asyncs), 3248 M_DEVBUF, M_WAITOK); 3249 ma->next = sc->sc_async_mixer; 3250 ma->proc = p; 3251 sc->sc_async_mixer = ma; 3252 } 3253 error = 0; 3254 break; 3255 3256 case AUDIO_GETDEV: 3257 DPRINTF(("AUDIO_GETDEV\n")); 3258 error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr); 3259 break; 3260 3261 case AUDIO_MIXER_DEVINFO: 3262 DPRINTF(("AUDIO_MIXER_DEVINFO\n")); 3263 ((mixer_devinfo_t *)addr)->un.v.delta = 0; /* default */ 3264 error = hw->query_devinfo(sc->hw_hdl, (mixer_devinfo_t *)addr); 3265 break; 3266 3267 case AUDIO_MIXER_READ: 3268 DPRINTF(("AUDIO_MIXER_READ\n")); 3269 error = hw->get_port(sc->hw_hdl, (mixer_ctrl_t *)addr); 3270 break; 3271 3272 case AUDIO_MIXER_WRITE: 3273 if (!(flag & FWRITE)) 3274 return (EACCES); 3275 DPRINTF(("AUDIO_MIXER_WRITE\n")); 3276 error = hw->set_port(sc->hw_hdl, (mixer_ctrl_t *)addr); 3277 if (!error && hw->commit_settings) 3278 error = hw->commit_settings(sc->hw_hdl); 3279 if (!error) 3280 mixer_signal(sc); 3281 break; 3282 3283 default: 3284 error = ENOTTY; 3285 break; 3286 } 3287 DPRINTF(("mixer_ioctl(%d,'%c',%d) result %d\n", 3288 IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff, error)); 3289 return (error); 3290 } 3291 3292 int 3293 audiokqfilter(dev_t dev, struct knote *kn) 3294 { 3295 int unit = AUDIOUNIT(dev); 3296 struct audio_softc *sc = audio_cd.cd_devs[unit]; 3297 struct klist *klist; 3298 int s; 3299 3300 switch (kn->kn_filter) { 3301 case EVFILT_READ: 3302 klist = &sc->sc_rsel.si_note; 3303 kn->kn_fop = &audioread_filtops; 3304 break; 3305 case EVFILT_WRITE: 3306 klist = &sc->sc_wsel.si_note; 3307 kn->kn_fop = &audiowrite_filtops; 3308 break; 3309 default: 3310 return (EINVAL); 3311 } 3312 kn->kn_hook = (void *)sc; 3313 3314 s = splaudio(); 3315 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 3316 splx(s); 3317 3318 return (0); 3319 } 3320 3321 void 3322 filt_audiordetach(struct knote *kn) 3323 { 3324 struct audio_softc *sc = (struct audio_softc *)kn->kn_hook; 3325 int s = splaudio(); 3326 3327 SLIST_REMOVE(&sc->sc_rsel.si_note, kn, knote, kn_selnext); 3328 splx(s); 3329 } 3330 3331 int 3332 filt_audioread(struct knote *kn, long hint) 3333 { 3334 struct audio_softc *sc = (struct audio_softc *)kn->kn_hook; 3335 3336 return AUDIO_FILTREAD(sc); 3337 } 3338 3339 void 3340 filt_audiowdetach(struct knote *kn) 3341 { 3342 struct audio_softc *sc = (struct audio_softc *)kn->kn_hook; 3343 int s = splaudio(); 3344 3345 SLIST_REMOVE(&sc->sc_wsel.si_note, kn, knote, kn_selnext); 3346 splx(s); 3347 } 3348 3349 int 3350 filt_audiowrite(struct knote *kn, long hint) 3351 { 3352 struct audio_softc *sc = (struct audio_softc *)kn->kn_hook; 3353 3354 return AUDIO_FILTWRITE(sc); 3355 } 3356 3357 #if NWSKBD > 0 3358 int 3359 wskbd_set_mixervolume(long dir, int out) 3360 { 3361 struct audio_softc *sc; 3362 mixer_devinfo_t mi; 3363 int error; 3364 u_int gain; 3365 u_char balance, mute; 3366 struct au_mixer_ports *ports; 3367 3368 if (audio_cd.cd_ndevs == 0 || (sc = audio_cd.cd_devs[0]) == NULL) { 3369 DPRINTF(("wskbd_set_mixervolume: audio_cd\n")); 3370 return (ENXIO); 3371 } 3372 3373 ports = out ? &sc->sc_outports : &sc->sc_inports; 3374 3375 if (ports->master == -1) { 3376 DPRINTF(("wskbd_set_mixervolume: master == -1\n")); 3377 return (ENXIO); 3378 } 3379 3380 if (dir == 0) { 3381 /* Mute */ 3382 3383 error = au_get_mute(sc, ports, &mute); 3384 if (error != 0) { 3385 DPRINTF(("wskbd_set_mixervolume:" 3386 " au_get_mute: %d\n", error)); 3387 return (error); 3388 } 3389 3390 mute = !mute; 3391 3392 error = au_set_mute(sc, ports, mute); 3393 if (error != 0) { 3394 DPRINTF(("wskbd_set_mixervolume:" 3395 " au_set_mute: %d\n", error)); 3396 return (error); 3397 } 3398 } else { 3399 /* Raise or lower volume */ 3400 3401 mi.index = ports->master; 3402 error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi); 3403 if (error != 0) { 3404 DPRINTF(("wskbd_set_mixervolume:" 3405 " query_devinfo: %d\n", error)); 3406 return (error); 3407 } 3408 3409 au_get_gain(sc, ports, &gain, &balance); 3410 3411 if (dir > 0) 3412 gain += mi.un.v.delta; 3413 else 3414 gain -= mi.un.v.delta; 3415 3416 error = au_set_gain(sc, ports, gain, balance); 3417 if (error != 0) { 3418 DPRINTF(("wskbd_set_mixervolume:" 3419 " au_set_gain: %d\n", error)); 3420 return (error); 3421 } 3422 } 3423 3424 return (0); 3425 } 3426 #endif /* NWSKBD > 0 */ 3427