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