1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012-2021 Ruslan Bukin <br@bsdpad.com> 5 * Copyright (c) 2023-2024 Florian Walpen <dev@submerge.ch> 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 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /* 31 * RME HDSPe driver for FreeBSD (pcm-part). 32 * Supported cards: AIO, RayDAT. 33 */ 34 35 #include <dev/sound/pcm/sound.h> 36 #include <dev/sound/pci/hdspe.h> 37 #include <dev/sound/chip.h> 38 39 #include <dev/pci/pcireg.h> 40 #include <dev/pci/pcivar.h> 41 42 #include <mixer_if.h> 43 44 #define HDSPE_MATRIX_MAX 8 45 46 struct hdspe_latency { 47 uint32_t n; 48 uint32_t period; 49 float ms; 50 }; 51 52 static struct hdspe_latency latency_map[] = { 53 { 7, 32, 0.7 }, 54 { 0, 64, 1.5 }, 55 { 1, 128, 3 }, 56 { 2, 256, 6 }, 57 { 3, 512, 12 }, 58 { 4, 1024, 23 }, 59 { 5, 2048, 46 }, 60 { 6, 4096, 93 }, 61 62 { 0, 0, 0 }, 63 }; 64 65 struct hdspe_rate { 66 uint32_t speed; 67 uint32_t reg; 68 }; 69 70 static struct hdspe_rate rate_map[] = { 71 { 32000, (HDSPE_FREQ_32000) }, 72 { 44100, (HDSPE_FREQ_44100) }, 73 { 48000, (HDSPE_FREQ_48000) }, 74 { 64000, (HDSPE_FREQ_32000 | HDSPE_FREQ_DOUBLE) }, 75 { 88200, (HDSPE_FREQ_44100 | HDSPE_FREQ_DOUBLE) }, 76 { 96000, (HDSPE_FREQ_48000 | HDSPE_FREQ_DOUBLE) }, 77 { 128000, (HDSPE_FREQ_32000 | HDSPE_FREQ_QUAD) }, 78 { 176400, (HDSPE_FREQ_44100 | HDSPE_FREQ_QUAD) }, 79 { 192000, (HDSPE_FREQ_48000 | HDSPE_FREQ_QUAD) }, 80 81 { 0, 0 }, 82 }; 83 84 static uint32_t 85 hdspe_channel_play_ports(struct hdspe_channel *hc) 86 { 87 return (hc->ports & (HDSPE_CHAN_AIO_ALL | HDSPE_CHAN_RAY_ALL)); 88 } 89 90 static uint32_t 91 hdspe_channel_rec_ports(struct hdspe_channel *hc) 92 { 93 return (hc->ports & (HDSPE_CHAN_AIO_ALL_REC | HDSPE_CHAN_RAY_ALL)); 94 } 95 96 static unsigned int 97 hdspe_adat_width(uint32_t speed) 98 { 99 if (speed > 96000) 100 return (2); 101 if (speed > 48000) 102 return (4); 103 return (8); 104 } 105 106 static uint32_t 107 hdspe_port_first(uint32_t ports) 108 { 109 return (ports & (~(ports - 1))); /* Extract first bit set. */ 110 } 111 112 static uint32_t 113 hdspe_port_first_row(uint32_t ports) 114 { 115 uint32_t ends; 116 117 /* Restrict ports to one set with contiguous slots. */ 118 if (ports & HDSPE_CHAN_AIO_LINE) 119 ports = HDSPE_CHAN_AIO_LINE; /* Gap in the AIO slots here. */ 120 else if (ports & HDSPE_CHAN_AIO_ALL) 121 ports &= HDSPE_CHAN_AIO_ALL; /* Rest of the AIO slots. */ 122 else if (ports & HDSPE_CHAN_RAY_ALL) 123 ports &= HDSPE_CHAN_RAY_ALL; /* All RayDAT slots. */ 124 125 /* Ends of port rows are followed by a port which is not in the set. */ 126 ends = ports & (~(ports >> 1)); 127 /* First row of contiguous ports ends in the first row end. */ 128 return (ports & (ends ^ (ends - 1))); 129 } 130 131 static unsigned int 132 hdspe_channel_count(uint32_t ports, uint32_t adat_width) 133 { 134 unsigned int count = 0; 135 136 if (ports & HDSPE_CHAN_AIO_ALL) { 137 /* AIO ports. */ 138 if (ports & HDSPE_CHAN_AIO_LINE) 139 count += 2; 140 if (ports & HDSPE_CHAN_AIO_PHONE) 141 count += 2; 142 if (ports & HDSPE_CHAN_AIO_AES) 143 count += 2; 144 if (ports & HDSPE_CHAN_AIO_SPDIF) 145 count += 2; 146 if (ports & HDSPE_CHAN_AIO_ADAT) 147 count += adat_width; 148 } else if (ports & HDSPE_CHAN_RAY_ALL) { 149 /* RayDAT ports. */ 150 if (ports & HDSPE_CHAN_RAY_AES) 151 count += 2; 152 if (ports & HDSPE_CHAN_RAY_SPDIF) 153 count += 2; 154 if (ports & HDSPE_CHAN_RAY_ADAT1) 155 count += adat_width; 156 if (ports & HDSPE_CHAN_RAY_ADAT2) 157 count += adat_width; 158 if (ports & HDSPE_CHAN_RAY_ADAT3) 159 count += adat_width; 160 if (ports & HDSPE_CHAN_RAY_ADAT4) 161 count += adat_width; 162 } 163 164 return (count); 165 } 166 167 static unsigned int 168 hdspe_channel_offset(uint32_t subset, uint32_t ports, unsigned int adat_width) 169 { 170 uint32_t preceding; 171 172 /* Make sure we have a subset of ports. */ 173 subset &= ports; 174 /* Include all ports preceding the first one of the subset. */ 175 preceding = ports & (~subset & (subset - 1)); 176 177 if (preceding & HDSPE_CHAN_AIO_ALL) 178 preceding &= HDSPE_CHAN_AIO_ALL; /* Contiguous AIO slots. */ 179 else if (preceding & HDSPE_CHAN_RAY_ALL) 180 preceding &= HDSPE_CHAN_RAY_ALL; /* Contiguous RayDAT slots. */ 181 182 return (hdspe_channel_count(preceding, adat_width)); 183 } 184 185 static unsigned int 186 hdspe_port_slot_offset(uint32_t port, unsigned int adat_width) 187 { 188 /* Exctract the first port (lowest bit) if set of ports. */ 189 switch (hdspe_port_first(port)) { 190 /* AIO ports */ 191 case HDSPE_CHAN_AIO_LINE: 192 return (0); 193 case HDSPE_CHAN_AIO_PHONE: 194 return (6); 195 case HDSPE_CHAN_AIO_AES: 196 return (8); 197 case HDSPE_CHAN_AIO_SPDIF: 198 return (10); 199 case HDSPE_CHAN_AIO_ADAT: 200 return (12); 201 202 /* RayDAT ports */ 203 case HDSPE_CHAN_RAY_AES: 204 return (0); 205 case HDSPE_CHAN_RAY_SPDIF: 206 return (2); 207 case HDSPE_CHAN_RAY_ADAT1: 208 return (4); 209 case HDSPE_CHAN_RAY_ADAT2: 210 return (4 + adat_width); 211 case HDSPE_CHAN_RAY_ADAT3: 212 return (4 + 2 * adat_width); 213 case HDSPE_CHAN_RAY_ADAT4: 214 return (4 + 3 * adat_width); 215 default: 216 return (0); 217 } 218 } 219 220 static unsigned int 221 hdspe_port_slot_width(uint32_t ports, unsigned int adat_width) 222 { 223 uint32_t row; 224 225 /* Count number of contiguous slots from the first physical port. */ 226 row = hdspe_port_first_row(ports); 227 return (hdspe_channel_count(row, adat_width)); 228 } 229 230 static int 231 hdspe_hw_mixer(struct sc_chinfo *ch, unsigned int dst, 232 unsigned int src, unsigned short data) 233 { 234 struct sc_pcminfo *scp; 235 struct sc_info *sc; 236 int offs; 237 238 scp = ch->parent; 239 sc = scp->sc; 240 241 offs = 0; 242 if (ch->dir == PCMDIR_PLAY) 243 offs = 64; 244 245 hdspe_write_4(sc, HDSPE_MIXER_BASE + 246 ((offs + src + 128 * dst) * sizeof(uint32_t)), 247 data & 0xFFFF); 248 249 return (0); 250 }; 251 252 static int 253 hdspechan_setgain(struct sc_chinfo *ch) 254 { 255 struct sc_info *sc; 256 uint32_t port, ports; 257 unsigned int slot, end_slot; 258 unsigned short volume; 259 260 sc = ch->parent->sc; 261 262 /* Iterate through all physical ports of the channel. */ 263 ports = ch->ports; 264 port = hdspe_port_first(ports); 265 while (port != 0) { 266 /* Get slot range of the physical port. */ 267 slot = 268 hdspe_port_slot_offset(port, hdspe_adat_width(sc->speed)); 269 end_slot = slot + 270 hdspe_port_slot_width(port, hdspe_adat_width(sc->speed)); 271 272 /* Treat first slot as left channel. */ 273 volume = ch->lvol * HDSPE_MAX_GAIN / 100; 274 for (; slot < end_slot; slot++) { 275 hdspe_hw_mixer(ch, slot, slot, volume); 276 /* Subsequent slots all get the right channel volume. */ 277 volume = ch->rvol * HDSPE_MAX_GAIN / 100; 278 } 279 280 ports &= ~port; 281 port = hdspe_port_first(ports); 282 } 283 284 return (0); 285 } 286 287 static int 288 hdspemixer_init(struct snd_mixer *m) 289 { 290 struct sc_pcminfo *scp; 291 struct sc_info *sc; 292 int mask; 293 294 scp = mix_getdevinfo(m); 295 sc = scp->sc; 296 if (sc == NULL) 297 return (-1); 298 299 mask = SOUND_MASK_PCM; 300 301 if (hdspe_channel_play_ports(scp->hc)) 302 mask |= SOUND_MASK_VOLUME; 303 304 if (hdspe_channel_rec_ports(scp->hc)) 305 mask |= SOUND_MASK_RECLEV; 306 307 snd_mtxlock(sc->lock); 308 pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL); 309 mix_setdevs(m, mask); 310 snd_mtxunlock(sc->lock); 311 312 return (0); 313 } 314 315 static int 316 hdspemixer_set(struct snd_mixer *m, unsigned dev, 317 unsigned left, unsigned right) 318 { 319 struct sc_pcminfo *scp; 320 struct sc_chinfo *ch; 321 int i; 322 323 scp = mix_getdevinfo(m); 324 325 #if 0 326 device_printf(scp->dev, "hdspemixer_set() %d %d\n", 327 left, right); 328 #endif 329 330 for (i = 0; i < scp->chnum; i++) { 331 ch = &scp->chan[i]; 332 if ((dev == SOUND_MIXER_VOLUME && ch->dir == PCMDIR_PLAY) || 333 (dev == SOUND_MIXER_RECLEV && ch->dir == PCMDIR_REC)) { 334 ch->lvol = left; 335 ch->rvol = right; 336 if (ch->run) 337 hdspechan_setgain(ch); 338 } 339 } 340 341 return (0); 342 } 343 344 static kobj_method_t hdspemixer_methods[] = { 345 KOBJMETHOD(mixer_init, hdspemixer_init), 346 KOBJMETHOD(mixer_set, hdspemixer_set), 347 KOBJMETHOD_END 348 }; 349 MIXER_DECLARE(hdspemixer); 350 351 static void 352 hdspechan_enable(struct sc_chinfo *ch, int value) 353 { 354 struct sc_pcminfo *scp; 355 struct sc_info *sc; 356 uint32_t row, ports; 357 int reg; 358 unsigned int slot, end_slot; 359 360 scp = ch->parent; 361 sc = scp->sc; 362 363 if (ch->dir == PCMDIR_PLAY) 364 reg = HDSPE_OUT_ENABLE_BASE; 365 else 366 reg = HDSPE_IN_ENABLE_BASE; 367 368 ch->run = value; 369 370 /* Iterate through rows of ports with contiguous slots. */ 371 ports = ch->ports; 372 row = hdspe_port_first_row(ports); 373 while (row != 0) { 374 slot = 375 hdspe_port_slot_offset(row, hdspe_adat_width(sc->speed)); 376 end_slot = slot + 377 hdspe_port_slot_width(row, hdspe_adat_width(sc->speed)); 378 379 for (; slot < end_slot; slot++) { 380 hdspe_write_1(sc, reg + (4 * slot), value); 381 } 382 383 ports &= ~row; 384 row = hdspe_port_first_row(ports); 385 } 386 } 387 388 static int 389 hdspe_running(struct sc_info *sc) 390 { 391 struct sc_pcminfo *scp; 392 struct sc_chinfo *ch; 393 device_t *devlist; 394 int devcount; 395 int i, j; 396 int err; 397 398 if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0) 399 goto bad; 400 401 for (i = 0; i < devcount; i++) { 402 scp = device_get_ivars(devlist[i]); 403 for (j = 0; j < scp->chnum; j++) { 404 ch = &scp->chan[j]; 405 if (ch->run) 406 goto bad; 407 } 408 } 409 410 free(devlist, M_TEMP); 411 412 return (0); 413 bad: 414 415 #if 0 416 device_printf(sc->dev, "hdspe is running\n"); 417 #endif 418 419 free(devlist, M_TEMP); 420 421 return (1); 422 } 423 424 static void 425 hdspe_start_audio(struct sc_info *sc) 426 { 427 428 sc->ctrl_register |= (HDSPE_AUDIO_INT_ENABLE | HDSPE_ENABLE); 429 hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register); 430 } 431 432 static void 433 hdspe_stop_audio(struct sc_info *sc) 434 { 435 436 if (hdspe_running(sc) == 1) 437 return; 438 439 sc->ctrl_register &= ~(HDSPE_AUDIO_INT_ENABLE | HDSPE_ENABLE); 440 hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register); 441 } 442 443 static void 444 buffer_mux_write(uint32_t *dma, uint32_t *pcm, unsigned int pos, 445 unsigned int samples, unsigned int slots, unsigned int channels) 446 { 447 int slot; 448 449 for (; samples > 0; samples--) { 450 for (slot = 0; slot < slots; slot++) { 451 dma[slot * HDSPE_CHANBUF_SAMPLES + pos] = 452 pcm[pos * channels + slot]; 453 } 454 pos = (pos + 1) % HDSPE_CHANBUF_SAMPLES; 455 } 456 } 457 458 static void 459 buffer_mux_port(uint32_t *dma, uint32_t *pcm, uint32_t subset, uint32_t ports, 460 unsigned int pos, unsigned int samples, unsigned int adat_width, 461 unsigned int pcm_width) 462 { 463 unsigned int slot_offset, slots; 464 unsigned int channels, chan_pos; 465 466 /* Translate DMA slot offset to DMA buffer offset. */ 467 slot_offset = hdspe_port_slot_offset(subset, adat_width); 468 dma += slot_offset * HDSPE_CHANBUF_SAMPLES; 469 470 /* Channel position of the port subset and total number of channels. */ 471 chan_pos = hdspe_channel_offset(subset, ports, pcm_width); 472 pcm += chan_pos; 473 channels = hdspe_channel_count(ports, pcm_width); 474 475 /* Only copy as much as supported by both hardware and pcm channel. */ 476 slots = hdspe_port_slot_width(subset, MIN(adat_width, pcm_width)); 477 478 /* Let the compiler inline and loop unroll common cases. */ 479 if (slots == 2) 480 buffer_mux_write(dma, pcm, pos, samples, 2, channels); 481 else if (slots == 4) 482 buffer_mux_write(dma, pcm, pos, samples, 4, channels); 483 else if (slots == 8) 484 buffer_mux_write(dma, pcm, pos, samples, 8, channels); 485 else 486 buffer_mux_write(dma, pcm, pos, samples, slots, channels); 487 } 488 489 static void 490 buffer_demux_read(uint32_t *dma, uint32_t *pcm, unsigned int pos, 491 unsigned int samples, unsigned int slots, unsigned int channels) 492 { 493 int slot; 494 495 for (; samples > 0; samples--) { 496 for (slot = 0; slot < slots; slot++) { 497 pcm[pos * channels + slot] = 498 dma[slot * HDSPE_CHANBUF_SAMPLES + pos]; 499 } 500 pos = (pos + 1) % HDSPE_CHANBUF_SAMPLES; 501 } 502 } 503 504 static void 505 buffer_demux_port(uint32_t *dma, uint32_t *pcm, uint32_t subset, uint32_t ports, 506 unsigned int pos, unsigned int samples, unsigned int adat_width, 507 unsigned int pcm_width) 508 { 509 unsigned int slot_offset, slots; 510 unsigned int channels, chan_pos; 511 512 /* Translate port slot offset to DMA buffer offset. */ 513 slot_offset = hdspe_port_slot_offset(subset, adat_width); 514 dma += slot_offset * HDSPE_CHANBUF_SAMPLES; 515 516 /* Channel position of the port subset and total number of channels. */ 517 chan_pos = hdspe_channel_offset(subset, ports, pcm_width); 518 pcm += chan_pos; 519 channels = hdspe_channel_count(ports, pcm_width); 520 521 /* Only copy as much as supported by both hardware and pcm channel. */ 522 slots = hdspe_port_slot_width(subset, MIN(adat_width, pcm_width)); 523 524 /* Let the compiler inline and loop unroll common cases. */ 525 if (slots == 2) 526 buffer_demux_read(dma, pcm, pos, samples, 2, channels); 527 else if (slots == 4) 528 buffer_demux_read(dma, pcm, pos, samples, 4, channels); 529 else if (slots == 8) 530 buffer_demux_read(dma, pcm, pos, samples, 8, channels); 531 else 532 buffer_demux_read(dma, pcm, pos, samples, slots, channels); 533 } 534 535 536 /* Copy data between DMA and PCM buffers. */ 537 static void 538 buffer_copy(struct sc_chinfo *ch) 539 { 540 struct sc_pcminfo *scp; 541 struct sc_info *sc; 542 uint32_t row, ports; 543 unsigned int pos; 544 unsigned int n; 545 unsigned int adat_width, pcm_width; 546 547 scp = ch->parent; 548 sc = scp->sc; 549 550 n = AFMT_CHANNEL(ch->format); /* n channels */ 551 552 /* Let pcm formats differ from current hardware ADAT width. */ 553 adat_width = hdspe_adat_width(sc->speed); 554 if (n == hdspe_channel_count(ch->ports, 2)) 555 pcm_width = 2; 556 else if (n == hdspe_channel_count(ch->ports, 4)) 557 pcm_width = 4; 558 else 559 pcm_width = 8; 560 561 if (ch->dir == PCMDIR_PLAY) 562 pos = sndbuf_getreadyptr(ch->buffer); 563 else 564 pos = sndbuf_getfreeptr(ch->buffer); 565 566 pos /= 4; /* Bytes per sample. */ 567 pos /= n; /* Destination buffer n-times smaller. */ 568 569 /* Iterate through rows of ports with contiguous slots. */ 570 ports = ch->ports; 571 if (pcm_width == adat_width) 572 row = hdspe_port_first_row(ports); 573 else 574 row = hdspe_port_first(ports); 575 576 while (row != 0) { 577 if (ch->dir == PCMDIR_PLAY) 578 buffer_mux_port(sc->pbuf, ch->data, row, ch->ports, pos, 579 sc->period * 2, adat_width, pcm_width); 580 else 581 buffer_demux_port(sc->rbuf, ch->data, row, ch->ports, 582 pos, sc->period * 2, adat_width, pcm_width); 583 584 ports &= ~row; 585 if (pcm_width == adat_width) 586 row = hdspe_port_first_row(ports); 587 else 588 row = hdspe_port_first(ports); 589 } 590 } 591 592 static int 593 clean(struct sc_chinfo *ch) 594 { 595 struct sc_pcminfo *scp; 596 struct sc_info *sc; 597 uint32_t *buf; 598 uint32_t row, ports; 599 unsigned int offset, slots; 600 601 scp = ch->parent; 602 sc = scp->sc; 603 buf = sc->rbuf; 604 605 if (ch->dir == PCMDIR_PLAY) 606 buf = sc->pbuf; 607 608 /* Iterate through rows of ports with contiguous slots. */ 609 ports = ch->ports; 610 row = hdspe_port_first_row(ports); 611 while (row != 0) { 612 offset = hdspe_port_slot_offset(row, 613 hdspe_adat_width(sc->speed)); 614 slots = hdspe_port_slot_width(row, hdspe_adat_width(sc->speed)); 615 616 bzero(buf + offset * HDSPE_CHANBUF_SAMPLES, 617 slots * HDSPE_CHANBUF_SIZE); 618 619 ports &= ~row; 620 row = hdspe_port_first_row(ports); 621 } 622 623 return (0); 624 } 625 626 /* Channel interface. */ 627 static void * 628 hdspechan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 629 struct pcm_channel *c, int dir) 630 { 631 struct sc_pcminfo *scp; 632 struct sc_chinfo *ch; 633 struct sc_info *sc; 634 int num; 635 636 scp = devinfo; 637 sc = scp->sc; 638 639 snd_mtxlock(sc->lock); 640 num = scp->chnum; 641 642 ch = &scp->chan[num]; 643 644 if (dir == PCMDIR_PLAY) 645 ch->ports = hdspe_channel_play_ports(scp->hc); 646 else 647 ch->ports = hdspe_channel_rec_ports(scp->hc); 648 649 ch->run = 0; 650 ch->lvol = 0; 651 ch->rvol = 0; 652 653 /* Support all possible ADAT widths as channel formats. */ 654 ch->cap_fmts[0] = 655 SND_FORMAT(AFMT_S32_LE, hdspe_channel_count(ch->ports, 2), 0); 656 ch->cap_fmts[1] = 657 SND_FORMAT(AFMT_S32_LE, hdspe_channel_count(ch->ports, 4), 0); 658 ch->cap_fmts[2] = 659 SND_FORMAT(AFMT_S32_LE, hdspe_channel_count(ch->ports, 8), 0); 660 ch->cap_fmts[3] = 0; 661 ch->caps = malloc(sizeof(struct pcmchan_caps), M_HDSPE, M_NOWAIT); 662 *(ch->caps) = (struct pcmchan_caps) {32000, 192000, ch->cap_fmts, 0}; 663 664 /* Allocate maximum buffer size. */ 665 ch->size = HDSPE_CHANBUF_SIZE * hdspe_channel_count(ch->ports, 8); 666 ch->data = malloc(ch->size, M_HDSPE, M_NOWAIT); 667 668 ch->buffer = b; 669 ch->channel = c; 670 ch->parent = scp; 671 672 ch->dir = dir; 673 674 snd_mtxunlock(sc->lock); 675 676 if (sndbuf_setup(ch->buffer, ch->data, ch->size) != 0) { 677 device_printf(scp->dev, "Can't setup sndbuf.\n"); 678 return (NULL); 679 } 680 681 return (ch); 682 } 683 684 static int 685 hdspechan_trigger(kobj_t obj, void *data, int go) 686 { 687 struct sc_pcminfo *scp; 688 struct sc_chinfo *ch; 689 struct sc_info *sc; 690 691 ch = data; 692 scp = ch->parent; 693 sc = scp->sc; 694 695 snd_mtxlock(sc->lock); 696 switch (go) { 697 case PCMTRIG_START: 698 #if 0 699 device_printf(scp->dev, "hdspechan_trigger(): start\n"); 700 #endif 701 hdspechan_enable(ch, 1); 702 hdspechan_setgain(ch); 703 hdspe_start_audio(sc); 704 break; 705 706 case PCMTRIG_STOP: 707 case PCMTRIG_ABORT: 708 #if 0 709 device_printf(scp->dev, "hdspechan_trigger(): stop or abort\n"); 710 #endif 711 clean(ch); 712 hdspechan_enable(ch, 0); 713 hdspe_stop_audio(sc); 714 break; 715 716 case PCMTRIG_EMLDMAWR: 717 case PCMTRIG_EMLDMARD: 718 if(ch->run) 719 buffer_copy(ch); 720 break; 721 } 722 723 snd_mtxunlock(sc->lock); 724 725 return (0); 726 } 727 728 static uint32_t 729 hdspechan_getptr(kobj_t obj, void *data) 730 { 731 struct sc_pcminfo *scp; 732 struct sc_chinfo *ch; 733 struct sc_info *sc; 734 uint32_t ret, pos; 735 736 ch = data; 737 scp = ch->parent; 738 sc = scp->sc; 739 740 snd_mtxlock(sc->lock); 741 ret = hdspe_read_2(sc, HDSPE_STATUS_REG); 742 snd_mtxunlock(sc->lock); 743 744 pos = ret & HDSPE_BUF_POSITION_MASK; 745 pos *= AFMT_CHANNEL(ch->format); /* Hardbuf with multiple channels. */ 746 747 return (pos); 748 } 749 750 static int 751 hdspechan_free(kobj_t obj, void *data) 752 { 753 struct sc_pcminfo *scp; 754 struct sc_chinfo *ch; 755 struct sc_info *sc; 756 757 ch = data; 758 scp = ch->parent; 759 sc = scp->sc; 760 761 #if 0 762 device_printf(scp->dev, "hdspechan_free()\n"); 763 #endif 764 765 snd_mtxlock(sc->lock); 766 if (ch->data != NULL) { 767 free(ch->data, M_HDSPE); 768 ch->data = NULL; 769 } 770 if (ch->caps != NULL) { 771 free(ch->caps, M_HDSPE); 772 ch->caps = NULL; 773 } 774 snd_mtxunlock(sc->lock); 775 776 return (0); 777 } 778 779 static int 780 hdspechan_setformat(kobj_t obj, void *data, uint32_t format) 781 { 782 struct sc_chinfo *ch; 783 784 ch = data; 785 786 #if 0 787 struct sc_pcminfo *scp = ch->parent; 788 device_printf(scp->dev, "hdspechan_setformat(%d)\n", format); 789 #endif 790 791 ch->format = format; 792 793 return (0); 794 } 795 796 static uint32_t 797 hdspechan_setspeed(kobj_t obj, void *data, uint32_t speed) 798 { 799 struct sc_pcminfo *scp; 800 struct hdspe_rate *hr; 801 struct sc_chinfo *ch; 802 struct sc_info *sc; 803 long long period; 804 int threshold; 805 int i; 806 807 ch = data; 808 scp = ch->parent; 809 sc = scp->sc; 810 hr = NULL; 811 812 #if 0 813 device_printf(scp->dev, "hdspechan_setspeed(%d)\n", speed); 814 #endif 815 816 if (hdspe_running(sc) == 1) 817 goto end; 818 819 if (sc->force_speed > 0) 820 speed = sc->force_speed; 821 822 /* First look for equal frequency. */ 823 for (i = 0; rate_map[i].speed != 0; i++) { 824 if (rate_map[i].speed == speed) 825 hr = &rate_map[i]; 826 } 827 828 /* If no match, just find nearest. */ 829 if (hr == NULL) { 830 for (i = 0; rate_map[i].speed != 0; i++) { 831 hr = &rate_map[i]; 832 threshold = hr->speed + ((rate_map[i + 1].speed != 0) ? 833 ((rate_map[i + 1].speed - hr->speed) >> 1) : 0); 834 if (speed < threshold) 835 break; 836 } 837 } 838 839 switch (sc->type) { 840 case HDSPE_RAYDAT: 841 case HDSPE_AIO: 842 period = HDSPE_FREQ_AIO; 843 break; 844 default: 845 /* Unsupported card. */ 846 goto end; 847 } 848 849 /* Write frequency on the device. */ 850 sc->ctrl_register &= ~HDSPE_FREQ_MASK; 851 sc->ctrl_register |= hr->reg; 852 hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register); 853 854 speed = hr->speed; 855 if (speed > 96000) 856 speed /= 4; 857 else if (speed > 48000) 858 speed /= 2; 859 860 /* Set DDS value. */ 861 period /= speed; 862 hdspe_write_4(sc, HDSPE_FREQ_REG, period); 863 864 sc->speed = hr->speed; 865 end: 866 867 return (sc->speed); 868 } 869 870 static uint32_t 871 hdspechan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) 872 { 873 struct hdspe_latency *hl; 874 struct sc_pcminfo *scp; 875 struct sc_chinfo *ch; 876 struct sc_info *sc; 877 int threshold; 878 int i; 879 880 ch = data; 881 scp = ch->parent; 882 sc = scp->sc; 883 hl = NULL; 884 885 #if 0 886 device_printf(scp->dev, "hdspechan_setblocksize(%d)\n", blocksize); 887 #endif 888 889 if (hdspe_running(sc) == 1) 890 goto end; 891 892 if (blocksize > HDSPE_LAT_BYTES_MAX) 893 blocksize = HDSPE_LAT_BYTES_MAX; 894 else if (blocksize < HDSPE_LAT_BYTES_MIN) 895 blocksize = HDSPE_LAT_BYTES_MIN; 896 897 blocksize /= 4 /* samples */; 898 899 if (sc->force_period > 0) 900 blocksize = sc->force_period; 901 902 /* First look for equal latency. */ 903 for (i = 0; latency_map[i].period != 0; i++) { 904 if (latency_map[i].period == blocksize) 905 hl = &latency_map[i]; 906 } 907 908 /* If no match, just find nearest. */ 909 if (hl == NULL) { 910 for (i = 0; latency_map[i].period != 0; i++) { 911 hl = &latency_map[i]; 912 threshold = hl->period + ((latency_map[i + 1].period != 0) ? 913 ((latency_map[i + 1].period - hl->period) >> 1) : 0); 914 if (blocksize < threshold) 915 break; 916 } 917 } 918 919 snd_mtxlock(sc->lock); 920 sc->ctrl_register &= ~HDSPE_LAT_MASK; 921 sc->ctrl_register |= hdspe_encode_latency(hl->n); 922 hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register); 923 sc->period = hl->period; 924 snd_mtxunlock(sc->lock); 925 926 #if 0 927 device_printf(scp->dev, "New period=%d\n", sc->period); 928 #endif 929 930 sndbuf_resize(ch->buffer, 931 (HDSPE_CHANBUF_SIZE * AFMT_CHANNEL(ch->format)) / (sc->period * 4), 932 (sc->period * 4)); 933 end: 934 935 return (sndbuf_getblksz(ch->buffer)); 936 } 937 938 static uint32_t hdspe_bkp_fmt[] = { 939 SND_FORMAT(AFMT_S32_LE, 2, 0), 940 0 941 }; 942 943 static struct pcmchan_caps hdspe_bkp_caps = {32000, 192000, hdspe_bkp_fmt, 0}; 944 945 static struct pcmchan_caps * 946 hdspechan_getcaps(kobj_t obj, void *data) 947 { 948 struct sc_chinfo *ch; 949 950 ch = data; 951 952 #if 0 953 struct sc_pcminfo *scl = ch->parent; 954 device_printf(scp->dev, "hdspechan_getcaps()\n"); 955 #endif 956 957 if (ch->caps != NULL) 958 return (ch->caps); 959 960 return (&hdspe_bkp_caps); 961 } 962 963 static kobj_method_t hdspechan_methods[] = { 964 KOBJMETHOD(channel_init, hdspechan_init), 965 KOBJMETHOD(channel_free, hdspechan_free), 966 KOBJMETHOD(channel_setformat, hdspechan_setformat), 967 KOBJMETHOD(channel_setspeed, hdspechan_setspeed), 968 KOBJMETHOD(channel_setblocksize, hdspechan_setblocksize), 969 KOBJMETHOD(channel_trigger, hdspechan_trigger), 970 KOBJMETHOD(channel_getptr, hdspechan_getptr), 971 KOBJMETHOD(channel_getcaps, hdspechan_getcaps), 972 KOBJMETHOD_END 973 }; 974 CHANNEL_DECLARE(hdspechan); 975 976 static int 977 hdspe_pcm_probe(device_t dev) 978 { 979 980 #if 0 981 device_printf(dev,"hdspe_pcm_probe()\n"); 982 #endif 983 984 return (0); 985 } 986 987 static uint32_t 988 hdspe_pcm_intr(struct sc_pcminfo *scp) 989 { 990 struct sc_chinfo *ch; 991 struct sc_info *sc; 992 int i; 993 994 sc = scp->sc; 995 996 for (i = 0; i < scp->chnum; i++) { 997 ch = &scp->chan[i]; 998 snd_mtxunlock(sc->lock); 999 chn_intr(ch->channel); 1000 snd_mtxlock(sc->lock); 1001 } 1002 1003 return (0); 1004 } 1005 1006 static int 1007 hdspe_pcm_attach(device_t dev) 1008 { 1009 char status[SND_STATUSLEN]; 1010 struct sc_pcminfo *scp; 1011 const char *buf; 1012 uint32_t pcm_flags; 1013 int err; 1014 int play, rec; 1015 1016 scp = device_get_ivars(dev); 1017 scp->ih = &hdspe_pcm_intr; 1018 1019 if (scp->hc->ports & HDSPE_CHAN_AIO_ALL) 1020 buf = "AIO"; 1021 else if (scp->hc->ports & HDSPE_CHAN_RAY_ALL) 1022 buf = "RayDAT"; 1023 else 1024 buf = "?"; 1025 device_set_descf(dev, "HDSPe %s [%s]", buf, scp->hc->descr); 1026 1027 /* 1028 * We don't register interrupt handler with snd_setup_intr 1029 * in pcm device. Mark pcm device as MPSAFE manually. 1030 */ 1031 pcm_flags = pcm_getflags(dev) | SD_F_MPSAFE; 1032 if (hdspe_channel_count(scp->hc->ports, 8) > HDSPE_MATRIX_MAX) 1033 /* Disable vchan conversion, too many channels. */ 1034 pcm_flags |= SD_F_BITPERFECT; 1035 pcm_setflags(dev, pcm_flags); 1036 1037 play = (hdspe_channel_play_ports(scp->hc)) ? 1 : 0; 1038 rec = (hdspe_channel_rec_ports(scp->hc)) ? 1 : 0; 1039 err = pcm_register(dev, scp, play, rec); 1040 if (err) { 1041 device_printf(dev, "Can't register pcm.\n"); 1042 return (ENXIO); 1043 } 1044 1045 scp->chnum = 0; 1046 if (play) { 1047 pcm_addchan(dev, PCMDIR_PLAY, &hdspechan_class, scp); 1048 scp->chnum++; 1049 } 1050 1051 if (rec) { 1052 pcm_addchan(dev, PCMDIR_REC, &hdspechan_class, scp); 1053 scp->chnum++; 1054 } 1055 1056 snprintf(status, SND_STATUSLEN, "port 0x%jx irq %jd on %s", 1057 rman_get_start(scp->sc->cs), 1058 rman_get_start(scp->sc->irq), 1059 device_get_nameunit(device_get_parent(dev))); 1060 pcm_setstatus(dev, status); 1061 1062 mixer_init(dev, &hdspemixer_class, scp); 1063 1064 return (0); 1065 } 1066 1067 static int 1068 hdspe_pcm_detach(device_t dev) 1069 { 1070 int err; 1071 1072 err = pcm_unregister(dev); 1073 if (err) { 1074 device_printf(dev, "Can't unregister device.\n"); 1075 return (err); 1076 } 1077 1078 return (0); 1079 } 1080 1081 static device_method_t hdspe_pcm_methods[] = { 1082 DEVMETHOD(device_probe, hdspe_pcm_probe), 1083 DEVMETHOD(device_attach, hdspe_pcm_attach), 1084 DEVMETHOD(device_detach, hdspe_pcm_detach), 1085 { 0, 0 } 1086 }; 1087 1088 static driver_t hdspe_pcm_driver = { 1089 "pcm", 1090 hdspe_pcm_methods, 1091 PCM_SOFTC_SIZE, 1092 }; 1093 1094 DRIVER_MODULE(snd_hdspe_pcm, hdspe, hdspe_pcm_driver, 0, 0); 1095 MODULE_DEPEND(snd_hdspe, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 1096 MODULE_VERSION(snd_hdspe, 1); 1097