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 $
31 * $DragonFly: src/sys/dev/sound/isa/i386/sbxvi/Attic/sb16_dsp.c,v 1.3 2003/08/07 21:17:12 dillon Exp $
39 #include <dev/sound/isa/i386/sound_config.h>
40 #include <dev/sound/isa/i386/sb_mixer.h>
41 #include <dev/sound/isa/i386/sbcard.h>
43 #if defined(CONFIG_SB16) && (NSB > 0) && defined(CONFIG_AUDIO) && defined(CONFIG_SBPRO)
45 extern sound_os_info *sb_osp;
48 static int sb16_dsp_ok = 0;
49 static int dsp_16bit = 0;
50 static int dsp_stereo = 0;
51 static int dsp_current_speed = 8000;
52 static int dsp_busy = 0;
53 static int dma16, dma8;
56 static int trigger_bits = 0;
57 static u_long dsp_count = 0;
59 static int irq_mode = IMODE_NONE;
60 static int my_dev = 0;
62 static volatile int intr_active = 0;
64 static int sb16_dsp_open(int dev, int mode);
65 static void sb16_dsp_close(int dev);
66 static void sb16_dsp_output_block(int dev, u_long buf, int count, int intrflag, int dma_restart);
67 static void sb16_dsp_start_input(int dev, u_long buf, int count, int intrflag, int dma_restart);
68 static int sb16_dsp_ioctl(int dev, u_int cmd, ioctl_arg arg, int local);
69 static int sb16_dsp_prepare_for_input(int dev, int bsize, int bcount);
70 static int sb16_dsp_prepare_for_output(int dev, int bsize, int bcount);
71 static void sb16_dsp_reset(int dev);
72 static void sb16_dsp_halt(int dev);
73 static void sb16_dsp_trigger(int dev, int bits);
74 static int dsp_set_speed(int);
75 static int dsp_set_stereo(int);
76 static void dsp_cleanup(void);
78 static struct audio_operations sb16_dsp_operations =
82 AFMT_U8 | AFMT_S16_LE,
86 sb16_dsp_output_block,
89 sb16_dsp_prepare_for_input,
90 sb16_dsp_prepare_for_output,
101 sb_dsp_command01(u_char val)
105 while (--i & (!inb(DSP_STATUS) & 0x80));
107 printf("SB16 sb_dsp_command01 Timeout\n");
108 return sb_dsp_command(val);
112 dsp_set_speed(int mode)
114 DEB(printf("dsp_set_speed(%d)\n", mode));
116 RANGE (mode, 5000, 44100);
117 dsp_current_speed = mode;
123 dsp_set_stereo(int mode)
125 DEB(printf("dsp_set_stereo(%d)\n", mode));
131 dsp_set_bits(int arg)
133 DEB(printf("dsp_set_bits(%d)\n", arg));
136 dsp_16bit = (arg == 16) ? 1 : 0 ;
137 return dsp_16bit ? 16 : 8;
141 sb16_dsp_ioctl(int dev, u_int cmd, ioctl_arg arg, int local)
144 case SOUND_PCM_WRITE_RATE:
146 return dsp_set_speed((int) arg);
147 return *(int *) arg = dsp_set_speed((*(int *) arg));
149 case SOUND_PCM_READ_RATE:
151 return dsp_current_speed;
152 return *(int *) arg = dsp_current_speed;
154 case SNDCTL_DSP_STEREO:
156 return dsp_set_stereo((int) arg);
157 return *(int *) arg = dsp_set_stereo((*(int *) arg));
159 case SOUND_PCM_WRITE_CHANNELS:
161 return dsp_set_stereo((int) arg - 1) + 1;
162 return *(int *) arg = dsp_set_stereo((*(int *) arg) - 1) + 1;
164 case SOUND_PCM_READ_CHANNELS:
166 return dsp_stereo + 1;
167 return *(int *) arg = dsp_stereo + 1;
169 case SNDCTL_DSP_SETFMT:
171 return dsp_set_bits((int) arg);
172 return *(int *) arg = dsp_set_bits((*(int *) arg));
174 case SOUND_PCM_READ_BITS:
176 return dsp_16bit ? 16 : 8;
177 return *(int *) arg = dsp_16bit ? 16 : 8;
179 case SOUND_PCM_WRITE_FILTER: /* NOT YET IMPLEMENTED */
180 if ((*(int *) arg) > 1)
181 return *(int *) arg = -(EINVAL);
186 return *(int *) arg = 1;
191 return *(int *) arg = 1;
201 sb16_dsp_open(int dev, int mode)
203 DEB(printf("sb16_dsp_open()\n"));
206 printf("SB16 Error: SoundBlaster board not installed\n");
215 irq_mode = IMODE_NONE;
223 sb16_dsp_close(int dev)
227 DEB(printf("sb16_dsp_close()\n"));
228 sb_dsp_command01(0xd9);
229 sb_dsp_command01(0xd5);
233 audio_devs[dev]->dmachan1 = dma8;
243 sb16_dsp_output_block(int dev, u_long buf, int count, int intrflag, int dma_restart)
253 if (audio_devs[dev]->flags & DMA_AUTOMODE && intrflag && cnt==dsp_count) {
254 irq_mode = IMODE_OUTPUT;
256 return; /* Auto mode on. No need to react */
263 DMAbuf_start_dma(dev, buf, count, 1);
267 sb_dsp_command(0x41);
268 sb_dsp_command((u_char) ((dsp_current_speed >> 8) & 0xff));
269 sb_dsp_command((u_char) (dsp_current_speed & 0xff));
270 sb_dsp_command((u_char) (dsp_16bit ? 0xb6 : 0xc6));
272 sb_dsp_command((u_char) ((dsp_stereo ? 0x20 : 0) +
273 (dsp_16bit ? 0x10 : 0)));
274 sb_dsp_command((u_char) (cnt & 0xff));
275 sb_dsp_command((u_char) (cnt >> 8));
277 irq_mode = IMODE_OUTPUT;
283 sb16_dsp_start_input(int dev, u_long buf, int count, int intrflag, int dma_restart)
292 if (audio_devs[dev]->flags & DMA_AUTOMODE && intrflag && cnt == dsp_count) {
293 irq_mode = IMODE_INPUT;
295 return; /* Auto mode on. No need to react */
301 DMAbuf_start_dma(dev, buf, count, 0);
303 sb_dsp_command(0x42);
304 sb_dsp_command((u_char) ((dsp_current_speed >> 8) & 0xff));
305 sb_dsp_command((u_char) (dsp_current_speed & 0xff));
306 sb_dsp_command((u_char) (dsp_16bit ? 0xbe : 0xce));
308 sb_dsp_command((u_char) ((dsp_stereo ? 0x20 : 0) +
309 (dsp_16bit ? 0x10 : 0)));
310 sb_dsp_command01((u_char) (cnt & 0xff));
311 sb_dsp_command((u_char) (cnt >> 8));
313 irq_mode = IMODE_INPUT;
319 sb16_dsp_prepare_for_input(int dev, int bsize, int bcount)
322 struct dma_buffparms *dmap = audio_devs[dev]->dmap_in;
324 audio_devs[my_dev]->dmachan2 = dsp_16bit ? dma16 : dma8;
327 fudge = audio_devs[my_dev]->dmachan2 ;
329 if (dmap->dma_chan != fudge ) {
330 isa_dma_release( dmap->dma_chan);
331 isa_dma_acquire(fudge);
332 dmap->dma_chan = fudge;
338 sb_dsp_command(0xd5); /* Halt DMA until trigger() is called */
340 sb_dsp_command(0xd0); /* Halt DMA until trigger() is called */
347 sb16_dsp_prepare_for_output(int dev, int bsize, int bcount)
349 int fudge = dsp_16bit ? dma16 : dma8;
350 struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
352 if (dmap->dma_chan != fudge ) {
353 isa_dma_release( dmap->dma_chan);
354 isa_dma_acquire(fudge);
355 dmap->dma_chan = fudge;
358 audio_devs[my_dev]->dmachan1 = fudge;
363 sb_dsp_command(0xd5); /* Halt DMA until trigger() is called */
365 sb_dsp_command(0xd0); /* Halt DMA until trigger() is called */
372 sb16_dsp_trigger(int dev, int bits)
377 if (bits == trigger_bits) /* No change */
383 sb_dsp_command(0xd0); /* Halt DMA */
384 else if (bits & irq_mode) {
386 sb_dsp_command(0xd6); /* Continue 16bit DMA */
388 sb_dsp_command(0xd4); /* Continue 8bit DMA */
395 irq_mode = IMODE_NONE;
400 sb16_dsp_reset(int dev)
413 sb16_dsp_halt(int dev)
417 sb_dsp_command01(0xd9);
418 sb_dsp_command01(0xd5);
420 sb_dsp_command01(0xda);
421 sb_dsp_command01(0xd0);
428 set_irq_hw(int level)
458 printf("SB16_IRQ_LEVEL %d does not exist\n", level);
461 sb_setmixer(IRQ_NR, ival);
465 sb16_dsp_init(struct address_info * hw_config)
468 return; /* Not a SB16 */
470 snprintf(sb16_dsp_operations.name, sizeof(sb16_dsp_operations.name),
471 "SoundBlaster 16 %d.%d", sbc_major, sbc_minor);
473 conf_printf(sb16_dsp_operations.name, hw_config);
475 if (num_audiodevs < MAX_AUDIO_DEV) {
476 audio_devs[my_dev = num_audiodevs++] = &sb16_dsp_operations;
477 audio_devs[my_dev]->dmachan1 = dma8;
478 audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
481 printf("SB: Too many DSP devices available\n");
487 sb16_dsp_detect(struct address_info * hw_config)
489 struct address_info *sb_config;
492 return 1; /* Can't drive two cards */
494 if (!(sb_config = sound_getconf(SNDCARD_SB))) {
495 printf("SB16 Error: Plain SB not configured\n");
499 * sb_setmixer(OPSW,0xf); if(sb_getmixer(OPSW)!=0xf) return 0;
505 if (sbc_major < 4) /* Set by the plain SB driver */
506 return 0; /* Not a SB16 */
509 hw_config->dma = sb_config->dma;
511 if (hw_config->dma < 4)
512 if (hw_config->dma != sb_config->dma) {
513 printf("SB16 Error: Invalid DMA channel %d/%d\n",
514 sb_config->dma, hw_config->dma);
518 dma16 = hw_config->dma;
519 dma8 = sb_config->dma;
520 /* hw_config->irq = 0; sb_config->irq;
521 hw_config->io_base = sb_config->io_base;
523 set_irq_hw(sb_config->irq);
526 sb_setmixer (DMA_NR, hw_config->dma == 0 ? 1 : 2);
528 sb_setmixer(DMA_NR, (1 << hw_config->dma) | (1 << sb_config->dma));
531 DEB(printf("SoundBlaster 16: IRQ %d DMA %d OK\n",
532 sb_config->irq, hw_config->dma));
535 * dsp_showmessage(0xe3,99);
542 sb16_dsp_interrupt(int unused)
546 data = inb(DSP_DATA_AVL16); /* Interrupt acknowledge */
551 DMAbuf_outputintr(my_dev, 1);
555 DMAbuf_inputintr(my_dev);
559 printf("SoundBlaster: Unexpected interrupt\n");