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