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