1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012-2016 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. 32 * Supported cards: AIO, RayDAT. 33 */ 34 35 #include <sys/types.h> 36 #include <sys/sysctl.h> 37 38 #include <dev/sound/pcm/sound.h> 39 #include <dev/sound/pci/hdspe.h> 40 41 #include <dev/pci/pcireg.h> 42 #include <dev/pci/pcivar.h> 43 44 #include <mixer_if.h> 45 46 static bool hdspe_unified_pcm = false; 47 48 static SYSCTL_NODE(_hw, OID_AUTO, hdspe, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 49 "PCI HDSPe"); 50 51 SYSCTL_BOOL(_hw_hdspe, OID_AUTO, unified_pcm, CTLFLAG_RWTUN, 52 &hdspe_unified_pcm, 0, "Combine physical ports in one unified pcm device"); 53 54 static struct hdspe_clock_source hdspe_clock_source_table_rd[] = { 55 { "internal", 0 << 1 | 1, HDSPE_STATUS1_CLOCK(15), 0, 0 }, 56 { "word", 0 << 1 | 0, HDSPE_STATUS1_CLOCK( 0), 1 << 24, 1 << 25 }, 57 { "aes", 1 << 1 | 0, HDSPE_STATUS1_CLOCK( 1), 1 << 0, 1 << 8 }, 58 { "spdif", 2 << 1 | 0, HDSPE_STATUS1_CLOCK( 2), 1 << 1, 1 << 9 }, 59 { "adat1", 3 << 1 | 0, HDSPE_STATUS1_CLOCK( 3), 1 << 2, 1 << 10 }, 60 { "adat2", 4 << 1 | 0, HDSPE_STATUS1_CLOCK( 4), 1 << 3, 1 << 11 }, 61 { "adat3", 5 << 1 | 0, HDSPE_STATUS1_CLOCK( 5), 1 << 4, 1 << 12 }, 62 { "adat4", 6 << 1 | 0, HDSPE_STATUS1_CLOCK( 6), 1 << 5, 1 << 13 }, 63 { "tco", 9 << 1 | 0, HDSPE_STATUS1_CLOCK( 9), 1 << 26, 1 << 27 }, 64 { "sync_in", 10 << 1 | 0, HDSPE_STATUS1_CLOCK(10), 0, 0 }, 65 { NULL, 0 << 1 | 0, HDSPE_STATUS1_CLOCK( 0), 0, 0 }, 66 }; 67 68 static struct hdspe_clock_source hdspe_clock_source_table_aio[] = { 69 { "internal", 0 << 1 | 1, HDSPE_STATUS1_CLOCK(15), 0, 0 }, 70 { "word", 0 << 1 | 0, HDSPE_STATUS1_CLOCK( 0), 1 << 24, 1 << 25 }, 71 { "aes", 1 << 1 | 0, HDSPE_STATUS1_CLOCK( 1), 1 << 0, 1 << 8 }, 72 { "spdif", 2 << 1 | 0, HDSPE_STATUS1_CLOCK( 2), 1 << 1, 1 << 9 }, 73 { "adat", 3 << 1 | 0, HDSPE_STATUS1_CLOCK( 3), 1 << 2, 1 << 10 }, 74 { "tco", 9 << 1 | 0, HDSPE_STATUS1_CLOCK( 9), 1 << 26, 1 << 27 }, 75 { "sync_in", 10 << 1 | 0, HDSPE_STATUS1_CLOCK(10), 0, 0 }, 76 { NULL, 0 << 1 | 0, HDSPE_STATUS1_CLOCK( 0), 0, 0 }, 77 }; 78 79 static struct hdspe_channel chan_map_aio[] = { 80 { HDSPE_CHAN_AIO_LINE, "line" }, 81 { HDSPE_CHAN_AIO_EXT, "ext" }, 82 { HDSPE_CHAN_AIO_PHONE, "phone" }, 83 { HDSPE_CHAN_AIO_AES, "aes" }, 84 { HDSPE_CHAN_AIO_SPDIF, "s/pdif" }, 85 { HDSPE_CHAN_AIO_ADAT, "adat" }, 86 { 0, NULL }, 87 }; 88 89 static struct hdspe_channel chan_map_aio_uni[] = { 90 { HDSPE_CHAN_AIO_ALL, "all" }, 91 { 0, NULL }, 92 }; 93 94 static struct hdspe_channel chan_map_rd[] = { 95 { HDSPE_CHAN_RAY_AES, "aes" }, 96 { HDSPE_CHAN_RAY_SPDIF, "s/pdif" }, 97 { HDSPE_CHAN_RAY_ADAT1, "adat1" }, 98 { HDSPE_CHAN_RAY_ADAT2, "adat2" }, 99 { HDSPE_CHAN_RAY_ADAT3, "adat3" }, 100 { HDSPE_CHAN_RAY_ADAT4, "adat4" }, 101 { 0, NULL }, 102 }; 103 104 static struct hdspe_channel chan_map_rd_uni[] = { 105 { HDSPE_CHAN_RAY_ALL, "all" }, 106 { 0, NULL }, 107 }; 108 109 static void 110 hdspe_intr(void *p) 111 { 112 struct sc_pcminfo *scp; 113 struct sc_info *sc; 114 device_t *devlist; 115 int devcount; 116 int status; 117 int err; 118 int i; 119 120 sc = (struct sc_info *)p; 121 122 snd_mtxlock(sc->lock); 123 124 status = hdspe_read_1(sc, HDSPE_STATUS_REG); 125 if (status & HDSPE_AUDIO_IRQ_PENDING) { 126 if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0) 127 return; 128 129 for (i = 0; i < devcount; i++) { 130 scp = device_get_ivars(devlist[i]); 131 if (scp->ih != NULL) 132 scp->ih(scp); 133 } 134 135 hdspe_write_1(sc, HDSPE_INTERRUPT_ACK, 0); 136 free(devlist, M_TEMP); 137 } 138 139 snd_mtxunlock(sc->lock); 140 } 141 142 static void 143 hdspe_dmapsetmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) 144 { 145 #if 0 146 device_printf(sc->dev, "hdspe_dmapsetmap()\n"); 147 #endif 148 } 149 150 static int 151 hdspe_alloc_resources(struct sc_info *sc) 152 { 153 154 /* Allocate resource. */ 155 sc->csid = PCIR_BAR(0); 156 sc->cs = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, 157 &sc->csid, RF_ACTIVE); 158 159 if (!sc->cs) { 160 device_printf(sc->dev, "Unable to map SYS_RES_MEMORY.\n"); 161 return (ENXIO); 162 } 163 164 sc->cst = rman_get_bustag(sc->cs); 165 sc->csh = rman_get_bushandle(sc->cs); 166 167 /* Allocate interrupt resource. */ 168 sc->irqid = 0; 169 sc->irq = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &sc->irqid, 170 RF_ACTIVE | RF_SHAREABLE); 171 172 if (!sc->irq || 173 bus_setup_intr(sc->dev, sc->irq, INTR_MPSAFE | INTR_TYPE_AV, 174 NULL, hdspe_intr, sc, &sc->ih)) { 175 device_printf(sc->dev, "Unable to alloc interrupt resource.\n"); 176 return (ENXIO); 177 } 178 179 /* Allocate DMA resources. */ 180 if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(sc->dev), 181 /*alignment*/4, 182 /*boundary*/0, 183 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 184 /*highaddr*/BUS_SPACE_MAXADDR, 185 /*filter*/NULL, 186 /*filterarg*/NULL, 187 /*maxsize*/2 * HDSPE_DMASEGSIZE, 188 /*nsegments*/2, 189 /*maxsegsz*/HDSPE_DMASEGSIZE, 190 /*flags*/0, 191 /*lockfunc*/NULL, 192 /*lockarg*/NULL, 193 /*dmatag*/&sc->dmat) != 0) { 194 device_printf(sc->dev, "Unable to create dma tag.\n"); 195 return (ENXIO); 196 } 197 198 sc->bufsize = HDSPE_DMASEGSIZE; 199 200 /* pbuf (play buffer). */ 201 if (bus_dmamem_alloc(sc->dmat, (void **)&sc->pbuf, BUS_DMA_WAITOK, 202 &sc->pmap)) { 203 device_printf(sc->dev, "Can't alloc pbuf.\n"); 204 return (ENXIO); 205 } 206 207 if (bus_dmamap_load(sc->dmat, sc->pmap, sc->pbuf, sc->bufsize, 208 hdspe_dmapsetmap, sc, BUS_DMA_NOWAIT)) { 209 device_printf(sc->dev, "Can't load pbuf.\n"); 210 return (ENXIO); 211 } 212 213 /* rbuf (rec buffer). */ 214 if (bus_dmamem_alloc(sc->dmat, (void **)&sc->rbuf, BUS_DMA_WAITOK, 215 &sc->rmap)) { 216 device_printf(sc->dev, "Can't alloc rbuf.\n"); 217 return (ENXIO); 218 } 219 220 if (bus_dmamap_load(sc->dmat, sc->rmap, sc->rbuf, sc->bufsize, 221 hdspe_dmapsetmap, sc, BUS_DMA_NOWAIT)) { 222 device_printf(sc->dev, "Can't load rbuf.\n"); 223 return (ENXIO); 224 } 225 226 bzero(sc->pbuf, sc->bufsize); 227 bzero(sc->rbuf, sc->bufsize); 228 229 return (0); 230 } 231 232 static void 233 hdspe_map_dmabuf(struct sc_info *sc) 234 { 235 uint32_t paddr, raddr; 236 int i; 237 238 paddr = vtophys(sc->pbuf); 239 raddr = vtophys(sc->rbuf); 240 241 for (i = 0; i < HDSPE_MAX_SLOTS * 16; i++) { 242 hdspe_write_4(sc, HDSPE_PAGE_ADDR_BUF_OUT + 4 * i, 243 paddr + i * 4096); 244 hdspe_write_4(sc, HDSPE_PAGE_ADDR_BUF_IN + 4 * i, 245 raddr + i * 4096); 246 } 247 } 248 249 static const char * 250 hdspe_settings_input_level(uint32_t settings) 251 { 252 switch (settings & HDSPE_INPUT_LEVEL_MASK) { 253 case HDSPE_INPUT_LEVEL_LOWGAIN: 254 return ("LowGain"); 255 case HDSPE_INPUT_LEVEL_PLUS4DBU: 256 return ("+4dBu"); 257 case HDSPE_INPUT_LEVEL_MINUS10DBV: 258 return ("-10dBV"); 259 default: 260 return (NULL); 261 } 262 } 263 264 static int 265 hdspe_sysctl_input_level(SYSCTL_HANDLER_ARGS) 266 { 267 struct sc_info *sc; 268 const char *label; 269 char buf[16] = "invalid"; 270 int error; 271 uint32_t settings; 272 273 sc = oidp->oid_arg1; 274 275 /* Only available on HDSPE AIO. */ 276 if (sc->type != HDSPE_AIO) 277 return (ENXIO); 278 279 /* Extract current input level from settings register. */ 280 settings = sc->settings_register & HDSPE_INPUT_LEVEL_MASK; 281 label = hdspe_settings_input_level(settings); 282 if (label != NULL) 283 strlcpy(buf, label, sizeof(buf)); 284 285 /* Process sysctl string request. */ 286 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 287 if (error != 0 || req->newptr == NULL) 288 return (error); 289 290 /* Find input level matching the sysctl string. */ 291 label = hdspe_settings_input_level(HDSPE_INPUT_LEVEL_LOWGAIN); 292 if (strncasecmp(buf, label, sizeof(buf)) == 0) 293 settings = HDSPE_INPUT_LEVEL_LOWGAIN; 294 label = hdspe_settings_input_level(HDSPE_INPUT_LEVEL_PLUS4DBU); 295 if (strncasecmp(buf, label, sizeof(buf)) == 0) 296 settings = HDSPE_INPUT_LEVEL_PLUS4DBU; 297 label = hdspe_settings_input_level(HDSPE_INPUT_LEVEL_MINUS10DBV); 298 if (strncasecmp(buf, label, sizeof(buf)) == 0) 299 settings = HDSPE_INPUT_LEVEL_MINUS10DBV; 300 301 /* Set input level in settings register. */ 302 settings &= HDSPE_INPUT_LEVEL_MASK; 303 if (settings != (sc->settings_register & HDSPE_INPUT_LEVEL_MASK)) { 304 snd_mtxlock(sc->lock); 305 sc->settings_register &= ~HDSPE_INPUT_LEVEL_MASK; 306 sc->settings_register |= settings; 307 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register); 308 snd_mtxunlock(sc->lock); 309 } 310 return (0); 311 } 312 313 static const char * 314 hdspe_settings_output_level(uint32_t settings) 315 { 316 switch (settings & HDSPE_OUTPUT_LEVEL_MASK) { 317 case HDSPE_OUTPUT_LEVEL_HIGHGAIN: 318 return ("HighGain"); 319 case HDSPE_OUTPUT_LEVEL_PLUS4DBU: 320 return ("+4dBu"); 321 case HDSPE_OUTPUT_LEVEL_MINUS10DBV: 322 return ("-10dBV"); 323 default: 324 return (NULL); 325 } 326 } 327 328 static int 329 hdspe_sysctl_output_level(SYSCTL_HANDLER_ARGS) 330 { 331 struct sc_info *sc; 332 const char *label; 333 char buf[16] = "invalid"; 334 int error; 335 uint32_t settings; 336 337 sc = oidp->oid_arg1; 338 339 /* Only available on HDSPE AIO. */ 340 if (sc->type != HDSPE_AIO) 341 return (ENXIO); 342 343 /* Extract current output level from settings register. */ 344 settings = sc->settings_register & HDSPE_OUTPUT_LEVEL_MASK; 345 label = hdspe_settings_output_level(settings); 346 if (label != NULL) 347 strlcpy(buf, label, sizeof(buf)); 348 349 /* Process sysctl string request. */ 350 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 351 if (error != 0 || req->newptr == NULL) 352 return (error); 353 354 /* Find output level matching the sysctl string. */ 355 label = hdspe_settings_output_level(HDSPE_OUTPUT_LEVEL_HIGHGAIN); 356 if (strncasecmp(buf, label, sizeof(buf)) == 0) 357 settings = HDSPE_OUTPUT_LEVEL_HIGHGAIN; 358 label = hdspe_settings_output_level(HDSPE_OUTPUT_LEVEL_PLUS4DBU); 359 if (strncasecmp(buf, label, sizeof(buf)) == 0) 360 settings = HDSPE_OUTPUT_LEVEL_PLUS4DBU; 361 label = hdspe_settings_output_level(HDSPE_OUTPUT_LEVEL_MINUS10DBV); 362 if (strncasecmp(buf, label, sizeof(buf)) == 0) 363 settings = HDSPE_OUTPUT_LEVEL_MINUS10DBV; 364 365 /* Set output level in settings register. */ 366 settings &= HDSPE_OUTPUT_LEVEL_MASK; 367 if (settings != (sc->settings_register & HDSPE_OUTPUT_LEVEL_MASK)) { 368 snd_mtxlock(sc->lock); 369 sc->settings_register &= ~HDSPE_OUTPUT_LEVEL_MASK; 370 sc->settings_register |= settings; 371 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register); 372 snd_mtxunlock(sc->lock); 373 } 374 return (0); 375 } 376 377 static const char * 378 hdspe_settings_phones_level(uint32_t settings) 379 { 380 switch (settings & HDSPE_PHONES_LEVEL_MASK) { 381 case HDSPE_PHONES_LEVEL_HIGHGAIN: 382 return ("HighGain"); 383 case HDSPE_PHONES_LEVEL_PLUS4DBU: 384 return ("+4dBu"); 385 case HDSPE_PHONES_LEVEL_MINUS10DBV: 386 return ("-10dBV"); 387 default: 388 return (NULL); 389 } 390 } 391 392 static int 393 hdspe_sysctl_phones_level(SYSCTL_HANDLER_ARGS) 394 { 395 struct sc_info *sc; 396 const char *label; 397 char buf[16] = "invalid"; 398 int error; 399 uint32_t settings; 400 401 sc = oidp->oid_arg1; 402 403 /* Only available on HDSPE AIO. */ 404 if (sc->type != HDSPE_AIO) 405 return (ENXIO); 406 407 /* Extract current phones level from settings register. */ 408 settings = sc->settings_register & HDSPE_PHONES_LEVEL_MASK; 409 label = hdspe_settings_phones_level(settings); 410 if (label != NULL) 411 strlcpy(buf, label, sizeof(buf)); 412 413 /* Process sysctl string request. */ 414 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 415 if (error != 0 || req->newptr == NULL) 416 return (error); 417 418 /* Find phones level matching the sysctl string. */ 419 label = hdspe_settings_phones_level(HDSPE_PHONES_LEVEL_HIGHGAIN); 420 if (strncasecmp(buf, label, sizeof(buf)) == 0) 421 settings = HDSPE_PHONES_LEVEL_HIGHGAIN; 422 label = hdspe_settings_phones_level(HDSPE_PHONES_LEVEL_PLUS4DBU); 423 if (strncasecmp(buf, label, sizeof(buf)) == 0) 424 settings = HDSPE_PHONES_LEVEL_PLUS4DBU; 425 label = hdspe_settings_phones_level(HDSPE_PHONES_LEVEL_MINUS10DBV); 426 if (strncasecmp(buf, label, sizeof(buf)) == 0) 427 settings = HDSPE_PHONES_LEVEL_MINUS10DBV; 428 429 /* Set phones level in settings register. */ 430 settings &= HDSPE_PHONES_LEVEL_MASK; 431 if (settings != (sc->settings_register & HDSPE_PHONES_LEVEL_MASK)) { 432 snd_mtxlock(sc->lock); 433 sc->settings_register &= ~HDSPE_PHONES_LEVEL_MASK; 434 sc->settings_register |= settings; 435 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register); 436 snd_mtxunlock(sc->lock); 437 } 438 return (0); 439 } 440 441 static int 442 hdspe_sysctl_sample_rate(SYSCTL_HANDLER_ARGS) 443 { 444 struct sc_info *sc = oidp->oid_arg1; 445 int error; 446 unsigned int speed, multiplier; 447 448 speed = sc->force_speed; 449 450 /* Process sysctl (unsigned) integer request. */ 451 error = sysctl_handle_int(oidp, &speed, 0, req); 452 if (error != 0 || req->newptr == NULL) 453 return (error); 454 455 /* Speed from 32000 to 192000, 0 falls back to pcm speed setting. */ 456 sc->force_speed = 0; 457 if (speed > 0) { 458 multiplier = 1; 459 if (speed > (96000 + 128000) / 2) 460 multiplier = 4; 461 else if (speed > (48000 + 64000) / 2) 462 multiplier = 2; 463 464 if (speed < ((32000 + 44100) / 2) * multiplier) 465 sc->force_speed = 32000 * multiplier; 466 else if (speed < ((44100 + 48000) / 2) * multiplier) 467 sc->force_speed = 44100 * multiplier; 468 else 469 sc->force_speed = 48000 * multiplier; 470 } 471 472 return (0); 473 } 474 475 476 static int 477 hdspe_sysctl_period(SYSCTL_HANDLER_ARGS) 478 { 479 struct sc_info *sc = oidp->oid_arg1; 480 int error; 481 unsigned int period; 482 483 period = sc->force_period; 484 485 /* Process sysctl (unsigned) integer request. */ 486 error = sysctl_handle_int(oidp, &period, 0, req); 487 if (error != 0 || req->newptr == NULL) 488 return (error); 489 490 /* Period is from 2^5 to 2^14, 0 falls back to pcm latency settings. */ 491 sc->force_period = 0; 492 if (period > 0) { 493 sc->force_period = 32; 494 while (sc->force_period < period && sc->force_period < 4096) 495 sc->force_period <<= 1; 496 } 497 498 return (0); 499 } 500 501 static int 502 hdspe_sysctl_clock_preference(SYSCTL_HANDLER_ARGS) 503 { 504 struct sc_info *sc; 505 struct hdspe_clock_source *clock_table, *clock; 506 char buf[16] = "invalid"; 507 int error; 508 uint32_t setting; 509 510 sc = oidp->oid_arg1; 511 512 /* Select sync ports table for device type. */ 513 if (sc->type == HDSPE_AIO) 514 clock_table = hdspe_clock_source_table_aio; 515 else if (sc->type == HDSPE_RAYDAT) 516 clock_table = hdspe_clock_source_table_rd; 517 else 518 return (ENXIO); 519 520 /* Extract preferred clock source from settings register. */ 521 setting = sc->settings_register & HDSPE_SETTING_CLOCK_MASK; 522 for (clock = clock_table; clock->name != NULL; ++clock) { 523 if (clock->setting == setting) 524 break; 525 } 526 if (clock->name != NULL) 527 strlcpy(buf, clock->name, sizeof(buf)); 528 529 /* Process sysctl string request. */ 530 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 531 if (error != 0 || req->newptr == NULL) 532 return (error); 533 534 /* Find clock source matching the sysctl string. */ 535 for (clock = clock_table; clock->name != NULL; ++clock) { 536 if (strncasecmp(buf, clock->name, sizeof(buf)) == 0) 537 break; 538 } 539 540 /* Set preferred clock source in settings register. */ 541 if (clock->name != NULL) { 542 setting = clock->setting & HDSPE_SETTING_CLOCK_MASK; 543 snd_mtxlock(sc->lock); 544 sc->settings_register &= ~HDSPE_SETTING_CLOCK_MASK; 545 sc->settings_register |= setting; 546 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register); 547 snd_mtxunlock(sc->lock); 548 } 549 return (0); 550 } 551 552 static int 553 hdspe_sysctl_clock_source(SYSCTL_HANDLER_ARGS) 554 { 555 struct sc_info *sc; 556 struct hdspe_clock_source *clock_table, *clock; 557 char buf[16] = "invalid"; 558 uint32_t status; 559 560 sc = oidp->oid_arg1; 561 562 /* Select sync ports table for device type. */ 563 if (sc->type == HDSPE_AIO) 564 clock_table = hdspe_clock_source_table_aio; 565 else if (sc->type == HDSPE_RAYDAT) 566 clock_table = hdspe_clock_source_table_rd; 567 else 568 return (ENXIO); 569 570 /* Read current (autosync) clock source from status register. */ 571 snd_mtxlock(sc->lock); 572 status = hdspe_read_4(sc, HDSPE_STATUS1_REG); 573 status &= HDSPE_STATUS1_CLOCK_MASK; 574 snd_mtxunlock(sc->lock); 575 576 /* Translate status register value to clock source. */ 577 for (clock = clock_table; clock->name != NULL; ++clock) { 578 /* In clock master mode, override with internal clock source. */ 579 if (sc->settings_register & HDSPE_SETTING_MASTER) { 580 if (clock->setting & HDSPE_SETTING_MASTER) 581 break; 582 } else if (clock->status == status) 583 break; 584 } 585 586 /* Process sysctl string request. */ 587 if (clock->name != NULL) 588 strlcpy(buf, clock->name, sizeof(buf)); 589 return (sysctl_handle_string(oidp, buf, sizeof(buf), req)); 590 } 591 592 static int 593 hdspe_sysctl_clock_list(SYSCTL_HANDLER_ARGS) 594 { 595 struct sc_info *sc; 596 struct hdspe_clock_source *clock_table, *clock; 597 char buf[256]; 598 int n; 599 600 sc = oidp->oid_arg1; 601 n = 0; 602 603 /* Select clock source table for device type. */ 604 if (sc->type == HDSPE_AIO) 605 clock_table = hdspe_clock_source_table_aio; 606 else if (sc->type == HDSPE_RAYDAT) 607 clock_table = hdspe_clock_source_table_rd; 608 else 609 return (ENXIO); 610 611 /* List available clock sources. */ 612 buf[0] = 0; 613 for (clock = clock_table; clock->name != NULL; ++clock) { 614 if (n > 0) 615 n += strlcpy(buf + n, ",", sizeof(buf) - n); 616 n += strlcpy(buf + n, clock->name, sizeof(buf) - n); 617 } 618 return (sysctl_handle_string(oidp, buf, sizeof(buf), req)); 619 } 620 621 static int 622 hdspe_sysctl_sync_status(SYSCTL_HANDLER_ARGS) 623 { 624 struct sc_info *sc; 625 struct hdspe_clock_source *clock_table, *clock; 626 char buf[256]; 627 char *state; 628 int n; 629 uint32_t status; 630 631 sc = oidp->oid_arg1; 632 n = 0; 633 634 /* Select sync ports table for device type. */ 635 if (sc->type == HDSPE_AIO) 636 clock_table = hdspe_clock_source_table_aio; 637 else if (sc->type == HDSPE_RAYDAT) 638 clock_table = hdspe_clock_source_table_rd; 639 else 640 return (ENXIO); 641 642 /* Read current lock and sync bits from status register. */ 643 snd_mtxlock(sc->lock); 644 status = hdspe_read_4(sc, HDSPE_STATUS1_REG); 645 snd_mtxunlock(sc->lock); 646 647 /* List clock sources with lock and sync state. */ 648 for (clock = clock_table; clock->name != NULL; ++clock) { 649 if (clock->sync_bit != 0) { 650 if (n > 0) 651 n += strlcpy(buf + n, ",", sizeof(buf) - n); 652 state = "none"; 653 if ((clock->sync_bit & status) != 0) 654 state = "sync"; 655 else if ((clock->lock_bit & status) != 0) 656 state = "lock"; 657 n += snprintf(buf + n, sizeof(buf) - n, "%s(%s)", 658 clock->name, state); 659 } 660 } 661 return (sysctl_handle_string(oidp, buf, sizeof(buf), req)); 662 } 663 664 static int 665 hdspe_probe(device_t dev) 666 { 667 uint32_t rev; 668 669 if ((pci_get_vendor(dev) == PCI_VENDOR_XILINX || 670 pci_get_vendor(dev) == PCI_VENDOR_RME) && 671 pci_get_device(dev) == PCI_DEVICE_XILINX_HDSPE) { 672 rev = pci_get_revid(dev); 673 switch (rev) { 674 case PCI_REVISION_AIO: 675 device_set_desc(dev, "RME HDSPe AIO"); 676 return (0); 677 case PCI_REVISION_RAYDAT: 678 device_set_desc(dev, "RME HDSPe RayDAT"); 679 return (0); 680 } 681 } 682 683 return (ENXIO); 684 } 685 686 static int 687 hdspe_init(struct sc_info *sc) 688 { 689 long long period; 690 691 /* Set latency. */ 692 sc->period = 32; 693 /* 694 * The pcm channel latency settings propagate unreliable blocksizes, 695 * different for recording and playback, and skewed due to rounding 696 * and total buffer size limits. 697 * Force period to a consistent default until these issues are fixed. 698 */ 699 sc->force_period = 256; 700 sc->ctrl_register = hdspe_encode_latency(7); 701 702 /* Set rate. */ 703 sc->speed = HDSPE_SPEED_DEFAULT; 704 sc->force_speed = 0; 705 sc->ctrl_register &= ~HDSPE_FREQ_MASK; 706 sc->ctrl_register |= HDSPE_FREQ_MASK_DEFAULT; 707 hdspe_write_4(sc, HDSPE_CONTROL_REG, sc->ctrl_register); 708 709 switch (sc->type) { 710 case HDSPE_RAYDAT: 711 case HDSPE_AIO: 712 period = HDSPE_FREQ_AIO; 713 break; 714 default: 715 return (ENXIO); 716 } 717 718 /* Set DDS value. */ 719 period /= sc->speed; 720 hdspe_write_4(sc, HDSPE_FREQ_REG, period); 721 722 /* Other settings. */ 723 sc->settings_register = 0; 724 725 /* Default gain levels. */ 726 sc->settings_register &= ~HDSPE_INPUT_LEVEL_MASK; 727 sc->settings_register |= HDSPE_INPUT_LEVEL_LOWGAIN; 728 sc->settings_register &= ~HDSPE_OUTPUT_LEVEL_MASK; 729 sc->settings_register |= HDSPE_OUTPUT_LEVEL_MINUS10DBV; 730 sc->settings_register &= ~HDSPE_PHONES_LEVEL_MASK; 731 sc->settings_register |= HDSPE_PHONES_LEVEL_MINUS10DBV; 732 733 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register); 734 735 return (0); 736 } 737 738 static int 739 hdspe_attach(device_t dev) 740 { 741 struct hdspe_channel *chan_map; 742 struct sc_pcminfo *scp; 743 struct sc_info *sc; 744 uint32_t rev; 745 int i, err; 746 747 #if 0 748 device_printf(dev, "hdspe_attach()\n"); 749 #endif 750 751 sc = device_get_softc(dev); 752 sc->lock = snd_mtxcreate(device_get_nameunit(dev), 753 "snd_hdspe softc"); 754 sc->dev = dev; 755 756 pci_enable_busmaster(dev); 757 rev = pci_get_revid(dev); 758 switch (rev) { 759 case PCI_REVISION_AIO: 760 sc->type = HDSPE_AIO; 761 chan_map = hdspe_unified_pcm ? chan_map_aio_uni : chan_map_aio; 762 break; 763 case PCI_REVISION_RAYDAT: 764 sc->type = HDSPE_RAYDAT; 765 chan_map = hdspe_unified_pcm ? chan_map_rd_uni : chan_map_rd; 766 break; 767 default: 768 return (ENXIO); 769 } 770 771 /* Allocate resources. */ 772 err = hdspe_alloc_resources(sc); 773 if (err) { 774 device_printf(dev, "Unable to allocate system resources.\n"); 775 return (ENXIO); 776 } 777 778 if (hdspe_init(sc) != 0) 779 return (ENXIO); 780 781 for (i = 0; i < HDSPE_MAX_CHANS && chan_map[i].descr != NULL; i++) { 782 scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_WAITOK | M_ZERO); 783 scp->hc = &chan_map[i]; 784 scp->sc = sc; 785 scp->dev = device_add_child(dev, "pcm", DEVICE_UNIT_ANY); 786 device_set_ivars(scp->dev, scp); 787 } 788 789 hdspe_map_dmabuf(sc); 790 791 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 792 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 793 "sync_status", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 794 sc, 0, hdspe_sysctl_sync_status, "A", 795 "List clock source signal lock and sync status"); 796 797 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 798 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 799 "clock_source", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 800 sc, 0, hdspe_sysctl_clock_source, "A", 801 "Currently effective clock source"); 802 803 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 804 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 805 "clock_preference", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, 806 sc, 0, hdspe_sysctl_clock_preference, "A", 807 "Set 'internal' (master) or preferred autosync clock source"); 808 809 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 810 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 811 "clock_list", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 812 sc, 0, hdspe_sysctl_clock_list, "A", 813 "List of supported clock sources"); 814 815 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 816 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 817 "period", CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, 818 sc, 0, hdspe_sysctl_period, "A", 819 "Force period of samples per interrupt (32, 64, ... 4096)"); 820 821 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 822 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 823 "sample_rate", CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, 824 sc, 0, hdspe_sysctl_sample_rate, "A", 825 "Force sample rate (32000, 44100, 48000, ... 192000)"); 826 827 if (sc->type == HDSPE_AIO) { 828 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 829 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 830 "phones_level", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, 831 sc, 0, hdspe_sysctl_phones_level, "A", 832 "Phones output level ('HighGain', '+4dBU', '-10dBV')"); 833 834 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 835 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 836 "output_level", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, 837 sc, 0, hdspe_sysctl_output_level, "A", 838 "Analog output level ('HighGain', '+4dBU', '-10dBV')"); 839 840 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 841 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 842 "input_level", CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, 843 sc, 0, hdspe_sysctl_input_level, "A", 844 "Analog input level ('LowGain', '+4dBU', '-10dBV')"); 845 } 846 847 bus_attach_children(dev); 848 return (0); 849 } 850 851 static void 852 hdspe_child_deleted(device_t dev, device_t child) 853 { 854 free(device_get_ivars(child), M_DEVBUF); 855 } 856 857 static void 858 hdspe_dmafree(struct sc_info *sc) 859 { 860 861 bus_dmamap_unload(sc->dmat, sc->rmap); 862 bus_dmamap_unload(sc->dmat, sc->pmap); 863 bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap); 864 bus_dmamem_free(sc->dmat, sc->pbuf, sc->pmap); 865 sc->rbuf = sc->pbuf = NULL; 866 } 867 868 static int 869 hdspe_detach(device_t dev) 870 { 871 struct sc_info *sc; 872 int err; 873 874 sc = device_get_softc(dev); 875 if (sc == NULL) { 876 device_printf(dev,"Can't detach: softc is null.\n"); 877 return (0); 878 } 879 880 err = device_delete_children(dev); 881 if (err) 882 return (err); 883 884 hdspe_dmafree(sc); 885 886 if (sc->ih) 887 bus_teardown_intr(dev, sc->irq, sc->ih); 888 if (sc->dmat) 889 bus_dma_tag_destroy(sc->dmat); 890 if (sc->irq) 891 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); 892 if (sc->cs) 893 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->cs); 894 if (sc->lock) 895 snd_mtxfree(sc->lock); 896 897 return (0); 898 } 899 900 static device_method_t hdspe_methods[] = { 901 DEVMETHOD(device_probe, hdspe_probe), 902 DEVMETHOD(device_attach, hdspe_attach), 903 DEVMETHOD(device_detach, hdspe_detach), 904 DEVMETHOD(bus_child_deleted, hdspe_child_deleted), 905 { 0, 0 } 906 }; 907 908 static driver_t hdspe_driver = { 909 "hdspe", 910 hdspe_methods, 911 PCM_SOFTC_SIZE, 912 }; 913 914 DRIVER_MODULE(snd_hdspe, pci, hdspe_driver, 0, 0); 915