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