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