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