1 /* $OpenBSD: cmpci.c,v 1.5 2001/10/31 11:00:24 art Exp $ */ 2 3 /* 4 * Copyright (c) 2000 Takuya SHIOZAKI 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29 30 /* 31 * C-Media CMI8x38 Audio Chip Support. 32 * 33 * TODO: 34 * - Legacy MPU, OPL and Joystick support (but, I have no interest...) 35 * - SPDIF support 36 * 37 */ 38 39 #undef CMPCI_SPDIF_SUPPORT /* XXX: not working */ 40 41 #if defined(AUDIO_DEBUG) || defined(DEBUG) 42 #define DPRINTF(x) printf x 43 #else 44 #define DPRINTF(x) 45 #endif 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/kernel.h> 50 #include <sys/malloc.h> 51 #include <sys/device.h> 52 #include <sys/proc.h> 53 54 #include <dev/pci/pcidevs.h> 55 #include <dev/pci/pcivar.h> 56 57 #include <sys/audioio.h> 58 #include <dev/audio_if.h> 59 #include <dev/mulaw.h> 60 #include <dev/auconv.h> 61 62 #include <dev/pci/cmpcireg.h> 63 #include <dev/pci/cmpcivar.h> 64 65 #include <machine/bus.h> 66 #include <machine/intr.h> 67 68 /* 69 * Low-level HW interface 70 */ 71 static __inline uint8_t cmpci_mixerreg_read __P((struct cmpci_softc *, 72 uint8_t)); 73 static __inline void cmpci_mixerreg_write __P((struct cmpci_softc *, 74 uint8_t, uint8_t)); 75 static __inline void cmpci_reg_partial_write_4 __P((struct cmpci_softc *, 76 int, int, 77 uint32_t, uint32_t)); 78 static __inline void cmpci_reg_set_4 __P((struct cmpci_softc *, 79 int, uint32_t)); 80 static __inline void cmpci_reg_clear_4 __P((struct cmpci_softc *, 81 int, uint32_t)); 82 static int cmpci_rate_to_index __P((int)); 83 static __inline int cmpci_index_to_rate __P((int)); 84 static __inline int cmpci_index_to_divider __P((int)); 85 86 static int cmpci_adjust __P((int, int)); 87 static void cmpci_set_mixer_gain __P((struct cmpci_softc *, int)); 88 static int cmpci_set_in_ports __P((struct cmpci_softc *, int)); 89 90 91 /* 92 * autoconf interface 93 */ 94 int cmpci_match __P((struct device *, void *, void *)); 95 void cmpci_attach __P((struct device *, struct device *, void *)); 96 97 struct cfdriver cmpci_cd = { 98 NULL, "cmpci", DV_DULL 99 }; 100 101 struct cfattach cmpci_ca = { 102 sizeof (struct cmpci_softc), cmpci_match, cmpci_attach 103 }; 104 105 struct audio_device cmpci_device = { 106 "CMI PCI Audio", 107 "", 108 "cmpci" 109 }; 110 111 /* interrupt */ 112 int cmpci_intr __P((void *)); 113 114 115 /* 116 * DMA stuff 117 */ 118 int cmpci_alloc_dmamem __P((struct cmpci_softc *, 119 size_t, int, int, caddr_t *)); 120 int cmpci_free_dmamem __P((struct cmpci_softc *, caddr_t, int)); 121 struct cmpci_dmanode * cmpci_find_dmamem __P((struct cmpci_softc *, 122 caddr_t)); 123 124 /* 125 * Interface to machine independent layer 126 */ 127 int cmpci_open __P((void *, int)); 128 void cmpci_close __P((void *)); 129 int cmpci_query_encoding __P((void *, struct audio_encoding *)); 130 int cmpci_set_params __P((void *, int, int, 131 struct audio_params *, 132 struct audio_params *)); 133 int cmpci_round_blocksize __P((void *, int)); 134 int cmpci_halt_output __P((void *)); 135 int cmpci_halt_input __P((void *)); 136 int cmpci_getdev __P((void *, struct audio_device *)); 137 int cmpci_set_port __P((void *, mixer_ctrl_t *)); 138 int cmpci_get_port __P((void *, mixer_ctrl_t *)); 139 int cmpci_query_devinfo __P((void *, mixer_devinfo_t *)); 140 void *cmpci_malloc __P((void *, u_long, int, int)); 141 void cmpci_free __P((void *, void *, int)); 142 u_long cmpci_round_buffersize __P((void *, u_long)); 143 paddr_t cmpci_mappage __P((void *, void *, off_t, int)); 144 int cmpci_get_props __P((void *)); 145 int cmpci_trigger_output __P((void *, void *, void *, int, 146 void (*)(void *), void *, 147 struct audio_params *)); 148 int cmpci_trigger_input __P((void *, void *, void *, int, 149 void (*)(void *), void *, 150 struct audio_params *)); 151 152 struct audio_hw_if cmpci_hw_if = { 153 cmpci_open, /* open */ 154 cmpci_close, /* close */ 155 NULL, /* drain */ 156 cmpci_query_encoding, /* query_encoding */ 157 cmpci_set_params, /* set_params */ 158 cmpci_round_blocksize, /* round_blocksize */ 159 NULL, /* commit_settings */ 160 NULL, /* init_output */ 161 NULL, /* init_input */ 162 NULL, /* start_output */ 163 NULL, /* start_input */ 164 cmpci_halt_output, /* halt_output */ 165 cmpci_halt_input, /* halt_input */ 166 NULL, /* speaker_ctl */ 167 cmpci_getdev, /* getdev */ 168 NULL, /* setfd */ 169 cmpci_set_port, /* set_port */ 170 cmpci_get_port, /* get_port */ 171 cmpci_query_devinfo, /* query_devinfo */ 172 cmpci_malloc, /* malloc */ 173 cmpci_free, /* free */ 174 cmpci_round_buffersize, /* round_buffersize */ 175 cmpci_mappage, /* mappage */ 176 cmpci_get_props, /* get_props */ 177 cmpci_trigger_output, /* trigger_output */ 178 cmpci_trigger_input /* trigger_input */ 179 }; 180 181 182 /* 183 * Low-level HW interface 184 */ 185 186 /* mixer register read/write */ 187 static __inline uint8_t 188 cmpci_mixerreg_read(sc, no) 189 struct cmpci_softc *sc; 190 uint8_t no; 191 { 192 uint8_t ret; 193 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBADDR, no); 194 delay(10); 195 ret = bus_space_read_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBDATA); 196 delay(10); 197 return ret; 198 } 199 200 static __inline void 201 cmpci_mixerreg_write(sc, no, val) 202 struct cmpci_softc *sc; 203 uint8_t no, val; 204 { 205 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBADDR, no); 206 delay(10); 207 bus_space_write_1(sc->sc_iot, sc->sc_ioh, CMPCI_REG_SBDATA, val); 208 delay(10); 209 } 210 211 /* register partial write */ 212 static __inline void 213 cmpci_reg_partial_write_4(sc, no, shift, mask, val) 214 struct cmpci_softc *sc; 215 int no, shift; 216 uint32_t mask, val; 217 { 218 bus_space_write_4(sc->sc_iot, sc->sc_ioh, no, 219 (val<<shift) | 220 (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) & ~(mask<<shift))); 221 delay(10); 222 } 223 224 /* register set/clear bit */ 225 static __inline void 226 cmpci_reg_set_4(sc, no, mask) 227 struct cmpci_softc *sc; 228 int no; 229 uint32_t mask; 230 { 231 bus_space_write_4(sc->sc_iot, sc->sc_ioh, no, 232 (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) | mask)); 233 delay(10); 234 } 235 236 static __inline void 237 cmpci_reg_clear_4(sc, no, mask) 238 struct cmpci_softc *sc; 239 int no; 240 uint32_t mask; 241 { 242 bus_space_write_4(sc->sc_iot, sc->sc_ioh, no, 243 (bus_space_read_4(sc->sc_iot, sc->sc_ioh, no) & ~mask)); 244 delay(10); 245 } 246 247 248 /* rate */ 249 struct { 250 int rate; 251 int divider; 252 } cmpci_rate_table[CMPCI_REG_NUMRATE] = { 253 #define _RATE(n) { n, CMPCI_REG_RATE_ ## n } 254 _RATE(5512), 255 _RATE(8000), 256 _RATE(11025), 257 _RATE(16000), 258 _RATE(22050), 259 _RATE(32000), 260 _RATE(44100), 261 _RATE(48000) 262 #undef _RATE 263 }; 264 265 int 266 cmpci_rate_to_index(rate) 267 int rate; 268 { 269 int i; 270 for (i=0; i<CMPCI_REG_NUMRATE-2; i++) 271 if (rate <= 272 (cmpci_rate_table[i].rate + cmpci_rate_table[i+1].rate) / 2) 273 return i; 274 return i; /* 48000 */ 275 } 276 277 static __inline int 278 cmpci_index_to_rate(index) 279 int index; 280 { 281 282 return cmpci_rate_table[index].rate; 283 } 284 285 static __inline int 286 cmpci_index_to_divider(index) 287 int index; 288 { 289 return cmpci_rate_table[index].divider; 290 } 291 292 293 /* 294 * interface to configure the device. 295 */ 296 int 297 cmpci_match(parent, match, aux) 298 struct device *parent; 299 void *match; 300 void *aux; 301 { 302 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 303 304 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CMI && 305 (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CMI_CMI8338A || 306 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CMI_CMI8338B || 307 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CMI_CMI8738)) 308 return 1; 309 310 return 0; 311 } 312 313 void 314 cmpci_attach(parent, self, aux) 315 struct device *parent, *self; 316 void *aux; 317 { 318 struct cmpci_softc *sc = (struct cmpci_softc *)self; 319 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 320 pci_intr_handle_t ih; 321 char const *intrstr; 322 int i, v; 323 324 /* map I/O space */ 325 if (pci_mapreg_map(pa, CMPCI_PCI_IOBASEREG, PCI_MAPREG_TYPE_IO, 0, 326 &sc->sc_iot, &sc->sc_ioh, NULL, NULL, 0)) { 327 printf("\n%s: failed to map I/O space\n", sc->sc_dev.dv_xname); 328 return; 329 } 330 331 /* interrupt */ 332 if (pci_intr_map(pa, &ih)) { 333 printf("\n%s: failed to map interrupt\n", sc->sc_dev.dv_xname); 334 return; 335 } 336 intrstr = pci_intr_string(pa->pa_pc, ih); 337 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, cmpci_intr, 338 sc, sc->sc_dev.dv_xname); 339 340 if (sc->sc_ih == NULL) { 341 printf("\n%s: couldn't establish interrupt", 342 sc->sc_dev.dv_xname); 343 if (intrstr) 344 printf(" at %s", intrstr); 345 printf("\n"); 346 return; 347 } 348 printf(": %s\n", intrstr); 349 350 sc->sc_dmat = pa->pa_dmat; 351 352 audio_attach_mi(&cmpci_hw_if, sc, &sc->sc_dev); 353 354 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_RESET, 0); 355 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, 0); 356 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, 0); 357 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, 358 CMPCI_SB16_SW_CD|CMPCI_SB16_SW_MIC| 359 CMPCI_SB16_SW_LINE); 360 for (i = 0; i < CMPCI_NDEVS; i++) { 361 switch(i) { 362 case CMPCI_MIC_VOL: 363 case CMPCI_LINE_IN_VOL: 364 v = 0; 365 break; 366 case CMPCI_BASS: 367 case CMPCI_TREBLE: 368 v = CMPCI_ADJUST_GAIN(sc, AUDIO_MAX_GAIN / 2); 369 break; 370 case CMPCI_CD_IN_MUTE: 371 case CMPCI_MIC_IN_MUTE: 372 case CMPCI_LINE_IN_MUTE: 373 case CMPCI_FM_IN_MUTE: 374 case CMPCI_CD_SWAP: 375 case CMPCI_MIC_SWAP: 376 case CMPCI_LINE_SWAP: 377 case CMPCI_FM_SWAP: 378 v = 0; 379 break; 380 case CMPCI_CD_OUT_MUTE: 381 case CMPCI_MIC_OUT_MUTE: 382 case CMPCI_LINE_OUT_MUTE: 383 v = 1; 384 break; 385 default: 386 v = CMPCI_ADJUST_GAIN(sc, AUDIO_MAX_GAIN / 2); 387 } 388 sc->gain[i][CMPCI_LEFT] = sc->gain[i][CMPCI_RIGHT] = v; 389 cmpci_set_mixer_gain(sc, i); 390 } 391 } 392 393 int 394 cmpci_intr(handle) 395 void *handle; 396 { 397 struct cmpci_softc *sc = handle; 398 uint32_t intrstat; 399 int s; 400 401 intrstat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 402 CMPCI_REG_INTR_STATUS); 403 delay(10); 404 405 if (!(intrstat & CMPCI_REG_ANY_INTR)) 406 return 0; 407 408 /* disable and reset intr */ 409 s = splaudio(); 410 if (intrstat & CMPCI_REG_CH0_INTR) 411 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 412 CMPCI_REG_CH0_INTR_ENABLE); 413 if (intrstat&CMPCI_REG_CH1_INTR) 414 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 415 CMPCI_REG_CH1_INTR_ENABLE); 416 splx(s); 417 418 if (intrstat & CMPCI_REG_CH0_INTR) { 419 if (sc->sc_play.intr) 420 (*sc->sc_play.intr)(sc->sc_play.intr_arg); 421 } 422 if (intrstat & CMPCI_REG_CH1_INTR) { 423 if (sc->sc_rec.intr) 424 (*sc->sc_rec.intr)(sc->sc_rec.intr_arg); 425 } 426 427 /* enable intr */ 428 s = splaudio(); 429 if ( intrstat & CMPCI_REG_CH0_INTR ) 430 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 431 CMPCI_REG_CH0_INTR_ENABLE); 432 if (intrstat & CMPCI_REG_CH1_INTR) 433 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 434 CMPCI_REG_CH1_INTR_ENABLE); 435 splx(s); 436 437 return 1; 438 } 439 440 /* open/close */ 441 int 442 cmpci_open(handle, flags) 443 void *handle; 444 int flags; 445 { 446 struct cmpci_softc *sc = handle; 447 (void)sc; 448 (void)flags; 449 450 return 0; 451 } 452 453 void 454 cmpci_close(handle) 455 void *handle; 456 { 457 (void)handle; 458 } 459 460 int 461 cmpci_query_encoding(handle, fp) 462 void *handle; 463 struct audio_encoding *fp; 464 { 465 struct cmpci_softc *sc = handle; 466 (void)sc; 467 468 switch (fp->index) { 469 case 0: 470 strcpy(fp->name, AudioEulinear); 471 fp->encoding = AUDIO_ENCODING_ULINEAR; 472 fp->precision = 8; 473 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 474 break; 475 case 1: 476 strcpy(fp->name, AudioEmulaw); 477 fp->encoding = AUDIO_ENCODING_ULAW; 478 fp->precision = 8; 479 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 480 break; 481 case 2: 482 strcpy(fp->name, AudioEalaw); 483 fp->encoding = AUDIO_ENCODING_ALAW; 484 fp->precision = 8; 485 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 486 break; 487 case 3: 488 strcpy(fp->name, AudioEslinear); 489 fp->encoding = AUDIO_ENCODING_SLINEAR; 490 fp->precision = 8; 491 fp->flags = 0; 492 break; 493 case 4: 494 strcpy(fp->name, AudioEslinear_le); 495 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 496 fp->precision = 16; 497 fp->flags = 0; 498 break; 499 case 5: 500 strcpy(fp->name, AudioEulinear_le); 501 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 502 fp->precision = 16; 503 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 504 break; 505 case 6: 506 strcpy(fp->name, AudioEslinear_be); 507 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 508 fp->precision = 16; 509 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 510 break; 511 case 7: 512 strcpy(fp->name, AudioEulinear_be); 513 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 514 fp->precision = 16; 515 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 516 break; 517 default: 518 return EINVAL; 519 } 520 return 0; 521 } 522 523 524 int 525 cmpci_set_params(handle, setmode, usemode, play, rec) 526 void *handle; 527 int setmode, usemode; 528 struct audio_params *play, *rec; 529 { 530 int i; 531 struct cmpci_softc *sc = handle; 532 533 for (i=0; i<2; i++) { 534 int md_format; 535 int md_divide; 536 int md_index; 537 int mode; 538 struct audio_params *p; 539 540 switch (i) { 541 case 0: 542 mode = AUMODE_PLAY; 543 p = play; 544 break; 545 case 1: 546 mode = AUMODE_RECORD; 547 p = rec; 548 break; 549 } 550 551 if (!(setmode & mode)) 552 continue; 553 554 /* format */ 555 p->sw_code = NULL; 556 switch (p->channels) { 557 case 1: 558 md_format = CMPCI_REG_FORMAT_MONO; 559 break; 560 case 2: 561 md_format = CMPCI_REG_FORMAT_STEREO; 562 break; 563 default: 564 return (EINVAL); 565 } 566 switch (p->encoding) { 567 case AUDIO_ENCODING_ULAW: 568 if (p->precision != 8) 569 return (EINVAL); 570 if (mode & AUMODE_PLAY) { 571 p->factor = 2; 572 p->sw_code = mulaw_to_slinear16; 573 md_format |= CMPCI_REG_FORMAT_16BIT; 574 } else 575 p->sw_code = ulinear8_to_mulaw; 576 md_format |= CMPCI_REG_FORMAT_8BIT; 577 break; 578 case AUDIO_ENCODING_ALAW: 579 if (p->precision != 8) 580 return (EINVAL); 581 if (mode & AUMODE_PLAY) { 582 p->factor = 2; 583 p->sw_code = alaw_to_slinear16; 584 md_format |= CMPCI_REG_FORMAT_16BIT; 585 } else 586 p->sw_code = ulinear8_to_alaw; 587 md_format |= CMPCI_REG_FORMAT_8BIT; 588 break; 589 case AUDIO_ENCODING_SLINEAR_LE: 590 switch (p->precision) { 591 case 8: 592 p->sw_code = change_sign8; 593 md_format |= CMPCI_REG_FORMAT_8BIT; 594 break; 595 case 16: 596 md_format |= CMPCI_REG_FORMAT_16BIT; 597 break; 598 default: 599 return (EINVAL); 600 } 601 break; 602 case AUDIO_ENCODING_SLINEAR_BE: 603 switch (p->precision) { 604 case 8: 605 md_format |= CMPCI_REG_FORMAT_8BIT; 606 p->sw_code = change_sign8; 607 break; 608 case 16: 609 md_format |= CMPCI_REG_FORMAT_16BIT; 610 p->sw_code = swap_bytes; 611 break; 612 default: 613 return (EINVAL); 614 } 615 break; 616 case AUDIO_ENCODING_ULINEAR_LE: 617 switch ( p->precision ) { 618 case 8: 619 md_format |= CMPCI_REG_FORMAT_8BIT; 620 break; 621 case 16: 622 md_format |= CMPCI_REG_FORMAT_16BIT; 623 p->sw_code = change_sign16; 624 break; 625 default: 626 return (EINVAL); 627 } 628 break; 629 case AUDIO_ENCODING_ULINEAR_BE: 630 switch (p->precision) { 631 case 8: 632 md_format |= CMPCI_REG_FORMAT_8BIT; 633 break; 634 case 16: 635 md_format |= CMPCI_REG_FORMAT_16BIT; 636 if ( mode&AUMODE_PLAY ) 637 p->sw_code = swap_bytes_change_sign16; 638 else 639 p->sw_code = change_sign16_swap_bytes; 640 break; 641 default: 642 return (EINVAL); 643 } 644 break; 645 default: 646 return (EINVAL); 647 } 648 if (mode & AUMODE_PLAY) 649 cmpci_reg_partial_write_4(sc, 650 CMPCI_REG_CHANNEL_FORMAT, 651 CMPCI_REG_CH0_FORMAT_SHIFT, 652 CMPCI_REG_CH0_FORMAT_MASK, 653 md_format); 654 else 655 cmpci_reg_partial_write_4(sc, 656 CMPCI_REG_CHANNEL_FORMAT, 657 CMPCI_REG_CH1_FORMAT_SHIFT, 658 CMPCI_REG_CH1_FORMAT_MASK, 659 md_format); 660 /* sample rate */ 661 md_index = cmpci_rate_to_index(p->sample_rate); 662 md_divide = cmpci_index_to_divider(md_index); 663 p->sample_rate = cmpci_index_to_rate(md_index); 664 #if 0 665 DPRINTF(("%s: sample:%d, divider=%d\n", 666 sc->sc_dev.dv_xname, (int)p->sample_rate, md_divide)); 667 #endif 668 if (mode & AUMODE_PLAY) { 669 cmpci_reg_partial_write_4(sc, 670 CMPCI_REG_FUNC_1, 671 CMPCI_REG_DAC_FS_SHIFT, 672 CMPCI_REG_DAC_FS_MASK, 673 md_divide); 674 #ifdef CMPCI_SPDIF_SUPPORT 675 switch (md_divide) { 676 case CMPCI_REG_RATE_44100: 677 cmpci_reg_clear_4(sc, CMPCI_REG_MISC, 678 CMPCI_REG_SPDIF_48K); 679 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 680 CMPCI_REG_SPDIF_LOOP); 681 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 682 CMPCI_REG_SPDIF0_ENABLE); 683 break; 684 case CMPCI_REG_RATE_48000: 685 cmpci_reg_set_4(sc, CMPCI_REG_MISC, 686 CMPCI_REG_SPDIF_48K); 687 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 688 CMPCI_REG_SPDIF_LOOP); 689 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 690 CMPCI_REG_SPDIF0_ENABLE); 691 break; 692 default: 693 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 694 CMPCI_REG_SPDIF0_ENABLE); 695 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 696 CMPCI_REG_SPDIF_LOOP); 697 } 698 #endif 699 } else { 700 cmpci_reg_partial_write_4(sc, 701 CMPCI_REG_FUNC_1, 702 CMPCI_REG_ADC_FS_SHIFT, 703 CMPCI_REG_ADC_FS_MASK, 704 md_divide); 705 #ifdef CMPCI_SPDIF_SUPPORT 706 if ( sc->in_mask&CMPCI_SPDIF_IN) { 707 switch (md_divide) { 708 case CMPCI_REG_RATE_44100: 709 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 710 CMPCI_REG_SPDIF1_ENABLE); 711 break; 712 default: 713 return EINVAL; 714 } 715 } else 716 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 717 CMPCI_REG_SPDIF1_ENABLE); 718 #endif 719 } 720 } 721 return 0; 722 } 723 724 /* ARGSUSED */ 725 int 726 cmpci_round_blocksize(handle, block) 727 void *handle; 728 int block; 729 { 730 return (block & -4); 731 } 732 733 int 734 cmpci_halt_output(handle) 735 void *handle; 736 { 737 struct cmpci_softc *sc = handle; 738 int s; 739 740 s = splaudio(); 741 sc->sc_play.intr = NULL; 742 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE); 743 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE); 744 /* wait for reset DMA */ 745 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET); 746 delay(10); 747 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET); 748 splx(s); 749 750 return 0; 751 } 752 753 int 754 cmpci_halt_input(handle) 755 void *handle; 756 { 757 struct cmpci_softc *sc = handle; 758 int s; 759 760 s = splaudio(); 761 sc->sc_rec.intr = NULL; 762 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 763 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 764 /* wait for reset DMA */ 765 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 766 delay(10); 767 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 768 splx(s); 769 770 return 0; 771 } 772 773 int 774 cmpci_getdev(handle, retp) 775 void *handle; 776 struct audio_device *retp; 777 { 778 *retp = cmpci_device; 779 return 0; 780 } 781 782 783 /* mixer device information */ 784 int 785 cmpci_query_devinfo(handle, dip) 786 void *handle; 787 mixer_devinfo_t *dip; 788 { 789 struct cmpci_softc *sc = handle; 790 (void)sc; 791 792 switch (dip->index) { 793 case CMPCI_MASTER_VOL: 794 dip->type = AUDIO_MIXER_VALUE; 795 dip->mixer_class = CMPCI_OUTPUT_CLASS; 796 dip->prev = dip->next = AUDIO_MIXER_LAST; 797 strcpy(dip->label.name, AudioNmaster); 798 dip->un.v.num_channels = 2; 799 strcpy(dip->un.v.units.name, AudioNvolume); 800 return 0; 801 case CMPCI_FM_VOL: 802 dip->type = AUDIO_MIXER_VALUE; 803 dip->mixer_class = CMPCI_INPUT_CLASS; 804 dip->prev = AUDIO_MIXER_LAST; 805 dip->next = CMPCI_FM_IN_MUTE; 806 strcpy(dip->label.name, AudioNfmsynth); 807 dip->un.v.num_channels = 2; 808 strcpy(dip->un.v.units.name, AudioNvolume); 809 return 0; 810 case CMPCI_CD_VOL: 811 dip->type = AUDIO_MIXER_VALUE; 812 dip->mixer_class = CMPCI_INPUT_CLASS; 813 dip->prev = AUDIO_MIXER_LAST; 814 dip->next = CMPCI_CD_IN_MUTE; 815 strcpy(dip->label.name, AudioNcd); 816 dip->un.v.num_channels = 2; 817 strcpy(dip->un.v.units.name, AudioNvolume); 818 return 0; 819 case CMPCI_VOICE_VOL: 820 dip->type = AUDIO_MIXER_VALUE; 821 dip->mixer_class = CMPCI_OUTPUT_CLASS; 822 dip->prev = AUDIO_MIXER_LAST; 823 dip->next = AUDIO_MIXER_LAST; 824 strcpy(dip->label.name, AudioNdac); 825 dip->un.v.num_channels = 2; 826 strcpy(dip->un.v.units.name, AudioNvolume); 827 return 0; 828 case CMPCI_OUTPUT_CLASS: 829 dip->type = AUDIO_MIXER_CLASS; 830 dip->mixer_class = CMPCI_INPUT_CLASS; 831 dip->next = dip->prev = AUDIO_MIXER_LAST; 832 strcpy(dip->label.name, AudioCoutputs); 833 return 0; 834 case CMPCI_MIC_VOL: 835 dip->type = AUDIO_MIXER_VALUE; 836 dip->mixer_class = CMPCI_INPUT_CLASS; 837 dip->prev = AUDIO_MIXER_LAST; 838 dip->next = CMPCI_MIC_IN_MUTE; 839 strcpy(dip->label.name, AudioNmicrophone); 840 dip->un.v.num_channels = 1; 841 strcpy(dip->un.v.units.name, AudioNvolume); 842 return 0; 843 case CMPCI_LINE_IN_VOL: 844 dip->type = AUDIO_MIXER_VALUE; 845 dip->mixer_class = CMPCI_INPUT_CLASS; 846 dip->prev = AUDIO_MIXER_LAST; 847 dip->next = CMPCI_LINE_IN_MUTE; 848 strcpy(dip->label.name, AudioNline); 849 dip->un.v.num_channels = 2; 850 strcpy(dip->un.v.units.name, AudioNvolume); 851 return 0; 852 case CMPCI_RECORD_SOURCE: 853 dip->mixer_class = CMPCI_RECORD_CLASS; 854 dip->prev = dip->next = AUDIO_MIXER_LAST; 855 strcpy(dip->label.name, AudioNsource); 856 dip->type = AUDIO_MIXER_SET; 857 #ifdef CMPCI_SPDIF_SUPPORT 858 dip->un.s.num_mem = 5; 859 #else 860 dip->un.s.num_mem = 4; 861 #endif 862 strcpy(dip->un.s.member[0].label.name, AudioNmicrophone); 863 dip->un.s.member[0].mask = 1 << CMPCI_MIC_VOL; 864 strcpy(dip->un.s.member[1].label.name, AudioNcd); 865 dip->un.s.member[1].mask = 1 << CMPCI_CD_VOL; 866 strcpy(dip->un.s.member[2].label.name, AudioNline); 867 dip->un.s.member[2].mask = 1 << CMPCI_LINE_IN_VOL; 868 strcpy(dip->un.s.member[3].label.name, AudioNfmsynth); 869 dip->un.s.member[3].mask = 1 << CMPCI_FM_VOL; 870 #ifdef CMPCI_SPDIF_SUPPORT 871 strcpy(dip->un.s.member[4].label.name, CmpciNspdif); 872 dip->un.s.member[4].mask = 1 << CMPCI_SPDIF_IN; 873 #endif 874 return 0; 875 case CMPCI_BASS: 876 dip->prev = dip->next = AUDIO_MIXER_LAST; 877 strcpy(dip->label.name, AudioNbass); 878 dip->type = AUDIO_MIXER_VALUE; 879 dip->mixer_class = CMPCI_EQUALIZATION_CLASS; 880 dip->un.v.num_channels = 2; 881 strcpy(dip->un.v.units.name, AudioNbass); 882 return 0; 883 case CMPCI_TREBLE: 884 dip->prev = dip->next = AUDIO_MIXER_LAST; 885 strcpy(dip->label.name, AudioNtreble); 886 dip->type = AUDIO_MIXER_VALUE; 887 dip->mixer_class = CMPCI_EQUALIZATION_CLASS; 888 dip->un.v.num_channels = 2; 889 strcpy(dip->un.v.units.name, AudioNtreble); 890 return 0; 891 case CMPCI_RECORD_CLASS: 892 dip->type = AUDIO_MIXER_CLASS; 893 dip->mixer_class = CMPCI_RECORD_CLASS; 894 dip->next = dip->prev = AUDIO_MIXER_LAST; 895 strcpy(dip->label.name, AudioCrecord); 896 return 0; 897 case CMPCI_INPUT_CLASS: 898 dip->type = AUDIO_MIXER_CLASS; 899 dip->mixer_class = CMPCI_INPUT_CLASS; 900 dip->next = dip->prev = AUDIO_MIXER_LAST; 901 strcpy(dip->label.name, AudioCinputs); 902 return 0; 903 case CMPCI_PCSPEAKER: 904 dip->type = AUDIO_MIXER_VALUE; 905 dip->mixer_class = CMPCI_INPUT_CLASS; 906 dip->prev = dip->next = AUDIO_MIXER_LAST; 907 strcpy(dip->label.name, "pc_speaker"); 908 dip->un.v.num_channels = 1; 909 strcpy(dip->un.v.units.name, AudioNvolume); 910 return 0; 911 case CMPCI_INPUT_GAIN: 912 dip->type = AUDIO_MIXER_VALUE; 913 dip->mixer_class = CMPCI_INPUT_CLASS; 914 dip->prev = dip->next = AUDIO_MIXER_LAST; 915 strcpy(dip->label.name, AudioNinput); 916 dip->un.v.num_channels = 2; 917 strcpy(dip->un.v.units.name, AudioNvolume); 918 return 0; 919 case CMPCI_OUTPUT_GAIN: 920 dip->type = AUDIO_MIXER_VALUE; 921 dip->mixer_class = CMPCI_OUTPUT_CLASS; 922 dip->prev = dip->next = AUDIO_MIXER_LAST; 923 strcpy(dip->label.name, AudioNoutput); 924 dip->un.v.num_channels = 2; 925 strcpy(dip->un.v.units.name, AudioNvolume); 926 return 0; 927 case CMPCI_AGC: 928 dip->type = AUDIO_MIXER_ENUM; 929 dip->mixer_class = CMPCI_INPUT_CLASS; 930 dip->prev = dip->next = AUDIO_MIXER_LAST; 931 strcpy(dip->label.name, "agc"); 932 dip->un.e.num_mem = 2; 933 strcpy(dip->un.e.member[0].label.name, AudioNoff); 934 dip->un.e.member[0].ord = 0; 935 strcpy(dip->un.e.member[1].label.name, AudioNon); 936 dip->un.e.member[1].ord = 1; 937 return 0; 938 case CMPCI_EQUALIZATION_CLASS: 939 dip->type = AUDIO_MIXER_CLASS; 940 dip->mixer_class = CMPCI_EQUALIZATION_CLASS; 941 dip->next = dip->prev = AUDIO_MIXER_LAST; 942 strcpy(dip->label.name, AudioCequalization); 943 return 0; 944 case CMPCI_CD_IN_MUTE: 945 dip->prev = CMPCI_CD_VOL; 946 dip->next = CMPCI_CD_SWAP; 947 dip->mixer_class = CMPCI_INPUT_CLASS; 948 goto mute; 949 case CMPCI_MIC_IN_MUTE: 950 dip->prev = CMPCI_MIC_VOL; 951 dip->next = CMPCI_MIC_SWAP; 952 dip->mixer_class = CMPCI_INPUT_CLASS; 953 goto mute; 954 case CMPCI_LINE_IN_MUTE: 955 dip->prev = CMPCI_LINE_IN_VOL; 956 dip->next = CMPCI_LINE_SWAP; 957 dip->mixer_class = CMPCI_INPUT_CLASS; 958 goto mute; 959 case CMPCI_FM_IN_MUTE: 960 dip->prev = CMPCI_FM_VOL; 961 dip->next = CMPCI_FM_SWAP; 962 dip->mixer_class = CMPCI_INPUT_CLASS; 963 goto mute; 964 case CMPCI_CD_SWAP: 965 dip->prev = CMPCI_CD_IN_MUTE; 966 dip->next = CMPCI_CD_OUT_MUTE; 967 goto swap; 968 case CMPCI_MIC_SWAP: 969 dip->prev = CMPCI_MIC_IN_MUTE; 970 dip->next = CMPCI_MIC_OUT_MUTE; 971 goto swap; 972 case CMPCI_LINE_SWAP: 973 dip->prev = CMPCI_LINE_IN_MUTE; 974 dip->next = CMPCI_LINE_OUT_MUTE; 975 goto swap; 976 case CMPCI_FM_SWAP: 977 dip->prev = CMPCI_FM_IN_MUTE; 978 dip->next = AUDIO_MIXER_LAST; 979 swap: 980 dip->mixer_class = CMPCI_INPUT_CLASS; 981 strcpy(dip->label.name, AudioNswap); 982 goto mute1; 983 case CMPCI_CD_OUT_MUTE: 984 dip->prev = CMPCI_CD_SWAP; 985 dip->next = AUDIO_MIXER_LAST; 986 dip->mixer_class = CMPCI_OUTPUT_CLASS; 987 goto mute; 988 case CMPCI_MIC_OUT_MUTE: 989 dip->prev = CMPCI_MIC_SWAP; 990 dip->next = AUDIO_MIXER_LAST; 991 dip->mixer_class = CMPCI_OUTPUT_CLASS; 992 goto mute; 993 case CMPCI_LINE_OUT_MUTE: 994 dip->prev = CMPCI_LINE_SWAP; 995 dip->next = AUDIO_MIXER_LAST; 996 dip->mixer_class = CMPCI_OUTPUT_CLASS; 997 mute: 998 strcpy(dip->label.name, AudioNmute); 999 mute1: 1000 dip->type = AUDIO_MIXER_ENUM; 1001 dip->un.e.num_mem = 2; 1002 strcpy(dip->un.e.member[0].label.name, AudioNoff); 1003 dip->un.e.member[0].ord = 0; 1004 strcpy(dip->un.e.member[1].label.name, AudioNon); 1005 dip->un.e.member[1].ord = 1; 1006 return 0; 1007 } 1008 1009 return ENXIO; 1010 } 1011 1012 int 1013 cmpci_alloc_dmamem(sc, size, type, flags, r_addr) 1014 struct cmpci_softc *sc; 1015 size_t size; 1016 int type, flags; 1017 caddr_t *r_addr; 1018 { 1019 int ret = 0; 1020 struct cmpci_dmanode *n; 1021 int w; 1022 1023 if ( NULL == (n=malloc(sizeof(struct cmpci_dmanode), type, flags)) ) { 1024 ret = ENOMEM; 1025 goto quit; 1026 } 1027 1028 w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK; 1029 #define CMPCI_DMABUF_ALIGN 0x4 1030 #define CMPCI_DMABUF_BOUNDARY 0x0 1031 n->cd_tag = sc->sc_dmat; 1032 n->cd_size = size; 1033 if ( (ret=bus_dmamem_alloc(n->cd_tag, n->cd_size, 1034 CMPCI_DMABUF_ALIGN, CMPCI_DMABUF_BOUNDARY, 1035 n->cd_segs, 1036 sizeof(n->cd_segs)/sizeof(n->cd_segs[0]), 1037 &n->cd_nsegs, w)) ) 1038 goto mfree; 1039 if ( (ret=bus_dmamem_map(n->cd_tag, n->cd_segs, n->cd_nsegs, n->cd_size, 1040 &n->cd_addr, w | BUS_DMA_COHERENT)) ) 1041 goto dmafree; 1042 if ( (ret=bus_dmamap_create(n->cd_tag, n->cd_size, 1, n->cd_size, 0, 1043 w, &n->cd_map)) ) 1044 goto unmap; 1045 if ( (ret=bus_dmamap_load(n->cd_tag, n->cd_map, n->cd_addr, n->cd_size, 1046 NULL, w)) ) 1047 goto destroy; 1048 1049 n->cd_next = sc->sc_dmap; 1050 sc->sc_dmap = n; 1051 *r_addr = KVADDR(n); 1052 return 0; 1053 1054 destroy: 1055 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1056 unmap: 1057 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1058 dmafree: 1059 bus_dmamem_free(n->cd_tag, 1060 n->cd_segs, sizeof(n->cd_segs)/sizeof(n->cd_segs[0])); 1061 mfree: 1062 free(n, type); 1063 quit: 1064 return ret; 1065 } 1066 1067 int 1068 cmpci_free_dmamem(sc, addr, type) 1069 struct cmpci_softc *sc; 1070 caddr_t addr; 1071 int type; 1072 { 1073 struct cmpci_dmanode **nnp; 1074 1075 for (nnp = &sc->sc_dmap; *nnp; nnp = &(*nnp)->cd_next) { 1076 if ((*nnp)->cd_addr == addr) { 1077 struct cmpci_dmanode *n = *nnp; 1078 1079 bus_dmamap_unload(n->cd_tag, n->cd_map); 1080 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1081 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1082 bus_dmamem_free(n->cd_tag, n->cd_segs, 1083 sizeof(n->cd_segs)/sizeof(n->cd_segs[0])); 1084 free(n, type); 1085 return 0; 1086 } 1087 } 1088 return -1; 1089 } 1090 1091 struct cmpci_dmanode * 1092 cmpci_find_dmamem(sc, addr) 1093 struct cmpci_softc *sc; 1094 caddr_t addr; 1095 { 1096 struct cmpci_dmanode *p; 1097 for (p = sc->sc_dmap; p; p = p->cd_next) { 1098 if (KVADDR(p) == (void *)addr) 1099 break; 1100 } 1101 return p; 1102 } 1103 1104 #if 0 1105 void 1106 cmpci_print_dmamem __P((struct cmpci_dmanode *p)); 1107 void 1108 cmpci_print_dmamem(p) 1109 struct cmpci_dmanode *p; 1110 { 1111 DPRINTF(("DMA at virt:%p, dmaseg:%p, mapseg:%p, size:%p\n", 1112 (void *)p->cd_addr, (void *)p->cd_segs[0].ds_addr, 1113 (void *)DMAADDR(p), (void *)p->cd_size)); 1114 } 1115 #endif /* DEBUG */ 1116 1117 void * 1118 cmpci_malloc(handle, size, type, flags) 1119 void *handle; 1120 u_long size; 1121 int type, flags; 1122 { 1123 struct cmpci_softc *sc = handle; 1124 caddr_t addr; 1125 1126 if ( cmpci_alloc_dmamem(sc, size, type, flags, &addr) ) 1127 return NULL; 1128 return addr; 1129 } 1130 1131 void 1132 cmpci_free(handle, addr, type) 1133 void *handle; 1134 void *addr; 1135 int type; 1136 { 1137 struct cmpci_softc *sc = handle; 1138 1139 cmpci_free_dmamem(sc, addr, type); 1140 } 1141 1142 #define MAXVAL 256 1143 int 1144 cmpci_adjust(val, mask) 1145 int val, mask; 1146 { 1147 val += (MAXVAL - mask) >> 1; 1148 if (val >= MAXVAL) 1149 val = MAXVAL-1; 1150 return val & mask; 1151 } 1152 1153 void 1154 cmpci_set_mixer_gain(sc, port) 1155 struct cmpci_softc *sc; 1156 int port; 1157 { 1158 int src; 1159 1160 switch (port) { 1161 case CMPCI_MIC_VOL: 1162 src = CMPCI_SB16_MIXER_MIC; 1163 break; 1164 case CMPCI_MASTER_VOL: 1165 src = CMPCI_SB16_MIXER_MASTER_L; 1166 break; 1167 case CMPCI_LINE_IN_VOL: 1168 src = CMPCI_SB16_MIXER_LINE_L; 1169 break; 1170 case CMPCI_VOICE_VOL: 1171 src = CMPCI_SB16_MIXER_VOICE_L; 1172 break; 1173 case CMPCI_FM_VOL: 1174 src = CMPCI_SB16_MIXER_FM_L; 1175 break; 1176 case CMPCI_CD_VOL: 1177 src = CMPCI_SB16_MIXER_CDDA_L; 1178 break; 1179 case CMPCI_INPUT_GAIN: 1180 src = CMPCI_SB16_MIXER_INGAIN_L; 1181 break; 1182 case CMPCI_OUTPUT_GAIN: 1183 src = CMPCI_SB16_MIXER_OUTGAIN_L; 1184 break; 1185 case CMPCI_TREBLE: 1186 src = CMPCI_SB16_MIXER_TREBLE_L; 1187 break; 1188 case CMPCI_BASS: 1189 src = CMPCI_SB16_MIXER_BASS_L; 1190 break; 1191 case CMPCI_PCSPEAKER: 1192 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_SPEAKER, 1193 sc->gain[port][CMPCI_LEFT]); 1194 return; 1195 default: 1196 return; 1197 } 1198 cmpci_mixerreg_write(sc, src, sc->gain[port][CMPCI_LEFT]); 1199 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_L_TO_R(src), 1200 sc->gain[port][CMPCI_RIGHT]); 1201 } 1202 1203 int 1204 cmpci_set_in_ports(sc, mask) 1205 struct cmpci_softc *sc; 1206 int mask; 1207 { 1208 int bitsl, bitsr; 1209 1210 if (mask & ~((1<<CMPCI_FM_VOL) | (1<<CMPCI_LINE_IN_VOL) | 1211 (1<<CMPCI_CD_VOL) | (1<<CMPCI_MIC_VOL) 1212 #ifdef CMPCI_SPDIF_SUPPORT 1213 | (1<<CMPCI_SPDIF_IN) 1214 #endif 1215 )) 1216 return EINVAL; 1217 bitsr = 0; 1218 if (mask & (1<<CMPCI_FM_VOL)) 1219 bitsr |= CMPCI_SB16_MIXER_FM_SRC_R; 1220 if (mask & (1<<CMPCI_LINE_IN_VOL)) 1221 bitsr |= CMPCI_SB16_MIXER_LINE_SRC_R; 1222 if (mask & (1<<CMPCI_CD_VOL)) 1223 bitsr |= CMPCI_SB16_MIXER_CD_SRC_R; 1224 bitsl = CMPCI_SB16_MIXER_SRC_R_TO_L(bitsr); 1225 if (mask & (1<<CMPCI_MIC_VOL)) { 1226 bitsl |= CMPCI_SB16_MIXER_MIC_SRC; 1227 bitsr |= CMPCI_SB16_MIXER_MIC_SRC; 1228 } 1229 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, bitsl); 1230 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, bitsr); 1231 1232 sc->in_mask = mask; 1233 1234 return 0; 1235 } 1236 1237 int 1238 cmpci_set_port(handle, cp) 1239 void *handle; 1240 mixer_ctrl_t *cp; 1241 { 1242 struct cmpci_softc *sc = handle; 1243 int lgain, rgain; 1244 int mask, bits; 1245 int lmask, rmask, lbits, rbits; 1246 int mute, swap; 1247 1248 switch (cp->dev) { 1249 case CMPCI_TREBLE: 1250 case CMPCI_BASS: 1251 case CMPCI_PCSPEAKER: 1252 case CMPCI_INPUT_GAIN: 1253 case CMPCI_OUTPUT_GAIN: 1254 case CMPCI_MIC_VOL: 1255 case CMPCI_LINE_IN_VOL: 1256 case CMPCI_VOICE_VOL: 1257 case CMPCI_FM_VOL: 1258 case CMPCI_CD_VOL: 1259 case CMPCI_MASTER_VOL: 1260 if (cp->type != AUDIO_MIXER_VALUE) 1261 return EINVAL; 1262 switch (cp->dev) { 1263 case CMPCI_MIC_VOL: 1264 if (cp->un.value.num_channels != 1) 1265 return EINVAL; 1266 1267 lgain = rgain = CMPCI_ADJUST_MIC_GAIN(sc, 1268 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1269 break; 1270 case CMPCI_PCSPEAKER: 1271 if (cp->un.value.num_channels != 1) 1272 return EINVAL; 1273 /* FALLTHROUGH */ 1274 case CMPCI_INPUT_GAIN: 1275 case CMPCI_OUTPUT_GAIN: 1276 lgain = rgain = CMPCI_ADJUST_2_GAIN(sc, 1277 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1278 break; 1279 default: 1280 switch (cp->un.value.num_channels) { 1281 case 1: 1282 lgain = rgain = CMPCI_ADJUST_GAIN(sc, 1283 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1284 break; 1285 case 2: 1286 lgain = CMPCI_ADJUST_GAIN(sc, 1287 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]); 1288 rgain = CMPCI_ADJUST_GAIN(sc, 1289 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); 1290 break; 1291 default: 1292 return EINVAL; 1293 } 1294 break; 1295 } 1296 sc->gain[cp->dev][CMPCI_LEFT] = lgain; 1297 sc->gain[cp->dev][CMPCI_RIGHT] = rgain; 1298 1299 cmpci_set_mixer_gain(sc, cp->dev); 1300 break; 1301 1302 case CMPCI_RECORD_SOURCE: 1303 if (cp->type != AUDIO_MIXER_SET) 1304 return EINVAL; 1305 #ifdef CMPCI_SPDIF_SUPPORT 1306 if ( cp->un.mask&(1<<CMPCI_SPDIF_IN) ) 1307 cp->un.mask = 1<<CMPCI_SPDIF_IN; 1308 #endif 1309 return cmpci_set_in_ports(sc, cp->un.mask); 1310 1311 case CMPCI_AGC: 1312 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_AGC, cp->un.ord & 1); 1313 break; 1314 case CMPCI_CD_OUT_MUTE: 1315 mask = CMPCI_SB16_SW_CD; 1316 goto omute; 1317 case CMPCI_MIC_OUT_MUTE: 1318 mask = CMPCI_SB16_SW_MIC; 1319 goto omute; 1320 case CMPCI_LINE_OUT_MUTE: 1321 mask = CMPCI_SB16_SW_LINE; 1322 omute: 1323 if (cp->type != AUDIO_MIXER_ENUM) 1324 return EINVAL; 1325 bits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_OUTMIX); 1326 sc->gain[cp->dev][CMPCI_LR] = cp->un.ord != 0; 1327 if (cp->un.ord) 1328 bits = bits & ~mask; 1329 else 1330 bits = bits | mask; 1331 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, bits); 1332 break; 1333 1334 case CMPCI_MIC_IN_MUTE: 1335 case CMPCI_MIC_SWAP: 1336 lmask = rmask = CMPCI_SB16_SW_MIC; 1337 goto imute; 1338 case CMPCI_CD_IN_MUTE: 1339 case CMPCI_CD_SWAP: 1340 lmask = CMPCI_SB16_SW_CD_L; 1341 rmask = CMPCI_SB16_SW_CD_R; 1342 goto imute; 1343 case CMPCI_LINE_IN_MUTE: 1344 case CMPCI_LINE_SWAP: 1345 lmask = CMPCI_SB16_SW_LINE_L; 1346 rmask = CMPCI_SB16_SW_LINE_R; 1347 goto imute; 1348 case CMPCI_FM_IN_MUTE: 1349 case CMPCI_FM_SWAP: 1350 lmask = CMPCI_SB16_SW_FM_L; 1351 rmask = CMPCI_SB16_SW_FM_R; 1352 imute: 1353 if (cp->type != AUDIO_MIXER_ENUM) 1354 return EINVAL; 1355 mask = lmask | rmask; 1356 lbits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_ADCMIX_L) 1357 & ~mask; 1358 rbits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_ADCMIX_R) 1359 & ~mask; 1360 sc->gain[cp->dev][CMPCI_LR] = cp->un.ord != 0; 1361 if (CMPCI_IS_IN_MUTE(cp->dev)) { 1362 mute = cp->dev; 1363 swap = mute - CMPCI_CD_IN_MUTE + CMPCI_CD_SWAP; 1364 } else { 1365 swap = cp->dev; 1366 mute = swap + CMPCI_CD_IN_MUTE - CMPCI_CD_SWAP; 1367 } 1368 if (sc->gain[swap][CMPCI_LR]) { 1369 mask = lmask; 1370 lmask = rmask; 1371 rmask = mask; 1372 } 1373 if (!sc->gain[mute][CMPCI_LR]) { 1374 lbits = lbits | lmask; 1375 rbits = rbits | rmask; 1376 } 1377 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, lbits); 1378 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, rbits); 1379 break; 1380 1381 default: 1382 return EINVAL; 1383 } 1384 1385 return 0; 1386 } 1387 1388 int 1389 cmpci_get_port(handle, cp) 1390 void *handle; 1391 mixer_ctrl_t *cp; 1392 { 1393 struct cmpci_softc *sc = handle; 1394 1395 switch (cp->dev) { 1396 case CMPCI_MIC_VOL: 1397 case CMPCI_LINE_IN_VOL: 1398 if (cp->un.value.num_channels != 1) 1399 return EINVAL; 1400 /* FALLTHROUGH */ 1401 case CMPCI_TREBLE: 1402 case CMPCI_BASS: 1403 case CMPCI_PCSPEAKER: 1404 case CMPCI_INPUT_GAIN: 1405 case CMPCI_OUTPUT_GAIN: 1406 case CMPCI_VOICE_VOL: 1407 case CMPCI_FM_VOL: 1408 case CMPCI_CD_VOL: 1409 case CMPCI_MASTER_VOL: 1410 switch (cp->un.value.num_channels) { 1411 case 1: 1412 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1413 sc->gain[cp->dev][CMPCI_LEFT]; 1414 break; 1415 case 2: 1416 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1417 sc->gain[cp->dev][CMPCI_LEFT]; 1418 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1419 sc->gain[cp->dev][CMPCI_RIGHT]; 1420 break; 1421 default: 1422 return EINVAL; 1423 } 1424 break; 1425 1426 case CMPCI_RECORD_SOURCE: 1427 cp->un.mask = sc->in_mask; 1428 break; 1429 1430 case CMPCI_AGC: 1431 cp->un.ord = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_AGC); 1432 break; 1433 1434 case CMPCI_CD_IN_MUTE: 1435 case CMPCI_MIC_IN_MUTE: 1436 case CMPCI_LINE_IN_MUTE: 1437 case CMPCI_FM_IN_MUTE: 1438 case CMPCI_CD_SWAP: 1439 case CMPCI_MIC_SWAP: 1440 case CMPCI_LINE_SWAP: 1441 case CMPCI_FM_SWAP: 1442 case CMPCI_CD_OUT_MUTE: 1443 case CMPCI_MIC_OUT_MUTE: 1444 case CMPCI_LINE_OUT_MUTE: 1445 cp->un.ord = sc->gain[cp->dev][CMPCI_LR]; 1446 break; 1447 1448 default: 1449 return EINVAL; 1450 } 1451 1452 return 0; 1453 } 1454 1455 /* ARGSUSED */ 1456 u_long 1457 cmpci_round_buffersize(handle, bufsize) 1458 void *handle; 1459 u_long bufsize; 1460 { 1461 if (bufsize > 0x10000) 1462 bufsize = 0x10000; 1463 1464 return bufsize; 1465 } 1466 1467 paddr_t 1468 cmpci_mappage(handle, addr, offset, prot) 1469 void *handle; 1470 void *addr; 1471 off_t offset; 1472 int prot; 1473 { 1474 struct cmpci_softc *sc = handle; 1475 struct cmpci_dmanode *p; 1476 1477 if ( offset < 0 || (p = cmpci_find_dmamem(sc, addr)) == NULL) 1478 return -1; 1479 1480 return bus_dmamem_mmap(p->cd_tag, p->cd_segs, 1481 sizeof(p->cd_segs)/sizeof(p->cd_segs[0]), 1482 offset, prot, BUS_DMA_WAITOK); 1483 } 1484 1485 /* ARGSUSED */ 1486 int 1487 cmpci_get_props(handle) 1488 void *handle; 1489 { 1490 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1491 } 1492 1493 1494 int 1495 cmpci_trigger_output(handle, start, end, blksize, intr, arg, param) 1496 void *handle; 1497 void *start, *end; 1498 int blksize; 1499 void (*intr) __P((void *)); 1500 void *arg; 1501 struct audio_params *param; 1502 { 1503 struct cmpci_softc *sc = handle; 1504 struct cmpci_dmanode *p; 1505 int bps; 1506 1507 sc->sc_play.intr = intr; 1508 sc->sc_play.intr_arg = arg; 1509 bps = param->channels * param->precision * param->factor / 8; 1510 if (!bps) 1511 return EINVAL; 1512 1513 /* set DMA frame */ 1514 if (!(p = cmpci_find_dmamem(sc, start))) 1515 return EINVAL; 1516 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA0_BASE, 1517 DMAADDR(p)); 1518 delay(10); 1519 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA0_BYTES, 1520 ((caddr_t)end-(caddr_t)start+1)/bps-1); 1521 delay(10); 1522 1523 /* set interrupt count */ 1524 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA0_SAMPLES, 1525 (blksize+bps-1)/bps-1); 1526 delay(10); 1527 1528 /* start DMA */ 1529 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_DIR); /* PLAY */ 1530 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE); 1531 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE); 1532 1533 return 0; 1534 } 1535 1536 int 1537 cmpci_trigger_input(handle, start, end, blksize, intr, arg, param) 1538 void *handle; 1539 void *start, *end; 1540 int blksize; 1541 void (*intr) __P((void *)); 1542 void *arg; 1543 struct audio_params *param; 1544 { 1545 struct cmpci_softc *sc = handle; 1546 struct cmpci_dmanode *p; 1547 int bps; 1548 1549 sc->sc_rec.intr = intr; 1550 sc->sc_rec.intr_arg = arg; 1551 bps = param->channels*param->precision*param->factor/8; 1552 if (!bps) 1553 return EINVAL; 1554 1555 /* set DMA frame */ 1556 if (!(p = cmpci_find_dmamem(sc, start))) 1557 return EINVAL; 1558 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BASE, 1559 DMAADDR(p)); 1560 delay(10); 1561 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BYTES, 1562 ((caddr_t)end-(caddr_t)start+1)/bps-1); 1563 delay(10); 1564 1565 /* set interrupt count */ 1566 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_SAMPLES, 1567 (blksize+bps-1)/bps-1); 1568 delay(10); 1569 1570 /* start DMA */ 1571 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR); /* REC */ 1572 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 1573 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 1574 1575 return 0; 1576 } 1577