4 * The low level driver for the SoundBlaster DSP chip.
6 * (C) 1993 J. Schubert (jsb@sth.ruhr-uni-bochum.de)
8 * based on SB-driver by (C) Hannu Savolainen
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met: 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 2.
14 * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * $FreeBSD: src/sys/i386/isa/sound/sb16_dsp.c,v 1.33 1999/12/27 04:37:18 tanimura Exp $
36 #include <i386/isa/sound/sound_config.h>
38 #include <i386/isa/sound/sb_mixer.h>
39 #include <i386/isa/sound/sbcard.h>
41 #if defined(CONFIG_SB16) && (NSB > 0) && defined(CONFIG_AUDIO) && defined(CONFIG_SBPRO)
44 extern sound_os_info *sb_osp;
47 static int sb16_dsp_ok = 0;
48 static int dsp_16bit = 0;
49 static int dsp_stereo = 0;
50 static int dsp_current_speed = 8000;
51 static int dsp_busy = 0;
52 static int dma16, dma8;
55 static int trigger_bits = 0;
56 static u_long dsp_count = 0;
58 static int irq_mode = IMODE_NONE;
59 static int my_dev = 0;
61 static volatile int intr_active = 0;
63 static int sb16_dsp_open(int dev, int mode);
64 static void sb16_dsp_close(int dev);
65 static void sb16_dsp_output_block(int dev, u_long buf, int count, int intrflag, int dma_restart);
66 static void sb16_dsp_start_input(int dev, u_long buf, int count, int intrflag, int dma_restart);
67 static int sb16_dsp_ioctl(int dev, u_int cmd, ioctl_arg arg, int local);
68 static int sb16_dsp_prepare_for_input(int dev, int bsize, int bcount);
69 static int sb16_dsp_prepare_for_output(int dev, int bsize, int bcount);
70 static void sb16_dsp_reset(int dev);
71 static void sb16_dsp_halt(int dev);
72 static void sb16_dsp_trigger(int dev, int bits);
73 static int dsp_set_speed(int);
74 static int dsp_set_stereo(int);
75 static void dsp_cleanup(void);
77 static struct audio_operations sb16_dsp_operations =
81 AFMT_U8 | AFMT_S16_LE,
85 sb16_dsp_output_block,
88 sb16_dsp_prepare_for_input,
89 sb16_dsp_prepare_for_output,
100 sb_dsp_command01(u_char val)
104 while (--i & (!inb(DSP_STATUS) & 0x80));
106 printf("SB16 sb_dsp_command01 Timeout\n");
107 return sb_dsp_command(val);
111 dsp_set_speed(int mode)
113 DEB(printf("dsp_set_speed(%d)\n", mode));
115 RANGE (mode, 5000, 44100);
116 dsp_current_speed = mode;
122 dsp_set_stereo(int mode)
124 DEB(printf("dsp_set_stereo(%d)\n", mode));
130 dsp_set_bits(int arg)
132 DEB(printf("dsp_set_bits(%d)\n", arg));
135 dsp_16bit = (arg == 16) ? 1 : 0 ;
136 return dsp_16bit ? 16 : 8;
140 sb16_dsp_ioctl(int dev, u_int cmd, ioctl_arg arg, int local)
143 case SOUND_PCM_WRITE_RATE:
145 return dsp_set_speed((int) arg);
146 return *(int *) arg = dsp_set_speed((*(int *) arg));
148 case SOUND_PCM_READ_RATE:
150 return dsp_current_speed;
151 return *(int *) arg = dsp_current_speed;
153 case SNDCTL_DSP_STEREO:
155 return dsp_set_stereo((int) arg);
156 return *(int *) arg = dsp_set_stereo((*(int *) arg));
158 case SOUND_PCM_WRITE_CHANNELS:
160 return dsp_set_stereo((int) arg - 1) + 1;
161 return *(int *) arg = dsp_set_stereo((*(int *) arg) - 1) + 1;
163 case SOUND_PCM_READ_CHANNELS:
165 return dsp_stereo + 1;
166 return *(int *) arg = dsp_stereo + 1;
168 case SNDCTL_DSP_SETFMT:
170 return dsp_set_bits((int) arg);
171 return *(int *) arg = dsp_set_bits((*(int *) arg));
173 case SOUND_PCM_READ_BITS:
175 return dsp_16bit ? 16 : 8;
176 return *(int *) arg = dsp_16bit ? 16 : 8;
178 case SOUND_PCM_WRITE_FILTER: /* NOT YET IMPLEMENTED */
179 if ((*(int *) arg) > 1)
180 return *(int *) arg = -(EINVAL);
185 return *(int *) arg = 1;
190 return *(int *) arg = 1;
200 sb16_dsp_open(int dev, int mode)
202 DEB(printf("sb16_dsp_open()\n"));
205 printf("SB16 Error: SoundBlaster board not installed\n");
214 irq_mode = IMODE_NONE;
222 sb16_dsp_close(int dev)
226 DEB(printf("sb16_dsp_close()\n"));
227 sb_dsp_command01(0xd9);
228 sb_dsp_command01(0xd5);
232 audio_devs[dev]->dmachan1 = dma8;
242 sb16_dsp_output_block(int dev, u_long buf, int count, int intrflag, int dma_restart)
252 if (audio_devs[dev]->flags & DMA_AUTOMODE && intrflag && cnt==dsp_count) {
253 irq_mode = IMODE_OUTPUT;
255 return; /* Auto mode on. No need to react */
262 DMAbuf_start_dma(dev, buf, count, 1);
266 sb_dsp_command(0x41);
267 sb_dsp_command((u_char) ((dsp_current_speed >> 8) & 0xff));
268 sb_dsp_command((u_char) (dsp_current_speed & 0xff));
269 sb_dsp_command((u_char) (dsp_16bit ? 0xb6 : 0xc6));
271 sb_dsp_command((u_char) ((dsp_stereo ? 0x20 : 0) +
272 (dsp_16bit ? 0x10 : 0)));
273 sb_dsp_command((u_char) (cnt & 0xff));
274 sb_dsp_command((u_char) (cnt >> 8));
276 irq_mode = IMODE_OUTPUT;
282 sb16_dsp_start_input(int dev, u_long buf, int count, int intrflag, int dma_restart)
291 if (audio_devs[dev]->flags & DMA_AUTOMODE && intrflag && cnt == dsp_count) {
292 irq_mode = IMODE_INPUT;
294 return; /* Auto mode on. No need to react */
300 DMAbuf_start_dma(dev, buf, count, 0);
302 sb_dsp_command(0x42);
303 sb_dsp_command((u_char) ((dsp_current_speed >> 8) & 0xff));
304 sb_dsp_command((u_char) (dsp_current_speed & 0xff));
305 sb_dsp_command((u_char) (dsp_16bit ? 0xbe : 0xce));
307 sb_dsp_command((u_char) ((dsp_stereo ? 0x20 : 0) +
308 (dsp_16bit ? 0x10 : 0)));
309 sb_dsp_command01((u_char) (cnt & 0xff));
310 sb_dsp_command((u_char) (cnt >> 8));
312 irq_mode = IMODE_INPUT;
318 sb16_dsp_prepare_for_input(int dev, int bsize, int bcount)
321 struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
323 audio_devs[my_dev]->dmachan2 = dsp_16bit ? dma16 : dma8;
326 fudge = audio_devs[my_dev]->dmachan2 ;
328 if (dmap->dma_chan != fudge ) {
329 isa_dma_release( dmap->dma_chan);
330 isa_dma_acquire(fudge);
331 dmap->dma_chan = fudge;
337 sb_dsp_command(0xd5); /* Halt DMA until trigger() is called */
339 sb_dsp_command(0xd0); /* Halt DMA until trigger() is called */
346 sb16_dsp_prepare_for_output(int dev, int bsize, int bcount)
348 int fudge = dsp_16bit ? dma16 : dma8;
349 struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
351 if (dmap->dma_chan != fudge ) {
352 isa_dma_release( dmap->dma_chan);
353 isa_dma_acquire(fudge);
354 dmap->dma_chan = fudge;
357 audio_devs[my_dev]->dmachan1 = fudge;
362 sb_dsp_command(0xd5); /* Halt DMA until trigger() is called */
364 sb_dsp_command(0xd0); /* Halt DMA until trigger() is called */
371 sb16_dsp_trigger(int dev, int bits)
376 if (bits == trigger_bits) /* No change */
382 sb_dsp_command(0xd0); /* Halt DMA */
383 else if (bits & irq_mode) {
385 sb_dsp_command(0xd6); /* Continue 16bit DMA */
387 sb_dsp_command(0xd4); /* Continue 8bit DMA */
394 irq_mode = IMODE_NONE;
399 sb16_dsp_reset(int dev)
412 sb16_dsp_halt(int dev)
416 sb_dsp_command01(0xd9);
417 sb_dsp_command01(0xd5);
419 sb_dsp_command01(0xda);
420 sb_dsp_command01(0xd0);
427 set_irq_hw(int level)
457 printf("SB16_IRQ_LEVEL %d does not exist\n", level);
460 sb_setmixer(IRQ_NR, ival);
464 sb16_dsp_init(struct address_info * hw_config)
467 return; /* Not a SB16 */
469 snprintf(sb16_dsp_operations.name, sizeof(sb16_dsp_operations.name),
470 "SoundBlaster 16 %d.%d", sbc_major, sbc_minor);
472 conf_printf(sb16_dsp_operations.name, hw_config);
474 if (num_audiodevs < MAX_AUDIO_DEV) {
475 audio_devs[my_dev = num_audiodevs++] = &sb16_dsp_operations;
476 audio_devs[my_dev]->dmachan1 = dma8;
477 audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
480 printf("SB: Too many DSP devices available\n");
486 sb16_dsp_detect(struct address_info * hw_config)
488 struct address_info *sb_config;
491 return 1; /* Can't drive two cards */
493 if (!(sb_config = sound_getconf(SNDCARD_SB))) {
494 printf("SB16 Error: Plain SB not configured\n");
498 * sb_setmixer(OPSW,0xf); if(sb_getmixer(OPSW)!=0xf) return 0;
504 if (sbc_major < 4) /* Set by the plain SB driver */
505 return 0; /* Not a SB16 */
508 hw_config->dma = sb_config->dma;
510 if (hw_config->dma < 4)
511 if (hw_config->dma != sb_config->dma) {
512 printf("SB16 Error: Invalid DMA channel %d/%d\n",
513 sb_config->dma, hw_config->dma);
517 dma16 = hw_config->dma;
518 dma8 = sb_config->dma;
519 /* hw_config->irq = 0; sb_config->irq;
520 hw_config->io_base = sb_config->io_base;
522 set_irq_hw(sb_config->irq);
525 sb_setmixer (DMA_NR, hw_config->dma == 0 ? 1 : 2);
527 sb_setmixer(DMA_NR, (1 << hw_config->dma) | (1 << sb_config->dma));
530 DEB(printf("SoundBlaster 16: IRQ %d DMA %d OK\n",
531 sb_config->irq, hw_config->dma));
534 * dsp_showmessage(0xe3,99);
541 sb16_dsp_interrupt(int unused)
545 data = inb(DSP_DATA_AVL16); /* Interrupt acknowledge */
550 DMAbuf_outputintr(my_dev, 1);
554 DMAbuf_inputintr(my_dev);
558 printf("SoundBlaster: Unexpected interrupt\n");