/*
* Driver for S3 SonicVibes soundcard
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
* BUGS:
* It looks like 86c617 rev 3 doesn't supports DDMA buffers above 16MB?
* Driver sometimes hangs... Nobody knows why at this moment...
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/gameport.h>
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/info.h>
#include <sound/control.h>
#include <sound/mpu401.h>
#include <sound/opl3.h>
#include <sound/initval.h>
#include <asm/io.h>
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("S3 SonicVibes PCI");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}");
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
#define SUPPORT_JOYSTICK 1
#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int reverb[SNDRV_CARDS];
static int mge[SNDRV_CARDS];
static unsigned int dmaio = 0x7a00; /* DDMA i/o address */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for S3 SonicVibes soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for S3 SonicVibes soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable S3 SonicVibes soundcard.");
module_param_array(reverb, bool, NULL, 0444);
MODULE_PARM_DESC(reverb, "Enable reverb (SRAM is present) for S3 SonicVibes soundcard.");
module_param_array(mge, bool, NULL, 0444);
MODULE_PARM_DESC(mge, "MIC Gain Enable for S3 SonicVibes soundcard.");
module_param(dmaio, uint, 0444);
MODULE_PARM_DESC(dmaio, "DDMA i/o base address for S3 SonicVibes soundcard.");
/*
* Enhanced port direct registers
*/
#define SV_REG(sonic, x) ((sonic)->enh_port + SV_REG_##x)
#define SV_REG_CONTROL 0x00 /* R/W: CODEC/Mixer control register */
#define SV_ENHANCED 0x01 /* audio mode select - enhanced mode */
#define SV_TEST 0x02 /* test bit */
#define SV_REVERB 0x04 /* reverb enable */
#define SV_WAVETABLE 0x08 /* wavetable active / FM active if not set */
#define SV_INTA 0x20 /* INTA driving - should be always 1 */
#define SV_RESET 0x80 /* reset chip */
#define SV_REG_IRQMASK 0x01 /* R/W: CODEC/Mixer interrupt mask register */
#define SV_DMAA_MASK 0x01 /* mask DMA-A interrupt */
#define SV_DMAC_MASK 0x04 /* mask DMA-C interrupt */
#define SV_SPEC_MASK 0x08 /* special interrupt mask - should be always masked */
#define SV_UD_MASK 0x40 /* Up/Down button interrupt mask */
#define SV_MIDI_MASK 0x80 /* mask MIDI interrupt */
#define SV_REG_STATUS 0x02 /* R/O: CODEC/Mixer status register */
#define SV_DMAA_IRQ 0x01 /* DMA-A interrupt */
#define SV_DMAC_IRQ 0x04 /* DMA-C interrupt */
#define SV_SPEC_IRQ 0x08 /* special interrupt */
#define SV_UD_IRQ 0x40 /* Up/Down interrupt */
#define SV_MIDI_IRQ 0x80 /* MIDI interrupt */
#define SV_REG_INDEX 0x04 /* R/W: CODEC/Mixer index address register */
#define SV_MCE 0x40 /* mode change enable */
#define SV_TRD 0x80 /* DMA transfer request disabled */
#define SV_REG_DATA 0x05 /* R/W: CODEC/Mixer index data register */
/*
* Enhanced port indirect registers
*/
#define SV_IREG_LEFT_ADC 0x00 /* Left ADC Input Control */
#define SV_IREG_RIGHT_ADC 0x01 /* Right ADC Input Control */
#define SV_IREG_LEFT_AUX1 0x02 /* Left AUX1 Input Control */
#define SV_IREG_RIGHT_AUX1 0x03 /* Right AUX1 Input Control */
#define SV_IREG_LEFT_CD 0x04 /* Left CD Input Control */
#define SV_IREG_RIGHT_CD 0x05 /* Right CD Input Control */
#define SV_IREG_LEFT_LINE 0x06 /* Left Line Input Control */
#define SV_IREG_RIGHT_LINE 0x07 /* Right Line Input Control */
#define SV_IREG_MIC 0x08 /* MIC Input Control */
#define SV_IREG_GAME_PORT 0x09 /* Game Port Control */
#define SV_IREG_LEFT_SYNTH 0x0a /* Left Synth Input Control */
#define SV_IREG_RIGHT_SYNTH 0x0b /* Right Synth Input Control */
#define SV_IREG_LEFT_AUX2 0x0c /* Left AUX2 Input Control */
#define SV_IREG_RIGHT_AUX2 0x0d /* Right AUX2 Input Control */
#define SV_IREG_LEFT_ANALOG 0x0e /* Left Analog Mixer Output Control */
#define SV_IREG_RIGHT_ANALOG 0x0f /* Right Analog Mixer Output Control */
#define SV_IREG_LEFT_PCM 0x10 /* Left PCM Input Control */
#define SV_IREG_RIGHT_PCM 0x11 /* Right PCM Input Control */
#define SV_IREG_DMA_DATA_FMT 0x12 /* DMA Data Format */
#define SV_IREG_PC_ENABLE 0x13 /* Playback/Capture Enable Register */
#define SV_IREG_UD_BUTTON 0x14 /* Up/Down Button Register */
#define SV_IREG_REVISION 0x15 /* Revision */
#define SV_IREG_ADC_OUTPUT_CTRL 0x16 /* ADC Output Control */
#define SV_IREG_DMA_A_UPPER 0x18 /* DMA A Upper Base Count */
#define SV_IREG_DMA_A_LOWER 0x19 /* DMA A Lower Base Count */
#define SV_IREG_DMA_C_UPPER 0x1c /* DMA C Upper Base Count */
#define SV_IREG_DMA_C_LOWER 0x1d /* DMA C Lower Base Count */
#define SV_IREG_PCM_RATE_LOW 0x1e /* PCM Sampling Rate Low Byte */
#define SV_IREG_PCM_RATE_HIGH 0x1f /* PCM Sampling Rate High Byte */
#define SV_IREG_SYNTH_RATE_LOW 0x20 /* Synthesizer Sampling Rate Low Byte */
#define SV_IREG_SYNTH_RATE_HIGH 0x21 /* Synthesizer Sampling Rate High Byte */
#define SV_IREG_ADC_CLOCK 0x22 /* ADC Clock Source Selection */
#define SV_IREG_ADC_ALT_RATE 0x23 /* ADC Alternative Sampling Rate Selection */
#define SV_IREG_ADC_PLL_M 0x24 /* ADC PLL M Register */
#define SV_IREG_ADC_PLL_N 0x25 /* ADC PLL N Register */
#define SV_IREG_SYNTH_PLL_M 0x26 /* Synthesizer PLL M Register */
#define SV_IREG_SYNTH_PLL_N 0x27 /* Synthesizer PLL N Register */
#define SV_IREG_MPU401 0x2a /* MPU-401 UART Operation */
#define SV_IREG_DRIVE_CTRL 0x2b /* Drive Control */
#define SV_IREG_SRS_SPACE 0x2c /* SRS Space Control */
#define SV_IREG_SRS_CENTER 0x2d /
|