1 /* $NetBSD: interwave.c,v 1.38 2013/11/08 03:12:17 christos 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.38 2013/11/08 03:12:17 christos 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 __USE(reg); 580 581 return freq; 582 } 583 584 /* Encoding. */ 585 int 586 iw_query_encoding(void *addr, audio_encoding_t *fp) 587 { 588 /* 589 * LINEAR, ALAW, ULAW, ADPCM in HW, we'll use linear unsigned 590 * hardware mode for all 8-bit modes due to buggy (?) codec. 591 */ 592 593 /* 594 * except in wavetable synth. there we have only mu-law and 8 and 16 595 * bit linear data 596 */ 597 598 switch (fp->index) { 599 case 0: 600 strcpy(fp->name, AudioEulinear); 601 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 602 fp->precision = 8; 603 fp->flags = 0; 604 break; 605 case 1: 606 strcpy(fp->name, AudioEmulaw); 607 fp->encoding = AUDIO_ENCODING_ULAW; 608 fp->precision = 8; 609 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 610 break; 611 case 2: 612 strcpy(fp->name, AudioEalaw); 613 fp->encoding = AUDIO_ENCODING_ALAW; 614 fp->precision = 8; 615 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 616 break; 617 case 3: 618 strcpy(fp->name, AudioEadpcm); 619 fp->encoding = AUDIO_ENCODING_ADPCM; 620 fp->precision = 8; /* really 4 bit */ 621 fp->flags = 0; 622 break; 623 case 4: 624 strcpy(fp->name, AudioEslinear_le); 625 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 626 fp->precision = 16; 627 fp->flags = 0; 628 break; 629 case 5: 630 strcpy(fp->name, AudioEslinear_be); 631 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 632 fp->precision = 16; 633 fp->flags = 0; 634 break; 635 default: 636 return EINVAL; 637 /* NOTREACHED */ 638 } 639 return 0; 640 } 641 642 u_long 643 iw_set_format(struct iw_softc *sc, u_long precision, int in) 644 { 645 u_char data; 646 int encoding, channels; 647 648 encoding = in ? sc->rec_encoding : sc->play_encoding; 649 channels = in ? sc->rec_channels : sc->play_channels; 650 651 DPRINTF(("iw_set_format\n")); 652 653 switch (encoding) { 654 case AUDIO_ENCODING_ULAW: 655 data = 0x00; 656 break; 657 658 case AUDIO_ENCODING_ALAW: 659 data = 0x00; 660 break; 661 662 case AUDIO_ENCODING_SLINEAR_LE: 663 if (precision == 16) 664 data = 0x40; /* little endian. 0xc0 is big endian */ 665 else 666 data = 0x00; 667 break; 668 669 case AUDIO_ENCODING_SLINEAR_BE: 670 if (precision == 16) 671 data = 0xc0; 672 else 673 data = 0x00; 674 break; 675 676 case AUDIO_ENCODING_ADPCM: 677 data = 0xa0; 678 break; 679 680 default: 681 return -1; 682 } 683 684 if (channels == 2) 685 data |= 0x10; /* stereo */ 686 687 if (in) { 688 /* in */ 689 sc->recfmtbits = data; 690 /* This will zero the normal codec frequency, 691 * iw_set_speed should always be called afterwards. 692 */ 693 IW_WRITE_CODEC_1(CRDFI | IW_MCE, data); 694 } else { 695 /* out */ 696 sc->playfmtbits = data; 697 IW_WRITE_CODEC_1(CPDFI | IW_MCE, data); 698 } 699 700 DPRINTF(("formatbits %s %x", in ? "in" : "out", data)); 701 702 return encoding; 703 } 704 705 int 706 iw_set_params(void *addr, int setmode, int usemode, audio_params_t *p, 707 audio_params_t *q, stream_filter_list_t *pfil, stream_filter_list_t *rfil) 708 { 709 audio_params_t phw, rhw; 710 struct iw_softc *sc; 711 stream_filter_factory_t *swcode; 712 713 DPRINTF(("iw_setparams: code %u, prec %u, rate %u, chan %u\n", 714 p->encoding, p->precision, p->sample_rate, p->channels)); 715 sc = addr; 716 swcode = NULL; 717 phw = *p; 718 rhw = *q; 719 switch (p->encoding) { 720 case AUDIO_ENCODING_ULAW: 721 if (p->precision != 8) 722 return EINVAL; 723 phw.encoding = AUDIO_ENCODING_ULINEAR_LE; 724 rhw.encoding = AUDIO_ENCODING_ULINEAR_LE; 725 swcode = setmode & AUMODE_PLAY ? mulaw_to_linear8 : linear8_to_mulaw; 726 break; 727 case AUDIO_ENCODING_ALAW: 728 if (p->precision != 8) 729 return EINVAL; 730 phw.encoding = AUDIO_ENCODING_ULINEAR_LE; 731 rhw.encoding = AUDIO_ENCODING_ULINEAR_LE; 732 swcode = setmode & AUMODE_PLAY ? alaw_to_linear8 : linear8_to_alaw; 733 break; 734 case AUDIO_ENCODING_ADPCM: 735 if (p->precision != 8) 736 return EINVAL; 737 else 738 break; 739 740 case AUDIO_ENCODING_SLINEAR_LE: 741 case AUDIO_ENCODING_SLINEAR_BE: 742 if (p->precision != 8 && p->precision != 16) 743 return EINVAL; 744 else 745 break; 746 747 default: 748 return EINVAL; 749 750 } 751 752 if (setmode & AUMODE_PLAY) { 753 sc->play_channels = p->channels; 754 sc->play_encoding = p->encoding; 755 sc->play_precision = p->precision; 756 iw_set_format(sc, p->precision, 0); 757 q->sample_rate = p->sample_rate = sc->sc_orate = 758 iw_set_speed(sc, p->sample_rate, 0); 759 if (swcode != NULL) { 760 phw.sample_rate = p->sample_rate; 761 pfil->append(pfil, swcode, &phw); 762 } 763 } else { 764 #if 0 765 q->channels = sc->rec_channels = p->channels; 766 q->encoding = sc->rec_encoding = p->encoding; 767 q->precision = sc->rec_precision = p->precision; 768 #endif 769 sc->rec_channels = q->channels; 770 sc->rec_encoding = q->encoding; 771 sc->rec_precision = q->precision; 772 773 iw_set_format(sc, p->precision, 1); 774 q->sample_rate = sc->sc_irate = 775 iw_set_speed(sc, q->sample_rate, 1); 776 if (swcode != NULL) { 777 rhw.sample_rate = q->sample_rate; 778 rfil->append(rfil, swcode, &rhw); 779 } 780 } 781 return 0; 782 } 783 784 785 int 786 iw_round_blocksize(void *addr, int blk, int mode, 787 const audio_params_t *param) 788 { 789 790 /* Round to a multiple of the biggest sample size. */ 791 return blk &= -4; 792 } 793 794 void 795 iw_mixer_line_level(struct iw_softc *sc, int line, int levl, int levr) 796 { 797 u_char gainl, gainr, attenl, attenr; 798 799 switch (line) { 800 case IW_REC: 801 gainl = sc->sc_recsrcbits | (levl >> 4); 802 gainr = sc->sc_recsrcbits | (levr >> 4); 803 DPRINTF(("recording with %x", gainl)); 804 IW_WRITE_CODEC_1(CLICI, gainl); 805 IW_WRITE_CODEC_1(CRICI, gainr); 806 sc->sc_rec.voll = levl & 0xf0; 807 sc->sc_rec.volr = levr & 0xf0; 808 break; 809 810 case IW_AUX1: 811 812 gainl = (255 - levl) >> 3; 813 gainr = (255 - levr) >> 3; 814 815 /* mute if 0 level */ 816 if (levl == 0) 817 gainl |= 0x80; 818 if (levr == 0) 819 gainr |= 0x80; 820 821 IW_WRITE_CODEC_1(IW_LEFT_AUX1_PORT, gainl); 822 IW_WRITE_CODEC_1(IW_RIGHT_AUX1_PORT, gainr); 823 sc->sc_aux1.voll = levl & 0xf8; 824 sc->sc_aux1.volr = levr & 0xf8; 825 826 break; 827 828 case IW_AUX2: 829 830 gainl = (255 - levl) >> 3; 831 gainr = (255 - levr) >> 3; 832 833 /* mute if 0 level */ 834 if (levl == 0) 835 gainl |= 0x80; 836 if (levr == 0) 837 gainr |= 0x80; 838 839 IW_WRITE_CODEC_1(IW_LEFT_AUX2_PORT, gainl); 840 IW_WRITE_CODEC_1(IW_RIGHT_AUX2_PORT, gainr); 841 sc->sc_aux2.voll = levl & 0xf8; 842 sc->sc_aux2.volr = levr & 0xf8; 843 break; 844 case IW_DAC: 845 attenl = ((255 - levl) >> 2) | ((levl && !sc->sc_dac.off) ? 0 : 0x80); 846 attenr = ((255 - levr) >> 2) | ((levr && !sc->sc_dac.off) ? 0 : 0x80); 847 IW_WRITE_CODEC_1(CLDACI, attenl); 848 IW_WRITE_CODEC_1(CRDACI, attenr); 849 sc->sc_dac.voll = levl & 0xfc; 850 sc->sc_dac.volr = levr & 0xfc; 851 break; 852 case IW_LOOPBACK: 853 attenl = ((255 - levl) & 0xfc) | (levl ? 0x01 : 0); 854 IW_WRITE_CODEC_1(CLCI, attenl); 855 sc->sc_loopback.voll = levl & 0xfc; 856 break; 857 case IW_LINE_IN: 858 gainl = (levl >> 3) | (levl ? 0 : 0x80); 859 gainr = (levr >> 3) | (levr ? 0 : 0x80); 860 IW_WRITE_CODEC_1(CLLICI, gainl); 861 IW_WRITE_CODEC_1(CRLICI, gainr); 862 sc->sc_linein.voll = levl & 0xf8; 863 sc->sc_linein.volr = levr & 0xf8; 864 break; 865 case IW_MIC_IN: 866 gainl = ((255 - levl) >> 3) | (levl ? 0 : 0x80); 867 gainr = ((255 - levr) >> 3) | (levr ? 0 : 0x80); 868 IW_WRITE_CODEC_1(CLMICI, gainl); 869 IW_WRITE_CODEC_1(CRMICI, gainr); 870 sc->sc_mic.voll = levl & 0xf8; 871 sc->sc_mic.volr = levr & 0xf8; 872 break; 873 case IW_LINE_OUT: 874 attenl = ((255 - levl) >> 3) | (levl ? 0 : 0x80); 875 attenr = ((255 - levr) >> 3) | (levr ? 0 : 0x80); 876 IW_WRITE_CODEC_1(CLOAI, attenl); 877 IW_WRITE_CODEC_1(CROAI, attenr); 878 sc->sc_lineout.voll = levl & 0xf8; 879 sc->sc_lineout.volr = levr & 0xf8; 880 break; 881 case IW_MONO_IN: 882 attenl = ((255 - levl) >> 4) | (levl ? 0 : 0xc0); /* in/out mute */ 883 IW_WRITE_CODEC_1(CMONOI, attenl); 884 sc->sc_monoin.voll = levl & 0xf0; 885 break; 886 } 887 } 888 889 int 890 iw_commit_settings(void *addr) 891 { 892 893 return 0; 894 } 895 896 void 897 iw_trigger_dma(struct iw_softc *sc, u_char io) 898 { 899 u_char reg; 900 901 IW_READ_CODEC_1(CSR3I, reg); 902 IW_WRITE_CODEC_1(CSR3I, reg & ~(io == IW_DMA_PLAYBACK ? 0x10 : 0x20)); 903 904 IW_READ_CODEC_1(CFIG1I, reg); 905 906 IW_WRITE_CODEC_1(CFIG1I, reg | io); 907 908 /* let the counter run */ 909 IW_READ_CODEC_1(CFIG2I, reg); 910 IW_WRITE_CODEC_1(CFIG2I, reg & ~(io << 4)); 911 } 912 913 void 914 iw_stop_dma(struct iw_softc *sc, u_char io, u_char hard) 915 { 916 u_char reg; 917 918 /* just stop the counter, no need to flush the fifo */ 919 IW_READ_CODEC_1(CFIG2I, reg); 920 IW_WRITE_CODEC_1(CFIG2I, (reg | (io << 4))); 921 922 if (hard) { 923 /* unless we're closing the device */ 924 IW_READ_CODEC_1(CFIG1I, reg); 925 IW_WRITE_CODEC_1(CFIG1I, reg & ~io); 926 } 927 } 928 929 void 930 iw_dma_count(struct iw_softc *sc, u_short count, int io) 931 { 932 933 if (io == IW_DMA_PLAYBACK) { 934 IW_WRITE_CODEC_1(CLPCTI, (u_char) (count & 0x00ff)); 935 IW_WRITE_CODEC_1(CUPCTI, (u_char) ((count >> 8) & 0x00ff)); 936 } else { 937 IW_WRITE_CODEC_1(CLRCTI, (u_char) (count & 0x00ff)); 938 IW_WRITE_CODEC_1(CURCTI, (u_char) ((count >> 8) & 0x00ff)); 939 } 940 } 941 942 int 943 iw_init_output(void *addr, void *sbuf, int cc) 944 { 945 struct iw_softc *sc = (struct iw_softc *) addr; 946 947 DPRINTF(("iw_init_output\n")); 948 949 isa_dmastart(sc->sc_ic, sc->sc_playdrq, sbuf, 950 cc, NULL, DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT); 951 return 0; 952 } 953 954 int 955 iw_init_input(void *addr, void *sbuf, int cc) 956 { 957 struct iw_softc *sc; 958 959 DPRINTF(("iw_init_input\n")); 960 sc = (struct iw_softc *) addr; 961 isa_dmastart(sc->sc_ic, sc->sc_recdrq, sbuf, 962 cc, NULL, DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT); 963 return 0; 964 } 965 966 967 int 968 iw_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 969 { 970 struct iw_softc *sc; 971 972 #ifdef DIAGNOSTIC 973 if (!intr) { 974 printf("iw_start_output: no callback!\n"); 975 return 1; 976 } 977 #endif 978 sc = addr; 979 sc->sc_playintr = intr; 980 sc->sc_playarg = arg; 981 sc->sc_dma_flags |= DMAMODE_WRITE; 982 sc->sc_playdma_bp = p; 983 984 isa_dmastart(sc->sc_ic, sc->sc_playdrq, sc->sc_playdma_bp, 985 cc, NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT); 986 987 988 if (sc->play_encoding == AUDIO_ENCODING_ADPCM) 989 cc >>= 2; 990 if (sc->play_precision == 16) 991 cc >>= 1; 992 993 if (sc->play_channels == 2 && sc->play_encoding != AUDIO_ENCODING_ADPCM) 994 cc >>= 1; 995 996 cc -= iw_cc; 997 998 /* iw_dma_access(sc,1); */ 999 if (cc != sc->sc_playdma_cnt) { 1000 iw_dma_count(sc, (u_short) cc, IW_DMA_PLAYBACK); 1001 sc->sc_playdma_cnt = cc; 1002 1003 iw_trigger_dma(sc, IW_DMA_PLAYBACK); 1004 } 1005 1006 #ifdef DIAGNOSTIC 1007 if (outputs != iw_ints) 1008 printf("iw_start_output: out %d, int %d\n", outputs, iw_ints); 1009 outputs++; 1010 #endif 1011 1012 return 0; 1013 } 1014 1015 1016 int 1017 iw_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg) 1018 { 1019 struct iw_softc *sc; 1020 1021 #ifdef DIAGNOSTIC 1022 if (!intr) { 1023 printf("iw_start_input: no callback!\n"); 1024 return 1; 1025 } 1026 #endif 1027 sc = addr; 1028 sc->sc_recintr = intr; 1029 sc->sc_recarg = arg; 1030 sc->sc_dma_flags |= DMAMODE_READ; 1031 sc->sc_recdma_bp = p; 1032 1033 isa_dmastart(sc->sc_ic, sc->sc_recdrq, sc->sc_recdma_bp, 1034 cc, NULL, DMAMODE_READ, BUS_DMA_NOWAIT); 1035 1036 1037 if (sc->rec_encoding == AUDIO_ENCODING_ADPCM) 1038 cc >>= 2; 1039 if (sc->rec_precision == 16) 1040 cc >>= 1; 1041 1042 if (sc->rec_channels == 2 && sc->rec_encoding != AUDIO_ENCODING_ADPCM) 1043 cc >>= 1; 1044 1045 cc -= iw_cc; 1046 1047 /* iw_dma_access(sc,0); */ 1048 if (sc->sc_recdma_cnt != cc) { 1049 iw_dma_count(sc, (u_short) cc, IW_DMA_RECORD); 1050 sc->sc_recdma_cnt = cc; 1051 /* iw_dma_ctrl(sc, IW_DMA_RECORD); */ 1052 iw_trigger_dma(sc, IW_DMA_RECORD); 1053 } 1054 1055 #ifdef DIAGNOSTIC 1056 if ((inputs != iw_inints)) 1057 printf("iw_start_input: in %d, inints %d\n", inputs, iw_inints); 1058 inputs++; 1059 #endif 1060 1061 return 0; 1062 } 1063 1064 1065 int 1066 iw_halt_output(void *addr) 1067 { 1068 struct iw_softc *sc; 1069 1070 sc = addr; 1071 iw_stop_dma(sc, IW_DMA_PLAYBACK, 0); 1072 return 0; 1073 } 1074 1075 1076 int 1077 iw_halt_input(void *addr) 1078 { 1079 struct iw_softc *sc; 1080 1081 sc = addr; 1082 iw_stop_dma(sc, IW_DMA_RECORD, 0); 1083 return 0; 1084 } 1085 1086 int 1087 iw_speaker_ctl(void *addr, int newstate) 1088 { 1089 struct iw_softc *sc; 1090 u_char reg; 1091 1092 sc = addr; 1093 if (newstate == SPKR_ON) { 1094 sc->sc_dac.off = 0; 1095 IW_READ_CODEC_1(CLDACI, reg); 1096 IW_WRITE_CODEC_1(CLDACI, reg & 0x7f); 1097 IW_READ_CODEC_1(CRDACI, reg); 1098 IW_WRITE_CODEC_1(CRDACI, reg & 0x7f); 1099 } else { 1100 /* SPKR_OFF */ 1101 sc->sc_dac.off = 1; 1102 IW_READ_CODEC_1(CLDACI, reg); 1103 IW_WRITE_CODEC_1(CLDACI, reg | 0x80); 1104 IW_READ_CODEC_1(CRDACI, reg); 1105 IW_WRITE_CODEC_1(CRDACI, reg | 0x80); 1106 } 1107 return 0; 1108 } 1109 1110 int 1111 iw_getdev(void *addr, struct audio_device *retp) 1112 { 1113 1114 *retp = iw_device; 1115 return 0; 1116 } 1117 1118 int 1119 iw_setfd(void *addr, int flag) 1120 { 1121 1122 return 0; 1123 } 1124 1125 /* Mixer (in/out ports) */ 1126 int 1127 iw_set_port(void *addr, mixer_ctrl_t *cp) 1128 { 1129 struct iw_softc *sc; 1130 u_char vall, valr; 1131 int error; 1132 1133 sc = addr; 1134 vall = 0; 1135 valr = 0; 1136 error = EINVAL; 1137 switch (cp->dev) { 1138 case IW_MIC_IN_LVL: 1139 if (cp->type == AUDIO_MIXER_VALUE) { 1140 error = 0; 1141 if (cp->un.value.num_channels == 1) { 1142 vall = valr = cp->un.value.level[0]; 1143 } else { 1144 vall = cp->un.value.level[0]; 1145 valr = cp->un.value.level[1]; 1146 } 1147 sc->sc_mic.voll = vall; 1148 sc->sc_mic.volr = valr; 1149 iw_mixer_line_level(sc, IW_MIC_IN, vall, valr); 1150 } 1151 break; 1152 case IW_AUX1_LVL: 1153 if (cp->type == AUDIO_MIXER_VALUE) { 1154 error = 0; 1155 if (cp->un.value.num_channels == 1) { 1156 vall = valr = cp->un.value.level[0]; 1157 } else { 1158 vall = cp->un.value.level[0]; 1159 valr = cp->un.value.level[1]; 1160 } 1161 sc->sc_aux1.voll = vall; 1162 sc->sc_aux1.volr = valr; 1163 iw_mixer_line_level(sc, IW_AUX1, vall, valr); 1164 } 1165 break; 1166 case IW_AUX2_LVL: 1167 if (cp->type == AUDIO_MIXER_VALUE) { 1168 error = 0; 1169 if (cp->un.value.num_channels == 1) { 1170 vall = valr = cp->un.value.level[0]; 1171 } else { 1172 vall = cp->un.value.level[0]; 1173 valr = cp->un.value.level[1]; 1174 } 1175 sc->sc_aux2.voll = vall; 1176 sc->sc_aux2.volr = valr; 1177 iw_mixer_line_level(sc, IW_AUX2, vall, valr); 1178 } 1179 break; 1180 case IW_LINE_IN_LVL: 1181 if (cp->type == AUDIO_MIXER_VALUE) { 1182 error = 0; 1183 if (cp->un.value.num_channels == 1) { 1184 vall = valr = cp->un.value.level[0]; 1185 } else { 1186 vall = cp->un.value.level[0]; 1187 valr = cp->un.value.level[1]; 1188 } 1189 sc->sc_linein.voll = vall; 1190 sc->sc_linein.volr = valr; 1191 iw_mixer_line_level(sc, IW_LINE_IN, vall, valr); 1192 } 1193 break; 1194 case IW_LINE_OUT_LVL: 1195 if (cp->type == AUDIO_MIXER_VALUE) { 1196 error = 0; 1197 if (cp->un.value.num_channels == 1) { 1198 vall = valr = cp->un.value.level[0]; 1199 } else { 1200 vall = cp->un.value.level[0]; 1201 valr = cp->un.value.level[1]; 1202 } 1203 sc->sc_lineout.voll = vall; 1204 sc->sc_lineout.volr = valr; 1205 iw_mixer_line_level(sc, IW_LINE_OUT, vall, valr); 1206 } 1207 break; 1208 case IW_REC_LVL: 1209 if (cp->type == AUDIO_MIXER_VALUE) { 1210 error = 0; 1211 if (cp->un.value.num_channels == 1) { 1212 vall = valr = cp->un.value.level[0]; 1213 } else { 1214 vall = cp->un.value.level[0]; 1215 valr = cp->un.value.level[1]; 1216 } 1217 sc->sc_rec.voll = vall; 1218 sc->sc_rec.volr = valr; 1219 iw_mixer_line_level(sc, IW_REC, vall, valr); 1220 } 1221 break; 1222 1223 case IW_DAC_LVL: 1224 if (cp->type == AUDIO_MIXER_VALUE) { 1225 error = 0; 1226 if (cp->un.value.num_channels == 1) { 1227 vall = valr = cp->un.value.level[0]; 1228 } else { 1229 vall = cp->un.value.level[0]; 1230 valr = cp->un.value.level[1]; 1231 } 1232 sc->sc_dac.voll = vall; 1233 sc->sc_dac.volr = valr; 1234 iw_mixer_line_level(sc, IW_DAC, vall, valr); 1235 } 1236 break; 1237 1238 case IW_LOOPBACK_LVL: 1239 if (cp->type == AUDIO_MIXER_VALUE) { 1240 error = 0; 1241 if (cp->un.value.num_channels != 1) { 1242 return EINVAL; 1243 } else { 1244 valr = vall = cp->un.value.level[0]; 1245 } 1246 sc->sc_loopback.voll = vall; 1247 sc->sc_loopback.volr = valr; 1248 iw_mixer_line_level(sc, IW_LOOPBACK, vall, valr); 1249 } 1250 break; 1251 1252 case IW_MONO_IN_LVL: 1253 if (cp->type == AUDIO_MIXER_VALUE) { 1254 error = 0; 1255 if (cp->un.value.num_channels != 1) { 1256 return EINVAL; 1257 } else { 1258 valr = vall = cp->un.value.level[0]; 1259 } 1260 sc->sc_monoin.voll = vall; 1261 sc->sc_monoin.volr = valr; 1262 iw_mixer_line_level(sc, IW_MONO_IN, vall, valr); 1263 } 1264 break; 1265 case IW_RECORD_SOURCE: 1266 error = 0; 1267 sc->sc_recsrcbits = cp->un.ord << 6; 1268 DPRINTF(("record source %d bits %x\n", cp->un.ord, sc->sc_recsrcbits)); 1269 iw_mixer_line_level(sc, IW_REC, sc->sc_rec.voll, sc->sc_rec.volr); 1270 break; 1271 } 1272 1273 return error; 1274 } 1275 1276 1277 int 1278 iw_get_port(void *addr, mixer_ctrl_t *cp) 1279 { 1280 struct iw_softc *sc; 1281 int error; 1282 1283 sc = addr; 1284 error = EINVAL; 1285 switch (cp->dev) { 1286 case IW_MIC_IN_LVL: 1287 if (cp->type == AUDIO_MIXER_VALUE) { 1288 cp->un.value.num_channels = 2; 1289 cp->un.value.level[0] = sc->sc_mic.voll; 1290 cp->un.value.level[1] = sc->sc_mic.volr; 1291 error = 0; 1292 } 1293 break; 1294 case IW_AUX1_LVL: 1295 if (cp->type == AUDIO_MIXER_VALUE) { 1296 cp->un.value.num_channels = 2; 1297 cp->un.value.level[0] = sc->sc_aux1.voll; 1298 cp->un.value.level[1] = sc->sc_aux1.volr; 1299 error = 0; 1300 } 1301 break; 1302 case IW_AUX2_LVL: 1303 if (cp->type == AUDIO_MIXER_VALUE) { 1304 cp->un.value.num_channels = 2; 1305 cp->un.value.level[0] = sc->sc_aux2.voll; 1306 cp->un.value.level[1] = sc->sc_aux2.volr; 1307 error = 0; 1308 } 1309 break; 1310 case IW_LINE_OUT_LVL: 1311 if (cp->type == AUDIO_MIXER_VALUE) { 1312 cp->un.value.num_channels = 2; 1313 cp->un.value.level[0] = sc->sc_lineout.voll; 1314 cp->un.value.level[1] = sc->sc_lineout.volr; 1315 error = 0; 1316 } 1317 break; 1318 case IW_LINE_IN_LVL: 1319 if (cp->type == AUDIO_MIXER_VALUE) { 1320 cp->un.value.num_channels = 2; 1321 cp->un.value.level[0] = sc->sc_linein.voll; 1322 cp->un.value.level[1] = sc->sc_linein.volr; 1323 error = 0; 1324 } 1325 case IW_REC_LVL: 1326 if (cp->type == AUDIO_MIXER_VALUE) { 1327 cp->un.value.num_channels = 2; 1328 cp->un.value.level[0] = sc->sc_rec.voll; 1329 cp->un.value.level[1] = sc->sc_rec.volr; 1330 error = 0; 1331 } 1332 break; 1333 1334 case IW_DAC_LVL: 1335 if (cp->type == AUDIO_MIXER_VALUE) { 1336 cp->un.value.num_channels = 2; 1337 cp->un.value.level[0] = sc->sc_dac.voll; 1338 cp->un.value.level[1] = sc->sc_dac.volr; 1339 error = 0; 1340 } 1341 break; 1342 1343 case IW_LOOPBACK_LVL: 1344 if (cp->type == AUDIO_MIXER_VALUE) { 1345 cp->un.value.num_channels = 1; 1346 cp->un.value.level[0] = sc->sc_loopback.voll; 1347 error = 0; 1348 } 1349 break; 1350 1351 case IW_MONO_IN_LVL: 1352 if (cp->type == AUDIO_MIXER_VALUE) { 1353 cp->un.value.num_channels = 1; 1354 cp->un.value.level[0] = sc->sc_monoin.voll; 1355 error = 0; 1356 } 1357 break; 1358 case IW_RECORD_SOURCE: 1359 cp->un.ord = sc->sc_recsrcbits >> 6; 1360 error = 0; 1361 break; 1362 } 1363 1364 return error; 1365 } 1366 1367 1368 1369 int 1370 iw_query_devinfo(void *addr, mixer_devinfo_t *dip) 1371 { 1372 1373 switch (dip->index) { 1374 case IW_MIC_IN_LVL: /* Microphone */ 1375 dip->type = AUDIO_MIXER_VALUE; 1376 dip->mixer_class = IW_INPUT_CLASS; 1377 dip->prev = AUDIO_MIXER_LAST; 1378 dip->next = AUDIO_MIXER_LAST; 1379 strcpy(dip->label.name, AudioNmicrophone); 1380 dip->un.v.num_channels = 2; 1381 strcpy(dip->un.v.units.name, AudioNvolume); 1382 break; 1383 case IW_AUX1_LVL: 1384 dip->type = AUDIO_MIXER_VALUE; 1385 dip->mixer_class = IW_INPUT_CLASS; 1386 dip->prev = AUDIO_MIXER_LAST; 1387 dip->next = AUDIO_MIXER_LAST; 1388 strcpy(dip->label.name, AudioNline); 1389 dip->un.v.num_channels = 2; 1390 strcpy(dip->un.v.units.name, AudioNvolume); 1391 break; 1392 case IW_AUX2_LVL: 1393 dip->type = AUDIO_MIXER_VALUE; 1394 dip->mixer_class = IW_INPUT_CLASS; 1395 dip->prev = AUDIO_MIXER_LAST; 1396 dip->next = AUDIO_MIXER_LAST; 1397 strcpy(dip->label.name, AudioNcd); 1398 dip->un.v.num_channels = 2; 1399 strcpy(dip->un.v.units.name, AudioNvolume); 1400 break; 1401 case IW_LINE_OUT_LVL: 1402 dip->type = AUDIO_MIXER_VALUE; 1403 dip->mixer_class = IW_OUTPUT_CLASS; 1404 dip->prev = AUDIO_MIXER_LAST; 1405 dip->next = AUDIO_MIXER_LAST; 1406 strcpy(dip->label.name, AudioNline); 1407 dip->un.v.num_channels = 2; 1408 strcpy(dip->un.v.units.name, AudioNvolume); 1409 break; 1410 case IW_DAC_LVL: 1411 dip->type = AUDIO_MIXER_VALUE; 1412 dip->mixer_class = IW_OUTPUT_CLASS; 1413 dip->prev = AUDIO_MIXER_LAST; 1414 dip->next = AUDIO_MIXER_LAST; 1415 strcpy(dip->label.name, AudioNdac); 1416 dip->un.v.num_channels = 2; 1417 strcpy(dip->un.v.units.name, AudioNvolume); 1418 break; 1419 case IW_LINE_IN_LVL: 1420 dip->type = AUDIO_MIXER_VALUE; 1421 dip->mixer_class = IW_INPUT_CLASS; 1422 dip->prev = AUDIO_MIXER_LAST; 1423 dip->next = AUDIO_MIXER_LAST; 1424 strcpy(dip->label.name, AudioNinput); 1425 dip->un.v.num_channels = 2; 1426 strcpy(dip->un.v.units.name, AudioNvolume); 1427 break; 1428 case IW_MONO_IN_LVL: 1429 dip->type = AUDIO_MIXER_VALUE; 1430 dip->mixer_class = IW_INPUT_CLASS; 1431 dip->prev = AUDIO_MIXER_LAST; 1432 dip->next = AUDIO_MIXER_LAST; 1433 strcpy(dip->label.name, AudioNmono); 1434 dip->un.v.num_channels = 1; 1435 strcpy(dip->un.v.units.name, AudioNvolume); 1436 break; 1437 1438 case IW_REC_LVL: /* record level */ 1439 dip->type = AUDIO_MIXER_VALUE; 1440 dip->mixer_class = IW_RECORD_CLASS; 1441 dip->prev = AUDIO_MIXER_LAST; 1442 dip->next = AUDIO_MIXER_LAST; 1443 strcpy(dip->label.name, AudioNrecord); 1444 dip->un.v.num_channels = 2; 1445 strcpy(dip->un.v.units.name, AudioNvolume); 1446 break; 1447 1448 case IW_LOOPBACK_LVL: 1449 dip->type = AUDIO_MIXER_VALUE; 1450 dip->mixer_class = IW_RECORD_CLASS; 1451 dip->prev = AUDIO_MIXER_LAST; 1452 dip->next = AUDIO_MIXER_LAST; 1453 strcpy(dip->label.name, "filter"); 1454 dip->un.v.num_channels = 1; 1455 strcpy(dip->un.v.units.name, AudioNvolume); 1456 break; 1457 1458 case IW_RECORD_SOURCE: 1459 dip->mixer_class = IW_RECORD_CLASS; 1460 dip->type = AUDIO_MIXER_ENUM; 1461 dip->prev = AUDIO_MIXER_LAST; 1462 dip->next = AUDIO_MIXER_LAST; 1463 strcpy(dip->label.name, AudioNsource); 1464 dip->un.e.num_mem = 4; 1465 strcpy(dip->un.e.member[0].label.name, AudioNline); 1466 dip->un.e.member[0].ord = IW_LINE_IN_SRC; 1467 strcpy(dip->un.e.member[1].label.name, "aux1"); 1468 dip->un.e.member[1].ord = IW_AUX1_SRC; 1469 strcpy(dip->un.e.member[2].label.name, AudioNmicrophone); 1470 dip->un.e.member[2].ord = IW_MIC_IN_SRC; 1471 strcpy(dip->un.e.member[3].label.name, AudioNmixerout); 1472 dip->un.e.member[3].ord = IW_MIX_OUT_SRC; 1473 break; 1474 case IW_INPUT_CLASS: 1475 dip->type = AUDIO_MIXER_CLASS; 1476 dip->mixer_class = IW_INPUT_CLASS; 1477 dip->next = dip->prev = AUDIO_MIXER_LAST; 1478 strcpy(dip->label.name, AudioCinputs); 1479 break; 1480 case IW_OUTPUT_CLASS: 1481 dip->type = AUDIO_MIXER_CLASS; 1482 dip->mixer_class = IW_OUTPUT_CLASS; 1483 dip->next = dip->prev = AUDIO_MIXER_LAST; 1484 strcpy(dip->label.name, AudioCoutputs); 1485 break; 1486 case IW_RECORD_CLASS: /* record source class */ 1487 dip->type = AUDIO_MIXER_CLASS; 1488 dip->mixer_class = IW_RECORD_CLASS; 1489 dip->next = dip->prev = AUDIO_MIXER_LAST; 1490 strcpy(dip->label.name, AudioCrecord); 1491 return 0; 1492 default: 1493 return ENXIO; 1494 } 1495 return 0; 1496 } 1497 1498 1499 void * 1500 iw_malloc(void *addr, int direction, size_t size) 1501 { 1502 struct iw_softc *sc; 1503 int drq; 1504 1505 sc = addr; 1506 if (direction == AUMODE_PLAY) 1507 drq = sc->sc_playdrq; 1508 else 1509 drq = sc->sc_recdrq; 1510 return isa_malloc(sc->sc_ic, drq, size, M_DEVBUF, M_WAITOK); 1511 } 1512 1513 void 1514 iw_free(void *addr, void *ptr, size_t size) 1515 { 1516 1517 isa_free(ptr, M_DEVBUF); 1518 } 1519 1520 size_t 1521 iw_round_buffersize(void *addr, int direction, size_t size) 1522 { 1523 struct iw_softc *sc; 1524 bus_size_t maxsize; 1525 1526 sc = addr; 1527 if (direction == AUMODE_PLAY) 1528 maxsize = sc->sc_play_maxsize; 1529 else 1530 maxsize = sc->sc_rec_maxsize; 1531 1532 if (size > maxsize) 1533 size = maxsize; 1534 return size; 1535 } 1536 1537 paddr_t 1538 iw_mappage(void *addr, void *mem, off_t off, int prot) 1539 { 1540 1541 return isa_mappage(mem, off, prot); 1542 } 1543 1544 int 1545 iw_get_props(void *addr) 1546 { 1547 struct iw_softc *sc; 1548 1549 sc = addr; 1550 return AUDIO_PROP_MMAP | 1551 (sc->sc_fullduplex ? AUDIO_PROP_FULLDUPLEX : 0); 1552 } 1553 1554 void 1555 iw_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread) 1556 { 1557 struct iw_softc *sc; 1558 1559 sc = addr; 1560 *intr = &sc->sc_intr_lock; 1561 *thread = &sc->sc_lock; 1562 } 1563