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