1 /* $OpenBSD: cmpci.c,v 1.45 2018/09/14 08:37:34 miko 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 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 515 switch (act) { 516 case DVACT_RESUME: 517 cmpci_resume(sc); 518 break; 519 default: 520 break; 521 } 522 return (config_activate_children(self, act)); 523 } 524 525 void 526 cmpci_resume(struct cmpci_softc *sc) 527 { 528 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_RESET, 0); 529 } 530 531 int 532 cmpci_intr(void *handle) 533 { 534 struct cmpci_softc *sc = handle; 535 struct cmpci_channel *chan; 536 uint32_t intrstat; 537 uint16_t hwpos; 538 539 mtx_enter(&audio_lock); 540 intrstat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 541 CMPCI_REG_INTR_STATUS); 542 543 if (!(intrstat & CMPCI_REG_ANY_INTR)) { 544 mtx_leave(&audio_lock); 545 return 0; 546 } 547 548 delay(10); 549 550 /* disable and reset intr */ 551 if (intrstat & CMPCI_REG_CH0_INTR) 552 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 553 CMPCI_REG_CH0_INTR_ENABLE); 554 if (intrstat & CMPCI_REG_CH1_INTR) 555 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 556 CMPCI_REG_CH1_INTR_ENABLE); 557 558 if (intrstat & CMPCI_REG_CH0_INTR) { 559 chan = &sc->sc_ch0; 560 if (chan->intr != NULL) { 561 hwpos = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 562 CMPCI_REG_DMA0_BYTES); 563 hwpos = hwpos * chan->bps / chan->blksize; 564 hwpos = chan->nblocks - hwpos - 1; 565 while (chan->swpos != hwpos) { 566 (*chan->intr)(chan->intr_arg); 567 chan->swpos++; 568 if (chan->swpos >= chan->nblocks) 569 chan->swpos = 0; 570 if (chan->swpos != hwpos) { 571 DPRINTF(("%s: DMA0 hwpos=%d swpos=%d\n", 572 __func__, hwpos, chan->swpos)); 573 } 574 } 575 } 576 } 577 if (intrstat & CMPCI_REG_CH1_INTR) { 578 chan = &sc->sc_ch1; 579 if (chan->intr != NULL) { 580 hwpos = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 581 CMPCI_REG_DMA1_BYTES); 582 hwpos = hwpos * chan->bps / chan->blksize; 583 hwpos = chan->nblocks - hwpos - 1; 584 while (chan->swpos != hwpos) { 585 (*chan->intr)(chan->intr_arg); 586 chan->swpos++; 587 if (chan->swpos >= chan->nblocks) 588 chan->swpos = 0; 589 if (chan->swpos != hwpos) { 590 DPRINTF(("%s: DMA1 hwpos=%d swpos=%d\n", 591 __func__, hwpos, chan->swpos)); 592 } 593 } 594 } 595 } 596 597 /* enable intr */ 598 if (intrstat & CMPCI_REG_CH0_INTR) 599 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 600 CMPCI_REG_CH0_INTR_ENABLE); 601 if (intrstat & CMPCI_REG_CH1_INTR) 602 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 603 CMPCI_REG_CH1_INTR_ENABLE); 604 605 #if 0 606 if (intrstat & CMPCI_REG_UART_INTR && sc->sc_mpudev != NULL) 607 mpu_intr(sc->sc_mpudev); 608 #endif 609 610 mtx_leave(&audio_lock); 611 return 1; 612 } 613 614 /* open/close */ 615 int 616 cmpci_open(void *handle, int flags) 617 { 618 return 0; 619 } 620 621 void 622 cmpci_close(void *handle) 623 { 624 } 625 626 int 627 cmpci_set_params(void *handle, int setmode, int usemode, 628 struct audio_params *play, struct audio_params *rec) 629 { 630 int i; 631 struct cmpci_softc *sc = handle; 632 633 for (i = 0; i < 2; i++) { 634 int md_format; 635 int md_divide; 636 int md_index; 637 int mode; 638 struct audio_params *p; 639 640 switch (i) { 641 case 0: 642 mode = AUMODE_PLAY; 643 p = play; 644 break; 645 case 1: 646 mode = AUMODE_RECORD; 647 p = rec; 648 break; 649 default: 650 return EINVAL; 651 } 652 653 if (!(setmode & mode)) 654 continue; 655 656 if (setmode & AUMODE_RECORD) { 657 if (p->channels > 2) 658 p->channels = 2; 659 sc->sc_play_channel = 0; 660 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_ENDBDAC); 661 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_XCHGDAC); 662 } else { 663 sc->sc_play_channel = 1; 664 cmpci_reg_set_reg_misc(sc, CMPCI_REG_ENDBDAC); 665 cmpci_reg_set_reg_misc(sc, CMPCI_REG_XCHGDAC); 666 } 667 668 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 669 CMPCI_REG_NXCHG); 670 if (sc->sc_capable & CMPCI_CAP_4CH) 671 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, 672 CMPCI_REG_CHB3D); 673 if (sc->sc_capable & CMPCI_CAP_6CH) { 674 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, 675 CMPCI_REG_CHB3D5C); 676 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 677 CMPCI_REG_CHB3D6C); 678 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_ENCENTER); 679 } 680 if (sc->sc_capable & CMPCI_CAP_8CH) 681 cmpci_reg_clear_4(sc, CMPCI_REG_8768_MISC, 682 CMPCI_REG_CHB3D8C); 683 684 /* format */ 685 switch (p->channels) { 686 case 1: 687 md_format = CMPCI_REG_FORMAT_MONO; 688 break; 689 case 2: 690 md_format = CMPCI_REG_FORMAT_STEREO; 691 break; 692 case 4: 693 if (mode & AUMODE_PLAY) { 694 if (sc->sc_capable & CMPCI_CAP_4CH) { 695 cmpci_reg_clear_reg_misc(sc, 696 CMPCI_REG_N4SPK3D); 697 cmpci_reg_set_4(sc, 698 CMPCI_REG_CHANNEL_FORMAT, 699 CMPCI_REG_CHB3D); 700 cmpci_reg_set_4(sc, 701 CMPCI_REG_LEGACY_CTRL, 702 CMPCI_REG_NXCHG); 703 } else 704 p->channels = 2; 705 } 706 md_format = CMPCI_REG_FORMAT_STEREO; 707 break; 708 case 6: 709 if (mode & AUMODE_PLAY) { 710 if (sc->sc_capable & CMPCI_CAP_6CH) { 711 cmpci_reg_clear_reg_misc(sc, 712 CMPCI_REG_N4SPK3D); 713 cmpci_reg_set_4(sc, 714 CMPCI_REG_CHANNEL_FORMAT, 715 CMPCI_REG_CHB3D5C); 716 cmpci_reg_set_4(sc, 717 CMPCI_REG_LEGACY_CTRL, 718 CMPCI_REG_CHB3D6C); 719 cmpci_reg_set_reg_misc(sc, 720 CMPCI_REG_ENCENTER); 721 cmpci_reg_set_4(sc, 722 CMPCI_REG_LEGACY_CTRL, 723 CMPCI_REG_NXCHG); 724 } else 725 p->channels = 2; 726 } 727 md_format = CMPCI_REG_FORMAT_STEREO; 728 break; 729 case 8: 730 if (mode & AUMODE_PLAY) { 731 if (sc->sc_capable & CMPCI_CAP_8CH) { 732 cmpci_reg_clear_reg_misc(sc, 733 CMPCI_REG_N4SPK3D); 734 cmpci_reg_set_4(sc, 735 CMPCI_REG_CHANNEL_FORMAT, 736 CMPCI_REG_CHB3D5C); 737 cmpci_reg_set_4(sc, 738 CMPCI_REG_LEGACY_CTRL, 739 CMPCI_REG_CHB3D6C); 740 cmpci_reg_set_reg_misc(sc, 741 CMPCI_REG_ENCENTER); 742 cmpci_reg_set_4(sc, 743 CMPCI_REG_8768_MISC, 744 CMPCI_REG_CHB3D8C); 745 cmpci_reg_set_4(sc, 746 CMPCI_REG_LEGACY_CTRL, 747 CMPCI_REG_NXCHG); 748 } else 749 p->channels = 2; 750 } 751 md_format = CMPCI_REG_FORMAT_STEREO; 752 break; 753 default: 754 return (EINVAL); 755 } 756 if (p->precision >= 16) { 757 p->precision = 16; 758 p->encoding = AUDIO_ENCODING_SLINEAR_LE; 759 md_format |= CMPCI_REG_FORMAT_16BIT; 760 } else { 761 p->precision = 8; 762 p->encoding = AUDIO_ENCODING_ULINEAR_LE; 763 md_format |= CMPCI_REG_FORMAT_8BIT; 764 } 765 p->bps = AUDIO_BPS(p->precision); 766 p->msb = 1; 767 if (mode & AUMODE_PLAY) { 768 if (sc->sc_play_channel == 1) { 769 cmpci_reg_partial_write_4(sc, 770 CMPCI_REG_CHANNEL_FORMAT, 771 CMPCI_REG_CH1_FORMAT_SHIFT, 772 CMPCI_REG_CH1_FORMAT_MASK, md_format); 773 } else { 774 cmpci_reg_partial_write_4(sc, 775 CMPCI_REG_CHANNEL_FORMAT, 776 CMPCI_REG_CH0_FORMAT_SHIFT, 777 CMPCI_REG_CH0_FORMAT_MASK, md_format); 778 } 779 } else { 780 cmpci_reg_partial_write_4(sc, 781 CMPCI_REG_CHANNEL_FORMAT, 782 CMPCI_REG_CH1_FORMAT_SHIFT, 783 CMPCI_REG_CH1_FORMAT_MASK, md_format); 784 } 785 /* sample rate */ 786 md_index = cmpci_rate_to_index(p->sample_rate); 787 md_divide = cmpci_index_to_divider(md_index); 788 p->sample_rate = cmpci_index_to_rate(md_index); 789 DPRINTF(("%s: sample:%d, divider=%d\n", 790 sc->sc_dev.dv_xname, (int)p->sample_rate, md_divide)); 791 if (mode & AUMODE_PLAY) { 792 if (sc->sc_play_channel == 1) { 793 cmpci_reg_partial_write_4(sc, 794 CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT, 795 CMPCI_REG_ADC_FS_MASK, md_divide); 796 sc->sc_ch1.md_divide = md_divide; 797 } else { 798 cmpci_reg_partial_write_4(sc, 799 CMPCI_REG_FUNC_1, CMPCI_REG_DAC_FS_SHIFT, 800 CMPCI_REG_DAC_FS_MASK, md_divide); 801 sc->sc_ch0.md_divide = md_divide; 802 } 803 } else { 804 cmpci_reg_partial_write_4(sc, 805 CMPCI_REG_FUNC_1, CMPCI_REG_ADC_FS_SHIFT, 806 CMPCI_REG_ADC_FS_MASK, md_divide); 807 sc->sc_ch1.md_divide = md_divide; 808 } 809 } 810 811 return 0; 812 } 813 814 /* ARGSUSED */ 815 int 816 cmpci_round_blocksize(void *handle, int block) 817 { 818 return ((block + 3) & -4); 819 } 820 821 int 822 cmpci_halt_output(void *handle) 823 { 824 struct cmpci_softc *sc = handle; 825 uint32_t reg_intr, reg_enable, reg_reset; 826 827 mtx_enter(&audio_lock); 828 if (sc->sc_play_channel == 1) { 829 sc->sc_ch1.intr = NULL; 830 reg_intr = CMPCI_REG_CH1_INTR_ENABLE; 831 reg_enable = CMPCI_REG_CH1_ENABLE; 832 reg_reset = CMPCI_REG_CH1_RESET; 833 } else { 834 sc->sc_ch0.intr = NULL; 835 reg_intr = CMPCI_REG_CH0_INTR_ENABLE; 836 reg_enable = CMPCI_REG_CH0_ENABLE; 837 reg_reset = CMPCI_REG_CH0_RESET; 838 } 839 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, reg_intr); 840 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_enable); 841 /* wait for reset DMA */ 842 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_reset); 843 delay(10); 844 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_reset); 845 mtx_leave(&audio_lock); 846 return 0; 847 } 848 849 int 850 cmpci_halt_input(void *handle) 851 { 852 struct cmpci_softc *sc = handle; 853 854 mtx_enter(&audio_lock); 855 sc->sc_ch1.intr = NULL; 856 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 857 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 858 /* wait for reset DMA */ 859 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 860 delay(10); 861 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 862 mtx_leave(&audio_lock); 863 return 0; 864 } 865 866 /* mixer device information */ 867 int 868 cmpci_query_devinfo(void *handle, mixer_devinfo_t *dip) 869 { 870 static const char *const mixer_port_names[] = { 871 AudioNdac, AudioNfmsynth, AudioNcd, AudioNline, AudioNaux, 872 AudioNmicrophone 873 }; 874 static const char *const mixer_classes[] = { 875 AudioCinputs, AudioCoutputs, AudioCrecord, CmpciCplayback, 876 CmpciCspdif 877 }; 878 struct cmpci_softc *sc = handle; 879 int i; 880 881 dip->prev = dip->next = AUDIO_MIXER_LAST; 882 883 switch (dip->index) { 884 case CMPCI_INPUT_CLASS: 885 case CMPCI_OUTPUT_CLASS: 886 case CMPCI_RECORD_CLASS: 887 case CMPCI_PLAYBACK_CLASS: 888 case CMPCI_SPDIF_CLASS: 889 dip->type = AUDIO_MIXER_CLASS; 890 dip->mixer_class = dip->index; 891 strlcpy(dip->label.name, 892 mixer_classes[dip->index - CMPCI_INPUT_CLASS], 893 sizeof dip->label.name); 894 return 0; 895 896 case CMPCI_AUX_IN_VOL: 897 dip->un.v.delta = 1 << (8 - CMPCI_REG_AUX_VALBITS); 898 goto vol1; 899 case CMPCI_DAC_VOL: 900 case CMPCI_FM_VOL: 901 case CMPCI_CD_VOL: 902 case CMPCI_LINE_IN_VOL: 903 case CMPCI_MIC_VOL: 904 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS); 905 vol1: dip->mixer_class = CMPCI_INPUT_CLASS; 906 dip->next = dip->index + 6; /* CMPCI_xxx_MUTE */ 907 strlcpy(dip->label.name, mixer_port_names[dip->index], 908 sizeof dip->label.name); 909 dip->un.v.num_channels = (dip->index == CMPCI_MIC_VOL ? 1 : 2); 910 vol: 911 dip->type = AUDIO_MIXER_VALUE; 912 strlcpy(dip->un.v.units.name, AudioNvolume, 913 sizeof dip->un.v.units.name); 914 return 0; 915 916 case CMPCI_MIC_MUTE: 917 dip->next = CMPCI_MIC_PREAMP; 918 /* FALLTHROUGH */ 919 case CMPCI_DAC_MUTE: 920 case CMPCI_FM_MUTE: 921 case CMPCI_CD_MUTE: 922 case CMPCI_LINE_IN_MUTE: 923 case CMPCI_AUX_IN_MUTE: 924 dip->prev = dip->index - 6; /* CMPCI_xxx_VOL */ 925 dip->mixer_class = CMPCI_INPUT_CLASS; 926 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 927 goto on_off; 928 on_off: 929 dip->type = AUDIO_MIXER_ENUM; 930 dip->un.e.num_mem = 2; 931 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 932 sizeof dip->un.e.member[0].label.name); 933 dip->un.e.member[0].ord = 0; 934 strlcpy(dip->un.e.member[1].label.name, AudioNon, 935 sizeof dip->un.e.member[1].label.name); 936 dip->un.e.member[1].ord = 1; 937 return 0; 938 939 case CMPCI_MIC_PREAMP: 940 dip->mixer_class = CMPCI_INPUT_CLASS; 941 dip->prev = CMPCI_MIC_MUTE; 942 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name); 943 goto on_off; 944 case CMPCI_PCSPEAKER: 945 dip->mixer_class = CMPCI_INPUT_CLASS; 946 strlcpy(dip->label.name, AudioNspeaker, sizeof dip->label.name); 947 dip->un.v.num_channels = 1; 948 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_SPEAKER_VALBITS); 949 goto vol; 950 case CMPCI_RECORD_SOURCE: 951 dip->mixer_class = CMPCI_RECORD_CLASS; 952 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 953 dip->type = AUDIO_MIXER_SET; 954 dip->un.s.num_mem = 7; 955 strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone, 956 sizeof dip->un.s.member[0].label.name); 957 dip->un.s.member[0].mask = CMPCI_RECORD_SOURCE_MIC; 958 strlcpy(dip->un.s.member[1].label.name, AudioNcd, 959 sizeof dip->un.s.member[1].label.name); 960 dip->un.s.member[1].mask = CMPCI_RECORD_SOURCE_CD; 961 strlcpy(dip->un.s.member[2].label.name, AudioNline, 962 sizeof dip->un.s.member[2].label.name); 963 dip->un.s.member[2].mask = CMPCI_RECORD_SOURCE_LINE_IN; 964 strlcpy(dip->un.s.member[3].label.name, AudioNaux, 965 sizeof dip->un.s.member[3].label.name); 966 dip->un.s.member[3].mask = CMPCI_RECORD_SOURCE_AUX_IN; 967 strlcpy(dip->un.s.member[4].label.name, AudioNwave, 968 sizeof dip->un.s.member[4].label.name); 969 dip->un.s.member[4].mask = CMPCI_RECORD_SOURCE_WAVE; 970 strlcpy(dip->un.s.member[5].label.name, AudioNfmsynth, 971 sizeof dip->un.s.member[5].label.name); 972 dip->un.s.member[5].mask = CMPCI_RECORD_SOURCE_FM; 973 strlcpy(dip->un.s.member[6].label.name, CmpciNspdif, 974 sizeof dip->un.s.member[6].label.name); 975 dip->un.s.member[6].mask = CMPCI_RECORD_SOURCE_SPDIF; 976 return 0; 977 case CMPCI_MIC_RECVOL: 978 dip->mixer_class = CMPCI_RECORD_CLASS; 979 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 980 dip->un.v.num_channels = 1; 981 dip->un.v.delta = 1 << (8 - CMPCI_REG_ADMIC_VALBITS); 982 goto vol; 983 984 case CMPCI_PLAYBACK_MODE: 985 dip->mixer_class = CMPCI_PLAYBACK_CLASS; 986 dip->type = AUDIO_MIXER_ENUM; 987 strlcpy(dip->label.name, AudioNmode, sizeof dip->label.name); 988 dip->un.e.num_mem = 2; 989 strlcpy(dip->un.e.member[0].label.name, AudioNdac, 990 sizeof dip->un.e.member[0].label.name); 991 dip->un.e.member[0].ord = CMPCI_PLAYBACK_MODE_WAVE; 992 strlcpy(dip->un.e.member[1].label.name, CmpciNspdif, 993 sizeof dip->un.e.member[1].label.name); 994 dip->un.e.member[1].ord = CMPCI_PLAYBACK_MODE_SPDIF; 995 return 0; 996 case CMPCI_SPDIF_IN_SELECT: 997 dip->mixer_class = CMPCI_SPDIF_CLASS; 998 dip->type = AUDIO_MIXER_ENUM; 999 dip->next = CMPCI_SPDIF_IN_PHASE; 1000 strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name); 1001 i = 0; 1002 strlcpy(dip->un.e.member[i].label.name, CmpciNspdin1, 1003 sizeof dip->un.e.member[i].label.name); 1004 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN1; 1005 if (CMPCI_ISCAP(sc, 2ND_SPDIN)) { 1006 strlcpy(dip->un.e.member[i].label.name, CmpciNspdin2, 1007 sizeof dip->un.e.member[i].label.name); 1008 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN2; 1009 } 1010 strlcpy(dip->un.e.member[i].label.name, CmpciNspdout, 1011 sizeof dip->un.e.member[i].label.name); 1012 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDOUT; 1013 dip->un.e.num_mem = i; 1014 return 0; 1015 case CMPCI_SPDIF_IN_PHASE: 1016 dip->mixer_class = CMPCI_SPDIF_CLASS; 1017 dip->prev = CMPCI_SPDIF_IN_SELECT; 1018 strlcpy(dip->label.name, CmpciNphase, sizeof dip->label.name); 1019 dip->type = AUDIO_MIXER_ENUM; 1020 dip->un.e.num_mem = 2; 1021 strlcpy(dip->un.e.member[0].label.name, CmpciNpositive, 1022 sizeof dip->un.e.member[0].label.name); 1023 dip->un.e.member[0].ord = CMPCI_SPDIF_IN_PHASE_POSITIVE; 1024 strlcpy(dip->un.e.member[1].label.name, CmpciNnegative, 1025 sizeof dip->un.e.member[1].label.name); 1026 dip->un.e.member[1].ord = CMPCI_SPDIF_IN_PHASE_NEGATIVE; 1027 return 0; 1028 case CMPCI_SPDIF_LOOP: 1029 dip->mixer_class = CMPCI_SPDIF_CLASS; 1030 dip->next = CMPCI_SPDIF_OUT_PLAYBACK; 1031 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 1032 dip->type = AUDIO_MIXER_ENUM; 1033 dip->un.e.num_mem = 2; 1034 strlcpy(dip->un.e.member[0].label.name, CmpciNplayback, 1035 sizeof dip->un.e.member[0].label.name); 1036 dip->un.e.member[0].ord = CMPCI_SPDIF_LOOP_OFF; 1037 strlcpy(dip->un.e.member[1].label.name, CmpciNspdin, 1038 sizeof dip->un.e.member[1].label.name); 1039 dip->un.e.member[1].ord = CMPCI_SPDIF_LOOP_ON; 1040 return 0; 1041 case CMPCI_SPDIF_OUT_PLAYBACK: 1042 dip->mixer_class = CMPCI_SPDIF_CLASS; 1043 dip->prev = CMPCI_SPDIF_LOOP; 1044 dip->next = CMPCI_SPDIF_OUT_VOLTAGE; 1045 strlcpy(dip->label.name, CmpciNplayback, sizeof dip->label.name); 1046 dip->type = AUDIO_MIXER_ENUM; 1047 dip->un.e.num_mem = 2; 1048 strlcpy(dip->un.e.member[0].label.name, AudioNwave, 1049 sizeof dip->un.e.member[0].label.name); 1050 dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_PLAYBACK_WAVE; 1051 strlcpy(dip->un.e.member[1].label.name, CmpciNlegacy, 1052 sizeof dip->un.e.member[1].label.name); 1053 dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_PLAYBACK_LEGACY; 1054 return 0; 1055 case CMPCI_SPDIF_OUT_VOLTAGE: 1056 dip->mixer_class = CMPCI_SPDIF_CLASS; 1057 dip->prev = CMPCI_SPDIF_OUT_PLAYBACK; 1058 strlcpy(dip->label.name, CmpciNvoltage, sizeof dip->label.name); 1059 dip->type = AUDIO_MIXER_ENUM; 1060 dip->un.e.num_mem = 2; 1061 strlcpy(dip->un.e.member[0].label.name, CmpciNhigh_v, 1062 sizeof dip->un.e.member[0].label.name); 1063 dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_VOLTAGE_HIGH; 1064 strlcpy(dip->un.e.member[1].label.name, CmpciNlow_v, 1065 sizeof dip->un.e.member[1].label.name); 1066 dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_VOLTAGE_LOW; 1067 return 0; 1068 case CMPCI_MONITOR_DAC: 1069 dip->mixer_class = CMPCI_SPDIF_CLASS; 1070 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); 1071 dip->type = AUDIO_MIXER_ENUM; 1072 dip->un.e.num_mem = 3; 1073 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 1074 sizeof dip->un.e.member[0].label.name); 1075 dip->un.e.member[0].ord = CMPCI_MONITOR_DAC_OFF; 1076 strlcpy(dip->un.e.member[1].label.name, CmpciNspdin, 1077 sizeof dip->un.e.member[1].label.name); 1078 dip->un.e.member[1].ord = CMPCI_MONITOR_DAC_SPDIN; 1079 strlcpy(dip->un.e.member[2].label.name, CmpciNspdout, 1080 sizeof dip->un.e.member[2].label.name); 1081 dip->un.e.member[2].ord = CMPCI_MONITOR_DAC_SPDOUT; 1082 return 0; 1083 1084 case CMPCI_MASTER_VOL: 1085 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1086 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 1087 dip->un.v.num_channels = 2; 1088 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS); 1089 goto vol; 1090 case CMPCI_REAR: 1091 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1092 dip->next = CMPCI_INDIVIDUAL; 1093 strlcpy(dip->label.name, CmpciNrear, sizeof dip->label.name); 1094 goto on_off; 1095 case CMPCI_INDIVIDUAL: 1096 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1097 dip->prev = CMPCI_REAR; 1098 dip->next = CMPCI_REVERSE; 1099 strlcpy(dip->label.name, CmpciNindividual, sizeof dip->label.name); 1100 goto on_off; 1101 case CMPCI_REVERSE: 1102 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1103 dip->prev = CMPCI_INDIVIDUAL; 1104 strlcpy(dip->label.name, CmpciNreverse, sizeof dip->label.name); 1105 goto on_off; 1106 case CMPCI_SURROUND: 1107 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1108 strlcpy(dip->label.name, CmpciNsurround, sizeof dip->label.name); 1109 goto on_off; 1110 } 1111 1112 return ENXIO; 1113 } 1114 1115 int 1116 cmpci_alloc_dmamem(struct cmpci_softc *sc, size_t size, int type, int flags, 1117 caddr_t *r_addr) 1118 { 1119 int error = 0; 1120 struct cmpci_dmanode *n; 1121 int w; 1122 1123 n = malloc(sizeof(struct cmpci_dmanode), type, flags); 1124 if (n == NULL) { 1125 error = ENOMEM; 1126 goto quit; 1127 } 1128 1129 w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK; 1130 #define CMPCI_DMABUF_ALIGN 0x4 1131 #define CMPCI_DMABUF_BOUNDARY 0x0 1132 n->cd_tag = sc->sc_dmat; 1133 n->cd_size = size; 1134 error = bus_dmamem_alloc(n->cd_tag, n->cd_size, 1135 CMPCI_DMABUF_ALIGN, CMPCI_DMABUF_BOUNDARY, n->cd_segs, 1136 nitems(n->cd_segs), &n->cd_nsegs, w); 1137 if (error) 1138 goto mfree; 1139 error = bus_dmamem_map(n->cd_tag, n->cd_segs, n->cd_nsegs, n->cd_size, 1140 &n->cd_addr, w | BUS_DMA_COHERENT); 1141 if (error) 1142 goto dmafree; 1143 error = bus_dmamap_create(n->cd_tag, n->cd_size, 1, n->cd_size, 0, 1144 w, &n->cd_map); 1145 if (error) 1146 goto unmap; 1147 error = bus_dmamap_load(n->cd_tag, n->cd_map, n->cd_addr, n->cd_size, 1148 NULL, w); 1149 if (error) 1150 goto destroy; 1151 1152 n->cd_next = sc->sc_dmap; 1153 sc->sc_dmap = n; 1154 *r_addr = KVADDR(n); 1155 return 0; 1156 1157 destroy: 1158 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1159 unmap: 1160 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1161 dmafree: 1162 bus_dmamem_free(n->cd_tag, 1163 n->cd_segs, nitems(n->cd_segs)); 1164 mfree: 1165 free(n, type, 0); 1166 quit: 1167 return error; 1168 } 1169 1170 int 1171 cmpci_free_dmamem(struct cmpci_softc *sc, caddr_t addr, int type) 1172 { 1173 struct cmpci_dmanode **nnp; 1174 1175 for (nnp = &sc->sc_dmap; *nnp; nnp = &(*nnp)->cd_next) { 1176 if ((*nnp)->cd_addr == addr) { 1177 struct cmpci_dmanode *n = *nnp; 1178 bus_dmamap_unload(n->cd_tag, n->cd_map); 1179 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1180 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1181 bus_dmamem_free(n->cd_tag, n->cd_segs, 1182 nitems(n->cd_segs)); 1183 free(n, type, 0); 1184 return 0; 1185 } 1186 } 1187 return -1; 1188 } 1189 1190 struct cmpci_dmanode * 1191 cmpci_find_dmamem(struct cmpci_softc *sc, caddr_t addr) 1192 { 1193 struct cmpci_dmanode *p; 1194 1195 for (p = sc->sc_dmap; p; p = p->cd_next) { 1196 if (KVADDR(p) == (void *)addr) 1197 break; 1198 } 1199 return p; 1200 } 1201 1202 #if 0 1203 void cmpci_print_dmamem(struct cmpci_dmanode *p); 1204 1205 void 1206 cmpci_print_dmamem(struct cmpci_dmanode *p) 1207 { 1208 DPRINTF(("DMA at virt:%p, dmaseg:%p, mapseg:%p, size:%p\n", 1209 (void *)p->cd_addr, (void *)p->cd_segs[0].ds_addr, 1210 (void *)DMAADDR(p), (void *)p->cd_size)); 1211 } 1212 #endif /* DEBUG */ 1213 1214 void * 1215 cmpci_malloc(void *handle, int direction, size_t size, int type, 1216 int flags) 1217 { 1218 caddr_t addr; 1219 1220 if (cmpci_alloc_dmamem(handle, size, type, flags, &addr)) 1221 return NULL; 1222 return addr; 1223 } 1224 1225 void 1226 cmpci_free(void *handle, void *addr, int type) 1227 { 1228 cmpci_free_dmamem(handle, addr, type); 1229 } 1230 1231 #define MAXVAL 256 1232 int 1233 cmpci_adjust(int val, int mask) 1234 { 1235 val += (MAXVAL - mask) >> 1; 1236 if (val >= MAXVAL) 1237 val = MAXVAL-1; 1238 return val & mask; 1239 } 1240 1241 void 1242 cmpci_set_mixer_gain(struct cmpci_softc *sc, int port) 1243 { 1244 int src; 1245 int bits, mask; 1246 1247 switch (port) { 1248 case CMPCI_MIC_VOL: 1249 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_MIC, 1250 CMPCI_ADJUST_MIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR])); 1251 return; 1252 case CMPCI_MASTER_VOL: 1253 src = CMPCI_SB16_MIXER_MASTER_L; 1254 break; 1255 case CMPCI_LINE_IN_VOL: 1256 src = CMPCI_SB16_MIXER_LINE_L; 1257 break; 1258 case CMPCI_AUX_IN_VOL: 1259 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MIXER_AUX, 1260 CMPCI_ADJUST_AUX_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT], 1261 sc->sc_gain[port][CMPCI_RIGHT])); 1262 return; 1263 case CMPCI_MIC_RECVOL: 1264 cmpci_reg_partial_write_1(sc, CMPCI_REG_MIXER25, 1265 CMPCI_REG_ADMIC_SHIFT, CMPCI_REG_ADMIC_MASK, 1266 CMPCI_ADJUST_ADMIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR])); 1267 return; 1268 case CMPCI_DAC_VOL: 1269 src = CMPCI_SB16_MIXER_VOICE_L; 1270 break; 1271 case CMPCI_FM_VOL: 1272 src = CMPCI_SB16_MIXER_FM_L; 1273 break; 1274 case CMPCI_CD_VOL: 1275 src = CMPCI_SB16_MIXER_CDDA_L; 1276 break; 1277 case CMPCI_PCSPEAKER: 1278 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_SPEAKER, 1279 CMPCI_ADJUST_2_GAIN(sc, sc->sc_gain[port][CMPCI_LR])); 1280 return; 1281 case CMPCI_MIC_PREAMP: 1282 if (sc->sc_gain[port][CMPCI_LR]) 1283 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25, 1284 CMPCI_REG_MICGAINZ); 1285 else 1286 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25, 1287 CMPCI_REG_MICGAINZ); 1288 return; 1289 1290 case CMPCI_DAC_MUTE: 1291 if (sc->sc_gain[port][CMPCI_LR]) 1292 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1293 CMPCI_REG_WSMUTE); 1294 else 1295 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1296 CMPCI_REG_WSMUTE); 1297 return; 1298 case CMPCI_FM_MUTE: 1299 if (sc->sc_gain[port][CMPCI_LR]) 1300 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1301 CMPCI_REG_FMMUTE); 1302 else 1303 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1304 CMPCI_REG_FMMUTE); 1305 return; 1306 case CMPCI_AUX_IN_MUTE: 1307 if (sc->sc_gain[port][CMPCI_LR]) 1308 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25, 1309 CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM); 1310 else 1311 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25, 1312 CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM); 1313 return; 1314 case CMPCI_CD_MUTE: 1315 mask = CMPCI_SB16_SW_CD; 1316 goto sbmute; 1317 case CMPCI_MIC_MUTE: 1318 mask = CMPCI_SB16_SW_MIC; 1319 goto sbmute; 1320 case CMPCI_LINE_IN_MUTE: 1321 mask = CMPCI_SB16_SW_LINE; 1322 sbmute: 1323 bits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_OUTMIX); 1324 if (sc->sc_gain[port][CMPCI_LR]) 1325 bits = bits & ~mask; 1326 else 1327 bits = bits | mask; 1328 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, bits); 1329 return; 1330 1331 case CMPCI_SPDIF_IN_SELECT: 1332 case CMPCI_MONITOR_DAC: 1333 case CMPCI_PLAYBACK_MODE: 1334 case CMPCI_SPDIF_LOOP: 1335 case CMPCI_SPDIF_OUT_PLAYBACK: 1336 cmpci_set_out_ports(sc); 1337 return; 1338 case CMPCI_SPDIF_OUT_VOLTAGE: 1339 if (CMPCI_ISCAP(sc, SPDOUT_VOLTAGE)) { 1340 if (sc->sc_gain[CMPCI_SPDIF_OUT_VOLTAGE][CMPCI_LR] 1341 == CMPCI_SPDIF_OUT_VOLTAGE_HIGH) 1342 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_5V); 1343 else 1344 cmpci_reg_set_reg_misc(sc, CMPCI_REG_5V); 1345 } 1346 return; 1347 case CMPCI_SURROUND: 1348 if (CMPCI_ISCAP(sc, SURROUND)) { 1349 if (sc->sc_gain[CMPCI_SURROUND][CMPCI_LR]) 1350 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1351 CMPCI_REG_SURROUND); 1352 else 1353 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1354 CMPCI_REG_SURROUND); 1355 } 1356 return; 1357 case CMPCI_REAR: 1358 if (CMPCI_ISCAP(sc, REAR)) { 1359 if (sc->sc_gain[CMPCI_REAR][CMPCI_LR]) 1360 cmpci_reg_set_reg_misc(sc, CMPCI_REG_N4SPK3D); 1361 else 1362 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_N4SPK3D); 1363 } 1364 return; 1365 case CMPCI_INDIVIDUAL: 1366 if (CMPCI_ISCAP(sc, INDIVIDUAL_REAR)) { 1367 if (sc->sc_gain[CMPCI_REAR][CMPCI_LR]) 1368 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1369 CMPCI_REG_INDIVIDUAL); 1370 else 1371 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1372 CMPCI_REG_INDIVIDUAL); 1373 } 1374 return; 1375 case CMPCI_REVERSE: 1376 if (CMPCI_ISCAP(sc, REVERSE_FR)) { 1377 if (sc->sc_gain[CMPCI_REVERSE][CMPCI_LR]) 1378 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1379 CMPCI_REG_REVERSE_FR); 1380 else 1381 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1382 CMPCI_REG_REVERSE_FR); 1383 } 1384 return; 1385 case CMPCI_SPDIF_IN_PHASE: 1386 if (CMPCI_ISCAP(sc, SPDIN_PHASE)) { 1387 if (sc->sc_gain[CMPCI_SPDIF_IN_PHASE][CMPCI_LR] 1388 == CMPCI_SPDIF_IN_PHASE_POSITIVE) 1389 cmpci_reg_clear_1(sc, CMPCI_REG_CHANNEL_FORMAT, 1390 CMPCI_REG_SPDIN_PHASE); 1391 else 1392 cmpci_reg_set_1(sc, CMPCI_REG_CHANNEL_FORMAT, 1393 CMPCI_REG_SPDIN_PHASE); 1394 } 1395 return; 1396 default: 1397 return; 1398 } 1399 1400 cmpci_mixerreg_write(sc, src, 1401 CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT])); 1402 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_L_TO_R(src), 1403 CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_RIGHT])); 1404 } 1405 1406 void 1407 cmpci_set_out_ports(struct cmpci_softc *sc) 1408 { 1409 struct cmpci_channel *chan; 1410 u_int8_t v; 1411 int enspdout = 0; 1412 1413 if (!CMPCI_ISCAP(sc, SPDLOOP)) 1414 return; 1415 1416 /* SPDIF/out select */ 1417 if (sc->sc_gain[CMPCI_SPDIF_LOOP][CMPCI_LR] == CMPCI_SPDIF_LOOP_OFF) { 1418 /* playback */ 1419 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP); 1420 } else { 1421 /* monitor SPDIF/in */ 1422 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP); 1423 } 1424 1425 /* SPDIF in select */ 1426 v = sc->sc_gain[CMPCI_SPDIF_IN_SELECT][CMPCI_LR]; 1427 if (v & CMPCI_SPDIFIN_SPDIFIN2) 1428 cmpci_reg_set_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN); 1429 else 1430 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN); 1431 if (v & CMPCI_SPDIFIN_SPDIFOUT) 1432 cmpci_reg_set_reg_misc(sc, CMPCI_REG_SPDFLOOPI); 1433 else 1434 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPDFLOOPI); 1435 1436 if (sc->sc_play_channel == 1) 1437 chan = &sc->sc_ch1; 1438 else 1439 chan = &sc->sc_ch0; 1440 1441 /* disable ac3 and 24 and 32 bit s/pdif modes */ 1442 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, CMPCI_REG_AC3EN1); 1443 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_AC3EN2); 1444 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPD32SEL); 1445 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, CMPCI_REG_SPDIF_24); 1446 1447 /* playback to ... */ 1448 if (CMPCI_ISCAP(sc, SPDOUT) && 1449 sc->sc_gain[CMPCI_PLAYBACK_MODE][CMPCI_LR] 1450 == CMPCI_PLAYBACK_MODE_SPDIF && 1451 (chan->md_divide == CMPCI_REG_RATE_44100 || 1452 (CMPCI_ISCAP(sc, SPDOUT_48K) && 1453 chan->md_divide == CMPCI_REG_RATE_48000))) { 1454 /* playback to SPDIF */ 1455 if (sc->sc_play_channel == 0) 1456 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 1457 CMPCI_REG_SPDIF0_ENABLE); 1458 else 1459 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 1460 CMPCI_REG_SPDIF1_ENABLE); 1461 enspdout = 1; 1462 if (chan->md_divide == CMPCI_REG_RATE_48000) 1463 cmpci_reg_set_reg_misc(sc, 1464 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K); 1465 else 1466 cmpci_reg_clear_reg_misc(sc, 1467 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K); 1468 /* XXX assume sample rate <= 48kHz */ 1469 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, 1470 CMPCI_REG_DBL_SPD_RATE); 1471 } else { 1472 /* playback to DAC */ 1473 if (sc->sc_play_channel == 0) 1474 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 1475 CMPCI_REG_SPDIF0_ENABLE); 1476 else 1477 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 1478 CMPCI_REG_SPDIF1_ENABLE); 1479 if (CMPCI_ISCAP(sc, SPDOUT_48K)) 1480 cmpci_reg_clear_reg_misc(sc, 1481 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K); 1482 } 1483 1484 /* legacy to SPDIF/out or not */ 1485 if (CMPCI_ISCAP(sc, SPDLEGACY)) { 1486 if (sc->sc_gain[CMPCI_SPDIF_OUT_PLAYBACK][CMPCI_LR] 1487 == CMPCI_SPDIF_OUT_PLAYBACK_WAVE) 1488 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 1489 CMPCI_REG_LEGACY_SPDIF_ENABLE); 1490 else { 1491 cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL, 1492 CMPCI_REG_LEGACY_SPDIF_ENABLE); 1493 enspdout = 1; 1494 } 1495 } 1496 1497 /* enable/disable SPDIF/out */ 1498 if (CMPCI_ISCAP(sc, XSPDOUT) && enspdout) 1499 cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL, 1500 CMPCI_REG_XSPDIF_ENABLE); 1501 else 1502 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 1503 CMPCI_REG_XSPDIF_ENABLE); 1504 1505 /* SPDIF monitor (digital to analog output) */ 1506 if (CMPCI_ISCAP(sc, SPDIN_MONITOR)) { 1507 v = sc->sc_gain[CMPCI_MONITOR_DAC][CMPCI_LR]; 1508 if (!(v & CMPCI_MONDAC_ENABLE)) 1509 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1510 CMPCI_REG_SPDIN_MONITOR); 1511 if (v & CMPCI_MONDAC_SPDOUT) 1512 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 1513 CMPCI_REG_SPDIFOUT_DAC); 1514 else 1515 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 1516 CMPCI_REG_SPDIFOUT_DAC); 1517 if (v & CMPCI_MONDAC_ENABLE) 1518 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1519 CMPCI_REG_SPDIN_MONITOR); 1520 } 1521 } 1522 1523 int 1524 cmpci_set_in_ports(struct cmpci_softc *sc) 1525 { 1526 int mask; 1527 int bitsl, bitsr; 1528 1529 mask = sc->sc_in_mask; 1530 1531 /* 1532 * Note CMPCI_RECORD_SOURCE_CD, CMPCI_RECORD_SOURCE_LINE_IN and 1533 * CMPCI_RECORD_SOURCE_FM are defined to the corresponding bit 1534 * of the mixer register. 1535 */ 1536 bitsr = mask & (CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN | 1537 CMPCI_RECORD_SOURCE_FM); 1538 1539 bitsl = CMPCI_SB16_MIXER_SRC_R_TO_L(bitsr); 1540 if (mask & CMPCI_RECORD_SOURCE_MIC) { 1541 bitsl |= CMPCI_SB16_MIXER_MIC_SRC; 1542 bitsr |= CMPCI_SB16_MIXER_MIC_SRC; 1543 } 1544 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, bitsl); 1545 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, bitsr); 1546 1547 if (mask & CMPCI_RECORD_SOURCE_AUX_IN) 1548 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25, 1549 CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN); 1550 else 1551 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25, 1552 CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN); 1553 1554 if (mask & CMPCI_RECORD_SOURCE_WAVE) 1555 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1556 CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR); 1557 else 1558 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1559 CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR); 1560 1561 if (CMPCI_ISCAP(sc, SPDIN) && 1562 (sc->sc_ch1.md_divide == CMPCI_REG_RATE_44100 || 1563 (CMPCI_ISCAP(sc, SPDOUT_48K) && 1564 sc->sc_ch1.md_divide == CMPCI_REG_RATE_48000/* XXX? */))) { 1565 if (mask & CMPCI_RECORD_SOURCE_SPDIF) { 1566 /* enable SPDIF/in */ 1567 cmpci_reg_set_4(sc, 1568 CMPCI_REG_FUNC_1, 1569 CMPCI_REG_SPDIF1_ENABLE); 1570 } else { 1571 cmpci_reg_clear_4(sc, 1572 CMPCI_REG_FUNC_1, 1573 CMPCI_REG_SPDIF1_ENABLE); 1574 } 1575 } 1576 1577 return 0; 1578 } 1579 1580 int 1581 cmpci_set_port(void *handle, mixer_ctrl_t *cp) 1582 { 1583 struct cmpci_softc *sc = handle; 1584 int lgain, rgain; 1585 1586 switch (cp->dev) { 1587 case CMPCI_MIC_VOL: 1588 case CMPCI_PCSPEAKER: 1589 case CMPCI_MIC_RECVOL: 1590 if (cp->un.value.num_channels != 1) 1591 return EINVAL; 1592 /* FALLTHROUGH */ 1593 case CMPCI_DAC_VOL: 1594 case CMPCI_FM_VOL: 1595 case CMPCI_CD_VOL: 1596 case CMPCI_LINE_IN_VOL: 1597 case CMPCI_AUX_IN_VOL: 1598 case CMPCI_MASTER_VOL: 1599 if (cp->type != AUDIO_MIXER_VALUE) 1600 return EINVAL; 1601 switch (cp->un.value.num_channels) { 1602 case 1: 1603 lgain = rgain = 1604 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 1605 break; 1606 case 2: 1607 lgain = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1608 rgain = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 1609 break; 1610 default: 1611 return EINVAL; 1612 } 1613 sc->sc_gain[cp->dev][CMPCI_LEFT] = lgain; 1614 sc->sc_gain[cp->dev][CMPCI_RIGHT] = rgain; 1615 1616 cmpci_set_mixer_gain(sc, cp->dev); 1617 break; 1618 1619 case CMPCI_RECORD_SOURCE: 1620 if (cp->type != AUDIO_MIXER_SET) 1621 return EINVAL; 1622 1623 if (cp->un.mask & ~(CMPCI_RECORD_SOURCE_MIC | 1624 CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN | 1625 CMPCI_RECORD_SOURCE_AUX_IN | CMPCI_RECORD_SOURCE_WAVE | 1626 CMPCI_RECORD_SOURCE_FM | CMPCI_RECORD_SOURCE_SPDIF)) 1627 return EINVAL; 1628 1629 if (cp->un.mask & CMPCI_RECORD_SOURCE_SPDIF) 1630 cp->un.mask = CMPCI_RECORD_SOURCE_SPDIF; 1631 1632 sc->sc_in_mask = cp->un.mask; 1633 return cmpci_set_in_ports(sc); 1634 1635 /* boolean */ 1636 case CMPCI_DAC_MUTE: 1637 case CMPCI_FM_MUTE: 1638 case CMPCI_CD_MUTE: 1639 case CMPCI_LINE_IN_MUTE: 1640 case CMPCI_AUX_IN_MUTE: 1641 case CMPCI_MIC_MUTE: 1642 case CMPCI_MIC_PREAMP: 1643 case CMPCI_PLAYBACK_MODE: 1644 case CMPCI_SPDIF_IN_PHASE: 1645 case CMPCI_SPDIF_LOOP: 1646 case CMPCI_SPDIF_OUT_PLAYBACK: 1647 case CMPCI_SPDIF_OUT_VOLTAGE: 1648 case CMPCI_REAR: 1649 case CMPCI_INDIVIDUAL: 1650 case CMPCI_REVERSE: 1651 case CMPCI_SURROUND: 1652 if (cp->type != AUDIO_MIXER_ENUM) 1653 return EINVAL; 1654 sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord != 0; 1655 cmpci_set_mixer_gain(sc, cp->dev); 1656 break; 1657 1658 case CMPCI_SPDIF_IN_SELECT: 1659 switch (cp->un.ord) { 1660 case CMPCI_SPDIF_IN_SPDIN1: 1661 case CMPCI_SPDIF_IN_SPDIN2: 1662 case CMPCI_SPDIF_IN_SPDOUT: 1663 break; 1664 default: 1665 return EINVAL; 1666 } 1667 goto xenum; 1668 case CMPCI_MONITOR_DAC: 1669 switch (cp->un.ord) { 1670 case CMPCI_MONITOR_DAC_OFF: 1671 case CMPCI_MONITOR_DAC_SPDIN: 1672 case CMPCI_MONITOR_DAC_SPDOUT: 1673 break; 1674 default: 1675 return EINVAL; 1676 } 1677 xenum: 1678 if (cp->type != AUDIO_MIXER_ENUM) 1679 return EINVAL; 1680 sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord; 1681 cmpci_set_mixer_gain(sc, cp->dev); 1682 break; 1683 1684 default: 1685 return EINVAL; 1686 } 1687 1688 return 0; 1689 } 1690 1691 int 1692 cmpci_get_port(void *handle, mixer_ctrl_t *cp) 1693 { 1694 struct cmpci_softc *sc = handle; 1695 1696 switch (cp->dev) { 1697 case CMPCI_MIC_VOL: 1698 case CMPCI_PCSPEAKER: 1699 case CMPCI_MIC_RECVOL: 1700 if (cp->un.value.num_channels != 1) 1701 return EINVAL; 1702 /*FALLTHROUGH*/ 1703 case CMPCI_DAC_VOL: 1704 case CMPCI_FM_VOL: 1705 case CMPCI_CD_VOL: 1706 case CMPCI_LINE_IN_VOL: 1707 case CMPCI_AUX_IN_VOL: 1708 case CMPCI_MASTER_VOL: 1709 switch (cp->un.value.num_channels) { 1710 case 1: 1711 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1712 sc->sc_gain[cp->dev][CMPCI_LEFT]; 1713 break; 1714 case 2: 1715 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1716 sc->sc_gain[cp->dev][CMPCI_LEFT]; 1717 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1718 sc->sc_gain[cp->dev][CMPCI_RIGHT]; 1719 break; 1720 default: 1721 return EINVAL; 1722 } 1723 break; 1724 1725 case CMPCI_RECORD_SOURCE: 1726 cp->un.mask = sc->sc_in_mask; 1727 break; 1728 1729 case CMPCI_DAC_MUTE: 1730 case CMPCI_FM_MUTE: 1731 case CMPCI_CD_MUTE: 1732 case CMPCI_LINE_IN_MUTE: 1733 case CMPCI_AUX_IN_MUTE: 1734 case CMPCI_MIC_MUTE: 1735 case CMPCI_MIC_PREAMP: 1736 case CMPCI_PLAYBACK_MODE: 1737 case CMPCI_SPDIF_IN_SELECT: 1738 case CMPCI_SPDIF_IN_PHASE: 1739 case CMPCI_SPDIF_LOOP: 1740 case CMPCI_SPDIF_OUT_PLAYBACK: 1741 case CMPCI_SPDIF_OUT_VOLTAGE: 1742 case CMPCI_MONITOR_DAC: 1743 case CMPCI_REAR: 1744 case CMPCI_INDIVIDUAL: 1745 case CMPCI_REVERSE: 1746 case CMPCI_SURROUND: 1747 cp->un.ord = sc->sc_gain[cp->dev][CMPCI_LR]; 1748 break; 1749 1750 default: 1751 return EINVAL; 1752 } 1753 1754 return 0; 1755 } 1756 1757 /* ARGSUSED */ 1758 size_t 1759 cmpci_round_buffersize(void *handle, int direction, size_t bufsize) 1760 { 1761 if (bufsize > 0x10000) 1762 bufsize = 0x10000; 1763 1764 return bufsize; 1765 } 1766 1767 /* ARGSUSED */ 1768 int 1769 cmpci_get_props(void *handle) 1770 { 1771 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1772 } 1773 1774 int 1775 cmpci_trigger_output(void *handle, void *start, void *end, int blksize, 1776 void (*intr)(void *), void *arg, struct audio_params *param) 1777 { 1778 struct cmpci_softc *sc = handle; 1779 struct cmpci_dmanode *p; 1780 struct cmpci_channel *chan; 1781 uint32_t reg_dma_base, reg_dma_bytes, reg_dma_samples, reg_dir, 1782 reg_intr_enable, reg_enable; 1783 uint32_t length; 1784 size_t buffer_size = (caddr_t)end - (caddr_t)start; 1785 1786 cmpci_set_out_ports(sc); 1787 1788 if (sc->sc_play_channel == 1) { 1789 chan = &sc->sc_ch1; 1790 reg_dma_base = CMPCI_REG_DMA1_BASE; 1791 reg_dma_bytes = CMPCI_REG_DMA1_BYTES; 1792 reg_dma_samples = CMPCI_REG_DMA1_SAMPLES; 1793 reg_dir = CMPCI_REG_CH1_DIR; 1794 reg_intr_enable = CMPCI_REG_CH1_INTR_ENABLE; 1795 reg_enable = CMPCI_REG_CH1_ENABLE; 1796 } else { 1797 chan = &sc->sc_ch0; 1798 reg_dma_base = CMPCI_REG_DMA0_BASE; 1799 reg_dma_bytes = CMPCI_REG_DMA0_BYTES; 1800 reg_dma_samples = CMPCI_REG_DMA0_SAMPLES; 1801 reg_dir = CMPCI_REG_CH0_DIR; 1802 reg_intr_enable = CMPCI_REG_CH0_INTR_ENABLE; 1803 reg_enable = CMPCI_REG_CH0_ENABLE; 1804 } 1805 1806 chan->bps = (param->channels > 1 ? 2 : 1) * param->bps; 1807 if (!chan->bps) 1808 return EINVAL; 1809 1810 chan->intr = intr; 1811 chan->intr_arg = arg; 1812 chan->blksize = blksize; 1813 chan->nblocks = buffer_size / chan->blksize; 1814 chan->swpos = 0; 1815 1816 /* set DMA frame */ 1817 if (!(p = cmpci_find_dmamem(sc, start))) 1818 return EINVAL; 1819 bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_dma_base, 1820 DMAADDR(p)); 1821 delay(10); 1822 length = (buffer_size + 1) / chan->bps - 1; 1823 bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_bytes, length); 1824 delay(10); 1825 1826 /* set interrupt count */ 1827 length = (chan->blksize + chan->bps - 1) / chan->bps - 1; 1828 bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_samples, length); 1829 delay(10); 1830 1831 /* start DMA */ 1832 mtx_enter(&audio_lock); 1833 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_dir); /* PLAY */ 1834 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, reg_intr_enable); 1835 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_enable); 1836 mtx_leave(&audio_lock); 1837 return 0; 1838 } 1839 1840 int 1841 cmpci_trigger_input(void *handle, void *start, void *end, int blksize, 1842 void (*intr)(void *), void *arg, struct audio_params *param) 1843 { 1844 struct cmpci_softc *sc = handle; 1845 struct cmpci_dmanode *p; 1846 struct cmpci_channel *chan = &sc->sc_ch1; 1847 size_t buffer_size = (caddr_t)end - (caddr_t)start; 1848 1849 cmpci_set_in_ports(sc); 1850 1851 chan->bps = param->channels * param->bps; 1852 if (!chan->bps) 1853 return EINVAL; 1854 1855 chan->intr = intr; 1856 chan->intr_arg = arg; 1857 chan->blksize = blksize; 1858 chan->nblocks = buffer_size / chan->blksize; 1859 chan->swpos = 0; 1860 1861 /* set DMA frame */ 1862 if (!(p = cmpci_find_dmamem(sc, start))) 1863 return EINVAL; 1864 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BASE, 1865 DMAADDR(p)); 1866 delay(10); 1867 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BYTES, 1868 (buffer_size + 1) / chan->bps - 1); 1869 delay(10); 1870 1871 /* set interrupt count */ 1872 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_SAMPLES, 1873 (chan->blksize + chan->bps - 1) / chan->bps - 1); 1874 delay(10); 1875 1876 /* start DMA */ 1877 mtx_enter(&audio_lock); 1878 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR); /* REC */ 1879 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 1880 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 1881 mtx_leave(&audio_lock); 1882 return 0; 1883 } 1884 1885 /* end of file */ 1886