1 /* $OpenBSD: cmpci.c,v 1.11 2003/06/05 23:53:54 fgsch 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(struct cmpci_softc *, 72 uint8_t); 73 static __inline void cmpci_mixerreg_write(struct cmpci_softc *, 74 uint8_t, uint8_t); 75 static __inline void cmpci_reg_partial_write_4(struct cmpci_softc *, 76 int, int, 77 uint32_t, uint32_t); 78 static __inline void cmpci_reg_set_4(struct cmpci_softc *, 79 int, uint32_t); 80 static __inline void cmpci_reg_clear_4(struct cmpci_softc *, 81 int, uint32_t); 82 static int cmpci_rate_to_index(int); 83 static __inline int cmpci_index_to_rate(int); 84 static __inline int cmpci_index_to_divider(int); 85 86 static int cmpci_adjust(int, int); 87 static void cmpci_set_mixer_gain(struct cmpci_softc *, int); 88 static int cmpci_set_in_ports(struct cmpci_softc *, int); 89 90 91 /* 92 * autoconf interface 93 */ 94 int cmpci_match(struct device *, void *, void *); 95 void cmpci_attach(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(void *); 113 114 115 /* 116 * DMA stuff 117 */ 118 int cmpci_alloc_dmamem(struct cmpci_softc *, 119 size_t, int, int, caddr_t *); 120 int cmpci_free_dmamem(struct cmpci_softc *, caddr_t, int); 121 struct cmpci_dmanode * cmpci_find_dmamem(struct cmpci_softc *, 122 caddr_t); 123 124 /* 125 * Interface to machine independent layer 126 */ 127 int cmpci_open(void *, int); 128 void cmpci_close(void *); 129 int cmpci_query_encoding(void *, struct audio_encoding *); 130 int cmpci_set_params(void *, int, int, 131 struct audio_params *, 132 struct audio_params *); 133 int cmpci_round_blocksize(void *, int); 134 int cmpci_halt_output(void *); 135 int cmpci_halt_input(void *); 136 int cmpci_getdev(void *, struct audio_device *); 137 int cmpci_set_port(void *, mixer_ctrl_t *); 138 int cmpci_get_port(void *, mixer_ctrl_t *); 139 int cmpci_query_devinfo(void *, mixer_devinfo_t *); 140 void *cmpci_malloc(void *, int, size_t, int, int); 141 void cmpci_free(void *, void *, int); 142 size_t cmpci_round_buffersize(void *, int, size_t); 143 paddr_t cmpci_mappage(void *, void *, off_t, int); 144 int cmpci_get_props(void *); 145 int cmpci_trigger_output(void *, void *, void *, int, 146 void (*)(void *), void *, 147 struct audio_params *); 148 int cmpci_trigger_input(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 const struct pci_matchid cmpci_devices[] = { 293 { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8338A }, 294 { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8338B }, 295 { PCI_VENDOR_CMI, PCI_PRODUCT_CMI_CMI8738 }, 296 }; 297 298 /* 299 * interface to configure the device. 300 */ 301 int 302 cmpci_match(parent, match, aux) 303 struct device *parent; 304 void *match; 305 void *aux; 306 { 307 return (pci_matchbyid((struct pci_attach_args *)aux, cmpci_devices, 308 sizeof(cmpci_devices)/sizeof(cmpci_devices[0]))); 309 } 310 311 void 312 cmpci_attach(parent, self, aux) 313 struct device *parent, *self; 314 void *aux; 315 { 316 struct cmpci_softc *sc = (struct cmpci_softc *)self; 317 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 318 pci_intr_handle_t ih; 319 char const *intrstr; 320 int i, v; 321 322 /* map I/O space */ 323 if (pci_mapreg_map(pa, CMPCI_PCI_IOBASEREG, PCI_MAPREG_TYPE_IO, 0, 324 &sc->sc_iot, &sc->sc_ioh, NULL, NULL, 0)) { 325 printf("\n%s: failed to map I/O space\n", sc->sc_dev.dv_xname); 326 return; 327 } 328 329 /* interrupt */ 330 if (pci_intr_map(pa, &ih)) { 331 printf("\n%s: failed to map interrupt\n", sc->sc_dev.dv_xname); 332 return; 333 } 334 intrstr = pci_intr_string(pa->pa_pc, ih); 335 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, cmpci_intr, 336 sc, sc->sc_dev.dv_xname); 337 338 if (sc->sc_ih == NULL) { 339 printf("\n%s: couldn't establish interrupt", 340 sc->sc_dev.dv_xname); 341 if (intrstr) 342 printf(" at %s", intrstr); 343 printf("\n"); 344 return; 345 } 346 printf(": %s\n", intrstr); 347 348 sc->sc_dmat = pa->pa_dmat; 349 350 audio_attach_mi(&cmpci_hw_if, sc, &sc->sc_dev); 351 352 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_RESET, 0); 353 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, 0); 354 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, 0); 355 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, 356 CMPCI_SB16_SW_CD|CMPCI_SB16_SW_MIC| 357 CMPCI_SB16_SW_LINE); 358 for (i = 0; i < CMPCI_NDEVS; i++) { 359 switch(i) { 360 case CMPCI_MIC_VOL: 361 case CMPCI_LINE_IN_VOL: 362 v = 0; 363 break; 364 case CMPCI_BASS: 365 case CMPCI_TREBLE: 366 v = CMPCI_ADJUST_GAIN(sc, AUDIO_MAX_GAIN / 2); 367 break; 368 case CMPCI_CD_IN_MUTE: 369 case CMPCI_MIC_IN_MUTE: 370 case CMPCI_LINE_IN_MUTE: 371 case CMPCI_FM_IN_MUTE: 372 case CMPCI_CD_SWAP: 373 case CMPCI_MIC_SWAP: 374 case CMPCI_LINE_SWAP: 375 case CMPCI_FM_SWAP: 376 v = 0; 377 break; 378 case CMPCI_CD_OUT_MUTE: 379 case CMPCI_MIC_OUT_MUTE: 380 case CMPCI_LINE_OUT_MUTE: 381 v = 1; 382 break; 383 default: 384 v = CMPCI_ADJUST_GAIN(sc, AUDIO_MAX_GAIN / 2); 385 } 386 sc->gain[i][CMPCI_LEFT] = sc->gain[i][CMPCI_RIGHT] = v; 387 cmpci_set_mixer_gain(sc, i); 388 } 389 } 390 391 int 392 cmpci_intr(handle) 393 void *handle; 394 { 395 struct cmpci_softc *sc = handle; 396 uint32_t intrstat; 397 int s; 398 399 intrstat = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 400 CMPCI_REG_INTR_STATUS); 401 delay(10); 402 403 if (!(intrstat & CMPCI_REG_ANY_INTR)) 404 return 0; 405 406 /* disable and reset intr */ 407 s = splaudio(); 408 if (intrstat & CMPCI_REG_CH0_INTR) 409 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 410 CMPCI_REG_CH0_INTR_ENABLE); 411 if (intrstat&CMPCI_REG_CH1_INTR) 412 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, 413 CMPCI_REG_CH1_INTR_ENABLE); 414 splx(s); 415 416 if (intrstat & CMPCI_REG_CH0_INTR) { 417 if (sc->sc_play.intr) 418 (*sc->sc_play.intr)(sc->sc_play.intr_arg); 419 } 420 if (intrstat & CMPCI_REG_CH1_INTR) { 421 if (sc->sc_rec.intr) 422 (*sc->sc_rec.intr)(sc->sc_rec.intr_arg); 423 } 424 425 /* enable intr */ 426 s = splaudio(); 427 if ( intrstat & CMPCI_REG_CH0_INTR ) 428 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 429 CMPCI_REG_CH0_INTR_ENABLE); 430 if (intrstat & CMPCI_REG_CH1_INTR) 431 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, 432 CMPCI_REG_CH1_INTR_ENABLE); 433 splx(s); 434 435 return 1; 436 } 437 438 /* open/close */ 439 int 440 cmpci_open(handle, flags) 441 void *handle; 442 int flags; 443 { 444 struct cmpci_softc *sc = handle; 445 (void)sc; 446 (void)flags; 447 448 return 0; 449 } 450 451 void 452 cmpci_close(handle) 453 void *handle; 454 { 455 (void)handle; 456 } 457 458 int 459 cmpci_query_encoding(handle, fp) 460 void *handle; 461 struct audio_encoding *fp; 462 { 463 struct cmpci_softc *sc = handle; 464 (void)sc; 465 466 switch (fp->index) { 467 case 0: 468 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 469 fp->encoding = AUDIO_ENCODING_ULINEAR; 470 fp->precision = 8; 471 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 472 break; 473 case 1: 474 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 475 fp->encoding = AUDIO_ENCODING_ULAW; 476 fp->precision = 8; 477 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 478 break; 479 case 2: 480 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 481 fp->encoding = AUDIO_ENCODING_ALAW; 482 fp->precision = 8; 483 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 484 break; 485 case 3: 486 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 487 fp->encoding = AUDIO_ENCODING_SLINEAR; 488 fp->precision = 8; 489 fp->flags = 0; 490 break; 491 case 4: 492 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 493 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 494 fp->precision = 16; 495 fp->flags = 0; 496 break; 497 case 5: 498 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 499 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 500 fp->precision = 16; 501 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 502 break; 503 case 6: 504 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 505 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 506 fp->precision = 16; 507 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 508 break; 509 case 7: 510 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 511 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 512 fp->precision = 16; 513 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 514 break; 515 default: 516 return EINVAL; 517 } 518 return 0; 519 } 520 521 522 int 523 cmpci_set_params(handle, setmode, usemode, play, rec) 524 void *handle; 525 int setmode, usemode; 526 struct audio_params *play, *rec; 527 { 528 int i; 529 struct cmpci_softc *sc = handle; 530 531 for (i=0; i<2; i++) { 532 int md_format; 533 int md_divide; 534 int md_index; 535 int mode; 536 struct audio_params *p; 537 538 switch (i) { 539 case 0: 540 mode = AUMODE_PLAY; 541 p = play; 542 break; 543 case 1: 544 mode = AUMODE_RECORD; 545 p = rec; 546 break; 547 } 548 549 if (!(setmode & mode)) 550 continue; 551 552 /* format */ 553 p->sw_code = NULL; 554 switch (p->channels) { 555 case 1: 556 md_format = CMPCI_REG_FORMAT_MONO; 557 break; 558 case 2: 559 md_format = CMPCI_REG_FORMAT_STEREO; 560 break; 561 default: 562 return (EINVAL); 563 } 564 switch (p->encoding) { 565 case AUDIO_ENCODING_ULAW: 566 if (p->precision != 8) 567 return (EINVAL); 568 if (mode & AUMODE_PLAY) { 569 p->factor = 2; 570 p->sw_code = mulaw_to_slinear16; 571 md_format |= CMPCI_REG_FORMAT_16BIT; 572 } else 573 p->sw_code = ulinear8_to_mulaw; 574 md_format |= CMPCI_REG_FORMAT_8BIT; 575 break; 576 case AUDIO_ENCODING_ALAW: 577 if (p->precision != 8) 578 return (EINVAL); 579 if (mode & AUMODE_PLAY) { 580 p->factor = 2; 581 p->sw_code = alaw_to_slinear16; 582 md_format |= CMPCI_REG_FORMAT_16BIT; 583 } else 584 p->sw_code = ulinear8_to_alaw; 585 md_format |= CMPCI_REG_FORMAT_8BIT; 586 break; 587 case AUDIO_ENCODING_SLINEAR_LE: 588 switch (p->precision) { 589 case 8: 590 p->sw_code = change_sign8; 591 md_format |= CMPCI_REG_FORMAT_8BIT; 592 break; 593 case 16: 594 md_format |= CMPCI_REG_FORMAT_16BIT; 595 break; 596 default: 597 return (EINVAL); 598 } 599 break; 600 case AUDIO_ENCODING_SLINEAR_BE: 601 switch (p->precision) { 602 case 8: 603 md_format |= CMPCI_REG_FORMAT_8BIT; 604 p->sw_code = change_sign8; 605 break; 606 case 16: 607 md_format |= CMPCI_REG_FORMAT_16BIT; 608 p->sw_code = swap_bytes; 609 break; 610 default: 611 return (EINVAL); 612 } 613 break; 614 case AUDIO_ENCODING_ULINEAR_LE: 615 switch ( p->precision ) { 616 case 8: 617 md_format |= CMPCI_REG_FORMAT_8BIT; 618 break; 619 case 16: 620 md_format |= CMPCI_REG_FORMAT_16BIT; 621 p->sw_code = change_sign16; 622 break; 623 default: 624 return (EINVAL); 625 } 626 break; 627 case AUDIO_ENCODING_ULINEAR_BE: 628 switch (p->precision) { 629 case 8: 630 md_format |= CMPCI_REG_FORMAT_8BIT; 631 break; 632 case 16: 633 md_format |= CMPCI_REG_FORMAT_16BIT; 634 if ( mode&AUMODE_PLAY ) 635 p->sw_code = swap_bytes_change_sign16; 636 else 637 p->sw_code = change_sign16_swap_bytes; 638 break; 639 default: 640 return (EINVAL); 641 } 642 break; 643 default: 644 return (EINVAL); 645 } 646 if (mode & AUMODE_PLAY) 647 cmpci_reg_partial_write_4(sc, 648 CMPCI_REG_CHANNEL_FORMAT, 649 CMPCI_REG_CH0_FORMAT_SHIFT, 650 CMPCI_REG_CH0_FORMAT_MASK, 651 md_format); 652 else 653 cmpci_reg_partial_write_4(sc, 654 CMPCI_REG_CHANNEL_FORMAT, 655 CMPCI_REG_CH1_FORMAT_SHIFT, 656 CMPCI_REG_CH1_FORMAT_MASK, 657 md_format); 658 /* sample rate */ 659 md_index = cmpci_rate_to_index(p->sample_rate); 660 md_divide = cmpci_index_to_divider(md_index); 661 p->sample_rate = cmpci_index_to_rate(md_index); 662 #if 0 663 DPRINTF(("%s: sample:%d, divider=%d\n", 664 sc->sc_dev.dv_xname, (int)p->sample_rate, md_divide)); 665 #endif 666 if (mode & AUMODE_PLAY) { 667 cmpci_reg_partial_write_4(sc, 668 CMPCI_REG_FUNC_1, 669 CMPCI_REG_DAC_FS_SHIFT, 670 CMPCI_REG_DAC_FS_MASK, 671 md_divide); 672 #ifdef CMPCI_SPDIF_SUPPORT 673 switch (md_divide) { 674 case CMPCI_REG_RATE_44100: 675 cmpci_reg_clear_4(sc, CMPCI_REG_MISC, 676 CMPCI_REG_SPDIF_48K); 677 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 678 CMPCI_REG_SPDIF_LOOP); 679 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 680 CMPCI_REG_SPDIF0_ENABLE); 681 break; 682 case CMPCI_REG_RATE_48000: 683 cmpci_reg_set_4(sc, CMPCI_REG_MISC, 684 CMPCI_REG_SPDIF_48K); 685 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 686 CMPCI_REG_SPDIF_LOOP); 687 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 688 CMPCI_REG_SPDIF0_ENABLE); 689 break; 690 default: 691 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 692 CMPCI_REG_SPDIF0_ENABLE); 693 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 694 CMPCI_REG_SPDIF_LOOP); 695 } 696 #endif 697 } else { 698 cmpci_reg_partial_write_4(sc, 699 CMPCI_REG_FUNC_1, 700 CMPCI_REG_ADC_FS_SHIFT, 701 CMPCI_REG_ADC_FS_MASK, 702 md_divide); 703 #ifdef CMPCI_SPDIF_SUPPORT 704 if ( sc->in_mask&CMPCI_SPDIF_IN) { 705 switch (md_divide) { 706 case CMPCI_REG_RATE_44100: 707 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_1, 708 CMPCI_REG_SPDIF1_ENABLE); 709 break; 710 default: 711 return EINVAL; 712 } 713 } else 714 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_1, 715 CMPCI_REG_SPDIF1_ENABLE); 716 #endif 717 } 718 } 719 return 0; 720 } 721 722 /* ARGSUSED */ 723 int 724 cmpci_round_blocksize(handle, block) 725 void *handle; 726 int block; 727 { 728 return (block & -4); 729 } 730 731 int 732 cmpci_halt_output(handle) 733 void *handle; 734 { 735 struct cmpci_softc *sc = handle; 736 int s; 737 738 s = splaudio(); 739 sc->sc_play.intr = NULL; 740 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE); 741 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE); 742 /* wait for reset DMA */ 743 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET); 744 delay(10); 745 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_RESET); 746 splx(s); 747 748 return 0; 749 } 750 751 int 752 cmpci_halt_input(handle) 753 void *handle; 754 { 755 struct cmpci_softc *sc = handle; 756 int s; 757 758 s = splaudio(); 759 sc->sc_rec.intr = NULL; 760 cmpci_reg_clear_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 761 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 762 /* wait for reset DMA */ 763 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 764 delay(10); 765 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_RESET); 766 splx(s); 767 768 return 0; 769 } 770 771 int 772 cmpci_getdev(handle, retp) 773 void *handle; 774 struct audio_device *retp; 775 { 776 *retp = cmpci_device; 777 return 0; 778 } 779 780 781 /* mixer device information */ 782 int 783 cmpci_query_devinfo(handle, dip) 784 void *handle; 785 mixer_devinfo_t *dip; 786 { 787 struct cmpci_softc *sc = handle; 788 (void)sc; 789 790 switch (dip->index) { 791 case CMPCI_MASTER_VOL: 792 dip->type = AUDIO_MIXER_VALUE; 793 dip->mixer_class = CMPCI_OUTPUT_CLASS; 794 dip->prev = dip->next = AUDIO_MIXER_LAST; 795 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 796 dip->un.v.num_channels = 2; 797 strlcpy(dip->un.v.units.name, AudioNvolume, 798 sizeof dip->un.v.units.name); 799 return 0; 800 case CMPCI_FM_VOL: 801 dip->type = AUDIO_MIXER_VALUE; 802 dip->mixer_class = CMPCI_INPUT_CLASS; 803 dip->prev = AUDIO_MIXER_LAST; 804 dip->next = CMPCI_FM_IN_MUTE; 805 strlcpy(dip->label.name, AudioNfmsynth, 806 sizeof dip->label.name); 807 dip->un.v.num_channels = 2; 808 strlcpy(dip->un.v.units.name, AudioNvolume, 809 sizeof dip->un.v.units.name); 810 return 0; 811 case CMPCI_CD_VOL: 812 dip->type = AUDIO_MIXER_VALUE; 813 dip->mixer_class = CMPCI_INPUT_CLASS; 814 dip->prev = AUDIO_MIXER_LAST; 815 dip->next = CMPCI_CD_IN_MUTE; 816 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 817 dip->un.v.num_channels = 2; 818 strlcpy(dip->un.v.units.name, AudioNvolume, 819 sizeof dip->un.v.units.name); 820 return 0; 821 case CMPCI_VOICE_VOL: 822 dip->type = AUDIO_MIXER_VALUE; 823 dip->mixer_class = CMPCI_OUTPUT_CLASS; 824 dip->prev = AUDIO_MIXER_LAST; 825 dip->next = AUDIO_MIXER_LAST; 826 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 827 dip->un.v.num_channels = 2; 828 strlcpy(dip->un.v.units.name, AudioNvolume, 829 sizeof dip->un.v.units.name); 830 return 0; 831 case CMPCI_OUTPUT_CLASS: 832 dip->type = AUDIO_MIXER_CLASS; 833 dip->mixer_class = CMPCI_OUTPUT_CLASS; 834 dip->next = dip->prev = AUDIO_MIXER_LAST; 835 strlcpy(dip->label.name, AudioCoutputs, 836 sizeof dip->label.name); 837 return 0; 838 case CMPCI_MIC_VOL: 839 dip->type = AUDIO_MIXER_VALUE; 840 dip->mixer_class = CMPCI_INPUT_CLASS; 841 dip->prev = AUDIO_MIXER_LAST; 842 dip->next = CMPCI_MIC_IN_MUTE; 843 strlcpy(dip->label.name, AudioNmicrophone, 844 sizeof dip->label.name); 845 dip->un.v.num_channels = 1; 846 strlcpy(dip->un.v.units.name, AudioNvolume, 847 sizeof dip->un.v.units.name); 848 return 0; 849 case CMPCI_LINE_IN_VOL: 850 dip->type = AUDIO_MIXER_VALUE; 851 dip->mixer_class = CMPCI_INPUT_CLASS; 852 dip->prev = AUDIO_MIXER_LAST; 853 dip->next = CMPCI_LINE_IN_MUTE; 854 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 855 dip->un.v.num_channels = 2; 856 strlcpy(dip->un.v.units.name, AudioNvolume, 857 sizeof dip->un.v.units.name); 858 return 0; 859 case CMPCI_RECORD_SOURCE: 860 dip->mixer_class = CMPCI_RECORD_CLASS; 861 dip->prev = dip->next = AUDIO_MIXER_LAST; 862 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 863 dip->type = AUDIO_MIXER_SET; 864 #ifdef CMPCI_SPDIF_SUPPORT 865 dip->un.s.num_mem = 5; 866 #else 867 dip->un.s.num_mem = 4; 868 #endif 869 strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone, 870 sizeof dip->un.s.member[0].label.name); 871 dip->un.s.member[0].mask = 1 << CMPCI_MIC_VOL; 872 strlcpy(dip->un.s.member[1].label.name, AudioNcd, 873 sizeof dip->un.s.member[1].label.name); 874 dip->un.s.member[1].mask = 1 << CMPCI_CD_VOL; 875 strlcpy(dip->un.s.member[2].label.name, AudioNline, 876 sizeof dip->un.s.member[2].label.name); 877 dip->un.s.member[2].mask = 1 << CMPCI_LINE_IN_VOL; 878 strlcpy(dip->un.s.member[3].label.name, AudioNfmsynth, 879 sizeof dip->un.s.member[3].label.name); 880 dip->un.s.member[3].mask = 1 << CMPCI_FM_VOL; 881 #ifdef CMPCI_SPDIF_SUPPORT 882 strlcpy(dip->un.s.member[4].label.name, CmpciNspdif, 883 sizeof dip->un.s.member[4].label.name); 884 dip->un.s.member[4].mask = 1 << CMPCI_SPDIF_IN; 885 #endif 886 return 0; 887 case CMPCI_BASS: 888 dip->prev = dip->next = AUDIO_MIXER_LAST; 889 strlcpy(dip->label.name, AudioNbass, sizeof dip->label.name); 890 dip->type = AUDIO_MIXER_VALUE; 891 dip->mixer_class = CMPCI_EQUALIZATION_CLASS; 892 dip->un.v.num_channels = 2; 893 strlcpy(dip->un.v.units.name, AudioNbass, 894 sizeof dip->un.v.units.name); 895 return 0; 896 case CMPCI_TREBLE: 897 dip->prev = dip->next = AUDIO_MIXER_LAST; 898 strlcpy(dip->label.name, AudioNtreble, sizeof dip->label.name); 899 dip->type = AUDIO_MIXER_VALUE; 900 dip->mixer_class = CMPCI_EQUALIZATION_CLASS; 901 dip->un.v.num_channels = 2; 902 strlcpy(dip->un.v.units.name, AudioNtreble, 903 sizeof dip->un.v.units.name); 904 return 0; 905 case CMPCI_RECORD_CLASS: 906 dip->type = AUDIO_MIXER_CLASS; 907 dip->mixer_class = CMPCI_RECORD_CLASS; 908 dip->next = dip->prev = AUDIO_MIXER_LAST; 909 strlcpy(dip->label.name, AudioCrecord, 910 sizeof dip->label.name); 911 return 0; 912 case CMPCI_INPUT_CLASS: 913 dip->type = AUDIO_MIXER_CLASS; 914 dip->mixer_class = CMPCI_INPUT_CLASS; 915 dip->next = dip->prev = AUDIO_MIXER_LAST; 916 strlcpy(dip->label.name, AudioCinputs, 917 sizeof dip->label.name); 918 return 0; 919 case CMPCI_PCSPEAKER: 920 dip->type = AUDIO_MIXER_VALUE; 921 dip->mixer_class = CMPCI_INPUT_CLASS; 922 dip->prev = dip->next = AUDIO_MIXER_LAST; 923 strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name); 924 dip->un.v.num_channels = 1; 925 strlcpy(dip->un.v.units.name, AudioNvolume, 926 sizeof dip->un.v.units.name); 927 return 0; 928 case CMPCI_INPUT_GAIN: 929 dip->type = AUDIO_MIXER_VALUE; 930 dip->mixer_class = CMPCI_INPUT_CLASS; 931 dip->prev = dip->next = AUDIO_MIXER_LAST; 932 strlcpy(dip->label.name, AudioNinput, 933 sizeof dip->label.name); 934 dip->un.v.num_channels = 2; 935 strlcpy(dip->un.v.units.name, AudioNvolume, 936 sizeof dip->un.v.units.name); 937 return 0; 938 case CMPCI_OUTPUT_GAIN: 939 dip->type = AUDIO_MIXER_VALUE; 940 dip->mixer_class = CMPCI_OUTPUT_CLASS; 941 dip->prev = dip->next = AUDIO_MIXER_LAST; 942 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 943 dip->un.v.num_channels = 2; 944 strlcpy(dip->un.v.units.name, AudioNvolume, 945 sizeof dip->un.v.units.name); 946 return 0; 947 case CMPCI_AGC: 948 dip->type = AUDIO_MIXER_ENUM; 949 dip->mixer_class = CMPCI_INPUT_CLASS; 950 dip->prev = dip->next = AUDIO_MIXER_LAST; 951 strlcpy(dip->label.name, "agc", sizeof dip->label.name); 952 dip->un.e.num_mem = 2; 953 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 954 sizeof dip->un.e.member[0].label.name); 955 dip->un.e.member[0].ord = 0; 956 strlcpy(dip->un.e.member[1].label.name, AudioNon, 957 sizeof dip->un.e.member[1].label.name); 958 dip->un.e.member[1].ord = 1; 959 return 0; 960 case CMPCI_EQUALIZATION_CLASS: 961 dip->type = AUDIO_MIXER_CLASS; 962 dip->mixer_class = CMPCI_EQUALIZATION_CLASS; 963 dip->next = dip->prev = AUDIO_MIXER_LAST; 964 strlcpy(dip->label.name, AudioCequalization, 965 sizeof dip->label.name); 966 return 0; 967 case CMPCI_CD_IN_MUTE: 968 dip->prev = CMPCI_CD_VOL; 969 dip->next = CMPCI_CD_SWAP; 970 dip->mixer_class = CMPCI_INPUT_CLASS; 971 goto mute; 972 case CMPCI_MIC_IN_MUTE: 973 dip->prev = CMPCI_MIC_VOL; 974 dip->next = CMPCI_MIC_SWAP; 975 dip->mixer_class = CMPCI_INPUT_CLASS; 976 goto mute; 977 case CMPCI_LINE_IN_MUTE: 978 dip->prev = CMPCI_LINE_IN_VOL; 979 dip->next = CMPCI_LINE_SWAP; 980 dip->mixer_class = CMPCI_INPUT_CLASS; 981 goto mute; 982 case CMPCI_FM_IN_MUTE: 983 dip->prev = CMPCI_FM_VOL; 984 dip->next = CMPCI_FM_SWAP; 985 dip->mixer_class = CMPCI_INPUT_CLASS; 986 goto mute; 987 case CMPCI_CD_SWAP: 988 dip->prev = CMPCI_CD_IN_MUTE; 989 dip->next = CMPCI_CD_OUT_MUTE; 990 goto swap; 991 case CMPCI_MIC_SWAP: 992 dip->prev = CMPCI_MIC_IN_MUTE; 993 dip->next = CMPCI_MIC_OUT_MUTE; 994 goto swap; 995 case CMPCI_LINE_SWAP: 996 dip->prev = CMPCI_LINE_IN_MUTE; 997 dip->next = CMPCI_LINE_OUT_MUTE; 998 goto swap; 999 case CMPCI_FM_SWAP: 1000 dip->prev = CMPCI_FM_IN_MUTE; 1001 dip->next = AUDIO_MIXER_LAST; 1002 swap: 1003 dip->mixer_class = CMPCI_INPUT_CLASS; 1004 strlcpy(dip->label.name, AudioNswap, sizeof dip->label.name); 1005 goto mute1; 1006 case CMPCI_CD_OUT_MUTE: 1007 dip->prev = CMPCI_CD_SWAP; 1008 dip->next = AUDIO_MIXER_LAST; 1009 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1010 goto mute; 1011 case CMPCI_MIC_OUT_MUTE: 1012 dip->prev = CMPCI_MIC_SWAP; 1013 dip->next = AUDIO_MIXER_LAST; 1014 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1015 goto mute; 1016 case CMPCI_LINE_OUT_MUTE: 1017 dip->prev = CMPCI_LINE_SWAP; 1018 dip->next = AUDIO_MIXER_LAST; 1019 dip->mixer_class = CMPCI_OUTPUT_CLASS; 1020 mute: 1021 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 1022 mute1: 1023 dip->type = AUDIO_MIXER_ENUM; 1024 dip->un.e.num_mem = 2; 1025 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 1026 sizeof dip->un.e.member[0].label.name); 1027 dip->un.e.member[0].ord = 0; 1028 strlcpy(dip->un.e.member[1].label.name, AudioNon, 1029 sizeof dip->un.e.member[1].label.name); 1030 dip->un.e.member[1].ord = 1; 1031 return 0; 1032 } 1033 1034 return ENXIO; 1035 } 1036 1037 int 1038 cmpci_alloc_dmamem(sc, size, type, flags, r_addr) 1039 struct cmpci_softc *sc; 1040 size_t size; 1041 int type, flags; 1042 caddr_t *r_addr; 1043 { 1044 int ret = 0; 1045 struct cmpci_dmanode *n; 1046 int w; 1047 1048 if ( NULL == (n=malloc(sizeof(struct cmpci_dmanode), type, flags)) ) { 1049 ret = ENOMEM; 1050 goto quit; 1051 } 1052 1053 w = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK; 1054 #define CMPCI_DMABUF_ALIGN 0x4 1055 #define CMPCI_DMABUF_BOUNDARY 0x0 1056 n->cd_tag = sc->sc_dmat; 1057 n->cd_size = size; 1058 if ( (ret=bus_dmamem_alloc(n->cd_tag, n->cd_size, 1059 CMPCI_DMABUF_ALIGN, CMPCI_DMABUF_BOUNDARY, 1060 n->cd_segs, 1061 sizeof(n->cd_segs)/sizeof(n->cd_segs[0]), 1062 &n->cd_nsegs, w)) ) 1063 goto mfree; 1064 if ( (ret=bus_dmamem_map(n->cd_tag, n->cd_segs, n->cd_nsegs, n->cd_size, 1065 &n->cd_addr, w | BUS_DMA_COHERENT)) ) 1066 goto dmafree; 1067 if ( (ret=bus_dmamap_create(n->cd_tag, n->cd_size, 1, n->cd_size, 0, 1068 w, &n->cd_map)) ) 1069 goto unmap; 1070 if ( (ret=bus_dmamap_load(n->cd_tag, n->cd_map, n->cd_addr, n->cd_size, 1071 NULL, w)) ) 1072 goto destroy; 1073 1074 n->cd_next = sc->sc_dmap; 1075 sc->sc_dmap = n; 1076 *r_addr = KVADDR(n); 1077 return 0; 1078 1079 destroy: 1080 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1081 unmap: 1082 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1083 dmafree: 1084 bus_dmamem_free(n->cd_tag, 1085 n->cd_segs, sizeof(n->cd_segs)/sizeof(n->cd_segs[0])); 1086 mfree: 1087 free(n, type); 1088 quit: 1089 return ret; 1090 } 1091 1092 int 1093 cmpci_free_dmamem(sc, addr, type) 1094 struct cmpci_softc *sc; 1095 caddr_t addr; 1096 int type; 1097 { 1098 struct cmpci_dmanode **nnp; 1099 1100 for (nnp = &sc->sc_dmap; *nnp; nnp = &(*nnp)->cd_next) { 1101 if ((*nnp)->cd_addr == addr) { 1102 struct cmpci_dmanode *n = *nnp; 1103 1104 bus_dmamap_unload(n->cd_tag, n->cd_map); 1105 bus_dmamap_destroy(n->cd_tag, n->cd_map); 1106 bus_dmamem_unmap(n->cd_tag, n->cd_addr, n->cd_size); 1107 bus_dmamem_free(n->cd_tag, n->cd_segs, 1108 sizeof(n->cd_segs)/sizeof(n->cd_segs[0])); 1109 free(n, type); 1110 return 0; 1111 } 1112 } 1113 return -1; 1114 } 1115 1116 struct cmpci_dmanode * 1117 cmpci_find_dmamem(sc, addr) 1118 struct cmpci_softc *sc; 1119 caddr_t addr; 1120 { 1121 struct cmpci_dmanode *p; 1122 for (p = sc->sc_dmap; p; p = p->cd_next) { 1123 if (KVADDR(p) == (void *)addr) 1124 break; 1125 } 1126 return p; 1127 } 1128 1129 #if 0 1130 void 1131 cmpci_print_dmamem(struct cmpci_dmanode *p); 1132 void 1133 cmpci_print_dmamem(p) 1134 struct cmpci_dmanode *p; 1135 { 1136 DPRINTF(("DMA at virt:%p, dmaseg:%p, mapseg:%p, size:%p\n", 1137 (void *)p->cd_addr, (void *)p->cd_segs[0].ds_addr, 1138 (void *)DMAADDR(p), (void *)p->cd_size)); 1139 } 1140 #endif /* DEBUG */ 1141 1142 void * 1143 cmpci_malloc(handle, direction, size, type, flags) 1144 void *handle; 1145 int direction; 1146 size_t size; 1147 int type, flags; 1148 { 1149 struct cmpci_softc *sc = handle; 1150 caddr_t addr; 1151 1152 if ( cmpci_alloc_dmamem(sc, size, type, flags, &addr) ) 1153 return NULL; 1154 return addr; 1155 } 1156 1157 void 1158 cmpci_free(handle, addr, type) 1159 void *handle; 1160 void *addr; 1161 int type; 1162 { 1163 struct cmpci_softc *sc = handle; 1164 1165 cmpci_free_dmamem(sc, addr, type); 1166 } 1167 1168 #define MAXVAL 256 1169 int 1170 cmpci_adjust(val, mask) 1171 int val, mask; 1172 { 1173 val += (MAXVAL - mask) >> 1; 1174 if (val >= MAXVAL) 1175 val = MAXVAL-1; 1176 return val & mask; 1177 } 1178 1179 void 1180 cmpci_set_mixer_gain(sc, port) 1181 struct cmpci_softc *sc; 1182 int port; 1183 { 1184 int src; 1185 1186 switch (port) { 1187 case CMPCI_MIC_VOL: 1188 src = CMPCI_SB16_MIXER_MIC; 1189 break; 1190 case CMPCI_MASTER_VOL: 1191 src = CMPCI_SB16_MIXER_MASTER_L; 1192 break; 1193 case CMPCI_LINE_IN_VOL: 1194 src = CMPCI_SB16_MIXER_LINE_L; 1195 break; 1196 case CMPCI_VOICE_VOL: 1197 src = CMPCI_SB16_MIXER_VOICE_L; 1198 break; 1199 case CMPCI_FM_VOL: 1200 src = CMPCI_SB16_MIXER_FM_L; 1201 break; 1202 case CMPCI_CD_VOL: 1203 src = CMPCI_SB16_MIXER_CDDA_L; 1204 break; 1205 case CMPCI_INPUT_GAIN: 1206 src = CMPCI_SB16_MIXER_INGAIN_L; 1207 break; 1208 case CMPCI_OUTPUT_GAIN: 1209 src = CMPCI_SB16_MIXER_OUTGAIN_L; 1210 break; 1211 case CMPCI_TREBLE: 1212 src = CMPCI_SB16_MIXER_TREBLE_L; 1213 break; 1214 case CMPCI_BASS: 1215 src = CMPCI_SB16_MIXER_BASS_L; 1216 break; 1217 case CMPCI_PCSPEAKER: 1218 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_SPEAKER, 1219 sc->gain[port][CMPCI_LEFT]); 1220 return; 1221 default: 1222 return; 1223 } 1224 cmpci_mixerreg_write(sc, src, sc->gain[port][CMPCI_LEFT]); 1225 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_L_TO_R(src), 1226 sc->gain[port][CMPCI_RIGHT]); 1227 } 1228 1229 int 1230 cmpci_set_in_ports(sc, mask) 1231 struct cmpci_softc *sc; 1232 int mask; 1233 { 1234 int bitsl, bitsr; 1235 1236 if (mask & ~((1<<CMPCI_FM_VOL) | (1<<CMPCI_LINE_IN_VOL) | 1237 (1<<CMPCI_CD_VOL) | (1<<CMPCI_MIC_VOL) 1238 #ifdef CMPCI_SPDIF_SUPPORT 1239 | (1<<CMPCI_SPDIF_IN) 1240 #endif 1241 )) 1242 return EINVAL; 1243 bitsr = 0; 1244 if (mask & (1<<CMPCI_FM_VOL)) 1245 bitsr |= CMPCI_SB16_MIXER_FM_SRC_R; 1246 if (mask & (1<<CMPCI_LINE_IN_VOL)) 1247 bitsr |= CMPCI_SB16_MIXER_LINE_SRC_R; 1248 if (mask & (1<<CMPCI_CD_VOL)) 1249 bitsr |= CMPCI_SB16_MIXER_CD_SRC_R; 1250 bitsl = CMPCI_SB16_MIXER_SRC_R_TO_L(bitsr); 1251 if (mask & (1<<CMPCI_MIC_VOL)) { 1252 bitsl |= CMPCI_SB16_MIXER_MIC_SRC; 1253 bitsr |= CMPCI_SB16_MIXER_MIC_SRC; 1254 } 1255 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, bitsl); 1256 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, bitsr); 1257 1258 sc->in_mask = mask; 1259 1260 return 0; 1261 } 1262 1263 int 1264 cmpci_set_port(handle, cp) 1265 void *handle; 1266 mixer_ctrl_t *cp; 1267 { 1268 struct cmpci_softc *sc = handle; 1269 int lgain, rgain; 1270 int mask, bits; 1271 int lmask, rmask, lbits, rbits; 1272 int mute, swap; 1273 1274 switch (cp->dev) { 1275 case CMPCI_TREBLE: 1276 case CMPCI_BASS: 1277 case CMPCI_PCSPEAKER: 1278 case CMPCI_INPUT_GAIN: 1279 case CMPCI_OUTPUT_GAIN: 1280 case CMPCI_MIC_VOL: 1281 case CMPCI_LINE_IN_VOL: 1282 case CMPCI_VOICE_VOL: 1283 case CMPCI_FM_VOL: 1284 case CMPCI_CD_VOL: 1285 case CMPCI_MASTER_VOL: 1286 if (cp->type != AUDIO_MIXER_VALUE) 1287 return EINVAL; 1288 switch (cp->dev) { 1289 case CMPCI_MIC_VOL: 1290 if (cp->un.value.num_channels != 1) 1291 return EINVAL; 1292 1293 lgain = rgain = CMPCI_ADJUST_MIC_GAIN(sc, 1294 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1295 break; 1296 case CMPCI_PCSPEAKER: 1297 if (cp->un.value.num_channels != 1) 1298 return EINVAL; 1299 /* FALLTHROUGH */ 1300 case CMPCI_INPUT_GAIN: 1301 case CMPCI_OUTPUT_GAIN: 1302 lgain = rgain = CMPCI_ADJUST_2_GAIN(sc, 1303 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1304 break; 1305 default: 1306 switch (cp->un.value.num_channels) { 1307 case 1: 1308 lgain = rgain = CMPCI_ADJUST_GAIN(sc, 1309 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1310 break; 1311 case 2: 1312 lgain = CMPCI_ADJUST_GAIN(sc, 1313 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]); 1314 rgain = CMPCI_ADJUST_GAIN(sc, 1315 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); 1316 break; 1317 default: 1318 return EINVAL; 1319 } 1320 break; 1321 } 1322 sc->gain[cp->dev][CMPCI_LEFT] = lgain; 1323 sc->gain[cp->dev][CMPCI_RIGHT] = rgain; 1324 1325 cmpci_set_mixer_gain(sc, cp->dev); 1326 break; 1327 1328 case CMPCI_RECORD_SOURCE: 1329 if (cp->type != AUDIO_MIXER_SET) 1330 return EINVAL; 1331 #ifdef CMPCI_SPDIF_SUPPORT 1332 if ( cp->un.mask&(1<<CMPCI_SPDIF_IN) ) 1333 cp->un.mask = 1<<CMPCI_SPDIF_IN; 1334 #endif 1335 return cmpci_set_in_ports(sc, cp->un.mask); 1336 1337 case CMPCI_AGC: 1338 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_AGC, cp->un.ord & 1); 1339 break; 1340 case CMPCI_CD_OUT_MUTE: 1341 mask = CMPCI_SB16_SW_CD; 1342 goto omute; 1343 case CMPCI_MIC_OUT_MUTE: 1344 mask = CMPCI_SB16_SW_MIC; 1345 goto omute; 1346 case CMPCI_LINE_OUT_MUTE: 1347 mask = CMPCI_SB16_SW_LINE; 1348 omute: 1349 if (cp->type != AUDIO_MIXER_ENUM) 1350 return EINVAL; 1351 bits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_OUTMIX); 1352 sc->gain[cp->dev][CMPCI_LR] = cp->un.ord != 0; 1353 if (cp->un.ord) 1354 bits = bits & ~mask; 1355 else 1356 bits = bits | mask; 1357 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_OUTMIX, bits); 1358 break; 1359 1360 case CMPCI_MIC_IN_MUTE: 1361 case CMPCI_MIC_SWAP: 1362 lmask = rmask = CMPCI_SB16_SW_MIC; 1363 goto imute; 1364 case CMPCI_CD_IN_MUTE: 1365 case CMPCI_CD_SWAP: 1366 lmask = CMPCI_SB16_SW_CD_L; 1367 rmask = CMPCI_SB16_SW_CD_R; 1368 goto imute; 1369 case CMPCI_LINE_IN_MUTE: 1370 case CMPCI_LINE_SWAP: 1371 lmask = CMPCI_SB16_SW_LINE_L; 1372 rmask = CMPCI_SB16_SW_LINE_R; 1373 goto imute; 1374 case CMPCI_FM_IN_MUTE: 1375 case CMPCI_FM_SWAP: 1376 lmask = CMPCI_SB16_SW_FM_L; 1377 rmask = CMPCI_SB16_SW_FM_R; 1378 imute: 1379 if (cp->type != AUDIO_MIXER_ENUM) 1380 return EINVAL; 1381 mask = lmask | rmask; 1382 lbits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_ADCMIX_L) 1383 & ~mask; 1384 rbits = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_ADCMIX_R) 1385 & ~mask; 1386 sc->gain[cp->dev][CMPCI_LR] = cp->un.ord != 0; 1387 if (CMPCI_IS_IN_MUTE(cp->dev)) { 1388 mute = cp->dev; 1389 swap = mute - CMPCI_CD_IN_MUTE + CMPCI_CD_SWAP; 1390 } else { 1391 swap = cp->dev; 1392 mute = swap + CMPCI_CD_IN_MUTE - CMPCI_CD_SWAP; 1393 } 1394 if (sc->gain[swap][CMPCI_LR]) { 1395 mask = lmask; 1396 lmask = rmask; 1397 rmask = mask; 1398 } 1399 if (!sc->gain[mute][CMPCI_LR]) { 1400 lbits = lbits | lmask; 1401 rbits = rbits | rmask; 1402 } 1403 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_L, lbits); 1404 cmpci_mixerreg_write(sc, CMPCI_SB16_MIXER_ADCMIX_R, rbits); 1405 break; 1406 1407 default: 1408 return EINVAL; 1409 } 1410 1411 return 0; 1412 } 1413 1414 int 1415 cmpci_get_port(handle, cp) 1416 void *handle; 1417 mixer_ctrl_t *cp; 1418 { 1419 struct cmpci_softc *sc = handle; 1420 1421 switch (cp->dev) { 1422 case CMPCI_MIC_VOL: 1423 case CMPCI_LINE_IN_VOL: 1424 if (cp->un.value.num_channels != 1) 1425 return EINVAL; 1426 /* FALLTHROUGH */ 1427 case CMPCI_TREBLE: 1428 case CMPCI_BASS: 1429 case CMPCI_PCSPEAKER: 1430 case CMPCI_INPUT_GAIN: 1431 case CMPCI_OUTPUT_GAIN: 1432 case CMPCI_VOICE_VOL: 1433 case CMPCI_FM_VOL: 1434 case CMPCI_CD_VOL: 1435 case CMPCI_MASTER_VOL: 1436 switch (cp->un.value.num_channels) { 1437 case 1: 1438 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1439 sc->gain[cp->dev][CMPCI_LEFT]; 1440 break; 1441 case 2: 1442 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1443 sc->gain[cp->dev][CMPCI_LEFT]; 1444 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1445 sc->gain[cp->dev][CMPCI_RIGHT]; 1446 break; 1447 default: 1448 return EINVAL; 1449 } 1450 break; 1451 1452 case CMPCI_RECORD_SOURCE: 1453 cp->un.mask = sc->in_mask; 1454 break; 1455 1456 case CMPCI_AGC: 1457 cp->un.ord = cmpci_mixerreg_read(sc, CMPCI_SB16_MIXER_AGC); 1458 break; 1459 1460 case CMPCI_CD_IN_MUTE: 1461 case CMPCI_MIC_IN_MUTE: 1462 case CMPCI_LINE_IN_MUTE: 1463 case CMPCI_FM_IN_MUTE: 1464 case CMPCI_CD_SWAP: 1465 case CMPCI_MIC_SWAP: 1466 case CMPCI_LINE_SWAP: 1467 case CMPCI_FM_SWAP: 1468 case CMPCI_CD_OUT_MUTE: 1469 case CMPCI_MIC_OUT_MUTE: 1470 case CMPCI_LINE_OUT_MUTE: 1471 cp->un.ord = sc->gain[cp->dev][CMPCI_LR]; 1472 break; 1473 1474 default: 1475 return EINVAL; 1476 } 1477 1478 return 0; 1479 } 1480 1481 /* ARGSUSED */ 1482 size_t 1483 cmpci_round_buffersize(handle, direction, bufsize) 1484 void *handle; 1485 int direction; 1486 size_t bufsize; 1487 { 1488 if (bufsize > 0x10000) 1489 bufsize = 0x10000; 1490 1491 return bufsize; 1492 } 1493 1494 paddr_t 1495 cmpci_mappage(handle, addr, offset, prot) 1496 void *handle; 1497 void *addr; 1498 off_t offset; 1499 int prot; 1500 { 1501 struct cmpci_softc *sc = handle; 1502 struct cmpci_dmanode *p; 1503 1504 if ( offset < 0 || (p = cmpci_find_dmamem(sc, addr)) == NULL) 1505 return -1; 1506 1507 return bus_dmamem_mmap(p->cd_tag, p->cd_segs, 1508 sizeof(p->cd_segs)/sizeof(p->cd_segs[0]), 1509 offset, prot, BUS_DMA_WAITOK); 1510 } 1511 1512 /* ARGSUSED */ 1513 int 1514 cmpci_get_props(handle) 1515 void *handle; 1516 { 1517 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1518 } 1519 1520 1521 int 1522 cmpci_trigger_output(handle, start, end, blksize, intr, arg, param) 1523 void *handle; 1524 void *start, *end; 1525 int blksize; 1526 void (*intr)(void *); 1527 void *arg; 1528 struct audio_params *param; 1529 { 1530 struct cmpci_softc *sc = handle; 1531 struct cmpci_dmanode *p; 1532 int bps; 1533 1534 sc->sc_play.intr = intr; 1535 sc->sc_play.intr_arg = arg; 1536 bps = param->channels * param->precision * param->factor / 8; 1537 if (!bps) 1538 return EINVAL; 1539 1540 /* set DMA frame */ 1541 if (!(p = cmpci_find_dmamem(sc, start))) 1542 return EINVAL; 1543 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA0_BASE, 1544 DMAADDR(p)); 1545 delay(10); 1546 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA0_BYTES, 1547 ((caddr_t)end-(caddr_t)start+1)/bps-1); 1548 delay(10); 1549 1550 /* set interrupt count */ 1551 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA0_SAMPLES, 1552 (blksize+bps-1)/bps-1); 1553 delay(10); 1554 1555 /* start DMA */ 1556 cmpci_reg_clear_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_DIR); /* PLAY */ 1557 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE); 1558 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH0_ENABLE); 1559 1560 return 0; 1561 } 1562 1563 int 1564 cmpci_trigger_input(handle, start, end, blksize, intr, arg, param) 1565 void *handle; 1566 void *start, *end; 1567 int blksize; 1568 void (*intr)(void *); 1569 void *arg; 1570 struct audio_params *param; 1571 { 1572 struct cmpci_softc *sc = handle; 1573 struct cmpci_dmanode *p; 1574 int bps; 1575 1576 sc->sc_rec.intr = intr; 1577 sc->sc_rec.intr_arg = arg; 1578 bps = param->channels*param->precision*param->factor/8; 1579 if (!bps) 1580 return EINVAL; 1581 1582 /* set DMA frame */ 1583 if (!(p = cmpci_find_dmamem(sc, start))) 1584 return EINVAL; 1585 bus_space_write_4(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BASE, 1586 DMAADDR(p)); 1587 delay(10); 1588 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_BYTES, 1589 ((caddr_t)end-(caddr_t)start+1)/bps-1); 1590 delay(10); 1591 1592 /* set interrupt count */ 1593 bus_space_write_2(sc->sc_iot, sc->sc_ioh, CMPCI_REG_DMA1_SAMPLES, 1594 (blksize+bps-1)/bps-1); 1595 delay(10); 1596 1597 /* start DMA */ 1598 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_DIR); /* REC */ 1599 cmpci_reg_set_4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); 1600 cmpci_reg_set_4(sc, CMPCI_REG_FUNC_0, CMPCI_REG_CH1_ENABLE); 1601 1602 return 0; 1603 } 1604