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