sbdsp.c revision 1.5 1 1.5 mycroft /* $NetBSD: sbdsp.c,v 1.5 1995/03/25 00:01:00 mycroft Exp $ */
2 1.1 brezak
3 1.1 brezak /*
4 1.1 brezak * Copyright (c) 1991-1993 Regents of the University of California.
5 1.1 brezak * All rights reserved.
6 1.1 brezak *
7 1.1 brezak * Redistribution and use in source and binary forms, with or without
8 1.1 brezak * modification, are permitted provided that the following conditions
9 1.1 brezak * are met:
10 1.1 brezak * 1. Redistributions of source code must retain the above copyright
11 1.1 brezak * notice, this list of conditions and the following disclaimer.
12 1.1 brezak * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 brezak * notice, this list of conditions and the following disclaimer in the
14 1.1 brezak * documentation and/or other materials provided with the distribution.
15 1.1 brezak * 3. All advertising materials mentioning features or use of this software
16 1.1 brezak * must display the following acknowledgement:
17 1.1 brezak * This product includes software developed by the Computer Systems
18 1.1 brezak * Engineering Group at Lawrence Berkeley Laboratory.
19 1.1 brezak * 4. Neither the name of the University nor of the Laboratory may be used
20 1.1 brezak * to endorse or promote products derived from this software without
21 1.1 brezak * specific prior written permission.
22 1.1 brezak *
23 1.1 brezak * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 1.1 brezak * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.1 brezak * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 brezak * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 1.1 brezak * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 brezak * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 1.1 brezak * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1 brezak * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1 brezak * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1 brezak * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1 brezak * SUCH DAMAGE.
34 1.1 brezak *
35 1.5 mycroft * $Id: sbdsp.c,v 1.5 1995/03/25 00:01:00 mycroft Exp $
36 1.1 brezak */
37 1.1 brezak /*
38 1.1 brezak * SoundBlaster Pro code provided by John Kohl, based on lots of
39 1.1 brezak * information he gleaned from Steve Haehnichen <steve (at) vigra.com>'s
40 1.1 brezak * SBlast driver for 386BSD and DOS driver code from Daniel Sachs
41 1.1 brezak * <sachs (at) meibm15.cen.uiuc.edu>.
42 1.1 brezak */
43 1.1 brezak
44 1.1 brezak #include <sys/param.h>
45 1.1 brezak #include <sys/systm.h>
46 1.1 brezak #include <sys/errno.h>
47 1.1 brezak #include <sys/ioctl.h>
48 1.1 brezak #include <sys/syslog.h>
49 1.1 brezak #include <sys/device.h>
50 1.1 brezak #include <sys/proc.h>
51 1.1 brezak #include <sys/buf.h>
52 1.1 brezak #include <vm/vm.h>
53 1.1 brezak
54 1.1 brezak #include <machine/cpu.h>
55 1.1 brezak #include <machine/pio.h>
56 1.1 brezak
57 1.1 brezak #include <sys/audioio.h>
58 1.1 brezak #include <dev/audio_if.h>
59 1.1 brezak
60 1.1 brezak #include <i386/isa/isavar.h>
61 1.1 brezak #include <i386/isa/dmavar.h>
62 1.1 brezak #include <i386/isa/icu.h>
63 1.1 brezak
64 1.1 brezak #include <i386/isa/sbreg.h>
65 1.1 brezak #include <i386/isa/sbdspvar.h>
66 1.1 brezak
67 1.1 brezak #ifdef DEBUG
68 1.1 brezak extern void Dprintf __P((const char *, ...));
69 1.1 brezak
70 1.1 brezak #define DPRINTF(x) if (sbdspdebug) printf x
71 1.1 brezak int sbdspdebug = 0;
72 1.1 brezak #else
73 1.1 brezak #define DPRINTF(x)
74 1.1 brezak #endif
75 1.1 brezak
76 1.1 brezak #ifndef NEWCONFIG
77 1.1 brezak #define at_dma(flags, ptr, cc, chan) isa_dmastart(flags, ptr, cc, chan)
78 1.1 brezak #endif
79 1.1 brezak
80 1.1 brezak #ifndef SBDSP_NPOLL
81 1.1 brezak #define SBDSP_NPOLL 3000
82 1.1 brezak #endif
83 1.1 brezak
84 1.1 brezak struct {
85 1.1 brezak int wdsp;
86 1.1 brezak int rdsp;
87 1.1 brezak int wmidi;
88 1.1 brezak } sberr;
89 1.1 brezak
90 1.1 brezak #ifdef DEBUG
91 1.1 brezak void
92 1.1 brezak sb_printsc(struct sbdsp_softc *sc)
93 1.1 brezak {
94 1.1 brezak int i;
95 1.1 brezak
96 1.1 brezak printf("open %d dmachan %d iobase %x locked %d\n", sc->sc_open, sc->sc_drq,
97 1.1 brezak sc->sc_iobase, sc->sc_locked);
98 1.1 brezak printf("hispeed %d irate %d orate %d encoding %x\n",
99 1.1 brezak sc->sc_adacmode, sc->sc_irate, sc->sc_orate, sc->encoding);
100 1.1 brezak printf("outport %d inport %d spkron %d nintr %d\n",
101 1.1 brezak sc->out_port, sc->in_port, sc->spkr_state, sc->sc_interrupts);
102 1.1 brezak printf("tc %x chans %x scintr %x arg %x\n", sc->sc_adactc, sc->sc_chans,
103 1.1 brezak sc->sc_intr, sc->sc_arg);
104 1.1 brezak printf("gain: ");
105 1.1 brezak for (i = 0; i < SB_NDEVS; i++)
106 1.1 brezak printf("%d ", sc->gain[i]);
107 1.1 brezak printf("\n");
108 1.1 brezak }
109 1.1 brezak #endif
110 1.1 brezak
111 1.1 brezak /*
112 1.1 brezak * Probe / attach routines.
113 1.1 brezak */
114 1.1 brezak
115 1.1 brezak /*
116 1.1 brezak * Probe for the soundblaster hardware.
117 1.1 brezak */
118 1.1 brezak int
119 1.1 brezak sbdsp_probe(sc)
120 1.1 brezak struct sbdsp_softc *sc;
121 1.1 brezak {
122 1.1 brezak register u_short iobase = sc->sc_iobase;
123 1.1 brezak
124 1.1 brezak if (sbdsp_reset(sc) < 0) {
125 1.1 brezak DPRINTF(("sbdsp: couldn't reset card\n"));
126 1.1 brezak return 0;
127 1.1 brezak }
128 1.1 brezak sc->sc_model = sbversion(sc);
129 1.1 brezak
130 1.1 brezak return 1;
131 1.1 brezak }
132 1.1 brezak
133 1.1 brezak /*
134 1.1 brezak * Attach hardware to driver, attach hardware driver to audio
135 1.1 brezak * pseudo-device driver .
136 1.1 brezak */
137 1.1 brezak void
138 1.1 brezak sbdsp_attach(sc)
139 1.1 brezak struct sbdsp_softc *sc;
140 1.1 brezak {
141 1.1 brezak register u_short iobase = sc->sc_iobase;
142 1.1 brezak
143 1.1 brezak sc->sc_locked = 0;
144 1.1 brezak
145 1.1 brezak #ifdef NEWCONFIG
146 1.1 brezak /*
147 1.1 brezak * We limit DMA transfers to a page, and use the generic DMA handling
148 1.1 brezak * code in isa.c. This code can end up copying a buffer, but since
149 1.1 brezak * the audio driver uses relative small buffers this isn't likely.
150 1.1 brezak *
151 1.1 brezak * This allocation scheme means that the maximum transfer is limited
152 1.1 brezak * by the page size (rather than 64k). This is reasonable. For 4K
153 1.1 brezak * pages, the transfer time at 48KHz is 4096 / 48000 = 85ms. This
154 1.1 brezak * is plenty long enough to amortize any fixed time overhead.
155 1.1 brezak */
156 1.1 brezak at_setup_dmachan(sc->sc_drq, NBPG);
157 1.1 brezak #endif
158 1.1 brezak
159 1.1 brezak /* Set defaults */
160 1.1 brezak if (ISSBPROCLASS(sc))
161 1.1 brezak sc->sc_irate = sc->sc_orate = 45454;
162 1.1 brezak else
163 1.1 brezak sc->sc_irate = sc->sc_orate = 14925;
164 1.1 brezak sc->sc_chans = 1;
165 1.1 brezak sc->encoding = AUDIO_ENCODING_LINEAR;
166 1.1 brezak
167 1.5 mycroft (void) sbdsp_set_in_sr_real(sc, sc->sc_irate);
168 1.5 mycroft (void) sbdsp_set_out_sr_real(sc, sc->sc_orate);
169 1.1 brezak
170 1.5 mycroft (void) sbdsp_set_in_port(sc, SB_MIC_PORT);
171 1.5 mycroft (void) sbdsp_set_out_port(sc, SB_SPEAKER);
172 1.1 brezak
173 1.1 brezak if (ISSBPROCLASS(sc)) {
174 1.1 brezak int i;
175 1.1 brezak
176 1.1 brezak /* set mixer to default levels, by sending a mixer
177 1.1 brezak reset command. */
178 1.1 brezak sbdsp_mix_write(sc, SBP_MIX_RESET, SBP_MIX_RESET);
179 1.1 brezak /* then some adjustments :) */
180 1.1 brezak sbdsp_mix_write(sc, SBP_CD_VOL,
181 1.1 brezak sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL));
182 1.1 brezak sbdsp_mix_write(sc, SBP_DAC_VOL,
183 1.1 brezak sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL));
184 1.1 brezak sbdsp_mix_write(sc, SBP_MASTER_VOL,
185 1.1 brezak sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL));
186 1.1 brezak sbdsp_mix_write(sc, SBP_LINE_VOL,
187 1.1 brezak sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL));
188 1.1 brezak for (i = 0; i < SB_NDEVS; i++)
189 1.1 brezak sc->gain[i] = sbdsp_stereo_vol(SBP_MAXVOL, SBP_MAXVOL);
190 1.1 brezak }
191 1.1 brezak printf(": dsp v%d.%d\n",
192 1.1 brezak SBVER_MAJOR(sc->sc_model), SBVER_MINOR(sc->sc_model));
193 1.1 brezak }
194 1.1 brezak
195 1.1 brezak /*
196 1.1 brezak * Various routines to interface to higher level audio driver
197 1.1 brezak */
198 1.1 brezak
199 1.1 brezak void
200 1.1 brezak sbdsp_mix_write(sc, mixerport, val)
201 1.1 brezak struct sbdsp_softc *sc;
202 1.1 brezak int mixerport;
203 1.1 brezak int val;
204 1.1 brezak {
205 1.1 brezak int iobase = sc->sc_iobase;
206 1.1 brezak outb(iobase + SBP_MIXER_ADDR, mixerport);
207 1.1 brezak delay(10);
208 1.1 brezak outb(iobase + SBP_MIXER_DATA, val);
209 1.1 brezak delay(30);
210 1.1 brezak }
211 1.1 brezak
212 1.1 brezak int
213 1.1 brezak sbdsp_mix_read(sc, mixerport)
214 1.1 brezak struct sbdsp_softc *sc;
215 1.1 brezak int mixerport;
216 1.1 brezak {
217 1.1 brezak int iobase = sc->sc_iobase;
218 1.1 brezak outb(iobase + SBP_MIXER_ADDR, mixerport);
219 1.1 brezak delay(10);
220 1.1 brezak return inb(iobase + SBP_MIXER_DATA);
221 1.1 brezak }
222 1.1 brezak
223 1.1 brezak int
224 1.1 brezak sbdsp_set_in_sr(addr, sr)
225 1.5 mycroft void *addr;
226 1.1 brezak u_long sr;
227 1.1 brezak {
228 1.5 mycroft register struct sbdsp_softc *sc = addr;
229 1.1 brezak
230 1.1 brezak sc->sc_irate = sr;
231 1.1 brezak
232 1.1 brezak return 0;
233 1.1 brezak }
234 1.1 brezak
235 1.1 brezak int
236 1.1 brezak sbdsp_set_in_sr_real(addr, sr)
237 1.5 mycroft void *addr;
238 1.1 brezak u_long sr;
239 1.1 brezak {
240 1.5 mycroft register struct sbdsp_softc *sc = addr;
241 1.1 brezak int rval;
242 1.1 brezak
243 1.1 brezak if (rval = sbdsp_set_sr(sc, &sr, SB_INPUT_RATE))
244 1.1 brezak return rval;
245 1.1 brezak sc->sc_irate = sr;
246 1.1 brezak sc->sc_dmain_inprogress = 0; /* do it again on next DMA out */
247 1.1 brezak sc->sc_dmaout_inprogress = 0;
248 1.1 brezak return(0);
249 1.1 brezak }
250 1.1 brezak
251 1.1 brezak u_long
252 1.1 brezak sbdsp_get_in_sr(addr)
253 1.5 mycroft void *addr;
254 1.1 brezak {
255 1.5 mycroft register struct sbdsp_softc *sc = addr;
256 1.1 brezak
257 1.1 brezak return(sc->sc_irate);
258 1.1 brezak }
259 1.1 brezak
260 1.1 brezak int
261 1.1 brezak sbdsp_set_out_sr(addr, sr)
262 1.5 mycroft void *addr;
263 1.1 brezak u_long sr;
264 1.1 brezak {
265 1.5 mycroft register struct sbdsp_softc *sc = addr;
266 1.1 brezak
267 1.1 brezak sc->sc_orate = sr;
268 1.1 brezak return(0);
269 1.1 brezak }
270 1.1 brezak
271 1.1 brezak int
272 1.1 brezak sbdsp_set_out_sr_real(addr, sr)
273 1.5 mycroft void *addr;
274 1.1 brezak u_long sr;
275 1.1 brezak {
276 1.5 mycroft register struct sbdsp_softc *sc = addr;
277 1.1 brezak int rval;
278 1.1 brezak
279 1.1 brezak if (rval = sbdsp_set_sr(sc, &sr, SB_OUTPUT_RATE))
280 1.1 brezak return rval;
281 1.1 brezak sc->sc_orate = sr;
282 1.1 brezak sc->sc_dmain_inprogress = 0; /* do it again on next DMA out */
283 1.1 brezak return(0);
284 1.1 brezak }
285 1.1 brezak
286 1.1 brezak u_long
287 1.1 brezak sbdsp_get_out_sr(addr)
288 1.5 mycroft void *addr;
289 1.1 brezak {
290 1.5 mycroft register struct sbdsp_softc *sc = addr;
291 1.1 brezak
292 1.1 brezak return(sc->sc_orate);
293 1.1 brezak }
294 1.1 brezak
295 1.1 brezak int
296 1.1 brezak sbdsp_query_encoding(addr, fp)
297 1.5 mycroft void *addr;
298 1.1 brezak struct audio_encoding *fp;
299 1.1 brezak {
300 1.5 mycroft register struct sbdsp_softc *sc = addr;
301 1.1 brezak
302 1.1 brezak switch (fp->index) {
303 1.1 brezak case 0:
304 1.1 brezak strcpy(fp->name, "MU-Law");
305 1.1 brezak fp->format_id = AUDIO_ENCODING_ULAW;
306 1.1 brezak break;
307 1.1 brezak case 2:
308 1.1 brezak strcpy(fp->name, "pcm16");
309 1.1 brezak fp->format_id = AUDIO_ENCODING_PCM16;
310 1.1 brezak break;
311 1.1 brezak default:
312 1.1 brezak return(EINVAL);
313 1.1 brezak /*NOTREACHED*/
314 1.1 brezak }
315 1.1 brezak return (0);
316 1.1 brezak }
317 1.1 brezak
318 1.1 brezak int
319 1.1 brezak sbdsp_set_encoding(addr, enc)
320 1.5 mycroft void *addr;
321 1.1 brezak u_int enc;
322 1.1 brezak {
323 1.5 mycroft register struct sbdsp_softc *sc = addr;
324 1.1 brezak
325 1.1 brezak switch(enc){
326 1.1 brezak case AUDIO_ENCODING_ULAW:
327 1.1 brezak sc->encoding = AUDIO_ENCODING_ULAW;
328 1.1 brezak break;
329 1.1 brezak case AUDIO_ENCODING_LINEAR:
330 1.1 brezak sc->encoding = AUDIO_ENCODING_LINEAR;
331 1.1 brezak break;
332 1.1 brezak default:
333 1.1 brezak return (EINVAL);
334 1.1 brezak }
335 1.1 brezak return (0);
336 1.1 brezak }
337 1.1 brezak
338 1.1 brezak int
339 1.1 brezak sbdsp_get_encoding(addr)
340 1.5 mycroft void *addr;
341 1.1 brezak {
342 1.5 mycroft register struct sbdsp_softc *sc = addr;
343 1.1 brezak
344 1.1 brezak return(sc->encoding);
345 1.1 brezak }
346 1.1 brezak
347 1.1 brezak int
348 1.1 brezak sbdsp_set_precision(addr, prec)
349 1.5 mycroft void *addr;
350 1.1 brezak u_int prec;
351 1.1 brezak {
352 1.1 brezak
353 1.1 brezak if (prec != 8)
354 1.1 brezak return(EINVAL);
355 1.1 brezak return(0);
356 1.1 brezak }
357 1.1 brezak
358 1.1 brezak int
359 1.1 brezak sbdsp_get_precision(addr)
360 1.5 mycroft void *addr;
361 1.1 brezak {
362 1.1 brezak return(8);
363 1.1 brezak }
364 1.1 brezak
365 1.1 brezak int
366 1.1 brezak sbdsp_set_channels(addr, chans)
367 1.5 mycroft void *addr;
368 1.1 brezak int chans;
369 1.1 brezak {
370 1.5 mycroft register struct sbdsp_softc *sc = addr;
371 1.1 brezak int rval;
372 1.1 brezak
373 1.1 brezak if (ISSBPROCLASS(sc)) {
374 1.1 brezak if (chans != 1 && chans != 2)
375 1.1 brezak return(EINVAL);
376 1.1 brezak
377 1.1 brezak sc->sc_chans = chans;
378 1.1 brezak if (rval = sbdsp_set_in_sr_real(addr, sc->sc_irate))
379 1.1 brezak return rval;
380 1.1 brezak sbdsp_mix_write(sc, SBP_STEREO,
381 1.1 brezak (sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) |
382 1.1 brezak (chans == 2 ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO));
383 1.1 brezak /* recording channels needs to be done right when we start
384 1.1 brezak DMA recording. Just record number of channels for now
385 1.1 brezak and set stereo when ready. */
386 1.1 brezak }
387 1.1 brezak else {
388 1.1 brezak if (chans != 1)
389 1.1 brezak return(EINVAL);
390 1.1 brezak sc->sc_chans = 1;
391 1.1 brezak }
392 1.1 brezak
393 1.1 brezak return(0);
394 1.1 brezak }
395 1.1 brezak
396 1.1 brezak int
397 1.1 brezak sbdsp_get_channels(addr)
398 1.5 mycroft void *addr;
399 1.1 brezak {
400 1.5 mycroft register struct sbdsp_softc *sc = addr;
401 1.1 brezak
402 1.1 brezak #if 0
403 1.1 brezak /* recording stereo may frob the mixer output */
404 1.1 brezak if (ISSBPROCLASS(sc)) {
405 1.1 brezak if ((sbdsp_mix_read(sc, SBP_STEREO) & SBP_PLAYMODE_MASK) == SBP_PLAYMODE_STEREO) {
406 1.1 brezak sc->sc_chans = 2;
407 1.1 brezak }
408 1.1 brezak else {
409 1.1 brezak sc->sc_chans = 1;
410 1.1 brezak }
411 1.1 brezak }
412 1.1 brezak else {
413 1.1 brezak sc->sc_chans = 1;
414 1.1 brezak }
415 1.1 brezak #endif
416 1.1 brezak
417 1.1 brezak return(sc->sc_chans);
418 1.1 brezak }
419 1.1 brezak
420 1.1 brezak int
421 1.1 brezak sbdsp_set_out_port(addr, port)
422 1.5 mycroft void *addr;
423 1.1 brezak int port;
424 1.1 brezak {
425 1.5 mycroft register struct sbdsp_softc *sc = addr;
426 1.1 brezak
427 1.1 brezak sc->out_port = port; /* Just record it */
428 1.1 brezak
429 1.1 brezak return(0);
430 1.1 brezak }
431 1.1 brezak
432 1.1 brezak int
433 1.1 brezak sbdsp_get_out_port(addr)
434 1.5 mycroft void *addr;
435 1.1 brezak {
436 1.5 mycroft register struct sbdsp_softc *sc = addr;
437 1.1 brezak
438 1.1 brezak return(sc->out_port);
439 1.1 brezak }
440 1.1 brezak
441 1.1 brezak
442 1.1 brezak int
443 1.1 brezak sbdsp_set_in_port(addr, port)
444 1.5 mycroft void *addr;
445 1.1 brezak int port;
446 1.1 brezak {
447 1.5 mycroft register struct sbdsp_softc *sc = addr;
448 1.1 brezak int mixport, sbport;
449 1.1 brezak
450 1.1 brezak switch (port) {
451 1.1 brezak case SB_MIC_PORT:
452 1.1 brezak sbport = SBP_FROM_MIC;
453 1.1 brezak mixport = SBP_MIC_VOL;
454 1.1 brezak break;
455 1.1 brezak }
456 1.1 brezak
457 1.1 brezak if (ISSBPROCLASS(sc)) {
458 1.1 brezak switch (port) {
459 1.1 brezak case SB_LINE_IN_PORT:
460 1.1 brezak sbport = SBP_FROM_LINE;
461 1.1 brezak mixport = SBP_LINE_VOL;
462 1.1 brezak break;
463 1.1 brezak case SB_CD_PORT:
464 1.1 brezak sbport = SBP_FROM_CD;
465 1.1 brezak mixport = SBP_CD_VOL;
466 1.1 brezak break;
467 1.1 brezak case SB_DAC_PORT:
468 1.1 brezak case SB_FM_PORT:
469 1.1 brezak default:
470 1.1 brezak return(EINVAL);
471 1.1 brezak /*NOTREACHED*/
472 1.1 brezak }
473 1.1 brezak }
474 1.1 brezak else {
475 1.1 brezak return(EINVAL);
476 1.1 brezak /*NOTREACHED*/
477 1.1 brezak }
478 1.1 brezak
479 1.1 brezak sc->in_port = port; /* Just record it */
480 1.1 brezak
481 1.1 brezak if (ISSBPROCLASS(sc)) {
482 1.1 brezak /* record from that port */
483 1.1 brezak sbdsp_mix_write(sc, SBP_RECORD_SOURCE,
484 1.1 brezak SBP_RECORD_FROM(sbport, SBP_FILTER_OFF,
485 1.1 brezak SBP_FILTER_HIGH));
486 1.1 brezak /* fetch gain from that port */
487 1.1 brezak sc->gain[port] = sbdsp_mix_read(sc, mixport);
488 1.1 brezak }
489 1.1 brezak
490 1.1 brezak return(0);
491 1.1 brezak }
492 1.1 brezak
493 1.1 brezak int
494 1.1 brezak sbdsp_get_in_port(addr)
495 1.5 mycroft void *addr;
496 1.1 brezak {
497 1.5 mycroft register struct sbdsp_softc *sc = addr;
498 1.1 brezak
499 1.1 brezak return(sc->in_port);
500 1.1 brezak }
501 1.1 brezak
502 1.1 brezak
503 1.1 brezak int
504 1.1 brezak sbdsp_speaker_ctl(addr, newstate)
505 1.5 mycroft void *addr;
506 1.1 brezak int newstate;
507 1.1 brezak {
508 1.5 mycroft register struct sbdsp_softc *sc = addr;
509 1.1 brezak
510 1.1 brezak if ((newstate == SPKR_ON) &&
511 1.1 brezak (sc->spkr_state == SPKR_OFF)) {
512 1.1 brezak sbdsp_spkron(sc);
513 1.1 brezak sc->spkr_state = SPKR_ON;
514 1.1 brezak }
515 1.1 brezak if ((newstate == SPKR_OFF) &&
516 1.1 brezak (sc->spkr_state == SPKR_ON)) {
517 1.1 brezak sbdsp_spkroff(sc);
518 1.1 brezak sc->spkr_state = SPKR_OFF;
519 1.1 brezak }
520 1.1 brezak return(0);
521 1.1 brezak }
522 1.1 brezak
523 1.1 brezak int
524 1.1 brezak sbdsp_round_blocksize(addr, blk)
525 1.5 mycroft void *addr;
526 1.1 brezak int blk;
527 1.1 brezak {
528 1.5 mycroft register struct sbdsp_softc *sc = addr;
529 1.1 brezak
530 1.1 brezak sc->sc_last_hsr_size = sc->sc_last_hsw_size = 0;
531 1.1 brezak
532 1.1 brezak /* Higher speeds need bigger blocks to avoid popping and silence gaps. */
533 1.1 brezak if ((sc->sc_orate > 8000 || sc->sc_irate > 8000) &&
534 1.1 brezak (blk > NBPG/2 || blk < NBPG/4))
535 1.1 brezak blk = NBPG/2;
536 1.1 brezak /* don't try to DMA too much at once, though. */
537 1.1 brezak if (blk > NBPG) blk = NBPG;
538 1.1 brezak if (sc->sc_chans == 2)
539 1.1 brezak return (blk & ~1); /* must be even to preserve stereo separation */
540 1.1 brezak else
541 1.1 brezak return(blk); /* Anything goes :-) */
542 1.1 brezak }
543 1.1 brezak
544 1.1 brezak int
545 1.1 brezak sbdsp_commit_settings(addr)
546 1.5 mycroft void *addr;
547 1.1 brezak {
548 1.1 brezak /* due to potentially unfortunate ordering in the above layers,
549 1.1 brezak re-do a few sets which may be important--input gains
550 1.1 brezak (adjust the proper channels), number of input channels (hit the
551 1.1 brezak record rate and set mode) */
552 1.1 brezak
553 1.5 mycroft register struct sbdsp_softc *sc = addr;
554 1.1 brezak
555 1.3 brezak sbdsp_set_out_sr_real(addr, sc->sc_orate);
556 1.3 brezak sbdsp_set_in_sr_real(addr, sc->sc_irate);
557 1.3 brezak
558 1.1 brezak sc->sc_last_hsw_size = sc->sc_last_hsr_size = 0;
559 1.1 brezak return(0);
560 1.1 brezak }
561 1.1 brezak
562 1.1 brezak
563 1.1 brezak int
564 1.1 brezak sbdsp_open(sc, dev, flags)
565 1.1 brezak register struct sbdsp_softc *sc;
566 1.1 brezak dev_t dev;
567 1.1 brezak int flags;
568 1.1 brezak {
569 1.1 brezak DPRINTF(("sbdsp_open: sc=0x%x\n", sc));
570 1.1 brezak
571 1.1 brezak if (sc->sc_open != 0 || sbdsp_reset(sc) != 0)
572 1.1 brezak return ENXIO;
573 1.1 brezak
574 1.1 brezak sc->sc_open = 1;
575 1.1 brezak sc->sc_mintr = 0;
576 1.1 brezak sc->sc_intr = 0;
577 1.1 brezak sc->sc_arg = 0;
578 1.1 brezak sc->sc_locked = 0;
579 1.1 brezak if (ISSBPROCLASS(sc) &&
580 1.1 brezak sbdsp_wdsp(sc->sc_iobase, SB_DSP_RECORD_MONO) < 0) {
581 1.1 brezak DPRINTF(("sbdsp_open: can't set mono mode\n"));
582 1.1 brezak /* we'll readjust when it's time for DMA. */
583 1.1 brezak }
584 1.1 brezak sc->sc_dmain_inprogress = 0;
585 1.1 brezak sc->sc_dmaout_inprogress = 0;
586 1.1 brezak
587 1.1 brezak /*
588 1.1 brezak * Leave most things as they were; users must change things if
589 1.1 brezak * the previous process didn't leave it they way they wanted.
590 1.1 brezak * Looked at another way, it's easy to set up a configuration
591 1.1 brezak * in one program and leave it for another to inherit.
592 1.1 brezak */
593 1.1 brezak DPRINTF(("sbdsp_open: opened\n"));
594 1.1 brezak
595 1.1 brezak return 0;
596 1.1 brezak }
597 1.1 brezak
598 1.1 brezak void
599 1.1 brezak sbdsp_close(addr)
600 1.5 mycroft void *addr;
601 1.1 brezak {
602 1.5 mycroft struct sbdsp_softc *sc = addr;
603 1.1 brezak
604 1.1 brezak DPRINTF(("sbdsp_close: sc=0x%x\n", sc));
605 1.1 brezak
606 1.1 brezak sc->sc_open = 0;
607 1.1 brezak sbdsp_spkroff(sc);
608 1.1 brezak sc->spkr_state = SPKR_OFF;
609 1.1 brezak sc->sc_intr = 0;
610 1.1 brezak sc->sc_mintr = 0;
611 1.1 brezak /* XXX this will turn off any dma */
612 1.1 brezak sbdsp_reset(sc);
613 1.1 brezak
614 1.1 brezak DPRINTF(("sbdsp_close: closed\n"));
615 1.1 brezak }
616 1.1 brezak
617 1.1 brezak /*
618 1.1 brezak * Lower-level routines
619 1.1 brezak */
620 1.1 brezak
621 1.1 brezak /*
622 1.1 brezak * Reset the card.
623 1.1 brezak * Return non-zero if the card isn't detected.
624 1.1 brezak */
625 1.1 brezak int
626 1.1 brezak sbdsp_reset(sc)
627 1.1 brezak register struct sbdsp_softc *sc;
628 1.1 brezak {
629 1.1 brezak register u_short iobase = sc->sc_iobase;
630 1.1 brezak
631 1.1 brezak /*
632 1.1 brezak * erase any memory of last transfer size.
633 1.1 brezak */
634 1.1 brezak sc->sc_last_hsr_size = sc->sc_last_hsw_size = 0;
635 1.1 brezak /*
636 1.1 brezak * See SBK, section 11.3.
637 1.1 brezak * We pulse a reset signal into the card.
638 1.1 brezak * Gee, what a brilliant hardware design.
639 1.1 brezak */
640 1.1 brezak outb(iobase + SBP_DSP_RESET, 1);
641 1.1 brezak delay(3);
642 1.1 brezak outb(iobase + SBP_DSP_RESET, 0);
643 1.1 brezak if (sbdsp_rdsp(iobase) != SB_MAGIC)
644 1.1 brezak return -1;
645 1.1 brezak return 0;
646 1.1 brezak }
647 1.1 brezak
648 1.1 brezak /*
649 1.1 brezak * Write a byte to the dsp.
650 1.1 brezak * XXX We are at the mercy of the card as we use a
651 1.1 brezak * polling loop and wait until it can take the byte.
652 1.1 brezak */
653 1.1 brezak int
654 1.1 brezak sbdsp_wdsp(u_short iobase, int v)
655 1.1 brezak {
656 1.1 brezak register int i;
657 1.1 brezak
658 1.1 brezak for (i = SBDSP_NPOLL; --i >= 0; ) {
659 1.1 brezak if ((inb(iobase + SBP_DSP_WSTAT) & SB_DSP_BUSY) != 0) {
660 1.1 brezak delay(10); continue;
661 1.1 brezak }
662 1.1 brezak outb(iobase + SBP_DSP_WRITE, v);
663 1.1 brezak return 0;
664 1.1 brezak }
665 1.1 brezak ++sberr.wdsp;
666 1.1 brezak return -1;
667 1.1 brezak }
668 1.1 brezak
669 1.1 brezak /*
670 1.1 brezak * Read a byte from the DSP, using polling.
671 1.1 brezak */
672 1.1 brezak int
673 1.1 brezak sbdsp_rdsp(u_short iobase)
674 1.1 brezak {
675 1.1 brezak register int i;
676 1.1 brezak
677 1.1 brezak for (i = SBDSP_NPOLL; --i >= 0; ) {
678 1.1 brezak if ((inb(iobase + SBP_DSP_RSTAT) & SB_DSP_READY) == 0)
679 1.1 brezak continue;
680 1.1 brezak return inb(iobase + SBP_DSP_READ);
681 1.1 brezak }
682 1.1 brezak ++sberr.rdsp;
683 1.1 brezak return -1;
684 1.1 brezak }
685 1.1 brezak
686 1.1 brezak /*
687 1.1 brezak * Doing certain things (like toggling the speaker) make
688 1.1 brezak * the SB hardware go away for a while, so pause a little.
689 1.1 brezak */
690 1.1 brezak void
691 1.1 brezak sbdsp_to(arg)
692 1.1 brezak void *arg;
693 1.1 brezak {
694 1.1 brezak wakeup(arg);
695 1.1 brezak }
696 1.1 brezak
697 1.1 brezak void
698 1.1 brezak sbdsp_pause(sc)
699 1.1 brezak struct sbdsp_softc *sc;
700 1.1 brezak {
701 1.1 brezak extern int hz;
702 1.1 brezak
703 1.1 brezak timeout(sbdsp_to, sbdsp_to, hz/8);
704 1.5 mycroft (void)tsleep(sbdsp_to, PWAIT, "sbpause", 0);
705 1.1 brezak }
706 1.1 brezak
707 1.1 brezak /*
708 1.1 brezak * Turn on the speaker. The SBK documention says this operation
709 1.1 brezak * can take up to 1/10 of a second. Higher level layers should
710 1.1 brezak * probably let the task sleep for this amount of time after
711 1.1 brezak * calling here. Otherwise, things might not work (because
712 1.1 brezak * sbdsp_wdsp() and sbdsp_rdsp() will probably timeout.)
713 1.1 brezak *
714 1.1 brezak * These engineers had their heads up their ass when
715 1.1 brezak * they designed this card.
716 1.1 brezak */
717 1.1 brezak void
718 1.1 brezak sbdsp_spkron(sc)
719 1.1 brezak struct sbdsp_softc *sc;
720 1.1 brezak {
721 1.1 brezak (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_SPKR_ON);
722 1.1 brezak sbdsp_pause(sc);
723 1.1 brezak }
724 1.1 brezak
725 1.1 brezak /*
726 1.1 brezak * Turn off the speaker; see comment above.
727 1.1 brezak */
728 1.1 brezak void
729 1.1 brezak sbdsp_spkroff(sc)
730 1.1 brezak struct sbdsp_softc *sc;
731 1.1 brezak {
732 1.1 brezak (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_SPKR_OFF);
733 1.1 brezak sbdsp_pause(sc);
734 1.1 brezak }
735 1.1 brezak
736 1.1 brezak /*
737 1.1 brezak * Read the version number out of the card. Return major code
738 1.1 brezak * in high byte, and minor code in low byte.
739 1.1 brezak */
740 1.1 brezak short
741 1.1 brezak sbversion(sc)
742 1.1 brezak struct sbdsp_softc *sc;
743 1.1 brezak {
744 1.1 brezak register u_short iobase = sc->sc_iobase;
745 1.1 brezak short v;
746 1.1 brezak
747 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_VERSION) < 0)
748 1.1 brezak return 0;
749 1.1 brezak v = sbdsp_rdsp(iobase) << 8;
750 1.1 brezak v |= sbdsp_rdsp(iobase);
751 1.1 brezak return ((v >= 0) ? v : 0);
752 1.1 brezak }
753 1.1 brezak
754 1.1 brezak /*
755 1.1 brezak * Halt a DMA in progress. A low-speed transfer can be
756 1.1 brezak * resumed with sbdsp_contdma().
757 1.1 brezak */
758 1.1 brezak int
759 1.1 brezak sbdsp_haltdma(addr)
760 1.5 mycroft void *addr;
761 1.1 brezak {
762 1.5 mycroft register struct sbdsp_softc *sc = addr;
763 1.1 brezak
764 1.1 brezak DPRINTF(("sbdsp_haltdma: sc=0x%x\n", sc));
765 1.1 brezak
766 1.1 brezak if (sc->sc_locked)
767 1.1 brezak sbdsp_reset(sc);
768 1.1 brezak else
769 1.1 brezak (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_HALT);
770 1.1 brezak
771 1.1 brezak isa_dmaabort(sc->sc_drq);
772 1.1 brezak sc->dmaaddr = 0;
773 1.1 brezak sc->dmacnt = 0;
774 1.1 brezak sc->sc_locked = 0;
775 1.1 brezak sc->dmaflags = 0;
776 1.1 brezak sc->sc_dmain_inprogress = sc->sc_dmaout_inprogress = 0;
777 1.1 brezak return(0);
778 1.1 brezak }
779 1.1 brezak
780 1.1 brezak int
781 1.1 brezak sbdsp_contdma(addr)
782 1.5 mycroft void *addr;
783 1.1 brezak {
784 1.5 mycroft register struct sbdsp_softc *sc = addr;
785 1.1 brezak
786 1.1 brezak DPRINTF(("sbdsp_contdma: sc=0x%x\n", sc));
787 1.1 brezak
788 1.1 brezak /* XXX how do we reinitialize the DMA controller state? do we care? */
789 1.1 brezak (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_CONT);
790 1.1 brezak return(0);
791 1.1 brezak }
792 1.1 brezak
793 1.1 brezak /*
794 1.1 brezak * Time constant routines follow. See SBK, section 12.
795 1.1 brezak * Although they don't come out and say it (in the docs),
796 1.1 brezak * the card clearly uses a 1MHz countdown timer, as the
797 1.1 brezak * low-speed formula (p. 12-4) is:
798 1.1 brezak * tc = 256 - 10^6 / sr
799 1.1 brezak * In high-speed mode, the constant is the upper byte of a 16-bit counter,
800 1.1 brezak * and a 256MHz clock is used:
801 1.1 brezak * tc = 65536 - 256 * 10^ 6 / sr
802 1.1 brezak * Since we can only use the upper byte of the HS TC, the two formulae
803 1.1 brezak * are equivalent. (Why didn't they say so?) E.g.,
804 1.1 brezak * (65536 - 256 * 10 ^ 6 / x) >> 8 = 256 - 10^6 / x
805 1.1 brezak *
806 1.1 brezak * The crossover point (from low- to high-speed modes) is different
807 1.1 brezak * for the SBPRO and SB20. The table on p. 12-5 gives the following data:
808 1.1 brezak *
809 1.1 brezak * SBPRO SB20
810 1.1 brezak * ----- --------
811 1.1 brezak * input ls min 4 KHz 4 KHz
812 1.1 brezak * input ls max 23 KHz 13 KHz
813 1.1 brezak * input hs max 44.1 KHz 15 KHz
814 1.1 brezak * output ls min 4 KHz 4 KHz
815 1.1 brezak * output ls max 23 KHz 23 KHz
816 1.1 brezak * output hs max 44.1 KHz 44.1 KHz
817 1.1 brezak */
818 1.1 brezak #define SB_LS_MIN 0x06 /* 4000 Hz */
819 1.1 brezak #define SBPRO_ADC_LS_MAX 0xd4 /* 22727 Hz */
820 1.1 brezak #define SBPRO_ADC_HS_MAX 0xea /* 45454 Hz */
821 1.1 brezak #define SBCLA_ADC_LS_MAX 0xb3 /* 12987 Hz */
822 1.1 brezak #define SBCLA_ADC_HS_MAX 0xbd /* 14925 Hz */
823 1.1 brezak #define SB_DAC_LS_MAX 0xd4 /* 22727 Hz */
824 1.1 brezak #define SB_DAC_HS_MAX 0xea /* 45454 Hz */
825 1.1 brezak
826 1.1 brezak /*
827 1.1 brezak * Convert a linear sampling rate into the DAC time constant.
828 1.1 brezak * Set *mode to indicate the high/low-speed DMA operation.
829 1.1 brezak * Because of limitations of the card, not all rates are possible.
830 1.1 brezak * We return the time constant of the closest possible rate.
831 1.1 brezak * The sampling rate limits are different for the DAC and ADC,
832 1.1 brezak * so isdac indicates output, and !isdac indicates input.
833 1.1 brezak */
834 1.1 brezak int
835 1.1 brezak sbdsp_srtotc(sc, sr, mode, isdac)
836 1.1 brezak register struct sbdsp_softc *sc;
837 1.1 brezak int sr;
838 1.1 brezak int *mode;
839 1.1 brezak int isdac;
840 1.1 brezak {
841 1.1 brezak int adc_ls_max, adc_hs_max;
842 1.1 brezak register int tc;
843 1.1 brezak
844 1.1 brezak if (sr == 0) {
845 1.1 brezak *mode = SB_ADAC_LS;
846 1.1 brezak return SB_LS_MIN;
847 1.1 brezak }
848 1.1 brezak tc = 256 - 1000000 / sr;
849 1.1 brezak
850 1.1 brezak /* XXX use better rounding--compare distance to nearest tc on both
851 1.1 brezak sides of requested speed */
852 1.1 brezak if (ISSBPROCLASS(sc)) {
853 1.1 brezak adc_ls_max = SBPRO_ADC_LS_MAX;
854 1.1 brezak adc_hs_max = SBPRO_ADC_HS_MAX;
855 1.1 brezak }
856 1.1 brezak else {
857 1.1 brezak adc_ls_max = SBCLA_ADC_LS_MAX;
858 1.1 brezak adc_hs_max = SBCLA_ADC_HS_MAX;
859 1.1 brezak }
860 1.1 brezak
861 1.1 brezak if (tc < SB_LS_MIN) {
862 1.1 brezak tc = SB_LS_MIN;
863 1.1 brezak *mode = SB_ADAC_LS;
864 1.1 brezak } else if (isdac) {
865 1.1 brezak if (tc <= SB_DAC_LS_MAX)
866 1.1 brezak *mode = SB_ADAC_LS;
867 1.1 brezak else {
868 1.1 brezak *mode = SB_ADAC_HS;
869 1.1 brezak if (tc > SB_DAC_HS_MAX)
870 1.1 brezak tc = SB_DAC_HS_MAX;
871 1.1 brezak }
872 1.1 brezak } else {
873 1.1 brezak if (tc <= adc_ls_max)
874 1.1 brezak *mode = SB_ADAC_LS;
875 1.1 brezak else {
876 1.1 brezak *mode = SB_ADAC_HS;
877 1.1 brezak if (tc > adc_hs_max)
878 1.1 brezak tc = adc_hs_max;
879 1.1 brezak }
880 1.1 brezak }
881 1.1 brezak return tc;
882 1.1 brezak }
883 1.1 brezak
884 1.1 brezak /*
885 1.1 brezak * Convert a DAC time constant to a sampling rate.
886 1.1 brezak * See SBK, section 12.
887 1.1 brezak */
888 1.1 brezak int
889 1.1 brezak sbdsp_tctosr(sc, tc)
890 1.1 brezak register struct sbdsp_softc *sc;
891 1.1 brezak int tc;
892 1.1 brezak {
893 1.1 brezak int adc;
894 1.1 brezak
895 1.1 brezak if (ISSBPROCLASS(sc))
896 1.1 brezak adc = SBPRO_ADC_HS_MAX;
897 1.1 brezak else
898 1.1 brezak adc = SBCLA_ADC_HS_MAX;
899 1.1 brezak
900 1.1 brezak if (tc > adc)
901 1.1 brezak tc = adc;
902 1.1 brezak
903 1.1 brezak return (1000000 / (256 - tc));
904 1.1 brezak }
905 1.1 brezak
906 1.1 brezak int
907 1.1 brezak sbdsp_set_sr(sc, srp, isdac)
908 1.1 brezak register struct sbdsp_softc *sc;
909 1.1 brezak u_long *srp;
910 1.1 brezak int isdac;
911 1.1 brezak {
912 1.1 brezak register int tc;
913 1.1 brezak int mode;
914 1.1 brezak int sr = *srp;
915 1.1 brezak register u_short iobase;
916 1.1 brezak
917 1.1 brezak /*
918 1.1 brezak * A SBPro in stereo mode uses time constants at double the
919 1.1 brezak * actual rate.
920 1.1 brezak */
921 1.1 brezak if (ISSBPRO(sc) && sc->sc_chans == 2) {
922 1.1 brezak if (sr > 22727)
923 1.1 brezak sr = 22727; /* Can't bounce it...order of
924 1.1 brezak operations may yield bogus
925 1.1 brezak sr here. */
926 1.1 brezak sr *= 2;
927 1.1 brezak }
928 1.1 brezak else if (!ISSBPROCLASS(sc) && sc->sc_chans != 1)
929 1.1 brezak return EINVAL;
930 1.1 brezak
931 1.1 brezak tc = sbdsp_srtotc(sc, sr, &mode, isdac);
932 1.1 brezak DPRINTF(("sbdsp_set_sr: sc=0x%x sr=%d mode=0x%x\n", sc, sr, mode));
933 1.1 brezak
934 1.1 brezak iobase = sc->sc_iobase;
935 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_TIMECONST) < 0 ||
936 1.1 brezak sbdsp_wdsp(iobase, tc) < 0)
937 1.1 brezak return EIO;
938 1.1 brezak
939 1.1 brezak sr = sbdsp_tctosr(sc, tc);
940 1.1 brezak if (ISSBPRO(sc) && sc->sc_chans == 2)
941 1.1 brezak *srp = sr / 2;
942 1.1 brezak else
943 1.1 brezak *srp = sr;
944 1.1 brezak
945 1.1 brezak sc->sc_adacmode = mode;
946 1.1 brezak sc->sc_adactc = tc;
947 1.1 brezak return 0;
948 1.1 brezak }
949 1.1 brezak
950 1.1 brezak int
951 1.1 brezak sbdsp_dma_input(addr, p, cc, intr, arg)
952 1.5 mycroft void *addr;
953 1.1 brezak void *p;
954 1.1 brezak int cc;
955 1.1 brezak void (*intr)();
956 1.1 brezak void *arg;
957 1.1 brezak {
958 1.5 mycroft register struct sbdsp_softc *sc = addr;
959 1.1 brezak register u_short iobase;
960 1.1 brezak u_int phys;
961 1.1 brezak
962 1.1 brezak #ifdef DEBUG
963 1.1 brezak if (sbdspdebug > 1)
964 1.1 brezak Dprintf("sbdsp_dma_input: cc=%d 0x%x (0x%x)\n", cc, intr, arg);
965 1.1 brezak #endif
966 1.1 brezak if (sc->sc_chans == 2 && (cc & 1)) {
967 1.1 brezak DPRINTF(("sbdsp_dma_input: stereo input, odd bytecnt\n"));
968 1.1 brezak return EIO;
969 1.1 brezak }
970 1.1 brezak iobase = sc->sc_iobase;
971 1.1 brezak if (ISSBPROCLASS(sc) && !sc->sc_dmain_inprogress) {
972 1.1 brezak if (sc->sc_chans == 2) {
973 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_RECORD_STEREO) < 0)
974 1.1 brezak goto badmode;
975 1.1 brezak sbdsp_mix_write(sc, SBP_STEREO,
976 1.1 brezak sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK);
977 1.1 brezak sbdsp_mix_write(sc, SBP_INFILTER,
978 1.1 brezak sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF);
979 1.1 brezak }
980 1.1 brezak else {
981 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_RECORD_MONO) < 0)
982 1.1 brezak goto badmode;
983 1.1 brezak sbdsp_mix_write(sc, SBP_STEREO,
984 1.1 brezak sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK);
985 1.1 brezak sbdsp_mix_write(sc, SBP_INFILTER,
986 1.1 brezak sc->sc_irate <= 8000 ?
987 1.1 brezak sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_FILTER_MASK :
988 1.1 brezak sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF);
989 1.1 brezak }
990 1.1 brezak sc->sc_dmain_inprogress = 1;
991 1.1 brezak sc->sc_last_hsr_size = 0; /* restarting */
992 1.1 brezak }
993 1.1 brezak sc->sc_dmaout_inprogress = 0;
994 1.1 brezak
995 1.1 brezak at_dma(B_READ, p, cc, sc->sc_drq);
996 1.1 brezak sc->sc_intr = intr;
997 1.1 brezak sc->sc_arg = arg;
998 1.1 brezak sc->dmaflags = B_READ;
999 1.1 brezak sc->dmaaddr = p;
1000 1.1 brezak sc->dmacnt = --cc; /* DMA controller is strange...? */
1001 1.1 brezak if (sc->sc_adacmode == SB_ADAC_LS) {
1002 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_RDMA) < 0 ||
1003 1.1 brezak sbdsp_wdsp(iobase, cc) < 0 ||
1004 1.1 brezak sbdsp_wdsp(iobase, cc >> 8) < 0) {
1005 1.1 brezak goto giveup;
1006 1.1 brezak }
1007 1.1 brezak }
1008 1.1 brezak else {
1009 1.1 brezak if (cc != sc->sc_last_hsr_size) {
1010 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 ||
1011 1.1 brezak sbdsp_wdsp(iobase, cc) < 0 ||
1012 1.1 brezak sbdsp_wdsp(iobase, cc >> 8) < 0)
1013 1.1 brezak goto giveup;
1014 1.1 brezak }
1015 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_HS_INPUT) < 0)
1016 1.1 brezak goto giveup;
1017 1.1 brezak sc->sc_last_hsr_size = cc;
1018 1.1 brezak sc->sc_locked = 1;
1019 1.1 brezak }
1020 1.1 brezak return 0;
1021 1.1 brezak
1022 1.1 brezak giveup:
1023 1.1 brezak isa_dmaabort(sc->sc_drq);
1024 1.1 brezak sbdsp_reset(sc);
1025 1.1 brezak sc->sc_intr = 0;
1026 1.1 brezak sc->sc_arg = 0;
1027 1.1 brezak return EIO;
1028 1.1 brezak badmode:
1029 1.1 brezak DPRINTF(("sbdsp_dma_input: can't set %s mode\n",
1030 1.1 brezak sc->sc_chans == 2 ? "stereo" : "mono"));
1031 1.1 brezak return EIO;
1032 1.1 brezak }
1033 1.1 brezak
1034 1.1 brezak int
1035 1.1 brezak sbdsp_dma_output(addr, p, cc, intr, arg)
1036 1.5 mycroft void *addr;
1037 1.1 brezak void *p;
1038 1.1 brezak int cc;
1039 1.1 brezak void (*intr)();
1040 1.1 brezak void *arg;
1041 1.1 brezak {
1042 1.5 mycroft register struct sbdsp_softc *sc = addr;
1043 1.1 brezak register u_short iobase;
1044 1.1 brezak
1045 1.1 brezak #ifdef DEBUG
1046 1.1 brezak if (sbdspdebug > 1)
1047 1.1 brezak Dprintf("sbdsp_dma_output: cc=%d 0x%x (0x%x)\n", cc, intr, arg);
1048 1.1 brezak #endif
1049 1.1 brezak if (sc->sc_chans == 2 && cc & 1) {
1050 1.1 brezak DPRINTF(("stereo playback odd bytes (%d)\n", cc));
1051 1.1 brezak return EIO;
1052 1.1 brezak }
1053 1.1 brezak
1054 1.1 brezak if (ISSBPROCLASS(sc) && !sc->sc_dmaout_inprogress) {
1055 1.1 brezak /* make sure we re-set stereo mixer bit when we start
1056 1.1 brezak output. */
1057 1.1 brezak sbdsp_mix_write(sc, SBP_STEREO,
1058 1.1 brezak (sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) |
1059 1.1 brezak (sc->sc_chans == 2 ?
1060 1.1 brezak SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO));
1061 1.1 brezak sc->sc_dmaout_inprogress = 1;
1062 1.1 brezak sc->sc_last_hsw_size = 0; /* restarting */
1063 1.1 brezak }
1064 1.1 brezak sc->sc_dmain_inprogress = 0;
1065 1.1 brezak at_dma(B_WRITE, p, cc, sc->sc_drq);
1066 1.1 brezak sc->sc_intr = intr;
1067 1.1 brezak sc->sc_arg = arg;
1068 1.1 brezak sc->dmaflags = B_WRITE;
1069 1.1 brezak sc->dmaaddr = p;
1070 1.1 brezak sc->dmacnt = --cc; /* a vagary of how DMA works, apparently. */
1071 1.1 brezak
1072 1.1 brezak iobase = sc->sc_iobase;
1073 1.1 brezak if (sc->sc_adacmode == SB_ADAC_LS) {
1074 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_WDMA) < 0 ||
1075 1.1 brezak sbdsp_wdsp(iobase, cc) < 0 ||
1076 1.1 brezak sbdsp_wdsp(iobase, cc >> 8) < 0) {
1077 1.1 brezak DPRINTF(("sbdsp_dma_output: LS DMA start failed\n"));
1078 1.1 brezak goto giveup;
1079 1.1 brezak }
1080 1.1 brezak }
1081 1.1 brezak else {
1082 1.1 brezak if (cc != sc->sc_last_hsw_size) {
1083 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0) {
1084 1.1 brezak /* sometimes fails initial startup?? */
1085 1.1 brezak delay(100);
1086 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0) {
1087 1.1 brezak DPRINTF(("sbdsp_dma_output: BLOCKSIZE failed\n"));
1088 1.1 brezak goto giveup;
1089 1.1 brezak }
1090 1.1 brezak }
1091 1.1 brezak if (sbdsp_wdsp(iobase, cc) < 0 ||
1092 1.1 brezak sbdsp_wdsp(iobase, cc >> 8) < 0) {
1093 1.1 brezak DPRINTF(("sbdsp_dma_output: HS DMA start failed\n"));
1094 1.1 brezak goto giveup;
1095 1.1 brezak }
1096 1.1 brezak sc->sc_last_hsw_size = cc;
1097 1.1 brezak }
1098 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_HS_OUTPUT) < 0) {
1099 1.1 brezak delay(100);
1100 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_HS_OUTPUT) < 0) {
1101 1.1 brezak DPRINTF(("sbdsp_dma_output: HS DMA restart failed\n"));
1102 1.1 brezak goto giveup;
1103 1.1 brezak }
1104 1.1 brezak }
1105 1.1 brezak sc->sc_locked = 1;
1106 1.1 brezak }
1107 1.1 brezak
1108 1.1 brezak return 0;
1109 1.1 brezak
1110 1.1 brezak giveup:
1111 1.1 brezak isa_dmaabort(sc->sc_drq);
1112 1.1 brezak sbdsp_reset(sc);
1113 1.1 brezak sc->sc_intr = 0;
1114 1.1 brezak sc->sc_arg = 0;
1115 1.1 brezak return EIO;
1116 1.1 brezak }
1117 1.1 brezak
1118 1.1 brezak /*
1119 1.1 brezak * Only the DSP unit on the sound blaster generates interrupts.
1120 1.1 brezak * There are three cases of interrupt: reception of a midi byte
1121 1.1 brezak * (when mode is enabled), completion of dma transmission, or
1122 1.1 brezak * completion of a dma reception. The three modes are mutually
1123 1.1 brezak * exclusive so we know a priori which event has occurred.
1124 1.1 brezak */
1125 1.1 brezak int
1126 1.1 brezak sbdsp_intr(sc)
1127 1.1 brezak register struct sbdsp_softc *sc;
1128 1.1 brezak {
1129 1.1 brezak
1130 1.1 brezak #ifdef DEBUG
1131 1.1 brezak if (sbdspdebug > 1)
1132 1.1 brezak Dprintf("sbdsp_intr: intr=0x%x\n", sc->sc_intr);
1133 1.1 brezak #endif
1134 1.1 brezak sc->sc_interrupts++;
1135 1.1 brezak sc->sc_locked = 0;
1136 1.1 brezak /* clear interrupt */
1137 1.1 brezak inb(sc->sc_iobase + SBP_DSP_RSTAT);
1138 1.1 brezak #if 0
1139 1.1 brezak if (sc->sc_mintr != 0) {
1140 1.1 brezak int c = sbdsp_rdsp(sc->sc_iobase);
1141 1.1 brezak (*sc->sc_mintr)(sc->sc_arg, c);
1142 1.1 brezak } else
1143 1.1 brezak #endif
1144 1.1 brezak if (sc->sc_intr != 0) {
1145 1.1 brezak /*
1146 1.1 brezak * The SBPro used to develop and test this driver often
1147 1.1 brezak * generated dma underruns--it interrupted to signal
1148 1.1 brezak * completion of the DMA input recording block, but the
1149 1.1 brezak * ISA DMA controller didn't think the channel was
1150 1.1 brezak * finished. Maybe this is just a bus speed issue, I dunno,
1151 1.1 brezak * but it seems strange and leads to channel-flipping with stereo
1152 1.1 brezak * recording. Sigh.
1153 1.1 brezak */
1154 1.1 brezak isa_dmadone(sc->dmaflags, sc->dmaaddr, sc->dmacnt,
1155 1.1 brezak sc->sc_drq);
1156 1.1 brezak sc->dmaflags = 0;
1157 1.1 brezak sc->dmaaddr = 0;
1158 1.1 brezak sc->dmacnt = 0;
1159 1.1 brezak (*sc->sc_intr)(sc->sc_arg);
1160 1.1 brezak }
1161 1.1 brezak else
1162 1.1 brezak return 0;
1163 1.1 brezak return 1;
1164 1.1 brezak }
1165 1.1 brezak
1166 1.1 brezak #if 0
1167 1.1 brezak /*
1168 1.1 brezak * Enter midi uart mode and arrange for read interrupts
1169 1.1 brezak * to vector to `intr'. This puts the card in a mode
1170 1.1 brezak * which allows only midi I/O; the card must be reset
1171 1.1 brezak * to leave this mode. Unfortunately, the card does not
1172 1.1 brezak * use transmit interrupts, so bytes must be output
1173 1.1 brezak * using polling. To keep the polling overhead to a
1174 1.1 brezak * minimum, output should be driven off a timer.
1175 1.1 brezak * This is a little tricky since only 320us separate
1176 1.1 brezak * consecutive midi bytes.
1177 1.1 brezak */
1178 1.1 brezak void
1179 1.1 brezak sbdsp_set_midi_mode(sc, intr, arg)
1180 1.1 brezak struct sbdsp_softc *sc;
1181 1.1 brezak void (*intr)();
1182 1.1 brezak void *arg;
1183 1.1 brezak {
1184 1.1 brezak
1185 1.1 brezak sbdsp_wdsp(sc->sc_iobase, SB_MIDI_UART_INTR);
1186 1.1 brezak sc->sc_mintr = intr;
1187 1.1 brezak sc->sc_intr = 0;
1188 1.1 brezak sc->sc_arg = arg;
1189 1.1 brezak }
1190 1.1 brezak
1191 1.1 brezak /*
1192 1.1 brezak * Write a byte to the midi port, when in midi uart mode.
1193 1.1 brezak */
1194 1.1 brezak void
1195 1.1 brezak sbdsp_midi_output(sc, v)
1196 1.1 brezak struct sbdsp_softc *sc;
1197 1.1 brezak int v;
1198 1.1 brezak {
1199 1.1 brezak
1200 1.1 brezak if (sbdsp_wdsp(sc->sc_iobase, v) < 0)
1201 1.1 brezak ++sberr.wmidi;
1202 1.1 brezak }
1203 1.1 brezak #endif
1204 1.1 brezak
1205 1.1 brezak u_int
1206 1.1 brezak sbdsp_get_silence(enc)
1207 1.1 brezak int enc;
1208 1.1 brezak {
1209 1.1 brezak #define ULAW_SILENCE 0x7f
1210 1.1 brezak #define LINEAR_SILENCE 0
1211 1.1 brezak u_int auzero;
1212 1.1 brezak
1213 1.1 brezak switch (enc) {
1214 1.1 brezak case AUDIO_ENCODING_ULAW:
1215 1.1 brezak auzero = ULAW_SILENCE;
1216 1.1 brezak break;
1217 1.1 brezak case AUDIO_ENCODING_PCM16:
1218 1.1 brezak default:
1219 1.1 brezak auzero = LINEAR_SILENCE;
1220 1.1 brezak break;
1221 1.1 brezak }
1222 1.1 brezak
1223 1.1 brezak return(auzero);
1224 1.1 brezak }
1225 1.1 brezak
1226 1.1 brezak static u_char mulawtolin[256] = {
1227 1.1 brezak 128, 4, 8, 12, 16, 20, 24, 28,
1228 1.1 brezak 32, 36, 40, 44, 48, 52, 56, 60,
1229 1.1 brezak 64, 66, 68, 70, 72, 74, 76, 78,
1230 1.1 brezak 80, 82, 84, 86, 88, 90, 92, 94,
1231 1.1 brezak 96, 97, 98, 99, 100, 101, 102, 103,
1232 1.1 brezak 104, 105, 106, 107, 108, 109, 110, 111,
1233 1.1 brezak 112, 112, 113, 113, 114, 114, 115, 115,
1234 1.1 brezak 116, 116, 117, 117, 118, 118, 119, 119,
1235 1.1 brezak 120, 120, 120, 121, 121, 121, 121, 122,
1236 1.1 brezak 122, 122, 122, 123, 123, 123, 123, 124,
1237 1.1 brezak 124, 124, 124, 124, 125, 125, 125, 125,
1238 1.1 brezak 125, 125, 125, 125, 126, 126, 126, 126,
1239 1.1 brezak 126, 126, 126, 126, 126, 126, 126, 126,
1240 1.1 brezak 127, 127, 127, 127, 127, 127, 127, 127,
1241 1.1 brezak 127, 127, 127, 127, 127, 127, 127, 127,
1242 1.1 brezak 127, 127, 127, 127, 127, 127, 127, 127,
1243 1.1 brezak 255, 251, 247, 243, 239, 235, 231, 227,
1244 1.1 brezak 223, 219, 215, 211, 207, 203, 199, 195,
1245 1.1 brezak 191, 189, 187, 185, 183, 181, 179, 177,
1246 1.1 brezak 175, 173, 171, 169, 167, 165, 163, 161,
1247 1.1 brezak 159, 158, 157, 156, 155, 154, 153, 152,
1248 1.1 brezak 151, 150, 149, 148, 147, 146, 145, 144,
1249 1.1 brezak 143, 143, 142, 142, 141, 141, 140, 140,
1250 1.1 brezak 139, 139, 138, 138, 137, 137, 136, 136,
1251 1.1 brezak 135, 135, 135, 134, 134, 134, 134, 133,
1252 1.1 brezak 133, 133, 133, 132, 132, 132, 132, 131,
1253 1.1 brezak 131, 131, 131, 131, 130, 130, 130, 130,
1254 1.1 brezak 130, 130, 130, 130, 129, 129, 129, 129,
1255 1.1 brezak 129, 129, 129, 129, 129, 129, 129, 129,
1256 1.1 brezak 128, 128, 128, 128, 128, 128, 128, 128,
1257 1.1 brezak 128, 128, 128, 128, 128, 128, 128, 128,
1258 1.1 brezak 128, 128, 128, 128, 128, 128, 128, 128,
1259 1.1 brezak };
1260 1.1 brezak
1261 1.1 brezak static u_char lintomulaw[256] = {
1262 1.1 brezak 0, 0, 0, 0, 0, 1, 1, 1,
1263 1.1 brezak 1, 2, 2, 2, 2, 3, 3, 3,
1264 1.1 brezak 3, 4, 4, 4, 4, 5, 5, 5,
1265 1.1 brezak 5, 6, 6, 6, 6, 7, 7, 7,
1266 1.1 brezak 7, 8, 8, 8, 8, 9, 9, 9,
1267 1.1 brezak 9, 10, 10, 10, 10, 11, 11, 11,
1268 1.1 brezak 11, 12, 12, 12, 12, 13, 13, 13,
1269 1.1 brezak 13, 14, 14, 14, 14, 15, 15, 15,
1270 1.1 brezak 15, 16, 16, 17, 17, 18, 18, 19,
1271 1.1 brezak 19, 20, 20, 21, 21, 22, 22, 23,
1272 1.1 brezak 23, 24, 24, 25, 25, 26, 26, 27,
1273 1.1 brezak 27, 28, 28, 29, 29, 30, 30, 31,
1274 1.1 brezak 31, 32, 33, 34, 35, 36, 37, 38,
1275 1.1 brezak 39, 40, 41, 42, 43, 44, 45, 46,
1276 1.1 brezak 47, 48, 50, 52, 54, 56, 58, 60,
1277 1.1 brezak 62, 65, 69, 73, 77, 83, 91, 103,
1278 1.1 brezak 255, 231, 219, 211, 205, 201, 197, 193,
1279 1.1 brezak 190, 188, 186, 184, 182, 180, 178, 176,
1280 1.1 brezak 175, 174, 173, 172, 171, 170, 169, 168,
1281 1.1 brezak 167, 166, 165, 164, 163, 162, 161, 160,
1282 1.1 brezak 159, 159, 158, 158, 157, 157, 156, 156,
1283 1.1 brezak 155, 155, 154, 154, 153, 153, 152, 152,
1284 1.1 brezak 151, 151, 150, 150, 149, 149, 148, 148,
1285 1.1 brezak 147, 147, 146, 146, 145, 145, 144, 144,
1286 1.1 brezak 143, 143, 143, 143, 142, 142, 142, 142,
1287 1.1 brezak 141, 141, 141, 141, 140, 140, 140, 140,
1288 1.1 brezak 139, 139, 139, 139, 138, 138, 138, 138,
1289 1.1 brezak 137, 137, 137, 137, 136, 136, 136, 136,
1290 1.1 brezak 135, 135, 135, 135, 134, 134, 134, 134,
1291 1.1 brezak 133, 133, 133, 133, 132, 132, 132, 132,
1292 1.1 brezak 131, 131, 131, 131, 130, 130, 130, 130,
1293 1.1 brezak 129, 129, 129, 129, 128, 128, 128, 128,
1294 1.1 brezak };
1295 1.1 brezak
1296 1.1 brezak void
1297 1.1 brezak sbdsp_compress(e, p, cc)
1298 1.1 brezak int e;
1299 1.1 brezak u_char *p;
1300 1.1 brezak int cc;
1301 1.1 brezak {
1302 1.1 brezak u_char *tab;
1303 1.1 brezak
1304 1.1 brezak switch (e) {
1305 1.1 brezak case AUDIO_ENCODING_ULAW:
1306 1.1 brezak tab = lintomulaw;
1307 1.1 brezak break;
1308 1.1 brezak default:
1309 1.1 brezak return;
1310 1.1 brezak }
1311 1.1 brezak
1312 1.1 brezak while (--cc >= 0) {
1313 1.1 brezak *p = tab[*p];
1314 1.1 brezak ++p;
1315 1.1 brezak }
1316 1.1 brezak }
1317 1.1 brezak
1318 1.1 brezak void
1319 1.1 brezak sbdsp_expand(e, p, cc)
1320 1.1 brezak int e;
1321 1.1 brezak u_char *p;
1322 1.1 brezak int cc;
1323 1.1 brezak {
1324 1.1 brezak u_char *tab;
1325 1.1 brezak
1326 1.1 brezak switch (e) {
1327 1.1 brezak case AUDIO_ENCODING_ULAW:
1328 1.1 brezak tab = mulawtolin;
1329 1.1 brezak break;
1330 1.1 brezak default:
1331 1.1 brezak return;
1332 1.1 brezak }
1333 1.1 brezak
1334 1.1 brezak while (--cc >= 0) {
1335 1.1 brezak *p = tab[*p];
1336 1.1 brezak ++p;
1337 1.1 brezak }
1338 1.1 brezak }
1339 1.1 brezak
1340 1.1 brezak int
1341 1.1 brezak sbdsp_setfd(addr, flag)
1342 1.5 mycroft void *addr;
1343 1.1 brezak int flag;
1344 1.1 brezak {
1345 1.1 brezak /* Can't do full-duplex */
1346 1.1 brezak return(ENOTTY);
1347 1.1 brezak }
1348 1.1 brezak
1349 1.1 brezak int
1350 1.1 brezak sbdsp_mixer_set_port(addr, cp)
1351 1.5 mycroft void *addr;
1352 1.1 brezak mixer_ctrl_t *cp;
1353 1.1 brezak {
1354 1.5 mycroft register struct sbdsp_softc *sc = addr;
1355 1.1 brezak int error = 0;
1356 1.1 brezak int src, gain;
1357 1.1 brezak int left, right;
1358 1.1 brezak
1359 1.1 brezak DPRINTF(("sbdsp_mixer_set_port: port=%d num_channels=%d\n", cp->dev, cp->un.value.num_channels));
1360 1.1 brezak
1361 1.1 brezak /*
1362 1.1 brezak * Everything is a value except for SBPro special OUTPUT_MODE and
1363 1.1 brezak * RECORD_SOURCE
1364 1.1 brezak */
1365 1.1 brezak if (cp->type != AUDIO_MIXER_VALUE) {
1366 1.1 brezak if (!ISSBPROCLASS(sc) || (cp->dev != SB_OUTPUT_MODE &&
1367 1.1 brezak cp->dev != SB_RECORD_SOURCE))
1368 1.1 brezak return EINVAL;
1369 1.1 brezak }
1370 1.1 brezak else {
1371 1.1 brezak /*
1372 1.1 brezak * All the mixer ports are stereo except for the microphone.
1373 1.1 brezak * If we get a single-channel gain value passed in, then we
1374 1.1 brezak * duplicate it to both left and right channels.
1375 1.1 brezak */
1376 1.1 brezak if (cp->un.value.num_channels == 2) {
1377 1.1 brezak left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1378 1.1 brezak right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1379 1.1 brezak }
1380 1.1 brezak else
1381 1.1 brezak left = right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
1382 1.1 brezak }
1383 1.1 brezak
1384 1.1 brezak if (ISSBPROCLASS(sc)) {
1385 1.1 brezak /* The _PORT things are all signal inputs to the mixer.
1386 1.1 brezak * Here we are tweaking their mixing level.
1387 1.1 brezak *
1388 1.1 brezak * We can also tweak the output stage volume (MASTER_VOL)
1389 1.1 brezak */
1390 1.1 brezak gain = sbdsp_stereo_vol(SBP_AGAIN_TO_SBGAIN(left),
1391 1.1 brezak SBP_AGAIN_TO_SBGAIN(right));
1392 1.1 brezak switch(cp->dev) {
1393 1.1 brezak case SB_MIC_PORT:
1394 1.1 brezak src = SBP_MIC_VOL;
1395 1.1 brezak if (cp->un.value.num_channels != 1)
1396 1.1 brezak error = EINVAL;
1397 1.1 brezak else
1398 1.1 brezak /* handle funny microphone gain */
1399 1.1 brezak gain = SBP_AGAIN_TO_MICGAIN(left);
1400 1.1 brezak break;
1401 1.1 brezak case SB_LINE_IN_PORT:
1402 1.1 brezak src = SBP_LINE_VOL;
1403 1.1 brezak break;
1404 1.1 brezak case SB_DAC_PORT:
1405 1.1 brezak src = SBP_DAC_VOL;
1406 1.1 brezak break;
1407 1.1 brezak case SB_FM_PORT:
1408 1.1 brezak src = SBP_FM_VOL;
1409 1.1 brezak break;
1410 1.1 brezak case SB_CD_PORT:
1411 1.1 brezak src = SBP_CD_VOL;
1412 1.1 brezak break;
1413 1.1 brezak case SB_SPEAKER:
1414 1.1 brezak cp->dev = SB_MASTER_VOL;
1415 1.1 brezak case SB_MASTER_VOL:
1416 1.1 brezak src = SBP_MASTER_VOL;
1417 1.1 brezak break;
1418 1.1 brezak #if 0
1419 1.1 brezak case SB_OUTPUT_MODE:
1420 1.1 brezak if (cp->type == AUDIO_MIXER_ENUM)
1421 1.1 brezak return sbdsp_set_channels(addr, cp->un.ord);
1422 1.1 brezak /* fall through...carefully! */
1423 1.1 brezak #endif
1424 1.1 brezak case SB_RECORD_SOURCE:
1425 1.1 brezak if (cp->type == AUDIO_MIXER_ENUM)
1426 1.1 brezak return sbdsp_set_in_port(addr, cp->un.ord);
1427 1.1 brezak /* else fall through: bad input */
1428 1.1 brezak case SB_TREBLE:
1429 1.1 brezak case SB_BASS:
1430 1.1 brezak default:
1431 1.1 brezak error = EINVAL;
1432 1.1 brezak break;
1433 1.1 brezak }
1434 1.1 brezak if (!error)
1435 1.1 brezak sbdsp_mix_write(sc, src, gain);
1436 1.1 brezak }
1437 1.1 brezak else if (cp->dev != SB_MIC_PORT &&
1438 1.1 brezak cp->dev != SB_SPEAKER)
1439 1.1 brezak error = EINVAL;
1440 1.1 brezak
1441 1.1 brezak if (!error)
1442 1.1 brezak sc->gain[cp->dev] = gain;
1443 1.1 brezak
1444 1.1 brezak return(error);
1445 1.1 brezak }
1446 1.1 brezak
1447 1.1 brezak int
1448 1.1 brezak sbdsp_mixer_get_port(addr, cp)
1449 1.5 mycroft void *addr;
1450 1.1 brezak mixer_ctrl_t *cp;
1451 1.1 brezak {
1452 1.5 mycroft register struct sbdsp_softc *sc = addr;
1453 1.1 brezak int error = 0;
1454 1.1 brezak int done = 0;
1455 1.1 brezak
1456 1.1 brezak DPRINTF(("sbdsp_mixer_get_port: port=%d", cp->dev));
1457 1.1 brezak
1458 1.1 brezak if (ISSBPROCLASS(sc))
1459 1.1 brezak switch(cp->dev) {
1460 1.1 brezak case SB_MIC_PORT:
1461 1.1 brezak if (cp->un.value.num_channels == 1) {
1462 1.1 brezak cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1463 1.1 brezak SBP_MICGAIN_TO_AGAIN(sc->gain[cp->dev]);
1464 1.1 brezak return 0;
1465 1.1 brezak }
1466 1.1 brezak else
1467 1.1 brezak return EINVAL;
1468 1.1 brezak break;
1469 1.1 brezak case SB_LINE_IN_PORT:
1470 1.1 brezak case SB_DAC_PORT:
1471 1.1 brezak case SB_FM_PORT:
1472 1.1 brezak case SB_CD_PORT:
1473 1.1 brezak case SB_MASTER_VOL:
1474 1.1 brezak break;
1475 1.1 brezak case SB_SPEAKER:
1476 1.1 brezak cp->dev = SB_MASTER_VOL;
1477 1.1 brezak break;
1478 1.1 brezak default:
1479 1.1 brezak error = EINVAL;
1480 1.1 brezak break;
1481 1.1 brezak }
1482 1.1 brezak else {
1483 1.1 brezak if (cp->un.value.num_channels != 1) /* no stereo on SB classic */
1484 1.1 brezak error = EINVAL;
1485 1.1 brezak else
1486 1.1 brezak switch(cp->dev) {
1487 1.1 brezak case SB_MIC_PORT:
1488 1.1 brezak break;
1489 1.1 brezak case SB_SPEAKER:
1490 1.1 brezak break;
1491 1.1 brezak default:
1492 1.1 brezak error = EINVAL;
1493 1.1 brezak break;
1494 1.1 brezak }
1495 1.1 brezak }
1496 1.1 brezak if (error == 0) {
1497 1.1 brezak if (cp->un.value.num_channels == 1) {
1498 1.1 brezak cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1499 1.1 brezak SBP_SBGAIN_TO_AGAIN(sc->gain[cp->dev]);
1500 1.1 brezak }
1501 1.1 brezak else if (cp->un.value.num_channels == 2) {
1502 1.1 brezak cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1503 1.1 brezak SBP_LEFTGAIN(sc->gain[cp->dev]);
1504 1.1 brezak cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1505 1.1 brezak SBP_RIGHTGAIN(sc->gain[cp->dev]);
1506 1.1 brezak } else
1507 1.1 brezak return EINVAL;
1508 1.1 brezak }
1509 1.1 brezak return(error);
1510 1.1 brezak }
1511 1.1 brezak
1512 1.1 brezak int
1513 1.1 brezak sbdsp_mixer_query_devinfo(addr, dip)
1514 1.5 mycroft void *addr;
1515 1.1 brezak register mixer_devinfo_t *dip;
1516 1.1 brezak {
1517 1.5 mycroft register struct sbdsp_softc *sc = addr;
1518 1.1 brezak int done = 0;
1519 1.1 brezak
1520 1.1 brezak DPRINTF(("sbdsp_mixer_query_devinfo: index=%d\n", dip->index));
1521 1.1 brezak
1522 1.1 brezak switch (dip->index) {
1523 1.1 brezak case SB_MIC_PORT:
1524 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1525 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1526 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1527 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1528 1.1 brezak strcpy(dip->label.name, AudioNmicrophone);
1529 1.1 brezak dip->un.v.num_channels = 1;
1530 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1531 1.1 brezak done = 1;
1532 1.1 brezak break;
1533 1.1 brezak case SB_SPEAKER:
1534 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1535 1.1 brezak dip->mixer_class = SB_OUTPUT_CLASS;
1536 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1537 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1538 1.1 brezak strcpy(dip->label.name, AudioNspeaker);
1539 1.1 brezak dip->un.v.num_channels = 1;
1540 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1541 1.1 brezak done = 1;
1542 1.1 brezak break;
1543 1.1 brezak case SB_INPUT_CLASS:
1544 1.1 brezak dip->type = AUDIO_MIXER_CLASS;
1545 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1546 1.1 brezak dip->next = dip->prev = AUDIO_MIXER_LAST;
1547 1.1 brezak strcpy(dip->label.name, AudioCInputs);
1548 1.1 brezak done = 1;
1549 1.1 brezak break;
1550 1.1 brezak case SB_OUTPUT_CLASS:
1551 1.1 brezak dip->type = AUDIO_MIXER_CLASS;
1552 1.1 brezak dip->mixer_class = SB_OUTPUT_CLASS;
1553 1.1 brezak dip->next = dip->prev = AUDIO_MIXER_LAST;
1554 1.1 brezak strcpy(dip->label.name, AudioCOutputs);
1555 1.1 brezak done = 1;
1556 1.1 brezak break;
1557 1.1 brezak }
1558 1.1 brezak
1559 1.1 brezak if (!done) {
1560 1.1 brezak if (ISSBPROCLASS(sc))
1561 1.1 brezak switch(dip->index) {
1562 1.1 brezak case SB_LINE_IN_PORT:
1563 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1564 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1565 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1566 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1567 1.1 brezak strcpy(dip->label.name, AudioNline);
1568 1.1 brezak dip->un.v.num_channels = 2;
1569 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1570 1.1 brezak break;
1571 1.1 brezak case SB_DAC_PORT:
1572 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1573 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1574 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1575 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1576 1.1 brezak strcpy(dip->label.name, AudioNdac);
1577 1.1 brezak dip->un.v.num_channels = 2;
1578 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1579 1.1 brezak break;
1580 1.1 brezak case SB_CD_PORT:
1581 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1582 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1583 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1584 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1585 1.1 brezak strcpy(dip->label.name, AudioNcd);
1586 1.1 brezak dip->un.v.num_channels = 2;
1587 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1588 1.1 brezak break;
1589 1.1 brezak case SB_FM_PORT:
1590 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1591 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1592 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1593 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1594 1.1 brezak strcpy(dip->label.name, "fmsynth"); /* XXX move to audioio.h */
1595 1.1 brezak dip->un.v.num_channels = 2;
1596 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1597 1.1 brezak break;
1598 1.1 brezak case SB_MASTER_VOL:
1599 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1600 1.1 brezak dip->mixer_class = SB_OUTPUT_CLASS;
1601 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1602 1.1 brezak dip->next = SB_OUTPUT_MODE;
1603 1.1 brezak strcpy(dip->label.name, AudioNvolume);
1604 1.1 brezak dip->un.v.num_channels = 2;
1605 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1606 1.1 brezak break;
1607 1.1 brezak #if 0
1608 1.1 brezak case SB_OUTPUT_MODE:
1609 1.1 brezak dip->mixer_class = SB_OUTPUT_CLASS;
1610 1.1 brezak dip->type = AUDIO_MIXER_ENUM;
1611 1.1 brezak dip->prev = SB_MASTER_VOL;
1612 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1613 1.1 brezak strcpy(dip->label.name, AudioNmode);
1614 1.1 brezak dip->un.e.num_mem = 2;
1615 1.1 brezak strcpy(dip->un.e.member[0].label.name, AudioNmono);
1616 1.1 brezak dip->un.e.member[0].ord = 1; /* nchans */
1617 1.1 brezak strcpy(dip->un.e.member[1].label.name, AudioNstereo);
1618 1.1 brezak dip->un.e.member[1].ord = 2; /* nchans */
1619 1.1 brezak break;
1620 1.1 brezak #endif
1621 1.1 brezak case SB_RECORD_SOURCE:
1622 1.1 brezak dip->mixer_class = SB_RECORD_CLASS;
1623 1.1 brezak dip->type = AUDIO_MIXER_ENUM;
1624 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1625 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1626 1.1 brezak strcpy(dip->label.name, AudioNsource);
1627 1.1 brezak dip->un.e.num_mem = 3;
1628 1.1 brezak strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
1629 1.1 brezak dip->un.e.member[0].ord = SB_MIC_PORT;
1630 1.1 brezak strcpy(dip->un.e.member[1].label.name, AudioNcd);
1631 1.1 brezak dip->un.e.member[1].ord = SB_CD_PORT;
1632 1.1 brezak strcpy(dip->un.e.member[2].label.name, AudioNline);
1633 1.1 brezak dip->un.e.member[2].ord = SB_LINE_IN_PORT;
1634 1.1 brezak break;
1635 1.1 brezak case SB_BASS:
1636 1.1 brezak case SB_TREBLE:
1637 1.1 brezak default:
1638 1.1 brezak return ENXIO;
1639 1.1 brezak /*NOTREACHED*/
1640 1.1 brezak }
1641 1.1 brezak else
1642 1.1 brezak return ENXIO;
1643 1.1 brezak }
1644 1.1 brezak
1645 1.1 brezak DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
1646 1.1 brezak
1647 1.1 brezak return 0;
1648 1.1 brezak }
1649