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