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