📄 maestro3.c
字号:
/* * Driver for ESS Maestro3/Allegro (ES1988) soundcards. * Copyright (c) 2000 by Zach Brown <zab@zabbo.net> * Takashi Iwai <tiwai@suse.de> * * Most of the hardware init stuffs are based on maestro3 driver for * OSS/Free by Zach Brown. Many thanks to Zach! * * 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 * * * ChangeLog: * Aug. 27, 2001 * - Fixed deadlock on capture * - Added Canyon3D-2 support by Rob Riggs <rob@pangalactic.org> * */ #define CARD_NAME "ESS Maestro3/Allegro/Canyon3D-2"#define DRIVER_NAME "Maestro3"#include <sound/driver.h>#include <asm/io.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/dma-mapping.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/moduleparam.h>#include <linux/firmware.h>#include <sound/core.h>#include <sound/info.h>#include <sound/control.h>#include <sound/pcm.h>#include <sound/mpu401.h>#include <sound/ac97_codec.h>#include <sound/initval.h>#include <asm/byteorder.h>MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>");MODULE_DESCRIPTION("ESS Maestro3 PCI");MODULE_LICENSE("GPL");MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI}," "{ESS,ES1988}," "{ESS,Allegro PCI}," "{ESS,Allegro-1 PCI}," "{ESS,Canyon3D-2/LE PCI}}");#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNELMODULE_FIRMWARE("ess/maestro3_assp_kernel.fw");MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw");#endifstatic 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; /* all enabled */static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};static int amp_gpio[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};module_param_array(index, int, NULL, 0444);MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");module_param_array(id, charp, NULL, 0444);MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");module_param_array(enable, bool, NULL, 0444);MODULE_PARM_DESC(enable, "Enable this soundcard.");module_param_array(external_amp, bool, NULL, 0444);MODULE_PARM_DESC(external_amp, "Enable external amp for " CARD_NAME " soundcard.");module_param_array(amp_gpio, int, NULL, 0444);MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)");#define MAX_PLAYBACKS 2#define MAX_CAPTURES 1#define NR_DSPS (MAX_PLAYBACKS + MAX_CAPTURES)/* * maestro3 registers *//* Allegro PCI configuration registers */#define PCI_LEGACY_AUDIO_CTRL 0x40#define SOUND_BLASTER_ENABLE 0x00000001#define FM_SYNTHESIS_ENABLE 0x00000002#define GAME_PORT_ENABLE 0x00000004#define MPU401_IO_ENABLE 0x00000008#define MPU401_IRQ_ENABLE 0x00000010#define ALIAS_10BIT_IO 0x00000020#define SB_DMA_MASK 0x000000C0#define SB_DMA_0 0x00000040#define SB_DMA_1 0x00000040#define SB_DMA_R 0x00000080#define SB_DMA_3 0x000000C0#define SB_IRQ_MASK 0x00000700#define SB_IRQ_5 0x00000000#define SB_IRQ_7 0x00000100#define SB_IRQ_9 0x00000200#define SB_IRQ_10 0x00000300#define MIDI_IRQ_MASK 0x00003800#define SERIAL_IRQ_ENABLE 0x00004000#define DISABLE_LEGACY 0x00008000#define PCI_ALLEGRO_CONFIG 0x50#define SB_ADDR_240 0x00000004#define MPU_ADDR_MASK 0x00000018#define MPU_ADDR_330 0x00000000#define MPU_ADDR_300 0x00000008#define MPU_ADDR_320 0x00000010#define MPU_ADDR_340 0x00000018#define USE_PCI_TIMING 0x00000040#define POSTED_WRITE_ENABLE 0x00000080#define DMA_POLICY_MASK 0x00000700#define DMA_DDMA 0x00000000#define DMA_TDMA 0x00000100#define DMA_PCPCI 0x00000200#define DMA_WBDMA16 0x00000400#define DMA_WBDMA4 0x00000500#define DMA_WBDMA2 0x00000600#define DMA_WBDMA1 0x00000700#define DMA_SAFE_GUARD 0x00000800#define HI_PERF_GP_ENABLE 0x00001000#define PIC_SNOOP_MODE_0 0x00002000#define PIC_SNOOP_MODE_1 0x00004000#define SOUNDBLASTER_IRQ_MASK 0x00008000#define RING_IN_ENABLE 0x00010000#define SPDIF_TEST_MODE 0x00020000#define CLK_MULT_MODE_SELECT_2 0x00040000#define EEPROM_WRITE_ENABLE 0x00080000#define CODEC_DIR_IN 0x00100000#define HV_BUTTON_FROM_GD 0x00200000#define REDUCED_DEBOUNCE 0x00400000#define HV_CTRL_ENABLE 0x00800000#define SPDIF_ENABLE 0x01000000#define CLK_DIV_SELECT 0x06000000#define CLK_DIV_BY_48 0x00000000#define CLK_DIV_BY_49 0x02000000#define CLK_DIV_BY_50 0x04000000#define CLK_DIV_RESERVED 0x06000000#define PM_CTRL_ENABLE 0x08000000#define CLK_MULT_MODE_SELECT 0x30000000#define CLK_MULT_MODE_SHIFT 28#define CLK_MULT_MODE_0 0x00000000#define CLK_MULT_MODE_1 0x10000000#define CLK_MULT_MODE_2 0x20000000#define CLK_MULT_MODE_3 0x30000000#define INT_CLK_SELECT 0x40000000#define INT_CLK_MULT_RESET 0x80000000/* M3 */#define INT_CLK_SRC_NOT_PCI 0x00100000#define INT_CLK_MULT_ENABLE 0x80000000#define PCI_ACPI_CONTROL 0x54#define PCI_ACPI_D0 0x00000000#define PCI_ACPI_D1 0xB4F70000#define PCI_ACPI_D2 0xB4F7B4F7#define PCI_USER_CONFIG 0x58#define EXT_PCI_MASTER_ENABLE 0x00000001#define SPDIF_OUT_SELECT 0x00000002#define TEST_PIN_DIR_CTRL 0x00000004#define AC97_CODEC_TEST 0x00000020#define TRI_STATE_BUFFER 0x00000080#define IN_CLK_12MHZ_SELECT 0x00000100#define MULTI_FUNC_DISABLE 0x00000200#define EXT_MASTER_PAIR_SEL 0x00000400#define PCI_MASTER_SUPPORT 0x00000800#define STOP_CLOCK_ENABLE 0x00001000#define EAPD_DRIVE_ENABLE 0x00002000#define REQ_TRI_STATE_ENABLE 0x00004000#define REQ_LOW_ENABLE 0x00008000#define MIDI_1_ENABLE 0x00010000#define MIDI_2_ENABLE 0x00020000#define SB_AUDIO_SYNC 0x00040000#define HV_CTRL_TEST 0x00100000#define SOUNDBLASTER_TEST 0x00400000#define PCI_USER_CONFIG_C 0x5C#define PCI_DDMA_CTRL 0x60#define DDMA_ENABLE 0x00000001/* Allegro registers */#define HOST_INT_CTRL 0x18#define SB_INT_ENABLE 0x0001#define MPU401_INT_ENABLE 0x0002#define ASSP_INT_ENABLE 0x0010#define RING_INT_ENABLE 0x0020#define HV_INT_ENABLE 0x0040#define CLKRUN_GEN_ENABLE 0x0100#define HV_CTRL_TO_PME 0x0400#define SOFTWARE_RESET_ENABLE 0x8000/* * should be using the above defines, probably. */#define REGB_ENABLE_RESET 0x01#define REGB_STOP_CLOCK 0x10#define HOST_INT_STATUS 0x1A#define SB_INT_PENDING 0x01#define MPU401_INT_PENDING 0x02#define ASSP_INT_PENDING 0x10#define RING_INT_PENDING 0x20#define HV_INT_PENDING 0x40#define HARDWARE_VOL_CTRL 0x1B#define SHADOW_MIX_REG_VOICE 0x1C#define HW_VOL_COUNTER_VOICE 0x1D#define SHADOW_MIX_REG_MASTER 0x1E#define HW_VOL_COUNTER_MASTER 0x1F#define CODEC_COMMAND 0x30#define CODEC_READ_B 0x80#define CODEC_STATUS 0x30#define CODEC_BUSY_B 0x01#define CODEC_DATA 0x32#define RING_BUS_CTRL_A 0x36#define RAC_PME_ENABLE 0x0100#define RAC_SDFS_ENABLE 0x0200#define LAC_PME_ENABLE 0x0400#define LAC_SDFS_ENABLE 0x0800#define SERIAL_AC_LINK_ENABLE 0x1000#define IO_SRAM_ENABLE 0x2000#define IIS_INPUT_ENABLE 0x8000#define RING_BUS_CTRL_B 0x38#define SECOND_CODEC_ID_MASK 0x0003#define SPDIF_FUNC_ENABLE 0x0010#define SECOND_AC_ENABLE 0x0020#define SB_MODULE_INTF_ENABLE 0x0040#define SSPE_ENABLE 0x0040#define M3I_DOCK_ENABLE 0x0080#define SDO_OUT_DEST_CTRL 0x3A#define COMMAND_ADDR_OUT 0x0003#define PCM_LR_OUT_LOCAL 0x0000#define PCM_LR_OUT_REMOTE 0x0004#define PCM_LR_OUT_MUTE 0x0008#define PCM_LR_OUT_BOTH 0x000C#define LINE1_DAC_OUT_LOCAL 0x0000#define LINE1_DAC_OUT_REMOTE 0x0010#define LINE1_DAC_OUT_MUTE 0x0020#define LINE1_DAC_OUT_BOTH 0x0030#define PCM_CLS_OUT_LOCAL 0x0000#define PCM_CLS_OUT_REMOTE 0x0040#define PCM_CLS_OUT_MUTE 0x0080#define PCM_CLS_OUT_BOTH 0x00C0#define PCM_RLF_OUT_LOCAL 0x0000#define PCM_RLF_OUT_REMOTE 0x0100#define PCM_RLF_OUT_MUTE 0x0200#define PCM_RLF_OUT_BOTH 0x0300#define LINE2_DAC_OUT_LOCAL 0x0000#define LINE2_DAC_OUT_REMOTE 0x0400#define LINE2_DAC_OUT_MUTE 0x0800#define LINE2_DAC_OUT_BOTH 0x0C00#define HANDSET_OUT_LOCAL 0x0000#define HANDSET_OUT_REMOTE 0x1000#define HANDSET_OUT_MUTE 0x2000#define HANDSET_OUT_BOTH 0x3000#define IO_CTRL_OUT_LOCAL 0x0000#define IO_CTRL_OUT_REMOTE 0x4000#define IO_CTRL_OUT_MUTE 0x8000#define IO_CTRL_OUT_BOTH 0xC000#define SDO_IN_DEST_CTRL 0x3C#define STATUS_ADDR_IN 0x0003#define PCM_LR_IN_LOCAL 0x0000#define PCM_LR_IN_REMOTE 0x0004#define PCM_LR_RESERVED 0x0008#define PCM_LR_IN_BOTH 0x000C#define LINE1_ADC_IN_LOCAL 0x0000#define LINE1_ADC_IN_REMOTE 0x0010#define LINE1_ADC_IN_MUTE 0x0020#define MIC_ADC_IN_LOCAL 0x0000#define MIC_ADC_IN_REMOTE 0x0040#define MIC_ADC_IN_MUTE 0x0080#define LINE2_DAC_IN_LOCAL 0x0000#define LINE2_DAC_IN_REMOTE 0x0400#define LINE2_DAC_IN_MUTE 0x0800#define HANDSET_IN_LOCAL 0x0000#define HANDSET_IN_REMOTE 0x1000#define HANDSET_IN_MUTE 0x2000#define IO_STATUS_IN_LOCAL 0x0000#define IO_STATUS_IN_REMOTE 0x4000#define SPDIF_IN_CTRL 0x3E#define SPDIF_IN_ENABLE 0x0001#define GPIO_DATA 0x60#define GPIO_DATA_MASK 0x0FFF#define GPIO_HV_STATUS 0x3000#define GPIO_PME_STATUS 0x4000#define GPIO_MASK 0x64#define GPIO_DIRECTION 0x68#define GPO_PRIMARY_AC97 0x0001#define GPI_LINEOUT_SENSE 0x0004#define GPO_SECONDARY_AC97 0x0008#define GPI_VOL_DOWN 0x0010#define GPI_VOL_UP 0x0020#define GPI_IIS_CLK 0x0040#define GPI_IIS_LRCLK 0x0080#define GPI_IIS_DATA 0x0100#define GPI_DOCKING_STATUS 0x0100#define GPI_HEADPHONE_SENSE 0x0200#define GPO_EXT_AMP_SHUTDOWN 0x1000#define GPO_EXT_AMP_M3 1 /* default m3 amp */#define GPO_EXT_AMP_ALLEGRO 8 /* default allegro amp *//* M3 */#define GPO_M3_EXT_AMP_SHUTDN 0x0002#define ASSP_INDEX_PORT 0x80#define ASSP_MEMORY_PORT 0x82#define ASSP_DATA_PORT 0x84#define MPU401_DATA_PORT 0x98#define MPU401_STATUS_PORT 0x99#define CLK_MULT_DATA_PORT 0x9C#define ASSP_CONTROL_A 0xA2#define ASSP_0_WS_ENABLE 0x01#define ASSP_CTRL_A_RESERVED1 0x02#define ASSP_CTRL_A_RESERVED2 0x04#define ASSP_CLK_49MHZ_SELECT 0x08#define FAST_PLU_ENABLE 0x10#define ASSP_CTRL_A_RESERVED3 0x20#define DSP_CLK_36MHZ_SELECT 0x40#define ASSP_CONTROL_B 0xA4#define RESET_ASSP 0x00#define RUN_ASSP 0x01#define ENABLE_ASSP_CLOCK 0x00#define STOP_ASSP_CLOCK 0x10#define RESET_TOGGLE 0x40#define ASSP_CONTROL_C 0xA6#define ASSP_HOST_INT_ENABLE 0x01#define FM_ADDR_REMAP_DISABLE 0x02#define HOST_WRITE_PORT_ENABLE 0x08#define ASSP_HOST_INT_STATUS 0xAC#define DSP2HOST_REQ_PIORECORD 0x01#define DSP2HOST_REQ_I2SRATE 0x02#define DSP2HOST_REQ_TIMER 0x04/* AC97 registers *//* XXX fix this crap up *//*#define AC97_RESET 0x00*/#define AC97_VOL_MUTE_B 0x8000#define AC97_VOL_M 0x1F#define AC97_LEFT_VOL_S 8#define AC97_MASTER_VOL 0x02#define AC97_LINE_LEVEL_VOL 0x04#define AC97_MASTER_MONO_VOL 0x06#define AC97_PC_BEEP_VOL 0x0A#define AC97_PC_BEEP_VOL_M 0x0F#define AC97_SROUND_MASTER_VOL 0x38#define AC97_PC_BEEP_VOL_S 1/*#define AC97_PHONE_VOL 0x0C#define AC97_MIC_VOL 0x0E*/#define AC97_MIC_20DB_ENABLE 0x40/*#define AC97_LINEIN_VOL 0x10#define AC97_CD_VOL 0x12#define AC97_VIDEO_VOL 0x14#define AC97_AUX_VOL 0x16*/#define AC97_PCM_OUT_VOL 0x18/*#define AC97_RECORD_SELECT 0x1A*/#define AC97_RECORD_MIC 0x00#define AC97_RECORD_CD 0x01#define AC97_RECORD_VIDEO 0x02#define AC97_RECORD_AUX 0x03#define AC97_RECORD_MONO_MUX 0x02#define AC97_RECORD_DIGITAL 0x03#define AC97_RECORD_LINE 0x04#define AC97_RECORD_STEREO 0x05#define AC97_RECORD_MONO 0x06#define AC97_RECORD_PHONE 0x07/*#define AC97_RECORD_GAIN 0x1C*/#define AC97_RECORD_VOL_M 0x0F/*#define AC97_GENERAL_PURPOSE 0x20*/#define AC97_POWER_DOWN_CTRL 0x26#define AC97_ADC_READY 0x0001
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -