Wed Oct 14 20:54:17 MEST 1998 Made a new patch, this time for linux-2.0.35 Happy patching, Rene Wed Mar 4 20:25:49 MET 1998 This is a patch for the Audio Excel DSP cards, and similar (Gallant) sound cards. I used the AudioExcelDSP16-2.0.21.diff patch as a basis for this. It turned out that after applying the AudioExcelDSP16-2.0.21.diff patch, with some help, things did not work smoothly. I modified the Config.in to get the Audio Excel configuration implemented and learned something about the capabilities of the tkparse.c program. I kept the lowlevel.c in the drivers/sound directory (as in the .21 patch) and the new aedsp16.c in the drivers/sound/lowlevel directory. I figured out how to add the stuff from the lowlevel to the sound.a library, and edited the Makefiles. Things compiled, and the new kernel did start up the Audio Excel card, but failed to initialise the MSS driver (note that you get 16 bit sound if you use the MSS mode, and only 8 bit sound in the Sondblaster compatibility mode. Under Linux your choice should be easy). The answer to the solution was found in local.h.master file. Someone had left the DESKPROXL defined, might bother more people with an MSS (compatible) card. After the patch is applied you can use the normal config programs (make menuconfig or make xconfig) to configure the card. Configure a normal SB or MSS card, and enter the same configuration for the low level AEDSP driver. Good luck, Rene van Paassen diff -N -r -C3 linux-2.0.35.orig/drivers/sound/.object_files linux-2.0.35/drivers/sound/.object_files *** linux-2.0.35.orig/drivers/sound/.object_files Sun Jun 30 10:50:18 1996 --- linux-2.0.35/drivers/sound/.object_files Wed Sep 2 22:35:22 1998 *************** *** 29,35 **** pss.o sscape.o trix.o - aedsp16.o mad16.o cs4232.o maui.o --- 29,34 ---- diff -N -r -C3 linux-2.0.35.orig/drivers/sound/.objects linux-2.0.35/drivers/sound/.objects *** linux-2.0.35.orig/drivers/sound/.objects Mon Aug 5 09:13:53 1996 --- linux-2.0.35/drivers/sound/.objects Wed Sep 2 22:35:22 1998 *************** *** 8,17 **** OBJS := $(OBJS) adlib_card.o endif - ifdef CONFIG_AEDSP16 - OBJS := $(OBJS) aedsp16.o - endif - ifdef CONFIG_AUDIO OBJS := $(OBJS) audio.o endif --- 8,13 ---- diff -N -r -C3 linux-2.0.35.orig/drivers/sound/Config.in linux-2.0.35/drivers/sound/Config.in *** linux-2.0.35.orig/drivers/sound/Config.in Sat Sep 6 05:43:58 1997 --- linux-2.0.35/drivers/sound/Config.in Sat Sep 5 22:03:36 1998 *************** *** 1,17 **** ! # ! # Sound driver configuration ! # ! #-------- ! # There is another config script which is compatible with rest of ! # the kernel. It can be activated by running 'make mkscript' in this ! # directory. Please note that this is an _experimental_ feature which ! # doesn't work with all cards (PSS, SM Wave, AudioTrix Pro, Maui). ! #-------- ! # ! $MAKE -C drivers/sound config || exit 1 bool 'Additional low level drivers' CONFIG_LOWLEVEL_SOUND if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then bool 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER fi --- 1,323 ---- ! bool 'ProAudioSpectrum 16 support' CONFIG_PAS ! bool 'Sound Blaster (SB, SBPro, SB16, clones) support' CONFIG_SB ! bool 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_ADLIB ! bool 'Gravis Ultrasound support' CONFIG_GUS ! bool 'MPU-401 support (NOT for SB16)' CONFIG_MPU401 ! bool '6850 UART Midi support' CONFIG_UART6850 ! bool 'PSS (ECHO-ADI2111) support' CONFIG_PSS ! bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16 ! bool 'GUS MAX support' CONFIG_GUSMAX ! bool 'Microsoft Sound System support' CONFIG_MSS ! bool 'Ensoniq SoundScape support' CONFIG_SSCAPE ! bool 'MediaTrix AudioTrix Pro support' CONFIG_TRIX ! bool 'Support for MAD16 and/or Mozart based cards' CONFIG_MAD16 ! bool 'Support for Crystal CS4232 based (PnP) cards' CONFIG_CS4232 ! bool 'Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_MAUI ! bool '/dev/dsp and /dev/audio support' CONFIG_AUDIO ! bool 'MIDI interface support' CONFIG_MIDI ! bool 'FM synthesizer (YM3812/OPL-3) support' CONFIG_YM3812 ! ! if [ "$CONFIG_SB" = "y" ]; then ! hex 'I/O base for SB Check from manual of the card' SBC_BASE 220 ! fi ! ! if [ "$CONFIG_SB" = "y" ]; then ! int 'Sound Blaster IRQ Check from manual of the card' SBC_IRQ 7 ! fi ! ! if [ "$CONFIG_SB" = "y" ]; then ! int 'Sound Blaster DMA 0, 1 or 3' SBC_DMA 1 ! fi ! ! if [ "$CONFIG_SB" = "y" ]; then ! int 'Sound Blaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' SB_DMA2 5 ! fi ! ! if [ "$CONFIG_SB" = "y" ]; then ! hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' SB_MPU_BASE 0 ! fi ! ! if [ "$CONFIG_SB" = "y" ]; then ! int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Use -1 with SB16' SB_MPU_IRQ -1 ! fi ! ! if [ "$CONFIG_PAS" = "y" ]; then ! int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' PAS_IRQ 10 ! fi ! ! if [ "$CONFIG_PAS" = "y" ]; then ! int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' PAS_DMA 3 ! fi ! ! if [ "$CONFIG_GUS" = "y" ]; then ! hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' GUS_BASE 220 ! fi ! ! if [ "$CONFIG_GUS" = "y" ]; then ! int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' GUS_IRQ 15 ! fi ! ! if [ "$CONFIG_GUS" = "y" ]; then ! int 'GUS DMA 1, 3, 5, 6 or 7' GUS_DMA 6 ! fi ! ! if [ "$CONFIG_GUS" = "y" ]; then ! int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' GUS_DMA2 -1 ! fi ! ! if [ "$CONFIG_GUS16" = "y" ]; then ! hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' GUS16_BASE 530 ! fi ! ! if [ "$CONFIG_GUS16" = "y" ]; then ! int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' GUS16_IRQ 7 ! fi ! ! if [ "$CONFIG_GUS16" = "y" ]; then ! int 'GUS DMA 0, 1 or 3' GUS16_DMA 3 ! fi ! ! if [ "$CONFIG_MPU401" = "y" ]; then ! hex 'I/O base for MPU401 Check from manual of the card' MPU_BASE 330 ! fi ! ! if [ "$CONFIG_MPU401" = "y" ]; then ! int 'MPU401 IRQ Check from manual of the card' MPU_IRQ 9 ! fi ! ! if [ "$CONFIG_MAUI" = "y" ]; then ! hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' MAUI_BASE 330 ! fi ! ! if [ "$CONFIG_MAUI" = "y" ]; then ! int 'Maui IRQ 5, 9, 12 or 15' MAUI_IRQ 9 ! fi ! ! if [ "$CONFIG_UART6850" = "y" ]; then ! hex 'I/O base for UART 6850 MIDI port (Unknown)' U6850_BASE 0 ! fi ! ! if [ "$CONFIG_UART6850" = "y" ]; then ! int 'UART6850 IRQ (Unknown)' U6850_IRQ -1 ! fi ! ! if [ "$CONFIG_PSS" = "y" ]; then ! hex 'PSS I/O base 220 or 240' PSS_BASE 220 ! fi ! ! if [ "$CONFIG_PSS" = "y" ]; then ! hex 'PSS audio I/O base 530, 604, E80 or F40' PSS_MSS_BASE 530 ! fi ! ! if [ "$CONFIG_PSS" = "y" ]; then ! int 'PSS audio IRQ 7, 9, 10 or 11' PSS_MSS_IRQ 11 ! fi ! ! if [ "$CONFIG_PSS" = "y" ]; then ! int 'PSS audio DMA 0, 1 or 3' PSS_MSS_DMA 3 ! fi ! ! if [ "$CONFIG_PSS" = "y" ]; then ! hex 'PSS MIDI I/O base ' PSS_MPU_BASE 330 ! fi ! ! if [ "$CONFIG_PSS" = "y" ]; then ! int 'PSS MIDI IRQ 3, 4, 5, 7 or 9' PSS_MPU_IRQ 9 ! fi ! ! if [ "$CONFIG_MSS" = "y" ]; then ! hex 'MSS/WSS I/O base 530, 604, E80 or F40' MSS_BASE 530 ! fi ! ! if [ "$CONFIG_MSS" = "y" ]; then ! int 'MSS/WSS IRQ 7, 9, 10 or 11' MSS_IRQ 11 ! fi ! ! if [ "$CONFIG_MSS" = "y" ]; then ! int 'MSS/WSS DMA 0, 1 or 3' MSS_DMA 3 ! fi ! ! if [ "$CONFIG_SSCAPE" = "y" ]; then ! hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' SSCAPE_BASE 330 ! fi ! ! if [ "$CONFIG_SSCAPE" = "y" ]; then ! int 'SoundScape MIDI IRQ ' SSCAPE_IRQ 9 ! fi ! ! if [ "$CONFIG_SSCAPE" = "y" ]; then ! int 'SoundScape initialization DMA 0, 1 or 3' SSCAPE_DMA 3 ! fi + if [ "$CONFIG_SSCAPE" = "y" ]; then + hex 'SoundScape audio I/O base 534, 608, E84 or F44' SSCAPE_MSS_BASE 534 + fi + + if [ "$CONFIG_SSCAPE" = "y" ]; then + int 'SoundScape audio IRQ 7, 9, 10 or 11' SSCAPE_MSS_IRQ 11 + fi + + if [ "$CONFIG_TRIX" = "y" ]; then + hex 'AudioTrix audio I/O base 530, 604, E80 or F40' TRIX_BASE 530 + fi + + if [ "$CONFIG_TRIX" = "y" ]; then + int 'AudioTrix audio IRQ 7, 9, 10 or 11' TRIX_IRQ 11 + fi + + if [ "$CONFIG_TRIX" = "y" ]; then + int 'AudioTrix audio DMA 0, 1 or 3' TRIX_DMA 0 + fi + + if [ "$CONFIG_TRIX" = "y" ]; then + int 'AudioTrix second (duplex) DMA 0, 1 or 3' TRIX_DMA2 3 + fi + + if [ "$CONFIG_TRIX" = "y" ]; then + hex 'AudioTrix MIDI I/O base 330, 370, 3B0 or 3F0' TRIX_MPU_BASE 330 + fi + + if [ "$CONFIG_TRIX" = "y" ]; then + int 'AudioTrix MIDI IRQ 3, 4, 5, 7 or 9' TRIX_MPU_IRQ 9 + fi + + if [ "$CONFIG_TRIX" = "y" ]; then + hex 'AudioTrix SB I/O base 220, 210, 230, 240, 250, 260 or 270' TRIX_SB_BASE 220 + fi + + if [ "$CONFIG_TRIX" = "y" ]; then + int 'AudioTrix SB IRQ 3, 4, 5 or 7' TRIX_SB_IRQ 7 + fi + + if [ "$CONFIG_TRIX" = "y" ]; then + int 'AudioTrix SB DMA 1 or 3' TRIX_SB_DMA 1 + fi + + if [ "$CONFIG_CS4232" = "y" ]; then + hex 'CS4232 audio I/O base 530, 604, E80 or F40' CS4232_BASE 530 + fi + + if [ "$CONFIG_CS4232" = "y" ]; then + int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CS4232_IRQ 11 + fi + + if [ "$CONFIG_CS4232" = "y" ]; then + int 'CS4232 audio DMA 0, 1 or 3' CS4232_DMA 0 + fi + + if [ "$CONFIG_CS4232" = "y" ]; then + int 'CS4232 second (duplex) DMA 0, 1 or 3' CS4232_DMA2 3 + fi + + if [ "$CONFIG_CS4232" = "y" ]; then + hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CS4232_MPU_BASE 330 + fi + + if [ "$CONFIG_CS4232" = "y" ]; then + int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CS4232_MPU_IRQ 9 + fi + + if [ "$CONFIG_MAD16" = "y" ]; then + hex 'MAD16 audio I/O base 530, 604, E80 or F40' MAD16_BASE 530 + fi + + if [ "$CONFIG_MAD16" = "y" ]; then + int 'MAD16 audio IRQ 7, 9, 10 or 11' MAD16_IRQ 11 + fi + + if [ "$CONFIG_MAD16" = "y" ]; then + int 'MAD16 audio DMA 0, 1 or 3' MAD16_DMA 3 + fi + + if [ "$CONFIG_MAD16" = "y" ]; then + int 'MAD16 second (duplex) DMA 0, 1 or 3' MAD16_DMA2 0 + fi + + if [ "$CONFIG_MAD16" = "y" ]; then + hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' MAD16_MPU_BASE 330 + fi + + if [ "$CONFIG_MAD16" = "y" ]; then + int 'MAD16 MIDI IRQ 5, 7, 9 or 10' MAD16_MPU_IRQ 9 + fi + + if [ "$CONFIG_AUDIO" = "y" ]; then + int 'Audio DMA buffer size 4096, 16384, 32768 or 65536' DSP_BUFFSIZE 65536 + fi + # + $MAKE -C drivers/sound kernelconfig || exit 1 bool 'Additional low level drivers' CONFIG_LOWLEVEL_SOUND if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then bool 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER + fi + + if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then + bool 'Gallant Audio Cards (e.g. AEDSP 16, SC-6000 and SC-6600AEDSP)' CONFIG_AEDSP16 + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + bool 'SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600 + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_SB" = "n" ]; then + bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_SB" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_SBPRO" = "n" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE $SBC_BASE + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' AEDSP16_SBC_IRQ $SBC_IRQ + int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_SBC_DMA $SBC_DMA + fi + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_MSS" = "n" ]; then + bool 'Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_MSS" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_MSS" = "n" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' AEDSP16_MSS_IRQ $MSS_IRQ + int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_MSS_DMA $MSS_DMA + fi + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_MIDI" = "n" ]; then + bool 'Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401 + fi + fi + + if [ ! "$CONFIG_AEDSP16" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_MPU401" = "n" ]; then + if [ "$CONFIG_AEDSP16_SBPRO" = "n" ]; then + if [ "$CONFIG_AEDSP16_MSS" = "n" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 + fi + fi + fi + fi + + if [ ! "$CONFIG_AEDSP16" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_MPU401" = "n" ]; then + int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' AEDSP16_MPU_IRQ $MPU_IRQ + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ "$CONFIG_SC6600" = "y" ]; then + bool 'Activate SC-6600 Joystick Interface' CONFIG_SC6600_JOY + int 'SC-6600 CDROM Interface (4==None, 3==IDE, 1==Panasonic, 0==?Sony?)' CONFIG_SC6600_CDROM 4 + hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0 + fi fi diff -N -r -C3 linux-2.0.35.orig/drivers/sound/Config.std linux-2.0.35/drivers/sound/Config.std *** linux-2.0.35.orig/drivers/sound/Config.std Sat Jul 6 10:31:43 1996 --- linux-2.0.35/drivers/sound/Config.std Thu Sep 3 00:20:44 1998 *************** *** 15,17 **** --- 15,87 ---- if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then bool 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER fi + + if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then + bool 'Gallant Audio Cards (e.g. AEDSP 16, SC-6000 and SC-6600AEDSP)' CONFIG_AEDSP16 + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + bool 'SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600 + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_SB" = "n" ]; then + bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_SB" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_SBPRO" = "n" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE $SBC_BASE + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' AEDSP16_SBC_IRQ $SBC_IRQ + int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_SBC_DMA $SBC_DMA + fi + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_MSS" = "n" ]; then + bool 'Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_MSS" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_MSS" = "n" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' AEDSP16_MSS_IRQ $MSS_IRQ + int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_MSS_DMA $MSS_DMA + fi + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_MIDI" = "n" ]; then + bool 'Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401 + fi + fi + + if [ ! "$CONFIG_AEDSP16" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_MPU401" = "n" ]; then + if [ "$CONFIG_AEDSP16_SBPRO" = "n" ]; then + if [ "$CONFIG_AEDSP16_MSS" = "n" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 + fi + fi + fi + fi + + if [ ! "$CONFIG_AEDSP16" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_MPU401" = "n" ]; then + int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' AEDSP16_MPU_IRQ $MPU_IRQ + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ "$CONFIG_SC6600" = "y" ]; then + bool 'Activate SC-6600 Joystick Interface' CONFIG_SC6600_JOY + int 'SC-6600 CDROM Interface (4==None, 3==IDE, 1==Panasonic, 0==?Sony?) CONFIG_SC6600_CDROM 4 + hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0 + fi + fi diff -N -r -C3 linux-2.0.35.orig/drivers/sound/aedsp16.c linux-2.0.35/drivers/sound/aedsp16.c *** linux-2.0.35.orig/drivers/sound/aedsp16.c Mon Jul 15 08:55:11 1996 --- linux-2.0.35/drivers/sound/aedsp16.c Thu Jan 1 01:00:00 1970 *************** *** 1,869 **** - /* - sound/aedsp16.c - - Audio Excel DSP 16 software configuration routines - - Copyright (C) 1995 Riccardo Facchetti (riccardo@cdc8g5.cdc.polimi.it) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. 2. - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - */ - /* - * Include the main voxware header file. It include all the os/voxware/etc - * headers needed by this source. - */ - #include - #include "sound_config.h" - - #ifndef AEDSP16_BASE - #undef CONFIG_AEDSP16 - #endif - - #if defined(CONFIG_AEDSP16) - /* - - READ THIS - - This module is intended for Audio Excel DSP 16 Sound Card. - - Audio Excel DSP 16 is an SB pro II, Microsoft Sound System - and MPU-401 compatible card. - It is software-only configurable (no jumpers to hard-set irq/dma/mpu-irq), - so before this module, the only way to configure the DSP under linux was - boot the MS-BAU loading the sound.sys device driver (this driver soft- - configure the sound board hardware by massaging someone of its registers), - and then ctrl-alt-del to boot linux with the DSP configured by the DOG - driver. - - This module works configuring your Audio Excel DSP 16's - irq, dma and mpu-401-irq. The voxware probe routines rely on the - fact that if the hardware is there, they can detect it. The problem - with AEDSP16 is that no hardware can be found by the probe routines - if the sound card is not well configured. Sometimes the kernel probe - routines can find an SBPRO even when the card is not configured (this - is the standard setup of the card), but the SBPRO emulation don't work - well if the card is not properly initialized. For this reason - - InitAEDSP16_...() - - routines are called before the voxware probe routines try to detect the - hardware. - - NOTE (READ THE NOTE TOO, IT CONTAIN USEFUL INFORMATIONS) - - The Audio Excel DSP 16 Sound Card emulates both SBPRO and MSS; - the voxware sound driver can be configured for SBPRO and MSS cards - at the same time, but the AEDSP16 can't be two cards!! - When we configure it, we have to choose the SBPRO or the MSS emulation - for AEDSP16. We also can install a *REAL* card of the other type - (see [1], not tested but I can't see any reason for it to fail). - - NOTE: If someone can test the combination AEDSP16+MSS or AEDSP16+SBPRO - please let me know if it works. - - The MPU-401 support can be compiled in together with one of the other - two operating modes. - - The board configuration calls, are in the probe_...() routines because - we have to configure the board before probing it for a particular - hardware. After card configuration, we can probe the hardware. - - NOTE: This is something like plug-and-play: we have only to plug - the AEDSP16 board in the socket, and then configure and compile - a kernel that uses the AEDSP16 software configuration capability. - No jumper setting is needed! - - For example, if you want AEDSP16 to be an SBPro, on irq 10, dma 3 - you have just to make config the voxware package, configuring - the SBPro sound card with that parameters, then when configure - asks if you have an AEDSP16, answer yes. That's it. - Compile the kernel and run it. - - NOTE: This means that you can choose irq and dma, but not the - I/O addresses. To change I/O addresses you have to set them - with jumpers. - - NOTE: InitAEDSP16_...() routines get as parameter the hw_config, - the hardware configuration of the - to be configured - board. - The InitAEDSP16() routine, configure the board following our - wishes, that are in the hw_config structure. - - You can change the irq/dma/mirq settings WITHOUT THE NEED to open - your computer and massage the jumpers (there are no irq/dma/mirq - jumpers to be configured anyway, only I/O port ones have to be - configured with jumpers) - - For some ununderstandable reason, the card default of irq 7, dma 1, - don't work for me. Seems to be an IRQ or DMA conflict. Under heavy - HDD work, the kernel start to erupt out a lot of messages like: - - 'Sound: DMA timed out - IRQ/DRQ config error?' - - For what I can say, I have NOT any conflict at irq 7 (under linux I'm - using the lp polling driver), and dma line 1 is unused as stated by - /proc/dma. I can suppose this is a bug of AEDSP16. I know my hardware so - I'm pretty sure I have not any conflict, but may be I'm wrong. Who knows! - Anyway a setting of irq 10, dma 3 works really fine. - - NOTE: if someone can use AEDSP16 with irq 7, dma 1, please let me know - the emulation mode, all the installed hardware and the hardware - configuration (irq and dma settings of all the hardware). - - This init module should work with SBPRO+MSS, when one of the two is - the AEDSP16 emulation and the other the real card. (see [1]) - For example: - - AEDSP16 (0x220) in SBPRO emu (0x220) + real MSS + other - AEDSP16 (0x220) in MSS emu + real SBPRO (0x240) + other - - MPU401 should work. (see [1]) - - [1] Not tested by me for lack of hardware. - - TODO, WISHES AND TECH - - May be there's lot of redundant delays, but for now I want to leave it - this way. - - Should be interesting eventually write down a new ioctl for the - AEDSP16, to let the suser() change the irq/dma/mirq on the fly. - The thing is not trivial. - In the real world, there's no need to have such an ioctl because - when we configure the kernel for compile, we can choose the config - parameters. If we change our mind, we can easily re-config the kernel - and re-compile. - Why let the suser() change the config parameters on the fly ? - If anyone have a reasonable answer to this question, I will write down - the code to do it. - - More integration with voxware, using voxware low level routines to - read-write DSP is not possible because you may want to have MSS - support and in that case we can not rely on the functions included - in sb_dsp.c to control 0x2yy I/O ports. I will continue to use my - own I/O functions. - - - About I/O ports allocation - - - The request_region should be done at device probe in every sound card - module. This module is not the best site for requesting regions. - When the request_region code will be added to the main modules such as - sb, adlib, gus, ad1848, etc, the requesting code in this module should - go away. - - I think the request regions should be done this way: - - if (check_region(...)) - return ERR; // I/O region already reserved - device_probe(...); - device_attach(...); - request_region(...); // reserve only when we are sure all is okay - - Request the 2x0h region in any case if we are using this card. - - NOTE: the "(SBPro)" string with which we are requesting the AEDSP16 region - (see code) does not mean necessarily that we are emulating SBPro. - It mean that the region is the SBPro I/O ports region. We use this - region to access the control registers of the card, and if emulating - SBPro, I/O SBPro registers too. If we are emulating MSS, the SBPro - registers are not used, in no way, to emulate an SBPro: they are - used only for configuration purposes. - - Someone pointed out that should be possible use both the SBPRO and MSS - modes because the sound card have all the two chipsets, supposing that - the card is really two cards. I have tried something to have the two - modes work together, but, for some reason unknown to me, without success. - - I think all the soft-config only cards have an init sequence similar to - this. If you have a card that is not an AEDSP16, you can try to start - with this module changing it (mainly in the CMD? I think) to fit your - needs. - - Started Fri Mar 17 16:13:18 MET 1995 - - v0.1 (ALPHA, was an user-level program called AudioExcelDSP16.c) - - Initial code. - v0.2 (ALPHA) - - Cleanups. - - Integrated with Linux voxware v 2.90-2 kernel sound driver. - - Sound Blaster Pro mode configuration. - - Microsoft Sound System mode configuration. - - MPU-401 mode configuration. - v0.3 (ALPHA) - - Cleanups. - - Rearranged the code to let InitAEDSP16 be more general. - - Erased the REALLY_SLOW_IO. We don't need it. Erased the linux/io.h - inclusion too. We rely on os.h - - Used the to get a variable - len string (we are not sure about the len of Copyright string). - This works with any SB and compatible. - - Added the code to request_region at device init (should go in - the main body of voxware). - v0.4 (BETA) - - Better configure.c patch for AEDSP16 configuration (better - logic of inclusion of AEDSP16 support) - - Modified the conditional compilation to better support more than - one sound card of the emulated type (read the NOTES above) - - Moved the sb init routine from the attach to the very first - probe in sb_card.c - - Rearrangements and cleanups - - Wiped out some unnecessary code and variables: this is kernel - code so it is better save some TEXT and DATA - - Fixed the request_region code. We must allocate the AEDSP16 (SBPro) - I/O ports in any case because they are used to access the DSP - configuration registers and we can not allow anyone to get them. - v0.5 - - cleanups on comments - - prep for diffs against v3.0-proto-950402 - v0.6 - - removed the request_region()s when compiling the MODULE sound.o - because we are not allowed (by the actual voxware structure) to - release_region() - - */ - - - #define VERSION "0.6" /* Version of Audio Excel DSP 16 driver */ - - #undef AEDSP16_DEBUG /* Define this to enable debug code */ - /* Actually no debug code is activated */ - - /* - * Hardware related defaults - */ - #define IRQ 7 /* 5 7(default) 9 10 11 */ - #define MIRQ 0 /* 5 7 9 10 0(default), 0 means disable */ - #define DMA 1 /* 0 1(default) 3 */ - - /* - * Commands of AEDSP16's DSP (SBPRO+special). - * For now they are CMDn, in the future they may change. - */ - #define CMD1 0xe3 /* Get DSP Copyright */ - #define CMD2 0xe1 /* Get DSP Version */ - #define CMD3 0x88 /* */ - #define CMD4 0x5c /* */ - #define CMD5 0x50 /* Set M&I&DRQ mask (the real config) */ - #define CMD6 0x8c /* Enable Microsoft Sound System mode */ - - /* - * Offsets of AEDSP16 DSP I/O ports. The offset is added to portbase - * to have the actual I/O port. - * Register permissions are: - * (wo) == Write Only - * (ro) == Read Only - * (w-) == Write - * (r-) == Read - */ - #define DSP_RESET 0x06 /* offset of DSP RESET (wo) */ - #define DSP_READ 0x0a /* offset of DSP READ (ro) */ - #define DSP_WRITE 0x0c /* offset of DSP WRITE (w-) */ - #define DSP_COMMAND 0x0c /* offset of DSP COMMAND (w-) */ - #define DSP_STATUS 0x0c /* offset of DSP STATUS (r-) */ - #define DSP_DATAVAIL 0x0e /* offset of DSP DATA AVAILABLE (ro) */ - - - #define RETRY 10 /* Various retry values on I/O opera- */ - #define STATUSRETRY 1000 /* tions. Sometimes we have to */ - #define HARDRETRY 500000 /* wait for previous cmd to complete */ - - /* - * Size of character arrays that store name and version of sound card - */ - #define CARDNAMELEN 15 /* Size of the card's name in chars */ - #define CARDVERLEN 2 /* Size of the card's version in chars */ - - /* - * Bit mapped flags for calling InitAEDSP16(), and saving the current - * emulation mode. - */ - #define INIT_NONE (0 ) - #define INIT_SBPRO (1<<0) - #define INIT_MSS (1<<1) - #define INIT_MPU401 (1<<2) - #define RESET_DSP16 (1<<3) - - /* Base HW Port for Audio Card */ - static int portbase = AEDSP16_BASE; - static int irq = IRQ; /* irq for DSP I/O */ - static int mirq = MIRQ; /* irq for MPU-401 I/O */ - static int dma = DMA; /* dma for DSP I/O */ - - /* Init status of the card */ - static int ae_init = INIT_NONE; /* (bitmapped variable) */ - static int oredparams = 0; /* Will contain or'ed values of params */ - static int gc = 0; /* generic counter (utility counter) */ - struct orVals - { /* Contain the values to be or'ed */ - int val; /* irq|mirq|dma */ - int or; /* oredparams |= TheStruct.or */ - }; - - /* - * Magic values that the DSP will eat when configuring irq/mirq/dma - */ - /* DSP IRQ conversion array */ - static struct orVals orIRQ[] = - { - {0x05, 0x28}, - {0x07, 0x08}, - {0x09, 0x10}, - {0x0a, 0x18}, - {0x0b, 0x20}, - {0x00, 0x00} - }; - - /* MPU-401 IRQ conversion array */ - static struct orVals orMIRQ[] = - { - {0x05, 0x04}, - {0x07, 0x44}, - {0x09, 0x84}, - {0x0a, 0xc4}, - {0x00, 0x00} - }; - - /* DMA Channels conversion array */ - static struct orVals orDMA[] = - { - {0x00, 0x01}, - {0x01, 0x02}, - {0x03, 0x03}, - {0x00, 0x00} - }; - - /* - * Buffers to store audio card information - */ - static char AudioExcelName[CARDNAMELEN + 1]; - static char AudioExcelVersion[CARDVERLEN + 1]; - - static void - tenmillisec (void) - { - - for (gc = 0; gc < 1000; gc++) - tenmicrosec (); - } - - static int - WaitForDataAvail (int port) - { - int loop = STATUSRETRY; - unsigned char ret = 0; - - do - { - ret = inb (port + DSP_DATAVAIL); - /* - * Wait for data available (bit 7 of ret == 1) - */ - } - while (!(ret & 0x80) && loop--); - - if (ret & 0x80) - return 0; - - return -1; - } - - static int - ReadData (int port) - { - if (WaitForDataAvail (port)) - return -1; - return inb (port + DSP_READ); - } - - static int - CheckDSPOkay (int port) - { - return ((ReadData (port) == 0xaa) ? 0 : -1); - } - - static int - ResetBoard (int port) - { - /* - * Reset DSP - */ - outb (1, (port + DSP_RESET)); - tenmicrosec (); - outb (0, (port + DSP_RESET)); - tenmicrosec (); - tenmicrosec (); - return CheckDSPOkay (port); - } - - static int - WriteDSPCommand (int port, int cmd) - { - unsigned char ret; - int loop = HARDRETRY; - - do - { - ret = inb (port + DSP_STATUS); - /* - * DSP ready to receive data if bit 7 of ret == 0 - */ - if (!(ret & 0x80)) - { - outb (cmd, port + DSP_COMMAND); - return 0; - } - } - while (loop--); - - printk ("[AEDSP16] DSP Command (0x%x) timeout.\n", cmd); - return -1; - } - - int - InitMSS (int port) - { - - tenmillisec (); - - if (WriteDSPCommand (port, CMD6)) - { - printk ("[AEDSP16] CMD 0x%x: failed!\n", CMD6); - return -1; - } - - tenmillisec (); - - return 0; - } - - static int - SetUpBoard (int port) - { - int loop = RETRY; - - do - { - if (WriteDSPCommand (portbase, CMD3)) - { - printk ("[AEDSP16] CMD 0x%x: failed!\n", CMD3); - return -1; - } - - tenmillisec (); - - } - while (WaitForDataAvail (port) && loop--); - - #if defined(THIS_SHOULD_GO_AWAY) - if (CheckDSPOkay (port)) - { - printk ("[AEDSP16] CheckDSPOkay: failed\n"); - return -1; - } - #else - if (ReadData (port) == -1) - { - printk ("[AEDSP16] ReadData after CMD 0x%x: failed\n", CMD3); - return -1; - } - #endif - - if (WriteDSPCommand (portbase, CMD4)) - { - printk ("[AEDSP16] CMD 0x%x: failed!\n", CMD4); - return -1; - } - - if (WriteDSPCommand (portbase, CMD5)) - { - printk ("[AEDSP16] CMD 0x%x: failed!\n", CMD5); - return -1; - } - - if (WriteDSPCommand (portbase, oredparams)) - { - printk ("[AEDSP16] Initialization of (M)IRQ and DMA: failed!\n"); - return -1; - } - return 0; - } - - static int - GetCardVersion (int port) - { - int len = 0; - int ret; - int ver[3]; - - do - { - if ((ret = ReadData (port)) == -1) - return -1; - /* - * We already know how many int are stored (2), so we know when the - * string is finished. - */ - ver[len++] = ret; - } - while (len < CARDVERLEN); - sprintf (AudioExcelVersion, "%d.%d", ver[0], ver[1]); - return 0; - } - - static int - GetCardName (int port) - { - int len = 0; - int ret; - - do - { - if ((ret = ReadData (port)) == -1) - /* - * If no more data available, return to the caller, no error if len>0. - * We have no other way to know when the string is finished. - */ - return (len ? 0 : -1); - - AudioExcelName[len++] = ret; - - } - while (len < CARDNAMELEN); - return 0; - } - - static void - InitializeHardParams (void) - { - - memset (AudioExcelName, 0, CARDNAMELEN + 1); - memset (AudioExcelVersion, 0, CARDVERLEN + 1); - - for (gc = 0; orIRQ[gc].or; gc++) - if (orIRQ[gc].val == irq) - oredparams |= orIRQ[gc].or; - - for (gc = 0; orMIRQ[gc].or; gc++) - if (orMIRQ[gc].or == mirq) - oredparams |= orMIRQ[gc].or; - - for (gc = 0; orDMA[gc].or; gc++) - if (orDMA[gc].val == dma) - oredparams |= orDMA[gc].or; - } - - static int - InitAEDSP16 (int which) - { - static char *InitName = NULL; - - InitializeHardParams (); - - if (ResetBoard (portbase)) - { - printk ("[AEDSP16] ResetBoard: failed!\n"); - return -1; - } - - #if defined(THIS_SHOULD_GO_AWAY) - if (CheckDSPOkay (portbase)) - { - printk ("[AEDSP16] CheckDSPOkay: failed!\n"); - return -1; - } - #endif - - if (WriteDSPCommand (portbase, CMD1)) - { - printk ("[AEDSP16] CMD 0x%x: failed!\n", CMD1); - return -1; - } - - if (GetCardName (portbase)) - { - printk ("[AEDSP16] GetCardName: failed!\n"); - return -1; - } - - /* - * My AEDSP16 card return SC-6000 in AudioExcelName, so - * if we have something different, we have to be warned. - */ - if (strcmp ("SC-6000", AudioExcelName)) - printk ("[AEDSP16] Warning: non SC-6000 audio card!\n"); - - if (WriteDSPCommand (portbase, CMD2)) - { - printk ("[AEDSP16] CMD 0x%x: failed!\n", CMD2); - return -1; - } - - if (GetCardVersion (portbase)) - { - printk ("[AEDSP16] GetCardVersion: failed!\n"); - return -1; - } - - if (SetUpBoard (portbase)) - { - printk ("[AEDSP16] SetUpBoard: failed!\n"); - return -1; - } - - if (which == INIT_MSS) - { - if (InitMSS (portbase)) - { - printk ("[AEDSP16] Can't initialize Microsoft Sound System mode.\n"); - return -1; - } - } - - /* - * If we are resetting, do not print any message because we may be - * in playing and we do not want lost too much time. - */ - if (!(which & RESET_DSP16)) - { - if (which & INIT_MPU401) - InitName = "MPU401"; - else if (which & INIT_SBPRO) - InitName = "SBPro"; - else if (which & INIT_MSS) - InitName = "MSS"; - else - InitName = "None"; - - printk ("Audio Excel DSP 16 init v%s (%s %s) [%s]\n", - VERSION, AudioExcelName, - AudioExcelVersion, InitName); - } - - tenmillisec (); - - return 0; - } - - #if defined(AEDSP16_SBPRO) - - int - InitAEDSP16_SBPRO (struct address_info *hw_config) - { - /* - * If the card is already init'ed MSS, we can not init it to SBPRO too - * because the board can not emulate simultaneously MSS and SBPRO. - */ - if (ae_init & INIT_MSS) - return -1; - if (ae_init & INIT_SBPRO) - return 0; - - /* - * For now we will leave this - * code included only when INCLUDE_AEDSP16 is configured in, but it should - * be better include it every time. - */ - if (!(ae_init & INIT_MPU401)) - { - if (check_region (hw_config->io_base, 0x0f)) - { - printk ("AEDSP16/SBPRO I/O port region is already in use.\n"); - return -1; - } - } - - /* - * Set up the internal hardware parameters, to let the driver reach - * the Sound Card. - */ - portbase = hw_config->io_base; - irq = hw_config->irq; - dma = hw_config->dma; - - if (InitAEDSP16 (INIT_SBPRO)) - return -1; - - #if !defined(MODULE) - /* - * If we are compiling sound.o (MODULAR version) we can not - * request any region because there is not a uninit routine that - * can allow me to release the requested region. - */ - if (!(ae_init & INIT_MPU401)) - request_region (hw_config->io_base, 0x0f, "AEDSP16 (SBPro)"); - #endif - - ae_init |= INIT_SBPRO; - return 0; - } - - #endif /* AEDSP16_SBPRO */ - - #if defined(AEDSP16_MSS) - - int - InitAEDSP16_MSS (struct address_info *hw_config) - { - /* - * If the card is already init'ed SBPRO, we can not init it to MSS too - * because the board can not emulate simultaneously MSS and SBPRO. - */ - if (ae_init & INIT_SBPRO) - return -1; - if (ae_init & INIT_MSS) - return 0; - - /* - * For now we will leave this - * code included only when INCLUDE_AEDSP16 is configured in, but it should - * be better include it every time. - */ - if (check_region (hw_config->io_base, 0x08)) - { - printk ("MSS I/O port region is already in use.\n"); - return -1; - } - - /* - * We must allocate the AEDSP16 region too because these are the I/O ports - * to access card's control registers. - */ - if (!(ae_init & INIT_MPU401)) - { - if (check_region (AEDSP16_BASE, 0x0f)) - { - printk ("AEDSP16 I/O port region is already in use.\n"); - return -1; - } - } - - - /* - * If we are configuring the card for MSS, the portbase for card - * configuration is the default one (0x220 unless you have changed the - * factory default with board switches), so no need to modify the - * portbase variable. - * The default is AEDSP16_BASE, that is the right value. - */ - irq = hw_config->irq; - dma = hw_config->dma; - - if (InitAEDSP16 (INIT_MSS)) - return -1; - - #if !defined(MODULE) - /* - * If we are compiling sound.o (MODULAR version) we can not - * request any region because there is not a uninit routine that - * can allow me to release the requested region. So when unloading - * and then reloading it, we are going to have some nice Oops! - */ - request_region (hw_config->io_base, 0x08, "AEDSP16 (MSS)"); - #endif - - if (!(ae_init & INIT_MPU401)) - request_region (AEDSP16_BASE, 0x0f, "AEDSP16 (SBPro)"); - - ae_init |= INIT_MSS; - return 0; - } - - #endif /* AEDSP16_MSS */ - - #if defined(AEDSP16_MPU401) - - int - InitAEDSP16_MPU401 (struct address_info *hw_config) - { - if (ae_init & INIT_MPU401) - return 0; - - /* - * For now we will leave this - * code included only when INCLUDE_AEDSP16 is configured in, but it should - * be better include it every time. - */ - if (check_region (hw_config->io_base, 0x02)) - { - printk ("SB I/O port region is already in use.\n"); - return -1; - } - - /* - * We must allocate the AEDSP16 region too because these are the I/O ports - * to access card's control registers. - */ - if (!(ae_init & (INIT_MSS | INIT_SBPRO))) - { - if (check_region (AEDSP16_BASE, 0x0f)) - { - printk ("AEDSP16 I/O port region is already in use.\n"); - return -1; - } - } - - /* - * If mpu401, the irq and dma are not important, do not touch it - * because we may use the default if SBPro is not yet configured, - * we may use the SBPro ones if configured, and nothing wrong - * should happen. - * - * The mirq default is 0, but once set it to non-0 value, we should - * not touch it anymore (unless I write an ioctl to do it, of course). - */ - mirq = hw_config->irq; - if (InitAEDSP16 (INIT_MPU401)) - return -1; - - #if !defined(MODULE) - /* - * If we are compiling sound.o (MODULAR version) we can not - * request any region because there is not a uninit routine that - * can allow me to release the requested region. - */ - request_region (hw_config->io_base, 0x02, "AEDSP16 (mpu401)"); - #endif - - if (!(ae_init & (INIT_MSS | INIT_SBPRO))) - request_region (AEDSP16_BASE, 0x0f, "AEDSP16 (SBPro)"); - - ae_init |= INIT_MPU401; - return 0; - } - - #endif /* AEDSP16_MPU401 */ - - #if 0 /* Leave it out for now. We are not using this portion of code. */ - - /* - * Entry point for a reset function. - * May be I will write the infamous ioctl :) - */ - int - ResetAEDSP16 (void) - { - #if defined(AEDSP16_DEBUG) - printk ("[AEDSP16] ResetAEDSP16 called.\n"); - #endif - return InitAEDSP16 (RESET_DSP16); - } - - #endif /* 0 */ - - #endif /* CONFIG_AEDSP16 */ --- 0 ---- diff -N -r -C3 linux-2.0.35.orig/drivers/sound/lowlevel/Config.tmpl linux-2.0.35/drivers/sound/lowlevel/Config.tmpl *** linux-2.0.35.orig/drivers/sound/lowlevel/Config.tmpl Thu May 16 10:05:56 1996 --- linux-2.0.35/drivers/sound/lowlevel/Config.tmpl Thu Sep 3 00:22:54 1998 *************** *** 3,5 **** --- 3,75 ---- if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then bool 'ACI mixer (miroPCM12)' CONFIG_ACI_MIXER fi + + if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then + bool 'Gallant Audio Cards (e.g. AEDSP 16, SC-6000 and SC-6600AEDSP)' CONFIG_AEDSP16 + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + bool 'SC-6600 based audio cards (new Audio Excel DSP 16)' CONFIG_SC6600 + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_SB" = "n" ]; then + bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_SB" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_SBPRO" = "n" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE $SBC_BASE + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' AEDSP16_SBC_IRQ $SBC_IRQ + int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_SBC_DMA $SBC_DMA + fi + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_MSS" = "n" ]; then + bool 'Audio Excel DSP 16 (MSS emulation)' CONFIG_AEDSP16_MSS + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_MSS" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_MSS" = "n" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 + int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' AEDSP16_MSS_IRQ $MSS_IRQ + int 'Audio Excel DSP 16 DMA 0, 1 or 3' AEDSP16_MSS_DMA $MSS_DMA + fi + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ ! "$CONFIG_MIDI" = "n" ]; then + bool 'Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401 + fi + fi + + if [ ! "$CONFIG_AEDSP16" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_MPU401" = "n" ]; then + if [ "$CONFIG_AEDSP16_SBPRO" = "n" ]; then + if [ "$CONFIG_AEDSP16_MSS" = "n" ]; then + hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220 + fi + fi + fi + fi + + if [ ! "$CONFIG_AEDSP16" = "n" ]; then + if [ ! "$CONFIG_AEDSP16_MPU401" = "n" ]; then + int 'MPU401 IRQ for Audio Excel DSP 16 5, 7, 9, 10 or 0 (disable)' AEDSP16_MPU_IRQ $MPU_IRQ + fi + fi + + if [ "$CONFIG_AEDSP16" = "y" ]; then + if [ "$CONFIG_SC6600" = "y" ]; then + bool 'Activate SC-6600 Joystick Interface' CONFIG_SC6600_JOY + int 'SC-6600 CDROM Interface (4==None, 3==IDE, 1==Panasonic, 0==?Sony?)' CONFIG_SC6600_CDROM 4 + hex 'SC-6600 CDROM Interface I/O Address' CONFIG_SC6600_CDROMBASE 0 + fi + fi diff -N -r -C3 linux-2.0.35.orig/drivers/sound/lowlevel/Makefile linux-2.0.35/drivers/sound/lowlevel/Makefile *** linux-2.0.35.orig/drivers/sound/lowlevel/Makefile Sun Sep 8 18:50:21 1996 --- linux-2.0.35/drivers/sound/lowlevel/Makefile Thu Sep 3 00:17:22 1998 *************** *** 6,11 **** --- 6,14 ---- ifdef CONFIG_ACI_MIXER OBJS := $(OBJS) aci.o endif + ifdef CONFIG_AEDSP16 + OBJS := $(OBJS) aedsp16.o + endif endif lowlevel.o: $(OBJS) *************** *** 17,19 **** --- 20,24 ---- ifdef HOSTCC include $(TOPDIR)/Rules.make endif + + diff -N -r -C3 linux-2.0.35.orig/drivers/sound/lowlevel/aedsp16.c linux-2.0.35/drivers/sound/lowlevel/aedsp16.c *** linux-2.0.35.orig/drivers/sound/lowlevel/aedsp16.c Thu Jan 1 01:00:00 1970 --- linux-2.0.35/drivers/sound/lowlevel/aedsp16.c Thu Sep 3 09:35:18 1998 *************** *** 0 **** --- 1,1312 ---- + /* + sound/aedsp16.c + + Audio Excel DSP 16 software configuration routines + Copyright (C) 1995 Riccardo Facchetti (riccardo@cdc8g5.cdc.polimi.it) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + /* + * Include the main USS/Lite header file. It include all the os, USS/Lite, etc + * headers needed by this source. + */ + #include + #include "../sound_config.h" + #include + + #ifndef AEDSP16_BASE + #undef CONFIG_AEDSP16 + #endif + + #if defined(CONFIG_AEDSP16) + + #if defined(CONFIG_AEDSP16_SBPRO) && defined(CONFIG_AEDSP16_MSS) + #error You have to enable only one of the MSS and SBPRO emulations. + #endif + + /* + + READ THIS + + This module is intended for Audio Excel DSP 16 Sound Card. + + NOTE: at this time, there is NO support for Audio Excel DSP 16 III: + I'm working on it. + + Audio Excel DSP 16 is an SB pro II, Microsoft Sound System and MPU-401 + compatible card. + It is software-only configurable (no jumpers to hard-set irq/dma/mpu-irq), + so before this module, the only way to configure the DSP under linux was + boot the MS-DOS loading the sound.sys device driver (this driver soft- + configure the sound board hardware by massaging someone of its registers), + and then ctrl-alt-del to boot linux with the DSP configured by the DOS + driver. + + This module works configuring your Audio Excel DSP 16's irq, dma and + mpu-401-irq. The USS/Lite routines rely on the fact that if the + hardware is there, they can detect it. The problem with AEDSP16 is + that no hardware can be found by the probe routines if the sound card + is not configured properly. Sometimes the kernel probe routines can find + an SBPRO even when the card is not configured (this is the standard setup + of the card), but the SBPRO emulation don't work well if the card is not + properly initialized. For this reason + + InitAEDSP16() + + routine is called before the USS/Lite probe routines try to detect the + hardware. + + NOTE (READ THE NOTE TOO, IT CONTAIN USEFUL INFORMATIONS) + + NOTE: Now it works with SC-6000 and SC-6600 based audio cards. + + NOTE: The driver is merged with the new USS/Lite sound driver. It works + as a lowlevel driver. + + The Audio Excel DSP 16 Sound Card emulates both SBPRO and MSS; + the USS/Lite sound driver can be configured for SBPRO and MSS cards + at the same time, but the aedsp16 can't be two cards!! + When we configure it, we have to choose the SBPRO or the MSS emulation + for AEDSP16. We also can install a *REAL* card of the other type (see [1]). + + NOTE: If someone can test the combination AEDSP16+MSS or AEDSP16+SBPRO + please let me know if it works. + + The MPU-401 support can be compiled in together with one of the other + two operating modes. + + NOTE: This is something like plug-and-play: we have only to plug + the AEDSP16 board in the socket, and then configure and compile + a kernel that uses the AEDSP16 software configuration capability. + No jumper setting is needed! + + For example, if you want AEDSP16 to be an SBPro, on irq 10, dma 3 + you have just to make config the USS/Lite package, configuring + the AEDSP16 sound card, then activating the SBPro emulation mode + and at last configuring IRQ and DMA. + Compile the kernel and run it. + + NOTE: This means that you can choose irq and dma, but not the + I/O addresses. To change I/O addresses you have to set them + with jumpers. + + You can change the irq/dma/mirq settings WITHOUT THE NEED to open + your computer and massage the jumpers (there are no irq/dma/mirq + jumpers to be configured anyway, only I/O BASE values have to be + configured with jumpers) + + For some ununderstandable reason, the card default of irq 7, dma 1, + don't work for me. Seems to be an IRQ or DMA conflict. Under heavy + HDD work, the kernel start to erupt out a lot of messages like: + + 'Sound: DMA timed out - IRQ/DRQ config error?' + + For what I can say, I have NOT any conflict at irq 7 (under linux I'm + using the lp polling driver), and dma line 1 is unused as stated by + /proc/dma. I can suppose this is a bug of AEDSP16. I know my hardware so + I'm pretty sure I have not any conflict, but may be I'm wrong. Who knows! + Anyway a setting of irq 10, dma 3 works really fine. + + NOTE: if someone can use AEDSP16 with irq 7, dma 1, please let me know + the emulation mode, all the installed hardware and the hardware + configuration (irq and dma settings of all the hardware). + + This init module should work with SBPRO+MSS, when one of the two is + the AEDSP16 emulation and the other the real card. (see [1]) + For example: + + AEDSP16 (0x220) in SBPRO emu (0x220) + real MSS + other + AEDSP16 (0x220) in MSS emu + real SBPRO (0x240) + other + + MPU401 should work. (see [2]) + + [1] + --- + Date: Mon, 29 Jul 1996 08:35:40 +0100 + From: Mr S J Greenaway + + [...] + Just to let you know got my Audio Excel (emulating a MSS) working + with my original SB16, thanks for the driver! + [...] + --- + + [2] Not tested by me for lack of hardware. + + TODO, WISHES AND TECH + + - About I/O ports allocation - + + Request the 2x0h region (port base) in any case if we are using this card. + + NOTE: the "aedsp16 (base)" string with which we are requesting the aedsp16 + port base region (see code) does not mean necessarily that we are emulating + sbpro. Even if this region is the sbpro I/O ports region, we use this + region to access the control registers of the card, and if emulating + sbpro, I/O sbpro registers too. If we are emulating MSS, the sbpro + registers are not used, in no way, to emulate an sbpro: they are + used only for configuration purposes. + + Started Fri Mar 17 16:13:18 MET 1995 + + v0.1 (ALPHA, was an user-level program called AudioExcelDSP16.c) + - Initial code. + v0.2 (ALPHA) + - Cleanups. + - Integrated with Linux voxware v 2.90-2 kernel sound driver. + - SoundBlaster Pro mode configuration. + - Microsoft Sound System mode configuration. + - MPU-401 mode configuration. + v0.3 (ALPHA) + - Cleanups. + - Rearranged the code to let InitAEDSP16 be more general. + - Erased the REALLY_SLOW_IO. We don't need it. Erased the linux/io.h + inclusion too. We rely on os.h + - Used the to get a variable + len string (we are not sure about the len of Copyright string). + This works with any SB and compatible. + - Added the code to request_region at device init (should go in + the main body of voxware). + v0.4 (BETA) + - Better configure.c patch for aedsp16 configuration (better + logic of inclusion of AEDSP16 support) + - Modified the conditional compilation to better support more than + one sound card of the emulated type (read the NOTES above) + - Moved the sb init routine from the attach to the very first + probe in sb_card.c + - Rearrangements and cleanups + - Wiped out some unnecessary code and variables: this is kernel + code so it is better save some TEXT and DATA + - Fixed the request_region code. We must allocate the aedsp16 (sbpro) + I/O ports in any case because they are used to access the DSP + configuration registers and we can not allow anyone to get them. + v0.5 + - cleanups on comments + - prep for diffs against v3.0-proto-950402 + v0.6 + - removed the request_region()s when compiling the MODULE sound.o + because we are not allowed (by the actual voxware structure) to + release_region() + v0.7 (pre ALPHA, not distributed) + - started porting this module to kernel 1.3.84. Dummy probe/attach + routines. + v0.8 (ALPHA) + - attached all the init routines. + v0.9 (BETA) + - Integrated with linux-pre2.0.7 + - Integrated with configuration scripts. + - Cleaned up and beautyfied the code. + v0.9.9 (BETA) + - Thanks to Piercarlo Grandi: corrected the conditonal compilation code. + Now only the code configured is compiled in, with some memory saving. + v0.9.10 + - Integration into the sound/lowlevel/ section of the sound driver. + - Re-organized the code. + v0.9.11 (not distributed) + - Rewritten the init interface-routines to initialize the AEDSP16 in + one shot. + - More cosmetics. + - More soft/hard configuration. + - SC-6600 support. + v0.9.12 + - Refined the v0.9.11 code with conditional compilation to distinguish + between SC-6000 and SC-6600 code. + + Known Problems: + - Audio Excel DSP 16 III don't work with this driver. I'm working on it. + + Credits: + Many thanks to Gerald Britton . He helped me a + lot in testing the 0.9.11 and 0.9.12 versions of this driver. + + */ + + + #define VERSION "0.9.12" /* Version of Audio Excel DSP 16 driver */ + + #undef AEDSP16_DEBUG 1 /* Define this to enable debug code */ + #undef AEDSP16_DEBUG_MORE 1 /* Define this to enable more debug */ + #undef AEDSP16_INFO 1 /* Define this to enable info code */ + + #if defined(AEDSP16_DEBUG) + # define DBG(x) printk x + # if defined(AEDSP16_DEBUG_MORE) + # define DBG1(x) printk x + # else + # define DBG1(x) + # endif + #else + # define DBG(x) + # define DBG1(x) + #endif + + /* + * Misc definitions + */ + #define TRUE 1 + #define FALSE 0 + + /* + * Hardware related defaults + */ + #define DEF_AEDSP16_IOB 0x220 /* 0x220(default) 0x240 */ + #define DEF_AEDSP16_IRQ 7 /* 5 7(default) 9 10 11 */ + #define DEF_AEDSP16_MRQ 0 /* 5 7 9 10 0(default), 0 means disable */ + #define DEF_AEDSP16_DMA 1 /* 0 1(default) 3 */ + + /* + * Commands of AEDSP16's DSP (SBPRO+special). + * Some of them are COMMAND_xx, in the future they may change. + */ + #define WRITE_MDIRQ_CFG 0x50 /* Set M&I&DRQ mask (the real config) */ + #define COMMAND_52 0x52 /* */ + #define READ_HARD_CFG 0x58 /* Read Hardware Config (I/O base etc) */ + #define COMMAND_5C 0x5c /* */ + #define COMMAND_60 0x60 /* */ + #define COMMAND_66 0x66 /* */ + #define COMMAND_6C 0x6c /* */ + #define COMMAND_6E 0x6e /* */ + #define COMMAND_88 0x88 /* */ + #define DSP_INIT_MSS 0x8c /* Enable Microsoft Sound System mode */ + #define COMMAND_C5 0xc5 /* */ + #define GET_DSP_VERSION 0xe1 /* Get DSP Version */ + #define GET_DSP_COPYRIGHT 0xe3 /* Get DSP Copyright */ + + /* + * Offsets of AEDSP16 DSP I/O ports. The offset is added to base I/O port + * to have the actual I/O port. + * Register permissions are: + * (wo) == Write Only + * (ro) == Read Only + * (w-) == Write + * (r-) == Read + */ + #define DSP_RESET 0x06 /* offset of DSP RESET (wo) */ + #define DSP_READ 0x0a /* offset of DSP READ (ro) */ + #define DSP_WRITE 0x0c /* offset of DSP WRITE (w-) */ + #define DSP_COMMAND 0x0c /* offset of DSP COMMAND (w-) */ + #define DSP_STATUS 0x0c /* offset of DSP STATUS (r-) */ + #define DSP_DATAVAIL 0x0e /* offset of DSP DATA AVAILABLE (ro) */ + + + #define RETRY 10 /* Various retry values on I/O opera- */ + #define STATUSRETRY 1000 /* tions. Sometimes we have to */ + #define HARDRETRY 500000 /* wait for previous cmd to complete */ + + /* + * Size of character arrays that store name and version of sound card + */ + #define CARDNAMELEN 15 /* Size of the card's name in chars */ + #define CARDVERLEN 2 /* Size of the card's version in chars */ + + /* + * Bitmapped flags of hard configuration + */ + /* + * Decode macros (xl == low byte, xh = high byte) + */ + #define IOBASE(xl) ((xl & 0x01)?0x240:0x220) + #define JOY(xl) (xl & 0x02) + #define MPUADDR(xl) ( \ + (xl & 0x0C)?0x330: \ + (xl & 0x08)?0x320: \ + (xl & 0x04)?0x310: \ + 0x300) + #define WSSADDR(xl) ((xl & 0x10)?0xE80:0x530) + #define CDROM(xh) (xh & 0x20) + #define CDROMADDR(xh) (((xh & 0x1F) << 4) + 0x200) + /* + * Encode macros + */ + #define BLDIOBASE(xl, val) { \ + xl &= ~0x01; \ + if (val == 0x240) \ + xl |= 0x01; \ + } + #define BLDJOY(xl, val) { \ + xl &= ~0x02; \ + if (val == 1) \ + xl |= 0x02; \ + } + #define BLDMPUADDR(xl, val) { \ + xl &= ~0x0C; \ + switch (val) { \ + case 0x330: \ + xl |= 0x0C; \ + break; \ + case 0x320: \ + xl |= 0x08; \ + break; \ + case 0x310: \ + xl |= 0x04; \ + break; \ + case 0x300: \ + xl |= 0x00; \ + break; \ + default: \ + xl |= 0x00; \ + break; \ + } \ + } + #define BLDWSSADDR(xl, val) { \ + xl &= ~0x10; \ + if (val == 0xE80) \ + xl |= 0x10; \ + } + #define BLDCDROM(xh, val) { \ + xh &= ~0x20; \ + if (val == 1) \ + xh |= 0x20; \ + } + #define BLDCDROMADDR(xh, val) { \ + int tmp = val; \ + tmp -= 0x200; \ + tmp >>= 4; \ + tmp &= 0x1F; \ + xh |= tmp; \ + xh &= 0x7F; \ + xh |= 0x40; \ + } + + /* + * Bit mapped flags for calling InitAEDSP16(), and saving the current + * emulation mode. + */ + #define INIT_NONE (0 ) + #define INIT_SBPRO (1<<0) + #define INIT_MSS (1<<1) + #define INIT_MPU401 (1<<2) + + static int soft_cfg = 0; /* Will contain or'ed values of soft cf */ + static int soft_cfg_1 = 0; /* Will contain or'ed values of some cf */ + static int gc = 0; /* generic counter (utility counter) */ + static int ver[3]; /* DSP Version, hi<-ver[0], lo<-ver[1] */ + + #if defined(CONFIG_SC6600) + static int hard_cfg[2] /* lo<-hard_cfg[0] hi<-hard_cfg[1] */ + = { 0, 0}; + #endif /* CONFIG_SC6600 */ + + #if defined(CONFIG_SC6600) + /* Decoded hard configuration */ + struct d_hcfg { + int iobase; + int joystick; + int mpubase; + int wssbase; + int cdrom; + int cdrombase; + } decoded_hcfg; + #endif /* CONFIG_SC6600 */ + + /* orVals contain the values to be or'ed */ + struct orVals { + int val; /* irq|mirq|dma */ + int or; /* soft_cfg |= TheStruct.or */ + }; + + /* aedsp16_info contain the audio card configuration */ + struct aedsp16_info { + int base_io; /* base I/O address for accessing card */ + int irq; /* irq value for DSP I/O */ + int mpu_irq; /* irq for mpu401 interface I/O */ + int dma; /* dma value for DSP I/O */ + int init; /* Initialization status of the card */ + }; + + /* + * Magic values that the DSP will eat when configuring irq/mirq/dma + */ + /* DSP IRQ conversion array */ + static struct orVals orIRQ[] = { + {0x05, 0x28}, + {0x07, 0x08}, + {0x09, 0x10}, + {0x0a, 0x18}, + {0x0b, 0x20}, + {0x00, 0x00} + }; + + /* MPU-401 IRQ conversion array */ + static struct orVals orMIRQ[] = { + {0x05, 0x04}, + {0x07, 0x44}, + {0x09, 0x84}, + {0x0a, 0xc4}, + {0x00, 0x00} + }; + + /* DMA Channels conversion array */ + static struct orVals orDMA[] = { + {0x00, 0x01}, + {0x01, 0x02}, + {0x03, 0x03}, + {0x00, 0x00} + }; + + static struct aedsp16_info ae_config = { + DEF_AEDSP16_IOB, + DEF_AEDSP16_IRQ, + DEF_AEDSP16_MRQ, + DEF_AEDSP16_DMA, + INIT_NONE + }; + + /* + * Buffers to store audio card informations + */ + static char DSPCopyright[CARDNAMELEN + 1]; + static char DSPVersion[CARDVERLEN + 1]; + + static void delay_10msec(void) + { + for (gc = 0; gc < 1000; gc++) + udelay(10); + } + + static int WaitForDataAvail(int port) + { + int loop = STATUSRETRY; + unsigned char ret = 0; + + DBG1(("WaitForDataAvail (0x%x): ", port)); + + do { + ret = inb(port + DSP_DATAVAIL); + /* + * Wait for data available (bit 7 of ret == 1) + */ + } while (!(ret & 0x80) && loop--); + + if (ret & 0x80) { + DBG1(("success.\n")); + return TRUE; + } + + DBG1(("failure.\n")); + return FALSE; + } + + static int ReadDSPByte(int port) + { + int inbyte; + + DBG((" Read DSP Byte (0x%x): ", port)); + + if (WaitForDataAvail(port) == FALSE) { + DBG(("failure.\n")); + return -1; + } + + inbyte = inb(port + DSP_READ); + + DBG(("read [0x%x]/{%c}.\n", inbyte, inbyte)); + + return inbyte; + } + + static int CheckDSPOkay(int port) + { + return ((ReadDSPByte(port) == 0xaa) ? TRUE : FALSE); + } + + static int ResetBoard(int port) + { + /* + * Reset DSP + */ + + DBG(("Reset DSP:\n")); + + outb(1, (port + DSP_RESET)); + udelay(10); + outb(0, (port + DSP_RESET)); + udelay(10); + udelay(10); + if (CheckDSPOkay(port) == TRUE) { + DBG(("success.\n")); + return TRUE; + } else + DBG(("failure.\n")); + return FALSE; + } + + static int WriteDSPByte(int port, int cmd) + { + unsigned char ret; + int loop = HARDRETRY; + + DBG((" Write DSP Byte (0x%x) [0x%x]: ", port, cmd)); + + do { + ret = inb(port + DSP_STATUS); + /* + * DSP ready to receive data if bit 7 of ret == 0 + */ + if (!(ret & 0x80)) { + outb(cmd, port + DSP_COMMAND); + DBG(("success.\n")); + return 0; + } + } while (loop--); + + DBG(("timeout.\n")); + printk("[aedsp16] DSP Command (0x%x) timeout.\n", cmd); + + return -1; + } + + #if defined(CONFIG_SC6600) + + #if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG) + void PrintInfo(void) { + DBG(("\n Base address: %x\n", decoded_hcfg.iobase)); + DBG((" Joystick : %s present\n", decoded_hcfg.joystick?"":" not")); + DBG((" WSS addr : %x\n", decoded_hcfg.wssbase)); + DBG((" MPU-401 addr: %x\n", decoded_hcfg.mpubase)); + DBG((" CDROM : %s present\n", (decoded_hcfg.cdrom!=4)?"":" not")); + DBG((" CDROMADDR : %x\n\n", decoded_hcfg.cdrombase)); + } + #endif + + void DecodeHardCfg(void) { + + DBG((" DecodeHardCfg: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1])); + + /* + * Decode Cfg Bytes. + */ + decoded_hcfg.iobase = IOBASE(hard_cfg[0]); + decoded_hcfg.joystick = JOY(hard_cfg[0]); + decoded_hcfg.wssbase = WSSADDR(hard_cfg[0]); + decoded_hcfg.mpubase = MPUADDR(hard_cfg[0]); + decoded_hcfg.cdrom = CDROM(hard_cfg[1]); + decoded_hcfg.cdrombase = CDROMADDR(hard_cfg[1]); + + #if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG) + printk(" Original sound card configuration:\n"); + PrintInfo(); + #endif + + /* + * Now set up the real kernel configuration. + */ + decoded_hcfg.iobase = AEDSP16_BASE; + #if defined(CONFIG_AEDSP16_MSS) + decoded_hcfg.wssbase = MSS_BASE; + #endif + #if defined(CONFIG_AEDSP16_MPU401) + decoded_hcfg.mpubase = MPU_BASE; + #endif + + #if defined(CONFIG_SC6600_JOY) + decoded_hcfg.joystick = CONFIG_SC6600_JOY; /* Enable */ + #endif + #if defined(CONFIG_SC6600_CDROM) + decoded_hcfg.cdrom = CONFIG_SC6600_CDROM; /* 4:N-3:I-2:G-1:P-0:S */ + #endif + #if defined(CONFIG_SC6600_CDROMBASE) + decoded_hcfg.cdrombase = CONFIG_SC6600_CDROMBASE; /* 0 Disable */ + #endif + + #if defined(AEDSP16_DEBUG) + DBG((" New Values:\n")); + PrintInfo(); + #endif + + DBG(("success.\n")); + } + + void BuildHardCfg(void) { + + DBG((" BuildHardCfg: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1])); + + hard_cfg[0] = 0; + hard_cfg[1] = 0; + + hard_cfg[0] |= 0x20; + + BLDIOBASE (hard_cfg[0], decoded_hcfg.iobase); + BLDWSSADDR(hard_cfg[0], decoded_hcfg.wssbase); + BLDMPUADDR(hard_cfg[0], decoded_hcfg.mpubase); + BLDJOY(hard_cfg[0], decoded_hcfg.joystick); + BLDCDROM(hard_cfg[1], decoded_hcfg.cdrom); + BLDCDROMADDR(hard_cfg[1], decoded_hcfg.cdrombase); + + #if defined(AEDSP16_DEBUG) + PrintInfo(); + #endif + + DBG((" BuildHardCfg: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1])); + DBG(("success.\n")); + + } + + static int WriteHardCfg(int port) { + + DBG(("WriteHardCfg:\n")); + + if (WriteDSPByte(port, COMMAND_6C)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_6C); + DBG(("failure.\n")); + return FALSE; + } + if (WriteDSPByte(port, COMMAND_5C)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_5C); + DBG(("failure.\n")); + return FALSE; + } + if (WriteDSPByte(port, hard_cfg[0])) { + printk("[aedsp16] DATA 0x%x: failed!\n", hard_cfg[0]); + DBG(("failure.\n")); + return FALSE; + } + if (WriteDSPByte(port, hard_cfg[1])) { + printk("[aedsp16] DATA 0x%x: failed!\n", hard_cfg[1]); + DBG(("failure.\n")); + return FALSE; + } + if (WriteDSPByte(port, COMMAND_C5)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_C5); + DBG(("failure.\n")); + return FALSE; + } + + DBG(("success.\n")); + + return TRUE; + } + + static int ReadHardCfg(int port) { + + DBG(("ReadHardCfg:\n")); + + if (WriteDSPByte(port, READ_HARD_CFG)) { + printk("[aedsp16] CMD 0x%x: failed!\n", READ_HARD_CFG); + DBG(("failure.\n")); + return FALSE; + } + + if ((hard_cfg[0] = ReadDSPByte(port)) == -1) { + printk("[aedsp16] ReadDSPByte after CMD 0x%x: failed\n", + READ_HARD_CFG); + DBG(("failure.\n")); + return FALSE; + } + if ((hard_cfg[1] = ReadDSPByte(port)) == -1) { + printk("[aedsp16] ReadDSPByte after CMD 0x%x: failed\n", + READ_HARD_CFG); + DBG(("failure.\n")); + return FALSE; + } + if (ReadDSPByte(port) == -1) { + printk("[aedsp16] ReadDSPByte after CMD 0x%x: failed\n", + READ_HARD_CFG); + DBG(("failure.\n")); + return FALSE; + } + + DBG(("success.\n")); + + return TRUE; + } + + static int ConfigExt(int port) { + + int extcfg, val; + + if (WriteDSPByte(port, COMMAND_66)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_66); + return FALSE; + } + + extcfg = 7; + if (decoded_hcfg.cdrom != 2) + extcfg = 0x0F; + if ((decoded_hcfg.cdrom == 4) || + (decoded_hcfg.cdrom == 3)) + extcfg &= ~2; + if (decoded_hcfg.cdrombase == 0) + extcfg &= ~2; + if (decoded_hcfg.mpubase == 0) + extcfg &= ~1; + + if (WriteDSPByte(port, extcfg)) { + printk("[aedsp16] Write extcfg: failed!\n"); + return FALSE; + } + if (WriteDSPByte(port, 0)) { + printk("[aedsp16] Write extcfg: failed!\n"); + return FALSE; + } + if (decoded_hcfg.cdrom == 3) { + if (WriteDSPByte(port, COMMAND_52)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_52); + return FALSE; + } + if ((val = ReadDSPByte(port)) == -1) { + printk("[aedsp16] ReadDSPByte after CMD 0x%x: failed\n", + COMMAND_52); + return FALSE; + } + val &= 0x7F; + if (WriteDSPByte(port, COMMAND_60)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_60); + return FALSE; + } + if (WriteDSPByte(port, val)) { + printk("[aedsp16] Write val: failed!\n"); + return FALSE; + } + } + + return TRUE; + } + + #endif /* CONFIG_SC6600 */ + + static int WriteSoftCfg(int port) { + if (WriteDSPByte(port, WRITE_MDIRQ_CFG)) { + printk("[aedsp16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG); + return FALSE; + } + if (WriteDSPByte(port, soft_cfg)) { + printk("[aedsp16] Initialization of (M)IRQ and DMA: failed!\n"); + return FALSE; + } + return TRUE; + } + + #if defined(CONFIG_AEDSP16_MSS) + + static int InitMSS(int port) + { + DBG(("InitMSS:\n")); + + delay_10msec(); + + if (WriteDSPByte(port, DSP_INIT_MSS)) { + printk("[aedsp16] InitMSS [0x%x]: failed!\n", DSP_INIT_MSS); + DBG(("failure.\n")); + return FALSE; + } + delay_10msec(); + + if (WriteSoftCfg(port) == FALSE) + return FALSE; + + outb(soft_cfg_1, MSS_BASE); + + DBG(("success.\n")); + + return TRUE; + } + + #endif + + static int SetUpBoard(int port) { + int loop = RETRY; + + #if defined(CONFIG_SC6600) + int val = 0; + + if (ReadHardCfg(port) == FALSE) { + printk("[aedsp16] ReadHardCfg: failed!\n"); + return FALSE; + } + + if (WriteDSPByte(port, COMMAND_52)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_52); + return FALSE; + } + + if ((val = ReadDSPByte(port)) == -1) { + printk("[aedsp16] ReadDSPByte after CMD 0x%x: failed\n", + COMMAND_52); + return FALSE; + } + #endif + + do { + if (WriteDSPByte(port, COMMAND_88)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_88); + return FALSE; + } + delay_10msec(); + } while ((WaitForDataAvail(port) == FALSE) && loop--); + + if (ReadDSPByte(port) == -1) { + printk("[aedsp16] ReadDSPByte after CMD 0x%x: failed\n", + COMMAND_88); + return FALSE; + } + + #if !defined(CONFIG_SC6600) + if (WriteDSPByte(port, COMMAND_5C)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_5C); + return FALSE; + } + #endif + + if (WriteSoftCfg(port) == FALSE) + return FALSE; + + #if defined(CONFIG_SC6600) + if (WriteDSPByte(port, COMMAND_60)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_60); + return FALSE; + } + if (WriteDSPByte(port, val)) { + printk("[aedsp16] DATA 0x%x: failed!\n", val); + return FALSE; + } + if (WriteDSPByte(port, COMMAND_6E)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_6E); + return FALSE; + } + if (WriteDSPByte(port, ver[0])) { + printk("[aedsp16] DATA 0x%x: failed!\n", ver[0]); + return FALSE; + } + if (WriteDSPByte(port, ver[1])) { + printk("[aedsp16] DATA 0x%x: failed!\n", ver[1]); + return FALSE; + } + + if (WriteHardCfg(port) == FALSE) { + printk("[aedsp16] WriteHardCfg: failed!\n"); + return FALSE; + } + + if (WriteDSPByte(port, COMMAND_5C)) { + printk("[aedsp16] CMD 0x%x: failed!\n", COMMAND_5C); + return FALSE; + } + + #if defined(THIS_IS_A_THING_I_HAVE_NOT_TESTED_YET) + if (WriteSoftCfg(port) == FALSE) + return FALSE; + #endif + + #endif + + return TRUE; + } + + static int ConfSTDValues(int port) { + if (WriteDSPByte(port, WRITE_MDIRQ_CFG)) { + printk("[aedsp16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG); + return FALSE; + } + /* + * 0x0A == (IRQ 7, DMA 1, MIRQ 0) + */ + if (WriteDSPByte(port, 0x0A)) { + printk("[aedsp16] ConfSTDValues: failed!\n"); + return FALSE; + } + return TRUE; + } + + static int GetDSPVersion(int port) + { + int len = 0; + int ret; + + DBG(("Get DSP Version:\n")); + + if (WriteDSPByte(ae_config.base_io, GET_DSP_VERSION)) { + printk("[aedsp16] CMD 0x%x: failed!\n", GET_DSP_VERSION); + DBG(("failed.\n")); + return FALSE; + } + + do { + if ((ret = ReadDSPByte(port)) == -1) { + DBG(("failed.\n")); + return FALSE; + } + /* + * We already know how many int are stored (2), so we know when the + * string is finished. + */ + ver[len++] = ret; + } while (len < CARDVERLEN); + sprintf(DSPVersion, "%d.%d", ver[0], ver[1]); + + DBG(("success.\n")); + + return TRUE; + } + + static int GetDSPCopyright(int port) + { + int len = 0; + int ret; + + DBG(("Get DSP Copyright:\n")); + + if (WriteDSPByte(ae_config.base_io, GET_DSP_COPYRIGHT)) { + printk("[aedsp16] CMD 0x%x: failed!\n", GET_DSP_COPYRIGHT); + DBG(("failed.\n")); + return FALSE; + } + + do { + if ((ret = ReadDSPByte(port)) == -1) { + /* + * If no more data available, return to the caller, no error if len>0. + * We have no other way to know when the string is finished. + */ + if (len) + break; + else { + DBG(("failed.\n")); + return FALSE; + } + } + + DSPCopyright[len++] = ret; + + } while (len < CARDNAMELEN); + + DBG(("success.\n")); + + return TRUE; + } + + static void InitializeHardParams(void) + { + memset(DSPCopyright, 0, CARDNAMELEN + 1); + memset(DSPVersion, 0, CARDVERLEN + 1); + + for (gc = 0; orIRQ[gc].or; gc++) + if (orIRQ[gc].val == ae_config.irq) { + soft_cfg |= orIRQ[gc].or; + soft_cfg_1 |= orIRQ[gc].or; + } + + for (gc = 0; orMIRQ[gc].or; gc++) + if (orMIRQ[gc].or == ae_config.mpu_irq) + soft_cfg |= orMIRQ[gc].or; + + for (gc = 0; orDMA[gc].or; gc++) + if (orDMA[gc].val == ae_config.dma) { + soft_cfg |= orDMA[gc].or; + soft_cfg_1 |= orDMA[gc].or; + } + } + + static int InitAEDSP16(void) + { + InitializeHardParams(); + + if (ResetBoard(ae_config.base_io) == FALSE) { + printk("[aedsp16] ResetBoard: failed!\n"); + return FALSE; + } + if (GetDSPCopyright(ae_config.base_io) == FALSE) { + printk("[aedsp16] GetDSPCopyright: failed!\n"); + return FALSE; + } + + /* + * My AEDSP16 card return SC-6000 in DSPCopyright, so + * if we have something different, we have to be warned. + */ + if (strcmp("SC-6000", DSPCopyright)) + printk("[aedsp16] Warning: non SC-6000 audio card!\n"); + + if (GetDSPVersion(ae_config.base_io) == FALSE) { + printk("[aedsp16] GetDSPVersion: failed!\n"); + return FALSE; + } + + if (ConfSTDValues(ae_config.base_io) == FALSE) { + printk("[aedsp16] ConfSTDValues: failed!\n"); + return FALSE; + } + + #if defined(CONFIG_SC6600) + if (ReadHardCfg(ae_config.base_io) == FALSE) { + printk("[aedsp16] ReadHardCfg: failed!\n"); + return FALSE; + } + + DecodeHardCfg(); + + BuildHardCfg(); + + if (WriteHardCfg(ae_config.base_io) == FALSE) { + printk("[aedsp16] WriteHardCfg: failed!\n"); + return FALSE; + } + + if (ConfigExt(ae_config.base_io) == FALSE) { + printk("[aedsp16] ConfigExt: failed!\n"); + return FALSE; + } + #endif /* CONFIG_SC6600 */ + + if (SetUpBoard(ae_config.base_io) == FALSE) { + printk("[aedsp16] SetUpBoard: failed!\n"); + return FALSE; + } + + #if defined(CONFIG_AEDSP16_MSS) + if (ae_config.init & INIT_MSS) { + if (InitMSS(ae_config.base_io) == FALSE) { + printk( + "[aedsp16] Can not initialize Microsoft Sound System mode.\n"); + return FALSE; + } + } + #endif + + #if !defined(MODULE) || defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG) + + printk("Audio Excel DSP 16 init v%s (%s %s) [", + VERSION, DSPCopyright, + DSPVersion); + + #if defined(CONFIG_AEDSP16_MPU401) + if (ae_config.init & INIT_MPU401) { + printk("MPU401"); + if ((ae_config.init & INIT_MSS) || + (ae_config.init & INIT_SBPRO)) + printk(" "); + } + #endif + + #if defined(CONFIG_AEDSP16_SBPRO) + if (ae_config.init & INIT_SBPRO) { + printk("SBPro"); + if (ae_config.init & INIT_MSS) + printk(" "); + } + #endif + + #if defined(CONFIG_AEDSP16_MSS) + if (ae_config.init & INIT_MSS) + printk("MSS"); + #endif + + printk("]\n"); + #endif /* MODULE || AEDSP16_INFO || AEDSP16_DEBUG */ + + delay_10msec(); + + return TRUE; + } + + #if defined(CONFIG_AEDSP16_SBPRO) + + static int init_aedsp16_sb(void) + { + DBG(("init_aedsp16_sb: ")); + + /* + * If the card is already init'ed MSS, we can not init it to SBPRO too + * because the board can not emulate simultaneously MSS and SBPRO. + */ + if (ae_config.init & INIT_MSS) + return FALSE; + if (ae_config.init & INIT_SBPRO) + return FALSE; + + ae_config.init |= INIT_SBPRO; + + DBG(("done.\n")); + + return TRUE; + } + + static void uninit_aedsp16_sb(void) + { + DBG(("uninit_aedsp16_sb: ")); + + ae_config.init &= ~INIT_SBPRO; + + DBG(("done.\n")); + } + #endif + + #if defined(CONFIG_AEDSP16_MSS) + + static int init_aedsp16_mss(void) + { + DBG(("init_aedsp16_mss: ")); + + /* + * If the card is already init'ed SBPRO, we can not init it to MSS too + * because the board can not emulate simultaneously MSS and SBPRO. + */ + if (ae_config.init & INIT_SBPRO) + return FALSE; + if (ae_config.init & INIT_MSS) + return FALSE; + /* + * We must check the AEDSP16_BASE region too because these are the I/O ports + * to access card's control registers. + */ + if (!(ae_config.init & INIT_MPU401)) { + if (check_region(ae_config.base_io, 0x0f)) { + printk( + "AEDSP16 BASE I/O port region is already in use.\n"); + return FALSE; + } + } + + /* + * We must allocate the AEDSP16_BASE region too because these are the I/O ports + * to access card's control registers. + */ + if (!(ae_config.init & INIT_MPU401)) + request_region(ae_config.base_io, 0x0f, "aedsp16 (base)"); + + ae_config.init |= INIT_MSS; + + DBG(("done.\n")); + + return TRUE; + } + + static void uninit_aedsp16_mss(void) + { + DBG(("uninit_aedsp16_mss: ")); + + if ((!(ae_config.init & INIT_MPU401)) && + (ae_config.init & INIT_MSS)) + release_region(ae_config.base_io, 0x0f); + + ae_config.init &= ~INIT_MSS; + DBG(("done.\n")); + } + #endif + + #if defined(CONFIG_AEDSP16_MPU401) + + static int init_aedsp16_mpu(void) + { + DBG(("init_aedsp16_mpu: ")); + + if (ae_config.init & INIT_MPU401) + return FALSE; + + /* + * We must check the AEDSP16_BASE region too because these are the I/O ports + * to access card's control registers. + */ + if (!(ae_config.init & (INIT_MSS | INIT_SBPRO))) { + if (check_region(ae_config.base_io, 0x0f)) { + printk( + "AEDSP16 BASE I/O port region is already in use.\n"); + return FALSE; + } + } + + if (!(ae_config.init & (INIT_MSS | INIT_SBPRO))) + request_region(ae_config.base_io, 0x0f, "aedsp16 (base)"); + + ae_config.init |= INIT_MPU401; + + DBG(("done.\n")); + + return TRUE; + } + + static void uninit_aedsp16_mpu(void) + { + DBG(("uninit_aedsp16_mpu: ")); + + if ((!(ae_config.init & (INIT_MSS | INIT_SBPRO))) && + (ae_config.init & INIT_MPU401)) + release_region(ae_config.base_io, 0x0f); + + ae_config.init &= ~INIT_MPU401; + + DBG(("done.\n")); + } + #endif + + int init_aedsp16(void) + { + int initialized = FALSE; + + ae_config.base_io = AEDSP16_BASE; + #if defined(CONFIG_AEDSP16_SBPRO) + ae_config.irq = AEDSP16_SBC_IRQ; + ae_config.dma = AEDSP16_SBC_DMA; + #endif + #if defined(CONFIG_AEDSP16_MSS) + ae_config.irq = AEDSP16_MSS_IRQ; + ae_config.dma = AEDSP16_MSS_DMA; + #endif + #if defined(CONFIG_AEDSP16_MPU401) + ae_config.mpu_irq = AEDSP16_MPU_IRQ; + #endif + + DBG(("Initializing BASE[0x%x] IRQ[%d] DMA[%d] MIRQ[%d]\n", + ae_config.base_io,ae_config.irq,ae_config.dma,ae_config.mpu_irq)); + + #if defined(CONFIG_AEDSP16_SBPRO) + if (init_aedsp16_sb() == FALSE) + uninit_aedsp16_sb(); + else + initialized = TRUE; + #endif + + #if defined(CONFIG_AEDSP16_MPU401) + if (init_aedsp16_mpu() == FALSE) + uninit_aedsp16_mpu(); + else + initialized = TRUE; + #endif + + #if defined(CONFIG_AEDSP16_MSS) + + /* + * In the sequence of init routines, the MSS init MUST be the last! + * This because of the special register programming the MSS mode needs. + * A board reset would disable the MSS mode restoring the default SBPRO + * mode. + */ + if (init_aedsp16_mss() == FALSE) + uninit_aedsp16_mss(); + else + initialized = TRUE; + #endif + + if (initialized) + initialized = InitAEDSP16(); + return initialized; + } + + void uninit_aedsp16(void) + { + #if defined(CONFIG_AEDSP16_MSS) + uninit_aedsp16_mss(); + #endif + + #if defined(CONFIG_AEDSP16_SBPRO) + uninit_aedsp16_sb(); + #endif + + #if defined(CONFIG_AEDSP16_MPU401) + uninit_aedsp16_mpu(); + #endif + } + #endif /* CONFIG_AEDSP16 */ diff -N -r -C3 linux-2.0.35.orig/drivers/sound/lowlevel/init.c linux-2.0.35/drivers/sound/lowlevel/init.c *** linux-2.0.35.orig/drivers/sound/lowlevel/init.c Tue May 28 16:45:17 1996 --- linux-2.0.35/drivers/sound/lowlevel/init.c Sat Sep 5 20:38:40 1998 *************** *** 7,12 **** --- 7,22 ---- #ifdef CONFIG_LOWLEVEL_SOUND extern int attach_aci(void); extern void unload_aci(void); + extern int init_aedsp16(void); + extern void uninit_aedsp16(void); + + void + sound_pre_init_lowlevel_drivers(void) + { + #ifdef CONFIG_AEDSP16 + init_aedsp16(); + #endif + } void sound_init_lowlevel_drivers(void) *************** *** 21,26 **** --- 31,39 ---- { #ifdef CONFIG_ACI_MIXER unload_aci(); + #endif + #ifdef CONFIG_AEDSP16 + uninit_aedsp16(); #endif } #endif diff -N -r -C3 linux-2.0.35.orig/drivers/sound/soundcard.c linux-2.0.35/drivers/sound/soundcard.c *** linux-2.0.35.orig/drivers/sound/soundcard.c Wed Aug 21 08:18:09 1996 --- linux-2.0.35/drivers/sound/soundcard.c Sat Sep 5 20:50:55 1998 *************** *** 326,331 **** --- 326,340 ---- chrdev_registered = 1; #endif + #ifdef CONFIG_LOWLEVEL_SOUND + { + /* initialisation of low-level drivers (such as the AudioExcel + detect and init -- that must run before card probing */ + extern void sound_pre_init_lowlevel_drivers(void); + sound_pre_init_lowlevel_drivers(); + } + #endif + soundcard_configured = 1; sndtable_init (); /* Initialize call tables and detect cards */ diff -N -r -C3 linux-2.0.35.orig/Documentation/Configure.help linux-2.0.35/Documentation/Configure.help *** linux-2.0.35.orig/Documentation/Configure.help Mon Jul 13 22:47:25 1998 --- linux-2.0.35/Documentation/Configure.help Thu Sep 24 21:15:19 1998 *************** *** 4385,4390 **** --- 4443,4463 ---- CONFIG_SUN_AUDIO This is support for the soundcards on Sun workstations. The code does not exist yet, so you might as well say N here. + + Audio Excel DSP 16 support + CONFIG_AEDSP16 + Answer Y if you have a Gallant's Audio Excel DSP 16 card. This card + emulate an SBPro or a Microsoft Sound System card. + You must select one of the Sound Blaster or Microsoft Sound System + before select this menu item. + Read the drivers/sound/lowlevel/Readme.aedsp16 file and the head of + drivers/sound/lowlevel/aedsp16.c to have more informations about + this driver and its configuration. + !!!NOTE!!! + The driver supports Audio Excel DSP 16 but not the III version of + this card. Read drivers/sound/lowlevel/Readme.aedsp16 if you want + to know something more on how to use the III version with this sound + driver. Kernel profiling support CONFIG_PROFILE