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