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