1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2005-2009 Ariff Abdullah <ariff@FreeBSD.org> 5 * Portions Copyright (c) Ryan Beasley <ryan.beasley@gmail.com> - GSoC 2006 6 * Copyright (c) 1999 Cameron Grant <cg@FreeBSD.org> 7 * Portions Copyright (c) Luigi Rizzo <luigi@FreeBSD.org> - 1997-99 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #ifdef HAVE_KERNEL_OPTION_HEADERS 33 #include "opt_snd.h" 34 #endif 35 36 #include <dev/sound/pcm/sound.h> 37 #include <dev/sound/pcm/vchan.h> 38 39 #include "feeder_if.h" 40 41 int report_soft_formats = 1; 42 SYSCTL_INT(_hw_snd, OID_AUTO, report_soft_formats, CTLFLAG_RW, 43 &report_soft_formats, 0, "report software-emulated formats"); 44 45 int report_soft_matrix = 1; 46 SYSCTL_INT(_hw_snd, OID_AUTO, report_soft_matrix, CTLFLAG_RW, 47 &report_soft_matrix, 0, "report software-emulated channel matrixing"); 48 49 int chn_latency = CHN_LATENCY_DEFAULT; 50 51 static int 52 sysctl_hw_snd_latency(SYSCTL_HANDLER_ARGS) 53 { 54 int err, val; 55 56 val = chn_latency; 57 err = sysctl_handle_int(oidp, &val, 0, req); 58 if (err != 0 || req->newptr == NULL) 59 return err; 60 if (val < CHN_LATENCY_MIN || val > CHN_LATENCY_MAX) 61 err = EINVAL; 62 else 63 chn_latency = val; 64 65 return err; 66 } 67 SYSCTL_PROC(_hw_snd, OID_AUTO, latency, 68 CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 0, sizeof(int), 69 sysctl_hw_snd_latency, "I", 70 "buffering latency (0=low ... 10=high)"); 71 72 int chn_latency_profile = CHN_LATENCY_PROFILE_DEFAULT; 73 74 static int 75 sysctl_hw_snd_latency_profile(SYSCTL_HANDLER_ARGS) 76 { 77 int err, val; 78 79 val = chn_latency_profile; 80 err = sysctl_handle_int(oidp, &val, 0, req); 81 if (err != 0 || req->newptr == NULL) 82 return err; 83 if (val < CHN_LATENCY_PROFILE_MIN || val > CHN_LATENCY_PROFILE_MAX) 84 err = EINVAL; 85 else 86 chn_latency_profile = val; 87 88 return err; 89 } 90 SYSCTL_PROC(_hw_snd, OID_AUTO, latency_profile, 91 CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 0, sizeof(int), 92 sysctl_hw_snd_latency_profile, "I", 93 "buffering latency profile (0=aggressive 1=safe)"); 94 95 static int chn_timeout = CHN_TIMEOUT; 96 97 static int 98 sysctl_hw_snd_timeout(SYSCTL_HANDLER_ARGS) 99 { 100 int err, val; 101 102 val = chn_timeout; 103 err = sysctl_handle_int(oidp, &val, 0, req); 104 if (err != 0 || req->newptr == NULL) 105 return err; 106 if (val < CHN_TIMEOUT_MIN || val > CHN_TIMEOUT_MAX) 107 err = EINVAL; 108 else 109 chn_timeout = val; 110 111 return err; 112 } 113 SYSCTL_PROC(_hw_snd, OID_AUTO, timeout, 114 CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 0, sizeof(int), 115 sysctl_hw_snd_timeout, "I", 116 "interrupt timeout (1 - 10) seconds"); 117 118 static int chn_vpc_autoreset = 1; 119 SYSCTL_INT(_hw_snd, OID_AUTO, vpc_autoreset, CTLFLAG_RWTUN, 120 &chn_vpc_autoreset, 0, "automatically reset channels volume to 0db"); 121 122 static int chn_vol_0db_pcm = SND_VOL_0DB_PCM; 123 124 static void 125 chn_vpc_proc(int reset, int db) 126 { 127 struct snddev_info *d; 128 struct pcm_channel *c; 129 int i; 130 131 for (i = 0; pcm_devclass != NULL && 132 i < devclass_get_maxunit(pcm_devclass); i++) { 133 d = devclass_get_softc(pcm_devclass, i); 134 if (!PCM_REGISTERED(d)) 135 continue; 136 PCM_LOCK(d); 137 PCM_WAIT(d); 138 PCM_ACQUIRE(d); 139 CHN_FOREACH(c, d, channels.pcm) { 140 CHN_LOCK(c); 141 CHN_SETVOLUME(c, SND_VOL_C_PCM, SND_CHN_T_VOL_0DB, db); 142 if (reset != 0) 143 chn_vpc_reset(c, SND_VOL_C_PCM, 1); 144 CHN_UNLOCK(c); 145 } 146 PCM_RELEASE(d); 147 PCM_UNLOCK(d); 148 } 149 } 150 151 static int 152 sysctl_hw_snd_vpc_0db(SYSCTL_HANDLER_ARGS) 153 { 154 int err, val; 155 156 val = chn_vol_0db_pcm; 157 err = sysctl_handle_int(oidp, &val, 0, req); 158 if (err != 0 || req->newptr == NULL) 159 return (err); 160 if (val < SND_VOL_0DB_MIN || val > SND_VOL_0DB_MAX) 161 return (EINVAL); 162 163 chn_vol_0db_pcm = val; 164 chn_vpc_proc(0, val); 165 166 return (0); 167 } 168 SYSCTL_PROC(_hw_snd, OID_AUTO, vpc_0db, 169 CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, 0, sizeof(int), 170 sysctl_hw_snd_vpc_0db, "I", 171 "0db relative level"); 172 173 static int 174 sysctl_hw_snd_vpc_reset(SYSCTL_HANDLER_ARGS) 175 { 176 int err, val; 177 178 val = 0; 179 err = sysctl_handle_int(oidp, &val, 0, req); 180 if (err != 0 || req->newptr == NULL || val == 0) 181 return (err); 182 183 chn_vol_0db_pcm = SND_VOL_0DB_PCM; 184 chn_vpc_proc(1, SND_VOL_0DB_PCM); 185 186 return (0); 187 } 188 SYSCTL_PROC(_hw_snd, OID_AUTO, vpc_reset, 189 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 0, sizeof(int), 190 sysctl_hw_snd_vpc_reset, "I", 191 "reset volume on all channels"); 192 193 static int chn_usefrags = 0; 194 static int chn_syncdelay = -1; 195 196 SYSCTL_INT(_hw_snd, OID_AUTO, usefrags, CTLFLAG_RWTUN, 197 &chn_usefrags, 0, "prefer setfragments() over setblocksize()"); 198 SYSCTL_INT(_hw_snd, OID_AUTO, syncdelay, CTLFLAG_RWTUN, 199 &chn_syncdelay, 0, 200 "append (0-1000) millisecond trailing buffer delay on each sync"); 201 202 /** 203 * @brief Channel sync group lock 204 * 205 * Clients should acquire this lock @b without holding any channel locks 206 * before touching syncgroups or the main syncgroup list. 207 */ 208 struct mtx snd_pcm_syncgroups_mtx; 209 MTX_SYSINIT(pcm_syncgroup, &snd_pcm_syncgroups_mtx, "PCM channel sync group lock", MTX_DEF); 210 /** 211 * @brief syncgroups' master list 212 * 213 * Each time a channel syncgroup is created, it's added to this list. This 214 * list should only be accessed with @sa snd_pcm_syncgroups_mtx held. 215 * 216 * See SNDCTL_DSP_SYNCGROUP for more information. 217 */ 218 struct pcm_synclist snd_pcm_syncgroups = SLIST_HEAD_INITIALIZER(snd_pcm_syncgroups); 219 220 static void 221 chn_lockinit(struct pcm_channel *c, int dir) 222 { 223 switch (dir) { 224 case PCMDIR_PLAY: 225 c->lock = snd_mtxcreate(c->name, "pcm play channel"); 226 cv_init(&c->intr_cv, "pcmwr"); 227 break; 228 case PCMDIR_PLAY_VIRTUAL: 229 c->lock = snd_mtxcreate(c->name, "pcm virtual play channel"); 230 cv_init(&c->intr_cv, "pcmwrv"); 231 break; 232 case PCMDIR_REC: 233 c->lock = snd_mtxcreate(c->name, "pcm record channel"); 234 cv_init(&c->intr_cv, "pcmrd"); 235 break; 236 case PCMDIR_REC_VIRTUAL: 237 c->lock = snd_mtxcreate(c->name, "pcm virtual record channel"); 238 cv_init(&c->intr_cv, "pcmrdv"); 239 break; 240 default: 241 panic("%s(): Invalid direction=%d", __func__, dir); 242 break; 243 } 244 245 cv_init(&c->cv, "pcmchn"); 246 } 247 248 static void 249 chn_lockdestroy(struct pcm_channel *c) 250 { 251 CHN_LOCKASSERT(c); 252 253 CHN_BROADCAST(&c->cv); 254 CHN_BROADCAST(&c->intr_cv); 255 256 cv_destroy(&c->cv); 257 cv_destroy(&c->intr_cv); 258 259 snd_mtxfree(c->lock); 260 } 261 262 /** 263 * @brief Determine channel is ready for I/O 264 * 265 * @retval 1 = ready for I/O 266 * @retval 0 = not ready for I/O 267 */ 268 static int 269 chn_polltrigger(struct pcm_channel *c) 270 { 271 struct snd_dbuf *bs = c->bufsoft; 272 u_int delta; 273 274 CHN_LOCKASSERT(c); 275 276 if (c->flags & CHN_F_MMAP) { 277 if (sndbuf_getprevtotal(bs) < c->lw) 278 delta = c->lw; 279 else 280 delta = sndbuf_gettotal(bs) - sndbuf_getprevtotal(bs); 281 } else { 282 if (c->direction == PCMDIR_PLAY) 283 delta = sndbuf_getfree(bs); 284 else 285 delta = sndbuf_getready(bs); 286 } 287 288 return ((delta < c->lw) ? 0 : 1); 289 } 290 291 static void 292 chn_pollreset(struct pcm_channel *c) 293 { 294 295 CHN_LOCKASSERT(c); 296 sndbuf_updateprevtotal(c->bufsoft); 297 } 298 299 static void 300 chn_wakeup(struct pcm_channel *c) 301 { 302 struct snd_dbuf *bs; 303 struct pcm_channel *ch; 304 305 CHN_LOCKASSERT(c); 306 307 bs = c->bufsoft; 308 309 if (CHN_EMPTY(c, children.busy)) { 310 if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c)) 311 selwakeuppri(sndbuf_getsel(bs), PRIBIO); 312 if (c->flags & CHN_F_SLEEPING) { 313 /* 314 * Ok, I can just panic it right here since it is 315 * quite obvious that we never allow multiple waiters 316 * from userland. I'm too generous... 317 */ 318 CHN_BROADCAST(&c->intr_cv); 319 } 320 } else { 321 CHN_FOREACH(ch, c, children.busy) { 322 CHN_LOCK(ch); 323 chn_wakeup(ch); 324 CHN_UNLOCK(ch); 325 } 326 } 327 } 328 329 static int 330 chn_sleep(struct pcm_channel *c, int timeout) 331 { 332 int ret; 333 334 CHN_LOCKASSERT(c); 335 336 if (c->flags & CHN_F_DEAD) 337 return (EINVAL); 338 339 c->flags |= CHN_F_SLEEPING; 340 ret = cv_timedwait_sig(&c->intr_cv, c->lock, timeout); 341 c->flags &= ~CHN_F_SLEEPING; 342 343 return ((c->flags & CHN_F_DEAD) ? EINVAL : ret); 344 } 345 346 /* 347 * chn_dmaupdate() tracks the status of a dma transfer, 348 * updating pointers. 349 */ 350 351 static unsigned int 352 chn_dmaupdate(struct pcm_channel *c) 353 { 354 struct snd_dbuf *b = c->bufhard; 355 unsigned int delta, old, hwptr, amt; 356 357 KASSERT(sndbuf_getsize(b) > 0, ("bufsize == 0")); 358 CHN_LOCKASSERT(c); 359 360 old = sndbuf_gethwptr(b); 361 hwptr = chn_getptr(c); 362 delta = (sndbuf_getsize(b) + hwptr - old) % sndbuf_getsize(b); 363 sndbuf_sethwptr(b, hwptr); 364 365 if (c->direction == PCMDIR_PLAY) { 366 amt = min(delta, sndbuf_getready(b)); 367 amt -= amt % sndbuf_getalign(b); 368 if (amt > 0) 369 sndbuf_dispose(b, NULL, amt); 370 } else { 371 amt = min(delta, sndbuf_getfree(b)); 372 amt -= amt % sndbuf_getalign(b); 373 if (amt > 0) 374 sndbuf_acquire(b, NULL, amt); 375 } 376 if (snd_verbose > 3 && CHN_STARTED(c) && delta == 0) { 377 device_printf(c->dev, "WARNING: %s DMA completion " 378 "too fast/slow ! hwptr=%u, old=%u " 379 "delta=%u amt=%u ready=%u free=%u\n", 380 CHN_DIRSTR(c), hwptr, old, delta, amt, 381 sndbuf_getready(b), sndbuf_getfree(b)); 382 } 383 384 return delta; 385 } 386 387 static void 388 chn_wrfeed(struct pcm_channel *c) 389 { 390 struct snd_dbuf *b = c->bufhard; 391 struct snd_dbuf *bs = c->bufsoft; 392 unsigned int amt, want, wasfree; 393 394 CHN_LOCKASSERT(c); 395 396 if ((c->flags & CHN_F_MMAP) && !(c->flags & CHN_F_CLOSING)) 397 sndbuf_acquire(bs, NULL, sndbuf_getfree(bs)); 398 399 wasfree = sndbuf_getfree(b); 400 want = min(sndbuf_getsize(b), 401 imax(0, sndbuf_xbytes(sndbuf_getsize(bs), bs, b) - 402 sndbuf_getready(b))); 403 amt = min(wasfree, want); 404 if (amt > 0) 405 sndbuf_feed(bs, b, c, c->feeder, amt); 406 407 /* 408 * Possible xruns. There should be no empty space left in buffer. 409 */ 410 if (sndbuf_getready(b) < want) 411 c->xruns++; 412 413 if (sndbuf_getfree(b) < wasfree) 414 chn_wakeup(c); 415 } 416 417 #if 0 418 static void 419 chn_wrupdate(struct pcm_channel *c) 420 { 421 422 CHN_LOCKASSERT(c); 423 KASSERT(c->direction == PCMDIR_PLAY, ("%s(): bad channel", __func__)); 424 425 if ((c->flags & (CHN_F_MMAP | CHN_F_VIRTUAL)) || CHN_STOPPED(c)) 426 return; 427 chn_dmaupdate(c); 428 chn_wrfeed(c); 429 /* tell the driver we've updated the primary buffer */ 430 chn_trigger(c, PCMTRIG_EMLDMAWR); 431 } 432 #endif 433 434 static void 435 chn_wrintr(struct pcm_channel *c) 436 { 437 438 CHN_LOCKASSERT(c); 439 /* update pointers in primary buffer */ 440 chn_dmaupdate(c); 441 /* ...and feed from secondary to primary */ 442 chn_wrfeed(c); 443 /* tell the driver we've updated the primary buffer */ 444 chn_trigger(c, PCMTRIG_EMLDMAWR); 445 } 446 447 /* 448 * user write routine - uiomove data into secondary buffer, trigger if necessary 449 * if blocking, sleep, rinse and repeat. 450 * 451 * called externally, so must handle locking 452 */ 453 454 int 455 chn_write(struct pcm_channel *c, struct uio *buf) 456 { 457 struct snd_dbuf *bs = c->bufsoft; 458 void *off; 459 int ret, timeout, sz, t, p; 460 461 CHN_LOCKASSERT(c); 462 463 ret = 0; 464 timeout = chn_timeout * hz; 465 466 while (ret == 0 && buf->uio_resid > 0) { 467 sz = min(buf->uio_resid, sndbuf_getfree(bs)); 468 if (sz > 0) { 469 /* 470 * The following assumes that the free space in 471 * the buffer can never be less around the 472 * unlock-uiomove-lock sequence. 473 */ 474 while (ret == 0 && sz > 0) { 475 p = sndbuf_getfreeptr(bs); 476 t = min(sz, sndbuf_getsize(bs) - p); 477 off = sndbuf_getbufofs(bs, p); 478 CHN_UNLOCK(c); 479 ret = uiomove(off, t, buf); 480 CHN_LOCK(c); 481 sz -= t; 482 sndbuf_acquire(bs, NULL, t); 483 } 484 ret = 0; 485 if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) { 486 ret = chn_start(c, 0); 487 if (ret != 0) 488 c->flags |= CHN_F_DEAD; 489 } 490 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) { 491 /** 492 * @todo Evaluate whether EAGAIN is truly desirable. 493 * 4Front drivers behave like this, but I'm 494 * not sure if it at all violates the "write 495 * should be allowed to block" model. 496 * 497 * The idea is that, while set with CHN_F_NOTRIGGER, 498 * a channel isn't playing, *but* without this we 499 * end up with "interrupt timeout / channel dead". 500 */ 501 ret = EAGAIN; 502 } else { 503 ret = chn_sleep(c, timeout); 504 if (ret == EAGAIN) { 505 ret = EINVAL; 506 c->flags |= CHN_F_DEAD; 507 device_printf(c->dev, "%s(): %s: " 508 "play interrupt timeout, channel dead\n", 509 __func__, c->name); 510 } else if (ret == ERESTART || ret == EINTR) 511 c->flags |= CHN_F_ABORTING; 512 } 513 } 514 515 return (ret); 516 } 517 518 /* 519 * Feed new data from the read buffer. Can be called in the bottom half. 520 */ 521 static void 522 chn_rdfeed(struct pcm_channel *c) 523 { 524 struct snd_dbuf *b = c->bufhard; 525 struct snd_dbuf *bs = c->bufsoft; 526 unsigned int amt; 527 528 CHN_LOCKASSERT(c); 529 530 if (c->flags & CHN_F_MMAP) 531 sndbuf_dispose(bs, NULL, sndbuf_getready(bs)); 532 533 amt = sndbuf_getfree(bs); 534 if (amt > 0) 535 sndbuf_feed(b, bs, c, c->feeder, amt); 536 537 amt = sndbuf_getready(b); 538 if (amt > 0) { 539 c->xruns++; 540 sndbuf_dispose(b, NULL, amt); 541 } 542 543 if (sndbuf_getready(bs) > 0) 544 chn_wakeup(c); 545 } 546 547 #if 0 548 static void 549 chn_rdupdate(struct pcm_channel *c) 550 { 551 552 CHN_LOCKASSERT(c); 553 KASSERT(c->direction == PCMDIR_REC, ("chn_rdupdate on bad channel")); 554 555 if ((c->flags & (CHN_F_MMAP | CHN_F_VIRTUAL)) || CHN_STOPPED(c)) 556 return; 557 chn_trigger(c, PCMTRIG_EMLDMARD); 558 chn_dmaupdate(c); 559 chn_rdfeed(c); 560 } 561 #endif 562 563 /* read interrupt routine. Must be called with interrupts blocked. */ 564 static void 565 chn_rdintr(struct pcm_channel *c) 566 { 567 568 CHN_LOCKASSERT(c); 569 /* tell the driver to update the primary buffer if non-dma */ 570 chn_trigger(c, PCMTRIG_EMLDMARD); 571 /* update pointers in primary buffer */ 572 chn_dmaupdate(c); 573 /* ...and feed from primary to secondary */ 574 chn_rdfeed(c); 575 } 576 577 /* 578 * user read routine - trigger if necessary, uiomove data from secondary buffer 579 * if blocking, sleep, rinse and repeat. 580 * 581 * called externally, so must handle locking 582 */ 583 584 int 585 chn_read(struct pcm_channel *c, struct uio *buf) 586 { 587 struct snd_dbuf *bs = c->bufsoft; 588 void *off; 589 int ret, timeout, sz, t, p; 590 591 CHN_LOCKASSERT(c); 592 593 if (CHN_STOPPED(c) && !(c->flags & CHN_F_NOTRIGGER)) { 594 ret = chn_start(c, 0); 595 if (ret != 0) { 596 c->flags |= CHN_F_DEAD; 597 return (ret); 598 } 599 } 600 601 ret = 0; 602 timeout = chn_timeout * hz; 603 604 while (ret == 0 && buf->uio_resid > 0) { 605 sz = min(buf->uio_resid, sndbuf_getready(bs)); 606 if (sz > 0) { 607 /* 608 * The following assumes that the free space in 609 * the buffer can never be less around the 610 * unlock-uiomove-lock sequence. 611 */ 612 while (ret == 0 && sz > 0) { 613 p = sndbuf_getreadyptr(bs); 614 t = min(sz, sndbuf_getsize(bs) - p); 615 off = sndbuf_getbufofs(bs, p); 616 CHN_UNLOCK(c); 617 ret = uiomove(off, t, buf); 618 CHN_LOCK(c); 619 sz -= t; 620 sndbuf_dispose(bs, NULL, t); 621 } 622 ret = 0; 623 } else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) 624 ret = EAGAIN; 625 else { 626 ret = chn_sleep(c, timeout); 627 if (ret == EAGAIN) { 628 ret = EINVAL; 629 c->flags |= CHN_F_DEAD; 630 device_printf(c->dev, "%s(): %s: " 631 "record interrupt timeout, channel dead\n", 632 __func__, c->name); 633 } else if (ret == ERESTART || ret == EINTR) 634 c->flags |= CHN_F_ABORTING; 635 } 636 } 637 638 return (ret); 639 } 640 641 void 642 chn_intr_locked(struct pcm_channel *c) 643 { 644 645 CHN_LOCKASSERT(c); 646 647 c->interrupts++; 648 649 if (c->direction == PCMDIR_PLAY) 650 chn_wrintr(c); 651 else 652 chn_rdintr(c); 653 } 654 655 void 656 chn_intr(struct pcm_channel *c) 657 { 658 659 if (CHN_LOCKOWNED(c)) { 660 chn_intr_locked(c); 661 return; 662 } 663 664 CHN_LOCK(c); 665 chn_intr_locked(c); 666 CHN_UNLOCK(c); 667 } 668 669 u_int32_t 670 chn_start(struct pcm_channel *c, int force) 671 { 672 u_int32_t i, j; 673 struct snd_dbuf *b = c->bufhard; 674 struct snd_dbuf *bs = c->bufsoft; 675 int err; 676 677 CHN_LOCKASSERT(c); 678 /* if we're running, or if we're prevented from triggering, bail */ 679 if (CHN_STARTED(c) || ((c->flags & CHN_F_NOTRIGGER) && !force)) 680 return (EINVAL); 681 682 err = 0; 683 684 if (force) { 685 i = 1; 686 j = 0; 687 } else { 688 if (c->direction == PCMDIR_REC) { 689 i = sndbuf_getfree(bs); 690 j = (i > 0) ? 1 : sndbuf_getready(b); 691 } else { 692 if (sndbuf_getfree(bs) == 0) { 693 i = 1; 694 j = 0; 695 } else { 696 struct snd_dbuf *pb; 697 698 pb = CHN_BUF_PARENT(c, b); 699 i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb); 700 j = sndbuf_getalign(pb); 701 } 702 } 703 if (snd_verbose > 3 && CHN_EMPTY(c, children)) 704 device_printf(c->dev, "%s(): %s (%s) threshold " 705 "i=%d j=%d\n", __func__, CHN_DIRSTR(c), 706 (c->flags & CHN_F_VIRTUAL) ? "virtual" : 707 "hardware", i, j); 708 } 709 710 if (i >= j) { 711 c->flags |= CHN_F_TRIGGERED; 712 sndbuf_setrun(b, 1); 713 if (c->flags & CHN_F_CLOSING) 714 c->feedcount = 2; 715 else { 716 c->feedcount = 0; 717 c->interrupts = 0; 718 c->xruns = 0; 719 } 720 if (c->parentchannel == NULL) { 721 if (c->direction == PCMDIR_PLAY) 722 sndbuf_fillsilence_rl(b, 723 sndbuf_xbytes(sndbuf_getsize(bs), bs, b)); 724 if (snd_verbose > 3) 725 device_printf(c->dev, 726 "%s(): %s starting! (%s/%s) " 727 "(ready=%d force=%d i=%d j=%d " 728 "intrtimeout=%u latency=%dms)\n", 729 __func__, 730 (c->flags & CHN_F_HAS_VCHAN) ? 731 "VCHAN PARENT" : "HW", CHN_DIRSTR(c), 732 (c->flags & CHN_F_CLOSING) ? "closing" : 733 "running", 734 sndbuf_getready(b), 735 force, i, j, c->timeout, 736 (sndbuf_getsize(b) * 1000) / 737 (sndbuf_getalign(b) * sndbuf_getspd(b))); 738 } 739 err = chn_trigger(c, PCMTRIG_START); 740 } 741 742 return (err); 743 } 744 745 void 746 chn_resetbuf(struct pcm_channel *c) 747 { 748 struct snd_dbuf *b = c->bufhard; 749 struct snd_dbuf *bs = c->bufsoft; 750 751 c->blocks = 0; 752 sndbuf_reset(b); 753 sndbuf_reset(bs); 754 } 755 756 /* 757 * chn_sync waits until the space in the given channel goes above 758 * a threshold. The threshold is checked against fl or rl respectively. 759 * Assume that the condition can become true, do not check here... 760 */ 761 int 762 chn_sync(struct pcm_channel *c, int threshold) 763 { 764 struct snd_dbuf *b, *bs; 765 int ret, count, hcount, minflush, resid, residp, syncdelay, blksz; 766 u_int32_t cflag; 767 768 CHN_LOCKASSERT(c); 769 770 if (c->direction != PCMDIR_PLAY) 771 return (EINVAL); 772 773 bs = c->bufsoft; 774 775 if ((c->flags & (CHN_F_DEAD | CHN_F_ABORTING)) || 776 (threshold < 1 && sndbuf_getready(bs) < 1)) 777 return (0); 778 779 /* if we haven't yet started and nothing is buffered, else start*/ 780 if (CHN_STOPPED(c)) { 781 if (threshold > 0 || sndbuf_getready(bs) > 0) { 782 ret = chn_start(c, 1); 783 if (ret != 0) 784 return (ret); 785 } else 786 return (0); 787 } 788 789 b = CHN_BUF_PARENT(c, c->bufhard); 790 791 minflush = threshold + sndbuf_xbytes(sndbuf_getready(b), b, bs); 792 793 syncdelay = chn_syncdelay; 794 795 if (syncdelay < 0 && (threshold > 0 || sndbuf_getready(bs) > 0)) 796 minflush += sndbuf_xbytes(sndbuf_getsize(b), b, bs); 797 798 /* 799 * Append (0-1000) millisecond trailing buffer (if needed) 800 * for slower / high latency hardwares (notably USB audio) 801 * to avoid audible truncation. 802 */ 803 if (syncdelay > 0) 804 minflush += (sndbuf_getalign(bs) * sndbuf_getspd(bs) * 805 ((syncdelay > 1000) ? 1000 : syncdelay)) / 1000; 806 807 minflush -= minflush % sndbuf_getalign(bs); 808 809 if (minflush > 0) { 810 threshold = min(minflush, sndbuf_getfree(bs)); 811 sndbuf_clear(bs, threshold); 812 sndbuf_acquire(bs, NULL, threshold); 813 minflush -= threshold; 814 } 815 816 resid = sndbuf_getready(bs); 817 residp = resid; 818 blksz = sndbuf_getblksz(b); 819 if (blksz < 1) { 820 device_printf(c->dev, 821 "%s(): WARNING: blksz < 1 ! maxsize=%d [%d/%d/%d]\n", 822 __func__, sndbuf_getmaxsize(b), sndbuf_getsize(b), 823 sndbuf_getblksz(b), sndbuf_getblkcnt(b)); 824 if (sndbuf_getblkcnt(b) > 0) 825 blksz = sndbuf_getsize(b) / sndbuf_getblkcnt(b); 826 if (blksz < 1) 827 blksz = 1; 828 } 829 count = sndbuf_xbytes(minflush + resid, bs, b) / blksz; 830 hcount = count; 831 ret = 0; 832 833 if (snd_verbose > 3) 834 device_printf(c->dev, "%s(): [begin] timeout=%d count=%d " 835 "minflush=%d resid=%d\n", __func__, c->timeout, count, 836 minflush, resid); 837 838 cflag = c->flags & CHN_F_CLOSING; 839 c->flags |= CHN_F_CLOSING; 840 while (count > 0 && (resid > 0 || minflush > 0)) { 841 ret = chn_sleep(c, c->timeout); 842 if (ret == ERESTART || ret == EINTR) { 843 c->flags |= CHN_F_ABORTING; 844 break; 845 } else if (ret == 0 || ret == EAGAIN) { 846 resid = sndbuf_getready(bs); 847 if (resid == residp) { 848 --count; 849 if (snd_verbose > 3) 850 device_printf(c->dev, 851 "%s(): [stalled] timeout=%d " 852 "count=%d hcount=%d " 853 "resid=%d minflush=%d\n", 854 __func__, c->timeout, count, 855 hcount, resid, minflush); 856 } else if (resid < residp && count < hcount) { 857 ++count; 858 if (snd_verbose > 3) 859 device_printf(c->dev, 860 "%s((): [resume] timeout=%d " 861 "count=%d hcount=%d " 862 "resid=%d minflush=%d\n", 863 __func__, c->timeout, count, 864 hcount, resid, minflush); 865 } 866 if (minflush > 0 && sndbuf_getfree(bs) > 0) { 867 threshold = min(minflush, 868 sndbuf_getfree(bs)); 869 sndbuf_clear(bs, threshold); 870 sndbuf_acquire(bs, NULL, threshold); 871 resid = sndbuf_getready(bs); 872 minflush -= threshold; 873 } 874 residp = resid; 875 } else 876 break; 877 } 878 c->flags &= ~CHN_F_CLOSING; 879 c->flags |= cflag; 880 881 if (snd_verbose > 3) 882 device_printf(c->dev, 883 "%s(): timeout=%d count=%d hcount=%d resid=%d residp=%d " 884 "minflush=%d ret=%d\n", 885 __func__, c->timeout, count, hcount, resid, residp, 886 minflush, ret); 887 888 return (0); 889 } 890 891 /* called externally, handle locking */ 892 int 893 chn_poll(struct pcm_channel *c, int ev, struct thread *td) 894 { 895 struct snd_dbuf *bs = c->bufsoft; 896 int ret; 897 898 CHN_LOCKASSERT(c); 899 900 if (!(c->flags & (CHN_F_MMAP | CHN_F_TRIGGERED))) { 901 ret = chn_start(c, 1); 902 if (ret != 0) 903 return (0); 904 } 905 906 ret = 0; 907 if (chn_polltrigger(c)) { 908 chn_pollreset(c); 909 ret = ev; 910 } else 911 selrecord(td, sndbuf_getsel(bs)); 912 913 return (ret); 914 } 915 916 /* 917 * chn_abort terminates a running dma transfer. it may sleep up to 200ms. 918 * it returns the number of bytes that have not been transferred. 919 * 920 * called from: dsp_close, dsp_ioctl, with channel locked 921 */ 922 int 923 chn_abort(struct pcm_channel *c) 924 { 925 int missing = 0; 926 struct snd_dbuf *b = c->bufhard; 927 struct snd_dbuf *bs = c->bufsoft; 928 929 CHN_LOCKASSERT(c); 930 if (CHN_STOPPED(c)) 931 return 0; 932 c->flags |= CHN_F_ABORTING; 933 934 c->flags &= ~CHN_F_TRIGGERED; 935 /* kill the channel */ 936 chn_trigger(c, PCMTRIG_ABORT); 937 sndbuf_setrun(b, 0); 938 if (!(c->flags & CHN_F_VIRTUAL)) 939 chn_dmaupdate(c); 940 missing = sndbuf_getready(bs); 941 942 c->flags &= ~CHN_F_ABORTING; 943 return missing; 944 } 945 946 /* 947 * this routine tries to flush the dma transfer. It is called 948 * on a close of a playback channel. 949 * first, if there is data in the buffer, but the dma has not yet 950 * begun, we need to start it. 951 * next, we wait for the play buffer to drain 952 * finally, we stop the dma. 953 * 954 * called from: dsp_close, not valid for record channels. 955 */ 956 957 int 958 chn_flush(struct pcm_channel *c) 959 { 960 struct snd_dbuf *b = c->bufhard; 961 962 CHN_LOCKASSERT(c); 963 KASSERT(c->direction == PCMDIR_PLAY, ("chn_flush on bad channel")); 964 DEB(printf("chn_flush: c->flags 0x%08x\n", c->flags)); 965 966 c->flags |= CHN_F_CLOSING; 967 chn_sync(c, 0); 968 c->flags &= ~CHN_F_TRIGGERED; 969 /* kill the channel */ 970 chn_trigger(c, PCMTRIG_ABORT); 971 sndbuf_setrun(b, 0); 972 973 c->flags &= ~CHN_F_CLOSING; 974 return 0; 975 } 976 977 int 978 snd_fmtvalid(uint32_t fmt, uint32_t *fmtlist) 979 { 980 int i; 981 982 for (i = 0; fmtlist[i] != 0; i++) { 983 if (fmt == fmtlist[i] || 984 ((fmt & AFMT_PASSTHROUGH) && 985 (AFMT_ENCODING(fmt) & fmtlist[i]))) 986 return (1); 987 } 988 989 return (0); 990 } 991 992 static const struct { 993 char *name, *alias1, *alias2; 994 uint32_t afmt; 995 } afmt_tab[] = { 996 { "alaw", NULL, NULL, AFMT_A_LAW }, 997 { "mulaw", NULL, NULL, AFMT_MU_LAW }, 998 { "u8", "8", NULL, AFMT_U8 }, 999 { "s8", NULL, NULL, AFMT_S8 }, 1000 #if BYTE_ORDER == LITTLE_ENDIAN 1001 { "s16le", "s16", "16", AFMT_S16_LE }, 1002 { "s16be", NULL, NULL, AFMT_S16_BE }, 1003 #else 1004 { "s16le", NULL, NULL, AFMT_S16_LE }, 1005 { "s16be", "s16", "16", AFMT_S16_BE }, 1006 #endif 1007 { "u16le", NULL, NULL, AFMT_U16_LE }, 1008 { "u16be", NULL, NULL, AFMT_U16_BE }, 1009 { "s24le", NULL, NULL, AFMT_S24_LE }, 1010 { "s24be", NULL, NULL, AFMT_S24_BE }, 1011 { "u24le", NULL, NULL, AFMT_U24_LE }, 1012 { "u24be", NULL, NULL, AFMT_U24_BE }, 1013 #if BYTE_ORDER == LITTLE_ENDIAN 1014 { "s32le", "s32", "32", AFMT_S32_LE }, 1015 { "s32be", NULL, NULL, AFMT_S32_BE }, 1016 #else 1017 { "s32le", NULL, NULL, AFMT_S32_LE }, 1018 { "s32be", "s32", "32", AFMT_S32_BE }, 1019 #endif 1020 { "u32le", NULL, NULL, AFMT_U32_LE }, 1021 { "u32be", NULL, NULL, AFMT_U32_BE }, 1022 { "ac3", NULL, NULL, AFMT_AC3 }, 1023 { NULL, NULL, NULL, 0 } 1024 }; 1025 1026 uint32_t 1027 snd_str2afmt(const char *req) 1028 { 1029 int ext; 1030 int ch; 1031 int i; 1032 char b1[8]; 1033 char b2[8]; 1034 1035 memset(b1, 0, sizeof(b1)); 1036 memset(b2, 0, sizeof(b2)); 1037 1038 i = sscanf(req, "%5[^:]:%6s", b1, b2); 1039 1040 if (i == 1) { 1041 if (strlen(req) != strlen(b1)) 1042 return (0); 1043 strlcpy(b2, "2.0", sizeof(b2)); 1044 } else if (i == 2) { 1045 if (strlen(req) != (strlen(b1) + 1 + strlen(b2))) 1046 return (0); 1047 } else 1048 return (0); 1049 1050 i = sscanf(b2, "%d.%d", &ch, &ext); 1051 1052 if (i == 0) { 1053 if (strcasecmp(b2, "mono") == 0) { 1054 ch = 1; 1055 ext = 0; 1056 } else if (strcasecmp(b2, "stereo") == 0) { 1057 ch = 2; 1058 ext = 0; 1059 } else if (strcasecmp(b2, "quad") == 0) { 1060 ch = 4; 1061 ext = 0; 1062 } else 1063 return (0); 1064 } else if (i == 1) { 1065 if (ch < 1 || ch > AFMT_CHANNEL_MAX) 1066 return (0); 1067 ext = 0; 1068 } else if (i == 2) { 1069 if (ext < 0 || ext > AFMT_EXTCHANNEL_MAX) 1070 return (0); 1071 if (ch < 1 || (ch + ext) > AFMT_CHANNEL_MAX) 1072 return (0); 1073 } else 1074 return (0); 1075 1076 for (i = 0; afmt_tab[i].name != NULL; i++) { 1077 if (strcasecmp(afmt_tab[i].name, b1) != 0) { 1078 if (afmt_tab[i].alias1 == NULL) 1079 continue; 1080 if (strcasecmp(afmt_tab[i].alias1, b1) != 0) { 1081 if (afmt_tab[i].alias2 == NULL) 1082 continue; 1083 if (strcasecmp(afmt_tab[i].alias2, b1) != 0) 1084 continue; 1085 } 1086 } 1087 /* found a match */ 1088 return (SND_FORMAT(afmt_tab[i].afmt, ch + ext, ext)); 1089 } 1090 /* not a valid format */ 1091 return (0); 1092 } 1093 1094 uint32_t 1095 snd_afmt2str(uint32_t afmt, char *buf, size_t len) 1096 { 1097 uint32_t enc; 1098 uint32_t ext; 1099 uint32_t ch; 1100 int i; 1101 1102 if (buf == NULL || len < AFMTSTR_LEN) 1103 return (0); 1104 1105 memset(buf, 0, len); 1106 1107 enc = AFMT_ENCODING(afmt); 1108 ch = AFMT_CHANNEL(afmt); 1109 ext = AFMT_EXTCHANNEL(afmt); 1110 /* check there is at least one channel */ 1111 if (ch <= ext) 1112 return (0); 1113 for (i = 0; afmt_tab[i].name != NULL; i++) { 1114 if (enc != afmt_tab[i].afmt) 1115 continue; 1116 /* found a match */ 1117 snprintf(buf, len, "%s:%d.%d", 1118 afmt_tab[i].name, ch - ext, ext); 1119 return (SND_FORMAT(enc, ch, ext)); 1120 } 1121 return (0); 1122 } 1123 1124 int 1125 chn_reset(struct pcm_channel *c, uint32_t fmt, uint32_t spd) 1126 { 1127 int r; 1128 1129 CHN_LOCKASSERT(c); 1130 c->feedcount = 0; 1131 c->flags &= CHN_F_RESET; 1132 c->interrupts = 0; 1133 c->timeout = 1; 1134 c->xruns = 0; 1135 1136 c->flags |= (pcm_getflags(c->dev) & SD_F_BITPERFECT) ? 1137 CHN_F_BITPERFECT : 0; 1138 1139 r = CHANNEL_RESET(c->methods, c->devinfo); 1140 if (r == 0 && fmt != 0 && spd != 0) { 1141 r = chn_setparam(c, fmt, spd); 1142 fmt = 0; 1143 spd = 0; 1144 } 1145 if (r == 0 && fmt != 0) 1146 r = chn_setformat(c, fmt); 1147 if (r == 0 && spd != 0) 1148 r = chn_setspeed(c, spd); 1149 if (r == 0) 1150 r = chn_setlatency(c, chn_latency); 1151 if (r == 0) { 1152 chn_resetbuf(c); 1153 r = CHANNEL_RESETDONE(c->methods, c->devinfo); 1154 } 1155 return r; 1156 } 1157 1158 int 1159 chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) 1160 { 1161 struct feeder_class *fc; 1162 struct snd_dbuf *b, *bs; 1163 int i, ret; 1164 1165 if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX) 1166 chn_timeout = CHN_TIMEOUT; 1167 1168 chn_lockinit(c, dir); 1169 1170 b = NULL; 1171 bs = NULL; 1172 CHN_INIT(c, children); 1173 CHN_INIT(c, children.busy); 1174 c->devinfo = NULL; 1175 c->feeder = NULL; 1176 c->latency = -1; 1177 c->timeout = 1; 1178 1179 ret = ENOMEM; 1180 b = sndbuf_create(c->dev, c->name, "primary", c); 1181 if (b == NULL) 1182 goto out; 1183 bs = sndbuf_create(c->dev, c->name, "secondary", c); 1184 if (bs == NULL) 1185 goto out; 1186 1187 CHN_LOCK(c); 1188 1189 ret = EINVAL; 1190 fc = feeder_getclass(NULL); 1191 if (fc == NULL) 1192 goto out; 1193 if (chn_addfeeder(c, fc, NULL)) 1194 goto out; 1195 1196 /* 1197 * XXX - sndbuf_setup() & sndbuf_resize() expect to be called 1198 * with the channel unlocked because they are also called 1199 * from driver methods that don't know about locking 1200 */ 1201 CHN_UNLOCK(c); 1202 sndbuf_setup(bs, NULL, 0); 1203 CHN_LOCK(c); 1204 c->bufhard = b; 1205 c->bufsoft = bs; 1206 c->flags = 0; 1207 c->feederflags = 0; 1208 c->sm = NULL; 1209 c->format = SND_FORMAT(AFMT_U8, 1, 0); 1210 c->speed = DSP_DEFAULT_SPEED; 1211 1212 c->matrix = *feeder_matrix_id_map(SND_CHN_MATRIX_1_0); 1213 c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL; 1214 1215 for (i = 0; i < SND_CHN_T_MAX; i++) { 1216 c->volume[SND_VOL_C_MASTER][i] = SND_VOL_0DB_MASTER; 1217 } 1218 1219 c->volume[SND_VOL_C_MASTER][SND_CHN_T_VOL_0DB] = SND_VOL_0DB_MASTER; 1220 c->volume[SND_VOL_C_PCM][SND_CHN_T_VOL_0DB] = chn_vol_0db_pcm; 1221 1222 memset(c->muted, 0, sizeof(c->muted)); 1223 1224 chn_vpc_reset(c, SND_VOL_C_PCM, 1); 1225 1226 ret = ENODEV; 1227 CHN_UNLOCK(c); /* XXX - Unlock for CHANNEL_INIT() malloc() call */ 1228 c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction); 1229 CHN_LOCK(c); 1230 if (c->devinfo == NULL) 1231 goto out; 1232 1233 ret = ENOMEM; 1234 if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0)) 1235 goto out; 1236 1237 ret = 0; 1238 c->direction = direction; 1239 1240 sndbuf_setfmt(b, c->format); 1241 sndbuf_setspd(b, c->speed); 1242 sndbuf_setfmt(bs, c->format); 1243 sndbuf_setspd(bs, c->speed); 1244 1245 /** 1246 * @todo Should this be moved somewhere else? The primary buffer 1247 * is allocated by the driver or via DMA map setup, and tmpbuf 1248 * seems to only come into existence in sndbuf_resize(). 1249 */ 1250 if (c->direction == PCMDIR_PLAY) { 1251 bs->sl = sndbuf_getmaxsize(bs); 1252 bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_NOWAIT); 1253 if (bs->shadbuf == NULL) { 1254 ret = ENOMEM; 1255 goto out; 1256 } 1257 } 1258 1259 out: 1260 CHN_UNLOCK(c); 1261 if (ret) { 1262 if (c->devinfo) { 1263 if (CHANNEL_FREE(c->methods, c->devinfo)) 1264 sndbuf_free(b); 1265 } 1266 if (bs) 1267 sndbuf_destroy(bs); 1268 if (b) 1269 sndbuf_destroy(b); 1270 CHN_LOCK(c); 1271 c->flags |= CHN_F_DEAD; 1272 chn_lockdestroy(c); 1273 1274 return ret; 1275 } 1276 1277 return 0; 1278 } 1279 1280 int 1281 chn_kill(struct pcm_channel *c) 1282 { 1283 struct snd_dbuf *b = c->bufhard; 1284 struct snd_dbuf *bs = c->bufsoft; 1285 1286 if (CHN_STARTED(c)) { 1287 CHN_LOCK(c); 1288 chn_trigger(c, PCMTRIG_ABORT); 1289 CHN_UNLOCK(c); 1290 } 1291 while (chn_removefeeder(c) == 0) 1292 ; 1293 if (CHANNEL_FREE(c->methods, c->devinfo)) 1294 sndbuf_free(b); 1295 sndbuf_destroy(bs); 1296 sndbuf_destroy(b); 1297 CHN_LOCK(c); 1298 c->flags |= CHN_F_DEAD; 1299 chn_lockdestroy(c); 1300 1301 return (0); 1302 } 1303 1304 int 1305 chn_setvolume_multi(struct pcm_channel *c, int vc, int left, int right, 1306 int center) 1307 { 1308 int i, ret; 1309 1310 ret = 0; 1311 1312 for (i = 0; i < SND_CHN_T_MAX; i++) { 1313 if ((1 << i) & SND_CHN_LEFT_MASK) 1314 ret |= chn_setvolume_matrix(c, vc, i, left); 1315 else if ((1 << i) & SND_CHN_RIGHT_MASK) 1316 ret |= chn_setvolume_matrix(c, vc, i, right) << 8; 1317 else 1318 ret |= chn_setvolume_matrix(c, vc, i, center) << 16; 1319 } 1320 1321 return (ret); 1322 } 1323 1324 int 1325 chn_setvolume_matrix(struct pcm_channel *c, int vc, int vt, int val) 1326 { 1327 int i; 1328 1329 KASSERT(c != NULL && vc >= SND_VOL_C_MASTER && vc < SND_VOL_C_MAX && 1330 (vc == SND_VOL_C_MASTER || (vc & 1)) && 1331 (vt == SND_CHN_T_VOL_0DB || (vt >= SND_CHN_T_BEGIN && 1332 vt <= SND_CHN_T_END)) && (vt != SND_CHN_T_VOL_0DB || 1333 (val >= SND_VOL_0DB_MIN && val <= SND_VOL_0DB_MAX)), 1334 ("%s(): invalid volume matrix c=%p vc=%d vt=%d val=%d", 1335 __func__, c, vc, vt, val)); 1336 CHN_LOCKASSERT(c); 1337 1338 if (val < 0) 1339 val = 0; 1340 if (val > 100) 1341 val = 100; 1342 1343 c->volume[vc][vt] = val; 1344 1345 /* 1346 * Do relative calculation here and store it into class + 1 1347 * to ease the job of feeder_volume. 1348 */ 1349 if (vc == SND_VOL_C_MASTER) { 1350 for (vc = SND_VOL_C_BEGIN; vc <= SND_VOL_C_END; 1351 vc += SND_VOL_C_STEP) 1352 c->volume[SND_VOL_C_VAL(vc)][vt] = 1353 SND_VOL_CALC_VAL(c->volume, vc, vt); 1354 } else if (vc & 1) { 1355 if (vt == SND_CHN_T_VOL_0DB) 1356 for (i = SND_CHN_T_BEGIN; i <= SND_CHN_T_END; 1357 i += SND_CHN_T_STEP) { 1358 c->volume[SND_VOL_C_VAL(vc)][i] = 1359 SND_VOL_CALC_VAL(c->volume, vc, i); 1360 } 1361 else 1362 c->volume[SND_VOL_C_VAL(vc)][vt] = 1363 SND_VOL_CALC_VAL(c->volume, vc, vt); 1364 } 1365 1366 return (val); 1367 } 1368 1369 int 1370 chn_getvolume_matrix(struct pcm_channel *c, int vc, int vt) 1371 { 1372 KASSERT(c != NULL && vc >= SND_VOL_C_MASTER && vc < SND_VOL_C_MAX && 1373 (vt == SND_CHN_T_VOL_0DB || 1374 (vt >= SND_CHN_T_BEGIN && vt <= SND_CHN_T_END)), 1375 ("%s(): invalid volume matrix c=%p vc=%d vt=%d", 1376 __func__, c, vc, vt)); 1377 CHN_LOCKASSERT(c); 1378 1379 return (c->volume[vc][vt]); 1380 } 1381 1382 int 1383 chn_setmute_multi(struct pcm_channel *c, int vc, int mute) 1384 { 1385 int i, ret; 1386 1387 ret = 0; 1388 1389 for (i = 0; i < SND_CHN_T_MAX; i++) { 1390 if ((1 << i) & SND_CHN_LEFT_MASK) 1391 ret |= chn_setmute_matrix(c, vc, i, mute); 1392 else if ((1 << i) & SND_CHN_RIGHT_MASK) 1393 ret |= chn_setmute_matrix(c, vc, i, mute) << 8; 1394 else 1395 ret |= chn_setmute_matrix(c, vc, i, mute) << 16; 1396 } 1397 return (ret); 1398 } 1399 1400 int 1401 chn_setmute_matrix(struct pcm_channel *c, int vc, int vt, int mute) 1402 { 1403 int i; 1404 1405 KASSERT(c != NULL && vc >= SND_VOL_C_MASTER && vc < SND_VOL_C_MAX && 1406 (vc == SND_VOL_C_MASTER || (vc & 1)) && 1407 (vt == SND_CHN_T_VOL_0DB || (vt >= SND_CHN_T_BEGIN && vt <= SND_CHN_T_END)), 1408 ("%s(): invalid mute matrix c=%p vc=%d vt=%d mute=%d", 1409 __func__, c, vc, vt, mute)); 1410 1411 CHN_LOCKASSERT(c); 1412 1413 mute = (mute != 0); 1414 1415 c->muted[vc][vt] = mute; 1416 1417 /* 1418 * Do relative calculation here and store it into class + 1 1419 * to ease the job of feeder_volume. 1420 */ 1421 if (vc == SND_VOL_C_MASTER) { 1422 for (vc = SND_VOL_C_BEGIN; vc <= SND_VOL_C_END; 1423 vc += SND_VOL_C_STEP) 1424 c->muted[SND_VOL_C_VAL(vc)][vt] = mute; 1425 } else if (vc & 1) { 1426 if (vt == SND_CHN_T_VOL_0DB) { 1427 for (i = SND_CHN_T_BEGIN; i <= SND_CHN_T_END; 1428 i += SND_CHN_T_STEP) { 1429 c->muted[SND_VOL_C_VAL(vc)][i] = mute; 1430 } 1431 } else { 1432 c->muted[SND_VOL_C_VAL(vc)][vt] = mute; 1433 } 1434 } 1435 return (mute); 1436 } 1437 1438 int 1439 chn_getmute_matrix(struct pcm_channel *c, int vc, int vt) 1440 { 1441 KASSERT(c != NULL && vc >= SND_VOL_C_MASTER && vc < SND_VOL_C_MAX && 1442 (vt == SND_CHN_T_VOL_0DB || 1443 (vt >= SND_CHN_T_BEGIN && vt <= SND_CHN_T_END)), 1444 ("%s(): invalid mute matrix c=%p vc=%d vt=%d", 1445 __func__, c, vc, vt)); 1446 CHN_LOCKASSERT(c); 1447 1448 return (c->muted[vc][vt]); 1449 } 1450 1451 struct pcmchan_matrix * 1452 chn_getmatrix(struct pcm_channel *c) 1453 { 1454 1455 KASSERT(c != NULL, ("%s(): NULL channel", __func__)); 1456 CHN_LOCKASSERT(c); 1457 1458 if (!(c->format & AFMT_CONVERTIBLE)) 1459 return (NULL); 1460 1461 return (&c->matrix); 1462 } 1463 1464 int 1465 chn_setmatrix(struct pcm_channel *c, struct pcmchan_matrix *m) 1466 { 1467 1468 KASSERT(c != NULL && m != NULL, 1469 ("%s(): NULL channel or matrix", __func__)); 1470 CHN_LOCKASSERT(c); 1471 1472 if (!(c->format & AFMT_CONVERTIBLE)) 1473 return (EINVAL); 1474 1475 c->matrix = *m; 1476 c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL; 1477 1478 return (chn_setformat(c, SND_FORMAT(c->format, m->channels, m->ext))); 1479 } 1480 1481 /* 1482 * XXX chn_oss_* exists for the sake of compatibility. 1483 */ 1484 int 1485 chn_oss_getorder(struct pcm_channel *c, unsigned long long *map) 1486 { 1487 1488 KASSERT(c != NULL && map != NULL, 1489 ("%s(): NULL channel or map", __func__)); 1490 CHN_LOCKASSERT(c); 1491 1492 if (!(c->format & AFMT_CONVERTIBLE)) 1493 return (EINVAL); 1494 1495 return (feeder_matrix_oss_get_channel_order(&c->matrix, map)); 1496 } 1497 1498 int 1499 chn_oss_setorder(struct pcm_channel *c, unsigned long long *map) 1500 { 1501 struct pcmchan_matrix m; 1502 int ret; 1503 1504 KASSERT(c != NULL && map != NULL, 1505 ("%s(): NULL channel or map", __func__)); 1506 CHN_LOCKASSERT(c); 1507 1508 if (!(c->format & AFMT_CONVERTIBLE)) 1509 return (EINVAL); 1510 1511 m = c->matrix; 1512 ret = feeder_matrix_oss_set_channel_order(&m, map); 1513 if (ret != 0) 1514 return (ret); 1515 1516 return (chn_setmatrix(c, &m)); 1517 } 1518 1519 #define SND_CHN_OSS_FRONT (SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR) 1520 #define SND_CHN_OSS_SURR (SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR) 1521 #define SND_CHN_OSS_CENTER_LFE (SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF) 1522 #define SND_CHN_OSS_REAR (SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR) 1523 1524 int 1525 chn_oss_getmask(struct pcm_channel *c, uint32_t *retmask) 1526 { 1527 struct pcmchan_matrix *m; 1528 struct pcmchan_caps *caps; 1529 uint32_t i, format; 1530 1531 KASSERT(c != NULL && retmask != NULL, 1532 ("%s(): NULL channel or retmask", __func__)); 1533 CHN_LOCKASSERT(c); 1534 1535 caps = chn_getcaps(c); 1536 if (caps == NULL || caps->fmtlist == NULL) 1537 return (ENODEV); 1538 1539 for (i = 0; caps->fmtlist[i] != 0; i++) { 1540 format = caps->fmtlist[i]; 1541 if (!(format & AFMT_CONVERTIBLE)) { 1542 *retmask |= DSP_BIND_SPDIF; 1543 continue; 1544 } 1545 m = CHANNEL_GETMATRIX(c->methods, c->devinfo, format); 1546 if (m == NULL) 1547 continue; 1548 if (m->mask & SND_CHN_OSS_FRONT) 1549 *retmask |= DSP_BIND_FRONT; 1550 if (m->mask & SND_CHN_OSS_SURR) 1551 *retmask |= DSP_BIND_SURR; 1552 if (m->mask & SND_CHN_OSS_CENTER_LFE) 1553 *retmask |= DSP_BIND_CENTER_LFE; 1554 if (m->mask & SND_CHN_OSS_REAR) 1555 *retmask |= DSP_BIND_REAR; 1556 } 1557 1558 /* report software-supported binding mask */ 1559 if (!CHN_BITPERFECT(c) && report_soft_matrix) 1560 *retmask |= DSP_BIND_FRONT | DSP_BIND_SURR | 1561 DSP_BIND_CENTER_LFE | DSP_BIND_REAR; 1562 1563 return (0); 1564 } 1565 1566 void 1567 chn_vpc_reset(struct pcm_channel *c, int vc, int force) 1568 { 1569 int i; 1570 1571 KASSERT(c != NULL && vc >= SND_VOL_C_BEGIN && vc <= SND_VOL_C_END, 1572 ("%s(): invalid reset c=%p vc=%d", __func__, c, vc)); 1573 CHN_LOCKASSERT(c); 1574 1575 if (force == 0 && chn_vpc_autoreset == 0) 1576 return; 1577 1578 for (i = SND_CHN_T_BEGIN; i <= SND_CHN_T_END; i += SND_CHN_T_STEP) 1579 CHN_SETVOLUME(c, vc, i, c->volume[vc][SND_CHN_T_VOL_0DB]); 1580 } 1581 1582 static u_int32_t 1583 round_pow2(u_int32_t v) 1584 { 1585 u_int32_t ret; 1586 1587 if (v < 2) 1588 v = 2; 1589 ret = 0; 1590 while (v >> ret) 1591 ret++; 1592 ret = 1 << (ret - 1); 1593 while (ret < v) 1594 ret <<= 1; 1595 return ret; 1596 } 1597 1598 static u_int32_t 1599 round_blksz(u_int32_t v, int round) 1600 { 1601 u_int32_t ret, tmp; 1602 1603 if (round < 1) 1604 round = 1; 1605 1606 ret = min(round_pow2(v), CHN_2NDBUFMAXSIZE >> 1); 1607 1608 if (ret > v && (ret >> 1) > 0 && (ret >> 1) >= ((v * 3) >> 2)) 1609 ret >>= 1; 1610 1611 tmp = ret - (ret % round); 1612 while (tmp < 16 || tmp < round) { 1613 ret <<= 1; 1614 tmp = ret - (ret % round); 1615 } 1616 1617 return ret; 1618 } 1619 1620 /* 1621 * 4Front call it DSP Policy, while we call it "Latency Profile". The idea 1622 * is to keep 2nd buffer short so that it doesn't cause long queue during 1623 * buffer transfer. 1624 * 1625 * Latency reference table for 48khz stereo 16bit: (PLAY) 1626 * 1627 * +---------+------------+-----------+------------+ 1628 * | Latency | Blockcount | Blocksize | Buffersize | 1629 * +---------+------------+-----------+------------+ 1630 * | 0 | 2 | 64 | 128 | 1631 * +---------+------------+-----------+------------+ 1632 * | 1 | 4 | 128 | 512 | 1633 * +---------+------------+-----------+------------+ 1634 * | 2 | 8 | 512 | 4096 | 1635 * +---------+------------+-----------+------------+ 1636 * | 3 | 16 | 512 | 8192 | 1637 * +---------+------------+-----------+------------+ 1638 * | 4 | 32 | 512 | 16384 | 1639 * +---------+------------+-----------+------------+ 1640 * | 5 | 32 | 1024 | 32768 | 1641 * +---------+------------+-----------+------------+ 1642 * | 6 | 16 | 2048 | 32768 | 1643 * +---------+------------+-----------+------------+ 1644 * | 7 | 8 | 4096 | 32768 | 1645 * +---------+------------+-----------+------------+ 1646 * | 8 | 4 | 8192 | 32768 | 1647 * +---------+------------+-----------+------------+ 1648 * | 9 | 2 | 16384 | 32768 | 1649 * +---------+------------+-----------+------------+ 1650 * | 10 | 2 | 32768 | 65536 | 1651 * +---------+------------+-----------+------------+ 1652 * 1653 * Recording need a different reference table. All we care is 1654 * gobbling up everything within reasonable buffering threshold. 1655 * 1656 * Latency reference table for 48khz stereo 16bit: (REC) 1657 * 1658 * +---------+------------+-----------+------------+ 1659 * | Latency | Blockcount | Blocksize | Buffersize | 1660 * +---------+------------+-----------+------------+ 1661 * | 0 | 512 | 32 | 16384 | 1662 * +---------+------------+-----------+------------+ 1663 * | 1 | 256 | 64 | 16384 | 1664 * +---------+------------+-----------+------------+ 1665 * | 2 | 128 | 128 | 16384 | 1666 * +---------+------------+-----------+------------+ 1667 * | 3 | 64 | 256 | 16384 | 1668 * +---------+------------+-----------+------------+ 1669 * | 4 | 32 | 512 | 16384 | 1670 * +---------+------------+-----------+------------+ 1671 * | 5 | 32 | 1024 | 32768 | 1672 * +---------+------------+-----------+------------+ 1673 * | 6 | 16 | 2048 | 32768 | 1674 * +---------+------------+-----------+------------+ 1675 * | 7 | 8 | 4096 | 32768 | 1676 * +---------+------------+-----------+------------+ 1677 * | 8 | 4 | 8192 | 32768 | 1678 * +---------+------------+-----------+------------+ 1679 * | 9 | 2 | 16384 | 32768 | 1680 * +---------+------------+-----------+------------+ 1681 * | 10 | 2 | 32768 | 65536 | 1682 * +---------+------------+-----------+------------+ 1683 * 1684 * Calculations for other data rate are entirely based on these reference 1685 * tables. For normal operation, Latency 5 seems give the best, well 1686 * balanced performance for typical workload. Anything below 5 will 1687 * eat up CPU to keep up with increasing context switches because of 1688 * shorter buffer space and usually require the application to handle it 1689 * aggressively through possibly real time programming technique. 1690 * 1691 */ 1692 #define CHN_LATENCY_PBLKCNT_REF \ 1693 {{1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 1}, \ 1694 {1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 1}} 1695 #define CHN_LATENCY_PBUFSZ_REF \ 1696 {{7, 9, 12, 13, 14, 15, 15, 15, 15, 15, 16}, \ 1697 {11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 17}} 1698 1699 #define CHN_LATENCY_RBLKCNT_REF \ 1700 {{9, 8, 7, 6, 5, 5, 4, 3, 2, 1, 1}, \ 1701 {9, 8, 7, 6, 5, 5, 4, 3, 2, 1, 1}} 1702 #define CHN_LATENCY_RBUFSZ_REF \ 1703 {{14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16}, \ 1704 {15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17}} 1705 1706 #define CHN_LATENCY_DATA_REF 192000 /* 48khz stereo 16bit ~ 48000 x 2 x 2 */ 1707 1708 static int 1709 chn_calclatency(int dir, int latency, int bps, u_int32_t datarate, 1710 u_int32_t max, int *rblksz, int *rblkcnt) 1711 { 1712 static int pblkcnts[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] = 1713 CHN_LATENCY_PBLKCNT_REF; 1714 static int pbufszs[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] = 1715 CHN_LATENCY_PBUFSZ_REF; 1716 static int rblkcnts[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] = 1717 CHN_LATENCY_RBLKCNT_REF; 1718 static int rbufszs[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] = 1719 CHN_LATENCY_RBUFSZ_REF; 1720 u_int32_t bufsz; 1721 int lprofile, blksz, blkcnt; 1722 1723 if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX || 1724 bps < 1 || datarate < 1 || 1725 !(dir == PCMDIR_PLAY || dir == PCMDIR_REC)) { 1726 if (rblksz != NULL) 1727 *rblksz = CHN_2NDBUFMAXSIZE >> 1; 1728 if (rblkcnt != NULL) 1729 *rblkcnt = 2; 1730 printf("%s(): FAILED dir=%d latency=%d bps=%d " 1731 "datarate=%u max=%u\n", 1732 __func__, dir, latency, bps, datarate, max); 1733 return CHN_2NDBUFMAXSIZE; 1734 } 1735 1736 lprofile = chn_latency_profile; 1737 1738 if (dir == PCMDIR_PLAY) { 1739 blkcnt = pblkcnts[lprofile][latency]; 1740 bufsz = pbufszs[lprofile][latency]; 1741 } else { 1742 blkcnt = rblkcnts[lprofile][latency]; 1743 bufsz = rbufszs[lprofile][latency]; 1744 } 1745 1746 bufsz = round_pow2(snd_xbytes(1 << bufsz, CHN_LATENCY_DATA_REF, 1747 datarate)); 1748 if (bufsz > max) 1749 bufsz = max; 1750 blksz = round_blksz(bufsz >> blkcnt, bps); 1751 1752 if (rblksz != NULL) 1753 *rblksz = blksz; 1754 if (rblkcnt != NULL) 1755 *rblkcnt = 1 << blkcnt; 1756 1757 return blksz << blkcnt; 1758 } 1759 1760 static int 1761 chn_resizebuf(struct pcm_channel *c, int latency, 1762 int blkcnt, int blksz) 1763 { 1764 struct snd_dbuf *b, *bs, *pb; 1765 int sblksz, sblkcnt, hblksz, hblkcnt, limit = 0, nsblksz, nsblkcnt; 1766 int ret; 1767 1768 CHN_LOCKASSERT(c); 1769 1770 if ((c->flags & (CHN_F_MMAP | CHN_F_TRIGGERED)) || 1771 !(c->direction == PCMDIR_PLAY || c->direction == PCMDIR_REC)) 1772 return EINVAL; 1773 1774 if (latency == -1) { 1775 c->latency = -1; 1776 latency = chn_latency; 1777 } else if (latency == -2) { 1778 latency = c->latency; 1779 if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX) 1780 latency = chn_latency; 1781 } else if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX) 1782 return EINVAL; 1783 else { 1784 c->latency = latency; 1785 } 1786 1787 bs = c->bufsoft; 1788 b = c->bufhard; 1789 1790 if (!(blksz == 0 || blkcnt == -1) && 1791 (blksz < 16 || blksz < sndbuf_getalign(bs) || blkcnt < 2 || 1792 (blksz * blkcnt) > CHN_2NDBUFMAXSIZE)) 1793 return EINVAL; 1794 1795 chn_calclatency(c->direction, latency, sndbuf_getalign(bs), 1796 sndbuf_getalign(bs) * sndbuf_getspd(bs), CHN_2NDBUFMAXSIZE, 1797 &sblksz, &sblkcnt); 1798 1799 if (blksz == 0 || blkcnt == -1) { 1800 if (blkcnt == -1) 1801 c->flags &= ~CHN_F_HAS_SIZE; 1802 if (c->flags & CHN_F_HAS_SIZE) { 1803 blksz = sndbuf_getblksz(bs); 1804 blkcnt = sndbuf_getblkcnt(bs); 1805 } 1806 } else 1807 c->flags |= CHN_F_HAS_SIZE; 1808 1809 if (c->flags & CHN_F_HAS_SIZE) { 1810 /* 1811 * The application has requested their own blksz/blkcnt. 1812 * Just obey with it, and let them toast alone. We can 1813 * clamp it to the nearest latency profile, but that would 1814 * defeat the purpose of having custom control. The least 1815 * we can do is round it to the nearest ^2 and align it. 1816 */ 1817 sblksz = round_blksz(blksz, sndbuf_getalign(bs)); 1818 sblkcnt = round_pow2(blkcnt); 1819 } 1820 1821 if (c->parentchannel != NULL) { 1822 pb = c->parentchannel->bufsoft; 1823 CHN_UNLOCK(c); 1824 CHN_LOCK(c->parentchannel); 1825 chn_notify(c->parentchannel, CHN_N_BLOCKSIZE); 1826 CHN_UNLOCK(c->parentchannel); 1827 CHN_LOCK(c); 1828 if (c->direction == PCMDIR_PLAY) { 1829 limit = (pb != NULL) ? 1830 sndbuf_xbytes(sndbuf_getsize(pb), pb, bs) : 0; 1831 } else { 1832 limit = (pb != NULL) ? 1833 sndbuf_xbytes(sndbuf_getblksz(pb), pb, bs) * 2 : 0; 1834 } 1835 } else { 1836 hblkcnt = 2; 1837 if (c->flags & CHN_F_HAS_SIZE) { 1838 hblksz = round_blksz(sndbuf_xbytes(sblksz, bs, b), 1839 sndbuf_getalign(b)); 1840 hblkcnt = round_pow2(sndbuf_getblkcnt(bs)); 1841 } else 1842 chn_calclatency(c->direction, latency, 1843 sndbuf_getalign(b), 1844 sndbuf_getalign(b) * sndbuf_getspd(b), 1845 CHN_2NDBUFMAXSIZE, &hblksz, &hblkcnt); 1846 1847 if ((hblksz << 1) > sndbuf_getmaxsize(b)) 1848 hblksz = round_blksz(sndbuf_getmaxsize(b) >> 1, 1849 sndbuf_getalign(b)); 1850 1851 while ((hblksz * hblkcnt) > sndbuf_getmaxsize(b)) { 1852 if (hblkcnt < 4) 1853 hblksz >>= 1; 1854 else 1855 hblkcnt >>= 1; 1856 } 1857 1858 hblksz -= hblksz % sndbuf_getalign(b); 1859 1860 #if 0 1861 hblksz = sndbuf_getmaxsize(b) >> 1; 1862 hblksz -= hblksz % sndbuf_getalign(b); 1863 hblkcnt = 2; 1864 #endif 1865 1866 CHN_UNLOCK(c); 1867 if (chn_usefrags == 0 || 1868 CHANNEL_SETFRAGMENTS(c->methods, c->devinfo, 1869 hblksz, hblkcnt) != 0) 1870 sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods, 1871 c->devinfo, hblksz)); 1872 CHN_LOCK(c); 1873 1874 if (!CHN_EMPTY(c, children)) { 1875 nsblksz = round_blksz( 1876 sndbuf_xbytes(sndbuf_getblksz(b), b, bs), 1877 sndbuf_getalign(bs)); 1878 nsblkcnt = sndbuf_getblkcnt(b); 1879 if (c->direction == PCMDIR_PLAY) { 1880 do { 1881 nsblkcnt--; 1882 } while (nsblkcnt >= 2 && 1883 nsblksz * nsblkcnt >= sblksz * sblkcnt); 1884 nsblkcnt++; 1885 } 1886 sblksz = nsblksz; 1887 sblkcnt = nsblkcnt; 1888 limit = 0; 1889 } else 1890 limit = sndbuf_xbytes(sndbuf_getblksz(b), b, bs) * 2; 1891 } 1892 1893 if (limit > CHN_2NDBUFMAXSIZE) 1894 limit = CHN_2NDBUFMAXSIZE; 1895 1896 #if 0 1897 while (limit > 0 && (sblksz * sblkcnt) > limit) { 1898 if (sblkcnt < 4) 1899 break; 1900 sblkcnt >>= 1; 1901 } 1902 #endif 1903 1904 while ((sblksz * sblkcnt) < limit) 1905 sblkcnt <<= 1; 1906 1907 while ((sblksz * sblkcnt) > CHN_2NDBUFMAXSIZE) { 1908 if (sblkcnt < 4) 1909 sblksz >>= 1; 1910 else 1911 sblkcnt >>= 1; 1912 } 1913 1914 sblksz -= sblksz % sndbuf_getalign(bs); 1915 1916 if (sndbuf_getblkcnt(bs) != sblkcnt || sndbuf_getblksz(bs) != sblksz || 1917 sndbuf_getsize(bs) != (sblkcnt * sblksz)) { 1918 ret = sndbuf_remalloc(bs, sblkcnt, sblksz); 1919 if (ret != 0) { 1920 device_printf(c->dev, "%s(): Failed: %d %d\n", 1921 __func__, sblkcnt, sblksz); 1922 return ret; 1923 } 1924 } 1925 1926 /* 1927 * Interrupt timeout 1928 */ 1929 c->timeout = ((u_int64_t)hz * sndbuf_getsize(bs)) / 1930 ((u_int64_t)sndbuf_getspd(bs) * sndbuf_getalign(bs)); 1931 if (c->parentchannel != NULL) 1932 c->timeout = min(c->timeout, c->parentchannel->timeout); 1933 if (c->timeout < 1) 1934 c->timeout = 1; 1935 1936 /* 1937 * OSSv4 docs: "By default OSS will set the low water level equal 1938 * to the fragment size which is optimal in most cases." 1939 */ 1940 c->lw = sndbuf_getblksz(bs); 1941 chn_resetbuf(c); 1942 1943 if (snd_verbose > 3) 1944 device_printf(c->dev, "%s(): %s (%s) timeout=%u " 1945 "b[%d/%d/%d] bs[%d/%d/%d] limit=%d\n", 1946 __func__, CHN_DIRSTR(c), 1947 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware", 1948 c->timeout, 1949 sndbuf_getsize(b), sndbuf_getblksz(b), 1950 sndbuf_getblkcnt(b), 1951 sndbuf_getsize(bs), sndbuf_getblksz(bs), 1952 sndbuf_getblkcnt(bs), limit); 1953 1954 return 0; 1955 } 1956 1957 int 1958 chn_setlatency(struct pcm_channel *c, int latency) 1959 { 1960 CHN_LOCKASSERT(c); 1961 /* Destroy blksz/blkcnt, enforce latency profile. */ 1962 return chn_resizebuf(c, latency, -1, 0); 1963 } 1964 1965 int 1966 chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz) 1967 { 1968 CHN_LOCKASSERT(c); 1969 /* Destroy latency profile, enforce blksz/blkcnt */ 1970 return chn_resizebuf(c, -1, blkcnt, blksz); 1971 } 1972 1973 int 1974 chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed) 1975 { 1976 struct pcmchan_caps *caps; 1977 uint32_t hwspeed, delta; 1978 int ret; 1979 1980 CHN_LOCKASSERT(c); 1981 1982 if (speed < 1 || format == 0 || CHN_STARTED(c)) 1983 return (EINVAL); 1984 1985 c->format = format; 1986 c->speed = speed; 1987 1988 caps = chn_getcaps(c); 1989 1990 hwspeed = speed; 1991 RANGE(hwspeed, caps->minspeed, caps->maxspeed); 1992 1993 sndbuf_setspd(c->bufhard, CHANNEL_SETSPEED(c->methods, c->devinfo, 1994 hwspeed)); 1995 hwspeed = sndbuf_getspd(c->bufhard); 1996 1997 delta = (hwspeed > speed) ? (hwspeed - speed) : (speed - hwspeed); 1998 1999 if (delta <= feeder_rate_round) 2000 c->speed = hwspeed; 2001 2002 ret = feeder_chain(c); 2003 2004 if (ret == 0) 2005 ret = CHANNEL_SETFORMAT(c->methods, c->devinfo, 2006 sndbuf_getfmt(c->bufhard)); 2007 2008 if (ret == 0) 2009 ret = chn_resizebuf(c, -2, 0, 0); 2010 2011 return (ret); 2012 } 2013 2014 int 2015 chn_setspeed(struct pcm_channel *c, uint32_t speed) 2016 { 2017 uint32_t oldformat, oldspeed, format; 2018 int ret; 2019 2020 #if 0 2021 /* XXX force 48k */ 2022 if (c->format & AFMT_PASSTHROUGH) 2023 speed = AFMT_PASSTHROUGH_RATE; 2024 #endif 2025 2026 oldformat = c->format; 2027 oldspeed = c->speed; 2028 format = oldformat; 2029 2030 ret = chn_setparam(c, format, speed); 2031 if (ret != 0) { 2032 if (snd_verbose > 3) 2033 device_printf(c->dev, 2034 "%s(): Setting speed %d failed, " 2035 "falling back to %d\n", 2036 __func__, speed, oldspeed); 2037 chn_setparam(c, c->format, oldspeed); 2038 } 2039 2040 return (ret); 2041 } 2042 2043 int 2044 chn_setformat(struct pcm_channel *c, uint32_t format) 2045 { 2046 uint32_t oldformat, oldspeed, speed; 2047 int ret; 2048 2049 /* XXX force stereo */ 2050 if ((format & AFMT_PASSTHROUGH) && AFMT_CHANNEL(format) < 2) { 2051 format = SND_FORMAT(format, AFMT_PASSTHROUGH_CHANNEL, 2052 AFMT_PASSTHROUGH_EXTCHANNEL); 2053 } 2054 2055 oldformat = c->format; 2056 oldspeed = c->speed; 2057 speed = oldspeed; 2058 2059 ret = chn_setparam(c, format, speed); 2060 if (ret != 0) { 2061 if (snd_verbose > 3) 2062 device_printf(c->dev, 2063 "%s(): Format change 0x%08x failed, " 2064 "falling back to 0x%08x\n", 2065 __func__, format, oldformat); 2066 chn_setparam(c, oldformat, oldspeed); 2067 } 2068 2069 return (ret); 2070 } 2071 2072 void 2073 chn_syncstate(struct pcm_channel *c) 2074 { 2075 struct snddev_info *d; 2076 struct snd_mixer *m; 2077 2078 d = (c != NULL) ? c->parentsnddev : NULL; 2079 m = (d != NULL && d->mixer_dev != NULL) ? d->mixer_dev->si_drv1 : 2080 NULL; 2081 2082 if (d == NULL || m == NULL) 2083 return; 2084 2085 CHN_LOCKASSERT(c); 2086 2087 if (c->feederflags & (1 << FEEDER_VOLUME)) { 2088 uint32_t parent; 2089 int vol, pvol, left, right, center; 2090 2091 if (c->direction == PCMDIR_PLAY && 2092 (d->flags & SD_F_SOFTPCMVOL)) { 2093 /* CHN_UNLOCK(c); */ 2094 vol = mix_get(m, SOUND_MIXER_PCM); 2095 parent = mix_getparent(m, SOUND_MIXER_PCM); 2096 if (parent != SOUND_MIXER_NONE) 2097 pvol = mix_get(m, parent); 2098 else 2099 pvol = 100 | (100 << 8); 2100 /* CHN_LOCK(c); */ 2101 } else { 2102 vol = 100 | (100 << 8); 2103 pvol = vol; 2104 } 2105 2106 if (vol == -1) { 2107 device_printf(c->dev, 2108 "Soft PCM Volume: Failed to read pcm " 2109 "default value\n"); 2110 vol = 100 | (100 << 8); 2111 } 2112 2113 if (pvol == -1) { 2114 device_printf(c->dev, 2115 "Soft PCM Volume: Failed to read parent " 2116 "default value\n"); 2117 pvol = 100 | (100 << 8); 2118 } 2119 2120 left = ((vol & 0x7f) * (pvol & 0x7f)) / 100; 2121 right = (((vol >> 8) & 0x7f) * ((pvol >> 8) & 0x7f)) / 100; 2122 center = (left + right) >> 1; 2123 2124 chn_setvolume_multi(c, SND_VOL_C_MASTER, left, right, center); 2125 } 2126 2127 if (c->feederflags & (1 << FEEDER_EQ)) { 2128 struct pcm_feeder *f; 2129 int treble, bass, state; 2130 2131 /* CHN_UNLOCK(c); */ 2132 treble = mix_get(m, SOUND_MIXER_TREBLE); 2133 bass = mix_get(m, SOUND_MIXER_BASS); 2134 /* CHN_LOCK(c); */ 2135 2136 if (treble == -1) 2137 treble = 50; 2138 else 2139 treble = ((treble & 0x7f) + 2140 ((treble >> 8) & 0x7f)) >> 1; 2141 2142 if (bass == -1) 2143 bass = 50; 2144 else 2145 bass = ((bass & 0x7f) + ((bass >> 8) & 0x7f)) >> 1; 2146 2147 f = chn_findfeeder(c, FEEDER_EQ); 2148 if (f != NULL) { 2149 if (FEEDER_SET(f, FEEDEQ_TREBLE, treble) != 0) 2150 device_printf(c->dev, 2151 "EQ: Failed to set treble -- %d\n", 2152 treble); 2153 if (FEEDER_SET(f, FEEDEQ_BASS, bass) != 0) 2154 device_printf(c->dev, 2155 "EQ: Failed to set bass -- %d\n", 2156 bass); 2157 if (FEEDER_SET(f, FEEDEQ_PREAMP, d->eqpreamp) != 0) 2158 device_printf(c->dev, 2159 "EQ: Failed to set preamp -- %d\n", 2160 d->eqpreamp); 2161 if (d->flags & SD_F_EQ_BYPASSED) 2162 state = FEEDEQ_BYPASS; 2163 else if (d->flags & SD_F_EQ_ENABLED) 2164 state = FEEDEQ_ENABLE; 2165 else 2166 state = FEEDEQ_DISABLE; 2167 if (FEEDER_SET(f, FEEDEQ_STATE, state) != 0) 2168 device_printf(c->dev, 2169 "EQ: Failed to set state -- %d\n", state); 2170 } 2171 } 2172 } 2173 2174 int 2175 chn_trigger(struct pcm_channel *c, int go) 2176 { 2177 struct snddev_info *d = c->parentsnddev; 2178 int ret; 2179 2180 CHN_LOCKASSERT(c); 2181 if (!PCMTRIG_COMMON(go)) 2182 return (CHANNEL_TRIGGER(c->methods, c->devinfo, go)); 2183 2184 if (go == c->trigger) 2185 return (0); 2186 2187 ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go); 2188 if (ret != 0) 2189 return (ret); 2190 2191 switch (go) { 2192 case PCMTRIG_START: 2193 if (snd_verbose > 3) 2194 device_printf(c->dev, 2195 "%s() %s: calling go=0x%08x , " 2196 "prev=0x%08x\n", __func__, c->name, go, 2197 c->trigger); 2198 if (c->trigger != PCMTRIG_START) { 2199 c->trigger = go; 2200 CHN_UNLOCK(c); 2201 PCM_LOCK(d); 2202 CHN_INSERT_HEAD(d, c, channels.pcm.busy); 2203 PCM_UNLOCK(d); 2204 CHN_LOCK(c); 2205 chn_syncstate(c); 2206 } 2207 break; 2208 case PCMTRIG_STOP: 2209 case PCMTRIG_ABORT: 2210 if (snd_verbose > 3) 2211 device_printf(c->dev, 2212 "%s() %s: calling go=0x%08x , " 2213 "prev=0x%08x\n", __func__, c->name, go, 2214 c->trigger); 2215 if (c->trigger == PCMTRIG_START) { 2216 c->trigger = go; 2217 CHN_UNLOCK(c); 2218 PCM_LOCK(d); 2219 CHN_REMOVE(d, c, channels.pcm.busy); 2220 PCM_UNLOCK(d); 2221 CHN_LOCK(c); 2222 } 2223 break; 2224 default: 2225 break; 2226 } 2227 2228 return (0); 2229 } 2230 2231 /** 2232 * @brief Queries sound driver for sample-aligned hardware buffer pointer index 2233 * 2234 * This function obtains the hardware pointer location, then aligns it to 2235 * the current bytes-per-sample value before returning. (E.g., a channel 2236 * running in 16 bit stereo mode would require 4 bytes per sample, so a 2237 * hwptr value ranging from 32-35 would be returned as 32.) 2238 * 2239 * @param c PCM channel context 2240 * @returns sample-aligned hardware buffer pointer index 2241 */ 2242 int 2243 chn_getptr(struct pcm_channel *c) 2244 { 2245 int hwptr; 2246 2247 CHN_LOCKASSERT(c); 2248 hwptr = (CHN_STARTED(c)) ? CHANNEL_GETPTR(c->methods, c->devinfo) : 0; 2249 return (hwptr - (hwptr % sndbuf_getalign(c->bufhard))); 2250 } 2251 2252 struct pcmchan_caps * 2253 chn_getcaps(struct pcm_channel *c) 2254 { 2255 CHN_LOCKASSERT(c); 2256 return CHANNEL_GETCAPS(c->methods, c->devinfo); 2257 } 2258 2259 u_int32_t 2260 chn_getformats(struct pcm_channel *c) 2261 { 2262 u_int32_t *fmtlist, fmts; 2263 int i; 2264 2265 fmtlist = chn_getcaps(c)->fmtlist; 2266 fmts = 0; 2267 for (i = 0; fmtlist[i]; i++) 2268 fmts |= fmtlist[i]; 2269 2270 /* report software-supported formats */ 2271 if (!CHN_BITPERFECT(c) && report_soft_formats) 2272 fmts |= AFMT_CONVERTIBLE; 2273 2274 return (AFMT_ENCODING(fmts)); 2275 } 2276 2277 int 2278 chn_notify(struct pcm_channel *c, u_int32_t flags) 2279 { 2280 struct pcm_channel *ch; 2281 struct pcmchan_caps *caps; 2282 uint32_t bestformat, bestspeed, besthwformat, *vchanformat, *vchanrate; 2283 uint32_t vpflags; 2284 int dirty, err, run, nrun; 2285 2286 CHN_LOCKASSERT(c); 2287 2288 if (CHN_EMPTY(c, children)) 2289 return (ENODEV); 2290 2291 err = 0; 2292 2293 /* 2294 * If the hwchan is running, we can't change its rate, format or 2295 * blocksize 2296 */ 2297 run = (CHN_STARTED(c)) ? 1 : 0; 2298 if (run) 2299 flags &= CHN_N_VOLUME | CHN_N_TRIGGER; 2300 2301 if (flags & CHN_N_RATE) { 2302 /* 2303 * XXX I'll make good use of this someday. 2304 * However this is currently being superseded by 2305 * the availability of CHN_F_VCHAN_DYNAMIC. 2306 */ 2307 } 2308 2309 if (flags & CHN_N_FORMAT) { 2310 /* 2311 * XXX I'll make good use of this someday. 2312 * However this is currently being superseded by 2313 * the availability of CHN_F_VCHAN_DYNAMIC. 2314 */ 2315 } 2316 2317 if (flags & CHN_N_VOLUME) { 2318 /* 2319 * XXX I'll make good use of this someday, though 2320 * soft volume control is currently pretty much 2321 * integrated. 2322 */ 2323 } 2324 2325 if (flags & CHN_N_BLOCKSIZE) { 2326 /* 2327 * Set to default latency profile 2328 */ 2329 chn_setlatency(c, chn_latency); 2330 } 2331 2332 if ((flags & CHN_N_TRIGGER) && !(c->flags & CHN_F_VCHAN_DYNAMIC)) { 2333 nrun = CHN_EMPTY(c, children.busy) ? 0 : 1; 2334 if (nrun && !run) 2335 err = chn_start(c, 1); 2336 if (!nrun && run) 2337 chn_abort(c); 2338 flags &= ~CHN_N_TRIGGER; 2339 } 2340 2341 if (flags & CHN_N_TRIGGER) { 2342 if (c->direction == PCMDIR_PLAY) { 2343 vchanformat = &c->parentsnddev->pvchanformat; 2344 vchanrate = &c->parentsnddev->pvchanrate; 2345 } else { 2346 vchanformat = &c->parentsnddev->rvchanformat; 2347 vchanrate = &c->parentsnddev->rvchanrate; 2348 } 2349 2350 /* Dynamic Virtual Channel */ 2351 if (!(c->flags & CHN_F_VCHAN_ADAPTIVE)) { 2352 bestformat = *vchanformat; 2353 bestspeed = *vchanrate; 2354 } else { 2355 bestformat = 0; 2356 bestspeed = 0; 2357 } 2358 2359 besthwformat = 0; 2360 nrun = 0; 2361 caps = chn_getcaps(c); 2362 dirty = 0; 2363 vpflags = 0; 2364 2365 CHN_FOREACH(ch, c, children.busy) { 2366 CHN_LOCK(ch); 2367 if ((ch->format & AFMT_PASSTHROUGH) && 2368 snd_fmtvalid(ch->format, caps->fmtlist)) { 2369 bestformat = ch->format; 2370 bestspeed = ch->speed; 2371 CHN_UNLOCK(ch); 2372 vpflags = CHN_F_PASSTHROUGH; 2373 nrun++; 2374 break; 2375 } 2376 if ((ch->flags & CHN_F_EXCLUSIVE) && vpflags == 0) { 2377 if (c->flags & CHN_F_VCHAN_ADAPTIVE) { 2378 bestspeed = ch->speed; 2379 RANGE(bestspeed, caps->minspeed, 2380 caps->maxspeed); 2381 besthwformat = snd_fmtbest(ch->format, 2382 caps->fmtlist); 2383 if (besthwformat != 0) 2384 bestformat = besthwformat; 2385 } 2386 CHN_UNLOCK(ch); 2387 vpflags = CHN_F_EXCLUSIVE; 2388 nrun++; 2389 continue; 2390 } 2391 if (!(c->flags & CHN_F_VCHAN_ADAPTIVE) || 2392 vpflags != 0) { 2393 CHN_UNLOCK(ch); 2394 nrun++; 2395 continue; 2396 } 2397 if (ch->speed > bestspeed) { 2398 bestspeed = ch->speed; 2399 RANGE(bestspeed, caps->minspeed, 2400 caps->maxspeed); 2401 } 2402 besthwformat = snd_fmtbest(ch->format, caps->fmtlist); 2403 if (!(besthwformat & AFMT_VCHAN)) { 2404 CHN_UNLOCK(ch); 2405 nrun++; 2406 continue; 2407 } 2408 if (AFMT_CHANNEL(besthwformat) > 2409 AFMT_CHANNEL(bestformat)) 2410 bestformat = besthwformat; 2411 else if (AFMT_CHANNEL(besthwformat) == 2412 AFMT_CHANNEL(bestformat) && 2413 AFMT_BIT(besthwformat) > AFMT_BIT(bestformat)) 2414 bestformat = besthwformat; 2415 CHN_UNLOCK(ch); 2416 nrun++; 2417 } 2418 2419 if (bestformat == 0) 2420 bestformat = c->format; 2421 if (bestspeed == 0) 2422 bestspeed = c->speed; 2423 2424 if (bestformat != c->format || bestspeed != c->speed) 2425 dirty = 1; 2426 2427 c->flags &= ~(CHN_F_PASSTHROUGH | CHN_F_EXCLUSIVE); 2428 c->flags |= vpflags; 2429 2430 if (nrun && !run) { 2431 if (dirty) { 2432 bestspeed = CHANNEL_SETSPEED(c->methods, 2433 c->devinfo, bestspeed); 2434 err = chn_reset(c, bestformat, bestspeed); 2435 } 2436 if (err == 0 && dirty) { 2437 CHN_FOREACH(ch, c, children.busy) { 2438 CHN_LOCK(ch); 2439 if (VCHAN_SYNC_REQUIRED(ch)) 2440 vchan_sync(ch); 2441 CHN_UNLOCK(ch); 2442 } 2443 } 2444 if (err == 0) { 2445 if (dirty) 2446 c->flags |= CHN_F_DIRTY; 2447 err = chn_start(c, 1); 2448 } 2449 } 2450 2451 if (nrun && run && dirty) { 2452 chn_abort(c); 2453 bestspeed = CHANNEL_SETSPEED(c->methods, c->devinfo, 2454 bestspeed); 2455 err = chn_reset(c, bestformat, bestspeed); 2456 if (err == 0) { 2457 CHN_FOREACH(ch, c, children.busy) { 2458 CHN_LOCK(ch); 2459 if (VCHAN_SYNC_REQUIRED(ch)) 2460 vchan_sync(ch); 2461 CHN_UNLOCK(ch); 2462 } 2463 } 2464 if (err == 0) { 2465 c->flags |= CHN_F_DIRTY; 2466 err = chn_start(c, 1); 2467 } 2468 } 2469 2470 if (err == 0 && !(bestformat & AFMT_PASSTHROUGH) && 2471 (bestformat & AFMT_VCHAN)) { 2472 *vchanformat = bestformat; 2473 *vchanrate = bestspeed; 2474 } 2475 2476 if (!nrun && run) { 2477 c->flags &= ~(CHN_F_PASSTHROUGH | CHN_F_EXCLUSIVE); 2478 bestformat = *vchanformat; 2479 bestspeed = *vchanrate; 2480 chn_abort(c); 2481 if (c->format != bestformat || c->speed != bestspeed) 2482 chn_reset(c, bestformat, bestspeed); 2483 } 2484 } 2485 2486 return (err); 2487 } 2488 2489 /** 2490 * @brief Fetch array of supported discrete sample rates 2491 * 2492 * Wrapper for CHANNEL_GETRATES. Please see channel_if.m:getrates() for 2493 * detailed information. 2494 * 2495 * @note If the operation isn't supported, this function will just return 0 2496 * (no rates in the array), and *rates will be set to NULL. Callers 2497 * should examine rates @b only if this function returns non-zero. 2498 * 2499 * @param c pcm channel to examine 2500 * @param rates pointer to array of integers; rate table will be recorded here 2501 * 2502 * @return number of rates in the array pointed to be @c rates 2503 */ 2504 int 2505 chn_getrates(struct pcm_channel *c, int **rates) 2506 { 2507 KASSERT(rates != NULL, ("rates is null")); 2508 CHN_LOCKASSERT(c); 2509 return CHANNEL_GETRATES(c->methods, c->devinfo, rates); 2510 } 2511 2512 /** 2513 * @brief Remove channel from a sync group, if there is one. 2514 * 2515 * This function is initially intended for the following conditions: 2516 * - Starting a syncgroup (@c SNDCTL_DSP_SYNCSTART ioctl) 2517 * - Closing a device. (A channel can't be destroyed if it's still in use.) 2518 * 2519 * @note Before calling this function, the syncgroup list mutex must be 2520 * held. (Consider pcm_channel::sm protected by the SG list mutex 2521 * whether @c c is locked or not.) 2522 * 2523 * @param c channel device to be started or closed 2524 * @returns If this channel was the only member of a group, the group ID 2525 * is returned to the caller so that the caller can release it 2526 * via free_unr() after giving up the syncgroup lock. Else it 2527 * returns 0. 2528 */ 2529 int 2530 chn_syncdestroy(struct pcm_channel *c) 2531 { 2532 struct pcmchan_syncmember *sm; 2533 struct pcmchan_syncgroup *sg; 2534 int sg_id; 2535 2536 sg_id = 0; 2537 2538 PCM_SG_LOCKASSERT(MA_OWNED); 2539 2540 if (c->sm != NULL) { 2541 sm = c->sm; 2542 sg = sm->parent; 2543 c->sm = NULL; 2544 2545 KASSERT(sg != NULL, ("syncmember has null parent")); 2546 2547 SLIST_REMOVE(&sg->members, sm, pcmchan_syncmember, link); 2548 free(sm, M_DEVBUF); 2549 2550 if (SLIST_EMPTY(&sg->members)) { 2551 SLIST_REMOVE(&snd_pcm_syncgroups, sg, pcmchan_syncgroup, link); 2552 sg_id = sg->id; 2553 free(sg, M_DEVBUF); 2554 } 2555 } 2556 2557 return sg_id; 2558 } 2559 2560 #ifdef OSSV4_EXPERIMENT 2561 int 2562 chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak) 2563 { 2564 CHN_LOCKASSERT(c); 2565 return CHANNEL_GETPEAKS(c->methods, c->devinfo, lpeak, rpeak); 2566 } 2567 #endif 2568