1 /* $OpenBSD: cmpci.c,v 1.54 2024/05/24 06:02:53 jsg Exp $ */ 2 /* $NetBSD: cmpci.c,v 1.25 2004/10/26 06:32:20 xtraeme Exp $ */ 3 4 /* 5 * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Takuya SHIOZAKI <tshiozak@NetBSD.org> . 10 * 11 * This code is derived from software contributed to The NetBSD Foundation 12 * by ITOH Yasufumi. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 */ 36 37 /* 38 * C-Media CMI8x38, CMI8768 Audio Chip Support. 39 * 40 * TODO: 41 * - Joystick support. 42 * 43 */ 44 45 #if defined(AUDIO_DEBUG) || defined(DEBUG) 46 #define DPRINTF(x) if (cmpcidebug) printf x 47 int cmpcidebug = 0; 48 #else 49 #define DPRINTF(x) 50 #endif 51 52 #include <sys/param.h> 53 #include <sys/systm.h> 54 #include <sys/malloc.h> 55 #include <sys/device.h> 56 57 #include <dev/pci/pcidevs.h> 58 #include <dev/pci/pcivar.h> 59 60 #include <sys/audioio.h> 61 #include <dev/audio_if.h> 62 63 #include <dev/pci/cmpcireg.h> 64 #include <dev/pci/cmpcivar.h> 65 66 #include <machine/bus.h> 67 #include <machine/intr.h> 68 69 /* 70 * Low-level HW interface 71 */ 72 uint8_t cmpci_mixerreg_read(struct cmpci_softc *, uint8_t); 73 void cmpci_mixerreg_write(struct cmpci_softc *, uint8_t, uint8_t); 74 void cmpci_reg_partial_write_1(struct cmpci_softc *, int, int, 75 unsigned, unsigned); 76 void cmpci_reg_partial_write_4(struct cmpci_softc *, int, int, 77 uint32_t, uint32_t); 78 void cmpci_reg_set_1(struct cmpci_softc *, int, uint8_t); 79 void cmpci_reg_clear_1(struct cmpci_softc *, int, uint8_t); 80 void cmpci_reg_set_4(struct cmpci_softc *, int, uint32_t); 81 void cmpci_reg_clear_4(struct cmpci_softc *, int, uint32_t); 82 void cmpci_reg_set_reg_misc(struct cmpci_softc *, uint32_t); 83 void cmpci_reg_clear_reg_misc(struct cmpci_softc *, uint32_t); 84 int cmpci_rate_to_index(int); 85 int cmpci_index_to_rate(int); 86 int cmpci_index_to_divider(int); 87 88 int cmpci_adjust(int, int); 89 void cmpci_set_mixer_gain(struct cmpci_softc *, int); 90 void cmpci_set_out_ports(struct cmpci_softc *); 91 int cmpci_set_in_ports(struct cmpci_softc *); 92 93 void cmpci_resume(struct cmpci_softc *); 94 95 /* 96 * autoconf interface 97 */ 98 int cmpci_match(struct device *, void *, void *); 99 void cmpci_attach(struct device *, struct device *, void *); 100 int cmpci_activate(struct device *, int); 101 102 struct cfdriver cmpci_cd = { 103 NULL, "cmpci", DV_DULL 104 }; 105 106 const struct cfattach cmpci_ca = { 107 sizeof (struct cmpci_softc), cmpci_match, cmpci_attach, NULL, 108 cmpci_activate 109 }; 110 111 /* interrupt */ 112 int cmpci_intr(void *); 113 114 /* 115 * DMA stuff 116 */ 117 int cmpci_alloc_dmamem(struct cmpci_softc *, 118 size_t, int, 119 int, caddr_t *); 120 int cmpci_free_dmamem(struct cmpci_softc *, caddr_t, 121 int); 122 struct cmpci_dmanode * cmpci_find_dmamem(struct cmpci_softc *, 123 caddr_t); 124 125 /* 126 * Interface to machine independent layer 127 */ 128 int cmpci_open(void *, int); 129 void cmpci_close(void *); 130 int cmpci_set_params(void *, int, int, 131 struct audio_params *, 132 struct audio_params *); 133 int cmpci_round_blocksize(void *, int); 134 int cmpci_halt_output(void *); 135 int cmpci_halt_input(void *); 136 int cmpci_set_port(void *, mixer_ctrl_t *); 137 int cmpci_get_port(void *, mixer_ctrl_t *); 138 int cmpci_query_devinfo(void *, mixer_devinfo_t *); 139 void *cmpci_malloc(void *, int, size_t, int, int); 140 void cmpci_free(void *, void *, int); 141 size_t cmpci_round_buffersize(void *, int, size_t); 142 int cmpci_trigger_output(void *, void *, void *, int, 143 void (*)(void *), void *, 144 struct audio_params *); 145 int cmpci_trigger_input(void *, void *, void *, int, 146 void (*)(void *), void *, 147 struct audio_params *); 148 149 const struct audio_hw_if cmpci_hw_if = { 150 .open = cmpci_open, 151 .close = cmpci_close, 152 .set_params = cmpci_set_params, 153 .round_blocksize = cmpci_round_blocksize, 154 .halt_output = cmpci_halt_output, 155 .halt_input = cmpci_halt_input, 156 .set_port = cmpci_set_port, 157 .get_port = cmpci_get_port, 158 .query_devinfo = cmpci_query_devinfo, 159 .allocm = cmpci_malloc, 160 .freem = cmpci_free, 161 .round_buffersize = cmpci_round_buffersize, 162 .trigger_output = cmpci_trigger_output, 163 .trigger_input = cmpci_trigger_input, 164 }; 165 166 /* 167 * Low-level HW interface 168 */ 169 170 /* mixer register read/write */ 171 uint8_t 172 cmpci_mixerreg_read(struct cmpci_softc *sc, uint8_t no) 173 { 174 uint8_t ret; 175 176 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBADDR, no); 177 delay(10); 178 ret = bus_space_read_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBDATA); 179 delay(10); 180 return ret; 181 } 182 183 void 184 cmpci_mixerreg_write(struct cmpci_softc *sc, uint8_t no, uint8_t val) 185 { 186 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBADDR, no); 187 delay(10); 188 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBDATA, val); 189 delay(10); 190 } 191 192 /* register partial write */ 193 void 194 cmpci_reg_partial_write_1(struct cmpci_softc *sc, int no, int shift, 195 unsigned mask, unsigned val) 196 { 197 bus_space_write_1(sc->sc_iot, sc->sc_ioh, no, 198 (val<<shift) | 199 (bus_space_read_1(sc->sc_iot, sc->sc_ioh, no) & ~(mask<<shift))); 200 delay(10); 201 } 202 203 void 204 cmpci_reg_partial_write_4(struct cmpci_softc *sc, int no, int shift, 205 uint32_t mask, uint32_t val) 206 { 207 bus_space_write_4(sc->sc_iot, sc->sc_ioh, no, 208 (val<<shift) | 209 (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) & ~(mask<<shift))); 210 delay(10); 211 } 212 213 /* register set/clear bit */ 214 void 215 cmpci_reg_set_1(struct cmpci_softc *sc, int no, uint8_t mask) 216 { 217 bus_space_write_1(sc->sc_iot, sc->sc_ioh, no, 218 (bus_space_read_1(sc->sc_iot, sc->sc_ioh, no) | mask)); 219 delay(10); 220 } 221 222 void 223 cmpci_reg_clear_1(struct cmpci_softc *sc, int no, uint8_t mask) 224 { 225 bus_space_write_1(sc->sc_iot, sc->sc_ioh, no, 226 (bus_space_read_1(sc->sc_iot, sc->sc_ioh, no) & ~mask)); 227 delay(10); 228 } 229 230 void 231 cmpci_reg_set_4(struct cmpci_softc *sc, int no, uint32_t mask) 232 { 233 /* use cmpci_reg_set_reg_misc() for CMPCI_REG_MISC */ 234 KDASSERT(no != CMPCI_REG_MISC); 235 236 bus_space_write_4(sc->sc_iot, sc->sc_ioh, no, 237 (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) | mask)); 238 delay(10); 239 } 240 241 void 242 cmpci_reg_clear_4(struct cmpci_softc *sc, int no, uint32_t mask) 243 { 244 /* use cmpci_reg_clear_reg_misc() for CMPCI_REG_MISC */ 245 KDASSERT(no != CMPCI_REG_MISC); 246 247 bus_space_write_4(sc->sc_iot, sc->sc_ioh, no, 248 (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) & ~mask)); 249 delay(10); 250 } 251 252 /* 253 * The CMPCI_REG_MISC register needs special handling, since one of 254 * its bits has different read/write values. 255 */ 256 void 257 cmpci_reg_set_reg_misc(struct cmpci_softc *sc, uint32_t mask) 258 { 259 sc->sc_reg_misc |= mask; 260 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MISC, 261 sc->sc_reg_misc); 262 delay(10); 263 } 264 265 void 266 cmpci_reg_clear_reg_misc(struct cmpci_softc *sc, uint32_t mask) 267 { 268 sc->sc_reg_misc &= ~mask; 269 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MISC, 270 sc->sc_reg_misc); 271 delay(10); 272 } 273 274 /* rate */ 275 static const struct { 276 int rate; 277 int divider; 278 } cmpci_rate_table[CMPCI_REG_NUMRATE] = { 279 #define _RATE(n) { n, CMPCI_REG_RATE_ ## n } 280 _RATE(5512), 281 _RATE(8000), 282 _RATE(11025), 283 _RATE(16000), 284 _RATE(22050), 285 _RATE(32000), 286 _RATE(44100), 287 _RATE(48000) 288 #undef _RATE 289 }; 290 291 int 292 cmpci_rate_to_index(int rate) 293 { 294 int i; 295 296 for (i = 0; i < CMPCI_REG_NUMRATE - 1; i++) 297 if (rate <= 298 (cmpci_rate_table[i].rate + cmpci_rate_table[i+1].rate) / 2) 299 return i; 300 return i; /* 48000 */ 301 } 302 303 int 304 cmpci_index_to_rate(int index) 305 { 306 return cmpci_rate_table[index].rate; 307 } 308 309 int 310 cmpci_index_to_divider(int index) 311 { 312 return cmpci_rate_table[index].divider; 313 } 314 315 const struct pci_matchid cmpci_devices[] = { 316 { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8338A }, 317 { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8338B }, 318 { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8738 }, 319 { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8738B } 320 }; 321 322 /* 323 * interface to configure the device. 324 */ 325 326 int 327 cmpci_match(struct device *parent, void *match, void *aux) 328 { 329 return (pci_matchbyid((struct pci_attach_args *)aux, cmpci_devices, 330 nitems(cmpci_devices))); 331 } 332 333 void 334 cmpci_attach(struct device *parent, struct device *self, void *aux) 335 { 336 struct cmpci_softc *sc = (struct cmpci_softc *)self; 337 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 338 struct audio_attach_args aa; 339 pci_intr_handle_t ih; 340 char const *intrstr; 341 int i, v, d; 342 343 sc->sc_id = pa->pa_id; 344 sc->sc_class = pa->pa_class; 345 switch (PCI_PRODUCT(sc->sc_id)) { 346 case PCI_PRODUCT_CMI_CMI8338A: 347 /*FALLTHROUGH*/ 348 case PCI_PRODUCT_CMI_CMI8338B: 349 sc->sc_capable = CMPCI_CAP_CMI8338; 350 break; 351 case PCI_PRODUCT_CMI_CMI8738: 352 /*FALLTHROUGH*/ 353 case PCI_PRODUCT_CMI_CMI8738B: 354 sc->sc_capable = CMPCI_CAP_CMI8738; 355 break; 356 } 357 358 /* map I/O space */ 359 if (pci_mapreg_map(pa, CMPCI_PCI_IOBASEREG, PCI_MAPREG_TYPE_IO, 0, 360 &sc->sc_iot, &sc->sc_ioh, NULL, NULL, 0)) { 361 printf(": can't map i/o space\n"); 362 return; 363 } 364 365 /* interrupt */ 366 if (pci_intr_map(pa, &ih)) { 367 printf(": can't map interrupt\n"); 368 return; 369 } 370 intrstr = pci_intr_string(pa->pa_pc, ih); 371 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO | IPL_MPSAFE, 372 cmpci_intr, sc, sc->sc_dev.dv_xname); 373 if (sc->sc_ih == NULL) { 374 printf(": can't establish interrupt"); 375 if (intrstr != NULL) 376 printf(" at %s", intrstr); 377 printf("\n"); 378 return; 379 } 380 printf(": %s\n", intrstr); 381 382 sc->sc_dmat = pa->pa_dmat; 383 384 audio_attach_mi(&cmpci_hw_if, sc, NULL, &sc->sc_dev); 385 386 /* attach OPL device */ 387 aa.type = AUDIODEV_TYPE_OPL; 388 aa.hwif = NULL; 389 aa.hdl = NULL; 390 (void)config_found(&sc->sc_dev, &aa, audioprint); 391 392 /* attach MPU-401 device */ 393 aa.type = AUDIODEV_TYPE_MPU; 394 aa.hwif = NULL; 395 aa.hdl = NULL; 396 if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, 397 CMPCI_REG_MPU_BASE, CMPCI_REG_MPU_SIZE, &sc->sc_mpu_ioh) == 0) 398 sc->sc_mpudev = config_found(&sc->sc_dev, &aa, audioprint); 399 400 /* get initial value (this is 0 and may be omitted but just in case) */ 401 sc->sc_reg_misc = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 402 CMPCI_REG_MISC) & ~CMPCI_REG_SPDIF48K; 403 404 /* extra capabilities check */ 405 d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_INTR_CTRL) & 406 CMPCI_REG_CHIP_MASK2; 407 if (d) { 408 if (d & CMPCI_REG_CHIP_8768) { 409 sc->sc_version = 68; 410 sc->sc_capable |= CMPCI_CAP_4CH | CMPCI_CAP_6CH | 411 CMPCI_CAP_8CH; 412 } else if (d & CMPCI_REG_CHIP_055) { 413 sc->sc_version = 55; 414 sc->sc_capable |= CMPCI_CAP_4CH | CMPCI_CAP_6CH; 415 } else if (d & CMPCI_REG_CHIP_039) { 416 sc->sc_version = 39; 417 sc->sc_capable |= CMPCI_CAP_4CH | 418 ((d & CMPCI_REG_CHIP_039_6CH) ? CMPCI_CAP_6CH : 0); 419 } else { 420 /* unknown version */ 421 sc->sc_version = 0; 422 } 423 } else { 424 d = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 425 CMPCI_REG_CHANNEL_FORMAT) & CMPCI_REG_CHIP_MASK1; 426 if (d) 427 sc->sc_version = 37; 428 else 429 sc->sc_version = 33; 430 } 431 432 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_RESET, 0); 433 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, 0); 434 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, 0); 435 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, 436 CMPCI_SB16_SW_CD|CMPCI_SB16_SW_MIC|CMPCI_SB16_SW_LINE); 437 for (i = 0; i < CMPCI_NDEVS; i++) { 438 switch(i) { 439 /* 440 * CMI8738 defaults are 441 * master: 0xe0 (0x00 - 0xf8) 442 * FM, DAC: 0xc0 (0x00 - 0xf8) 443 * PC speaker: 0x80 (0x00 - 0xc0) 444 * others: 0 445 */ 446 /* volume */ 447 case CMPCI_MASTER_VOL: 448 v = 128; /* 224 */ 449 break; 450 case CMPCI_FM_VOL: 451 case CMPCI_DAC_VOL: 452 v = 192; 453 break; 454 case CMPCI_PCSPEAKER: 455 v = 128; 456 break; 457 458 /* booleans, set to true */ 459 case CMPCI_CD_MUTE: 460 case CMPCI_MIC_MUTE: 461 case CMPCI_LINE_IN_MUTE: 462 case CMPCI_AUX_IN_MUTE: 463 v = 1; 464 break; 465 466 /* volume with initial value 0 */ 467 case CMPCI_CD_VOL: 468 case CMPCI_LINE_IN_VOL: 469 case CMPCI_AUX_IN_VOL: 470 case CMPCI_MIC_VOL: 471 case CMPCI_MIC_RECVOL: 472 /* FALLTHROUGH */ 473 474 /* others are cleared */ 475 case CMPCI_MIC_PREAMP: 476 case CMPCI_RECORD_SOURCE: 477 case CMPCI_PLAYBACK_MODE: 478 case CMPCI_SPDIF_IN_SELECT: 479 case CMPCI_SPDIF_IN_PHASE: 480 case CMPCI_SPDIF_LOOP: 481 case CMPCI_SPDIF_OUT_PLAYBACK: 482 case CMPCI_SPDIF_OUT_VOLTAGE: 483 case CMPCI_MONITOR_DAC: 484 case CMPCI_REAR: 485 case CMPCI_INDIVIDUAL: 486 case CMPCI_REVERSE: 487 case CMPCI_SURROUND: 488 default: 489 v = 0; 490 break; 491 } 492 sc->sc_gain[i][CMPCI_LEFT] = sc->sc_gain[i][CMPCI_RIGHT] = v; 493 cmpci_set_mixer_gain(sc, i); 494 } 495 496 sc->sc_play_channel = 0; 497 } 498 499 int 500 cmpci_activate(struct device *self, int act) 501 { 502 struct cmpci_softc *sc = (struct cmpci_softc *)self; 503 504 switch (act) { 505 case DVACT_RESUME: 506 cmpci_resume(sc); 507 break; 508 default: 509 break; 510 } 511 return (config_activate_children(self, act)); 512 } 513 514 void 515 cmpci_resume(struct cmpci_softc *sc) 516 { 517 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_RESET, 0); 518 } 519 520 int 521 cmpci_intr(void *handle) 522 { 523 struct cmpci_softc *sc = handle; 524 struct cmpci_channel *chan; 525 uint32_t intrstat; 526 uint16_t hwpos; 527 528 mtx_enter(&audio_lock); 529 intrstat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 530 CMPCI_REG_INTR_STATUS); 531 532 if (!(intrstat & CMPCI_REG_ANY_INTR)) { 533 mtx_leave(&audio_lock); 534 return 0; 535 } 536 537 delay(10); 538 539 /* disable and reset intr */ 540 if (intrstat & CMPCI_REG_CH0_INTR) 541 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 542 CMPCI_REG_CH0_INTR_ENABLE); 543 if (intrstat & CMPCI_REG_CH1_INTR) 544 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 545 CMPCI_REG_CH1_INTR_ENABLE); 546 547 if (intrstat & CMPCI_REG_CH0_INTR) { 548 chan = &sc->sc_ch0; 549 if (chan->intr != NULL) { 550 hwpos = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 551 CMPCI_REG_DMA0_BYTES); 552 hwpos = hwpos * chan->bps / chan->blksize; 553 hwpos = chan->nblocks - hwpos - 1; 554 while (chan->swpos != hwpos) { 555 (*chan->intr)(chan->intr_arg); 556 chan->swpos++; 557 if (chan->swpos >= chan->nblocks) 558 chan->swpos = 0; 559 if (chan->swpos != hwpos) { 560 DPRINTF(("%s: DMA0 hwpos=%d swpos=%d\n", 561 __func__, hwpos, chan->swpos)); 562 } 563 } 564 } 565 } 566 if (intrstat & CMPCI_REG_CH1_INTR) { 567 chan = &sc->sc_ch1; 568 if (chan->intr != NULL) { 569 hwpos = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 570 CMPCI_REG_DMA1_BYTES); 571 hwpos = hwpos * chan->bps / chan->blksize; 572 hwpos = chan->nblocks - hwpos - 1; 573 while (chan->swpos != hwpos) { 574 (*chan->intr)(chan->intr_arg); 575 chan->swpos++; 576 if (chan->swpos >= chan->nblocks) 577 chan->swpos = 0; 578 if (chan->swpos != hwpos) { 579 DPRINTF(("%s: DMA1 hwpos=%d swpos=%d\n", 580 __func__, hwpos, chan->swpos)); 581 } 582 } 583 } 584 } 585 586 /* enable intr */ 587 if (intrstat & CMPCI_REG_CH0_INTR) 588 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 589 CMPCI_REG_CH0_INTR_ENABLE); 590 if (intrstat & CMPCI_REG_CH1_INTR) 591 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 592 CMPCI_REG_CH1_INTR_ENABLE); 593 594 #if 0 595 if (intrstat & CMPCI_REG_UART_INTR && sc->sc_mpudev != NULL) 596 mpu_intr(sc->sc_mpudev); 597 #endif 598 599 mtx_leave(&audio_lock); 600 return 1; 601 } 602 603 /* open/close */ 604 int 605 cmpci_open(void *handle, int flags) 606 { 607 return 0; 608 } 609 610 void 611 cmpci_close(void *handle) 612 { 613 } 614 615 int 616 cmpci_set_params(void *handle, int setmode, int usemode, 617 struct audio_params *play, struct audio_params *rec) 618 { 619 int i; 620 struct cmpci_softc *sc = handle; 621 622 for (i = 0; i < 2; i++) { 623 int md_format; 624 int md_divide; 625 int md_index; 626 int mode; 627 struct audio_params *p; 628 629 switch (i) { 630 case 0: 631 mode = AUMODE_PLAY; 632 p = play; 633 break; 634 case 1: 635 mode = AUMODE_RECORD; 636 p = rec; 637 break; 638 default: 639 return EINVAL; 640 } 641 642 if (!(setmode & mode)) 643 continue; 644 645 if (setmode & AUMODE_RECORD) { 646 if (p->channels > 2) 647 p->channels = 2; 648 sc->sc_play_channel = 0; 649 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_ENDBDAC); 650 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_XCHGDAC); 651 } else { 652 sc->sc_play_channel = 1; 653 cmpci_reg_set_reg_misc(sc, CMPCI_REG_ENDBDAC); 654 cmpci_reg_set_reg_misc(sc, CMPCI_REG_XCHGDAC); 655 } 656 657 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 658 CMPCI_REG_NXCHG); 659 if (sc->sc_capable & CMPCI_CAP_4CH) 660 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, 661 CMPCI_REG_CHB3D); 662 if (sc->sc_capable & CMPCI_CAP_6CH) { 663 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, 664 CMPCI_REG_CHB3D5C); 665 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 666 CMPCI_REG_CHB3D6C); 667 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_ENCENTER); 668 } 669 if (sc->sc_capable & CMPCI_CAP_8CH) 670 cmpci_reg_clear_4(sc, CMPCI_REG_8768_MISC, 671 CMPCI_REG_CHB3D8C); 672 673 /* format */ 674 switch (p->channels) { 675 case 1: 676 md_format = CMPCI_REG_FORMAT_MONO; 677 break; 678 case 2: 679 md_format = CMPCI_REG_FORMAT_STEREO; 680 break; 681 case 4: 682 if (mode & AUMODE_PLAY) { 683 if (sc->sc_capable & CMPCI_CAP_4CH) { 684 cmpci_reg_clear_reg_misc(sc, 685 CMPCI_REG_N4SPK3D); 686 cmpci_reg_set_4(sc, 687 CMPCI_REG_CHANNEL_FORMAT, 688 CMPCI_REG_CHB3D); 689 cmpci_reg_set_4(sc, 690 CMPCI_REG_LEGACY_CTRL, 691 CMPCI_REG_NXCHG); 692 } else 693 p->channels = 2; 694 } 695 md_format = CMPCI_REG_FORMAT_STEREO; 696 break; 697 case 6: 698 if (mode & AUMODE_PLAY) { 699 if (sc->sc_capable & CMPCI_CAP_6CH) { 700 cmpci_reg_clear_reg_misc(sc, 701 CMPCI_REG_N4SPK3D); 702 cmpci_reg_set_4(sc, 703 CMPCI_REG_CHANNEL_FORMAT, 704 CMPCI_REG_CHB3D5C); 705 cmpci_reg_set_4(sc, 706 CMPCI_REG_LEGACY_CTRL, 707 CMPCI_REG_CHB3D6C); 708 cmpci_reg_set_reg_misc(sc, 709 CMPCI_REG_ENCENTER); 710 cmpci_reg_set_4(sc, 711 CMPCI_REG_LEGACY_CTRL, 712 CMPCI_REG_NXCHG); 713 } else 714 p->channels = 2; 715 } 716 md_format = CMPCI_REG_FORMAT_STEREO; 717 break; 718 case 8: 719 if (mode & AUMODE_PLAY) { 720 if (sc->sc_capable & CMPCI_CAP_8CH) { 721 cmpci_reg_clear_reg_misc(sc, 722 CMPCI_REG_N4SPK3D); 723 cmpci_reg_set_4(sc, 724 CMPCI_REG_CHANNEL_FORMAT, 725 CMPCI_REG_CHB3D5C); 726 cmpci_reg_set_4(sc, 727 CMPCI_REG_LEGACY_CTRL, 728 CMPCI_REG_CHB3D6C); 729 cmpci_reg_set_reg_misc(sc, 730 CMPCI_REG_ENCENTER); 731 cmpci_reg_set_4(sc, 732 CMPCI_REG_8768_MISC, 733 CMPCI_REG_CHB3D8C); 734 cmpci_reg_set_4(sc, 735 CMPCI_REG_LEGACY_CTRL, 736 CMPCI_REG_NXCHG); 737 } else 738 p->channels = 2; 739 } 740 md_format = CMPCI_REG_FORMAT_STEREO; 741 break; 742 default: 743 return (EINVAL); 744 } 745 if (p->precision >= 16) { 746 p->precision = 16; 747 p->encoding = AUDIO_ENCODING_SLINEAR_LE; 748 md_format |= CMPCI_REG_FORMAT_16BIT; 749 } else { 750 p->precision = 8; 751 p->encoding = AUDIO_ENCODING_ULINEAR_LE; 752 md_format |= CMPCI_REG_FORMAT_8BIT; 753 } 754 p->bps = AUDIO_BPS(p->precision); 755 p->msb = 1; 756 if (mode & AUMODE_PLAY) { 757 if (sc->sc_play_channel == 1) { 758 cmpci_reg_partial_write_4(sc, 759 CMPCI_REG_CHANNEL_FORMAT, 760 CMPCI_REG_CH1_FORMAT_SHIFT, 761 CMPCI_REG_CH1_FORMAT_MASK, md_format); 762 } else { 763 cmpci_reg_partial_write_4(sc, 764 CMPCI_REG_CHANNEL_FORMAT, 765 CMPCI_REG_CH0_FORMAT_SHIFT, 766 CMPCI_REG_CH0_FORMAT_MASK, md_format); 767 } 768 } else { 769 cmpci_reg_partial_write_4(sc, 770 CMPCI_REG_CHANNEL_FORMAT, 771 CMPCI_REG_CH1_FORMAT_SHIFT, 772 CMPCI_REG_CH1_FORMAT_MASK, md_format); 773 } 774 /* sample rate */ 775 md_index = cmpci_rate_to_index(p->sample_rate); 776 md_divide = cmpci_index_to_divider(md_index); 777 p->sample_rate = cmpci_index_to_rate(md_index); 778 DPRINTF(("%s: sample:%d, divider=%d\n", 779 sc->sc_dev.dv_xname, (int)p->sample_rate, md_divide)); 780 if (mode & AUMODE_PLAY) { 781 if (sc->sc_play_channel == 1) { 782 cmpci_reg_partial_write_4(sc, 783 CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT, 784 CMPCI_REG_ADC_FS_MASK, md_divide); 785 sc->sc_ch1.md_divide = md_divide; 786 } else { 787 cmpci_reg_partial_write_4(sc, 788 CMPCI_REG_FUNC_1, CMPCI_REG_DAC_FS_SHIFT, 789 CMPCI_REG_DAC_FS_MASK, md_divide); 790 sc->sc_ch0.md_divide = md_divide; 791 } 792 } else { 793 cmpci_reg_partial_write_4(sc, 794 CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT, 795 CMPCI_REG_ADC_FS_MASK, md_divide); 796 sc->sc_ch1.md_divide = md_divide; 797 } 798 } 799 800 return 0; 801 } 802 803 int 804 cmpci_round_blocksize(void *handle, int block) 805 { 806 return ((block + 3) & -4); 807 } 808 809 int 810 cmpci_halt_output(void *handle) 811 { 812 struct cmpci_softc *sc = handle; 813 uint32_t reg_intr, reg_enable, reg_reset; 814 815 mtx_enter(&audio_lock); 816 if (sc->sc_play_channel == 1) { 817 sc->sc_ch1.intr = NULL; 818 reg_intr = CMPCI_REG_CH1_INTR_ENABLE; 819 reg_enable = CMPCI_REG_CH1_ENABLE; 820 reg_reset = CMPCI_REG_CH1_RESET; 821 } else { 822 sc->sc_ch0.intr = NULL; 823 reg_intr = CMPCI_REG_CH0_INTR_ENABLE; 824 reg_enable = CMPCI_REG_CH0_ENABLE; 825 reg_reset = CMPCI_REG_CH0_RESET; 826 } 827 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, reg_intr); 828 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_enable); 829 /* wait for reset DMA */ 830 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_reset); 831 delay(10); 832 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_reset); 833 mtx_leave(&audio_lock); 834 return 0; 835 } 836 837 int 838 cmpci_halt_input(void *handle) 839 { 840 struct cmpci_softc *sc = handle; 841 842 mtx_enter(&audio_lock); 843 sc->sc_ch1.intr = NULL; 844 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 845 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 846 /* wait for reset DMA */ 847 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 848 delay(10); 849 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 850 mtx_leave(&audio_lock); 851 return 0; 852 } 853 854 /* mixer device information */ 855 int 856 cmpci_query_devinfo(void *handle, mixer_devinfo_t *dip) 857 { 858 static const char *const mixer_port_names[] = { 859 AudioNdac, AudioNfmsynth, AudioNcd, AudioNline, AudioNaux, 860 AudioNmicrophone 861 }; 862 static const char *const mixer_classes[] = { 863 AudioCinputs, AudioCoutputs, AudioCrecord, CmpciCplayback, 864 CmpciCspdif 865 }; 866 struct cmpci_softc *sc = handle; 867 int i; 868 869 dip->prev = dip->next = AUDIO_MIXER_LAST; 870 871 switch (dip->index) { 872 case CMPCI_INPUT_CLASS: 873 case CMPCI_OUTPUT_CLASS: 874 case CMPCI_RECORD_CLASS: 875 case CMPCI_PLAYBACK_CLASS: 876 case CMPCI_SPDIF_CLASS: 877 dip->type = AUDIO_MIXER_CLASS; 878 dip->mixer_class = dip->index; 879 strlcpy(dip->label.name, 880 mixer_classes[dip->index - CMPCI_INPUT_CLASS], 881 sizeof dip->label.name); 882 return 0; 883 884 case CMPCI_AUX_IN_VOL: 885 dip->un.v.delta = 1 << (8 - CMPCI_REG_AUX_VALBITS); 886 goto vol1; 887 case CMPCI_DAC_VOL: 888 case CMPCI_FM_VOL: 889 case CMPCI_CD_VOL: 890 case CMPCI_LINE_IN_VOL: 891 case CMPCI_MIC_VOL: 892 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS); 893 vol1: dip->mixer_class = CMPCI_INPUT_CLASS; 894 dip->next = dip->index + 6; /* CMPCI_xxx_MUTE */ 895 strlcpy(dip->label.name, mixer_port_names[dip->index], 896 sizeof dip->label.name); 897 dip->un.v.num_channels = (dip->index == CMPCI_MIC_VOL ? 1 : 2); 898 vol: 899 dip->type = AUDIO_MIXER_VALUE; 900 strlcpy(dip->un.v.units.name, AudioNvolume, 901 sizeof dip->un.v.units.name); 902 return 0; 903 904 case CMPCI_MIC_MUTE: 905 dip->next = CMPCI_MIC_PREAMP; 906 /* FALLTHROUGH */ 907 case CMPCI_DAC_MUTE: 908 case CMPCI_FM_MUTE: 909 case CMPCI_CD_MUTE: 910 case CMPCI_LINE_IN_MUTE: 911 case CMPCI_AUX_IN_MUTE: 912 dip->prev = dip->index - 6; /* CMPCI_xxx_VOL */ 913 dip->mixer_class = CMPCI_INPUT_CLASS; 914 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 915 goto on_off; 916 on_off: 917 dip->type = AUDIO_MIXER_ENUM; 918 dip->un.e.num_mem = 2; 919 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 920 sizeof dip->un.e.member[0].label.name); 921 dip->un.e.member[0].ord = 0; 922 strlcpy(dip->un.e.member[1].label.name, AudioNon, 923 sizeof dip->un.e.member[1].label.name); 924 dip->un.e.member[1].ord = 1; 925 return 0; 926 927 case CMPCI_MIC_PREAMP: 928 dip->mixer_class = CMPCI_INPUT_CLASS; 929 dip->prev = CMPCI_MIC_MUTE; 930 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name); 931 goto on_off; 932 case CMPCI_PCSPEAKER: 933 dip->mixer_class = CMPCI_INPUT_CLASS; 934 strlcpy(dip->label.name, AudioNspeaker, sizeof dip->label.name); 935 dip->un.v.num_channels = 1; 936 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_SPEAKER_VALBITS); 937 goto vol; 938 case CMPCI_RECORD_SOURCE: 939 dip->mixer_class = CMPCI_RECORD_CLASS; 940 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 941 dip->type = AUDIO_MIXER_SET; 942 dip->un.s.num_mem = 7; 943 strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone, 944 sizeof dip->un.s.member[0].label.name); 945 dip->un.s.member[0].mask = CMPCI_RECORD_SOURCE_MIC; 946 strlcpy(dip->un.s.member[1].label.name, AudioNcd, 947 sizeof dip->un.s.member[1].label.name); 948 dip->un.s.member[1].mask = CMPCI_RECORD_SOURCE_CD; 949 strlcpy(dip->un.s.member[2].label.name, AudioNline, 950 sizeof dip->un.s.member[2].label.name); 951 dip->un.s.member[2].mask = CMPCI_RECORD_SOURCE_LINE_IN; 952 strlcpy(dip->un.s.member[3].label.name, AudioNaux, 953 sizeof dip->un.s.member[3].label.name); 954 dip->un.s.member[3].mask = CMPCI_RECORD_SOURCE_AUX_IN; 955 strlcpy(dip->un.s.member[4].label.name, AudioNwave, 956 sizeof dip->un.s.member[4].label.name); 957 dip->un.s.member[4].mask = CMPCI_RECORD_SOURCE_WAVE; 958 strlcpy(dip->un.s.member[5].label.name, AudioNfmsynth, 959 sizeof dip->un.s.member[5].label.name); 960 dip->un.s.member[5].mask = CMPCI_RECORD_SOURCE_FM; 961 strlcpy(dip->un.s.member[6].label.name, CmpciNspdif, 962 sizeof dip->un.s.member[6].label.name); 963 dip->un.s.member[6].mask = CMPCI_RECORD_SOURCE_SPDIF; 964 return 0; 965 case CMPCI_MIC_RECVOL: 966 dip->mixer_class = CMPCI_RECORD_CLASS; 967 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 968 dip->un.v.num_channels = 1; 969 dip->un.v.delta = 1 << (8 - CMPCI_REG_ADMIC_VALBITS); 970 goto vol; 971 972 case CMPCI_PLAYBACK_MODE: 973 dip->mixer_class = CMPCI_PLAYBACK_CLASS; 974 dip->type = AUDIO_MIXER_ENUM; 975 strlcpy(dip->label.name, AudioNmode, sizeof dip->label.name); 976 dip->un.e.num_mem = 2; 977 strlcpy(dip->un.e.member[0].label.name, AudioNdac, 978 sizeof dip->un.e.member[0].label.name); 979 dip->un.e.member[0].ord = CMPCI_PLAYBACK_MODE_WAVE; 980 strlcpy(dip->un.e.member[1].label.name, CmpciNspdif, 981 sizeof dip->un.e.member[1].label.name); 982 dip->un.e.member[1].ord = CMPCI_PLAYBACK_MODE_SPDIF; 983 return 0; 984 case CMPCI_SPDIF_IN_SELECT: 985 dip->mixer_class = CMPCI_SPDIF_CLASS; 986 dip->type = AUDIO_MIXER_ENUM; 987 dip->next = CMPCI_SPDIF_IN_PHASE; 988 strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name); 989 i = 0; 990 strlcpy(dip->un.e.member[i].label.name, CmpciNspdin1, 991 sizeof dip->un.e.member[i].label.name); 992 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN1; 993 if (CMPCI_ISCAP(sc, 2ND_SPDIN)) { 994 strlcpy(dip->un.e.member[i].label.name, CmpciNspdin2, 995 sizeof dip->un.e.member[i].label.name); 996 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN2; 997 } 998 strlcpy(dip->un.e.member[i].label.name, CmpciNspdout, 999 sizeof dip->un.e.member[i].label.name); 1000 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDOUT; 1001 dip->un.e.num_mem = i; 1002 return 0; 1003 case CMPCI_SPDIF_IN_PHASE: 1004 dip->mixer_class = CMPCI_SPDIF_CLASS; 1005 dip->prev = CMPCI_SPDIF_IN_SELECT; 1006 strlcpy(dip->label.name, CmpciNphase, sizeof dip->label.name); 1007 dip->type = AUDIO_MIXER_ENUM; 1008 dip->un.e.num_mem = 2; 1009 strlcpy(dip->un.e.member[0].label.name, CmpciNpositive, 1010 sizeof dip->un.e.member[0].label.name); 1011 dip->un.e.member[0].ord = CMPCI_SPDIF_IN_PHASE_POSITIVE; 1012 strlcpy(dip->un.e.member[1].label.name, CmpciNnegative, 1013 sizeof dip->un.e.member[1].label.name); 1014 dip->un.e.member[1].ord = CMPCI_SPDIF_IN_PHASE_NEGATIVE; 1015 return 0; 1016 case CMPCI_SPDIF_LOOP: 1017 dip->mixer_class = CMPCI_SPDIF_CLASS; 1018 dip->next = CMPCI_SPDIF_OUT_PLAYBACK; 1019 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 1020 dip->type = AUDIO_MIXER_ENUM; 1021 dip->un.e.num_mem = 2; 1022 strlcpy(dip->un.e.member[0].label.name, CmpciNplayback, 1023 sizeof dip->un.e.member[0].label.name); 1024 dip->un.e.member[0].ord = CMPCI_SPDIF_LOOP_OFF; 1025 strlcpy(dip->un.e.member[1].label.name, CmpciNspdin, 1026 sizeof dip->un.e.member[1].label.name); 1027 dip->un.e.member[1].ord = CMPCI_SPDIF_LOOP_ON; 1028 return 0; 1029 case CMPCI_SPDIF_OUT_PLAYBACK: 1030 dip->mixer_class = CMPCI_SPDIF_CLASS; 1031 dip->prev = CMPCI_SPDIF_LOOP; 1032 dip->next = CMPCI_SPDIF_OUT_VOLTAGE; 1033 strlcpy(dip->label.name, CmpciNplayback, sizeof dip->label.name); 1034 dip->type = AUDIO_MIXER_ENUM; 1035 dip->un.e.num_mem = 2; 1036 strlcpy(dip->un.e.member[0].label.name, AudioNwave, 1037 sizeof dip->un.e.member[0].label.name); 1038 dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_PLAYBACK_WAVE; 1039 strlcpy(dip->un.e.member[1].label.name, CmpciNlegacy, 1040 sizeof dip->un.e.member[1].label.name); 1041 dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_PLAYBACK_LEGACY; 1042 return 0; 1043 case CMPCI_SPDIF_OUT_VOLTAGE: 1044 dip->mixer_class = CMPCI_SPDIF_CLASS; 1045 dip->prev = CMPCI_SPDIF_OUT_PLAYBACK; 1046 strlcpy(dip->label.name, CmpciNvoltage, sizeof dip->label.name); 1047 dip->type = AUDIO_MIXER_ENUM; 1048 dip->un.e.num_mem = 2; 1049 strlcpy(dip->un.e.member[0].label.name, CmpciNhigh_v, 1050 sizeof dip->un.e.member[0].label.name); 1051 dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_VOLTAGE_HIGH; 1052 strlcpy(dip->un.e.member[1].label.name, CmpciNlow_v, 1053 sizeof dip->un.e.member[1].label.name); 1054 dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_VOLTAGE_LOW; 1055 return 0; 1056 case CMPCI_MONITOR_DAC: 1057 dip->mixer_class = CMPCI_SPDIF_CLASS; 1058 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); 1059 dip->type = AUDIO_MIXER_ENUM; 1060 dip->un.e.num_mem = 3; 1061 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 1062 sizeof dip->un.e.member[0].label.name); 1063 dip->un.e.member[0].ord = CMPCI_MONITOR_DAC_OFF; 1064 strlcpy(dip->un.e.member[1].label.name, CmpciNspdin, 1065 sizeof dip->un.e.member[1].label.name); 1066 dip->un.e.member[1].ord = CMPCI_MONITOR_DAC_SPDIN; 1067 strlcpy(dip->un.e.member[2].label.name, CmpciNspdout, 1068 sizeof dip->un.e.member[2].label.name); 1069 dip->un.e.member[2].ord = CMPCI_MONITOR_DAC_SPDOUT; 1070 return 0; 1071 1072 case CMPCI_MASTER_VOL: 1073 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1074 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 1075 dip->un.v.num_channels = 2; 1076 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS); 1077 goto vol; 1078 case CMPCI_REAR: 1079 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1080 dip->next = CMPCI_INDIVIDUAL; 1081 strlcpy(dip->label.name, CmpciNrear, sizeof dip->label.name); 1082 goto on_off; 1083 case CMPCI_INDIVIDUAL: 1084 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1085 dip->prev = CMPCI_REAR; 1086 dip->next = CMPCI_REVERSE; 1087 strlcpy(dip->label.name, CmpciNindividual, sizeof dip->label.name); 1088 goto on_off; 1089 case CMPCI_REVERSE: 1090 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1091 dip->prev = CMPCI_INDIVIDUAL; 1092 strlcpy(dip->label.name, CmpciNreverse, sizeof dip->label.name); 1093 goto on_off; 1094 case CMPCI_SURROUND: 1095 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1096 strlcpy(dip->label.name, CmpciNsurround, sizeof dip->label.name); 1097 goto on_off; 1098 } 1099 1100 return ENXIO; 1101 } 1102 1103 int 1104 cmpci_alloc_dmamem(struct cmpci_softc *sc, size_t size, int type, int flags, 1105 caddr_t *r_addr) 1106 { 1107 int error = 0; 1108 struct cmpci_dmanode *n; 1109 int w; 1110 1111 n = malloc(sizeof(struct cmpci_dmanode), type, flags); 1112 if (n == NULL) { 1113 error = ENOMEM; 1114 goto quit; 1115 } 1116 1117 w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK; 1118 #define CMPCI_DMABUF_ALIGN 0x4 1119 #define CMPCI_DMABUF_BOUNDARY 0x0 1120 n->cd_tag = sc->sc_dmat; 1121 n->cd_size = size; 1122 error = bus_dmamem_alloc(n->cd_tag, n->cd_size, 1123 CMPCI_DMABUF_ALIGN, CMPCI_DMABUF_BOUNDARY, n->cd_segs, 1124 nitems(n->cd_segs), &n->cd_nsegs, w); 1125 if (error) 1126 goto mfree; 1127 error = bus_dmamem_map(n->cd_tag, n->cd_segs, n->cd_nsegs, n->cd_size, 1128 &n->cd_addr, w | BUS_DMA_COHERENT); 1129 if (error) 1130 goto dmafree; 1131 error = bus_dmamap_create(n->cd_tag, n->cd_size, 1, n->cd_size, 0, 1132 w, &n->cd_map); 1133 if (error) 1134 goto unmap; 1135 error = bus_dmamap_load(n->cd_tag, n->cd_map, n->cd_addr, n->cd_size, 1136 NULL, w); 1137 if (error) 1138 goto destroy; 1139 1140 n->cd_next = sc->sc_dmap; 1141 sc->sc_dmap = n; 1142 *r_addr = KVADDR(n); 1143 return 0; 1144 1145 destroy: 1146 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1147 unmap: 1148 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1149 dmafree: 1150 bus_dmamem_free(n->cd_tag, 1151 n->cd_segs, nitems(n->cd_segs)); 1152 mfree: 1153 free(n, type, 0); 1154 quit: 1155 return error; 1156 } 1157 1158 int 1159 cmpci_free_dmamem(struct cmpci_softc *sc, caddr_t addr, int type) 1160 { 1161 struct cmpci_dmanode **nnp; 1162 1163 for (nnp = &sc->sc_dmap; *nnp; nnp = &(*nnp)->cd_next) { 1164 if ((*nnp)->cd_addr == addr) { 1165 struct cmpci_dmanode *n = *nnp; 1166 bus_dmamap_unload(n->cd_tag, n->cd_map); 1167 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1168 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1169 bus_dmamem_free(n->cd_tag, n->cd_segs, 1170 nitems(n->cd_segs)); 1171 free(n, type, 0); 1172 return 0; 1173 } 1174 } 1175 return -1; 1176 } 1177 1178 struct cmpci_dmanode * 1179 cmpci_find_dmamem(struct cmpci_softc *sc, caddr_t addr) 1180 { 1181 struct cmpci_dmanode *p; 1182 1183 for (p = sc->sc_dmap; p; p = p->cd_next) { 1184 if (KVADDR(p) == (void *)addr) 1185 break; 1186 } 1187 return p; 1188 } 1189 1190 #if 0 1191 void cmpci_print_dmamem(struct cmpci_dmanode *p); 1192 1193 void 1194 cmpci_print_dmamem(struct cmpci_dmanode *p) 1195 { 1196 DPRINTF(("DMA at virt:%p, dmaseg:%p, mapseg:%p, size:%p\n", 1197 (void *)p->cd_addr, (void *)p->cd_segs[0].ds_addr, 1198 (void *)DMAADDR(p), (void *)p->cd_size)); 1199 } 1200 #endif /* DEBUG */ 1201 1202 void * 1203 cmpci_malloc(void *handle, int direction, size_t size, int type, 1204 int flags) 1205 { 1206 caddr_t addr; 1207 1208 if (cmpci_alloc_dmamem(handle, size, type, flags, &addr)) 1209 return NULL; 1210 return addr; 1211 } 1212 1213 void 1214 cmpci_free(void *handle, void *addr, int type) 1215 { 1216 cmpci_free_dmamem(handle, addr, type); 1217 } 1218 1219 #define MAXVAL 256 1220 int 1221 cmpci_adjust(int val, int mask) 1222 { 1223 val += (MAXVAL - mask) >> 1; 1224 if (val >= MAXVAL) 1225 val = MAXVAL-1; 1226 return val & mask; 1227 } 1228 1229 void 1230 cmpci_set_mixer_gain(struct cmpci_softc *sc, int port) 1231 { 1232 int src; 1233 int bits, mask; 1234 1235 switch (port) { 1236 case CMPCI_MIC_VOL: 1237 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_MIC, 1238 CMPCI_ADJUST_MIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR])); 1239 return; 1240 case CMPCI_MASTER_VOL: 1241 src = CMPCI_SB16_MIXER_MASTER_L; 1242 break; 1243 case CMPCI_LINE_IN_VOL: 1244 src = CMPCI_SB16_MIXER_LINE_L; 1245 break; 1246 case CMPCI_AUX_IN_VOL: 1247 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MIXER_AUX, 1248 CMPCI_ADJUST_AUX_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT], 1249 sc->sc_gain[port][CMPCI_RIGHT])); 1250 return; 1251 case CMPCI_MIC_RECVOL: 1252 cmpci_reg_partial_write_1(sc, CMPCI_REG_MIXER25, 1253 CMPCI_REG_ADMIC_SHIFT, CMPCI_REG_ADMIC_MASK, 1254 CMPCI_ADJUST_ADMIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR])); 1255 return; 1256 case CMPCI_DAC_VOL: 1257 src = CMPCI_SB16_MIXER_VOICE_L; 1258 break; 1259 case CMPCI_FM_VOL: 1260 src = CMPCI_SB16_MIXER_FM_L; 1261 break; 1262 case CMPCI_CD_VOL: 1263 src = CMPCI_SB16_MIXER_CDDA_L; 1264 break; 1265 case CMPCI_PCSPEAKER: 1266 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_SPEAKER, 1267 CMPCI_ADJUST_2_GAIN(sc, sc->sc_gain[port][CMPCI_LR])); 1268 return; 1269 case CMPCI_MIC_PREAMP: 1270 if (sc->sc_gain[port][CMPCI_LR]) 1271 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25, 1272 CMPCI_REG_MICGAINZ); 1273 else 1274 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25, 1275 CMPCI_REG_MICGAINZ); 1276 return; 1277 1278 case CMPCI_DAC_MUTE: 1279 if (sc->sc_gain[port][CMPCI_LR]) 1280 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1281 CMPCI_REG_WSMUTE); 1282 else 1283 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1284 CMPCI_REG_WSMUTE); 1285 return; 1286 case CMPCI_FM_MUTE: 1287 if (sc->sc_gain[port][CMPCI_LR]) 1288 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1289 CMPCI_REG_FMMUTE); 1290 else 1291 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1292 CMPCI_REG_FMMUTE); 1293 return; 1294 case CMPCI_AUX_IN_MUTE: 1295 if (sc->sc_gain[port][CMPCI_LR]) 1296 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25, 1297 CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM); 1298 else 1299 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25, 1300 CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM); 1301 return; 1302 case CMPCI_CD_MUTE: 1303 mask = CMPCI_SB16_SW_CD; 1304 goto sbmute; 1305 case CMPCI_MIC_MUTE: 1306 mask = CMPCI_SB16_SW_MIC; 1307 goto sbmute; 1308 case CMPCI_LINE_IN_MUTE: 1309 mask = CMPCI_SB16_SW_LINE; 1310 sbmute: 1311 bits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_OUTMIX); 1312 if (sc->sc_gain[port][CMPCI_LR]) 1313 bits = bits & ~mask; 1314 else 1315 bits = bits | mask; 1316 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, bits); 1317 return; 1318 1319 case CMPCI_SPDIF_IN_SELECT: 1320 case CMPCI_MONITOR_DAC: 1321 case CMPCI_PLAYBACK_MODE: 1322 case CMPCI_SPDIF_LOOP: 1323 case CMPCI_SPDIF_OUT_PLAYBACK: 1324 cmpci_set_out_ports(sc); 1325 return; 1326 case CMPCI_SPDIF_OUT_VOLTAGE: 1327 if (CMPCI_ISCAP(sc, SPDOUT_VOLTAGE)) { 1328 if (sc->sc_gain[CMPCI_SPDIF_OUT_VOLTAGE][CMPCI_LR] 1329 == CMPCI_SPDIF_OUT_VOLTAGE_HIGH) 1330 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_5V); 1331 else 1332 cmpci_reg_set_reg_misc(sc, CMPCI_REG_5V); 1333 } 1334 return; 1335 case CMPCI_SURROUND: 1336 if (CMPCI_ISCAP(sc, SURROUND)) { 1337 if (sc->sc_gain[CMPCI_SURROUND][CMPCI_LR]) 1338 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1339 CMPCI_REG_SURROUND); 1340 else 1341 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1342 CMPCI_REG_SURROUND); 1343 } 1344 return; 1345 case CMPCI_REAR: 1346 if (CMPCI_ISCAP(sc, REAR)) { 1347 if (sc->sc_gain[CMPCI_REAR][CMPCI_LR]) 1348 cmpci_reg_set_reg_misc(sc, CMPCI_REG_N4SPK3D); 1349 else 1350 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_N4SPK3D); 1351 } 1352 return; 1353 case CMPCI_INDIVIDUAL: 1354 if (CMPCI_ISCAP(sc, INDIVIDUAL_REAR)) { 1355 if (sc->sc_gain[CMPCI_REAR][CMPCI_LR]) 1356 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1357 CMPCI_REG_INDIVIDUAL); 1358 else 1359 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1360 CMPCI_REG_INDIVIDUAL); 1361 } 1362 return; 1363 case CMPCI_REVERSE: 1364 if (CMPCI_ISCAP(sc, REVERSE_FR)) { 1365 if (sc->sc_gain[CMPCI_REVERSE][CMPCI_LR]) 1366 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1367 CMPCI_REG_REVERSE_FR); 1368 else 1369 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1370 CMPCI_REG_REVERSE_FR); 1371 } 1372 return; 1373 case CMPCI_SPDIF_IN_PHASE: 1374 if (CMPCI_ISCAP(sc, SPDIN_PHASE)) { 1375 if (sc->sc_gain[CMPCI_SPDIF_IN_PHASE][CMPCI_LR] 1376 == CMPCI_SPDIF_IN_PHASE_POSITIVE) 1377 cmpci_reg_clear_1(sc, CMPCI_REG_CHANNEL_FORMAT, 1378 CMPCI_REG_SPDIN_PHASE); 1379 else 1380 cmpci_reg_set_1(sc, CMPCI_REG_CHANNEL_FORMAT, 1381 CMPCI_REG_SPDIN_PHASE); 1382 } 1383 return; 1384 default: 1385 return; 1386 } 1387 1388 cmpci_mixerreg_write(sc, src, 1389 CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT])); 1390 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_L_TO_R(src), 1391 CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_RIGHT])); 1392 } 1393 1394 void 1395 cmpci_set_out_ports(struct cmpci_softc *sc) 1396 { 1397 struct cmpci_channel *chan; 1398 u_int8_t v; 1399 int enspdout = 0; 1400 1401 if (!CMPCI_ISCAP(sc, SPDLOOP)) 1402 return; 1403 1404 /* SPDIF/out select */ 1405 if (sc->sc_gain[CMPCI_SPDIF_LOOP][CMPCI_LR] == CMPCI_SPDIF_LOOP_OFF) { 1406 /* playback */ 1407 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP); 1408 } else { 1409 /* monitor SPDIF/in */ 1410 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP); 1411 } 1412 1413 /* SPDIF in select */ 1414 v = sc->sc_gain[CMPCI_SPDIF_IN_SELECT][CMPCI_LR]; 1415 if (v & CMPCI_SPDIFIN_SPDIFIN2) 1416 cmpci_reg_set_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN); 1417 else 1418 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN); 1419 if (v & CMPCI_SPDIFIN_SPDIFOUT) 1420 cmpci_reg_set_reg_misc(sc, CMPCI_REG_SPDFLOOPI); 1421 else 1422 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPDFLOOPI); 1423 1424 if (sc->sc_play_channel == 1) 1425 chan = &sc->sc_ch1; 1426 else 1427 chan = &sc->sc_ch0; 1428 1429 /* disable ac3 and 24 and 32 bit s/pdif modes */ 1430 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, CMPCI_REG_AC3EN1); 1431 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_AC3EN2); 1432 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPD32SEL); 1433 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, CMPCI_REG_SPDIF_24); 1434 1435 /* playback to ... */ 1436 if (CMPCI_ISCAP(sc, SPDOUT) && 1437 sc->sc_gain[CMPCI_PLAYBACK_MODE][CMPCI_LR] 1438 == CMPCI_PLAYBACK_MODE_SPDIF && 1439 (chan->md_divide == CMPCI_REG_RATE_44100 || 1440 (CMPCI_ISCAP(sc, SPDOUT_48K) && 1441 chan->md_divide == CMPCI_REG_RATE_48000))) { 1442 /* playback to SPDIF */ 1443 if (sc->sc_play_channel == 0) 1444 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 1445 CMPCI_REG_SPDIF0_ENABLE); 1446 else 1447 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 1448 CMPCI_REG_SPDIF1_ENABLE); 1449 enspdout = 1; 1450 if (chan->md_divide == CMPCI_REG_RATE_48000) 1451 cmpci_reg_set_reg_misc(sc, 1452 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K); 1453 else 1454 cmpci_reg_clear_reg_misc(sc, 1455 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K); 1456 /* XXX assume sample rate <= 48kHz */ 1457 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, 1458 CMPCI_REG_DBL_SPD_RATE); 1459 } else { 1460 /* playback to DAC */ 1461 if (sc->sc_play_channel == 0) 1462 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 1463 CMPCI_REG_SPDIF0_ENABLE); 1464 else 1465 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 1466 CMPCI_REG_SPDIF1_ENABLE); 1467 if (CMPCI_ISCAP(sc, SPDOUT_48K)) 1468 cmpci_reg_clear_reg_misc(sc, 1469 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K); 1470 } 1471 1472 /* legacy to SPDIF/out or not */ 1473 if (CMPCI_ISCAP(sc, SPDLEGACY)) { 1474 if (sc->sc_gain[CMPCI_SPDIF_OUT_PLAYBACK][CMPCI_LR] 1475 == CMPCI_SPDIF_OUT_PLAYBACK_WAVE) 1476 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 1477 CMPCI_REG_LEGACY_SPDIF_ENABLE); 1478 else { 1479 cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL, 1480 CMPCI_REG_LEGACY_SPDIF_ENABLE); 1481 enspdout = 1; 1482 } 1483 } 1484 1485 /* enable/disable SPDIF/out */ 1486 if (CMPCI_ISCAP(sc, XSPDOUT) && enspdout) 1487 cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL, 1488 CMPCI_REG_XSPDIF_ENABLE); 1489 else 1490 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 1491 CMPCI_REG_XSPDIF_ENABLE); 1492 1493 /* SPDIF monitor (digital to analog output) */ 1494 if (CMPCI_ISCAP(sc, SPDIN_MONITOR)) { 1495 v = sc->sc_gain[CMPCI_MONITOR_DAC][CMPCI_LR]; 1496 if (!(v & CMPCI_MONDAC_ENABLE)) 1497 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1498 CMPCI_REG_SPDIN_MONITOR); 1499 if (v & CMPCI_MONDAC_SPDOUT) 1500 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 1501 CMPCI_REG_SPDIFOUT_DAC); 1502 else 1503 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 1504 CMPCI_REG_SPDIFOUT_DAC); 1505 if (v & CMPCI_MONDAC_ENABLE) 1506 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1507 CMPCI_REG_SPDIN_MONITOR); 1508 } 1509 } 1510 1511 int 1512 cmpci_set_in_ports(struct cmpci_softc *sc) 1513 { 1514 int mask; 1515 int bitsl, bitsr; 1516 1517 mask = sc->sc_in_mask; 1518 1519 /* 1520 * Note CMPCI_RECORD_SOURCE_CD, CMPCI_RECORD_SOURCE_LINE_IN and 1521 * CMPCI_RECORD_SOURCE_FM are defined to the corresponding bit 1522 * of the mixer register. 1523 */ 1524 bitsr = mask & (CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN | 1525 CMPCI_RECORD_SOURCE_FM); 1526 1527 bitsl = CMPCI_SB16_MIXER_SRC_R_TO_L(bitsr); 1528 if (mask & CMPCI_RECORD_SOURCE_MIC) { 1529 bitsl |= CMPCI_SB16_MIXER_MIC_SRC; 1530 bitsr |= CMPCI_SB16_MIXER_MIC_SRC; 1531 } 1532 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, bitsl); 1533 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, bitsr); 1534 1535 if (mask & CMPCI_RECORD_SOURCE_AUX_IN) 1536 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25, 1537 CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN); 1538 else 1539 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25, 1540 CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN); 1541 1542 if (mask & CMPCI_RECORD_SOURCE_WAVE) 1543 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1544 CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR); 1545 else 1546 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1547 CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR); 1548 1549 if (CMPCI_ISCAP(sc, SPDIN) && 1550 (sc->sc_ch1.md_divide == CMPCI_REG_RATE_44100 || 1551 (CMPCI_ISCAP(sc, SPDOUT_48K) && 1552 sc->sc_ch1.md_divide == CMPCI_REG_RATE_48000/* XXX? */))) { 1553 if (mask & CMPCI_RECORD_SOURCE_SPDIF) { 1554 /* enable SPDIF/in */ 1555 cmpci_reg_set_4(sc, 1556 CMPCI_REG_FUNC_1, 1557 CMPCI_REG_SPDIF1_ENABLE); 1558 } else { 1559 cmpci_reg_clear_4(sc, 1560 CMPCI_REG_FUNC_1, 1561 CMPCI_REG_SPDIF1_ENABLE); 1562 } 1563 } 1564 1565 return 0; 1566 } 1567 1568 int 1569 cmpci_set_port(void *handle, mixer_ctrl_t *cp) 1570 { 1571 struct cmpci_softc *sc = handle; 1572 int lgain, rgain; 1573 1574 switch (cp->dev) { 1575 case CMPCI_MIC_VOL: 1576 case CMPCI_PCSPEAKER: 1577 case CMPCI_MIC_RECVOL: 1578 if (cp->un.value.num_channels != 1) 1579 return EINVAL; 1580 /* FALLTHROUGH */ 1581 case CMPCI_DAC_VOL: 1582 case CMPCI_FM_VOL: 1583 case CMPCI_CD_VOL: 1584 case CMPCI_LINE_IN_VOL: 1585 case CMPCI_AUX_IN_VOL: 1586 case CMPCI_MASTER_VOL: 1587 if (cp->type != AUDIO_MIXER_VALUE) 1588 return EINVAL; 1589 switch (cp->un.value.num_channels) { 1590 case 1: 1591 lgain = rgain = 1592 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 1593 break; 1594 case 2: 1595 lgain = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1596 rgain = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 1597 break; 1598 default: 1599 return EINVAL; 1600 } 1601 sc->sc_gain[cp->dev][CMPCI_LEFT] = lgain; 1602 sc->sc_gain[cp->dev][CMPCI_RIGHT] = rgain; 1603 1604 cmpci_set_mixer_gain(sc, cp->dev); 1605 break; 1606 1607 case CMPCI_RECORD_SOURCE: 1608 if (cp->type != AUDIO_MIXER_SET) 1609 return EINVAL; 1610 1611 if (cp->un.mask & ~(CMPCI_RECORD_SOURCE_MIC | 1612 CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN | 1613 CMPCI_RECORD_SOURCE_AUX_IN | CMPCI_RECORD_SOURCE_WAVE | 1614 CMPCI_RECORD_SOURCE_FM | CMPCI_RECORD_SOURCE_SPDIF)) 1615 return EINVAL; 1616 1617 if (cp->un.mask & CMPCI_RECORD_SOURCE_SPDIF) 1618 cp->un.mask = CMPCI_RECORD_SOURCE_SPDIF; 1619 1620 sc->sc_in_mask = cp->un.mask; 1621 return cmpci_set_in_ports(sc); 1622 1623 /* boolean */ 1624 case CMPCI_DAC_MUTE: 1625 case CMPCI_FM_MUTE: 1626 case CMPCI_CD_MUTE: 1627 case CMPCI_LINE_IN_MUTE: 1628 case CMPCI_AUX_IN_MUTE: 1629 case CMPCI_MIC_MUTE: 1630 case CMPCI_MIC_PREAMP: 1631 case CMPCI_PLAYBACK_MODE: 1632 case CMPCI_SPDIF_IN_PHASE: 1633 case CMPCI_SPDIF_LOOP: 1634 case CMPCI_SPDIF_OUT_PLAYBACK: 1635 case CMPCI_SPDIF_OUT_VOLTAGE: 1636 case CMPCI_REAR: 1637 case CMPCI_INDIVIDUAL: 1638 case CMPCI_REVERSE: 1639 case CMPCI_SURROUND: 1640 if (cp->type != AUDIO_MIXER_ENUM) 1641 return EINVAL; 1642 sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord != 0; 1643 cmpci_set_mixer_gain(sc, cp->dev); 1644 break; 1645 1646 case CMPCI_SPDIF_IN_SELECT: 1647 switch (cp->un.ord) { 1648 case CMPCI_SPDIF_IN_SPDIN1: 1649 case CMPCI_SPDIF_IN_SPDIN2: 1650 case CMPCI_SPDIF_IN_SPDOUT: 1651 break; 1652 default: 1653 return EINVAL; 1654 } 1655 goto xenum; 1656 case CMPCI_MONITOR_DAC: 1657 switch (cp->un.ord) { 1658 case CMPCI_MONITOR_DAC_OFF: 1659 case CMPCI_MONITOR_DAC_SPDIN: 1660 case CMPCI_MONITOR_DAC_SPDOUT: 1661 break; 1662 default: 1663 return EINVAL; 1664 } 1665 xenum: 1666 if (cp->type != AUDIO_MIXER_ENUM) 1667 return EINVAL; 1668 sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord; 1669 cmpci_set_mixer_gain(sc, cp->dev); 1670 break; 1671 1672 default: 1673 return EINVAL; 1674 } 1675 1676 return 0; 1677 } 1678 1679 int 1680 cmpci_get_port(void *handle, mixer_ctrl_t *cp) 1681 { 1682 struct cmpci_softc *sc = handle; 1683 1684 switch (cp->dev) { 1685 case CMPCI_MIC_VOL: 1686 case CMPCI_PCSPEAKER: 1687 case CMPCI_MIC_RECVOL: 1688 if (cp->un.value.num_channels != 1) 1689 return EINVAL; 1690 /*FALLTHROUGH*/ 1691 case CMPCI_DAC_VOL: 1692 case CMPCI_FM_VOL: 1693 case CMPCI_CD_VOL: 1694 case CMPCI_LINE_IN_VOL: 1695 case CMPCI_AUX_IN_VOL: 1696 case CMPCI_MASTER_VOL: 1697 switch (cp->un.value.num_channels) { 1698 case 1: 1699 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1700 sc->sc_gain[cp->dev][CMPCI_LEFT]; 1701 break; 1702 case 2: 1703 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1704 sc->sc_gain[cp->dev][CMPCI_LEFT]; 1705 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1706 sc->sc_gain[cp->dev][CMPCI_RIGHT]; 1707 break; 1708 default: 1709 return EINVAL; 1710 } 1711 break; 1712 1713 case CMPCI_RECORD_SOURCE: 1714 cp->un.mask = sc->sc_in_mask; 1715 break; 1716 1717 case CMPCI_DAC_MUTE: 1718 case CMPCI_FM_MUTE: 1719 case CMPCI_CD_MUTE: 1720 case CMPCI_LINE_IN_MUTE: 1721 case CMPCI_AUX_IN_MUTE: 1722 case CMPCI_MIC_MUTE: 1723 case CMPCI_MIC_PREAMP: 1724 case CMPCI_PLAYBACK_MODE: 1725 case CMPCI_SPDIF_IN_SELECT: 1726 case CMPCI_SPDIF_IN_PHASE: 1727 case CMPCI_SPDIF_LOOP: 1728 case CMPCI_SPDIF_OUT_PLAYBACK: 1729 case CMPCI_SPDIF_OUT_VOLTAGE: 1730 case CMPCI_MONITOR_DAC: 1731 case CMPCI_REAR: 1732 case CMPCI_INDIVIDUAL: 1733 case CMPCI_REVERSE: 1734 case CMPCI_SURROUND: 1735 cp->un.ord = sc->sc_gain[cp->dev][CMPCI_LR]; 1736 break; 1737 1738 default: 1739 return EINVAL; 1740 } 1741 1742 return 0; 1743 } 1744 1745 size_t 1746 cmpci_round_buffersize(void *handle, int direction, size_t bufsize) 1747 { 1748 if (bufsize > 0x10000) 1749 bufsize = 0x10000; 1750 1751 return bufsize; 1752 } 1753 1754 int 1755 cmpci_trigger_output(void *handle, void *start, void *end, int blksize, 1756 void (*intr)(void *), void *arg, struct audio_params *param) 1757 { 1758 struct cmpci_softc *sc = handle; 1759 struct cmpci_dmanode *p; 1760 struct cmpci_channel *chan; 1761 uint32_t reg_dma_base, reg_dma_bytes, reg_dma_samples, reg_dir, 1762 reg_intr_enable, reg_enable; 1763 uint32_t length; 1764 size_t buffer_size = (caddr_t)end - (caddr_t)start; 1765 1766 cmpci_set_out_ports(sc); 1767 1768 if (sc->sc_play_channel == 1) { 1769 chan = &sc->sc_ch1; 1770 reg_dma_base = CMPCI_REG_DMA1_BASE; 1771 reg_dma_bytes = CMPCI_REG_DMA1_BYTES; 1772 reg_dma_samples = CMPCI_REG_DMA1_SAMPLES; 1773 reg_dir = CMPCI_REG_CH1_DIR; 1774 reg_intr_enable = CMPCI_REG_CH1_INTR_ENABLE; 1775 reg_enable = CMPCI_REG_CH1_ENABLE; 1776 } else { 1777 chan = &sc->sc_ch0; 1778 reg_dma_base = CMPCI_REG_DMA0_BASE; 1779 reg_dma_bytes = CMPCI_REG_DMA0_BYTES; 1780 reg_dma_samples = CMPCI_REG_DMA0_SAMPLES; 1781 reg_dir = CMPCI_REG_CH0_DIR; 1782 reg_intr_enable = CMPCI_REG_CH0_INTR_ENABLE; 1783 reg_enable = CMPCI_REG_CH0_ENABLE; 1784 } 1785 1786 chan->bps = (param->channels > 1 ? 2 : 1) * param->bps; 1787 if (!chan->bps) 1788 return EINVAL; 1789 1790 chan->intr = intr; 1791 chan->intr_arg = arg; 1792 chan->blksize = blksize; 1793 chan->nblocks = buffer_size / chan->blksize; 1794 chan->swpos = 0; 1795 1796 /* set DMA frame */ 1797 if (!(p = cmpci_find_dmamem(sc, start))) 1798 return EINVAL; 1799 bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_dma_base, 1800 DMAADDR(p)); 1801 delay(10); 1802 length = (buffer_size + 1) / chan->bps - 1; 1803 bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_bytes, length); 1804 delay(10); 1805 1806 /* set interrupt count */ 1807 length = (chan->blksize + chan->bps - 1) / chan->bps - 1; 1808 bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_samples, length); 1809 delay(10); 1810 1811 /* start DMA */ 1812 mtx_enter(&audio_lock); 1813 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_dir); /* PLAY */ 1814 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, reg_intr_enable); 1815 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_enable); 1816 mtx_leave(&audio_lock); 1817 return 0; 1818 } 1819 1820 int 1821 cmpci_trigger_input(void *handle, void *start, void *end, int blksize, 1822 void (*intr)(void *), void *arg, struct audio_params *param) 1823 { 1824 struct cmpci_softc *sc = handle; 1825 struct cmpci_dmanode *p; 1826 struct cmpci_channel *chan = &sc->sc_ch1; 1827 size_t buffer_size = (caddr_t)end - (caddr_t)start; 1828 1829 cmpci_set_in_ports(sc); 1830 1831 chan->bps = param->channels * param->bps; 1832 if (!chan->bps) 1833 return EINVAL; 1834 1835 chan->intr = intr; 1836 chan->intr_arg = arg; 1837 chan->blksize = blksize; 1838 chan->nblocks = buffer_size / chan->blksize; 1839 chan->swpos = 0; 1840 1841 /* set DMA frame */ 1842 if (!(p = cmpci_find_dmamem(sc, start))) 1843 return EINVAL; 1844 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BASE, 1845 DMAADDR(p)); 1846 delay(10); 1847 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BYTES, 1848 (buffer_size + 1) / chan->bps - 1); 1849 delay(10); 1850 1851 /* set interrupt count */ 1852 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_SAMPLES, 1853 (chan->blksize + chan->bps - 1) / chan->bps - 1); 1854 delay(10); 1855 1856 /* start DMA */ 1857 mtx_enter(&audio_lock); 1858 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR); /* REC */ 1859 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 1860 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 1861 mtx_leave(&audio_lock); 1862 return 0; 1863 } 1864 1865 /* end of file */ 1866