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