1 /* $OpenBSD: cmpci.c,v 1.33 2011/07/03 15:47:17 matthew 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, cmpci_intr, sc, 395 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_QUIESCE: 530 rv = config_activate_children(self, act); 531 break; 532 case DVACT_SUSPEND: 533 break; 534 case DVACT_RESUME: 535 cmpci_resume(sc); 536 rv = config_activate_children(self, act); 537 break; 538 case DVACT_DEACTIVATE: 539 break; 540 } 541 return (rv); 542 } 543 544 int 545 cmpci_resume(struct cmpci_softc *sc) 546 { 547 int i; 548 549 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_RESET, 0); 550 for (i = 0; i < CMPCI_NDEVS; i++) 551 cmpci_set_mixer_gain(sc, i); 552 553 return 0; 554 } 555 556 int 557 cmpci_intr(void *handle) 558 { 559 struct cmpci_softc *sc = handle; 560 struct cmpci_channel *chan; 561 uint32_t intrstat; 562 uint16_t hwpos; 563 564 intrstat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 565 CMPCI_REG_INTR_STATUS); 566 567 if (!(intrstat & CMPCI_REG_ANY_INTR)) 568 return 0; 569 570 delay(10); 571 572 /* disable and reset intr */ 573 if (intrstat & CMPCI_REG_CH0_INTR) 574 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 575 CMPCI_REG_CH0_INTR_ENABLE); 576 if (intrstat & CMPCI_REG_CH1_INTR) 577 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 578 CMPCI_REG_CH1_INTR_ENABLE); 579 580 if (intrstat & CMPCI_REG_CH0_INTR) { 581 chan = &sc->sc_ch0; 582 if (chan->intr != NULL) { 583 hwpos = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 584 CMPCI_REG_DMA0_BYTES); 585 hwpos = hwpos * chan->bps / chan->blksize; 586 hwpos = chan->nblocks - hwpos - 1; 587 while (chan->swpos != hwpos) { 588 (*chan->intr)(chan->intr_arg); 589 chan->swpos++; 590 if (chan->swpos >= chan->nblocks) 591 chan->swpos = 0; 592 if (chan->swpos != hwpos) { 593 DPRINTF(("%s: DMA0 hwpos=%d swpos=%d\n", 594 __func__, hwpos, chan->swpos)); 595 } 596 } 597 } 598 } 599 if (intrstat & CMPCI_REG_CH1_INTR) { 600 chan = &sc->sc_ch1; 601 if (chan->intr != NULL) { 602 hwpos = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 603 CMPCI_REG_DMA1_BYTES); 604 hwpos = hwpos * chan->bps / chan->blksize; 605 hwpos = chan->nblocks - hwpos - 1; 606 while (chan->swpos != hwpos) { 607 (*chan->intr)(chan->intr_arg); 608 chan->swpos++; 609 if (chan->swpos >= chan->nblocks) 610 chan->swpos = 0; 611 if (chan->swpos != hwpos) { 612 DPRINTF(("%s: DMA1 hwpos=%d swpos=%d\n", 613 __func__, hwpos, chan->swpos)); 614 } 615 } 616 } 617 } 618 619 /* enable intr */ 620 if (intrstat & CMPCI_REG_CH0_INTR) 621 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 622 CMPCI_REG_CH0_INTR_ENABLE); 623 if (intrstat & CMPCI_REG_CH1_INTR) 624 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 625 CMPCI_REG_CH1_INTR_ENABLE); 626 627 #if 0 628 if (intrstat & CMPCI_REG_UART_INTR && sc->sc_mpudev != NULL) 629 mpu_intr(sc->sc_mpudev); 630 #endif 631 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 int s; 998 999 s = splaudio(); 1000 if (sc->sc_play_channel == 1) { 1001 sc->sc_ch1.intr = NULL; 1002 reg_intr = CMPCI_REG_CH1_INTR_ENABLE; 1003 reg_enable = CMPCI_REG_CH1_ENABLE; 1004 reg_reset = CMPCI_REG_CH1_RESET; 1005 } else { 1006 sc->sc_ch0.intr = NULL; 1007 reg_intr = CMPCI_REG_CH0_INTR_ENABLE; 1008 reg_enable = CMPCI_REG_CH0_ENABLE; 1009 reg_reset = CMPCI_REG_CH0_RESET; 1010 } 1011 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, reg_intr); 1012 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_enable); 1013 /* wait for reset DMA */ 1014 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_reset); 1015 delay(10); 1016 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_reset); 1017 splx(s); 1018 1019 return 0; 1020 } 1021 1022 int 1023 cmpci_halt_input(void *handle) 1024 { 1025 struct cmpci_softc *sc = handle; 1026 int s; 1027 1028 s = splaudio(); 1029 sc->sc_ch1.intr = NULL; 1030 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 1031 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 1032 /* wait for reset DMA */ 1033 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 1034 delay(10); 1035 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 1036 splx(s); 1037 1038 return 0; 1039 } 1040 1041 /* get audio device information */ 1042 int 1043 cmpci_getdev(void *handle, struct audio_device *ad) 1044 { 1045 struct cmpci_softc *sc = handle; 1046 1047 strncpy(ad->name, "CMI PCI Audio", sizeof(ad->name)); 1048 snprintf(ad->version, sizeof(ad->version), "0x%02x (%d)", 1049 PCI_REVISION(sc->sc_class), sc->sc_version); 1050 switch (PCI_PRODUCT(sc->sc_id)) { 1051 case PCI_PRODUCT_CMI_CMI8338A: 1052 strncpy(ad->config, "CMI8338A", sizeof(ad->config)); 1053 break; 1054 case PCI_PRODUCT_CMI_CMI8338B: 1055 strncpy(ad->config, "CMI8338B", sizeof(ad->config)); 1056 break; 1057 case PCI_PRODUCT_CMI_CMI8738: 1058 strncpy(ad->config, "CMI8738", sizeof(ad->config)); 1059 break; 1060 case PCI_PRODUCT_CMI_CMI8738B: 1061 strncpy(ad->config, "CMI8738B", sizeof(ad->config)); 1062 break; 1063 default: 1064 strncpy(ad->config, "unknown", sizeof(ad->config)); 1065 } 1066 1067 return 0; 1068 } 1069 1070 /* mixer device information */ 1071 int 1072 cmpci_query_devinfo(void *handle, mixer_devinfo_t *dip) 1073 { 1074 static const char *const mixer_port_names[] = { 1075 AudioNdac, AudioNfmsynth, AudioNcd, AudioNline, AudioNaux, 1076 AudioNmicrophone 1077 }; 1078 static const char *const mixer_classes[] = { 1079 AudioCinputs, AudioCoutputs, AudioCrecord, CmpciCplayback, 1080 CmpciCspdif 1081 }; 1082 struct cmpci_softc *sc = handle; 1083 int i; 1084 1085 dip->prev = dip->next = AUDIO_MIXER_LAST; 1086 1087 switch (dip->index) { 1088 case CMPCI_INPUT_CLASS: 1089 case CMPCI_OUTPUT_CLASS: 1090 case CMPCI_RECORD_CLASS: 1091 case CMPCI_PLAYBACK_CLASS: 1092 case CMPCI_SPDIF_CLASS: 1093 dip->type = AUDIO_MIXER_CLASS; 1094 dip->mixer_class = dip->index; 1095 strlcpy(dip->label.name, 1096 mixer_classes[dip->index - CMPCI_INPUT_CLASS], 1097 sizeof dip->label.name); 1098 return 0; 1099 1100 case CMPCI_AUX_IN_VOL: 1101 dip->un.v.delta = 1 << (8 - CMPCI_REG_AUX_VALBITS); 1102 goto vol1; 1103 case CMPCI_DAC_VOL: 1104 case CMPCI_FM_VOL: 1105 case CMPCI_CD_VOL: 1106 case CMPCI_LINE_IN_VOL: 1107 case CMPCI_MIC_VOL: 1108 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS); 1109 vol1: dip->mixer_class = CMPCI_INPUT_CLASS; 1110 dip->next = dip->index + 6; /* CMPCI_xxx_MUTE */ 1111 strlcpy(dip->label.name, mixer_port_names[dip->index], 1112 sizeof dip->label.name); 1113 dip->un.v.num_channels = (dip->index == CMPCI_MIC_VOL ? 1 : 2); 1114 vol: 1115 dip->type = AUDIO_MIXER_VALUE; 1116 strlcpy(dip->un.v.units.name, AudioNvolume, 1117 sizeof dip->un.v.units.name); 1118 return 0; 1119 1120 case CMPCI_MIC_MUTE: 1121 dip->next = CMPCI_MIC_PREAMP; 1122 /* FALLTHROUGH */ 1123 case CMPCI_DAC_MUTE: 1124 case CMPCI_FM_MUTE: 1125 case CMPCI_CD_MUTE: 1126 case CMPCI_LINE_IN_MUTE: 1127 case CMPCI_AUX_IN_MUTE: 1128 dip->prev = dip->index - 6; /* CMPCI_xxx_VOL */ 1129 dip->mixer_class = CMPCI_INPUT_CLASS; 1130 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 1131 goto on_off; 1132 on_off: 1133 dip->type = AUDIO_MIXER_ENUM; 1134 dip->un.e.num_mem = 2; 1135 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 1136 sizeof dip->un.e.member[0].label.name); 1137 dip->un.e.member[0].ord = 0; 1138 strlcpy(dip->un.e.member[1].label.name, AudioNon, 1139 sizeof dip->un.e.member[1].label.name); 1140 dip->un.e.member[1].ord = 1; 1141 return 0; 1142 1143 case CMPCI_MIC_PREAMP: 1144 dip->mixer_class = CMPCI_INPUT_CLASS; 1145 dip->prev = CMPCI_MIC_MUTE; 1146 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name); 1147 goto on_off; 1148 case CMPCI_PCSPEAKER: 1149 dip->mixer_class = CMPCI_INPUT_CLASS; 1150 strlcpy(dip->label.name, AudioNspeaker, sizeof dip->label.name); 1151 dip->un.v.num_channels = 1; 1152 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_SPEAKER_VALBITS); 1153 goto vol; 1154 case CMPCI_RECORD_SOURCE: 1155 dip->mixer_class = CMPCI_RECORD_CLASS; 1156 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 1157 dip->type = AUDIO_MIXER_SET; 1158 dip->un.s.num_mem = 7; 1159 strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone, 1160 sizeof dip->un.s.member[0].label.name); 1161 dip->un.s.member[0].mask = CMPCI_RECORD_SOURCE_MIC; 1162 strlcpy(dip->un.s.member[1].label.name, AudioNcd, 1163 sizeof dip->un.s.member[1].label.name); 1164 dip->un.s.member[1].mask = CMPCI_RECORD_SOURCE_CD; 1165 strlcpy(dip->un.s.member[2].label.name, AudioNline, 1166 sizeof dip->un.s.member[2].label.name); 1167 dip->un.s.member[2].mask = CMPCI_RECORD_SOURCE_LINE_IN; 1168 strlcpy(dip->un.s.member[3].label.name, AudioNaux, 1169 sizeof dip->un.s.member[3].label.name); 1170 dip->un.s.member[3].mask = CMPCI_RECORD_SOURCE_AUX_IN; 1171 strlcpy(dip->un.s.member[4].label.name, AudioNwave, 1172 sizeof dip->un.s.member[4].label.name); 1173 dip->un.s.member[4].mask = CMPCI_RECORD_SOURCE_WAVE; 1174 strlcpy(dip->un.s.member[5].label.name, AudioNfmsynth, 1175 sizeof dip->un.s.member[5].label.name); 1176 dip->un.s.member[5].mask = CMPCI_RECORD_SOURCE_FM; 1177 strlcpy(dip->un.s.member[6].label.name, CmpciNspdif, 1178 sizeof dip->un.s.member[6].label.name); 1179 dip->un.s.member[6].mask = CMPCI_RECORD_SOURCE_SPDIF; 1180 return 0; 1181 case CMPCI_MIC_RECVOL: 1182 dip->mixer_class = CMPCI_RECORD_CLASS; 1183 strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); 1184 dip->un.v.num_channels = 1; 1185 dip->un.v.delta = 1 << (8 - CMPCI_REG_ADMIC_VALBITS); 1186 goto vol; 1187 1188 case CMPCI_PLAYBACK_MODE: 1189 dip->mixer_class = CMPCI_PLAYBACK_CLASS; 1190 dip->type = AUDIO_MIXER_ENUM; 1191 strlcpy(dip->label.name, AudioNmode, sizeof dip->label.name); 1192 dip->un.e.num_mem = 2; 1193 strlcpy(dip->un.e.member[0].label.name, AudioNdac, 1194 sizeof dip->un.e.member[0].label.name); 1195 dip->un.e.member[0].ord = CMPCI_PLAYBACK_MODE_WAVE; 1196 strlcpy(dip->un.e.member[1].label.name, CmpciNspdif, 1197 sizeof dip->un.e.member[1].label.name); 1198 dip->un.e.member[1].ord = CMPCI_PLAYBACK_MODE_SPDIF; 1199 return 0; 1200 case CMPCI_SPDIF_IN_SELECT: 1201 dip->mixer_class = CMPCI_SPDIF_CLASS; 1202 dip->type = AUDIO_MIXER_ENUM; 1203 dip->next = CMPCI_SPDIF_IN_PHASE; 1204 strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name); 1205 i = 0; 1206 strlcpy(dip->un.e.member[i].label.name, CmpciNspdin1, 1207 sizeof dip->un.e.member[i].label.name); 1208 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN1; 1209 if (CMPCI_ISCAP(sc, 2ND_SPDIN)) { 1210 strlcpy(dip->un.e.member[i].label.name, CmpciNspdin2, 1211 sizeof dip->un.e.member[i].label.name); 1212 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDIN2; 1213 } 1214 strlcpy(dip->un.e.member[i].label.name, CmpciNspdout, 1215 sizeof dip->un.e.member[i].label.name); 1216 dip->un.e.member[i++].ord = CMPCI_SPDIF_IN_SPDOUT; 1217 dip->un.e.num_mem = i; 1218 return 0; 1219 case CMPCI_SPDIF_IN_PHASE: 1220 dip->mixer_class = CMPCI_SPDIF_CLASS; 1221 dip->prev = CMPCI_SPDIF_IN_SELECT; 1222 strlcpy(dip->label.name, CmpciNphase, sizeof dip->label.name); 1223 dip->type = AUDIO_MIXER_ENUM; 1224 dip->un.e.num_mem = 2; 1225 strlcpy(dip->un.e.member[0].label.name, CmpciNpositive, 1226 sizeof dip->un.e.member[0].label.name); 1227 dip->un.e.member[0].ord = CMPCI_SPDIF_IN_PHASE_POSITIVE; 1228 strlcpy(dip->un.e.member[1].label.name, CmpciNnegative, 1229 sizeof dip->un.e.member[1].label.name); 1230 dip->un.e.member[1].ord = CMPCI_SPDIF_IN_PHASE_NEGATIVE; 1231 return 0; 1232 case CMPCI_SPDIF_LOOP: 1233 dip->mixer_class = CMPCI_SPDIF_CLASS; 1234 dip->next = CMPCI_SPDIF_OUT_PLAYBACK; 1235 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 1236 dip->type = AUDIO_MIXER_ENUM; 1237 dip->un.e.num_mem = 2; 1238 strlcpy(dip->un.e.member[0].label.name, CmpciNplayback, 1239 sizeof dip->un.e.member[0].label.name); 1240 dip->un.e.member[0].ord = CMPCI_SPDIF_LOOP_OFF; 1241 strlcpy(dip->un.e.member[1].label.name, CmpciNspdin, 1242 sizeof dip->un.e.member[1].label.name); 1243 dip->un.e.member[1].ord = CMPCI_SPDIF_LOOP_ON; 1244 return 0; 1245 case CMPCI_SPDIF_OUT_PLAYBACK: 1246 dip->mixer_class = CMPCI_SPDIF_CLASS; 1247 dip->prev = CMPCI_SPDIF_LOOP; 1248 dip->next = CMPCI_SPDIF_OUT_VOLTAGE; 1249 strlcpy(dip->label.name, CmpciNplayback, sizeof dip->label.name); 1250 dip->type = AUDIO_MIXER_ENUM; 1251 dip->un.e.num_mem = 2; 1252 strlcpy(dip->un.e.member[0].label.name, AudioNwave, 1253 sizeof dip->un.e.member[0].label.name); 1254 dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_PLAYBACK_WAVE; 1255 strlcpy(dip->un.e.member[1].label.name, CmpciNlegacy, 1256 sizeof dip->un.e.member[1].label.name); 1257 dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_PLAYBACK_LEGACY; 1258 return 0; 1259 case CMPCI_SPDIF_OUT_VOLTAGE: 1260 dip->mixer_class = CMPCI_SPDIF_CLASS; 1261 dip->prev = CMPCI_SPDIF_OUT_PLAYBACK; 1262 strlcpy(dip->label.name, CmpciNvoltage, sizeof dip->label.name); 1263 dip->type = AUDIO_MIXER_ENUM; 1264 dip->un.e.num_mem = 2; 1265 strlcpy(dip->un.e.member[0].label.name, CmpciNhigh_v, 1266 sizeof dip->un.e.member[0].label.name); 1267 dip->un.e.member[0].ord = CMPCI_SPDIF_OUT_VOLTAGE_HIGH; 1268 strlcpy(dip->un.e.member[1].label.name, CmpciNlow_v, 1269 sizeof dip->un.e.member[1].label.name); 1270 dip->un.e.member[1].ord = CMPCI_SPDIF_OUT_VOLTAGE_LOW; 1271 return 0; 1272 case CMPCI_MONITOR_DAC: 1273 dip->mixer_class = CMPCI_SPDIF_CLASS; 1274 strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); 1275 dip->type = AUDIO_MIXER_ENUM; 1276 dip->un.e.num_mem = 3; 1277 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 1278 sizeof dip->un.e.member[0].label.name); 1279 dip->un.e.member[0].ord = CMPCI_MONITOR_DAC_OFF; 1280 strlcpy(dip->un.e.member[1].label.name, CmpciNspdin, 1281 sizeof dip->un.e.member[1].label.name); 1282 dip->un.e.member[1].ord = CMPCI_MONITOR_DAC_SPDIN; 1283 strlcpy(dip->un.e.member[2].label.name, CmpciNspdout, 1284 sizeof dip->un.e.member[2].label.name); 1285 dip->un.e.member[2].ord = CMPCI_MONITOR_DAC_SPDOUT; 1286 return 0; 1287 1288 case CMPCI_MASTER_VOL: 1289 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1290 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 1291 dip->un.v.num_channels = 2; 1292 dip->un.v.delta = 1 << (8 - CMPCI_SB16_MIXER_VALBITS); 1293 goto vol; 1294 case CMPCI_REAR: 1295 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1296 dip->next = CMPCI_INDIVIDUAL; 1297 strlcpy(dip->label.name, CmpciNrear, sizeof dip->label.name); 1298 goto on_off; 1299 case CMPCI_INDIVIDUAL: 1300 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1301 dip->prev = CMPCI_REAR; 1302 dip->next = CMPCI_REVERSE; 1303 strlcpy(dip->label.name, CmpciNindividual, sizeof dip->label.name); 1304 goto on_off; 1305 case CMPCI_REVERSE: 1306 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1307 dip->prev = CMPCI_INDIVIDUAL; 1308 strlcpy(dip->label.name, CmpciNreverse, sizeof dip->label.name); 1309 goto on_off; 1310 case CMPCI_SURROUND: 1311 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1312 strlcpy(dip->label.name, CmpciNsurround, sizeof dip->label.name); 1313 goto on_off; 1314 } 1315 1316 return ENXIO; 1317 } 1318 1319 int 1320 cmpci_alloc_dmamem(struct cmpci_softc *sc, size_t size, int type, int flags, 1321 caddr_t *r_addr) 1322 { 1323 int error = 0; 1324 struct cmpci_dmanode *n; 1325 int w; 1326 1327 n = malloc(sizeof(struct cmpci_dmanode), type, flags); 1328 if (n == NULL) { 1329 error = ENOMEM; 1330 goto quit; 1331 } 1332 1333 w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK; 1334 #define CMPCI_DMABUF_ALIGN 0x4 1335 #define CMPCI_DMABUF_BOUNDARY 0x0 1336 n->cd_tag = sc->sc_dmat; 1337 n->cd_size = size; 1338 error = bus_dmamem_alloc(n->cd_tag, n->cd_size, 1339 CMPCI_DMABUF_ALIGN, CMPCI_DMABUF_BOUNDARY, n->cd_segs, 1340 nitems(n->cd_segs), &n->cd_nsegs, w); 1341 if (error) 1342 goto mfree; 1343 error = bus_dmamem_map(n->cd_tag, n->cd_segs, n->cd_nsegs, n->cd_size, 1344 &n->cd_addr, w | BUS_DMA_COHERENT); 1345 if (error) 1346 goto dmafree; 1347 error = bus_dmamap_create(n->cd_tag, n->cd_size, 1, n->cd_size, 0, 1348 w, &n->cd_map); 1349 if (error) 1350 goto unmap; 1351 error = bus_dmamap_load(n->cd_tag, n->cd_map, n->cd_addr, n->cd_size, 1352 NULL, w); 1353 if (error) 1354 goto destroy; 1355 1356 n->cd_next = sc->sc_dmap; 1357 sc->sc_dmap = n; 1358 *r_addr = KVADDR(n); 1359 return 0; 1360 1361 destroy: 1362 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1363 unmap: 1364 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1365 dmafree: 1366 bus_dmamem_free(n->cd_tag, 1367 n->cd_segs, nitems(n->cd_segs)); 1368 mfree: 1369 free(n, type); 1370 quit: 1371 return error; 1372 } 1373 1374 int 1375 cmpci_free_dmamem(struct cmpci_softc *sc, caddr_t addr, int type) 1376 { 1377 struct cmpci_dmanode **nnp; 1378 1379 for (nnp = &sc->sc_dmap; *nnp; nnp = &(*nnp)->cd_next) { 1380 if ((*nnp)->cd_addr == addr) { 1381 struct cmpci_dmanode *n = *nnp; 1382 bus_dmamap_unload(n->cd_tag, n->cd_map); 1383 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1384 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1385 bus_dmamem_free(n->cd_tag, n->cd_segs, 1386 nitems(n->cd_segs)); 1387 free(n, type); 1388 return 0; 1389 } 1390 } 1391 return -1; 1392 } 1393 1394 struct cmpci_dmanode * 1395 cmpci_find_dmamem(struct cmpci_softc *sc, caddr_t addr) 1396 { 1397 struct cmpci_dmanode *p; 1398 1399 for (p = sc->sc_dmap; p; p = p->cd_next) { 1400 if (KVADDR(p) == (void *)addr) 1401 break; 1402 } 1403 return p; 1404 } 1405 1406 #if 0 1407 void cmpci_print_dmamem(struct cmpci_dmanode *p); 1408 1409 void 1410 cmpci_print_dmamem(struct cmpci_dmanode *p) 1411 { 1412 DPRINTF(("DMA at virt:%p, dmaseg:%p, mapseg:%p, size:%p\n", 1413 (void *)p->cd_addr, (void *)p->cd_segs[0].ds_addr, 1414 (void *)DMAADDR(p), (void *)p->cd_size)); 1415 } 1416 #endif /* DEBUG */ 1417 1418 void * 1419 cmpci_malloc(void *handle, int direction, size_t size, int type, 1420 int flags) 1421 { 1422 caddr_t addr; 1423 1424 if (cmpci_alloc_dmamem(handle, size, type, flags, &addr)) 1425 return NULL; 1426 return addr; 1427 } 1428 1429 void 1430 cmpci_free(void *handle, void *addr, int type) 1431 { 1432 cmpci_free_dmamem(handle, addr, type); 1433 } 1434 1435 #define MAXVAL 256 1436 int 1437 cmpci_adjust(int val, int mask) 1438 { 1439 val += (MAXVAL - mask) >> 1; 1440 if (val >= MAXVAL) 1441 val = MAXVAL-1; 1442 return val & mask; 1443 } 1444 1445 void 1446 cmpci_set_mixer_gain(struct cmpci_softc *sc, int port) 1447 { 1448 int src; 1449 int bits, mask; 1450 1451 switch (port) { 1452 case CMPCI_MIC_VOL: 1453 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_MIC, 1454 CMPCI_ADJUST_MIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR])); 1455 return; 1456 case CMPCI_MASTER_VOL: 1457 src = CMPCI_SB16_MIXER_MASTER_L; 1458 break; 1459 case CMPCI_LINE_IN_VOL: 1460 src = CMPCI_SB16_MIXER_LINE_L; 1461 break; 1462 case CMPCI_AUX_IN_VOL: 1463 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_MIXER_AUX, 1464 CMPCI_ADJUST_AUX_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT], 1465 sc->sc_gain[port][CMPCI_RIGHT])); 1466 return; 1467 case CMPCI_MIC_RECVOL: 1468 cmpci_reg_partial_write_1(sc, CMPCI_REG_MIXER25, 1469 CMPCI_REG_ADMIC_SHIFT, CMPCI_REG_ADMIC_MASK, 1470 CMPCI_ADJUST_ADMIC_GAIN(sc, sc->sc_gain[port][CMPCI_LR])); 1471 return; 1472 case CMPCI_DAC_VOL: 1473 src = CMPCI_SB16_MIXER_VOICE_L; 1474 break; 1475 case CMPCI_FM_VOL: 1476 src = CMPCI_SB16_MIXER_FM_L; 1477 break; 1478 case CMPCI_CD_VOL: 1479 src = CMPCI_SB16_MIXER_CDDA_L; 1480 break; 1481 case CMPCI_PCSPEAKER: 1482 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_SPEAKER, 1483 CMPCI_ADJUST_2_GAIN(sc, sc->sc_gain[port][CMPCI_LR])); 1484 return; 1485 case CMPCI_MIC_PREAMP: 1486 if (sc->sc_gain[port][CMPCI_LR]) 1487 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25, 1488 CMPCI_REG_MICGAINZ); 1489 else 1490 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25, 1491 CMPCI_REG_MICGAINZ); 1492 return; 1493 1494 case CMPCI_DAC_MUTE: 1495 if (sc->sc_gain[port][CMPCI_LR]) 1496 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1497 CMPCI_REG_WSMUTE); 1498 else 1499 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1500 CMPCI_REG_WSMUTE); 1501 return; 1502 case CMPCI_FM_MUTE: 1503 if (sc->sc_gain[port][CMPCI_LR]) 1504 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1505 CMPCI_REG_FMMUTE); 1506 else 1507 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1508 CMPCI_REG_FMMUTE); 1509 return; 1510 case CMPCI_AUX_IN_MUTE: 1511 if (sc->sc_gain[port][CMPCI_LR]) 1512 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25, 1513 CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM); 1514 else 1515 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25, 1516 CMPCI_REG_VAUXRM|CMPCI_REG_VAUXLM); 1517 return; 1518 case CMPCI_CD_MUTE: 1519 mask = CMPCI_SB16_SW_CD; 1520 goto sbmute; 1521 case CMPCI_MIC_MUTE: 1522 mask = CMPCI_SB16_SW_MIC; 1523 goto sbmute; 1524 case CMPCI_LINE_IN_MUTE: 1525 mask = CMPCI_SB16_SW_LINE; 1526 sbmute: 1527 bits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_OUTMIX); 1528 if (sc->sc_gain[port][CMPCI_LR]) 1529 bits = bits & ~mask; 1530 else 1531 bits = bits | mask; 1532 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, bits); 1533 return; 1534 1535 case CMPCI_SPDIF_IN_SELECT: 1536 case CMPCI_MONITOR_DAC: 1537 case CMPCI_PLAYBACK_MODE: 1538 case CMPCI_SPDIF_LOOP: 1539 case CMPCI_SPDIF_OUT_PLAYBACK: 1540 cmpci_set_out_ports(sc); 1541 return; 1542 case CMPCI_SPDIF_OUT_VOLTAGE: 1543 if (CMPCI_ISCAP(sc, SPDOUT_VOLTAGE)) { 1544 if (sc->sc_gain[CMPCI_SPDIF_OUT_VOLTAGE][CMPCI_LR] 1545 == CMPCI_SPDIF_OUT_VOLTAGE_HIGH) 1546 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_5V); 1547 else 1548 cmpci_reg_set_reg_misc(sc, CMPCI_REG_5V); 1549 } 1550 return; 1551 case CMPCI_SURROUND: 1552 if (CMPCI_ISCAP(sc, SURROUND)) { 1553 if (sc->sc_gain[CMPCI_SURROUND][CMPCI_LR]) 1554 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1555 CMPCI_REG_SURROUND); 1556 else 1557 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1558 CMPCI_REG_SURROUND); 1559 } 1560 return; 1561 case CMPCI_REAR: 1562 if (CMPCI_ISCAP(sc, REAR)) { 1563 if (sc->sc_gain[CMPCI_REAR][CMPCI_LR]) 1564 cmpci_reg_set_reg_misc(sc, CMPCI_REG_N4SPK3D); 1565 else 1566 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_N4SPK3D); 1567 } 1568 return; 1569 case CMPCI_INDIVIDUAL: 1570 if (CMPCI_ISCAP(sc, INDIVIDUAL_REAR)) { 1571 if (sc->sc_gain[CMPCI_REAR][CMPCI_LR]) 1572 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1573 CMPCI_REG_INDIVIDUAL); 1574 else 1575 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1576 CMPCI_REG_INDIVIDUAL); 1577 } 1578 return; 1579 case CMPCI_REVERSE: 1580 if (CMPCI_ISCAP(sc, REVERSE_FR)) { 1581 if (sc->sc_gain[CMPCI_REVERSE][CMPCI_LR]) 1582 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1583 CMPCI_REG_REVERSE_FR); 1584 else 1585 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1586 CMPCI_REG_REVERSE_FR); 1587 } 1588 return; 1589 case CMPCI_SPDIF_IN_PHASE: 1590 if (CMPCI_ISCAP(sc, SPDIN_PHASE)) { 1591 if (sc->sc_gain[CMPCI_SPDIF_IN_PHASE][CMPCI_LR] 1592 == CMPCI_SPDIF_IN_PHASE_POSITIVE) 1593 cmpci_reg_clear_1(sc, CMPCI_REG_CHANNEL_FORMAT, 1594 CMPCI_REG_SPDIN_PHASE); 1595 else 1596 cmpci_reg_set_1(sc, CMPCI_REG_CHANNEL_FORMAT, 1597 CMPCI_REG_SPDIN_PHASE); 1598 } 1599 return; 1600 default: 1601 return; 1602 } 1603 1604 cmpci_mixerreg_write(sc, src, 1605 CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_LEFT])); 1606 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_L_TO_R(src), 1607 CMPCI_ADJUST_GAIN(sc, sc->sc_gain[port][CMPCI_RIGHT])); 1608 } 1609 1610 void 1611 cmpci_set_out_ports(struct cmpci_softc *sc) 1612 { 1613 struct cmpci_channel *chan; 1614 u_int8_t v; 1615 int enspdout = 0; 1616 1617 if (!CMPCI_ISCAP(sc, SPDLOOP)) 1618 return; 1619 1620 /* SPDIF/out select */ 1621 if (sc->sc_gain[CMPCI_SPDIF_LOOP][CMPCI_LR] == CMPCI_SPDIF_LOOP_OFF) { 1622 /* playback */ 1623 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP); 1624 } else { 1625 /* monitor SPDIF/in */ 1626 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, CMPCI_REG_SPDIF_LOOP); 1627 } 1628 1629 /* SPDIF in select */ 1630 v = sc->sc_gain[CMPCI_SPDIF_IN_SELECT][CMPCI_LR]; 1631 if (v & CMPCI_SPDIFIN_SPDIFIN2) 1632 cmpci_reg_set_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN); 1633 else 1634 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_2ND_SPDIFIN); 1635 if (v & CMPCI_SPDIFIN_SPDIFOUT) 1636 cmpci_reg_set_reg_misc(sc, CMPCI_REG_SPDFLOOPI); 1637 else 1638 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPDFLOOPI); 1639 1640 if (sc->sc_play_channel == 1) 1641 chan = &sc->sc_ch1; 1642 else 1643 chan = &sc->sc_ch0; 1644 1645 /* disable ac3 and 24 and 32 bit s/pdif modes */ 1646 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, CMPCI_REG_AC3EN1); 1647 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_AC3EN2); 1648 cmpci_reg_clear_reg_misc(sc, CMPCI_REG_SPD32SEL); 1649 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, CMPCI_REG_SPDIF_24); 1650 1651 /* playback to ... */ 1652 if (CMPCI_ISCAP(sc, SPDOUT) && 1653 sc->sc_gain[CMPCI_PLAYBACK_MODE][CMPCI_LR] 1654 == CMPCI_PLAYBACK_MODE_SPDIF && 1655 (chan->md_divide == CMPCI_REG_RATE_44100 || 1656 (CMPCI_ISCAP(sc, SPDOUT_48K) && 1657 chan->md_divide == CMPCI_REG_RATE_48000))) { 1658 /* playback to SPDIF */ 1659 if (sc->sc_play_channel == 0) 1660 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 1661 CMPCI_REG_SPDIF0_ENABLE); 1662 else 1663 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 1664 CMPCI_REG_SPDIF1_ENABLE); 1665 enspdout = 1; 1666 if (chan->md_divide == CMPCI_REG_RATE_48000) 1667 cmpci_reg_set_reg_misc(sc, 1668 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K); 1669 else 1670 cmpci_reg_clear_reg_misc(sc, 1671 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K); 1672 /* XXX assume sample rate <= 48kHz */ 1673 cmpci_reg_clear_4(sc, CMPCI_REG_CHANNEL_FORMAT, 1674 CMPCI_REG_DBL_SPD_RATE); 1675 } else { 1676 /* playback to DAC */ 1677 if (sc->sc_play_channel == 0) 1678 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 1679 CMPCI_REG_SPDIF0_ENABLE); 1680 else 1681 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 1682 CMPCI_REG_SPDIF1_ENABLE); 1683 if (CMPCI_ISCAP(sc, SPDOUT_48K)) 1684 cmpci_reg_clear_reg_misc(sc, 1685 CMPCI_REG_SPDIFOUT_48K | CMPCI_REG_SPDIF48K); 1686 } 1687 1688 /* legacy to SPDIF/out or not */ 1689 if (CMPCI_ISCAP(sc, SPDLEGACY)) { 1690 if (sc->sc_gain[CMPCI_SPDIF_OUT_PLAYBACK][CMPCI_LR] 1691 == CMPCI_SPDIF_OUT_PLAYBACK_WAVE) 1692 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 1693 CMPCI_REG_LEGACY_SPDIF_ENABLE); 1694 else { 1695 cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL, 1696 CMPCI_REG_LEGACY_SPDIF_ENABLE); 1697 enspdout = 1; 1698 } 1699 } 1700 1701 /* enable/disable SPDIF/out */ 1702 if (CMPCI_ISCAP(sc, XSPDOUT) && enspdout) 1703 cmpci_reg_set_4(sc, CMPCI_REG_LEGACY_CTRL, 1704 CMPCI_REG_XSPDIF_ENABLE); 1705 else 1706 cmpci_reg_clear_4(sc, CMPCI_REG_LEGACY_CTRL, 1707 CMPCI_REG_XSPDIF_ENABLE); 1708 1709 /* SPDIF monitor (digital to analog output) */ 1710 if (CMPCI_ISCAP(sc, SPDIN_MONITOR)) { 1711 v = sc->sc_gain[CMPCI_MONITOR_DAC][CMPCI_LR]; 1712 if (!(v & CMPCI_MONDAC_ENABLE)) 1713 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1714 CMPCI_REG_SPDIN_MONITOR); 1715 if (v & CMPCI_MONDAC_SPDOUT) 1716 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 1717 CMPCI_REG_SPDIFOUT_DAC); 1718 else 1719 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 1720 CMPCI_REG_SPDIFOUT_DAC); 1721 if (v & CMPCI_MONDAC_ENABLE) 1722 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1723 CMPCI_REG_SPDIN_MONITOR); 1724 } 1725 } 1726 1727 int 1728 cmpci_set_in_ports(struct cmpci_softc *sc) 1729 { 1730 int mask; 1731 int bitsl, bitsr; 1732 1733 mask = sc->sc_in_mask; 1734 1735 /* 1736 * Note CMPCI_RECORD_SOURCE_CD, CMPCI_RECORD_SOURCE_LINE_IN and 1737 * CMPCI_RECORD_SOURCE_FM are defined to the corresponding bit 1738 * of the mixer register. 1739 */ 1740 bitsr = mask & (CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN | 1741 CMPCI_RECORD_SOURCE_FM); 1742 1743 bitsl = CMPCI_SB16_MIXER_SRC_R_TO_L(bitsr); 1744 if (mask & CMPCI_RECORD_SOURCE_MIC) { 1745 bitsl |= CMPCI_SB16_MIXER_MIC_SRC; 1746 bitsr |= CMPCI_SB16_MIXER_MIC_SRC; 1747 } 1748 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, bitsl); 1749 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, bitsr); 1750 1751 if (mask & CMPCI_RECORD_SOURCE_AUX_IN) 1752 cmpci_reg_set_1(sc, CMPCI_REG_MIXER25, 1753 CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN); 1754 else 1755 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER25, 1756 CMPCI_REG_RAUXREN | CMPCI_REG_RAUXLEN); 1757 1758 if (mask & CMPCI_RECORD_SOURCE_WAVE) 1759 cmpci_reg_set_1(sc, CMPCI_REG_MIXER24, 1760 CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR); 1761 else 1762 cmpci_reg_clear_1(sc, CMPCI_REG_MIXER24, 1763 CMPCI_REG_WAVEINL | CMPCI_REG_WAVEINR); 1764 1765 if (CMPCI_ISCAP(sc, SPDIN) && 1766 (sc->sc_ch1.md_divide == CMPCI_REG_RATE_44100 || 1767 (CMPCI_ISCAP(sc, SPDOUT_48K) && 1768 sc->sc_ch1.md_divide == CMPCI_REG_RATE_48000/* XXX? */))) { 1769 if (mask & CMPCI_RECORD_SOURCE_SPDIF) { 1770 /* enable SPDIF/in */ 1771 cmpci_reg_set_4(sc, 1772 CMPCI_REG_FUNC_1, 1773 CMPCI_REG_SPDIF1_ENABLE); 1774 } else { 1775 cmpci_reg_clear_4(sc, 1776 CMPCI_REG_FUNC_1, 1777 CMPCI_REG_SPDIF1_ENABLE); 1778 } 1779 } 1780 1781 return 0; 1782 } 1783 1784 int 1785 cmpci_set_port(void *handle, mixer_ctrl_t *cp) 1786 { 1787 struct cmpci_softc *sc = handle; 1788 int lgain, rgain; 1789 1790 switch (cp->dev) { 1791 case CMPCI_MIC_VOL: 1792 case CMPCI_PCSPEAKER: 1793 case CMPCI_MIC_RECVOL: 1794 if (cp->un.value.num_channels != 1) 1795 return EINVAL; 1796 /* FALLTHROUGH */ 1797 case CMPCI_DAC_VOL: 1798 case CMPCI_FM_VOL: 1799 case CMPCI_CD_VOL: 1800 case CMPCI_LINE_IN_VOL: 1801 case CMPCI_AUX_IN_VOL: 1802 case CMPCI_MASTER_VOL: 1803 if (cp->type != AUDIO_MIXER_VALUE) 1804 return EINVAL; 1805 switch (cp->un.value.num_channels) { 1806 case 1: 1807 lgain = rgain = 1808 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 1809 break; 1810 case 2: 1811 lgain = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1812 rgain = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 1813 break; 1814 default: 1815 return EINVAL; 1816 } 1817 sc->sc_gain[cp->dev][CMPCI_LEFT] = lgain; 1818 sc->sc_gain[cp->dev][CMPCI_RIGHT] = rgain; 1819 1820 cmpci_set_mixer_gain(sc, cp->dev); 1821 break; 1822 1823 case CMPCI_RECORD_SOURCE: 1824 if (cp->type != AUDIO_MIXER_SET) 1825 return EINVAL; 1826 1827 if (cp->un.mask & ~(CMPCI_RECORD_SOURCE_MIC | 1828 CMPCI_RECORD_SOURCE_CD | CMPCI_RECORD_SOURCE_LINE_IN | 1829 CMPCI_RECORD_SOURCE_AUX_IN | CMPCI_RECORD_SOURCE_WAVE | 1830 CMPCI_RECORD_SOURCE_FM | CMPCI_RECORD_SOURCE_SPDIF)) 1831 return EINVAL; 1832 1833 if (cp->un.mask & CMPCI_RECORD_SOURCE_SPDIF) 1834 cp->un.mask = CMPCI_RECORD_SOURCE_SPDIF; 1835 1836 sc->sc_in_mask = cp->un.mask; 1837 return cmpci_set_in_ports(sc); 1838 1839 /* boolean */ 1840 case CMPCI_DAC_MUTE: 1841 case CMPCI_FM_MUTE: 1842 case CMPCI_CD_MUTE: 1843 case CMPCI_LINE_IN_MUTE: 1844 case CMPCI_AUX_IN_MUTE: 1845 case CMPCI_MIC_MUTE: 1846 case CMPCI_MIC_PREAMP: 1847 case CMPCI_PLAYBACK_MODE: 1848 case CMPCI_SPDIF_IN_PHASE: 1849 case CMPCI_SPDIF_LOOP: 1850 case CMPCI_SPDIF_OUT_PLAYBACK: 1851 case CMPCI_SPDIF_OUT_VOLTAGE: 1852 case CMPCI_REAR: 1853 case CMPCI_INDIVIDUAL: 1854 case CMPCI_REVERSE: 1855 case CMPCI_SURROUND: 1856 if (cp->type != AUDIO_MIXER_ENUM) 1857 return EINVAL; 1858 sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord != 0; 1859 cmpci_set_mixer_gain(sc, cp->dev); 1860 break; 1861 1862 case CMPCI_SPDIF_IN_SELECT: 1863 switch (cp->un.ord) { 1864 case CMPCI_SPDIF_IN_SPDIN1: 1865 case CMPCI_SPDIF_IN_SPDIN2: 1866 case CMPCI_SPDIF_IN_SPDOUT: 1867 break; 1868 default: 1869 return EINVAL; 1870 } 1871 goto xenum; 1872 case CMPCI_MONITOR_DAC: 1873 switch (cp->un.ord) { 1874 case CMPCI_MONITOR_DAC_OFF: 1875 case CMPCI_MONITOR_DAC_SPDIN: 1876 case CMPCI_MONITOR_DAC_SPDOUT: 1877 break; 1878 default: 1879 return EINVAL; 1880 } 1881 xenum: 1882 if (cp->type != AUDIO_MIXER_ENUM) 1883 return EINVAL; 1884 sc->sc_gain[cp->dev][CMPCI_LR] = cp->un.ord; 1885 cmpci_set_mixer_gain(sc, cp->dev); 1886 break; 1887 1888 default: 1889 return EINVAL; 1890 } 1891 1892 return 0; 1893 } 1894 1895 int 1896 cmpci_get_port(void *handle, mixer_ctrl_t *cp) 1897 { 1898 struct cmpci_softc *sc = handle; 1899 1900 switch (cp->dev) { 1901 case CMPCI_MIC_VOL: 1902 case CMPCI_PCSPEAKER: 1903 case CMPCI_MIC_RECVOL: 1904 if (cp->un.value.num_channels != 1) 1905 return EINVAL; 1906 /*FALLTHROUGH*/ 1907 case CMPCI_DAC_VOL: 1908 case CMPCI_FM_VOL: 1909 case CMPCI_CD_VOL: 1910 case CMPCI_LINE_IN_VOL: 1911 case CMPCI_AUX_IN_VOL: 1912 case CMPCI_MASTER_VOL: 1913 switch (cp->un.value.num_channels) { 1914 case 1: 1915 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1916 sc->sc_gain[cp->dev][CMPCI_LEFT]; 1917 break; 1918 case 2: 1919 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1920 sc->sc_gain[cp->dev][CMPCI_LEFT]; 1921 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1922 sc->sc_gain[cp->dev][CMPCI_RIGHT]; 1923 break; 1924 default: 1925 return EINVAL; 1926 } 1927 break; 1928 1929 case CMPCI_RECORD_SOURCE: 1930 cp->un.mask = sc->sc_in_mask; 1931 break; 1932 1933 case CMPCI_DAC_MUTE: 1934 case CMPCI_FM_MUTE: 1935 case CMPCI_CD_MUTE: 1936 case CMPCI_LINE_IN_MUTE: 1937 case CMPCI_AUX_IN_MUTE: 1938 case CMPCI_MIC_MUTE: 1939 case CMPCI_MIC_PREAMP: 1940 case CMPCI_PLAYBACK_MODE: 1941 case CMPCI_SPDIF_IN_SELECT: 1942 case CMPCI_SPDIF_IN_PHASE: 1943 case CMPCI_SPDIF_LOOP: 1944 case CMPCI_SPDIF_OUT_PLAYBACK: 1945 case CMPCI_SPDIF_OUT_VOLTAGE: 1946 case CMPCI_MONITOR_DAC: 1947 case CMPCI_REAR: 1948 case CMPCI_INDIVIDUAL: 1949 case CMPCI_REVERSE: 1950 case CMPCI_SURROUND: 1951 cp->un.ord = sc->sc_gain[cp->dev][CMPCI_LR]; 1952 break; 1953 1954 default: 1955 return EINVAL; 1956 } 1957 1958 return 0; 1959 } 1960 1961 /* ARGSUSED */ 1962 size_t 1963 cmpci_round_buffersize(void *handle, int direction, size_t bufsize) 1964 { 1965 if (bufsize > 0x10000) 1966 bufsize = 0x10000; 1967 1968 return bufsize; 1969 } 1970 1971 paddr_t 1972 cmpci_mappage(void *handle, void *addr, off_t offset, int prot) 1973 { 1974 struct cmpci_softc *sc = handle; 1975 struct cmpci_dmanode *p; 1976 1977 if (offset < 0 || NULL == (p = cmpci_find_dmamem(sc, addr))) 1978 return -1; 1979 1980 return bus_dmamem_mmap(p->cd_tag, p->cd_segs, 1981 nitems(p->cd_segs), offset, prot, BUS_DMA_WAITOK); 1982 } 1983 1984 /* ARGSUSED */ 1985 int 1986 cmpci_get_props(void *handle) 1987 { 1988 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1989 } 1990 1991 int 1992 cmpci_trigger_output(void *handle, void *start, void *end, int blksize, 1993 void (*intr)(void *), void *arg, struct audio_params *param) 1994 { 1995 struct cmpci_softc *sc = handle; 1996 struct cmpci_dmanode *p; 1997 struct cmpci_channel *chan; 1998 uint32_t reg_dma_base, reg_dma_bytes, reg_dma_samples, reg_dir, 1999 reg_intr_enable, reg_enable; 2000 uint32_t length; 2001 size_t buffer_size = (caddr_t)end - (caddr_t)start; 2002 2003 cmpci_set_out_ports(sc); 2004 2005 if (sc->sc_play_channel == 1) { 2006 chan = &sc->sc_ch1; 2007 reg_dma_base = CMPCI_REG_DMA1_BASE; 2008 reg_dma_bytes = CMPCI_REG_DMA1_BYTES; 2009 reg_dma_samples = CMPCI_REG_DMA1_SAMPLES; 2010 reg_dir = CMPCI_REG_CH1_DIR; 2011 reg_intr_enable = CMPCI_REG_CH1_INTR_ENABLE; 2012 reg_enable = CMPCI_REG_CH1_ENABLE; 2013 } else { 2014 chan = &sc->sc_ch0; 2015 reg_dma_base = CMPCI_REG_DMA0_BASE; 2016 reg_dma_bytes = CMPCI_REG_DMA0_BYTES; 2017 reg_dma_samples = CMPCI_REG_DMA0_SAMPLES; 2018 reg_dir = CMPCI_REG_CH0_DIR; 2019 reg_intr_enable = CMPCI_REG_CH0_INTR_ENABLE; 2020 reg_enable = CMPCI_REG_CH0_ENABLE; 2021 } 2022 2023 chan->bps = (param->channels > 1 ? 2 : 1) * param->bps * param->factor; 2024 if (!chan->bps) 2025 return EINVAL; 2026 2027 chan->intr = intr; 2028 chan->intr_arg = arg; 2029 chan->blksize = blksize; 2030 chan->nblocks = buffer_size / chan->blksize; 2031 chan->swpos = 0; 2032 2033 /* set DMA frame */ 2034 if (!(p = cmpci_find_dmamem(sc, start))) 2035 return EINVAL; 2036 bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg_dma_base, 2037 DMAADDR(p)); 2038 delay(10); 2039 length = (buffer_size + 1) / chan->bps - 1; 2040 bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_bytes, length); 2041 delay(10); 2042 2043 /* set interrupt count */ 2044 length = (chan->blksize + chan->bps - 1) / chan->bps - 1; 2045 bus_space_write_2(sc->sc_iot, sc->sc_ioh, reg_dma_samples, length); 2046 delay(10); 2047 2048 /* start DMA */ 2049 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, reg_dir); /* PLAY */ 2050 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, reg_intr_enable); 2051 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, reg_enable); 2052 2053 return 0; 2054 } 2055 2056 int 2057 cmpci_trigger_input(void *handle, void *start, void *end, int blksize, 2058 void (*intr)(void *), void *arg, struct audio_params *param) 2059 { 2060 struct cmpci_softc *sc = handle; 2061 struct cmpci_dmanode *p; 2062 struct cmpci_channel *chan = &sc->sc_ch1; 2063 size_t buffer_size = (caddr_t)end - (caddr_t)start; 2064 2065 cmpci_set_in_ports(sc); 2066 2067 chan->bps = param->channels * param->bps * param->factor; 2068 if (!chan->bps) 2069 return EINVAL; 2070 2071 chan->intr = intr; 2072 chan->intr_arg = arg; 2073 chan->blksize = blksize; 2074 chan->nblocks = buffer_size / chan->blksize; 2075 chan->swpos = 0; 2076 2077 /* set DMA frame */ 2078 if (!(p = cmpci_find_dmamem(sc, start))) 2079 return EINVAL; 2080 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BASE, 2081 DMAADDR(p)); 2082 delay(10); 2083 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BYTES, 2084 (buffer_size + 1) / chan->bps - 1); 2085 delay(10); 2086 2087 /* set interrupt count */ 2088 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_SAMPLES, 2089 (chan->blksize + chan->bps - 1) / chan->bps - 1); 2090 delay(10); 2091 2092 /* start DMA */ 2093 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR); /* REC */ 2094 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 2095 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 2096 2097 return 0; 2098 } 2099 2100 /* end of file */ 2101