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