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