1 /* $OpenBSD: sbdsp.c,v 1.32 2012/03/30 08:18:19 ratchov Exp $ */ 2 3 /* 4 * Copyright (c) 1991-1993 Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the Computer Systems 18 * Engineering Group at Lawrence Berkeley Laboratory. 19 * 4. Neither the name of the University nor of the Laboratory may be used 20 * to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 */ 36 37 /* 38 * SoundBlaster Pro code provided by John Kohl, based on lots of 39 * information he gleaned from Steve Haehnichen <steve@vigra.com>'s 40 * SBlast driver for 386BSD and DOS driver code from Daniel Sachs 41 * <sachs@meibm15.cen.uiuc.edu>. 42 * Lots of rewrites by Lennart Augustsson <augustss@cs.chalmers.se> 43 * with information from SB "Hardware Programming Guide" and the 44 * Linux drivers. 45 */ 46 47 #include "midi.h" 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/errno.h> 52 #include <sys/ioctl.h> 53 #include <sys/syslog.h> 54 #include <sys/device.h> 55 #include <sys/proc.h> 56 #include <sys/buf.h> 57 58 #include <machine/cpu.h> 59 #include <machine/intr.h> 60 #include <machine/bus.h> 61 62 #include <sys/audioio.h> 63 #include <dev/audio_if.h> 64 #include <dev/midi_if.h> 65 #include <dev/mulaw.h> 66 #include <dev/auconv.h> 67 68 #include <dev/isa/isavar.h> 69 #include <dev/isa/isadmavar.h> 70 71 #include <dev/isa/sbreg.h> 72 #include <dev/isa/sbdspvar.h> 73 74 75 #ifdef AUDIO_DEBUG 76 #define DPRINTF(x) if (sbdspdebug) printf x 77 #define DPRINTFN(n,x) if (sbdspdebug >= (n)) printf x 78 int sbdspdebug = 0; 79 #else 80 #define DPRINTF(x) 81 #define DPRINTFN(n,x) 82 #endif 83 84 #ifndef SBDSP_NPOLL 85 #define SBDSP_NPOLL 3000 86 #endif 87 88 struct { 89 int wdsp; 90 int rdsp; 91 int wmidi; 92 } sberr; 93 94 /* 95 * Time constant routines follow. See SBK, section 12. 96 * Although they don't come out and say it (in the docs), 97 * the card clearly uses a 1MHz countdown timer, as the 98 * low-speed formula (p. 12-4) is: 99 * tc = 256 - 10^6 / sr 100 * In high-speed mode, the constant is the upper byte of a 16-bit counter, 101 * and a 256MHz clock is used: 102 * tc = 65536 - 256 * 10^ 6 / sr 103 * Since we can only use the upper byte of the HS TC, the two formulae 104 * are equivalent. (Why didn't they say so?) E.g., 105 * (65536 - 256 * 10 ^ 6 / x) >> 8 = 256 - 10^6 / x 106 * 107 * The crossover point (from low- to high-speed modes) is different 108 * for the SBPRO and SB20. The table on p. 12-5 gives the following data: 109 * 110 * SBPRO SB20 111 * ----- -------- 112 * input ls min 4 KHz 4 KHz 113 * input ls max 23 KHz 13 KHz 114 * input hs max 44.1 KHz 15 KHz 115 * output ls min 4 KHz 4 KHz 116 * output ls max 23 KHz 23 KHz 117 * output hs max 44.1 KHz 44.1 KHz 118 */ 119 /* XXX Should we round the tc? 120 #define SB_RATE_TO_TC(x) (((65536 - 256 * 1000000 / (x)) + 128) >> 8) 121 */ 122 #define SB_RATE_TO_TC(x) (256 - 1000000 / (x)) 123 #define SB_TC_TO_RATE(tc) (1000000 / (256 - (tc))) 124 125 struct sbmode { 126 short model; 127 u_char channels; 128 u_char precision; 129 u_short lowrate, highrate; 130 u_char cmd; 131 u_char cmdchan; 132 }; 133 static struct sbmode sbpmodes[] = { 134 { SB_1, 1, 8, 4000, 22727, SB_DSP_WDMA }, 135 { SB_20, 1, 8, 4000, 22727, SB_DSP_WDMA_LOOP }, 136 { SB_2x, 1, 8, 4000, 22727, SB_DSP_WDMA_LOOP }, 137 { SB_2x, 1, 8, 22727, 45454, SB_DSP_HS_OUTPUT }, 138 { SB_PRO, 1, 8, 4000, 22727, SB_DSP_WDMA_LOOP }, 139 { SB_PRO, 1, 8, 22727, 45454, SB_DSP_HS_OUTPUT }, 140 { SB_PRO, 2, 8, 11025, 22727, SB_DSP_HS_OUTPUT }, 141 /* Yes, we write the record mode to set 16-bit playback mode. weird, huh? */ 142 { SB_JAZZ, 1, 8, 4000, 22727, SB_DSP_WDMA_LOOP, SB_DSP_RECORD_MONO }, 143 { SB_JAZZ, 1, 8, 22727, 45454, SB_DSP_HS_OUTPUT, SB_DSP_RECORD_MONO }, 144 { SB_JAZZ, 2, 8, 11025, 22727, SB_DSP_HS_OUTPUT, SB_DSP_RECORD_STEREO }, 145 { SB_JAZZ, 1, 16, 4000, 22727, SB_DSP_WDMA_LOOP, JAZZ16_RECORD_MONO }, 146 { SB_JAZZ, 1, 16, 22727, 45454, SB_DSP_HS_OUTPUT, JAZZ16_RECORD_MONO }, 147 { SB_JAZZ, 2, 16, 11025, 22727, SB_DSP_HS_OUTPUT, JAZZ16_RECORD_STEREO }, 148 { SB_16, 1, 8, 5000, 45000, SB_DSP16_WDMA_8 }, 149 { SB_16, 2, 8, 5000, 45000, SB_DSP16_WDMA_8 }, 150 #define PLAY16 15 /* must be the index of the next entry in the table */ 151 { SB_16, 1, 16, 5000, 45000, SB_DSP16_WDMA_16 }, 152 { SB_16, 2, 16, 5000, 45000, SB_DSP16_WDMA_16 }, 153 { -1 } 154 }; 155 static struct sbmode sbrmodes[] = { 156 { SB_1, 1, 8, 4000, 12987, SB_DSP_RDMA }, 157 { SB_20, 1, 8, 4000, 12987, SB_DSP_RDMA_LOOP }, 158 { SB_2x, 1, 8, 4000, 12987, SB_DSP_RDMA_LOOP }, 159 { SB_2x, 1, 8, 12987, 14925, SB_DSP_HS_INPUT }, 160 { SB_PRO, 1, 8, 4000, 22727, SB_DSP_RDMA_LOOP, SB_DSP_RECORD_MONO }, 161 { SB_PRO, 1, 8, 22727, 45454, SB_DSP_HS_INPUT, SB_DSP_RECORD_MONO }, 162 { SB_PRO, 2, 8, 11025, 22727, SB_DSP_HS_INPUT, SB_DSP_RECORD_STEREO }, 163 { SB_JAZZ, 1, 8, 4000, 22727, SB_DSP_RDMA_LOOP, SB_DSP_RECORD_MONO }, 164 { SB_JAZZ, 1, 8, 22727, 45454, SB_DSP_HS_INPUT, SB_DSP_RECORD_MONO }, 165 { SB_JAZZ, 2, 8, 11025, 22727, SB_DSP_HS_INPUT, SB_DSP_RECORD_STEREO }, 166 { SB_JAZZ, 1, 16, 4000, 22727, SB_DSP_RDMA_LOOP, JAZZ16_RECORD_MONO }, 167 { SB_JAZZ, 1, 16, 22727, 45454, SB_DSP_HS_INPUT, JAZZ16_RECORD_MONO }, 168 { SB_JAZZ, 2, 16, 11025, 22727, SB_DSP_HS_INPUT, JAZZ16_RECORD_STEREO }, 169 { SB_16, 1, 8, 5000, 45000, SB_DSP16_RDMA_8 }, 170 { SB_16, 2, 8, 5000, 45000, SB_DSP16_RDMA_8 }, 171 { SB_16, 1, 16, 5000, 45000, SB_DSP16_RDMA_16 }, 172 { SB_16, 2, 16, 5000, 45000, SB_DSP16_RDMA_16 }, 173 { -1 } 174 }; 175 176 void sbversion(struct sbdsp_softc *); 177 void sbdsp_jazz16_probe(struct sbdsp_softc *); 178 void sbdsp_set_mixer_gain(struct sbdsp_softc *sc, int port); 179 void sbdsp_to(void *); 180 void sbdsp_pause(struct sbdsp_softc *); 181 int sbdsp_set_timeconst(struct sbdsp_softc *, int); 182 int sbdsp16_set_rate(struct sbdsp_softc *, int, int); 183 int sbdsp_set_in_ports(struct sbdsp_softc *, int); 184 void sbdsp_set_ifilter(void *, int); 185 int sbdsp_get_ifilter(void *); 186 187 int sbdsp_block_output(void *); 188 int sbdsp_block_input(void *); 189 static int sbdsp_adjust(int, int); 190 191 int sbdsp_midi_intr(void *); 192 193 #ifdef AUDIO_DEBUG 194 void sb_printsc(struct sbdsp_softc *); 195 196 void 197 sb_printsc(sc) 198 struct sbdsp_softc *sc; 199 { 200 int i; 201 202 printf("open %d dmachan %d/%d %d/%d iobase 0x%x irq %d\n", 203 (int)sc->sc_open, sc->sc_i.run, sc->sc_o.run, 204 sc->sc_drq8, sc->sc_drq16, 205 sc->sc_iobase, sc->sc_irq); 206 printf("irate %d itc %x orate %d otc %x\n", 207 sc->sc_i.rate, sc->sc_i.tc, 208 sc->sc_o.rate, sc->sc_o.tc); 209 printf("spkron %u nintr %lu\n", 210 sc->spkr_state, sc->sc_interrupts); 211 printf("intr8 %p arg8 %p\n", 212 sc->sc_intr8, sc->sc_arg16); 213 printf("intr16 %p arg16 %p\n", 214 sc->sc_intr8, sc->sc_arg16); 215 printf("gain:"); 216 for (i = 0; i < SB_NDEVS; i++) 217 printf(" %u,%u", sc->gain[i][SB_LEFT], sc->gain[i][SB_RIGHT]); 218 printf("\n"); 219 } 220 #endif /* AUDIO_DEBUG */ 221 222 /* 223 * Probe / attach routines. 224 */ 225 226 /* 227 * Probe for the soundblaster hardware. 228 */ 229 int 230 sbdsp_probe(sc) 231 struct sbdsp_softc *sc; 232 { 233 234 if (sbdsp_reset(sc) < 0) { 235 DPRINTF(("sbdsp: couldn't reset card\n")); 236 return 0; 237 } 238 /* if flags set, go and probe the jazz16 stuff */ 239 if (sc->sc_dev.dv_cfdata->cf_flags & 1) 240 sbdsp_jazz16_probe(sc); 241 else 242 sbversion(sc); 243 if (sc->sc_model == SB_UNK) { 244 /* Unknown SB model found. */ 245 DPRINTF(("sbdsp: unknown SB model found\n")); 246 return 0; 247 } 248 return 1; 249 } 250 251 /* 252 * Try add-on stuff for Jazz16. 253 */ 254 void 255 sbdsp_jazz16_probe(sc) 256 struct sbdsp_softc *sc; 257 { 258 static u_char jazz16_irq_conf[16] = { 259 -1, -1, 0x02, 0x03, 260 -1, 0x01, -1, 0x04, 261 -1, 0x02, 0x05, -1, 262 -1, -1, -1, 0x06}; 263 static u_char jazz16_drq_conf[8] = { 264 -1, 0x01, -1, 0x02, 265 -1, 0x03, -1, 0x04}; 266 267 bus_space_tag_t iot = sc->sc_iot; 268 bus_space_handle_t ioh; 269 270 sbversion(sc); 271 272 DPRINTF(("jazz16 probe\n")); 273 274 if (bus_space_map(iot, JAZZ16_CONFIG_PORT, 1, 0, &ioh)) { 275 DPRINTF(("bus map failed\n")); 276 return; 277 } 278 279 if (jazz16_drq_conf[sc->sc_drq8] == (u_char)-1 || 280 jazz16_irq_conf[sc->sc_irq] == (u_char)-1) { 281 DPRINTF(("drq/irq check failed\n")); 282 goto done; /* give up, we can't do it. */ 283 } 284 285 bus_space_write_1(iot, ioh, 0, JAZZ16_WAKEUP); 286 delay(10000); /* delay 10 ms */ 287 bus_space_write_1(iot, ioh, 0, JAZZ16_SETBASE); 288 bus_space_write_1(iot, ioh, 0, sc->sc_iobase & 0x70); 289 290 if (sbdsp_reset(sc) < 0) { 291 DPRINTF(("sbdsp_reset check failed\n")); 292 goto done; /* XXX? what else could we do? */ 293 } 294 295 if (sbdsp_wdsp(sc, JAZZ16_READ_VER)) { 296 DPRINTF(("read16 setup failed\n")); 297 goto done; 298 } 299 300 if (sbdsp_rdsp(sc) != JAZZ16_VER_JAZZ) { 301 DPRINTF(("read16 failed\n")); 302 goto done; 303 } 304 305 /* XXX set both 8 & 16-bit drq to same channel, it works fine. */ 306 sc->sc_drq16 = sc->sc_drq8; 307 if (sbdsp_wdsp(sc, JAZZ16_SET_DMAINTR) || 308 sbdsp_wdsp(sc, (jazz16_drq_conf[sc->sc_drq16] << 4) | 309 jazz16_drq_conf[sc->sc_drq8]) || 310 sbdsp_wdsp(sc, jazz16_irq_conf[sc->sc_irq])) { 311 DPRINTF(("sbdsp: can't write jazz16 probe stuff\n")); 312 } else { 313 DPRINTF(("jazz16 detected!\n")); 314 sc->sc_model = SB_JAZZ; 315 sc->sc_mixer_model = SBM_CT1345; /* XXX really? */ 316 } 317 318 done: 319 bus_space_unmap(iot, ioh, 1); 320 } 321 322 /* 323 * Attach hardware to driver, attach hardware driver to audio 324 * pseudo-device driver . 325 */ 326 void 327 sbdsp_attach(sc) 328 struct sbdsp_softc *sc; 329 { 330 struct audio_params pparams, rparams; 331 int i; 332 u_int v; 333 334 /* 335 * Create our DMA maps. 336 */ 337 if (sc->sc_drq8 != -1) { 338 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq8, 339 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 340 printf("%s: can't create map for drq %d\n", 341 sc->sc_dev.dv_xname, sc->sc_drq8); 342 return; 343 } 344 } 345 if (sc->sc_drq16 != -1 && sc->sc_drq16 != sc->sc_drq8) { 346 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq16, 347 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) { 348 printf("%s: can't create map for drq %d\n", 349 sc->sc_dev.dv_xname, sc->sc_drq16); 350 return; 351 } 352 } 353 354 pparams = audio_default; 355 rparams = audio_default; 356 sbdsp_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams); 357 358 sbdsp_set_in_ports(sc, 1 << SB_MIC_VOL); 359 360 if (sc->sc_mixer_model != SBM_NONE) { 361 /* Reset the mixer.*/ 362 sbdsp_mix_write(sc, SBP_MIX_RESET, SBP_MIX_RESET); 363 /* And set our own default values */ 364 for (i = 0; i < SB_NDEVS; i++) { 365 switch(i) { 366 case SB_MIC_VOL: 367 case SB_LINE_IN_VOL: 368 v = 0; 369 break; 370 case SB_BASS: 371 case SB_TREBLE: 372 v = SB_ADJUST_GAIN(sc, AUDIO_MAX_GAIN/2); 373 break; 374 case SB_CD_IN_MUTE: 375 case SB_MIC_IN_MUTE: 376 case SB_LINE_IN_MUTE: 377 case SB_MIDI_IN_MUTE: 378 case SB_CD_SWAP: 379 case SB_MIC_SWAP: 380 case SB_LINE_SWAP: 381 case SB_MIDI_SWAP: 382 case SB_CD_OUT_MUTE: 383 case SB_MIC_OUT_MUTE: 384 case SB_LINE_OUT_MUTE: 385 v = 0; 386 break; 387 default: 388 v = SB_ADJUST_GAIN(sc, AUDIO_MAX_GAIN / 2); 389 break; 390 } 391 sc->gain[i][SB_LEFT] = sc->gain[i][SB_RIGHT] = v; 392 sbdsp_set_mixer_gain(sc, i); 393 } 394 sc->in_filter = 0; /* no filters turned on, please */ 395 } 396 397 printf(": dsp v%d.%02d%s\n", 398 SBVER_MAJOR(sc->sc_version), SBVER_MINOR(sc->sc_version), 399 sc->sc_model == SB_JAZZ ? ": <Jazz16>" : ""); 400 401 timeout_set(&sc->sc_tmo, sbdsp_to, sbdsp_to); 402 sc->sc_fullduplex = ISSB16CLASS(sc) && 403 sc->sc_drq8 != -1 && sc->sc_drq16 != -1 && 404 sc->sc_drq8 != sc->sc_drq16; 405 } 406 407 void 408 sbdsp_mix_write(sc, mixerport, val) 409 struct sbdsp_softc *sc; 410 int mixerport; 411 int val; 412 { 413 bus_space_tag_t iot = sc->sc_iot; 414 bus_space_handle_t ioh = sc->sc_ioh; 415 int s; 416 417 s = splaudio(); 418 bus_space_write_1(iot, ioh, SBP_MIXER_ADDR, mixerport); 419 delay(20); 420 bus_space_write_1(iot, ioh, SBP_MIXER_DATA, val); 421 delay(30); 422 splx(s); 423 } 424 425 int 426 sbdsp_mix_read(sc, mixerport) 427 struct sbdsp_softc *sc; 428 int mixerport; 429 { 430 bus_space_tag_t iot = sc->sc_iot; 431 bus_space_handle_t ioh = sc->sc_ioh; 432 int val; 433 int s; 434 435 s = splaudio(); 436 bus_space_write_1(iot, ioh, SBP_MIXER_ADDR, mixerport); 437 delay(20); 438 val = bus_space_read_1(iot, ioh, SBP_MIXER_DATA); 439 delay(30); 440 splx(s); 441 return val; 442 } 443 444 /* 445 * Various routines to interface to higher level audio driver 446 */ 447 448 int 449 sbdsp_query_encoding(addr, fp) 450 void *addr; 451 struct audio_encoding *fp; 452 { 453 struct sbdsp_softc *sc = addr; 454 int emul, found = 0; 455 456 emul = ISSB16CLASS(sc) ? 0 : AUDIO_ENCODINGFLAG_EMULATED; 457 458 switch (fp->index) { 459 case 0: 460 strlcpy(fp->name, AudioEulinear, sizeof fp->name); 461 fp->encoding = AUDIO_ENCODING_ULINEAR; 462 fp->precision = 8; 463 fp->flags = 0; 464 found = 1; 465 break; 466 case 1: 467 strlcpy(fp->name, AudioEmulaw, sizeof fp->name); 468 fp->encoding = AUDIO_ENCODING_ULAW; 469 fp->precision = 8; 470 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 471 found = 1; 472 break; 473 case 2: 474 strlcpy(fp->name, AudioEalaw, sizeof fp->name); 475 fp->encoding = AUDIO_ENCODING_ALAW; 476 fp->precision = 8; 477 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 478 found = 1; 479 break; 480 case 3: 481 strlcpy(fp->name, AudioEslinear, sizeof fp->name); 482 fp->encoding = AUDIO_ENCODING_SLINEAR; 483 fp->precision = 8; 484 fp->flags = emul; 485 found = 1; 486 break; 487 } 488 if (found) { 489 fp->bps = 1; 490 fp->msb = 1; 491 return 0; 492 } else if (!ISSB16CLASS(sc) && sc->sc_model != SB_JAZZ) 493 return EINVAL; 494 495 switch(fp->index) { 496 case 4: 497 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); 498 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 499 fp->precision = 16; 500 fp->flags = 0; 501 break; 502 case 5: 503 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); 504 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 505 fp->precision = 16; 506 fp->flags = emul; 507 break; 508 case 6: 509 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); 510 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 511 fp->precision = 16; 512 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 513 break; 514 case 7: 515 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); 516 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 517 fp->precision = 16; 518 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 519 break; 520 default: 521 return EINVAL; 522 } 523 fp->bps = 2; 524 fp->msb = 1; 525 return 0; 526 } 527 528 int 529 sbdsp_set_params(addr, setmode, usemode, play, rec) 530 void *addr; 531 int setmode, usemode; 532 struct audio_params *play, *rec; 533 { 534 struct sbdsp_softc *sc = addr; 535 struct sbmode *m; 536 u_int rate, tc, bmode; 537 void (*swcode)(void *, u_char *buf, int cnt); 538 int factor; 539 int model; 540 int chan; 541 struct audio_params *p; 542 int mode; 543 544 if (sc->sc_open == SB_OPEN_MIDI) 545 return EBUSY; 546 547 model = sc->sc_model; 548 if (model > SB_16) 549 model = SB_16; /* later models work like SB16 */ 550 551 /* 552 * Prior to the SB16, we have only one clock, so make the sample 553 * rates match. 554 */ 555 if (!ISSB16CLASS(sc) && 556 play->sample_rate != rec->sample_rate && 557 usemode == (AUMODE_PLAY | AUMODE_RECORD)) { 558 if (setmode == AUMODE_PLAY) { 559 rec->sample_rate = play->sample_rate; 560 setmode |= AUMODE_RECORD; 561 } else if (setmode == AUMODE_RECORD) { 562 play->sample_rate = rec->sample_rate; 563 setmode |= AUMODE_PLAY; 564 } else 565 return (EINVAL); 566 } 567 568 /* Set first record info, then play info */ 569 for (mode = AUMODE_RECORD; mode != -1; 570 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 571 if ((setmode & mode) == 0) 572 continue; 573 574 p = mode == AUMODE_PLAY ? play : rec; 575 576 switch (model) { 577 case SB_1: 578 case SB_20: 579 if (mode == AUMODE_PLAY) { 580 if (p->sample_rate < 4000) 581 p->sample_rate = 4000; 582 else if (p->sample_rate > 22727) 583 p->sample_rate = 22727; /* 22050 ? */ 584 } else { 585 if (p->sample_rate < 4000) 586 p->sample_rate = 4000; 587 else if (p->sample_rate > 12987) 588 p->sample_rate = 12987; 589 } 590 break; 591 case SB_2x: 592 if (mode == AUMODE_PLAY) { 593 if (p->sample_rate < 4000) 594 p->sample_rate = 4000; 595 else if (p->sample_rate > 45454) 596 p->sample_rate = 45454; /* 44100 ? */ 597 } else { 598 if (p->sample_rate < 4000) 599 p->sample_rate = 4000; 600 else if (p->sample_rate > 14925) 601 p->sample_rate = 14925; /* ??? */ 602 } 603 break; 604 case SB_PRO: 605 case SB_JAZZ: 606 if (p->channels == 2) { 607 if (p->sample_rate < 11025) 608 p->sample_rate = 11025; 609 else if (p->sample_rate > 22727) 610 p->sample_rate = 22727; /* 22050 ? */ 611 } else { 612 if (p->sample_rate < 4000) 613 p->sample_rate = 4000; 614 else if (p->sample_rate > 45454) 615 p->sample_rate = 45454; /* 44100 ? */ 616 } 617 break; 618 case SB_16: 619 if (p->sample_rate < 5000) 620 p->sample_rate = 5000; 621 else if (p->sample_rate > 45000) 622 p->sample_rate = 45000; /* 44100 ? */ 623 break; 624 } 625 626 /* Locate proper commands */ 627 for(m = mode == AUMODE_PLAY ? sbpmodes : sbrmodes; 628 m->model != -1; m++) { 629 if (model == m->model && 630 p->channels == m->channels && 631 p->precision == m->precision && 632 p->sample_rate >= m->lowrate && 633 p->sample_rate <= m->highrate) 634 break; 635 } 636 if (m->model == -1) 637 return EINVAL; 638 rate = p->sample_rate; 639 swcode = 0; 640 factor = 1; 641 tc = 1; 642 bmode = -1; 643 if (model == SB_16) { 644 switch (p->encoding) { 645 case AUDIO_ENCODING_SLINEAR_BE: 646 if (p->precision == 16) 647 swcode = swap_bytes; 648 /* fall into */ 649 case AUDIO_ENCODING_SLINEAR_LE: 650 bmode = SB_BMODE_SIGNED; 651 break; 652 case AUDIO_ENCODING_ULINEAR_BE: 653 if (p->precision == 16) 654 swcode = swap_bytes; 655 /* fall into */ 656 case AUDIO_ENCODING_ULINEAR_LE: 657 bmode = SB_BMODE_UNSIGNED; 658 break; 659 case AUDIO_ENCODING_ULAW: 660 if (mode == AUMODE_PLAY) { 661 swcode = mulaw_to_ulinear16_le; 662 factor = 2; 663 m = &sbpmodes[PLAY16]; 664 } else 665 swcode = ulinear8_to_mulaw; 666 bmode = SB_BMODE_UNSIGNED; 667 break; 668 case AUDIO_ENCODING_ALAW: 669 if (mode == AUMODE_PLAY) { 670 swcode = alaw_to_ulinear16_le; 671 factor = 2; 672 m = &sbpmodes[PLAY16]; 673 } else 674 swcode = ulinear8_to_alaw; 675 bmode = SB_BMODE_UNSIGNED; 676 break; 677 default: 678 return EINVAL; 679 } 680 if (p->channels == 2) 681 bmode |= SB_BMODE_STEREO; 682 } else if (m->model == SB_JAZZ && m->precision == 16) { 683 switch (p->encoding) { 684 case AUDIO_ENCODING_SLINEAR_LE: 685 break; 686 case AUDIO_ENCODING_ULINEAR_LE: 687 swcode = change_sign16_le; 688 break; 689 case AUDIO_ENCODING_SLINEAR_BE: 690 swcode = swap_bytes; 691 break; 692 case AUDIO_ENCODING_ULINEAR_BE: 693 swcode = mode == AUMODE_PLAY ? 694 swap_bytes_change_sign16_le : change_sign16_swap_bytes_le; 695 break; 696 case AUDIO_ENCODING_ULAW: 697 swcode = mode == AUMODE_PLAY ? 698 mulaw_to_ulinear8 : ulinear8_to_mulaw; 699 break; 700 case AUDIO_ENCODING_ALAW: 701 swcode = mode == AUMODE_PLAY ? 702 alaw_to_ulinear8 : ulinear8_to_alaw; 703 break; 704 default: 705 return EINVAL; 706 } 707 tc = SB_RATE_TO_TC(p->sample_rate * p->channels); 708 p->sample_rate = SB_TC_TO_RATE(tc) / p->channels; 709 } else { 710 switch (p->encoding) { 711 case AUDIO_ENCODING_SLINEAR_BE: 712 case AUDIO_ENCODING_SLINEAR_LE: 713 swcode = change_sign8; 714 break; 715 case AUDIO_ENCODING_ULINEAR_BE: 716 case AUDIO_ENCODING_ULINEAR_LE: 717 break; 718 case AUDIO_ENCODING_ULAW: 719 swcode = mode == AUMODE_PLAY ? 720 mulaw_to_ulinear8 : ulinear8_to_mulaw; 721 break; 722 case AUDIO_ENCODING_ALAW: 723 swcode = mode == AUMODE_PLAY ? 724 alaw_to_ulinear8 : ulinear8_to_alaw; 725 break; 726 default: 727 return EINVAL; 728 } 729 tc = SB_RATE_TO_TC(p->sample_rate * p->channels); 730 p->sample_rate = SB_TC_TO_RATE(tc) / p->channels; 731 } 732 733 chan = m->precision == 16 ? sc->sc_drq16 : sc->sc_drq8; 734 if (mode == AUMODE_PLAY) { 735 sc->sc_o.rate = rate; 736 sc->sc_o.tc = tc; 737 sc->sc_o.modep = m; 738 sc->sc_o.bmode = bmode; 739 sc->sc_o.dmachan = chan; 740 } else { 741 sc->sc_i.rate = rate; 742 sc->sc_i.tc = tc; 743 sc->sc_i.modep = m; 744 sc->sc_i.bmode = bmode; 745 sc->sc_i.dmachan = chan; 746 } 747 748 p->sw_code = swcode; 749 p->factor = factor; 750 p->bps = AUDIO_BPS(p->precision); 751 p->msb = 1; 752 DPRINTF(("sbdsp_set_params: model=%d, mode=%d, rate=%ld, prec=%d, chan=%d, enc=%d -> tc=%02x, cmd=%02x, bmode=%02x, cmdchan=%02x, swcode=%p, factor=%d\n", 753 sc->sc_model, mode, p->sample_rate, p->precision, p->channels, 754 p->encoding, tc, m->cmd, bmode, m->cmdchan, swcode, factor)); 755 756 } 757 758 /* 759 * XXX 760 * Should wait for chip to be idle. 761 */ 762 sc->sc_i.run = SB_NOTRUNNING; 763 sc->sc_o.run = SB_NOTRUNNING; 764 765 if (sc->sc_fullduplex && 766 usemode == (AUMODE_PLAY | AUMODE_RECORD) && 767 sc->sc_i.dmachan == sc->sc_o.dmachan) { 768 DPRINTF(("sbdsp_set_params: fd=%d, usemode=%d, idma=%d, odma=%d\n", sc->sc_fullduplex, usemode, sc->sc_i.dmachan, sc->sc_o.dmachan)); 769 if (sc->sc_o.dmachan == sc->sc_drq8) { 770 /* Use 16 bit DMA for playing by expanding the samples. */ 771 play->sw_code = linear8_to_linear16_le; 772 play->factor = 2; 773 sc->sc_o.modep = &sbpmodes[PLAY16]; 774 sc->sc_o.dmachan = sc->sc_drq16; 775 } else { 776 return EINVAL; 777 } 778 } 779 DPRINTF(("sbdsp_set_params ichan=%d, ochan=%d\n", 780 sc->sc_i.dmachan, sc->sc_o.dmachan)); 781 782 return 0; 783 } 784 785 void 786 sbdsp_set_ifilter(addr, which) 787 void *addr; 788 int which; 789 { 790 struct sbdsp_softc *sc = addr; 791 int mixval; 792 793 mixval = sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_IFILTER_MASK; 794 switch (which) { 795 case 0: 796 mixval |= SBP_FILTER_OFF; 797 break; 798 case SB_TREBLE: 799 mixval |= SBP_FILTER_ON | SBP_IFILTER_HIGH; 800 break; 801 case SB_BASS: 802 mixval |= SBP_FILTER_ON | SBP_IFILTER_LOW; 803 break; 804 default: 805 return; 806 } 807 sc->in_filter = mixval & SBP_IFILTER_MASK; 808 sbdsp_mix_write(sc, SBP_INFILTER, mixval); 809 } 810 811 int 812 sbdsp_get_ifilter(addr) 813 void *addr; 814 { 815 struct sbdsp_softc *sc = addr; 816 817 sc->in_filter = 818 sbdsp_mix_read(sc, SBP_INFILTER) & SBP_IFILTER_MASK; 819 switch (sc->in_filter) { 820 case SBP_FILTER_ON|SBP_IFILTER_HIGH: 821 return SB_TREBLE; 822 case SBP_FILTER_ON|SBP_IFILTER_LOW: 823 return SB_BASS; 824 default: 825 return 0; 826 } 827 } 828 829 int 830 sbdsp_set_in_ports(sc, mask) 831 struct sbdsp_softc *sc; 832 int mask; 833 { 834 int bitsl, bitsr; 835 int sbport; 836 837 if (sc->sc_open == SB_OPEN_MIDI) 838 return EBUSY; 839 840 DPRINTF(("sbdsp_set_in_ports: model=%d, mask=%x\n", 841 sc->sc_mixer_model, mask)); 842 843 switch(sc->sc_mixer_model) { 844 case SBM_NONE: 845 return EINVAL; 846 case SBM_CT1335: 847 if (mask != (1 << SB_MIC_VOL)) 848 return EINVAL; 849 break; 850 case SBM_CT1345: 851 switch (mask) { 852 case 1 << SB_MIC_VOL: 853 sbport = SBP_FROM_MIC; 854 break; 855 case 1 << SB_LINE_IN_VOL: 856 sbport = SBP_FROM_LINE; 857 break; 858 case 1 << SB_CD_VOL: 859 sbport = SBP_FROM_CD; 860 break; 861 default: 862 return (EINVAL); 863 } 864 sbdsp_mix_write(sc, SBP_RECORD_SOURCE, sbport | sc->in_filter); 865 break; 866 case SBM_CT1XX5: 867 case SBM_CT1745: 868 if (mask & ~((1<<SB_MIDI_VOL) | (1<<SB_LINE_IN_VOL) | 869 (1<<SB_CD_VOL) | (1<<SB_MIC_VOL))) 870 return EINVAL; 871 bitsr = 0; 872 if (mask & (1<<SB_MIDI_VOL)) bitsr |= SBP_MIDI_SRC_R; 873 if (mask & (1<<SB_LINE_IN_VOL)) bitsr |= SBP_LINE_SRC_R; 874 if (mask & (1<<SB_CD_VOL)) bitsr |= SBP_CD_SRC_R; 875 bitsl = SB_SRC_R_TO_L(bitsr); 876 if (mask & (1<<SB_MIC_VOL)) { 877 bitsl |= SBP_MIC_SRC; 878 bitsr |= SBP_MIC_SRC; 879 } 880 sbdsp_mix_write(sc, SBP_RECORD_SOURCE_L, bitsl); 881 sbdsp_mix_write(sc, SBP_RECORD_SOURCE_R, bitsr); 882 break; 883 } 884 sc->in_mask = mask; 885 886 return 0; 887 } 888 889 int 890 sbdsp_speaker_ctl(addr, newstate) 891 void *addr; 892 int newstate; 893 { 894 struct sbdsp_softc *sc = addr; 895 896 if (sc->sc_open == SB_OPEN_MIDI) 897 return EBUSY; 898 899 if ((newstate == SPKR_ON) && 900 (sc->spkr_state == SPKR_OFF)) { 901 sbdsp_spkron(sc); 902 sc->spkr_state = SPKR_ON; 903 } 904 if ((newstate == SPKR_OFF) && 905 (sc->spkr_state == SPKR_ON)) { 906 sbdsp_spkroff(sc); 907 sc->spkr_state = SPKR_OFF; 908 } 909 return 0; 910 } 911 912 int 913 sbdsp_round_blocksize(addr, blk) 914 void *addr; 915 int blk; 916 { 917 return (blk + 3) & -4; /* round to biggest sample size */ 918 } 919 920 int 921 sbdsp_open(addr, flags) 922 void *addr; 923 int flags; 924 { 925 struct sbdsp_softc *sc = addr; 926 927 DPRINTF(("sbdsp_open: sc=%p\n", sc)); 928 929 if (sc->sc_open != SB_CLOSED) 930 return EBUSY; 931 if (sbdsp_reset(sc) != 0) 932 return EIO; 933 934 sc->sc_open = SB_OPEN_AUDIO; 935 sc->sc_openflags = flags; 936 sc->sc_intrm = 0; 937 if (ISSBPRO(sc) && 938 sbdsp_wdsp(sc, SB_DSP_RECORD_MONO) < 0) { 939 DPRINTF(("sbdsp_open: can't set mono mode\n")); 940 /* we'll readjust when it's time for DMA. */ 941 } 942 943 /* 944 * Leave most things as they were; users must change things if 945 * the previous process didn't leave it they way they wanted. 946 * Looked at another way, it's easy to set up a configuration 947 * in one program and leave it for another to inherit. 948 */ 949 DPRINTF(("sbdsp_open: opened\n")); 950 951 return 0; 952 } 953 954 void 955 sbdsp_close(addr) 956 void *addr; 957 { 958 struct sbdsp_softc *sc = addr; 959 960 DPRINTF(("sbdsp_close: sc=%p\n", sc)); 961 962 sc->sc_open = SB_CLOSED; 963 sbdsp_spkroff(sc); 964 sc->spkr_state = SPKR_OFF; 965 sc->sc_intr8 = 0; 966 sc->sc_intr16 = 0; 967 sc->sc_intrm = 0; 968 sbdsp_haltdma(sc); 969 970 DPRINTF(("sbdsp_close: closed\n")); 971 } 972 973 /* 974 * Lower-level routines 975 */ 976 977 /* 978 * Reset the card. 979 * Return non-zero if the card isn't detected. 980 */ 981 int 982 sbdsp_reset(sc) 983 struct sbdsp_softc *sc; 984 { 985 bus_space_tag_t iot = sc->sc_iot; 986 bus_space_handle_t ioh = sc->sc_ioh; 987 988 sc->sc_intr8 = 0; 989 sc->sc_intr16 = 0; 990 if (sc->sc_i.run != SB_NOTRUNNING) { 991 isa_dmaabort(sc->sc_isa, sc->sc_i.dmachan); 992 sc->sc_i.run = SB_NOTRUNNING; 993 } 994 if (sc->sc_o.run != SB_NOTRUNNING) { 995 isa_dmaabort(sc->sc_isa, sc->sc_o.dmachan); 996 sc->sc_o.run = SB_NOTRUNNING; 997 } 998 999 /* 1000 * See SBK, section 11.3. 1001 * We pulse a reset signal into the card. 1002 * Gee, what a brilliant hardware design. 1003 */ 1004 bus_space_write_1(iot, ioh, SBP_DSP_RESET, 1); 1005 delay(10); 1006 bus_space_write_1(iot, ioh, SBP_DSP_RESET, 0); 1007 delay(30); 1008 if (sbdsp_rdsp(sc) != SB_MAGIC) 1009 return -1; 1010 1011 return 0; 1012 } 1013 1014 /* 1015 * Write a byte to the dsp. 1016 * We are at the mercy of the card as we use a 1017 * polling loop and wait until it can take the byte. 1018 */ 1019 int 1020 sbdsp_wdsp(sc, v) 1021 struct sbdsp_softc *sc; 1022 int v; 1023 { 1024 bus_space_tag_t iot = sc->sc_iot; 1025 bus_space_handle_t ioh = sc->sc_ioh; 1026 int i; 1027 u_char x; 1028 1029 for (i = SBDSP_NPOLL; --i >= 0; ) { 1030 x = bus_space_read_1(iot, ioh, SBP_DSP_WSTAT); 1031 delay(10); 1032 if ((x & SB_DSP_BUSY) == 0) { 1033 bus_space_write_1(iot, ioh, SBP_DSP_WRITE, v); 1034 delay(10); 1035 return 0; 1036 } 1037 } 1038 ++sberr.wdsp; 1039 return -1; 1040 } 1041 1042 /* 1043 * Read a byte from the DSP, using polling. 1044 */ 1045 int 1046 sbdsp_rdsp(sc) 1047 struct sbdsp_softc *sc; 1048 { 1049 bus_space_tag_t iot = sc->sc_iot; 1050 bus_space_handle_t ioh = sc->sc_ioh; 1051 int i; 1052 u_char x; 1053 1054 for (i = SBDSP_NPOLL; --i >= 0; ) { 1055 x = bus_space_read_1(iot, ioh, SBP_DSP_RSTAT); 1056 delay(10); 1057 if (x & SB_DSP_READY) { 1058 x = bus_space_read_1(iot, ioh, SBP_DSP_READ); 1059 delay(10); 1060 return x; 1061 } 1062 } 1063 ++sberr.rdsp; 1064 return -1; 1065 } 1066 1067 /* 1068 * Doing certain things (like toggling the speaker) make 1069 * the SB hardware go away for a while, so pause a little. 1070 */ 1071 void 1072 sbdsp_to(arg) 1073 void *arg; 1074 { 1075 wakeup(arg); 1076 } 1077 1078 void 1079 sbdsp_pause(sc) 1080 struct sbdsp_softc *sc; 1081 { 1082 timeout_add_msec(&sc->sc_tmo, 125); /* 8x per second */ 1083 (void)tsleep(sbdsp_to, PWAIT, "sbpause", 0); 1084 } 1085 1086 /* 1087 * Turn on the speaker. The SBK documention says this operation 1088 * can take up to 1/10 of a second. Higher level layers should 1089 * probably let the task sleep for this amount of time after 1090 * calling here. Otherwise, things might not work (because 1091 * sbdsp_wdsp() and sbdsp_rdsp() will probably timeout.) 1092 * 1093 * These engineers had their heads up their ass when 1094 * they designed this card. 1095 */ 1096 void 1097 sbdsp_spkron(sc) 1098 struct sbdsp_softc *sc; 1099 { 1100 (void)sbdsp_wdsp(sc, SB_DSP_SPKR_ON); 1101 sbdsp_pause(sc); 1102 } 1103 1104 /* 1105 * Turn off the speaker; see comment above. 1106 */ 1107 void 1108 sbdsp_spkroff(sc) 1109 struct sbdsp_softc *sc; 1110 { 1111 (void)sbdsp_wdsp(sc, SB_DSP_SPKR_OFF); 1112 sbdsp_pause(sc); 1113 } 1114 1115 /* 1116 * Read the version number out of the card. 1117 * Store version information in the softc. 1118 */ 1119 void 1120 sbversion(sc) 1121 struct sbdsp_softc *sc; 1122 { 1123 int v; 1124 1125 sc->sc_model = SB_UNK; 1126 sc->sc_version = 0; 1127 if (sbdsp_wdsp(sc, SB_DSP_VERSION) < 0) 1128 return; 1129 v = sbdsp_rdsp(sc) << 8; 1130 v |= sbdsp_rdsp(sc); 1131 if (v < 0) 1132 return; 1133 sc->sc_version = v; 1134 switch(SBVER_MAJOR(v)) { 1135 case 1: 1136 sc->sc_mixer_model = SBM_NONE; 1137 sc->sc_model = SB_1; 1138 break; 1139 case 2: 1140 /* Some SB2 have a mixer, some don't. */ 1141 sbdsp_mix_write(sc, SBP_1335_MASTER_VOL, 0x04); 1142 sbdsp_mix_write(sc, SBP_1335_MIDI_VOL, 0x06); 1143 /* Check if we can read back the mixer values. */ 1144 if ((sbdsp_mix_read(sc, SBP_1335_MASTER_VOL) & 0x0e) == 0x04 && 1145 (sbdsp_mix_read(sc, SBP_1335_MIDI_VOL) & 0x0e) == 0x06) 1146 sc->sc_mixer_model = SBM_CT1335; 1147 else 1148 sc->sc_mixer_model = SBM_NONE; 1149 if (SBVER_MINOR(v) == 0) 1150 sc->sc_model = SB_20; 1151 else 1152 sc->sc_model = SB_2x; 1153 break; 1154 case 3: 1155 sc->sc_mixer_model = SBM_CT1345; 1156 sc->sc_model = SB_PRO; 1157 break; 1158 case 4: 1159 #if 0 1160 /* XXX This does not work */ 1161 /* Most SB16 have a tone controls, but some don't. */ 1162 sbdsp_mix_write(sc, SB16P_TREBLE_L, 0x80); 1163 /* Check if we can read back the mixer value. */ 1164 if ((sbdsp_mix_read(sc, SB16P_TREBLE_L) & 0xf0) == 0x80) 1165 sc->sc_mixer_model = SBM_CT1745; 1166 else 1167 sc->sc_mixer_model = SBM_CT1XX5; 1168 #else 1169 sc->sc_mixer_model = SBM_CT1745; 1170 #endif 1171 #if 0 1172 /* XXX figure out a good way of determining the model */ 1173 /* XXX what about SB_32 */ 1174 if (SBVER_MINOR(v) == 16) 1175 sc->sc_model = SB_64; 1176 else 1177 #endif 1178 sc->sc_model = SB_16; 1179 break; 1180 } 1181 } 1182 1183 /* 1184 * Halt a DMA in progress. 1185 */ 1186 int 1187 sbdsp_haltdma(addr) 1188 void *addr; 1189 { 1190 struct sbdsp_softc *sc = addr; 1191 1192 DPRINTF(("sbdsp_haltdma: sc=%p\n", sc)); 1193 1194 sbdsp_reset(sc); 1195 return 0; 1196 } 1197 1198 int 1199 sbdsp_set_timeconst(sc, tc) 1200 struct sbdsp_softc *sc; 1201 int tc; 1202 { 1203 DPRINTF(("sbdsp_set_timeconst: sc=%p tc=%d\n", sc, tc)); 1204 1205 if (sbdsp_wdsp(sc, SB_DSP_TIMECONST) < 0 || 1206 sbdsp_wdsp(sc, tc) < 0) 1207 return EIO; 1208 1209 return 0; 1210 } 1211 1212 int 1213 sbdsp16_set_rate(sc, cmd, rate) 1214 struct sbdsp_softc *sc; 1215 int cmd, rate; 1216 { 1217 DPRINTF(("sbdsp16_set_rate: sc=%p cmd=0x%02x rate=%d\n", sc, cmd, rate)); 1218 1219 if (sbdsp_wdsp(sc, cmd) < 0 || 1220 sbdsp_wdsp(sc, rate >> 8) < 0 || 1221 sbdsp_wdsp(sc, rate) < 0) 1222 return EIO; 1223 return 0; 1224 } 1225 1226 int 1227 sbdsp_trigger_input(addr, start, end, blksize, intr, arg, param) 1228 void *addr; 1229 void *start, *end; 1230 int blksize; 1231 void (*intr)(void *); 1232 void *arg; 1233 struct audio_params *param; 1234 { 1235 struct sbdsp_softc *sc = addr; 1236 int stereo = param->channels == 2; 1237 int width = param->precision * param->factor; 1238 int filter; 1239 1240 #ifdef DIAGNOSTIC 1241 if (stereo && (blksize & 1)) { 1242 DPRINTF(("stereo record odd bytes (%d)\n", blksize)); 1243 return (EIO); 1244 } 1245 #endif 1246 1247 sc->sc_intrr = intr; 1248 sc->sc_argr = arg; 1249 1250 if (width == 8) { 1251 #ifdef DIAGNOSTIC 1252 if (sc->sc_i.dmachan != sc->sc_drq8) { 1253 printf("sbdsp_trigger_input: width=%d bad chan %d\n", 1254 width, sc->sc_i.dmachan); 1255 return (EIO); 1256 } 1257 #endif 1258 sc->sc_intr8 = sbdsp_block_input; 1259 sc->sc_arg8 = addr; 1260 } else { 1261 #ifdef DIAGNOSTIC 1262 if (sc->sc_i.dmachan != sc->sc_drq16) { 1263 printf("sbdsp_trigger_input: width=%d bad chan %d\n", 1264 width, sc->sc_i.dmachan); 1265 return (EIO); 1266 } 1267 #endif 1268 sc->sc_intr16 = sbdsp_block_input; 1269 sc->sc_arg16 = addr; 1270 } 1271 1272 if ((sc->sc_model == SB_JAZZ) ? (sc->sc_i.dmachan > 3) : (width == 16)) 1273 blksize >>= 1; 1274 --blksize; 1275 sc->sc_i.blksize = blksize; 1276 1277 if (ISSBPRO(sc)) { 1278 if (sbdsp_wdsp(sc, sc->sc_i.modep->cmdchan) < 0) 1279 return (EIO); 1280 filter = stereo ? SBP_FILTER_OFF : sc->in_filter; 1281 sbdsp_mix_write(sc, SBP_INFILTER, 1282 (sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_IFILTER_MASK) | 1283 filter); 1284 } 1285 1286 if (ISSB16CLASS(sc)) { 1287 if (sbdsp16_set_rate(sc, SB_DSP16_INPUTRATE, sc->sc_i.rate)) { 1288 DPRINTF(("sbdsp_trigger_input: rate=%d set failed\n", 1289 sc->sc_i.rate)); 1290 return (EIO); 1291 } 1292 } else { 1293 if (sbdsp_set_timeconst(sc, sc->sc_i.tc)) { 1294 DPRINTF(("sbdsp_trigger_input: tc=%d set failed\n", 1295 sc->sc_i.rate)); 1296 return (EIO); 1297 } 1298 } 1299 1300 DPRINTF(("sbdsp: dma start loop input start=%p end=%p chan=%d\n", 1301 start, end, sc->sc_i.dmachan)); 1302 isa_dmastart(sc->sc_isa, sc->sc_i.dmachan, start, (char *)end - 1303 (char *)start, NULL, DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT); 1304 1305 return sbdsp_block_input(addr); 1306 } 1307 1308 int 1309 sbdsp_block_input(addr) 1310 void *addr; 1311 { 1312 struct sbdsp_softc *sc = addr; 1313 int cc = sc->sc_i.blksize; 1314 1315 DPRINTFN(2, ("sbdsp_block_input: sc=%p cc=%d\n", addr, cc)); 1316 1317 if (sc->sc_i.run != SB_NOTRUNNING) 1318 sc->sc_intrr(sc->sc_argr); 1319 1320 if (sc->sc_model == SB_1) { 1321 /* Non-looping mode, start DMA */ 1322 if (sbdsp_wdsp(sc, sc->sc_i.modep->cmd) < 0 || 1323 sbdsp_wdsp(sc, cc) < 0 || 1324 sbdsp_wdsp(sc, cc >> 8) < 0) { 1325 DPRINTF(("sbdsp_block_input: SB1 DMA start failed\n")); 1326 return (EIO); 1327 } 1328 sc->sc_i.run = SB_RUNNING; 1329 } else if (sc->sc_i.run == SB_NOTRUNNING) { 1330 /* Initialize looping PCM */ 1331 if (ISSB16CLASS(sc)) { 1332 DPRINTFN(3, ("sbdsp16 input command cmd=0x%02x bmode=0x%02x cc=%d\n", 1333 sc->sc_i.modep->cmd, sc->sc_i.bmode, cc)); 1334 if (sbdsp_wdsp(sc, sc->sc_i.modep->cmd) < 0 || 1335 sbdsp_wdsp(sc, sc->sc_i.bmode) < 0 || 1336 sbdsp_wdsp(sc, cc) < 0 || 1337 sbdsp_wdsp(sc, cc >> 8) < 0) { 1338 DPRINTF(("sbdsp_block_input: SB16 DMA start failed\n")); 1339 return (EIO); 1340 } 1341 } else { 1342 DPRINTF(("sbdsp_block_input: set blocksize=%d\n", cc)); 1343 if (sbdsp_wdsp(sc, SB_DSP_BLOCKSIZE) < 0 || 1344 sbdsp_wdsp(sc, cc) < 0 || 1345 sbdsp_wdsp(sc, cc >> 8) < 0) { 1346 DPRINTF(("sbdsp_block_input: SB2 DMA blocksize failed\n")); 1347 return (EIO); 1348 } 1349 if (sbdsp_wdsp(sc, sc->sc_i.modep->cmd) < 0) { 1350 DPRINTF(("sbdsp_block_input: SB2 DMA start failed\n")); 1351 return (EIO); 1352 } 1353 } 1354 sc->sc_i.run = SB_LOOPING; 1355 } 1356 1357 return (0); 1358 } 1359 1360 int 1361 sbdsp_trigger_output(addr, start, end, blksize, intr, arg, param) 1362 void *addr; 1363 void *start, *end; 1364 int blksize; 1365 void (*intr)(void *); 1366 void *arg; 1367 struct audio_params *param; 1368 { 1369 struct sbdsp_softc *sc = addr; 1370 int stereo = param->channels == 2; 1371 int width = param->precision * param->factor; 1372 int cmd; 1373 1374 #ifdef DIAGNOSTIC 1375 if (stereo && (blksize & 1)) { 1376 DPRINTF(("stereo playback odd bytes (%d)\n", blksize)); 1377 return (EIO); 1378 } 1379 #endif 1380 1381 sc->sc_intrp = intr; 1382 sc->sc_argp = arg; 1383 1384 if (width == 8) { 1385 #ifdef DIAGNOSTIC 1386 if (sc->sc_o.dmachan != sc->sc_drq8) { 1387 printf("sbdsp_trigger_output: width=%d bad chan %d\n", 1388 width, sc->sc_o.dmachan); 1389 return (EIO); 1390 } 1391 #endif 1392 sc->sc_intr8 = sbdsp_block_output; 1393 sc->sc_arg8 = addr; 1394 } else { 1395 #ifdef DIAGNOSTIC 1396 if (sc->sc_o.dmachan != sc->sc_drq16) { 1397 printf("sbdsp_trigger_output: width=%d bad chan %d\n", 1398 width, sc->sc_o.dmachan); 1399 return (EIO); 1400 } 1401 #endif 1402 sc->sc_intr16 = sbdsp_block_output; 1403 sc->sc_arg16 = addr; 1404 } 1405 1406 if ((sc->sc_model == SB_JAZZ) ? (sc->sc_o.dmachan > 3) : (width == 16)) 1407 blksize >>= 1; 1408 --blksize; 1409 sc->sc_o.blksize = blksize; 1410 1411 if (ISSBPRO(sc)) { 1412 /* make sure we re-set stereo mixer bit when we start output. */ 1413 sbdsp_mix_write(sc, SBP_STEREO, 1414 (sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) | 1415 (stereo ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO)); 1416 cmd = sc->sc_o.modep->cmdchan; 1417 if (cmd && sbdsp_wdsp(sc, cmd) < 0) 1418 return (EIO); 1419 } 1420 1421 if (ISSB16CLASS(sc)) { 1422 if (sbdsp16_set_rate(sc, SB_DSP16_OUTPUTRATE, sc->sc_o.rate)) { 1423 DPRINTF(("sbdsp_trigger_output: rate=%d set failed\n", 1424 sc->sc_o.rate)); 1425 return (EIO); 1426 } 1427 } else { 1428 if (sbdsp_set_timeconst(sc, sc->sc_o.tc)) { 1429 DPRINTF(("sbdsp_trigger_output: tc=%d set failed\n", 1430 sc->sc_o.rate)); 1431 return (EIO); 1432 } 1433 } 1434 1435 DPRINTF(("sbdsp: dma start loop output start=%p end=%p chan=%d\n", 1436 start, end, sc->sc_o.dmachan)); 1437 isa_dmastart(sc->sc_isa, sc->sc_o.dmachan, start, (char *)end - 1438 (char *)start, NULL, DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT); 1439 1440 return sbdsp_block_output(addr); 1441 } 1442 1443 int 1444 sbdsp_block_output(addr) 1445 void *addr; 1446 { 1447 struct sbdsp_softc *sc = addr; 1448 int cc = sc->sc_o.blksize; 1449 1450 DPRINTFN(2, ("sbdsp_block_output: sc=%p cc=%d\n", addr, cc)); 1451 1452 if (sc->sc_o.run != SB_NOTRUNNING) 1453 sc->sc_intrp(sc->sc_argp); 1454 1455 if (sc->sc_model == SB_1) { 1456 /* Non-looping mode, initialized. Start DMA and PCM */ 1457 if (sbdsp_wdsp(sc, sc->sc_o.modep->cmd) < 0 || 1458 sbdsp_wdsp(sc, cc) < 0 || 1459 sbdsp_wdsp(sc, cc >> 8) < 0) { 1460 DPRINTF(("sbdsp_block_output: SB1 DMA start failed\n")); 1461 return (EIO); 1462 } 1463 sc->sc_o.run = SB_RUNNING; 1464 } else if (sc->sc_o.run == SB_NOTRUNNING) { 1465 /* Initialize looping PCM */ 1466 if (ISSB16CLASS(sc)) { 1467 DPRINTF(("sbdsp_block_output: SB16 cmd=0x%02x bmode=0x%02x cc=%d\n", 1468 sc->sc_o.modep->cmd,sc->sc_o.bmode, cc)); 1469 if (sbdsp_wdsp(sc, sc->sc_o.modep->cmd) < 0 || 1470 sbdsp_wdsp(sc, sc->sc_o.bmode) < 0 || 1471 sbdsp_wdsp(sc, cc) < 0 || 1472 sbdsp_wdsp(sc, cc >> 8) < 0) { 1473 DPRINTF(("sbdsp_block_output: SB16 DMA start failed\n")); 1474 return (EIO); 1475 } 1476 } else { 1477 DPRINTF(("sbdsp_block_output: set blocksize=%d\n", cc)); 1478 if (sbdsp_wdsp(sc, SB_DSP_BLOCKSIZE) < 0 || 1479 sbdsp_wdsp(sc, cc) < 0 || 1480 sbdsp_wdsp(sc, cc >> 8) < 0) { 1481 DPRINTF(("sbdsp_block_output: SB2 DMA blocksize failed\n")); 1482 return (EIO); 1483 } 1484 if (sbdsp_wdsp(sc, sc->sc_o.modep->cmd) < 0) { 1485 DPRINTF(("sbdsp_block_output: SB2 DMA start failed\n")); 1486 return (EIO); 1487 } 1488 } 1489 sc->sc_o.run = SB_LOOPING; 1490 } 1491 1492 return (0); 1493 } 1494 1495 /* 1496 * Only the DSP unit on the sound blaster generates interrupts. 1497 * There are three cases of interrupt: reception of a midi byte 1498 * (when mode is enabled), completion of dma transmission, or 1499 * completion of a dma reception. 1500 * 1501 * If there is interrupt sharing or a spurious interrupt occurs 1502 * there is no way to distinguish this on an SB2. So if you have 1503 * an SB2 and experience problems, buy an SB16 (it's only $40). 1504 */ 1505 int 1506 sbdsp_intr(arg) 1507 void *arg; 1508 { 1509 struct sbdsp_softc *sc = arg; 1510 u_char irq; 1511 1512 DPRINTFN(2, ("sbdsp_intr: intr8=%p, intr16=%p\n", 1513 sc->sc_intr8, sc->sc_intr16)); 1514 if (ISSB16CLASS(sc)) { 1515 irq = sbdsp_mix_read(sc, SBP_IRQ_STATUS); 1516 if ((irq & (SBP_IRQ_DMA8 | SBP_IRQ_DMA16 | SBP_IRQ_MPU401)) == 0) { 1517 DPRINTF(("sbdsp_intr: Spurious interrupt 0x%x\n", irq)); 1518 return 0; 1519 } 1520 } else { 1521 /* XXXX CHECK FOR INTERRUPT */ 1522 irq = SBP_IRQ_DMA8; 1523 } 1524 1525 sc->sc_interrupts++; 1526 delay(10); /* XXX why? */ 1527 1528 /* clear interrupt */ 1529 if (irq & SBP_IRQ_DMA8) { 1530 bus_space_read_1(sc->sc_iot, sc->sc_ioh, SBP_DSP_IRQACK8); 1531 if (sc->sc_intr8) 1532 sc->sc_intr8(sc->sc_arg8); 1533 } 1534 if (irq & SBP_IRQ_DMA16) { 1535 bus_space_read_1(sc->sc_iot, sc->sc_ioh, SBP_DSP_IRQACK16); 1536 if (sc->sc_intr16) 1537 sc->sc_intr16(sc->sc_arg16); 1538 } 1539 #if NMIDI > 0 1540 if ((irq & SBP_IRQ_MPU401) && sc->sc_hasmpu) { 1541 mpu_intr(&sc->sc_mpu_sc); 1542 } 1543 #endif 1544 return 1; 1545 } 1546 1547 /* Like val & mask, but make sure the result is correctly rounded. */ 1548 #define MAXVAL 256 1549 static int 1550 sbdsp_adjust(val, mask) 1551 int val, mask; 1552 { 1553 val += (MAXVAL - mask) >> 1; 1554 if (val >= MAXVAL) 1555 val = MAXVAL-1; 1556 return val & mask; 1557 } 1558 1559 void 1560 sbdsp_set_mixer_gain(sc, port) 1561 struct sbdsp_softc *sc; 1562 int port; 1563 { 1564 int src, gain; 1565 1566 switch(sc->sc_mixer_model) { 1567 case SBM_NONE: 1568 return; 1569 case SBM_CT1335: 1570 gain = SB_1335_GAIN(sc->gain[port][SB_LEFT]); 1571 switch(port) { 1572 case SB_MASTER_VOL: 1573 src = SBP_1335_MASTER_VOL; 1574 break; 1575 case SB_MIDI_VOL: 1576 src = SBP_1335_MIDI_VOL; 1577 break; 1578 case SB_CD_VOL: 1579 src = SBP_1335_CD_VOL; 1580 break; 1581 case SB_VOICE_VOL: 1582 src = SBP_1335_VOICE_VOL; 1583 gain = SB_1335_MASTER_GAIN(sc->gain[port][SB_LEFT]); 1584 break; 1585 default: 1586 return; 1587 } 1588 sbdsp_mix_write(sc, src, gain); 1589 break; 1590 case SBM_CT1345: 1591 gain = SB_STEREO_GAIN(sc->gain[port][SB_LEFT], 1592 sc->gain[port][SB_RIGHT]); 1593 switch (port) { 1594 case SB_MIC_VOL: 1595 src = SBP_MIC_VOL; 1596 gain = SB_MIC_GAIN(sc->gain[port][SB_LEFT]); 1597 break; 1598 case SB_MASTER_VOL: 1599 src = SBP_MASTER_VOL; 1600 break; 1601 case SB_LINE_IN_VOL: 1602 src = SBP_LINE_VOL; 1603 break; 1604 case SB_VOICE_VOL: 1605 src = SBP_VOICE_VOL; 1606 break; 1607 case SB_MIDI_VOL: 1608 src = SBP_MIDI_VOL; 1609 break; 1610 case SB_CD_VOL: 1611 src = SBP_CD_VOL; 1612 break; 1613 default: 1614 return; 1615 } 1616 sbdsp_mix_write(sc, src, gain); 1617 break; 1618 case SBM_CT1XX5: 1619 case SBM_CT1745: 1620 switch (port) { 1621 case SB_MIC_VOL: 1622 src = SB16P_MIC_L; 1623 break; 1624 case SB_MASTER_VOL: 1625 src = SB16P_MASTER_L; 1626 break; 1627 case SB_LINE_IN_VOL: 1628 src = SB16P_LINE_L; 1629 break; 1630 case SB_VOICE_VOL: 1631 src = SB16P_VOICE_L; 1632 break; 1633 case SB_MIDI_VOL: 1634 src = SB16P_MIDI_L; 1635 break; 1636 case SB_CD_VOL: 1637 src = SB16P_CD_L; 1638 break; 1639 case SB_INPUT_GAIN: 1640 src = SB16P_INPUT_GAIN_L; 1641 break; 1642 case SB_OUTPUT_GAIN: 1643 src = SB16P_OUTPUT_GAIN_L; 1644 break; 1645 case SB_TREBLE: 1646 src = SB16P_TREBLE_L; 1647 break; 1648 case SB_BASS: 1649 src = SB16P_BASS_L; 1650 break; 1651 case SB_PCSPEAKER: 1652 sbdsp_mix_write(sc, SB16P_PCSPEAKER, sc->gain[port][SB_LEFT]); 1653 return; 1654 default: 1655 return; 1656 } 1657 sbdsp_mix_write(sc, src, sc->gain[port][SB_LEFT]); 1658 sbdsp_mix_write(sc, SB16P_L_TO_R(src), sc->gain[port][SB_RIGHT]); 1659 break; 1660 } 1661 } 1662 1663 int 1664 sbdsp_mixer_set_port(addr, cp) 1665 void *addr; 1666 mixer_ctrl_t *cp; 1667 { 1668 struct sbdsp_softc *sc = addr; 1669 int lgain, rgain; 1670 int mask, bits; 1671 int lmask, rmask, lbits, rbits; 1672 int mute, swap; 1673 1674 if (sc->sc_open == SB_OPEN_MIDI) 1675 return EBUSY; 1676 1677 DPRINTF(("sbdsp_mixer_set_port: port=%d num_channels=%d\n", cp->dev, 1678 cp->un.value.num_channels)); 1679 1680 if (sc->sc_mixer_model == SBM_NONE) 1681 return EINVAL; 1682 1683 switch (cp->dev) { 1684 case SB_TREBLE: 1685 case SB_BASS: 1686 if (sc->sc_mixer_model == SBM_CT1345 || 1687 sc->sc_mixer_model == SBM_CT1XX5) { 1688 if (cp->type != AUDIO_MIXER_ENUM) 1689 return EINVAL; 1690 switch (cp->dev) { 1691 case SB_TREBLE: 1692 sbdsp_set_ifilter(addr, cp->un.ord ? SB_TREBLE : 0); 1693 return 0; 1694 case SB_BASS: 1695 sbdsp_set_ifilter(addr, cp->un.ord ? SB_BASS : 0); 1696 return 0; 1697 } 1698 } 1699 case SB_PCSPEAKER: 1700 case SB_INPUT_GAIN: 1701 case SB_OUTPUT_GAIN: 1702 if (!ISSBM1745(sc)) 1703 return EINVAL; 1704 case SB_MIC_VOL: 1705 case SB_LINE_IN_VOL: 1706 if (sc->sc_mixer_model == SBM_CT1335) 1707 return EINVAL; 1708 case SB_VOICE_VOL: 1709 case SB_MIDI_VOL: 1710 case SB_CD_VOL: 1711 case SB_MASTER_VOL: 1712 if (cp->type != AUDIO_MIXER_VALUE) 1713 return EINVAL; 1714 1715 /* 1716 * All the mixer ports are stereo except for the microphone. 1717 * If we get a single-channel gain value passed in, then we 1718 * duplicate it to both left and right channels. 1719 */ 1720 1721 switch (cp->dev) { 1722 case SB_MIC_VOL: 1723 if (cp->un.value.num_channels != 1) 1724 return EINVAL; 1725 1726 lgain = rgain = SB_ADJUST_MIC_GAIN(sc, 1727 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1728 break; 1729 case SB_PCSPEAKER: 1730 if (cp->un.value.num_channels != 1) 1731 return EINVAL; 1732 /* fall into */ 1733 case SB_INPUT_GAIN: 1734 case SB_OUTPUT_GAIN: 1735 lgain = rgain = SB_ADJUST_2_GAIN(sc, 1736 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1737 break; 1738 default: 1739 switch (cp->un.value.num_channels) { 1740 case 1: 1741 lgain = rgain = SB_ADJUST_GAIN(sc, 1742 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 1743 break; 1744 case 2: 1745 if (sc->sc_mixer_model == SBM_CT1335) 1746 return EINVAL; 1747 lgain = SB_ADJUST_GAIN(sc, 1748 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]); 1749 rgain = SB_ADJUST_GAIN(sc, 1750 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]); 1751 break; 1752 default: 1753 return EINVAL; 1754 } 1755 break; 1756 } 1757 sc->gain[cp->dev][SB_LEFT] = lgain; 1758 sc->gain[cp->dev][SB_RIGHT] = rgain; 1759 1760 sbdsp_set_mixer_gain(sc, cp->dev); 1761 break; 1762 1763 case SB_RECORD_SOURCE: 1764 if (ISSBM1745(sc)) { 1765 if (cp->type != AUDIO_MIXER_SET) 1766 return EINVAL; 1767 return sbdsp_set_in_ports(sc, cp->un.mask); 1768 } else { 1769 if (cp->type != AUDIO_MIXER_ENUM) 1770 return EINVAL; 1771 sc->in_port = cp->un.ord; 1772 return sbdsp_set_in_ports(sc, 1 << cp->un.ord); 1773 } 1774 break; 1775 1776 case SB_AGC: 1777 if (!ISSBM1745(sc) || cp->type != AUDIO_MIXER_ENUM) 1778 return EINVAL; 1779 sbdsp_mix_write(sc, SB16P_AGC, cp->un.ord & 1); 1780 break; 1781 1782 case SB_CD_OUT_MUTE: 1783 mask = SB16P_SW_CD; 1784 goto omute; 1785 case SB_MIC_OUT_MUTE: 1786 mask = SB16P_SW_MIC; 1787 goto omute; 1788 case SB_LINE_OUT_MUTE: 1789 mask = SB16P_SW_LINE; 1790 omute: 1791 if (cp->type != AUDIO_MIXER_ENUM) 1792 return EINVAL; 1793 bits = sbdsp_mix_read(sc, SB16P_OSWITCH); 1794 sc->gain[cp->dev][SB_LR] = cp->un.ord != 0; 1795 if (cp->un.ord) 1796 bits = bits & ~mask; 1797 else 1798 bits = bits | mask; 1799 sbdsp_mix_write(sc, SB16P_OSWITCH, bits); 1800 break; 1801 1802 case SB_MIC_IN_MUTE: 1803 case SB_MIC_SWAP: 1804 lmask = rmask = SB16P_SW_MIC; 1805 goto imute; 1806 case SB_CD_IN_MUTE: 1807 case SB_CD_SWAP: 1808 lmask = SB16P_SW_CD_L; 1809 rmask = SB16P_SW_CD_R; 1810 goto imute; 1811 case SB_LINE_IN_MUTE: 1812 case SB_LINE_SWAP: 1813 lmask = SB16P_SW_LINE_L; 1814 rmask = SB16P_SW_LINE_R; 1815 goto imute; 1816 case SB_MIDI_IN_MUTE: 1817 case SB_MIDI_SWAP: 1818 lmask = SB16P_SW_MIDI_L; 1819 rmask = SB16P_SW_MIDI_R; 1820 imute: 1821 if (cp->type != AUDIO_MIXER_ENUM) 1822 return EINVAL; 1823 mask = lmask | rmask; 1824 lbits = sbdsp_mix_read(sc, SB16P_ISWITCH_L) & ~mask; 1825 rbits = sbdsp_mix_read(sc, SB16P_ISWITCH_R) & ~mask; 1826 sc->gain[cp->dev][SB_LR] = cp->un.ord != 0; 1827 if (SB_IS_IN_MUTE(cp->dev)) { 1828 mute = cp->dev; 1829 swap = mute - SB_CD_IN_MUTE + SB_CD_SWAP; 1830 } else { 1831 swap = cp->dev; 1832 mute = swap + SB_CD_IN_MUTE - SB_CD_SWAP; 1833 } 1834 if (sc->gain[swap][SB_LR]) { 1835 mask = lmask; 1836 lmask = rmask; 1837 rmask = mask; 1838 } 1839 if (!sc->gain[mute][SB_LR]) { 1840 lbits = lbits | lmask; 1841 rbits = rbits | rmask; 1842 } 1843 sbdsp_mix_write(sc, SB16P_ISWITCH_L, lbits); 1844 sbdsp_mix_write(sc, SB16P_ISWITCH_L, rbits); 1845 break; 1846 1847 default: 1848 return EINVAL; 1849 } 1850 1851 return 0; 1852 } 1853 1854 int 1855 sbdsp_mixer_get_port(addr, cp) 1856 void *addr; 1857 mixer_ctrl_t *cp; 1858 { 1859 struct sbdsp_softc *sc = addr; 1860 1861 if (sc->sc_open == SB_OPEN_MIDI) 1862 return EBUSY; 1863 1864 DPRINTF(("sbdsp_mixer_get_port: port=%d\n", cp->dev)); 1865 1866 if (sc->sc_mixer_model == SBM_NONE) 1867 return EINVAL; 1868 1869 switch (cp->dev) { 1870 case SB_TREBLE: 1871 case SB_BASS: 1872 if (sc->sc_mixer_model == SBM_CT1345 || 1873 sc->sc_mixer_model == SBM_CT1XX5) { 1874 switch (cp->dev) { 1875 case SB_TREBLE: 1876 cp->un.ord = sbdsp_get_ifilter(addr) == SB_TREBLE; 1877 return 0; 1878 case SB_BASS: 1879 cp->un.ord = sbdsp_get_ifilter(addr) == SB_BASS; 1880 return 0; 1881 } 1882 } 1883 case SB_PCSPEAKER: 1884 case SB_INPUT_GAIN: 1885 case SB_OUTPUT_GAIN: 1886 if (!ISSBM1745(sc)) 1887 return EINVAL; 1888 case SB_MIC_VOL: 1889 case SB_LINE_IN_VOL: 1890 if (sc->sc_mixer_model == SBM_CT1335) 1891 return EINVAL; 1892 case SB_VOICE_VOL: 1893 case SB_MIDI_VOL: 1894 case SB_CD_VOL: 1895 case SB_MASTER_VOL: 1896 switch (cp->dev) { 1897 case SB_MIC_VOL: 1898 case SB_PCSPEAKER: 1899 if (cp->un.value.num_channels != 1) 1900 return EINVAL; 1901 /* fall into */ 1902 default: 1903 switch (cp->un.value.num_channels) { 1904 case 1: 1905 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1906 sc->gain[cp->dev][SB_LEFT]; 1907 break; 1908 case 2: 1909 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1910 sc->gain[cp->dev][SB_LEFT]; 1911 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1912 sc->gain[cp->dev][SB_RIGHT]; 1913 break; 1914 default: 1915 return EINVAL; 1916 } 1917 break; 1918 } 1919 break; 1920 1921 case SB_RECORD_SOURCE: 1922 if (ISSBM1745(sc)) 1923 cp->un.mask = sc->in_mask; 1924 else 1925 cp->un.ord = sc->in_port; 1926 break; 1927 1928 case SB_AGC: 1929 if (!ISSBM1745(sc)) 1930 return EINVAL; 1931 cp->un.ord = sbdsp_mix_read(sc, SB16P_AGC); 1932 break; 1933 1934 case SB_CD_IN_MUTE: 1935 case SB_MIC_IN_MUTE: 1936 case SB_LINE_IN_MUTE: 1937 case SB_MIDI_IN_MUTE: 1938 case SB_CD_SWAP: 1939 case SB_MIC_SWAP: 1940 case SB_LINE_SWAP: 1941 case SB_MIDI_SWAP: 1942 case SB_CD_OUT_MUTE: 1943 case SB_MIC_OUT_MUTE: 1944 case SB_LINE_OUT_MUTE: 1945 cp->un.ord = sc->gain[cp->dev][SB_LR]; 1946 break; 1947 1948 default: 1949 return EINVAL; 1950 } 1951 1952 return 0; 1953 } 1954 1955 int 1956 sbdsp_mixer_query_devinfo(addr, dip) 1957 void *addr; 1958 mixer_devinfo_t *dip; 1959 { 1960 struct sbdsp_softc *sc = addr; 1961 int chan, class, is1745; 1962 1963 DPRINTF(("sbdsp_mixer_query_devinfo: model=%d index=%d\n", 1964 sc->sc_mixer_model, dip->index)); 1965 1966 if (dip->index < 0) 1967 return ENXIO; 1968 1969 if (sc->sc_mixer_model == SBM_NONE) 1970 return ENXIO; 1971 1972 chan = sc->sc_mixer_model == SBM_CT1335 ? 1 : 2; 1973 is1745 = ISSBM1745(sc); 1974 class = is1745 ? SB_INPUT_CLASS : SB_OUTPUT_CLASS; 1975 1976 switch (dip->index) { 1977 case SB_MASTER_VOL: 1978 dip->type = AUDIO_MIXER_VALUE; 1979 dip->mixer_class = SB_OUTPUT_CLASS; 1980 dip->prev = dip->next = AUDIO_MIXER_LAST; 1981 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name); 1982 dip->un.v.num_channels = chan; 1983 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 1984 return 0; 1985 case SB_MIDI_VOL: 1986 dip->type = AUDIO_MIXER_VALUE; 1987 dip->mixer_class = class; 1988 dip->prev = AUDIO_MIXER_LAST; 1989 dip->next = is1745 ? SB_MIDI_IN_MUTE : AUDIO_MIXER_LAST; 1990 strlcpy(dip->label.name, AudioNfmsynth, sizeof dip->label.name); 1991 dip->un.v.num_channels = chan; 1992 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 1993 return 0; 1994 case SB_CD_VOL: 1995 dip->type = AUDIO_MIXER_VALUE; 1996 dip->mixer_class = class; 1997 dip->prev = AUDIO_MIXER_LAST; 1998 dip->next = is1745 ? SB_CD_IN_MUTE : AUDIO_MIXER_LAST; 1999 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name); 2000 dip->un.v.num_channels = chan; 2001 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 2002 return 0; 2003 case SB_VOICE_VOL: 2004 dip->type = AUDIO_MIXER_VALUE; 2005 dip->mixer_class = class; 2006 dip->prev = AUDIO_MIXER_LAST; 2007 dip->next = AUDIO_MIXER_LAST; 2008 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); 2009 dip->un.v.num_channels = chan; 2010 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 2011 return 0; 2012 case SB_OUTPUT_CLASS: 2013 dip->type = AUDIO_MIXER_CLASS; 2014 dip->mixer_class = SB_OUTPUT_CLASS; 2015 dip->next = dip->prev = AUDIO_MIXER_LAST; 2016 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); 2017 return 0; 2018 } 2019 2020 if (sc->sc_mixer_model == SBM_CT1335) 2021 return ENXIO; 2022 2023 switch (dip->index) { 2024 case SB_MIC_VOL: 2025 dip->type = AUDIO_MIXER_VALUE; 2026 dip->mixer_class = class; 2027 dip->prev = AUDIO_MIXER_LAST; 2028 dip->next = is1745 ? SB_MIC_IN_MUTE : AUDIO_MIXER_LAST; 2029 strlcpy(dip->label.name, AudioNmicrophone, 2030 sizeof dip->label.name); 2031 dip->un.v.num_channels = 1; 2032 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 2033 return 0; 2034 2035 case SB_LINE_IN_VOL: 2036 dip->type = AUDIO_MIXER_VALUE; 2037 dip->mixer_class = class; 2038 dip->prev = AUDIO_MIXER_LAST; 2039 dip->next = is1745 ? SB_LINE_IN_MUTE : AUDIO_MIXER_LAST; 2040 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name); 2041 dip->un.v.num_channels = 2; 2042 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 2043 return 0; 2044 2045 case SB_RECORD_SOURCE: 2046 dip->mixer_class = SB_RECORD_CLASS; 2047 dip->prev = dip->next = AUDIO_MIXER_LAST; 2048 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); 2049 if (ISSBM1745(sc)) { 2050 dip->type = AUDIO_MIXER_SET; 2051 dip->un.s.num_mem = 4; 2052 strlcpy(dip->un.s.member[0].label.name, 2053 AudioNmicrophone, 2054 sizeof dip->un.s.member[0].label.name); 2055 dip->un.s.member[0].mask = 1 << SB_MIC_VOL; 2056 strlcpy(dip->un.s.member[1].label.name, 2057 AudioNcd, sizeof dip->un.s.member[1].label.name); 2058 dip->un.s.member[1].mask = 1 << SB_CD_VOL; 2059 strlcpy(dip->un.s.member[2].label.name, 2060 AudioNline, sizeof dip->un.s.member[2].label.name); 2061 dip->un.s.member[2].mask = 1 << SB_LINE_IN_VOL; 2062 strlcpy(dip->un.s.member[3].label.name, 2063 AudioNfmsynth, 2064 sizeof dip->un.s.member[3].label.name); 2065 dip->un.s.member[3].mask = 1 << SB_MIDI_VOL; 2066 } else { 2067 dip->type = AUDIO_MIXER_ENUM; 2068 dip->un.e.num_mem = 3; 2069 strlcpy(dip->un.e.member[0].label.name, 2070 AudioNmicrophone, 2071 sizeof dip->un.e.member[0].label.name); 2072 dip->un.e.member[0].ord = SB_MIC_VOL; 2073 strlcpy(dip->un.e.member[1].label.name, AudioNcd, 2074 sizeof dip->un.e.member[1].label.name); 2075 dip->un.e.member[1].ord = SB_CD_VOL; 2076 strlcpy(dip->un.e.member[2].label.name, AudioNline, 2077 sizeof dip->un.e.member[2].label.name); 2078 dip->un.e.member[2].ord = SB_LINE_IN_VOL; 2079 } 2080 return 0; 2081 2082 case SB_BASS: 2083 dip->prev = dip->next = AUDIO_MIXER_LAST; 2084 strlcpy(dip->label.name, AudioNbass, sizeof dip->label.name); 2085 if (sc->sc_mixer_model == SBM_CT1745) { 2086 dip->type = AUDIO_MIXER_VALUE; 2087 dip->mixer_class = SB_EQUALIZATION_CLASS; 2088 dip->un.v.num_channels = 2; 2089 strlcpy(dip->un.v.units.name, AudioNbass, sizeof dip->un.v.units.name); 2090 } else { 2091 dip->type = AUDIO_MIXER_ENUM; 2092 dip->mixer_class = SB_INPUT_CLASS; 2093 dip->un.e.num_mem = 2; 2094 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 2095 sizeof dip->un.e.member[0].label.name); 2096 dip->un.e.member[0].ord = 0; 2097 strlcpy(dip->un.e.member[1].label.name, AudioNon, 2098 sizeof dip->un.e.member[1].label.name); 2099 dip->un.e.member[1].ord = 1; 2100 } 2101 return 0; 2102 2103 case SB_TREBLE: 2104 dip->prev = dip->next = AUDIO_MIXER_LAST; 2105 strlcpy(dip->label.name, AudioNtreble, sizeof dip->label.name); 2106 if (sc->sc_mixer_model == SBM_CT1745) { 2107 dip->type = AUDIO_MIXER_VALUE; 2108 dip->mixer_class = SB_EQUALIZATION_CLASS; 2109 dip->un.v.num_channels = 2; 2110 strlcpy(dip->un.v.units.name, AudioNtreble, sizeof dip->un.v.units.name); 2111 } else { 2112 dip->type = AUDIO_MIXER_ENUM; 2113 dip->mixer_class = SB_INPUT_CLASS; 2114 dip->un.e.num_mem = 2; 2115 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 2116 sizeof dip->un.e.member[0].label.name); 2117 dip->un.e.member[0].ord = 0; 2118 strlcpy(dip->un.e.member[1].label.name, AudioNon, 2119 sizeof dip->un.e.member[1].label.name); 2120 dip->un.e.member[1].ord = 1; 2121 } 2122 return 0; 2123 2124 case SB_RECORD_CLASS: /* record source class */ 2125 dip->type = AUDIO_MIXER_CLASS; 2126 dip->mixer_class = SB_RECORD_CLASS; 2127 dip->next = dip->prev = AUDIO_MIXER_LAST; 2128 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name); 2129 return 0; 2130 2131 case SB_INPUT_CLASS: 2132 dip->type = AUDIO_MIXER_CLASS; 2133 dip->mixer_class = SB_INPUT_CLASS; 2134 dip->next = dip->prev = AUDIO_MIXER_LAST; 2135 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); 2136 return 0; 2137 2138 } 2139 2140 if (sc->sc_mixer_model == SBM_CT1345) 2141 return ENXIO; 2142 2143 switch(dip->index) { 2144 case SB_PCSPEAKER: 2145 dip->type = AUDIO_MIXER_VALUE; 2146 dip->mixer_class = SB_INPUT_CLASS; 2147 dip->prev = dip->next = AUDIO_MIXER_LAST; 2148 strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name); 2149 dip->un.v.num_channels = 1; 2150 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 2151 return 0; 2152 2153 case SB_INPUT_GAIN: 2154 dip->type = AUDIO_MIXER_VALUE; 2155 dip->mixer_class = SB_INPUT_CLASS; 2156 dip->prev = dip->next = AUDIO_MIXER_LAST; 2157 strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name); 2158 dip->un.v.num_channels = 2; 2159 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 2160 return 0; 2161 2162 case SB_OUTPUT_GAIN: 2163 dip->type = AUDIO_MIXER_VALUE; 2164 dip->mixer_class = SB_OUTPUT_CLASS; 2165 dip->prev = dip->next = AUDIO_MIXER_LAST; 2166 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); 2167 dip->un.v.num_channels = 2; 2168 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); 2169 return 0; 2170 2171 case SB_AGC: 2172 dip->type = AUDIO_MIXER_ENUM; 2173 dip->mixer_class = SB_INPUT_CLASS; 2174 dip->prev = dip->next = AUDIO_MIXER_LAST; 2175 strlcpy(dip->label.name, "agc", sizeof dip->label.name); 2176 dip->un.e.num_mem = 2; 2177 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 2178 sizeof dip->un.e.member[0].label.name); 2179 dip->un.e.member[0].ord = 0; 2180 strlcpy(dip->un.e.member[1].label.name, AudioNon, 2181 sizeof dip->un.e.member[1].label.name); 2182 dip->un.e.member[1].ord = 1; 2183 return 0; 2184 2185 case SB_EQUALIZATION_CLASS: 2186 dip->type = AUDIO_MIXER_CLASS; 2187 dip->mixer_class = SB_EQUALIZATION_CLASS; 2188 dip->next = dip->prev = AUDIO_MIXER_LAST; 2189 strlcpy(dip->label.name, AudioCequalization, sizeof dip->label.name); 2190 return 0; 2191 2192 case SB_CD_IN_MUTE: 2193 dip->prev = SB_CD_VOL; 2194 dip->next = SB_CD_SWAP; 2195 dip->mixer_class = SB_INPUT_CLASS; 2196 goto mute; 2197 2198 case SB_MIC_IN_MUTE: 2199 dip->prev = SB_MIC_VOL; 2200 dip->next = SB_MIC_SWAP; 2201 dip->mixer_class = SB_INPUT_CLASS; 2202 goto mute; 2203 2204 case SB_LINE_IN_MUTE: 2205 dip->prev = SB_LINE_IN_VOL; 2206 dip->next = SB_LINE_SWAP; 2207 dip->mixer_class = SB_INPUT_CLASS; 2208 goto mute; 2209 2210 case SB_MIDI_IN_MUTE: 2211 dip->prev = SB_MIDI_VOL; 2212 dip->next = SB_MIDI_SWAP; 2213 dip->mixer_class = SB_INPUT_CLASS; 2214 goto mute; 2215 2216 case SB_CD_SWAP: 2217 dip->prev = SB_CD_IN_MUTE; 2218 dip->next = SB_CD_OUT_MUTE; 2219 goto swap; 2220 2221 case SB_MIC_SWAP: 2222 dip->prev = SB_MIC_IN_MUTE; 2223 dip->next = SB_MIC_OUT_MUTE; 2224 goto swap; 2225 2226 case SB_LINE_SWAP: 2227 dip->prev = SB_LINE_IN_MUTE; 2228 dip->next = SB_LINE_OUT_MUTE; 2229 goto swap; 2230 2231 case SB_MIDI_SWAP: 2232 dip->prev = SB_MIDI_IN_MUTE; 2233 dip->next = AUDIO_MIXER_LAST; 2234 swap: 2235 dip->mixer_class = SB_INPUT_CLASS; 2236 strlcpy(dip->label.name, AudioNswap, sizeof dip->label.name); 2237 goto mute1; 2238 2239 case SB_CD_OUT_MUTE: 2240 dip->prev = SB_CD_SWAP; 2241 dip->next = AUDIO_MIXER_LAST; 2242 dip->mixer_class = SB_OUTPUT_CLASS; 2243 goto mute; 2244 2245 case SB_MIC_OUT_MUTE: 2246 dip->prev = SB_MIC_SWAP; 2247 dip->next = AUDIO_MIXER_LAST; 2248 dip->mixer_class = SB_OUTPUT_CLASS; 2249 goto mute; 2250 2251 case SB_LINE_OUT_MUTE: 2252 dip->prev = SB_LINE_SWAP; 2253 dip->next = AUDIO_MIXER_LAST; 2254 dip->mixer_class = SB_OUTPUT_CLASS; 2255 mute: 2256 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); 2257 mute1: 2258 dip->type = AUDIO_MIXER_ENUM; 2259 dip->un.e.num_mem = 2; 2260 strlcpy(dip->un.e.member[0].label.name, AudioNoff, 2261 sizeof dip->un.e.member[0].label.name); 2262 dip->un.e.member[0].ord = 0; 2263 strlcpy(dip->un.e.member[1].label.name, AudioNon, 2264 sizeof dip->un.e.member[1].label.name); 2265 dip->un.e.member[1].ord = 1; 2266 return 0; 2267 2268 } 2269 2270 return ENXIO; 2271 } 2272 2273 void * 2274 sb_malloc(addr, direction, size, pool, flags) 2275 void *addr; 2276 int direction; 2277 size_t size; 2278 int pool; 2279 int flags; 2280 { 2281 struct sbdsp_softc *sc = addr; 2282 int drq; 2283 2284 /* 8-bit has more restrictive alignment */ 2285 if (sc->sc_drq8 != -1) 2286 drq = sc->sc_drq8; 2287 else 2288 drq = sc->sc_drq16; 2289 2290 return isa_malloc(sc->sc_isa, drq, size, pool, flags); 2291 } 2292 2293 void 2294 sb_free(addr, ptr, pool) 2295 void *addr; 2296 void *ptr; 2297 int pool; 2298 { 2299 isa_free(ptr, pool); 2300 } 2301 2302 size_t 2303 sb_round(addr, direction, size) 2304 void *addr; 2305 int direction; 2306 size_t size; 2307 { 2308 if (size > MAX_ISADMA) 2309 size = MAX_ISADMA; 2310 return size; 2311 } 2312 2313 paddr_t 2314 sb_mappage(addr, mem, off, prot) 2315 void *addr; 2316 void *mem; 2317 off_t off; 2318 int prot; 2319 { 2320 return isa_mappage(mem, off, prot); 2321 } 2322 2323 int 2324 sbdsp_get_props(addr) 2325 void *addr; 2326 { 2327 struct sbdsp_softc *sc = addr; 2328 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | 2329 (sc->sc_fullduplex ? AUDIO_PROP_FULLDUPLEX : 0); 2330 } 2331 2332 #if NMIDI > 0 2333 /* 2334 * MIDI related routines. 2335 */ 2336 2337 int 2338 sbdsp_midi_open(addr, flags, iintr, ointr, arg) 2339 void *addr; 2340 int flags; 2341 void (*iintr)(void *, int); 2342 void (*ointr)(void *); 2343 void *arg; 2344 { 2345 struct sbdsp_softc *sc = addr; 2346 2347 DPRINTF(("sbdsp_midi_open: sc=%p\n", sc)); 2348 2349 if (sc->sc_open != SB_CLOSED) 2350 return EBUSY; 2351 if (sbdsp_reset(sc) != 0) 2352 return EIO; 2353 2354 if (sc->sc_model >= SB_20) 2355 if (sbdsp_wdsp(sc, SB_MIDI_UART_INTR)) /* enter UART mode */ 2356 return EIO; 2357 sc->sc_open = SB_OPEN_MIDI; 2358 sc->sc_openflags = flags; 2359 sc->sc_intr8 = sbdsp_midi_intr; 2360 sc->sc_arg8 = addr; 2361 sc->sc_intrm = iintr; 2362 sc->sc_argm = arg; 2363 return 0; 2364 } 2365 2366 void 2367 sbdsp_midi_close(addr) 2368 void *addr; 2369 { 2370 struct sbdsp_softc *sc = addr; 2371 2372 DPRINTF(("sbdsp_midi_close: sc=%p\n", sc)); 2373 2374 if (sc->sc_model >= SB_20) 2375 sbdsp_reset(sc); /* exit UART mode */ 2376 sc->sc_open = SB_CLOSED; 2377 sc->sc_intrm = 0; 2378 } 2379 2380 int 2381 sbdsp_midi_output(addr, d) 2382 void *addr; 2383 int d; 2384 { 2385 struct sbdsp_softc *sc = addr; 2386 2387 if (sc->sc_model < SB_20 && sbdsp_wdsp(sc, SB_MIDI_WRITE)) 2388 return 1; 2389 (void)sbdsp_wdsp(sc, d); 2390 return 1; 2391 } 2392 2393 void 2394 sbdsp_midi_getinfo(addr, mi) 2395 void *addr; 2396 struct midi_info *mi; 2397 { 2398 struct sbdsp_softc *sc = addr; 2399 2400 mi->name = sc->sc_model < SB_20 ? "SB MIDI cmd" : "SB MIDI UART"; 2401 mi->props = MIDI_PROP_CAN_INPUT; 2402 } 2403 2404 int 2405 sbdsp_midi_intr(addr) 2406 void *addr; 2407 { 2408 struct sbdsp_softc *sc = addr; 2409 2410 sc->sc_intrm(sc->sc_argm, sbdsp_rdsp(sc)); 2411 return (0); 2412 } 2413 2414 #endif 2415