1 /* $NetBSD: interwave.c,v 1.37 2012/10/27 17:18:20 chs Exp $ */ 2 3 /* 4 * Copyright (c) 1997, 1999, 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Author: Kari Mettinen 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: interwave.c,v 1.37 2012/10/27 17:18:20 chs Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/errno.h> 37 #include <sys/ioctl.h> 38 #include <sys/syslog.h> 39 #include <sys/device.h> 40 #include <sys/proc.h> 41 #include <sys/buf.h> 42 #include <sys/fcntl.h> 43 #include <sys/malloc.h> 44 #include <sys/kernel.h> 45 #include <sys/cpu.h> 46 #include <sys/intr.h> 47 #include <sys/audioio.h> 48 49 #include <machine/pio.h> 50 51 #include <dev/audio_if.h> 52 #include <dev/mulaw.h> 53 54 #include <dev/isa/isavar.h> 55 #include <dev/isa/isadmavar.h> 56 57 #include <dev/ic/interwavereg.h> 58 #include <dev/ic/interwavevar.h> 59 60 61 static void iwreset(struct iw_softc *, int); 62 63 static int iw_set_speed(struct iw_softc *, u_long, char); 64 static u_long iw_set_format(struct iw_softc *, u_long, int); 65 static void iw_mixer_line_level(struct iw_softc *, int, int, int); 66 static void iw_trigger_dma(struct iw_softc *, u_char); 67 static void iw_stop_dma(struct iw_softc *, u_char, u_char); 68 static void iw_dma_count(struct iw_softc *, u_short, int); 69 static int iwintr(void *); 70 static void iw_meminit(struct iw_softc *); 71 static void iw_mempoke(struct iw_softc *, u_long, u_char); 72 static u_char iw_mempeek(struct iw_softc *, u_long); 73 74 #ifdef USE_WAVETABLE 75 static void iw_set_voice_place(struct iw_softc *, u_char, u_long); 76 static void iw_voice_pan(struct iw_softc *, u_char, u_short, u_short); 77 static void iw_voice_freq(struct iw_softc *, u_char, u_long); 78 static void iw_set_loopmode(struct iw_softc *, u_char, u_char, u_char); 79 static void iw_set_voice_pos(struct iw_softc *, u_short, u_long, u_long); 80 static void iw_start_voice(struct iw_softc *, u_char); 81 static void iw_play_voice(struct iw_softc *, u_long, u_long, u_short); 82 static void iw_stop_voice(struct iw_softc *, u_char); 83 static void iw_move_voice_end(struct iw_softc *, u_short, u_long); 84 static void iw_initvoices(struct iw_softc *); 85 #endif 86 87 struct audio_device iw_device = { 88 "Am78C201", 89 "0.1", 90 "guspnp" 91 }; 92 93 #ifdef AUDIO_DEBUG 94 int iw_debug; 95 #define DPRINTF(p) if (iw_debug) printf p 96 #else 97 #define DPRINTF(p) 98 #endif 99 100 static int iw_cc = 1; 101 #ifdef DIAGNOSTIC 102 static int outputs = 0; 103 static int iw_ints = 0; 104 static int inputs = 0; 105 static int iw_inints = 0; 106 #endif 107 108 int 109 iwintr(void *arg) 110 { 111 struct iw_softc *sc; 112 int val; 113 u_char intrs; 114 115 sc = arg; 116 val = 0; 117 intrs = 0; 118 119 mutex_spin_enter(&sc->sc_intr_lock); 120 121 IW_READ_DIRECT_1(6, sc->p2xr_h, intrs); /* UISR */ 122 123 /* codec ints */ 124 125 /* 126 * The proper order to do this seems to be to read CSR3 to get the 127 * int cause and fifo over underrrun status, then deal with the ints 128 * (new DMA set up), and to clear ints by writing the respective bit 129 * to 0. 130 */ 131 132 /* read what ints happened */ 133 134 IW_READ_CODEC_1(CSR3I, intrs); 135 136 /* clear them */ 137 138 IW_WRITE_DIRECT_1(2, sc->codec_index_h, 0x00); 139 140 /* and process them */ 141 142 if (intrs & 0x20) { 143 #ifdef DIAGNOSTIC 144 iw_inints++; 145 #endif 146 if (sc->sc_recintr != 0) 147 sc->sc_recintr(sc->sc_recarg); 148 val = 1; 149 } 150 if (intrs & 0x10) { 151 #ifdef DIAGNOSTIC 152 iw_ints++; 153 #endif 154 if (sc->sc_playintr != 0) 155 sc->sc_playintr(sc->sc_playarg); 156 val = 1; 157 } 158 159 mutex_spin_exit(&sc->sc_intr_lock); 160 161 return val; 162 } 163 164 void 165 iwattach(struct iw_softc *sc) 166 { 167 int got_irq; 168 169 DPRINTF(("iwattach sc %p\n", sc)); 170 got_irq = 0; 171 172 sc->cdatap = 1; /* relative offsets in region */ 173 sc->csr1r = 2; 174 sc->cxdr = 3; /* CPDR or CRDR */ 175 176 sc->gmxr = 0; /* sc->p3xr */ 177 sc->gmxdr = 1; /* GMTDR or GMRDR */ 178 sc->svsr = 2; 179 sc->igidxr = 3; 180 sc->i16dp = 4; 181 sc->i8dp = 5; 182 sc->lmbdr = 7; 183 184 sc->rec_precision = sc->play_precision = 8; 185 sc->rec_channels = sc->play_channels = 1; 186 sc->rec_encoding = sc->play_encoding = AUDIO_ENCODING_ULAW; 187 sc->sc_irate = 8000; 188 sc->sc_orate = 8000; 189 190 sc->sc_fullduplex = 1; 191 192 sc->sc_dma_flags = 0; 193 194 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 195 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); 196 197 /* 198 * We can only use a few selected irqs, see if we got one from pnp 199 * code that suits us. 200 */ 201 202 if (sc->sc_irq > 0) { 203 sc->sc_ih = isa_intr_establish(sc->sc_p2xr_ic, 204 sc->sc_irq, IST_EDGE, IPL_AUDIO, iwintr, sc); 205 got_irq = 1; 206 } 207 if (!got_irq) { 208 printf("\niwattach: couldn't get a suitable irq\n"); 209 mutex_destroy(&sc->sc_lock); 210 mutex_destroy(&sc->sc_intr_lock); 211 return; 212 } 213 printf("\n"); 214 iwreset(sc, 0); 215 iw_set_format(sc, AUDIO_ENCODING_ULAW, 0); 216 iw_set_format(sc, AUDIO_ENCODING_ULAW, 1); 217 printf("%s: interwave version %s\n", 218 device_xname(sc->sc_dev), iw_device.version); 219 audio_attach_mi(sc->iw_hw_if, sc, sc->sc_dev); 220 } 221 222 int 223 iwopen(struct iw_softc *sc, int flags) 224 { 225 226 DPRINTF(("iwopen: sc %p\n", sc)); 227 228 #ifdef DIAGNOSTIC 229 outputs = 0; 230 iw_ints = 0; 231 inputs = 0; 232 iw_inints = 0; 233 #endif 234 235 iwreset(sc, 1); 236 237 return 0; 238 } 239 240 void 241 iwclose(void *addr) 242 { 243 244 DPRINTF(("iwclose sc %p\n", addr)); 245 #ifdef DIAGNOSTIC 246 DPRINTF(("iwclose: outputs %d ints %d inputs %d in_ints %d\n", 247 outputs, iw_ints, inputs, iw_inints)); 248 #endif 249 } 250 251 #define RAM_STEP 64*1024 252 253 static void 254 iw_mempoke(struct iw_softc *sc, u_long addy, u_char val) 255 { 256 257 IW_WRITE_GENERAL_2(LMALI, (u_short) addy); 258 IW_WRITE_GENERAL_1(LMAHI, (u_char) (addy >> 16)); 259 260 /* Write byte to LMBDR */ 261 IW_WRITE_DIRECT_1(sc->p3xr + 7, sc->p3xr_h, val); 262 } 263 264 static u_char 265 iw_mempeek(struct iw_softc *sc, u_long addy) 266 { 267 u_char ret; 268 269 IW_WRITE_GENERAL_2(LMALI, (u_short) addy); 270 IW_WRITE_GENERAL_1(LMAHI, (u_char) (addy >> 16)); 271 272 IW_READ_DIRECT_1(sc->p3xr + 7, sc->p3xr_h, ret); 273 return ret; /* return byte from LMBDR */ 274 } 275 276 static void 277 iw_meminit(struct iw_softc *sc) 278 { 279 u_long bank[4] = {0L, 0L, 0L, 0L}; 280 u_long addr, base, cnt; 281 u_char i, ram /* ,memval=0 */ ; 282 u_short lmcfi; 283 u_long temppi; 284 u_long *lpbanks; 285 286 addr = 0L; 287 base = 0L; 288 cnt = 0L; 289 ram = 0; 290 lpbanks = &temppi; 291 292 IW_WRITE_GENERAL_1(LDMACI, 0x00); 293 294 IW_READ_GENERAL_2(LMCFI, lmcfi); /* 0x52 */ 295 lmcfi |= 0x0A0C; 296 IW_WRITE_GENERAL_2(LMCFI, lmcfi); /* max addr span */ 297 IW_WRITE_GENERAL_1(LMCI, 0x00); 298 299 /* fifo addresses */ 300 301 IW_WRITE_GENERAL_2(LMRFAI, ((4 * 1024 * 1024) >> 8)); 302 IW_WRITE_GENERAL_2(LMPFAI, ((4 * 1024 * 1024 + 16 * 1024) >> 8)); 303 304 IW_WRITE_GENERAL_2(LMFSI, 0x000); 305 306 IW_WRITE_GENERAL_2(LDICI, 0x0000); 307 308 while (addr < (16 * 1024 * 1024)) { 309 iw_mempoke(sc, addr, 0x00); 310 addr += RAM_STEP; 311 } 312 313 printf("%s:", device_xname(sc->sc_dev)); 314 315 for (i = 0; i < 4; i++) { 316 iw_mempoke(sc, base, 0xAA); /* mark start of bank */ 317 iw_mempoke(sc, base + 1L, 0x55); 318 if (iw_mempeek(sc, base) == 0xAA && 319 iw_mempeek(sc, base + 1L) == 0x55) 320 ram = 1; 321 if (ram) { 322 while (cnt < (4 * 1024 * 1024)) { 323 bank[i] += RAM_STEP; 324 cnt += RAM_STEP; 325 addr = base + cnt; 326 if (iw_mempeek(sc, addr) == 0xAA) 327 break; 328 } 329 } 330 if (lpbanks != NULL) { 331 *lpbanks = bank[i]; 332 lpbanks++; 333 } 334 bank[i] = bank[i] >> 10; 335 printf("%s bank[%d]: %ldK", i ? "," : "", i, bank[i]); 336 base += 4 * 1024 * 1024; 337 cnt = 0L; 338 ram = 0; 339 } 340 341 printf("\n"); 342 343 /* 344 * this is not really useful since GUS PnP supports memory 345 * configurations that aren't really supported by Interwave...beware 346 * of holes! Also, we don't use the memory for anything in this 347 * version of the driver. 348 * 349 * we've configured for 4M-4M-4M-4M 350 */ 351 } 352 353 static void 354 iwreset(struct iw_softc *sc, int warm) 355 { 356 u_char reg, cmode, val, mixer_image; 357 358 val = 0; 359 mixer_image = 0; 360 reg = 0; /* XXX gcc -Wall */ 361 362 cmode = 0x6c; /* enhanced codec mode (full duplex) */ 363 364 /* reset */ 365 366 IW_WRITE_GENERAL_1(URSTI, 0x00); 367 delay(10); 368 IW_WRITE_GENERAL_1(URSTI, 0x07); 369 IW_WRITE_GENERAL_1(ICMPTI, 0x1f); /* disable DSP and uici and 370 * udci writes */ 371 IW_WRITE_GENERAL_1(IDECI, 0x7f); /* enable ints to ISA and 372 * codec access */ 373 IW_READ_GENERAL_1(IVERI, reg); 374 IW_WRITE_GENERAL_1(IVERI, reg | 0x01); /* hidden reg lock disable */ 375 IW_WRITE_GENERAL_1(UASBCI, 0x00); 376 377 /* synth enhanced mode (default), 0 active voices, disable ints */ 378 379 IW_WRITE_GENERAL_1(SGMI_WR, 0x01); /* enhanced mode, LFOs 380 * disabled */ 381 for (val = 0; val < 32; val++) { 382 /* set each synth sound volume to 0 */ 383 IW_WRITE_DIRECT_1(sc->p3xr + 2, sc->p3xr_h, val); 384 IW_WRITE_GENERAL_1(SVSI_WR, 0x00); 385 IW_WRITE_GENERAL_2(SASLI_WR, 0x0000); 386 IW_WRITE_GENERAL_2(SASHI_WR, 0x0000); 387 IW_WRITE_GENERAL_2(SAELI_WR, 0x0000); 388 IW_WRITE_GENERAL_2(SAEHI_WR, 0x0000); 389 IW_WRITE_GENERAL_2(SFCI_WR, 0x0000); 390 IW_WRITE_GENERAL_1(SACI_WR, 0x02); 391 IW_WRITE_GENERAL_1(SVSI_WR, 0x00); 392 IW_WRITE_GENERAL_1(SVEI_WR, 0x00); 393 IW_WRITE_GENERAL_2(SVLI_WR, 0x0000); 394 IW_WRITE_GENERAL_1(SVCI_WR, 0x02); 395 IW_WRITE_GENERAL_1(SMSI_WR, 0x02); 396 } 397 398 IW_WRITE_GENERAL_1(SAVI_WR, 0x00); 399 400 /* codec mode/init */ 401 402 /* first change mode to 1 */ 403 404 IW_WRITE_CODEC_1(CMODEI, 0x00); 405 406 /* and mode 3 */ 407 408 IW_WRITE_CODEC_1(CMODEI, cmode); 409 410 IW_READ_CODEC_1(CMODEI, reg); 411 412 DPRINTF(("cmode %x\n", reg)); 413 414 sc->revision = ((reg & 0x80) >> 3) | (reg & 0x0f); 415 416 IW_WRITE_DIRECT_1(sc->codec_index + 2, sc->p2xr_h, 0x00); 417 418 IW_WRITE_CODEC_1(CFIG1I | IW_MCE, 0x00); /* DMA 2 chan access */ 419 IW_WRITE_CODEC_1(CEXTI, 0x00); /* disable ints for now */ 420 421 422 IW_WRITE_CODEC_1(CLPCTI, 0x00); /* reset playback sample counters */ 423 IW_WRITE_CODEC_1(CUPCTI, 0x00); /* always upper byte last */ 424 IW_WRITE_CODEC_1(CFIG2I, 0x80); /* full voltage range, enable record 425 * and playback sample counters, and 426 * don't center output in case or 427 * FIFO underrun */ 428 IW_WRITE_CODEC_1(CFIG3I, 0xc0); /* enable record/playback irq (still 429 * turned off from CEXTI), max DMA 430 * rate */ 431 IW_WRITE_CODEC_1(CSR3I, 0x00); /* clear status 3 reg */ 432 433 434 IW_WRITE_CODEC_1(CLRCTI, 0x00); /* reset record sample counters */ 435 IW_WRITE_CODEC_1(CURCTI, 0x00); /* always upper byte last */ 436 437 438 IW_READ_GENERAL_1(IVERI, reg); 439 440 sc->vers = reg >> 4; 441 if (!warm) 442 snprintf(iw_device.version, sizeof(iw_device.version), "%d.%d", 443 sc->vers, sc->revision); 444 445 IW_WRITE_GENERAL_1(IDECI, 0x7f); /* irqs and codec decode 446 * enable */ 447 448 449 /* ports */ 450 451 if (!warm) { 452 iw_mixer_line_level(sc, IW_LINE_OUT, 255, 255); 453 iw_mixer_line_level(sc, IW_LINE_IN, 0, 0); 454 iw_mixer_line_level(sc, IW_AUX1, 0, 0); 455 iw_mixer_line_level(sc, IW_AUX2, 200, 200); /* CD */ 456 sc->sc_dac.off = 0; 457 iw_mixer_line_level(sc, IW_DAC, 200, 200); 458 459 iw_mixer_line_level(sc, IW_MIC_IN, 0, 0); 460 iw_mixer_line_level(sc, IW_REC, 0, 0); 461 iw_mixer_line_level(sc, IW_LOOPBACK, 0, 0); 462 iw_mixer_line_level(sc, IW_MONO_IN, 0, 0); 463 464 /* mem stuff */ 465 iw_meminit(sc); 466 467 } 468 IW_WRITE_CODEC_1(CEXTI, 0x02); /* codec int enable */ 469 470 /* clear _LDMACI */ 471 472 IW_WRITE_GENERAL_1(LDMACI, 0x00); 473 474 /* enable mixer paths */ 475 mixer_image = 0x0c; 476 IW_WRITE_DIRECT_1(sc->p2xr, sc->p2xr_h, mixer_image); 477 /* 478 * enable output, line in. disable mic in bit 0 = 0 -> line in on 479 * (from codec?) bit 1 = 0 -> output on bit 2 = 1 -> mic in on bit 3 480 * = 1 -> irq&drq pin enable bit 4 = 1 -> channel interrupts to chan 481 * 1 bit 5 = 1 -> enable midi loop back bit 6 = 0 -> irq latches 482 * URCR[2:0] bit 6 = 1 -> DMA latches URCR[2:0] 483 */ 484 485 486 IW_READ_DIRECT_1(sc->p2xr, sc->p2xr_h, mixer_image); 487 #ifdef AUDIO_DEBUG 488 if (!warm) 489 DPRINTF(("mix image %x \n", mixer_image)); 490 #endif 491 } 492 493 struct iw_codec_freq { 494 u_long freq; 495 u_char bits; 496 }; 497 498 int 499 iw_set_speed(struct iw_softc *sc, u_long freq, char in) 500 { 501 u_char var, cfig3, reg; 502 503 static struct iw_codec_freq iw_cf[17] = { 504 #define FREQ_1 24576000 505 #define FREQ_2 16934400 506 #define XTAL1 0 507 #define XTAL2 1 508 {5510, 0x00 | XTAL2}, {6620, 0x0E | XTAL2}, 509 {8000, 0x00 | XTAL1}, {9600, 0x0E | XTAL1}, 510 {11025, 0x02 | XTAL2}, {16000, 0x02 | XTAL1}, 511 {18900, 0x04 | XTAL2}, {22050, 0x06 | XTAL2}, 512 {27420, 0x04 | XTAL1}, {32000, 0x06 | XTAL1}, 513 {33075, 0x0C | XTAL2}, {37800, 0x08 | XTAL2}, 514 {38400, 0x0A | XTAL1}, {44100, 0x0A | XTAL2}, 515 {44800, 0x08 | XTAL1}, {48000, 0x0C | XTAL1}, 516 {48000, 0x0C | XTAL1} /* really a dummy for indexing later */ 517 #undef XTAL1 518 #undef XTAL2 519 }; 520 521 cfig3 = 0; /* XXX gcc -Wall */ 522 523 /* 524 * if the frequency is between 3493 Hz and 32 kHz we can use a more 525 * accurate frequency than the ones listed above base on the formula 526 * FREQ/((16*(48+x))) where FREQ is either FREQ_1 (24576000Hz) or 527 * FREQ_2 (16934400Hz) and x is the value to be written to either 528 * CPVFI or CRVFI. To enable this option, bit 2 in CFIG3 needs to be 529 * set high 530 * 531 * NOT IMPLEMENTED! 532 * 533 * Note that if you have a 'bad' XTAL_1 (higher than 18.5 MHz), 44.8 kHz 534 * and 38.4 kHz modes will provide wrong frequencies to output. 535 */ 536 537 538 if (freq > 48000) 539 freq = 48000; 540 if (freq < 5510) 541 freq = 5510; 542 543 /* reset CFIG3[2] */ 544 545 IW_READ_CODEC_1(CFIG3I, cfig3); 546 547 cfig3 |= 0xc0; /* not full fifo treshhold */ 548 549 DPRINTF(("cfig3i = %x -> ", cfig3)); 550 551 cfig3 &= ~0x04; 552 IW_WRITE_CODEC_1(CFIG3I, cfig3); 553 IW_READ_CODEC_1(CFIG3I, cfig3); 554 555 DPRINTF(("%x\n", cfig3)); 556 557 for (var = 0; var < 16; var++) /* select closest frequency */ 558 if (freq <= iw_cf[var].freq) 559 break; 560 if (var != 16) 561 if (abs(freq - iw_cf[var].freq) > abs(iw_cf[var + 1].freq - freq)) 562 var++; 563 564 if (in) 565 IW_WRITE_CODEC_1(CRDFI | IW_MCE, sc->recfmtbits | iw_cf[var].bits); 566 else 567 IW_WRITE_CODEC_1(CPDFI | IW_MCE, sc->playfmtbits | iw_cf[var].bits); 568 freq = iw_cf[var].freq; 569 DPRINTF(("setting %s frequency to %d bits %x \n", 570 in ? "in" : "out", (int) freq, iw_cf[var].bits)); 571 572 IW_READ_CODEC_1(CPDFI, reg); 573 574 DPRINTF((" CPDFI %x ", reg)); 575 576 IW_READ_CODEC_1(CRDFI, reg); 577 578 DPRINTF((" CRDFI %x ", reg)); 579 580 return freq; 581 } 582 583 /* Encoding. */ 584 int 585 iw_query_encoding(void *addr, audio_encoding_t *fp) 586 { 587 /* 588 * LINEAR, ALAW, ULAW, ADPCM in HW, we'll use linear unsigned 589 * hardware mode for all 8-bit modes due to buggy (?) codec. 590 */ 591 592 /* 593 * except in wavetable synth. there we have only mu-law and 8 and 16 594 * bit linear data 595 */ 596 597 switch (fp->index) { 598 case 0: 599 strcpy(fp->name, AudioEulinear); 600 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 601 fp->precision = 8; 602 fp->flags = 0; 603 break; 604 case 1: 605 strcpy(fp->name, AudioEmulaw); 606 fp->encoding = AUDIO_ENCODING_ULAW; 607 fp->precision = 8; 608 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 609 break; 610 case 2: 611 strcpy(fp->name, AudioEalaw); 612 fp->encoding = AUDIO_ENCODING_ALAW; 613 fp->precision = 8; 614 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 615 break; 616 case 3: 617 strcpy(fp->name, AudioEadpcm); 618 fp->encoding = AUDIO_ENCODING_ADPCM; 619 fp->precision = 8; /* really 4 bit */ 620 fp->flags = 0; 621 break; 622 case 4: 623 strcpy(fp->name, AudioEslinear_le); 624 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 625 fp->precision = 16; 626 fp->flags = 0; 627 break; 628 case 5: 629 strcpy(fp->name, AudioEslinear_be); 630 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 631 fp->precision = 16; 632 fp->flags = 0; 633 break; 634 default: 635 return EINVAL; 636 /* NOTREACHED */ 637 } 638 return 0; 639 } 640 641 u_long 642 iw_set_format(struct iw_softc *sc, u_long precision, int in) 643 { 644 u_char data; 645 int encoding, channels; 646 647 encoding = in ? sc->rec_encoding : sc->play_encoding; 648 channels = in ? sc->rec_channels : sc->play_channels; 649 650 DPRINTF(("iw_set_format\n")); 651 652 switch (encoding) { 653 case AUDIO_ENCODING_ULAW: 654 data = 0x00; 655 break; 656 657 case AUDIO_ENCODING_ALAW: 658 data = 0x00; 659 break; 660 661 case AUDIO_ENCODING_SLINEAR_LE: 662 if (precision == 16) 663 data = 0x40; /* little endian. 0xc0 is big endian */ 664 else 665 data = 0x00; 666 break; 667 668 case AUDIO_ENCODING_SLINEAR_BE: 669 if (precision == 16) 670 data = 0xc0; 671 else 672 data = 0x00; 673 break; 674 675 case AUDIO_ENCODING_ADPCM: 676 data = 0xa0; 677 break; 678 679 default: 680 return -1; 681 } 682 683 if (channels == 2) 684 data |= 0x10; /* stereo */ 685 686 if (in) { 687 /* in */ 688 sc->recfmtbits = data; 689 /* This will zero the normal codec frequency, 690 * iw_set_speed should always be called afterwards. 691 */ 692 IW_WRITE_CODEC_1(CRDFI | IW_MCE, data); 693 } else { 694 /* out */ 695 sc->playfmtbits = data; 696 IW_WRITE_CODEC_1(CPDFI | IW_MCE, data); 697 } 698 699 DPRINTF(("formatbits %s %x", in ? "in" : "out", data)); 700 701 return encoding; 702 } 703 704 int 705 iw_set_params(void *addr, int setmode, int usemode, audio_params_t *p, 706 audio_params_t *q, stream_filter_list_t *pfil, stream_filter_list_t *rfil) 707 { 708 audio_params_t phw, rhw; 709 struct iw_softc *sc; 710 stream_filter_factory_t *swcode; 711 712 DPRINTF(("iw_setparams: code %u, prec %u, rate %u, chan %u\n", 713 p->encoding, p->precision, p->sample_rate, p->channels)); 714 sc = addr; 715 swcode = NULL; 716 phw = *p; 717 rhw = *q; 718 switch (p->encoding) { 719 case AUDIO_ENCODING_ULAW: 720 if (p->precision != 8) 721 return EINVAL; 722 phw.encoding = AUDIO_ENCODING_ULINEAR_LE; 723 rhw.encoding = AUDIO_ENCODING_ULINEAR_LE; 724 swcode = setmode & AUMODE_PLAY ? mulaw_to_linear8 : linear8_to_mulaw; 725 break; 726 case AUDIO_ENCODING_ALAW: 727 if (p->precision != 8) 728 return EINVAL; 729 phw.encoding = AUDIO_ENCODING_ULINEAR_LE; 730 rhw.encoding = AUDIO_ENCODING_ULINEAR_LE; 731 swcode = setmode & AUMODE_PLAY ? alaw_to_linear8 : linear8_to_alaw; 732 break; 733 case AUDIO_ENCODING_ADPCM: 734 if (p->precision != 8) 735 return EINVAL; 736 else 737 break; 738 739 case AUDIO_ENCODING_SLINEAR_LE: 740 case AUDIO_ENCODING_SLINEAR_BE: 741 if (p->precision != 8 && p->precision != 16) 742 return EINVAL; 743 else 744 break; 745 746 default: 747 return EINVAL; 748 749 } 750 751 if (setmode & AUMODE_PLAY) { 752 sc->play_channels = p->channels; 753 sc->play_encoding = p->encoding; 754 sc->play_precision = p->precision; 755 iw_set_format(sc, p->precision, 0); 756 q->sample_rate = p->sample_rate = sc->sc_orate = 757 iw_set_speed(sc, p->sample_rate, 0); 758 if (swcode != NULL) { 759 phw.sample_rate = p->sample_rate; 760 pfil->append(pfil, swcode, &phw); 761 } 762 } else { 763 #if 0 764 q->channels = sc->rec_channels = p->channels; 765 q->encoding = sc->rec_encoding = p->encoding; 766 q->precision = sc->rec_precision = p->precision; 767 #endif 768 sc->rec_channels = q->channels; 769 sc->rec_encoding = q->encoding; 770 sc->rec_precision = q->precision; 771 772 iw_set_format(sc, p->precision, 1); 773 q->sample_rate = sc->sc_irate = 774 iw_set_speed(sc, q->sample_rate, 1); 775 if (swcode != NULL) { 776 rhw.sample_rate = q->sample_rate; 777 rfil->append(rfil, swcode, &rhw); 778 } 779 } 780 return 0; 781 } 782 783 784 int 785 iw_round_blocksize(void *addr, int blk, int mode, 786 const audio_params_t *param) 787 { 788 789 /* Round to a multiple of the biggest sample size. */ 790 return blk &= -4; 791 } 792 793 void 794 iw_mixer_line_level(struct iw_softc *sc, int line, int levl, int levr) 795 { 796 u_char gainl, gainr, attenl, attenr; 797 798 switch (line) { 799 case IW_REC: 800 gainl = sc->sc_recsrcbits | (levl >> 4); 801 gainr = sc->sc_recsrcbits | (levr >> 4); 802 DPRINTF(("recording with %x", gainl)); 803 IW_WRITE_CODEC_1(CLICI, gainl); 804 IW_WRITE_CODEC_1(CRICI, gainr); 805 sc->sc_rec.voll = levl & 0xf0; 806 sc->sc_rec.volr = levr & 0xf0; 807 break; 808 809 case IW_AUX1: 810 811 gainl = (255 - levl) >> 3; 812 gainr = (255 - levr) >> 3; 813 814 /* mute if 0 level */ 815 if (levl == 0) 816 gainl |= 0x80; 817 if (levr == 0) 818 gainr |= 0x80; 819 820 IW_WRITE_CODEC_1(IW_LEFT_AUX1_PORT, gainl); 821 IW_WRITE_CODEC_1(IW_RIGHT_AUX1_PORT, gainr); 822 sc->sc_aux1.voll = levl & 0xf8; 823 sc->sc_aux1.volr = levr & 0xf8; 824 825 break; 826 827 case IW_AUX2: 828 829 gainl = (255 - levl) >> 3; 830 gainr = (255 - levr) >> 3; 831 832 /* mute if 0 level */ 833 if (levl == 0) 834 gainl |= 0x80; 835 if (levr == 0) 836 gainr |= 0x80; 837 838 IW_WRITE_CODEC_1(IW_LEFT_AUX2_PORT, gainl); 839 IW_WRITE_CODEC_1(IW_RIGHT_AUX2_PORT, gainr); 840 sc->sc_aux2.voll = levl & 0xf8; 841 sc->sc_aux2.volr = levr & 0xf8; 842 break; 843 case IW_DAC: 844 attenl = ((255 - levl) >> 2) | ((levl && !sc->sc_dac.off) ? 0 : 0x80); 845 attenr = ((255 - levr) >> 2) | ((levr && !sc->sc_dac.off) ? 0 : 0x80); 846 IW_WRITE_CODEC_1(CLDACI, attenl); 847 IW_WRITE_CODEC_1(CRDACI, attenr); 848 sc->sc_dac.voll = levl & 0xfc; 849 sc->sc_dac.volr = levr & 0xfc; 850 break; 851 case IW_LOOPBACK: 852 attenl = ((255 - levl) & 0xfc) | (levl ? 0x01 : 0); 853 IW_WRITE_CODEC_1(CLCI, attenl); 854 sc->sc_loopback.voll = levl & 0xfc; 855 break; 856 case IW_LINE_IN: 857 gainl = (levl >> 3) | (levl ? 0 : 0x80); 858 gainr = (levr >> 3) | (levr ? 0 : 0x80); 859 IW_WRITE_CODEC_1(CLLICI, gainl); 860 IW_WRITE_CODEC_1(CRLICI, gainr); 861 sc->sc_linein.voll = levl & 0xf8; 862 sc->sc_linein.volr = levr & 0xf8; 863 break; 864 case IW_MIC_IN: 865 gainl = ((255 - levl) >> 3) | (levl ? 0 : 0x80); 866 gainr = ((255 - levr) >> 3) | (levr ? 0 : 0x80); 867 IW_WRITE_CODEC_1(CLMICI, gainl); 868 IW_WRITE_CODEC_1(CRMICI, gainr); 869 sc->sc_mic.voll = levl & 0xf8; 870 sc->sc_mic.volr = levr & 0xf8; 871 break; 872 case IW_LINE_OUT: 873 attenl = ((255 - levl) >> 3) | (levl ? 0 : 0x80); 874 attenr = ((255 - levr) >> 3) | (levr ? 0 : 0x80); 875 IW_WRITE_CODEC_1(CLOAI, attenl); 876 IW_WRITE_CODEC_1(CROAI, attenr); 877 sc->sc_lineout.voll = levl & 0xf8; 878 sc->sc_lineout.volr = levr & 0xf8; 879 break; 880 case IW_MONO_IN: 881 attenl = ((255 - levl) >> 4) | (levl ? 0 : 0xc0); /* in/out mute */ 882 IW_WRITE_CODEC_1(CMONOI, attenl); 883 sc->sc_monoin.voll = levl & 0xf0; 884 break; 885 } 886 } 887 888 int 889 iw_commit_settings(void *addr) 890 { 891 892 return 0; 893 } 894 895 void 896 iw_trigger_dma(struct iw_softc *sc, u_char io) 897 { 898 u_char reg; 899 900 IW_READ_CODEC_1(CSR3I, reg); 901 IW_WRITE_CODEC_1(CSR3I, reg & ~(io == IW_DMA_PLAYBACK ? 0x10 : 0x20)); 902 903 IW_READ_CODEC_1(CFIG1I, reg); 904 905 IW_WRITE_CODEC_1(CFIG1I, reg | io); 906 907 /* let the counter run */ 908 IW_READ_CODEC_1(CFIG2I, reg); 909 IW_WRITE_CODEC_1(CFIG2I, reg & ~(io << 4)); 910 } 911 912 void 913 iw_stop_dma(struct iw_softc *sc, u_char io, u_char hard) 914 { 915 u_char reg; 916 917 /* just stop the counter, no need to flush the fifo */ 918 IW_READ_CODEC_1(CFIG2I, reg); 919 IW_WRITE_CODEC_1(CFIG2I, (reg | (io << 4))); 920 921 if (hard) { 922 /* unless we're closing the device */ 923 IW_READ_CODEC_1(CFIG1I, reg); 924 IW_WRITE_CODEC_1(CFIG1I, reg & ~io); 925 } 926 } 927 928 void 929 iw_dma_count(struct iw_softc *sc, u_short count, int io) 930 { 931 932 if (io == IW_DMA_PLAYBACK) { 933 IW_WRITE_CODEC_1(CLPCTI, (u_char) (count & 0x00ff)); 934 IW_WRITE_CODEC_1(CUPCTI, (u_char) ((count >> 8) & 0x00ff)); 935 } else { 936 IW_WRITE_CODEC_1(CLRCTI, (u_char) (count & 0x00ff)); 937 IW_WRITE_CODEC_1(CURCTI, (u_char) ((count >> 8) & 0x00ff)); 938 } 939 } 940 941 int 942 iw_init_output(void *addr, void *sbuf, int cc) 943 { 944 struct iw_softc *sc = (struct iw_softc *) addr; 945 946 DPRINTF(("iw_init_output\n")); 947 948 isa_dmastart(sc->sc_ic, sc->sc_playdrq, sbuf, 949 cc, NULL, DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT); 950 return 0; 951 } 952 953 int 954 iw_init_input(void *addr, void *sbuf, int cc) 955 { 956 struct iw_softc *sc; 957 958 DPRINTF(("iw_init_input\n")); 959 sc = (struct iw_softc *) addr; 960 isa_dmastart(sc->sc_ic, sc->sc_recdrq, sbuf, 961 cc, NULL, DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT); 962 return 0; 963 } 964 965 966 int 967 iw_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 968 { 969 struct iw_softc *sc; 970 971 #ifdef DIAGNOSTIC 972 if (!intr) { 973 printf("iw_start_output: no callback!\n"); 974 return 1; 975 } 976 #endif 977 sc = addr; 978 sc->sc_playintr = intr; 979 sc->sc_playarg = arg; 980 sc->sc_dma_flags |= DMAMODE_WRITE; 981 sc->sc_playdma_bp = p; 982 983 isa_dmastart(sc->sc_ic, sc->sc_playdrq, sc->sc_playdma_bp, 984 cc, NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT); 985 986 987 if (sc->play_encoding == AUDIO_ENCODING_ADPCM) 988 cc >>= 2; 989 if (sc->play_precision == 16) 990 cc >>= 1; 991 992 if (sc->play_channels == 2 && sc->play_encoding != AUDIO_ENCODING_ADPCM) 993 cc >>= 1; 994 995 cc -= iw_cc; 996 997 /* iw_dma_access(sc,1); */ 998 if (cc != sc->sc_playdma_cnt) { 999 iw_dma_count(sc, (u_short) cc, IW_DMA_PLAYBACK); 1000 sc->sc_playdma_cnt = cc; 1001 1002 iw_trigger_dma(sc, IW_DMA_PLAYBACK); 1003 } 1004 1005 #ifdef DIAGNOSTIC 1006 if (outputs != iw_ints) 1007 printf("iw_start_output: out %d, int %d\n", outputs, iw_ints); 1008 outputs++; 1009 #endif 1010 1011 return 0; 1012 } 1013 1014 1015 int 1016 iw_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 1017 { 1018 struct iw_softc *sc; 1019 1020 #ifdef DIAGNOSTIC 1021 if (!intr) { 1022 printf("iw_start_input: no callback!\n"); 1023 return 1; 1024 } 1025 #endif 1026 sc = addr; 1027 sc->sc_recintr = intr; 1028 sc->sc_recarg = arg; 1029 sc->sc_dma_flags |= DMAMODE_READ; 1030 sc->sc_recdma_bp = p; 1031 1032 isa_dmastart(sc->sc_ic, sc->sc_recdrq, sc->sc_recdma_bp, 1033 cc, NULL, DMAMODE_READ, BUS_DMA_NOWAIT); 1034 1035 1036 if (sc->rec_encoding == AUDIO_ENCODING_ADPCM) 1037 cc >>= 2; 1038 if (sc->rec_precision == 16) 1039 cc >>= 1; 1040 1041 if (sc->rec_channels == 2 && sc->rec_encoding != AUDIO_ENCODING_ADPCM) 1042 cc >>= 1; 1043 1044 cc -= iw_cc; 1045 1046 /* iw_dma_access(sc,0); */ 1047 if (sc->sc_recdma_cnt != cc) { 1048 iw_dma_count(sc, (u_short) cc, IW_DMA_RECORD); 1049 sc->sc_recdma_cnt = cc; 1050 /* iw_dma_ctrl(sc, IW_DMA_RECORD); */ 1051 iw_trigger_dma(sc, IW_DMA_RECORD); 1052 } 1053 1054 #ifdef DIAGNOSTIC 1055 if ((inputs != iw_inints)) 1056 printf("iw_start_input: in %d, inints %d\n", inputs, iw_inints); 1057 inputs++; 1058 #endif 1059 1060 return 0; 1061 } 1062 1063 1064 int 1065 iw_halt_output(void *addr) 1066 { 1067 struct iw_softc *sc; 1068 1069 sc = addr; 1070 iw_stop_dma(sc, IW_DMA_PLAYBACK, 0); 1071 return 0; 1072 } 1073 1074 1075 int 1076 iw_halt_input(void *addr) 1077 { 1078 struct iw_softc *sc; 1079 1080 sc = addr; 1081 iw_stop_dma(sc, IW_DMA_RECORD, 0); 1082 return 0; 1083 } 1084 1085 int 1086 iw_speaker_ctl(void *addr, int newstate) 1087 { 1088 struct iw_softc *sc; 1089 u_char reg; 1090 1091 sc = addr; 1092 if (newstate == SPKR_ON) { 1093 sc->sc_dac.off = 0; 1094 IW_READ_CODEC_1(CLDACI, reg); 1095 IW_WRITE_CODEC_1(CLDACI, reg & 0x7f); 1096 IW_READ_CODEC_1(CRDACI, reg); 1097 IW_WRITE_CODEC_1(CRDACI, reg & 0x7f); 1098 } else { 1099 /* SPKR_OFF */ 1100 sc->sc_dac.off = 1; 1101 IW_READ_CODEC_1(CLDACI, reg); 1102 IW_WRITE_CODEC_1(CLDACI, reg | 0x80); 1103 IW_READ_CODEC_1(CRDACI, reg); 1104 IW_WRITE_CODEC_1(CRDACI, reg | 0x80); 1105 } 1106 return 0; 1107 } 1108 1109 int 1110 iw_getdev(void *addr, struct audio_device *retp) 1111 { 1112 1113 *retp = iw_device; 1114 return 0; 1115 } 1116 1117 int 1118 iw_setfd(void *addr, int flag) 1119 { 1120 1121 return 0; 1122 } 1123 1124 /* Mixer (in/out ports) */ 1125 int 1126 iw_set_port(void *addr, mixer_ctrl_t *cp) 1127 { 1128 struct iw_softc *sc; 1129 u_char vall, valr; 1130 int error; 1131 1132 sc = addr; 1133 vall = 0; 1134 valr = 0; 1135 error = EINVAL; 1136 switch (cp->dev) { 1137 case IW_MIC_IN_LVL: 1138 if (cp->type == AUDIO_MIXER_VALUE) { 1139 error = 0; 1140 if (cp->un.value.num_channels == 1) { 1141 vall = valr = cp->un.value.level[0]; 1142 } else { 1143 vall = cp->un.value.level[0]; 1144 valr = cp->un.value.level[1]; 1145 } 1146 sc->sc_mic.voll = vall; 1147 sc->sc_mic.volr = valr; 1148 iw_mixer_line_level(sc, IW_MIC_IN, vall, valr); 1149 } 1150 break; 1151 case IW_AUX1_LVL: 1152 if (cp->type == AUDIO_MIXER_VALUE) { 1153 error = 0; 1154 if (cp->un.value.num_channels == 1) { 1155 vall = valr = cp->un.value.level[0]; 1156 } else { 1157 vall = cp->un.value.level[0]; 1158 valr = cp->un.value.level[1]; 1159 } 1160 sc->sc_aux1.voll = vall; 1161 sc->sc_aux1.volr = valr; 1162 iw_mixer_line_level(sc, IW_AUX1, vall, valr); 1163 } 1164 break; 1165 case IW_AUX2_LVL: 1166 if (cp->type == AUDIO_MIXER_VALUE) { 1167 error = 0; 1168 if (cp->un.value.num_channels == 1) { 1169 vall = valr = cp->un.value.level[0]; 1170 } else { 1171 vall = cp->un.value.level[0]; 1172 valr = cp->un.value.level[1]; 1173 } 1174 sc->sc_aux2.voll = vall; 1175 sc->sc_aux2.volr = valr; 1176 iw_mixer_line_level(sc, IW_AUX2, vall, valr); 1177 } 1178 break; 1179 case IW_LINE_IN_LVL: 1180 if (cp->type == AUDIO_MIXER_VALUE) { 1181 error = 0; 1182 if (cp->un.value.num_channels == 1) { 1183 vall = valr = cp->un.value.level[0]; 1184 } else { 1185 vall = cp->un.value.level[0]; 1186 valr = cp->un.value.level[1]; 1187 } 1188 sc->sc_linein.voll = vall; 1189 sc->sc_linein.volr = valr; 1190 iw_mixer_line_level(sc, IW_LINE_IN, vall, valr); 1191 } 1192 break; 1193 case IW_LINE_OUT_LVL: 1194 if (cp->type == AUDIO_MIXER_VALUE) { 1195 error = 0; 1196 if (cp->un.value.num_channels == 1) { 1197 vall = valr = cp->un.value.level[0]; 1198 } else { 1199 vall = cp->un.value.level[0]; 1200 valr = cp->un.value.level[1]; 1201 } 1202 sc->sc_lineout.voll = vall; 1203 sc->sc_lineout.volr = valr; 1204 iw_mixer_line_level(sc, IW_LINE_OUT, vall, valr); 1205 } 1206 break; 1207 case IW_REC_LVL: 1208 if (cp->type == AUDIO_MIXER_VALUE) { 1209 error = 0; 1210 if (cp->un.value.num_channels == 1) { 1211 vall = valr = cp->un.value.level[0]; 1212 } else { 1213 vall = cp->un.value.level[0]; 1214 valr = cp->un.value.level[1]; 1215 } 1216 sc->sc_rec.voll = vall; 1217 sc->sc_rec.volr = valr; 1218 iw_mixer_line_level(sc, IW_REC, vall, valr); 1219 } 1220 break; 1221 1222 case IW_DAC_LVL: 1223 if (cp->type == AUDIO_MIXER_VALUE) { 1224 error = 0; 1225 if (cp->un.value.num_channels == 1) { 1226 vall = valr = cp->un.value.level[0]; 1227 } else { 1228 vall = cp->un.value.level[0]; 1229 valr = cp->un.value.level[1]; 1230 } 1231 sc->sc_dac.voll = vall; 1232 sc->sc_dac.volr = valr; 1233 iw_mixer_line_level(sc, IW_DAC, vall, valr); 1234 } 1235 break; 1236 1237 case IW_LOOPBACK_LVL: 1238 if (cp->type == AUDIO_MIXER_VALUE) { 1239 error = 0; 1240 if (cp->un.value.num_channels != 1) { 1241 return EINVAL; 1242 } else { 1243 valr = vall = cp->un.value.level[0]; 1244 } 1245 sc->sc_loopback.voll = vall; 1246 sc->sc_loopback.volr = valr; 1247 iw_mixer_line_level(sc, IW_LOOPBACK, vall, valr); 1248 } 1249 break; 1250 1251 case IW_MONO_IN_LVL: 1252 if (cp->type == AUDIO_MIXER_VALUE) { 1253 error = 0; 1254 if (cp->un.value.num_channels != 1) { 1255 return EINVAL; 1256 } else { 1257 valr = vall = cp->un.value.level[0]; 1258 } 1259 sc->sc_monoin.voll = vall; 1260 sc->sc_monoin.volr = valr; 1261 iw_mixer_line_level(sc, IW_MONO_IN, vall, valr); 1262 } 1263 break; 1264 case IW_RECORD_SOURCE: 1265 error = 0; 1266 sc->sc_recsrcbits = cp->un.ord << 6; 1267 DPRINTF(("record source %d bits %x\n", cp->un.ord, sc->sc_recsrcbits)); 1268 iw_mixer_line_level(sc, IW_REC, sc->sc_rec.voll, sc->sc_rec.volr); 1269 break; 1270 } 1271 1272 return error; 1273 } 1274 1275 1276 int 1277 iw_get_port(void *addr, mixer_ctrl_t *cp) 1278 { 1279 struct iw_softc *sc; 1280 int error; 1281 1282 sc = addr; 1283 error = EINVAL; 1284 switch (cp->dev) { 1285 case IW_MIC_IN_LVL: 1286 if (cp->type == AUDIO_MIXER_VALUE) { 1287 cp->un.value.num_channels = 2; 1288 cp->un.value.level[0] = sc->sc_mic.voll; 1289 cp->un.value.level[1] = sc->sc_mic.volr; 1290 error = 0; 1291 } 1292 break; 1293 case IW_AUX1_LVL: 1294 if (cp->type == AUDIO_MIXER_VALUE) { 1295 cp->un.value.num_channels = 2; 1296 cp->un.value.level[0] = sc->sc_aux1.voll; 1297 cp->un.value.level[1] = sc->sc_aux1.volr; 1298 error = 0; 1299 } 1300 break; 1301 case IW_AUX2_LVL: 1302 if (cp->type == AUDIO_MIXER_VALUE) { 1303 cp->un.value.num_channels = 2; 1304 cp->un.value.level[0] = sc->sc_aux2.voll; 1305 cp->un.value.level[1] = sc->sc_aux2.volr; 1306 error = 0; 1307 } 1308 break; 1309 case IW_LINE_OUT_LVL: 1310 if (cp->type == AUDIO_MIXER_VALUE) { 1311 cp->un.value.num_channels = 2; 1312 cp->un.value.level[0] = sc->sc_lineout.voll; 1313 cp->un.value.level[1] = sc->sc_lineout.volr; 1314 error = 0; 1315 } 1316 break; 1317 case IW_LINE_IN_LVL: 1318 if (cp->type == AUDIO_MIXER_VALUE) { 1319 cp->un.value.num_channels = 2; 1320 cp->un.value.level[0] = sc->sc_linein.voll; 1321 cp->un.value.level[1] = sc->sc_linein.volr; 1322 error = 0; 1323 } 1324 case IW_REC_LVL: 1325 if (cp->type == AUDIO_MIXER_VALUE) { 1326 cp->un.value.num_channels = 2; 1327 cp->un.value.level[0] = sc->sc_rec.voll; 1328 cp->un.value.level[1] = sc->sc_rec.volr; 1329 error = 0; 1330 } 1331 break; 1332 1333 case IW_DAC_LVL: 1334 if (cp->type == AUDIO_MIXER_VALUE) { 1335 cp->un.value.num_channels = 2; 1336 cp->un.value.level[0] = sc->sc_dac.voll; 1337 cp->un.value.level[1] = sc->sc_dac.volr; 1338 error = 0; 1339 } 1340 break; 1341 1342 case IW_LOOPBACK_LVL: 1343 if (cp->type == AUDIO_MIXER_VALUE) { 1344 cp->un.value.num_channels = 1; 1345 cp->un.value.level[0] = sc->sc_loopback.voll; 1346 error = 0; 1347 } 1348 break; 1349 1350 case IW_MONO_IN_LVL: 1351 if (cp->type == AUDIO_MIXER_VALUE) { 1352 cp->un.value.num_channels = 1; 1353 cp->un.value.level[0] = sc->sc_monoin.voll; 1354 error = 0; 1355 } 1356 break; 1357 case IW_RECORD_SOURCE: 1358 cp->un.ord = sc->sc_recsrcbits >> 6; 1359 error = 0; 1360 break; 1361 } 1362 1363 return error; 1364 } 1365 1366 1367 1368 int 1369 iw_query_devinfo(void *addr, mixer_devinfo_t *dip) 1370 { 1371 1372 switch (dip->index) { 1373 case IW_MIC_IN_LVL: /* Microphone */ 1374 dip->type = AUDIO_MIXER_VALUE; 1375 dip->mixer_class = IW_INPUT_CLASS; 1376 dip->prev = AUDIO_MIXER_LAST; 1377 dip->next = AUDIO_MIXER_LAST; 1378 strcpy(dip->label.name, AudioNmicrophone); 1379 dip->un.v.num_channels = 2; 1380 strcpy(dip->un.v.units.name, AudioNvolume); 1381 break; 1382 case IW_AUX1_LVL: 1383 dip->type = AUDIO_MIXER_VALUE; 1384 dip->mixer_class = IW_INPUT_CLASS; 1385 dip->prev = AUDIO_MIXER_LAST; 1386 dip->next = AUDIO_MIXER_LAST; 1387 strcpy(dip->label.name, AudioNline); 1388 dip->un.v.num_channels = 2; 1389 strcpy(dip->un.v.units.name, AudioNvolume); 1390 break; 1391 case IW_AUX2_LVL: 1392 dip->type = AUDIO_MIXER_VALUE; 1393 dip->mixer_class = IW_INPUT_CLASS; 1394 dip->prev = AUDIO_MIXER_LAST; 1395 dip->next = AUDIO_MIXER_LAST; 1396 strcpy(dip->label.name, AudioNcd); 1397 dip->un.v.num_channels = 2; 1398 strcpy(dip->un.v.units.name, AudioNvolume); 1399 break; 1400 case IW_LINE_OUT_LVL: 1401 dip->type = AUDIO_MIXER_VALUE; 1402 dip->mixer_class = IW_OUTPUT_CLASS; 1403 dip->prev = AUDIO_MIXER_LAST; 1404 dip->next = AUDIO_MIXER_LAST; 1405 strcpy(dip->label.name, AudioNline); 1406 dip->un.v.num_channels = 2; 1407 strcpy(dip->un.v.units.name, AudioNvolume); 1408 break; 1409 case IW_DAC_LVL: 1410 dip->type = AUDIO_MIXER_VALUE; 1411 dip->mixer_class = IW_OUTPUT_CLASS; 1412 dip->prev = AUDIO_MIXER_LAST; 1413 dip->next = AUDIO_MIXER_LAST; 1414 strcpy(dip->label.name, AudioNdac); 1415 dip->un.v.num_channels = 2; 1416 strcpy(dip->un.v.units.name, AudioNvolume); 1417 break; 1418 case IW_LINE_IN_LVL: 1419 dip->type = AUDIO_MIXER_VALUE; 1420 dip->mixer_class = IW_INPUT_CLASS; 1421 dip->prev = AUDIO_MIXER_LAST; 1422 dip->next = AUDIO_MIXER_LAST; 1423 strcpy(dip->label.name, AudioNinput); 1424 dip->un.v.num_channels = 2; 1425 strcpy(dip->un.v.units.name, AudioNvolume); 1426 break; 1427 case IW_MONO_IN_LVL: 1428 dip->type = AUDIO_MIXER_VALUE; 1429 dip->mixer_class = IW_INPUT_CLASS; 1430 dip->prev = AUDIO_MIXER_LAST; 1431 dip->next = AUDIO_MIXER_LAST; 1432 strcpy(dip->label.name, AudioNmono); 1433 dip->un.v.num_channels = 1; 1434 strcpy(dip->un.v.units.name, AudioNvolume); 1435 break; 1436 1437 case IW_REC_LVL: /* record level */ 1438 dip->type = AUDIO_MIXER_VALUE; 1439 dip->mixer_class = IW_RECORD_CLASS; 1440 dip->prev = AUDIO_MIXER_LAST; 1441 dip->next = AUDIO_MIXER_LAST; 1442 strcpy(dip->label.name, AudioNrecord); 1443 dip->un.v.num_channels = 2; 1444 strcpy(dip->un.v.units.name, AudioNvolume); 1445 break; 1446 1447 case IW_LOOPBACK_LVL: 1448 dip->type = AUDIO_MIXER_VALUE; 1449 dip->mixer_class = IW_RECORD_CLASS; 1450 dip->prev = AUDIO_MIXER_LAST; 1451 dip->next = AUDIO_MIXER_LAST; 1452 strcpy(dip->label.name, "filter"); 1453 dip->un.v.num_channels = 1; 1454 strcpy(dip->un.v.units.name, AudioNvolume); 1455 break; 1456 1457 case IW_RECORD_SOURCE: 1458 dip->mixer_class = IW_RECORD_CLASS; 1459 dip->type = AUDIO_MIXER_ENUM; 1460 dip->prev = AUDIO_MIXER_LAST; 1461 dip->next = AUDIO_MIXER_LAST; 1462 strcpy(dip->label.name, AudioNsource); 1463 dip->un.e.num_mem = 4; 1464 strcpy(dip->un.e.member[0].label.name, AudioNline); 1465 dip->un.e.member[0].ord = IW_LINE_IN_SRC; 1466 strcpy(dip->un.e.member[1].label.name, "aux1"); 1467 dip->un.e.member[1].ord = IW_AUX1_SRC; 1468 strcpy(dip->un.e.member[2].label.name, AudioNmicrophone); 1469 dip->un.e.member[2].ord = IW_MIC_IN_SRC; 1470 strcpy(dip->un.e.member[3].label.name, AudioNmixerout); 1471 dip->un.e.member[3].ord = IW_MIX_OUT_SRC; 1472 break; 1473 case IW_INPUT_CLASS: 1474 dip->type = AUDIO_MIXER_CLASS; 1475 dip->mixer_class = IW_INPUT_CLASS; 1476 dip->next = dip->prev = AUDIO_MIXER_LAST; 1477 strcpy(dip->label.name, AudioCinputs); 1478 break; 1479 case IW_OUTPUT_CLASS: 1480 dip->type = AUDIO_MIXER_CLASS; 1481 dip->mixer_class = IW_OUTPUT_CLASS; 1482 dip->next = dip->prev = AUDIO_MIXER_LAST; 1483 strcpy(dip->label.name, AudioCoutputs); 1484 break; 1485 case IW_RECORD_CLASS: /* record source class */ 1486 dip->type = AUDIO_MIXER_CLASS; 1487 dip->mixer_class = IW_RECORD_CLASS; 1488 dip->next = dip->prev = AUDIO_MIXER_LAST; 1489 strcpy(dip->label.name, AudioCrecord); 1490 return 0; 1491 default: 1492 return ENXIO; 1493 } 1494 return 0; 1495 } 1496 1497 1498 void * 1499 iw_malloc(void *addr, int direction, size_t size) 1500 { 1501 struct iw_softc *sc; 1502 int drq; 1503 1504 sc = addr; 1505 if (direction == AUMODE_PLAY) 1506 drq = sc->sc_playdrq; 1507 else 1508 drq = sc->sc_recdrq; 1509 return isa_malloc(sc->sc_ic, drq, size, M_DEVBUF, M_WAITOK); 1510 } 1511 1512 void 1513 iw_free(void *addr, void *ptr, size_t size) 1514 { 1515 1516 isa_free(ptr, M_DEVBUF); 1517 } 1518 1519 size_t 1520 iw_round_buffersize(void *addr, int direction, size_t size) 1521 { 1522 struct iw_softc *sc; 1523 bus_size_t maxsize; 1524 1525 sc = addr; 1526 if (direction == AUMODE_PLAY) 1527 maxsize = sc->sc_play_maxsize; 1528 else 1529 maxsize = sc->sc_rec_maxsize; 1530 1531 if (size > maxsize) 1532 size = maxsize; 1533 return size; 1534 } 1535 1536 paddr_t 1537 iw_mappage(void *addr, void *mem, off_t off, int prot) 1538 { 1539 1540 return isa_mappage(mem, off, prot); 1541 } 1542 1543 int 1544 iw_get_props(void *addr) 1545 { 1546 struct iw_softc *sc; 1547 1548 sc = addr; 1549 return AUDIO_PROP_MMAP | 1550 (sc->sc_fullduplex ? AUDIO_PROP_FULLDUPLEX : 0); 1551 } 1552 1553 void 1554 iw_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread) 1555 { 1556 struct iw_softc *sc; 1557 1558 sc = addr; 1559 *intr = &sc->sc_intr_lock; 1560 *thread = &sc->sc_lock; 1561 } 1562