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