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