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