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
37 #include "sound_config.h"
41 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_AUDIO) && !defined(EXCLUDE_SBPRO)
45 static int sb16_dsp_ok
= 0; /* Set to 1 after successful initialization */
46 static int dsp_16bit
= 0;
47 static int dsp_stereo
= 0;
48 static int dsp_current_speed
= 8000;/*DSP_DEFAULT_SPEED;*/
49 static int dsp_busy
= 0;
50 static int dma16
, dma8
;
51 static unsigned long dsp_count
= 0;
53 static int irq_mode
= IMODE_NONE
; /* IMODE_INPUT, IMODE_OUTPUT or
55 static int my_dev
= 0;
57 static volatile int intr_active
= 0;
59 static int sb16_dsp_open (int dev
, int mode
);
60 static void sb16_dsp_close (int dev
);
61 static void sb16_dsp_output_block (int dev
, unsigned long buf
, int count
,int intrflag
, int dma_restart
);
62 static void sb16_dsp_start_input (int dev
, unsigned long buf
, int count
,int intrflag
, int dma_restart
);
63 static int sb16_dsp_ioctl (int dev
, unsigned int cmd
, unsigned int arg
,int local
);
64 static int sb16_dsp_prepare_for_input (int dev
, int bsize
, int bcount
);
65 static int sb16_dsp_prepare_for_output (int dev
, int bsize
, int bcount
);
66 static void sb16_dsp_reset (int dev
);
67 static void sb16_dsp_halt (int dev
);
68 static int dsp_set_speed (int);
69 static int dsp_set_stereo (int);
70 static void dsp_cleanup (void);
71 int sb_reset_dsp (void);
73 static struct audio_operations sb16_dsp_operations
=
78 sb16_dsp_output_block
,
81 sb16_dsp_prepare_for_input
,
82 sb16_dsp_prepare_for_output
,
89 static int sb_dsp_command01 (unsigned char val
)
93 while(--i
& (!INB (DSP_STATUS
) & 0x80));
95 printk("SB16 sb_dsp_command01 Timeout\n");
96 return sb_dsp_command(val
);
99 static int wait_data_avail(int t
)
104 if(INB(DSP_DATA_AVAIL
) & 0x80)
106 } while(--loopc
&& GET_TIME()<t
);
107 printk("!data_avail l=%d\n",loopc
);
111 static int read_dsp(int t
)
113 if(!wait_data_avail(t
))
116 return INB(DSP_READ
);
119 static int dsp_ini2(void)
122 /* sb_setmixer(0x83, sb_getmixer(0x83) | 0x03); */
123 sb_dsp_command(0xe2);
124 sb_dsp_command(0x76); /* E0 ??? */
125 sb_dsp_command(0xe2);
126 sb_dsp_command(0x30); /* A0 ??? */
127 sb_dsp_command(0xe4);
128 sb_dsp_command(0xaa);
129 sb_dsp_command(0xe8);
130 if(read_dsp(100)!=0xaa)
131 printk("Error dsp_ini2\n");
136 static char *dsp_getmessage(unsigned char command,int maxn)
138 static char buff[100];
141 sb_dsp_command(command);
142 while(n<maxn && wait_data_avail(2)) {
143 buff[++n]=INB(DSP_READ);
151 static void dsp_showmessage(unsigned char command,int len)
155 c=dsp_getmessage(command,len);
156 printk("DSP C=%x l=%d,lr=%d b=",command,len,c[0]);
158 if(c[n]>=' ' & c[n]<='z')
165 static int dsp_set_speed(int mode
)
167 DEB(printk("dsp_set_speed(%d)\n",mode
));
170 if (mode
< 5000) mode
= 5000;
171 if (mode
> 44100) mode
= 44100;
172 dsp_current_speed
=mode
;
177 static int dsp_set_stereo(int mode
)
179 DEB(printk("dsp_set_stereo(%d)\n",mode
));
186 static int dsp_set_bits(int arg
) {
187 DEB(printk("dsp_set_bits(%d)\n",arg
));
196 return RET_ERROR(EINVAL
);
198 return dsp_16bit
? 16:8;
202 sb16_dsp_ioctl (int dev
, unsigned int cmd
, unsigned int arg
,int local
)
205 case SOUND_PCM_WRITE_RATE
:
207 return dsp_set_speed(arg
);
208 return IOCTL_OUT (arg
, dsp_set_speed (IOCTL_IN (arg
)));
210 case SOUND_PCM_READ_RATE
:
212 return dsp_current_speed
;
213 return IOCTL_OUT (arg
, dsp_current_speed
);
215 case SNDCTL_DSP_STEREO
:
217 return dsp_set_stereo(arg
);
218 return IOCTL_OUT (arg
, dsp_set_stereo(IOCTL_IN(arg
)));
220 case SOUND_PCM_WRITE_CHANNELS
:
222 return dsp_set_stereo(arg
-1)+1;
223 return IOCTL_OUT (arg
, dsp_set_stereo (IOCTL_IN (arg
) - 1) + 1);
225 case SOUND_PCM_READ_CHANNELS
:
228 return IOCTL_OUT (arg
, dsp_stereo
+1);
230 case SNDCTL_DSP_SAMPLESIZE
:
232 return dsp_set_bits (arg
);
233 return IOCTL_OUT (arg
, dsp_set_bits (IOCTL_IN (arg
)));
235 case SOUND_PCM_READ_BITS
:
237 return dsp_16bit
?16:8;
238 return IOCTL_OUT (arg
, dsp_16bit
?16:8);
240 case SOUND_PCM_WRITE_FILTER
: /* NOT YET IMPLEMENTED */
241 if (IOCTL_IN (arg
) > 1)
242 return IOCTL_OUT (arg
, RET_ERROR (EINVAL
));
244 return RET_ERROR (EINVAL
);
247 return RET_ERROR (EINVAL
);
251 sb16_dsp_open (int dev
, int mode
)
255 DEB(printk("sb16_dsp_open()\n"));
258 printk ("SB16 Error: SoundBlaster board not installed\n");
259 return RET_ERROR(ENXIO
);
263 return RET_ERROR(EBUSY
);
265 retval
= sb_get_irq ();
269 if (ALLOC_DMA_CHN (dma8
))
271 printk ("SB16: Unable to grab DMA%d\n", dma8
);
273 return RET_ERROR(EBUSY
);
277 if (ALLOC_DMA_CHN (dma16
))
279 printk ("SB16: Unable to grab DMA%d\n", dma16
);
281 RELEASE_DMA_CHN (dma8
);
282 return RET_ERROR(EBUSY
);
287 irq_mode
= IMODE_NONE
;
294 sb16_dsp_close (int dev
)
297 DEB(printk("sb16_dsp_close()\n"));
298 sb_dsp_command01(0xd9);
299 sb_dsp_command01(0xd5);
301 DISABLE_INTR (flags
);
302 RELEASE_DMA_CHN (dma8
);
305 RELEASE_DMA_CHN (dma16
);
309 RESTORE_INTR (flags
);
313 sb16_dsp_output_block (int dev
, unsigned long buf
, int count
,int intrflag
, int dma_restart
)
315 unsigned long flags
, cnt
;
323 printk("output_block: %x %d %d\n",buf
,count
,intrflag
);
325 int pos
,chan
=sound_dsp_dmachan
[dev
];
326 DISABLE_INTR (flags
);
329 pos
=get_dma_residue(chan
);
331 RESTORE_INTR (flags
);
332 printk("dmapos=%d %x\n",pos
,pos
);
335 if (sound_dma_automode
[dev
] &&
338 irq_mode
= IMODE_OUTPUT
;
340 return; /* Auto mode on. No need to react */
342 DISABLE_INTR (flags
);
347 DMAbuf_start_dma (dev
, buf
, count
, DMA_MODE_WRITE
);
349 sb_dsp_command (0x41);
350 sb_dsp_command ((unsigned char)((dsp_current_speed
>> 8) & 0xff));
351 sb_dsp_command ((unsigned char)(dsp_current_speed
& 0xff));
352 sb_dsp_command ((unsigned char)(dsp_16bit
? 0xb6 : 0xc6));
353 sb_dsp_command ((unsigned char)((dsp_stereo
? 0x20 : 0) +
354 (dsp_16bit
? 0x10:0)));
355 sb_dsp_command01 ((unsigned char)(cnt
&0xff));
356 sb_dsp_command ((unsigned char)(cnt
>>8));
357 /* sb_dsp_command (0);
358 sb_dsp_command (0); */
360 RESTORE_INTR (flags
);
362 irq_mode
= IMODE_OUTPUT
;
367 sb16_dsp_start_input (int dev
, unsigned long buf
, int count
,int intrflag
, int dma_restart
)
369 unsigned long flags
, cnt
;
377 printk("start_input: %x %d %d\n",buf
,count
,intrflag
);
379 int pos
,chan
=sound_dsp_dmachan
[dev
];
380 DISABLE_INTR (flags
);
383 pos
=get_dma_residue(chan
);
385 RESTORE_INTR (flags
);
386 printk("dmapos=%d %x\n",pos
,pos
);
389 if (sound_dma_automode
[dev
] &&
392 irq_mode
= IMODE_INPUT
;
394 return; /* Auto mode on. No need to react */
396 DISABLE_INTR (flags
);
401 DMAbuf_start_dma (dev
, buf
, count
, DMA_MODE_READ
);
404 sb_dsp_command (0x42);
405 sb_dsp_command ((unsigned char)((dsp_current_speed
>> 8) & 0xff));
406 sb_dsp_command ((unsigned char)(dsp_current_speed
& 0xff));
407 sb_dsp_command ((unsigned char)(dsp_16bit
? 0xbe : 0xce));
408 sb_dsp_command ((unsigned char)((dsp_stereo
? 0x20 : 0) +
409 (dsp_16bit
? 0x10:0)));
410 sb_dsp_command01 ((unsigned char)(cnt
&0xff));
411 sb_dsp_command ((unsigned char)(cnt
>>8));
413 /* sb_dsp_command (0);
414 sb_dsp_command (0); */
415 RESTORE_INTR (flags
);
417 irq_mode
= IMODE_INPUT
;
422 sb16_dsp_prepare_for_input (int dev
, int bsize
, int bcount
)
424 sound_dsp_dmachan
[my_dev
] = dsp_16bit
? dma16
:dma8
;
431 sb16_dsp_prepare_for_output (int dev
, int bsize
, int bcount
)
433 sound_dsp_dmachan
[my_dev
] = dsp_16bit
? dma16
:dma8
;
442 irq_mode
= IMODE_NONE
;
447 sb16_dsp_reset (int dev
)
451 DISABLE_INTR (flags
);
456 RESTORE_INTR (flags
);
460 sb16_dsp_halt (int dev
)
464 sb_dsp_command01(0xd9);
465 sb_dsp_command01(0xd5);
469 sb_dsp_command01(0xda);
470 sb_dsp_command01(0xd0);
475 set_irq_hw(int level
) {
485 printk("SB16_IRQ_LEVEL %d does not exist\n",level
);
488 sb_setmixer(IRQ_NR
,ival
);
492 sb16_dsp_init (long mem_start
, struct address_info
*hw_config
)
497 sb_dsp_command (0xe1); /* Get version */
499 for (i
= 1000; i
; i
--) {
500 if (INB (DSP_DATA_AVAIL
) & 0x80)
501 { /* wait for Data Ready */
503 major
= INB (DSP_READ
);
506 minor
= INB (DSP_READ
);
513 sprintf (sb16_dsp_operations
.name
, "SoundBlaster 16 %d.%d", major
, minor
);
516 printk (" <%s>", sb16_dsp_operations
.name
);
518 if (num_dspdevs
< MAX_DSP_DEV
)
520 dsp_devs
[my_dev
= num_dspdevs
++] = &sb16_dsp_operations
;
521 sound_dsp_dmachan
[my_dev
] = hw_config
->dma
;
522 sound_buffcounts
[my_dev
] = 1;
523 sound_buffsizes
[my_dev
] = DSP_BUFFSIZE
;
524 sound_dma_automode
[my_dev
] = 1;
527 printk ("SB: Too many DSP devices available\n");
533 sb16_dsp_detect (struct address_info
*hw_config
)
535 struct address_info
*sb_config
;
538 return 1; /* Already initialized */
540 if (!(sb_config
=sound_getconf(SNDCARD_SB
)))
542 printk("SB16 Error: Plain SB not configured\n");
546 if (sbc_base
!= hw_config
->io_base
)
547 printk("Warning! SB16 I/O != SB I/O\n");
549 /* sb_setmixer(OPSW,0xf);
550 if(sb_getmixer(OPSW)!=0xf)
553 if (!sb_reset_dsp ())
556 if (hw_config
->irq
!= sb_config
->irq
)
558 printk("SB16 Error: Invalid IRQ number %d/%d\n",
559 sb_config
->irq
, hw_config
->irq
);
563 if (hw_config
->dma
< 4)
564 if (hw_config
->dma
!= sb_config
->dma
)
566 printk("SB16 Error: Invalid DMA channel %d/%d\n",
567 sb_config
->dma
, hw_config
->dma
);
571 dma16
= hw_config
->dma
;
572 dma8
= sb_config
->dma
;
573 set_irq_hw(hw_config
->irq
);
574 sb_setmixer(DMA_NR
, (1<<hw_config
->dma
) | (1<<sb_config
->dma
));
576 DEB(printk ("SoundBlaster 16: IRQ %d DMA %d OK\n",hw_config
->irq
,hw_config
->dma
));
579 dsp_showmessage(0xe3,99);
586 sb16_dsp_interrupt (int unused
)
589 data
= INB (DSP_DATA_AVL16
); /* Interrupt acknowledge */
596 DMAbuf_outputintr (my_dev
, 1);
601 DMAbuf_inputintr (my_dev
);
605 printk ("SoundBlaster: Unexpected interrupt\n");