sbdsp.c revision 1.9 1 1.9 brezak /* $NetBSD: sbdsp.c,v 1.9 1995/04/26 21:46:10 brezak 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.9 brezak * $Id: sbdsp.c,v 1.9 1995/04/26 21:46:10 brezak 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.6 cgd #include <dev/isa/isavar.h>
61 1.6 cgd #include <dev/isa/isadmavar.h>
62 1.7 cgd #include <i386/isa/icu.h> /* XXX BROKEN; WHY? */
63 1.1 brezak
64 1.7 cgd #include <dev/isa/sbreg.h>
65 1.7 cgd #include <dev/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.9 brezak printf(": dsp v%d.%02d\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 if (ISSBPROCLASS(sc)) {
451 1.1 brezak switch (port) {
452 1.8 mycroft case SB_MIC_PORT:
453 1.8 mycroft sbport = SBP_FROM_MIC;
454 1.8 mycroft mixport = SBP_MIC_VOL;
455 1.8 mycroft break;
456 1.1 brezak case SB_LINE_IN_PORT:
457 1.1 brezak sbport = SBP_FROM_LINE;
458 1.1 brezak mixport = SBP_LINE_VOL;
459 1.1 brezak break;
460 1.1 brezak case SB_CD_PORT:
461 1.1 brezak sbport = SBP_FROM_CD;
462 1.1 brezak mixport = SBP_CD_VOL;
463 1.1 brezak break;
464 1.1 brezak case SB_DAC_PORT:
465 1.1 brezak case SB_FM_PORT:
466 1.1 brezak default:
467 1.1 brezak return(EINVAL);
468 1.1 brezak /*NOTREACHED*/
469 1.1 brezak }
470 1.1 brezak }
471 1.1 brezak else {
472 1.8 mycroft switch (port) {
473 1.8 mycroft case SB_MIC_PORT:
474 1.8 mycroft sbport = SBP_FROM_MIC;
475 1.8 mycroft mixport = SBP_MIC_VOL;
476 1.8 mycroft break;
477 1.8 mycroft default:
478 1.8 mycroft return(EINVAL);
479 1.8 mycroft /*NOTREACHED*/
480 1.8 mycroft }
481 1.1 brezak }
482 1.1 brezak
483 1.1 brezak sc->in_port = port; /* Just record it */
484 1.1 brezak
485 1.1 brezak if (ISSBPROCLASS(sc)) {
486 1.1 brezak /* record from that port */
487 1.1 brezak sbdsp_mix_write(sc, SBP_RECORD_SOURCE,
488 1.1 brezak SBP_RECORD_FROM(sbport, SBP_FILTER_OFF,
489 1.1 brezak SBP_FILTER_HIGH));
490 1.1 brezak /* fetch gain from that port */
491 1.1 brezak sc->gain[port] = sbdsp_mix_read(sc, mixport);
492 1.1 brezak }
493 1.1 brezak
494 1.1 brezak return(0);
495 1.1 brezak }
496 1.1 brezak
497 1.1 brezak int
498 1.1 brezak sbdsp_get_in_port(addr)
499 1.5 mycroft void *addr;
500 1.1 brezak {
501 1.5 mycroft register struct sbdsp_softc *sc = addr;
502 1.1 brezak
503 1.1 brezak return(sc->in_port);
504 1.1 brezak }
505 1.1 brezak
506 1.1 brezak
507 1.1 brezak int
508 1.1 brezak sbdsp_speaker_ctl(addr, newstate)
509 1.5 mycroft void *addr;
510 1.1 brezak int newstate;
511 1.1 brezak {
512 1.5 mycroft register struct sbdsp_softc *sc = addr;
513 1.1 brezak
514 1.1 brezak if ((newstate == SPKR_ON) &&
515 1.1 brezak (sc->spkr_state == SPKR_OFF)) {
516 1.1 brezak sbdsp_spkron(sc);
517 1.1 brezak sc->spkr_state = SPKR_ON;
518 1.1 brezak }
519 1.1 brezak if ((newstate == SPKR_OFF) &&
520 1.1 brezak (sc->spkr_state == SPKR_ON)) {
521 1.1 brezak sbdsp_spkroff(sc);
522 1.1 brezak sc->spkr_state = SPKR_OFF;
523 1.1 brezak }
524 1.1 brezak return(0);
525 1.1 brezak }
526 1.1 brezak
527 1.1 brezak int
528 1.1 brezak sbdsp_round_blocksize(addr, blk)
529 1.5 mycroft void *addr;
530 1.1 brezak int blk;
531 1.1 brezak {
532 1.5 mycroft register struct sbdsp_softc *sc = addr;
533 1.1 brezak
534 1.1 brezak sc->sc_last_hsr_size = sc->sc_last_hsw_size = 0;
535 1.1 brezak
536 1.1 brezak /* Higher speeds need bigger blocks to avoid popping and silence gaps. */
537 1.1 brezak if ((sc->sc_orate > 8000 || sc->sc_irate > 8000) &&
538 1.1 brezak (blk > NBPG/2 || blk < NBPG/4))
539 1.1 brezak blk = NBPG/2;
540 1.1 brezak /* don't try to DMA too much at once, though. */
541 1.1 brezak if (blk > NBPG) blk = NBPG;
542 1.1 brezak if (sc->sc_chans == 2)
543 1.1 brezak return (blk & ~1); /* must be even to preserve stereo separation */
544 1.1 brezak else
545 1.1 brezak return(blk); /* Anything goes :-) */
546 1.1 brezak }
547 1.1 brezak
548 1.1 brezak int
549 1.1 brezak sbdsp_commit_settings(addr)
550 1.5 mycroft void *addr;
551 1.1 brezak {
552 1.1 brezak /* due to potentially unfortunate ordering in the above layers,
553 1.1 brezak re-do a few sets which may be important--input gains
554 1.1 brezak (adjust the proper channels), number of input channels (hit the
555 1.1 brezak record rate and set mode) */
556 1.1 brezak
557 1.5 mycroft register struct sbdsp_softc *sc = addr;
558 1.1 brezak
559 1.3 brezak sbdsp_set_out_sr_real(addr, sc->sc_orate);
560 1.3 brezak sbdsp_set_in_sr_real(addr, sc->sc_irate);
561 1.3 brezak
562 1.1 brezak sc->sc_last_hsw_size = sc->sc_last_hsr_size = 0;
563 1.1 brezak return(0);
564 1.1 brezak }
565 1.1 brezak
566 1.1 brezak
567 1.1 brezak int
568 1.1 brezak sbdsp_open(sc, dev, flags)
569 1.1 brezak register struct sbdsp_softc *sc;
570 1.1 brezak dev_t dev;
571 1.1 brezak int flags;
572 1.1 brezak {
573 1.1 brezak DPRINTF(("sbdsp_open: sc=0x%x\n", sc));
574 1.1 brezak
575 1.1 brezak if (sc->sc_open != 0 || sbdsp_reset(sc) != 0)
576 1.1 brezak return ENXIO;
577 1.1 brezak
578 1.1 brezak sc->sc_open = 1;
579 1.1 brezak sc->sc_mintr = 0;
580 1.1 brezak sc->sc_intr = 0;
581 1.1 brezak sc->sc_arg = 0;
582 1.1 brezak sc->sc_locked = 0;
583 1.1 brezak if (ISSBPROCLASS(sc) &&
584 1.1 brezak sbdsp_wdsp(sc->sc_iobase, SB_DSP_RECORD_MONO) < 0) {
585 1.1 brezak DPRINTF(("sbdsp_open: can't set mono mode\n"));
586 1.1 brezak /* we'll readjust when it's time for DMA. */
587 1.1 brezak }
588 1.1 brezak sc->sc_dmain_inprogress = 0;
589 1.1 brezak sc->sc_dmaout_inprogress = 0;
590 1.1 brezak
591 1.1 brezak /*
592 1.1 brezak * Leave most things as they were; users must change things if
593 1.1 brezak * the previous process didn't leave it they way they wanted.
594 1.1 brezak * Looked at another way, it's easy to set up a configuration
595 1.1 brezak * in one program and leave it for another to inherit.
596 1.1 brezak */
597 1.1 brezak DPRINTF(("sbdsp_open: opened\n"));
598 1.1 brezak
599 1.1 brezak return 0;
600 1.1 brezak }
601 1.1 brezak
602 1.1 brezak void
603 1.1 brezak sbdsp_close(addr)
604 1.5 mycroft void *addr;
605 1.1 brezak {
606 1.5 mycroft struct sbdsp_softc *sc = addr;
607 1.1 brezak
608 1.1 brezak DPRINTF(("sbdsp_close: sc=0x%x\n", sc));
609 1.1 brezak
610 1.1 brezak sc->sc_open = 0;
611 1.1 brezak sbdsp_spkroff(sc);
612 1.1 brezak sc->spkr_state = SPKR_OFF;
613 1.1 brezak sc->sc_intr = 0;
614 1.1 brezak sc->sc_mintr = 0;
615 1.1 brezak /* XXX this will turn off any dma */
616 1.1 brezak sbdsp_reset(sc);
617 1.1 brezak
618 1.1 brezak DPRINTF(("sbdsp_close: closed\n"));
619 1.1 brezak }
620 1.1 brezak
621 1.1 brezak /*
622 1.1 brezak * Lower-level routines
623 1.1 brezak */
624 1.1 brezak
625 1.1 brezak /*
626 1.1 brezak * Reset the card.
627 1.1 brezak * Return non-zero if the card isn't detected.
628 1.1 brezak */
629 1.1 brezak int
630 1.1 brezak sbdsp_reset(sc)
631 1.1 brezak register struct sbdsp_softc *sc;
632 1.1 brezak {
633 1.1 brezak register u_short iobase = sc->sc_iobase;
634 1.1 brezak
635 1.1 brezak /*
636 1.1 brezak * erase any memory of last transfer size.
637 1.1 brezak */
638 1.1 brezak sc->sc_last_hsr_size = sc->sc_last_hsw_size = 0;
639 1.1 brezak /*
640 1.1 brezak * See SBK, section 11.3.
641 1.1 brezak * We pulse a reset signal into the card.
642 1.1 brezak * Gee, what a brilliant hardware design.
643 1.1 brezak */
644 1.1 brezak outb(iobase + SBP_DSP_RESET, 1);
645 1.1 brezak delay(3);
646 1.1 brezak outb(iobase + SBP_DSP_RESET, 0);
647 1.1 brezak if (sbdsp_rdsp(iobase) != SB_MAGIC)
648 1.1 brezak return -1;
649 1.1 brezak return 0;
650 1.1 brezak }
651 1.1 brezak
652 1.1 brezak /*
653 1.1 brezak * Write a byte to the dsp.
654 1.1 brezak * XXX We are at the mercy of the card as we use a
655 1.1 brezak * polling loop and wait until it can take the byte.
656 1.1 brezak */
657 1.1 brezak int
658 1.1 brezak sbdsp_wdsp(u_short iobase, int v)
659 1.1 brezak {
660 1.1 brezak register int i;
661 1.1 brezak
662 1.1 brezak for (i = SBDSP_NPOLL; --i >= 0; ) {
663 1.1 brezak if ((inb(iobase + SBP_DSP_WSTAT) & SB_DSP_BUSY) != 0) {
664 1.1 brezak delay(10); continue;
665 1.1 brezak }
666 1.1 brezak outb(iobase + SBP_DSP_WRITE, v);
667 1.1 brezak return 0;
668 1.1 brezak }
669 1.1 brezak ++sberr.wdsp;
670 1.1 brezak return -1;
671 1.1 brezak }
672 1.1 brezak
673 1.1 brezak /*
674 1.1 brezak * Read a byte from the DSP, using polling.
675 1.1 brezak */
676 1.1 brezak int
677 1.1 brezak sbdsp_rdsp(u_short iobase)
678 1.1 brezak {
679 1.1 brezak register int i;
680 1.1 brezak
681 1.1 brezak for (i = SBDSP_NPOLL; --i >= 0; ) {
682 1.1 brezak if ((inb(iobase + SBP_DSP_RSTAT) & SB_DSP_READY) == 0)
683 1.1 brezak continue;
684 1.1 brezak return inb(iobase + SBP_DSP_READ);
685 1.1 brezak }
686 1.1 brezak ++sberr.rdsp;
687 1.1 brezak return -1;
688 1.1 brezak }
689 1.1 brezak
690 1.1 brezak /*
691 1.1 brezak * Doing certain things (like toggling the speaker) make
692 1.1 brezak * the SB hardware go away for a while, so pause a little.
693 1.1 brezak */
694 1.1 brezak void
695 1.1 brezak sbdsp_to(arg)
696 1.1 brezak void *arg;
697 1.1 brezak {
698 1.1 brezak wakeup(arg);
699 1.1 brezak }
700 1.1 brezak
701 1.1 brezak void
702 1.1 brezak sbdsp_pause(sc)
703 1.1 brezak struct sbdsp_softc *sc;
704 1.1 brezak {
705 1.1 brezak extern int hz;
706 1.1 brezak
707 1.1 brezak timeout(sbdsp_to, sbdsp_to, hz/8);
708 1.5 mycroft (void)tsleep(sbdsp_to, PWAIT, "sbpause", 0);
709 1.1 brezak }
710 1.1 brezak
711 1.1 brezak /*
712 1.1 brezak * Turn on the speaker. The SBK documention says this operation
713 1.1 brezak * can take up to 1/10 of a second. Higher level layers should
714 1.1 brezak * probably let the task sleep for this amount of time after
715 1.1 brezak * calling here. Otherwise, things might not work (because
716 1.1 brezak * sbdsp_wdsp() and sbdsp_rdsp() will probably timeout.)
717 1.1 brezak *
718 1.1 brezak * These engineers had their heads up their ass when
719 1.1 brezak * they designed this card.
720 1.1 brezak */
721 1.1 brezak void
722 1.1 brezak sbdsp_spkron(sc)
723 1.1 brezak struct sbdsp_softc *sc;
724 1.1 brezak {
725 1.1 brezak (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_SPKR_ON);
726 1.1 brezak sbdsp_pause(sc);
727 1.1 brezak }
728 1.1 brezak
729 1.1 brezak /*
730 1.1 brezak * Turn off the speaker; see comment above.
731 1.1 brezak */
732 1.1 brezak void
733 1.1 brezak sbdsp_spkroff(sc)
734 1.1 brezak struct sbdsp_softc *sc;
735 1.1 brezak {
736 1.1 brezak (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_SPKR_OFF);
737 1.1 brezak sbdsp_pause(sc);
738 1.1 brezak }
739 1.1 brezak
740 1.1 brezak /*
741 1.1 brezak * Read the version number out of the card. Return major code
742 1.1 brezak * in high byte, and minor code in low byte.
743 1.1 brezak */
744 1.1 brezak short
745 1.1 brezak sbversion(sc)
746 1.1 brezak struct sbdsp_softc *sc;
747 1.1 brezak {
748 1.1 brezak register u_short iobase = sc->sc_iobase;
749 1.1 brezak short v;
750 1.1 brezak
751 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_VERSION) < 0)
752 1.1 brezak return 0;
753 1.1 brezak v = sbdsp_rdsp(iobase) << 8;
754 1.1 brezak v |= sbdsp_rdsp(iobase);
755 1.1 brezak return ((v >= 0) ? v : 0);
756 1.1 brezak }
757 1.1 brezak
758 1.1 brezak /*
759 1.1 brezak * Halt a DMA in progress. A low-speed transfer can be
760 1.1 brezak * resumed with sbdsp_contdma().
761 1.1 brezak */
762 1.1 brezak int
763 1.1 brezak sbdsp_haltdma(addr)
764 1.5 mycroft void *addr;
765 1.1 brezak {
766 1.5 mycroft register struct sbdsp_softc *sc = addr;
767 1.1 brezak
768 1.1 brezak DPRINTF(("sbdsp_haltdma: sc=0x%x\n", sc));
769 1.1 brezak
770 1.1 brezak if (sc->sc_locked)
771 1.1 brezak sbdsp_reset(sc);
772 1.1 brezak else
773 1.1 brezak (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_HALT);
774 1.1 brezak
775 1.1 brezak isa_dmaabort(sc->sc_drq);
776 1.1 brezak sc->dmaaddr = 0;
777 1.1 brezak sc->dmacnt = 0;
778 1.1 brezak sc->sc_locked = 0;
779 1.1 brezak sc->dmaflags = 0;
780 1.1 brezak sc->sc_dmain_inprogress = sc->sc_dmaout_inprogress = 0;
781 1.1 brezak return(0);
782 1.1 brezak }
783 1.1 brezak
784 1.1 brezak int
785 1.1 brezak sbdsp_contdma(addr)
786 1.5 mycroft void *addr;
787 1.1 brezak {
788 1.5 mycroft register struct sbdsp_softc *sc = addr;
789 1.1 brezak
790 1.1 brezak DPRINTF(("sbdsp_contdma: sc=0x%x\n", sc));
791 1.1 brezak
792 1.1 brezak /* XXX how do we reinitialize the DMA controller state? do we care? */
793 1.1 brezak (void)sbdsp_wdsp(sc->sc_iobase, SB_DSP_CONT);
794 1.1 brezak return(0);
795 1.1 brezak }
796 1.1 brezak
797 1.1 brezak /*
798 1.1 brezak * Time constant routines follow. See SBK, section 12.
799 1.1 brezak * Although they don't come out and say it (in the docs),
800 1.1 brezak * the card clearly uses a 1MHz countdown timer, as the
801 1.1 brezak * low-speed formula (p. 12-4) is:
802 1.1 brezak * tc = 256 - 10^6 / sr
803 1.1 brezak * In high-speed mode, the constant is the upper byte of a 16-bit counter,
804 1.1 brezak * and a 256MHz clock is used:
805 1.1 brezak * tc = 65536 - 256 * 10^ 6 / sr
806 1.1 brezak * Since we can only use the upper byte of the HS TC, the two formulae
807 1.1 brezak * are equivalent. (Why didn't they say so?) E.g.,
808 1.1 brezak * (65536 - 256 * 10 ^ 6 / x) >> 8 = 256 - 10^6 / x
809 1.1 brezak *
810 1.1 brezak * The crossover point (from low- to high-speed modes) is different
811 1.1 brezak * for the SBPRO and SB20. The table on p. 12-5 gives the following data:
812 1.1 brezak *
813 1.1 brezak * SBPRO SB20
814 1.1 brezak * ----- --------
815 1.1 brezak * input ls min 4 KHz 4 KHz
816 1.1 brezak * input ls max 23 KHz 13 KHz
817 1.1 brezak * input hs max 44.1 KHz 15 KHz
818 1.1 brezak * output ls min 4 KHz 4 KHz
819 1.1 brezak * output ls max 23 KHz 23 KHz
820 1.1 brezak * output hs max 44.1 KHz 44.1 KHz
821 1.1 brezak */
822 1.1 brezak #define SB_LS_MIN 0x06 /* 4000 Hz */
823 1.1 brezak #define SBPRO_ADC_LS_MAX 0xd4 /* 22727 Hz */
824 1.1 brezak #define SBPRO_ADC_HS_MAX 0xea /* 45454 Hz */
825 1.1 brezak #define SBCLA_ADC_LS_MAX 0xb3 /* 12987 Hz */
826 1.1 brezak #define SBCLA_ADC_HS_MAX 0xbd /* 14925 Hz */
827 1.1 brezak #define SB_DAC_LS_MAX 0xd4 /* 22727 Hz */
828 1.1 brezak #define SB_DAC_HS_MAX 0xea /* 45454 Hz */
829 1.1 brezak
830 1.1 brezak /*
831 1.1 brezak * Convert a linear sampling rate into the DAC time constant.
832 1.1 brezak * Set *mode to indicate the high/low-speed DMA operation.
833 1.1 brezak * Because of limitations of the card, not all rates are possible.
834 1.1 brezak * We return the time constant of the closest possible rate.
835 1.1 brezak * The sampling rate limits are different for the DAC and ADC,
836 1.1 brezak * so isdac indicates output, and !isdac indicates input.
837 1.1 brezak */
838 1.1 brezak int
839 1.1 brezak sbdsp_srtotc(sc, sr, mode, isdac)
840 1.1 brezak register struct sbdsp_softc *sc;
841 1.1 brezak int sr;
842 1.1 brezak int *mode;
843 1.1 brezak int isdac;
844 1.1 brezak {
845 1.1 brezak int adc_ls_max, adc_hs_max;
846 1.1 brezak register int tc;
847 1.1 brezak
848 1.1 brezak if (sr == 0) {
849 1.1 brezak *mode = SB_ADAC_LS;
850 1.1 brezak return SB_LS_MIN;
851 1.1 brezak }
852 1.1 brezak tc = 256 - 1000000 / sr;
853 1.1 brezak
854 1.1 brezak /* XXX use better rounding--compare distance to nearest tc on both
855 1.1 brezak sides of requested speed */
856 1.1 brezak if (ISSBPROCLASS(sc)) {
857 1.1 brezak adc_ls_max = SBPRO_ADC_LS_MAX;
858 1.1 brezak adc_hs_max = SBPRO_ADC_HS_MAX;
859 1.1 brezak }
860 1.1 brezak else {
861 1.1 brezak adc_ls_max = SBCLA_ADC_LS_MAX;
862 1.1 brezak adc_hs_max = SBCLA_ADC_HS_MAX;
863 1.1 brezak }
864 1.1 brezak
865 1.1 brezak if (tc < SB_LS_MIN) {
866 1.1 brezak tc = SB_LS_MIN;
867 1.1 brezak *mode = SB_ADAC_LS;
868 1.1 brezak } else if (isdac) {
869 1.1 brezak if (tc <= SB_DAC_LS_MAX)
870 1.1 brezak *mode = SB_ADAC_LS;
871 1.1 brezak else {
872 1.1 brezak *mode = SB_ADAC_HS;
873 1.1 brezak if (tc > SB_DAC_HS_MAX)
874 1.1 brezak tc = SB_DAC_HS_MAX;
875 1.1 brezak }
876 1.1 brezak } else {
877 1.1 brezak if (tc <= adc_ls_max)
878 1.1 brezak *mode = SB_ADAC_LS;
879 1.1 brezak else {
880 1.1 brezak *mode = SB_ADAC_HS;
881 1.1 brezak if (tc > adc_hs_max)
882 1.1 brezak tc = adc_hs_max;
883 1.1 brezak }
884 1.1 brezak }
885 1.1 brezak return tc;
886 1.1 brezak }
887 1.1 brezak
888 1.1 brezak /*
889 1.1 brezak * Convert a DAC time constant to a sampling rate.
890 1.1 brezak * See SBK, section 12.
891 1.1 brezak */
892 1.1 brezak int
893 1.1 brezak sbdsp_tctosr(sc, tc)
894 1.1 brezak register struct sbdsp_softc *sc;
895 1.1 brezak int tc;
896 1.1 brezak {
897 1.1 brezak int adc;
898 1.1 brezak
899 1.1 brezak if (ISSBPROCLASS(sc))
900 1.1 brezak adc = SBPRO_ADC_HS_MAX;
901 1.1 brezak else
902 1.1 brezak adc = SBCLA_ADC_HS_MAX;
903 1.1 brezak
904 1.1 brezak if (tc > adc)
905 1.1 brezak tc = adc;
906 1.1 brezak
907 1.1 brezak return (1000000 / (256 - tc));
908 1.1 brezak }
909 1.1 brezak
910 1.1 brezak int
911 1.1 brezak sbdsp_set_sr(sc, srp, isdac)
912 1.1 brezak register struct sbdsp_softc *sc;
913 1.1 brezak u_long *srp;
914 1.1 brezak int isdac;
915 1.1 brezak {
916 1.1 brezak register int tc;
917 1.1 brezak int mode;
918 1.1 brezak int sr = *srp;
919 1.1 brezak register u_short iobase;
920 1.1 brezak
921 1.1 brezak /*
922 1.1 brezak * A SBPro in stereo mode uses time constants at double the
923 1.1 brezak * actual rate.
924 1.1 brezak */
925 1.1 brezak if (ISSBPRO(sc) && sc->sc_chans == 2) {
926 1.1 brezak if (sr > 22727)
927 1.1 brezak sr = 22727; /* Can't bounce it...order of
928 1.1 brezak operations may yield bogus
929 1.1 brezak sr here. */
930 1.1 brezak sr *= 2;
931 1.1 brezak }
932 1.1 brezak else if (!ISSBPROCLASS(sc) && sc->sc_chans != 1)
933 1.1 brezak return EINVAL;
934 1.1 brezak
935 1.1 brezak tc = sbdsp_srtotc(sc, sr, &mode, isdac);
936 1.1 brezak DPRINTF(("sbdsp_set_sr: sc=0x%x sr=%d mode=0x%x\n", sc, sr, mode));
937 1.1 brezak
938 1.1 brezak iobase = sc->sc_iobase;
939 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_TIMECONST) < 0 ||
940 1.1 brezak sbdsp_wdsp(iobase, tc) < 0)
941 1.1 brezak return EIO;
942 1.1 brezak
943 1.1 brezak sr = sbdsp_tctosr(sc, tc);
944 1.1 brezak if (ISSBPRO(sc) && sc->sc_chans == 2)
945 1.1 brezak *srp = sr / 2;
946 1.1 brezak else
947 1.1 brezak *srp = sr;
948 1.1 brezak
949 1.1 brezak sc->sc_adacmode = mode;
950 1.1 brezak sc->sc_adactc = tc;
951 1.1 brezak return 0;
952 1.1 brezak }
953 1.1 brezak
954 1.1 brezak int
955 1.1 brezak sbdsp_dma_input(addr, p, cc, intr, arg)
956 1.5 mycroft void *addr;
957 1.1 brezak void *p;
958 1.1 brezak int cc;
959 1.1 brezak void (*intr)();
960 1.1 brezak void *arg;
961 1.1 brezak {
962 1.5 mycroft register struct sbdsp_softc *sc = addr;
963 1.1 brezak register u_short iobase;
964 1.1 brezak u_int phys;
965 1.1 brezak
966 1.1 brezak #ifdef DEBUG
967 1.1 brezak if (sbdspdebug > 1)
968 1.1 brezak Dprintf("sbdsp_dma_input: cc=%d 0x%x (0x%x)\n", cc, intr, arg);
969 1.1 brezak #endif
970 1.1 brezak if (sc->sc_chans == 2 && (cc & 1)) {
971 1.1 brezak DPRINTF(("sbdsp_dma_input: stereo input, odd bytecnt\n"));
972 1.1 brezak return EIO;
973 1.1 brezak }
974 1.1 brezak iobase = sc->sc_iobase;
975 1.1 brezak if (ISSBPROCLASS(sc) && !sc->sc_dmain_inprogress) {
976 1.1 brezak if (sc->sc_chans == 2) {
977 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_RECORD_STEREO) < 0)
978 1.1 brezak goto badmode;
979 1.1 brezak sbdsp_mix_write(sc, SBP_STEREO,
980 1.1 brezak sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK);
981 1.1 brezak sbdsp_mix_write(sc, SBP_INFILTER,
982 1.1 brezak sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF);
983 1.1 brezak }
984 1.1 brezak else {
985 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_RECORD_MONO) < 0)
986 1.1 brezak goto badmode;
987 1.1 brezak sbdsp_mix_write(sc, SBP_STEREO,
988 1.1 brezak sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK);
989 1.1 brezak sbdsp_mix_write(sc, SBP_INFILTER,
990 1.1 brezak sc->sc_irate <= 8000 ?
991 1.1 brezak sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_FILTER_MASK :
992 1.1 brezak sbdsp_mix_read(sc, SBP_INFILTER) | SBP_FILTER_OFF);
993 1.1 brezak }
994 1.1 brezak sc->sc_dmain_inprogress = 1;
995 1.1 brezak sc->sc_last_hsr_size = 0; /* restarting */
996 1.1 brezak }
997 1.1 brezak sc->sc_dmaout_inprogress = 0;
998 1.1 brezak
999 1.1 brezak at_dma(B_READ, p, cc, sc->sc_drq);
1000 1.1 brezak sc->sc_intr = intr;
1001 1.1 brezak sc->sc_arg = arg;
1002 1.1 brezak sc->dmaflags = B_READ;
1003 1.1 brezak sc->dmaaddr = p;
1004 1.1 brezak sc->dmacnt = --cc; /* DMA controller is strange...? */
1005 1.1 brezak if (sc->sc_adacmode == SB_ADAC_LS) {
1006 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_RDMA) < 0 ||
1007 1.1 brezak sbdsp_wdsp(iobase, cc) < 0 ||
1008 1.1 brezak sbdsp_wdsp(iobase, cc >> 8) < 0) {
1009 1.1 brezak goto giveup;
1010 1.1 brezak }
1011 1.1 brezak }
1012 1.1 brezak else {
1013 1.1 brezak if (cc != sc->sc_last_hsr_size) {
1014 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0 ||
1015 1.1 brezak sbdsp_wdsp(iobase, cc) < 0 ||
1016 1.1 brezak sbdsp_wdsp(iobase, cc >> 8) < 0)
1017 1.1 brezak goto giveup;
1018 1.1 brezak }
1019 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_HS_INPUT) < 0)
1020 1.1 brezak goto giveup;
1021 1.1 brezak sc->sc_last_hsr_size = cc;
1022 1.1 brezak sc->sc_locked = 1;
1023 1.1 brezak }
1024 1.1 brezak return 0;
1025 1.1 brezak
1026 1.1 brezak giveup:
1027 1.1 brezak isa_dmaabort(sc->sc_drq);
1028 1.1 brezak sbdsp_reset(sc);
1029 1.1 brezak sc->sc_intr = 0;
1030 1.1 brezak sc->sc_arg = 0;
1031 1.1 brezak return EIO;
1032 1.1 brezak badmode:
1033 1.1 brezak DPRINTF(("sbdsp_dma_input: can't set %s mode\n",
1034 1.1 brezak sc->sc_chans == 2 ? "stereo" : "mono"));
1035 1.1 brezak return EIO;
1036 1.1 brezak }
1037 1.1 brezak
1038 1.1 brezak int
1039 1.1 brezak sbdsp_dma_output(addr, p, cc, intr, arg)
1040 1.5 mycroft void *addr;
1041 1.1 brezak void *p;
1042 1.1 brezak int cc;
1043 1.1 brezak void (*intr)();
1044 1.1 brezak void *arg;
1045 1.1 brezak {
1046 1.5 mycroft register struct sbdsp_softc *sc = addr;
1047 1.1 brezak register u_short iobase;
1048 1.1 brezak
1049 1.1 brezak #ifdef DEBUG
1050 1.1 brezak if (sbdspdebug > 1)
1051 1.1 brezak Dprintf("sbdsp_dma_output: cc=%d 0x%x (0x%x)\n", cc, intr, arg);
1052 1.1 brezak #endif
1053 1.1 brezak if (sc->sc_chans == 2 && cc & 1) {
1054 1.1 brezak DPRINTF(("stereo playback odd bytes (%d)\n", cc));
1055 1.1 brezak return EIO;
1056 1.1 brezak }
1057 1.1 brezak
1058 1.1 brezak if (ISSBPROCLASS(sc) && !sc->sc_dmaout_inprogress) {
1059 1.1 brezak /* make sure we re-set stereo mixer bit when we start
1060 1.1 brezak output. */
1061 1.1 brezak sbdsp_mix_write(sc, SBP_STEREO,
1062 1.1 brezak (sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) |
1063 1.1 brezak (sc->sc_chans == 2 ?
1064 1.1 brezak SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO));
1065 1.1 brezak sc->sc_dmaout_inprogress = 1;
1066 1.1 brezak sc->sc_last_hsw_size = 0; /* restarting */
1067 1.1 brezak }
1068 1.1 brezak sc->sc_dmain_inprogress = 0;
1069 1.1 brezak at_dma(B_WRITE, p, cc, sc->sc_drq);
1070 1.1 brezak sc->sc_intr = intr;
1071 1.1 brezak sc->sc_arg = arg;
1072 1.1 brezak sc->dmaflags = B_WRITE;
1073 1.1 brezak sc->dmaaddr = p;
1074 1.1 brezak sc->dmacnt = --cc; /* a vagary of how DMA works, apparently. */
1075 1.1 brezak
1076 1.1 brezak iobase = sc->sc_iobase;
1077 1.1 brezak if (sc->sc_adacmode == SB_ADAC_LS) {
1078 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_WDMA) < 0 ||
1079 1.1 brezak sbdsp_wdsp(iobase, cc) < 0 ||
1080 1.1 brezak sbdsp_wdsp(iobase, cc >> 8) < 0) {
1081 1.1 brezak DPRINTF(("sbdsp_dma_output: LS DMA start failed\n"));
1082 1.1 brezak goto giveup;
1083 1.1 brezak }
1084 1.1 brezak }
1085 1.1 brezak else {
1086 1.1 brezak if (cc != sc->sc_last_hsw_size) {
1087 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0) {
1088 1.1 brezak /* sometimes fails initial startup?? */
1089 1.1 brezak delay(100);
1090 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_BLOCKSIZE) < 0) {
1091 1.1 brezak DPRINTF(("sbdsp_dma_output: BLOCKSIZE failed\n"));
1092 1.1 brezak goto giveup;
1093 1.1 brezak }
1094 1.1 brezak }
1095 1.1 brezak if (sbdsp_wdsp(iobase, cc) < 0 ||
1096 1.1 brezak sbdsp_wdsp(iobase, cc >> 8) < 0) {
1097 1.1 brezak DPRINTF(("sbdsp_dma_output: HS DMA start failed\n"));
1098 1.1 brezak goto giveup;
1099 1.1 brezak }
1100 1.1 brezak sc->sc_last_hsw_size = cc;
1101 1.1 brezak }
1102 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_HS_OUTPUT) < 0) {
1103 1.1 brezak delay(100);
1104 1.1 brezak if (sbdsp_wdsp(iobase, SB_DSP_HS_OUTPUT) < 0) {
1105 1.1 brezak DPRINTF(("sbdsp_dma_output: HS DMA restart failed\n"));
1106 1.1 brezak goto giveup;
1107 1.1 brezak }
1108 1.1 brezak }
1109 1.1 brezak sc->sc_locked = 1;
1110 1.1 brezak }
1111 1.1 brezak
1112 1.1 brezak return 0;
1113 1.1 brezak
1114 1.1 brezak giveup:
1115 1.1 brezak isa_dmaabort(sc->sc_drq);
1116 1.1 brezak sbdsp_reset(sc);
1117 1.1 brezak sc->sc_intr = 0;
1118 1.1 brezak sc->sc_arg = 0;
1119 1.1 brezak return EIO;
1120 1.1 brezak }
1121 1.1 brezak
1122 1.1 brezak /*
1123 1.1 brezak * Only the DSP unit on the sound blaster generates interrupts.
1124 1.1 brezak * There are three cases of interrupt: reception of a midi byte
1125 1.1 brezak * (when mode is enabled), completion of dma transmission, or
1126 1.1 brezak * completion of a dma reception. The three modes are mutually
1127 1.1 brezak * exclusive so we know a priori which event has occurred.
1128 1.1 brezak */
1129 1.1 brezak int
1130 1.6 cgd sbdsp_intr(arg)
1131 1.6 cgd void *arg;
1132 1.1 brezak {
1133 1.6 cgd register struct sbdsp_softc *sc = arg;
1134 1.1 brezak
1135 1.1 brezak #ifdef DEBUG
1136 1.1 brezak if (sbdspdebug > 1)
1137 1.1 brezak Dprintf("sbdsp_intr: intr=0x%x\n", sc->sc_intr);
1138 1.1 brezak #endif
1139 1.1 brezak sc->sc_interrupts++;
1140 1.1 brezak sc->sc_locked = 0;
1141 1.1 brezak /* clear interrupt */
1142 1.1 brezak inb(sc->sc_iobase + SBP_DSP_RSTAT);
1143 1.1 brezak #if 0
1144 1.1 brezak if (sc->sc_mintr != 0) {
1145 1.1 brezak int c = sbdsp_rdsp(sc->sc_iobase);
1146 1.1 brezak (*sc->sc_mintr)(sc->sc_arg, c);
1147 1.1 brezak } else
1148 1.1 brezak #endif
1149 1.1 brezak if (sc->sc_intr != 0) {
1150 1.1 brezak /*
1151 1.1 brezak * The SBPro used to develop and test this driver often
1152 1.1 brezak * generated dma underruns--it interrupted to signal
1153 1.1 brezak * completion of the DMA input recording block, but the
1154 1.1 brezak * ISA DMA controller didn't think the channel was
1155 1.1 brezak * finished. Maybe this is just a bus speed issue, I dunno,
1156 1.1 brezak * but it seems strange and leads to channel-flipping with stereo
1157 1.1 brezak * recording. Sigh.
1158 1.1 brezak */
1159 1.1 brezak isa_dmadone(sc->dmaflags, sc->dmaaddr, sc->dmacnt,
1160 1.1 brezak sc->sc_drq);
1161 1.1 brezak sc->dmaflags = 0;
1162 1.1 brezak sc->dmaaddr = 0;
1163 1.1 brezak sc->dmacnt = 0;
1164 1.1 brezak (*sc->sc_intr)(sc->sc_arg);
1165 1.1 brezak }
1166 1.1 brezak else
1167 1.1 brezak return 0;
1168 1.1 brezak return 1;
1169 1.1 brezak }
1170 1.1 brezak
1171 1.1 brezak #if 0
1172 1.1 brezak /*
1173 1.1 brezak * Enter midi uart mode and arrange for read interrupts
1174 1.1 brezak * to vector to `intr'. This puts the card in a mode
1175 1.1 brezak * which allows only midi I/O; the card must be reset
1176 1.1 brezak * to leave this mode. Unfortunately, the card does not
1177 1.1 brezak * use transmit interrupts, so bytes must be output
1178 1.1 brezak * using polling. To keep the polling overhead to a
1179 1.1 brezak * minimum, output should be driven off a timer.
1180 1.1 brezak * This is a little tricky since only 320us separate
1181 1.1 brezak * consecutive midi bytes.
1182 1.1 brezak */
1183 1.1 brezak void
1184 1.1 brezak sbdsp_set_midi_mode(sc, intr, arg)
1185 1.1 brezak struct sbdsp_softc *sc;
1186 1.1 brezak void (*intr)();
1187 1.1 brezak void *arg;
1188 1.1 brezak {
1189 1.1 brezak
1190 1.1 brezak sbdsp_wdsp(sc->sc_iobase, SB_MIDI_UART_INTR);
1191 1.1 brezak sc->sc_mintr = intr;
1192 1.1 brezak sc->sc_intr = 0;
1193 1.1 brezak sc->sc_arg = arg;
1194 1.1 brezak }
1195 1.1 brezak
1196 1.1 brezak /*
1197 1.1 brezak * Write a byte to the midi port, when in midi uart mode.
1198 1.1 brezak */
1199 1.1 brezak void
1200 1.1 brezak sbdsp_midi_output(sc, v)
1201 1.1 brezak struct sbdsp_softc *sc;
1202 1.1 brezak int v;
1203 1.1 brezak {
1204 1.1 brezak
1205 1.1 brezak if (sbdsp_wdsp(sc->sc_iobase, v) < 0)
1206 1.1 brezak ++sberr.wmidi;
1207 1.1 brezak }
1208 1.1 brezak #endif
1209 1.1 brezak
1210 1.1 brezak u_int
1211 1.1 brezak sbdsp_get_silence(enc)
1212 1.1 brezak int enc;
1213 1.1 brezak {
1214 1.1 brezak #define ULAW_SILENCE 0x7f
1215 1.1 brezak #define LINEAR_SILENCE 0
1216 1.1 brezak u_int auzero;
1217 1.1 brezak
1218 1.1 brezak switch (enc) {
1219 1.1 brezak case AUDIO_ENCODING_ULAW:
1220 1.1 brezak auzero = ULAW_SILENCE;
1221 1.1 brezak break;
1222 1.1 brezak case AUDIO_ENCODING_PCM16:
1223 1.1 brezak default:
1224 1.1 brezak auzero = LINEAR_SILENCE;
1225 1.1 brezak break;
1226 1.1 brezak }
1227 1.1 brezak
1228 1.1 brezak return(auzero);
1229 1.1 brezak }
1230 1.1 brezak
1231 1.1 brezak static u_char mulawtolin[256] = {
1232 1.1 brezak 128, 4, 8, 12, 16, 20, 24, 28,
1233 1.1 brezak 32, 36, 40, 44, 48, 52, 56, 60,
1234 1.1 brezak 64, 66, 68, 70, 72, 74, 76, 78,
1235 1.1 brezak 80, 82, 84, 86, 88, 90, 92, 94,
1236 1.1 brezak 96, 97, 98, 99, 100, 101, 102, 103,
1237 1.1 brezak 104, 105, 106, 107, 108, 109, 110, 111,
1238 1.1 brezak 112, 112, 113, 113, 114, 114, 115, 115,
1239 1.1 brezak 116, 116, 117, 117, 118, 118, 119, 119,
1240 1.1 brezak 120, 120, 120, 121, 121, 121, 121, 122,
1241 1.1 brezak 122, 122, 122, 123, 123, 123, 123, 124,
1242 1.1 brezak 124, 124, 124, 124, 125, 125, 125, 125,
1243 1.1 brezak 125, 125, 125, 125, 126, 126, 126, 126,
1244 1.1 brezak 126, 126, 126, 126, 126, 126, 126, 126,
1245 1.1 brezak 127, 127, 127, 127, 127, 127, 127, 127,
1246 1.1 brezak 127, 127, 127, 127, 127, 127, 127, 127,
1247 1.1 brezak 127, 127, 127, 127, 127, 127, 127, 127,
1248 1.1 brezak 255, 251, 247, 243, 239, 235, 231, 227,
1249 1.1 brezak 223, 219, 215, 211, 207, 203, 199, 195,
1250 1.1 brezak 191, 189, 187, 185, 183, 181, 179, 177,
1251 1.1 brezak 175, 173, 171, 169, 167, 165, 163, 161,
1252 1.1 brezak 159, 158, 157, 156, 155, 154, 153, 152,
1253 1.1 brezak 151, 150, 149, 148, 147, 146, 145, 144,
1254 1.1 brezak 143, 143, 142, 142, 141, 141, 140, 140,
1255 1.1 brezak 139, 139, 138, 138, 137, 137, 136, 136,
1256 1.1 brezak 135, 135, 135, 134, 134, 134, 134, 133,
1257 1.1 brezak 133, 133, 133, 132, 132, 132, 132, 131,
1258 1.1 brezak 131, 131, 131, 131, 130, 130, 130, 130,
1259 1.1 brezak 130, 130, 130, 130, 129, 129, 129, 129,
1260 1.1 brezak 129, 129, 129, 129, 129, 129, 129, 129,
1261 1.1 brezak 128, 128, 128, 128, 128, 128, 128, 128,
1262 1.1 brezak 128, 128, 128, 128, 128, 128, 128, 128,
1263 1.1 brezak 128, 128, 128, 128, 128, 128, 128, 128,
1264 1.1 brezak };
1265 1.1 brezak
1266 1.1 brezak static u_char lintomulaw[256] = {
1267 1.1 brezak 0, 0, 0, 0, 0, 1, 1, 1,
1268 1.1 brezak 1, 2, 2, 2, 2, 3, 3, 3,
1269 1.1 brezak 3, 4, 4, 4, 4, 5, 5, 5,
1270 1.1 brezak 5, 6, 6, 6, 6, 7, 7, 7,
1271 1.1 brezak 7, 8, 8, 8, 8, 9, 9, 9,
1272 1.1 brezak 9, 10, 10, 10, 10, 11, 11, 11,
1273 1.1 brezak 11, 12, 12, 12, 12, 13, 13, 13,
1274 1.1 brezak 13, 14, 14, 14, 14, 15, 15, 15,
1275 1.1 brezak 15, 16, 16, 17, 17, 18, 18, 19,
1276 1.1 brezak 19, 20, 20, 21, 21, 22, 22, 23,
1277 1.1 brezak 23, 24, 24, 25, 25, 26, 26, 27,
1278 1.1 brezak 27, 28, 28, 29, 29, 30, 30, 31,
1279 1.1 brezak 31, 32, 33, 34, 35, 36, 37, 38,
1280 1.1 brezak 39, 40, 41, 42, 43, 44, 45, 46,
1281 1.1 brezak 47, 48, 50, 52, 54, 56, 58, 60,
1282 1.1 brezak 62, 65, 69, 73, 77, 83, 91, 103,
1283 1.1 brezak 255, 231, 219, 211, 205, 201, 197, 193,
1284 1.1 brezak 190, 188, 186, 184, 182, 180, 178, 176,
1285 1.1 brezak 175, 174, 173, 172, 171, 170, 169, 168,
1286 1.1 brezak 167, 166, 165, 164, 163, 162, 161, 160,
1287 1.1 brezak 159, 159, 158, 158, 157, 157, 156, 156,
1288 1.1 brezak 155, 155, 154, 154, 153, 153, 152, 152,
1289 1.1 brezak 151, 151, 150, 150, 149, 149, 148, 148,
1290 1.1 brezak 147, 147, 146, 146, 145, 145, 144, 144,
1291 1.1 brezak 143, 143, 143, 143, 142, 142, 142, 142,
1292 1.1 brezak 141, 141, 141, 141, 140, 140, 140, 140,
1293 1.1 brezak 139, 139, 139, 139, 138, 138, 138, 138,
1294 1.1 brezak 137, 137, 137, 137, 136, 136, 136, 136,
1295 1.1 brezak 135, 135, 135, 135, 134, 134, 134, 134,
1296 1.1 brezak 133, 133, 133, 133, 132, 132, 132, 132,
1297 1.1 brezak 131, 131, 131, 131, 130, 130, 130, 130,
1298 1.1 brezak 129, 129, 129, 129, 128, 128, 128, 128,
1299 1.1 brezak };
1300 1.1 brezak
1301 1.1 brezak void
1302 1.1 brezak sbdsp_compress(e, p, cc)
1303 1.1 brezak int e;
1304 1.1 brezak u_char *p;
1305 1.1 brezak int cc;
1306 1.1 brezak {
1307 1.1 brezak u_char *tab;
1308 1.1 brezak
1309 1.1 brezak switch (e) {
1310 1.1 brezak case AUDIO_ENCODING_ULAW:
1311 1.1 brezak tab = lintomulaw;
1312 1.1 brezak break;
1313 1.1 brezak default:
1314 1.1 brezak return;
1315 1.1 brezak }
1316 1.1 brezak
1317 1.1 brezak while (--cc >= 0) {
1318 1.1 brezak *p = tab[*p];
1319 1.1 brezak ++p;
1320 1.1 brezak }
1321 1.1 brezak }
1322 1.1 brezak
1323 1.1 brezak void
1324 1.1 brezak sbdsp_expand(e, p, cc)
1325 1.1 brezak int e;
1326 1.1 brezak u_char *p;
1327 1.1 brezak int cc;
1328 1.1 brezak {
1329 1.1 brezak u_char *tab;
1330 1.1 brezak
1331 1.1 brezak switch (e) {
1332 1.1 brezak case AUDIO_ENCODING_ULAW:
1333 1.1 brezak tab = mulawtolin;
1334 1.1 brezak break;
1335 1.1 brezak default:
1336 1.1 brezak return;
1337 1.1 brezak }
1338 1.1 brezak
1339 1.1 brezak while (--cc >= 0) {
1340 1.1 brezak *p = tab[*p];
1341 1.1 brezak ++p;
1342 1.1 brezak }
1343 1.1 brezak }
1344 1.1 brezak
1345 1.1 brezak int
1346 1.1 brezak sbdsp_setfd(addr, flag)
1347 1.5 mycroft void *addr;
1348 1.1 brezak int flag;
1349 1.1 brezak {
1350 1.1 brezak /* Can't do full-duplex */
1351 1.1 brezak return(ENOTTY);
1352 1.1 brezak }
1353 1.1 brezak
1354 1.1 brezak int
1355 1.1 brezak sbdsp_mixer_set_port(addr, cp)
1356 1.5 mycroft void *addr;
1357 1.1 brezak mixer_ctrl_t *cp;
1358 1.1 brezak {
1359 1.5 mycroft register struct sbdsp_softc *sc = addr;
1360 1.1 brezak int error = 0;
1361 1.1 brezak int src, gain;
1362 1.1 brezak int left, right;
1363 1.1 brezak
1364 1.1 brezak DPRINTF(("sbdsp_mixer_set_port: port=%d num_channels=%d\n", cp->dev, cp->un.value.num_channels));
1365 1.1 brezak
1366 1.1 brezak /*
1367 1.1 brezak * Everything is a value except for SBPro special OUTPUT_MODE and
1368 1.1 brezak * RECORD_SOURCE
1369 1.1 brezak */
1370 1.1 brezak if (cp->type != AUDIO_MIXER_VALUE) {
1371 1.1 brezak if (!ISSBPROCLASS(sc) || (cp->dev != SB_OUTPUT_MODE &&
1372 1.1 brezak cp->dev != SB_RECORD_SOURCE))
1373 1.1 brezak return EINVAL;
1374 1.1 brezak }
1375 1.1 brezak else {
1376 1.1 brezak /*
1377 1.1 brezak * All the mixer ports are stereo except for the microphone.
1378 1.1 brezak * If we get a single-channel gain value passed in, then we
1379 1.1 brezak * duplicate it to both left and right channels.
1380 1.1 brezak */
1381 1.1 brezak if (cp->un.value.num_channels == 2) {
1382 1.1 brezak left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
1383 1.1 brezak right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
1384 1.1 brezak }
1385 1.1 brezak else
1386 1.1 brezak left = right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
1387 1.1 brezak }
1388 1.1 brezak
1389 1.1 brezak if (ISSBPROCLASS(sc)) {
1390 1.1 brezak /* The _PORT things are all signal inputs to the mixer.
1391 1.1 brezak * Here we are tweaking their mixing level.
1392 1.1 brezak *
1393 1.1 brezak * We can also tweak the output stage volume (MASTER_VOL)
1394 1.1 brezak */
1395 1.1 brezak gain = sbdsp_stereo_vol(SBP_AGAIN_TO_SBGAIN(left),
1396 1.1 brezak SBP_AGAIN_TO_SBGAIN(right));
1397 1.1 brezak switch(cp->dev) {
1398 1.1 brezak case SB_MIC_PORT:
1399 1.1 brezak src = SBP_MIC_VOL;
1400 1.1 brezak if (cp->un.value.num_channels != 1)
1401 1.1 brezak error = EINVAL;
1402 1.1 brezak else
1403 1.1 brezak /* handle funny microphone gain */
1404 1.1 brezak gain = SBP_AGAIN_TO_MICGAIN(left);
1405 1.1 brezak break;
1406 1.1 brezak case SB_LINE_IN_PORT:
1407 1.1 brezak src = SBP_LINE_VOL;
1408 1.1 brezak break;
1409 1.1 brezak case SB_DAC_PORT:
1410 1.1 brezak src = SBP_DAC_VOL;
1411 1.1 brezak break;
1412 1.1 brezak case SB_FM_PORT:
1413 1.1 brezak src = SBP_FM_VOL;
1414 1.1 brezak break;
1415 1.1 brezak case SB_CD_PORT:
1416 1.1 brezak src = SBP_CD_VOL;
1417 1.1 brezak break;
1418 1.1 brezak case SB_SPEAKER:
1419 1.1 brezak cp->dev = SB_MASTER_VOL;
1420 1.1 brezak case SB_MASTER_VOL:
1421 1.1 brezak src = SBP_MASTER_VOL;
1422 1.1 brezak break;
1423 1.1 brezak #if 0
1424 1.1 brezak case SB_OUTPUT_MODE:
1425 1.1 brezak if (cp->type == AUDIO_MIXER_ENUM)
1426 1.1 brezak return sbdsp_set_channels(addr, cp->un.ord);
1427 1.1 brezak /* fall through...carefully! */
1428 1.1 brezak #endif
1429 1.1 brezak case SB_RECORD_SOURCE:
1430 1.1 brezak if (cp->type == AUDIO_MIXER_ENUM)
1431 1.1 brezak return sbdsp_set_in_port(addr, cp->un.ord);
1432 1.1 brezak /* else fall through: bad input */
1433 1.1 brezak case SB_TREBLE:
1434 1.1 brezak case SB_BASS:
1435 1.1 brezak default:
1436 1.1 brezak error = EINVAL;
1437 1.1 brezak break;
1438 1.1 brezak }
1439 1.1 brezak if (!error)
1440 1.1 brezak sbdsp_mix_write(sc, src, gain);
1441 1.1 brezak }
1442 1.1 brezak else if (cp->dev != SB_MIC_PORT &&
1443 1.1 brezak cp->dev != SB_SPEAKER)
1444 1.1 brezak error = EINVAL;
1445 1.1 brezak
1446 1.1 brezak if (!error)
1447 1.1 brezak sc->gain[cp->dev] = gain;
1448 1.1 brezak
1449 1.1 brezak return(error);
1450 1.1 brezak }
1451 1.1 brezak
1452 1.1 brezak int
1453 1.1 brezak sbdsp_mixer_get_port(addr, cp)
1454 1.5 mycroft void *addr;
1455 1.1 brezak mixer_ctrl_t *cp;
1456 1.1 brezak {
1457 1.5 mycroft register struct sbdsp_softc *sc = addr;
1458 1.1 brezak int error = 0;
1459 1.1 brezak int done = 0;
1460 1.1 brezak
1461 1.1 brezak DPRINTF(("sbdsp_mixer_get_port: port=%d", cp->dev));
1462 1.1 brezak
1463 1.1 brezak if (ISSBPROCLASS(sc))
1464 1.1 brezak switch(cp->dev) {
1465 1.1 brezak case SB_MIC_PORT:
1466 1.1 brezak if (cp->un.value.num_channels == 1) {
1467 1.1 brezak cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1468 1.1 brezak SBP_MICGAIN_TO_AGAIN(sc->gain[cp->dev]);
1469 1.1 brezak return 0;
1470 1.1 brezak }
1471 1.1 brezak else
1472 1.1 brezak return EINVAL;
1473 1.1 brezak break;
1474 1.1 brezak case SB_LINE_IN_PORT:
1475 1.1 brezak case SB_DAC_PORT:
1476 1.1 brezak case SB_FM_PORT:
1477 1.1 brezak case SB_CD_PORT:
1478 1.1 brezak case SB_MASTER_VOL:
1479 1.1 brezak break;
1480 1.1 brezak case SB_SPEAKER:
1481 1.1 brezak cp->dev = SB_MASTER_VOL;
1482 1.1 brezak break;
1483 1.1 brezak default:
1484 1.1 brezak error = EINVAL;
1485 1.1 brezak break;
1486 1.1 brezak }
1487 1.1 brezak else {
1488 1.1 brezak if (cp->un.value.num_channels != 1) /* no stereo on SB classic */
1489 1.1 brezak error = EINVAL;
1490 1.1 brezak else
1491 1.1 brezak switch(cp->dev) {
1492 1.1 brezak case SB_MIC_PORT:
1493 1.1 brezak break;
1494 1.1 brezak case SB_SPEAKER:
1495 1.1 brezak break;
1496 1.1 brezak default:
1497 1.1 brezak error = EINVAL;
1498 1.1 brezak break;
1499 1.1 brezak }
1500 1.1 brezak }
1501 1.1 brezak if (error == 0) {
1502 1.1 brezak if (cp->un.value.num_channels == 1) {
1503 1.1 brezak cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1504 1.1 brezak SBP_SBGAIN_TO_AGAIN(sc->gain[cp->dev]);
1505 1.1 brezak }
1506 1.1 brezak else if (cp->un.value.num_channels == 2) {
1507 1.1 brezak cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1508 1.1 brezak SBP_LEFTGAIN(sc->gain[cp->dev]);
1509 1.1 brezak cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1510 1.1 brezak SBP_RIGHTGAIN(sc->gain[cp->dev]);
1511 1.1 brezak } else
1512 1.1 brezak return EINVAL;
1513 1.1 brezak }
1514 1.1 brezak return(error);
1515 1.1 brezak }
1516 1.1 brezak
1517 1.1 brezak int
1518 1.1 brezak sbdsp_mixer_query_devinfo(addr, dip)
1519 1.5 mycroft void *addr;
1520 1.1 brezak register mixer_devinfo_t *dip;
1521 1.1 brezak {
1522 1.5 mycroft register struct sbdsp_softc *sc = addr;
1523 1.1 brezak int done = 0;
1524 1.1 brezak
1525 1.1 brezak DPRINTF(("sbdsp_mixer_query_devinfo: index=%d\n", dip->index));
1526 1.1 brezak
1527 1.1 brezak switch (dip->index) {
1528 1.1 brezak case SB_MIC_PORT:
1529 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1530 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1531 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1532 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1533 1.1 brezak strcpy(dip->label.name, AudioNmicrophone);
1534 1.1 brezak dip->un.v.num_channels = 1;
1535 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1536 1.1 brezak done = 1;
1537 1.1 brezak break;
1538 1.1 brezak case SB_SPEAKER:
1539 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1540 1.1 brezak dip->mixer_class = SB_OUTPUT_CLASS;
1541 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1542 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1543 1.1 brezak strcpy(dip->label.name, AudioNspeaker);
1544 1.1 brezak dip->un.v.num_channels = 1;
1545 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1546 1.1 brezak done = 1;
1547 1.1 brezak break;
1548 1.1 brezak case SB_INPUT_CLASS:
1549 1.1 brezak dip->type = AUDIO_MIXER_CLASS;
1550 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1551 1.1 brezak dip->next = dip->prev = AUDIO_MIXER_LAST;
1552 1.1 brezak strcpy(dip->label.name, AudioCInputs);
1553 1.1 brezak done = 1;
1554 1.1 brezak break;
1555 1.1 brezak case SB_OUTPUT_CLASS:
1556 1.1 brezak dip->type = AUDIO_MIXER_CLASS;
1557 1.1 brezak dip->mixer_class = SB_OUTPUT_CLASS;
1558 1.1 brezak dip->next = dip->prev = AUDIO_MIXER_LAST;
1559 1.1 brezak strcpy(dip->label.name, AudioCOutputs);
1560 1.1 brezak done = 1;
1561 1.1 brezak break;
1562 1.1 brezak }
1563 1.1 brezak
1564 1.1 brezak if (!done) {
1565 1.1 brezak if (ISSBPROCLASS(sc))
1566 1.1 brezak switch(dip->index) {
1567 1.1 brezak case SB_LINE_IN_PORT:
1568 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1569 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1570 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1571 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1572 1.1 brezak strcpy(dip->label.name, AudioNline);
1573 1.1 brezak dip->un.v.num_channels = 2;
1574 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1575 1.1 brezak break;
1576 1.1 brezak case SB_DAC_PORT:
1577 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1578 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1579 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1580 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1581 1.1 brezak strcpy(dip->label.name, AudioNdac);
1582 1.1 brezak dip->un.v.num_channels = 2;
1583 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1584 1.1 brezak break;
1585 1.1 brezak case SB_CD_PORT:
1586 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1587 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1588 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1589 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1590 1.1 brezak strcpy(dip->label.name, AudioNcd);
1591 1.1 brezak dip->un.v.num_channels = 2;
1592 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1593 1.1 brezak break;
1594 1.1 brezak case SB_FM_PORT:
1595 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1596 1.1 brezak dip->mixer_class = SB_INPUT_CLASS;
1597 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1598 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1599 1.1 brezak strcpy(dip->label.name, "fmsynth"); /* XXX move to audioio.h */
1600 1.1 brezak dip->un.v.num_channels = 2;
1601 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1602 1.1 brezak break;
1603 1.1 brezak case SB_MASTER_VOL:
1604 1.1 brezak dip->type = AUDIO_MIXER_VALUE;
1605 1.1 brezak dip->mixer_class = SB_OUTPUT_CLASS;
1606 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1607 1.1 brezak dip->next = SB_OUTPUT_MODE;
1608 1.1 brezak strcpy(dip->label.name, AudioNvolume);
1609 1.1 brezak dip->un.v.num_channels = 2;
1610 1.1 brezak strcpy(dip->un.v.units.name, AudioNvolume);
1611 1.1 brezak break;
1612 1.1 brezak #if 0
1613 1.1 brezak case SB_OUTPUT_MODE:
1614 1.1 brezak dip->mixer_class = SB_OUTPUT_CLASS;
1615 1.1 brezak dip->type = AUDIO_MIXER_ENUM;
1616 1.1 brezak dip->prev = SB_MASTER_VOL;
1617 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1618 1.1 brezak strcpy(dip->label.name, AudioNmode);
1619 1.1 brezak dip->un.e.num_mem = 2;
1620 1.1 brezak strcpy(dip->un.e.member[0].label.name, AudioNmono);
1621 1.1 brezak dip->un.e.member[0].ord = 1; /* nchans */
1622 1.1 brezak strcpy(dip->un.e.member[1].label.name, AudioNstereo);
1623 1.1 brezak dip->un.e.member[1].ord = 2; /* nchans */
1624 1.1 brezak break;
1625 1.1 brezak #endif
1626 1.1 brezak case SB_RECORD_SOURCE:
1627 1.1 brezak dip->mixer_class = SB_RECORD_CLASS;
1628 1.1 brezak dip->type = AUDIO_MIXER_ENUM;
1629 1.1 brezak dip->prev = AUDIO_MIXER_LAST;
1630 1.1 brezak dip->next = AUDIO_MIXER_LAST;
1631 1.1 brezak strcpy(dip->label.name, AudioNsource);
1632 1.1 brezak dip->un.e.num_mem = 3;
1633 1.1 brezak strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
1634 1.1 brezak dip->un.e.member[0].ord = SB_MIC_PORT;
1635 1.1 brezak strcpy(dip->un.e.member[1].label.name, AudioNcd);
1636 1.1 brezak dip->un.e.member[1].ord = SB_CD_PORT;
1637 1.1 brezak strcpy(dip->un.e.member[2].label.name, AudioNline);
1638 1.1 brezak dip->un.e.member[2].ord = SB_LINE_IN_PORT;
1639 1.1 brezak break;
1640 1.1 brezak case SB_BASS:
1641 1.1 brezak case SB_TREBLE:
1642 1.1 brezak default:
1643 1.1 brezak return ENXIO;
1644 1.1 brezak /*NOTREACHED*/
1645 1.1 brezak }
1646 1.1 brezak else
1647 1.1 brezak return ENXIO;
1648 1.1 brezak }
1649 1.1 brezak
1650 1.1 brezak DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
1651 1.1 brezak
1652 1.1 brezak return 0;
1653 1.1 brezak }
1654