📄 i810_audio.c
字号:
/* * Intel i810 and friends ICH driver for Linux * Alan Cox <alan@redhat.com> * * Built from: * Low level code: Zach Brown (original nonworking i810 OSS driver) * Jaroslav Kysela <perex@suse.cz> (working ALSA driver) * * Framework: Thomas Sailer <sailer@ife.ee.ethz.ch> * Extended by: Zach Brown <zab@redhat.com> * and others.. * * Hardware Provided By: * Analog Devices (A major AC97 codec maker) * Intel Corp (you've probably heard of them already) * * AC97 clues and assistance provided by * Analog Devices * Zach 'Fufu' Brown * Jeff Garzik * * 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. * * * Intel 810 theory of operation * * The chipset provides three DMA channels that talk to an AC97 * CODEC (AC97 is a digital/analog mixer standard). At its simplest * you get 48Khz audio with basic volume and mixer controls. At the * best you get rate adaption in the codec. We set the card up so * that we never take completion interrupts but instead keep the card * chasing its tail around a ring buffer. This is needed for mmap * mode audio and happens to work rather well for non-mmap modes too. * * The board has one output channel for PCM audio (supported) and * a stereo line in and mono microphone input. Again these are normally * locked to 48Khz only. Right now recording is not finished. * * There is no midi support, no synth support. Use timidity. To get * esd working you need to use esd -r 48000 as it won't probe 48KHz * by default. mpg123 can't handle 48Khz only audio so use xmms. * * Fix The Sound On Dell * * Not everyone uses 48KHz. We know of no way to detect this reliably * and certainly not to get the right data. If your i810 audio sounds * stupid you may need to investigate other speeds. According to Analog * they tend to use a 14.318MHz clock which gives you a base rate of * 41194Hz. * * This is available via the 'ftsodell=1' option. * * If you need to force a specific rate set the clocking= option * * This driver is cursed. (Ben LaHaise) * * ICH 3 caveats * Intel errata #7 for ICH3 IO. We need to disable SMI stuff * when codec probing. [Not Yet Done] * * ICH 4 caveats * * The ICH4 has the feature, that the codec ID doesn't have to be * congruent with the IO connection. * * Therefore, from driver version 0.23 on, there is a "codec ID" <-> * "IO register base offset" mapping (card->ac97_id_map) field. * * Juergen "George" Sawinski (jsaw) */ #include <linux/module.h>#include <linux/string.h>#include <linux/ctype.h>#include <linux/ioport.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/sound.h>#include <linux/slab.h>#include <linux/soundcard.h>#include <linux/pci.h>#include <linux/interrupt.h>#include <asm/io.h>#include <asm/dma.h>#include <linux/init.h>#include <linux/poll.h>#include <linux/spinlock.h>#include <linux/smp_lock.h>#include <linux/ac97_codec.h>#include <linux/bitops.h>#include <asm/uaccess.h>#define DRIVER_VERSION "1.01"#define MODULOP2(a, b) ((a) & ((b) - 1))#define MASKP2(a, b) ((a) & ~((b) - 1))static int ftsodell;static int strict_clocking;static unsigned int clocking;static int spdif_locked;static int ac97_quirk = AC97_TUNE_DEFAULT;//#define DEBUG//#define DEBUG2//#define DEBUG_INTERRUPTS//#define DEBUG_MMAP//#define DEBUG_MMIO#define ADC_RUNNING 1#define DAC_RUNNING 2#define I810_FMT_16BIT 1#define I810_FMT_STEREO 2#define I810_FMT_MASK 3#define SPDIF_ON 0x0004#define SURR_ON 0x0010#define CENTER_LFE_ON 0x0020#define VOL_MUTED 0x8000/* the 810's array of pointers to data buffers */struct sg_item {#define BUSADDR_MASK 0xFFFFFFFE u32 busaddr; #define CON_IOC 0x80000000 /* interrupt on completion */#define CON_BUFPAD 0x40000000 /* pad underrun with last sample, else 0 */#define CON_BUFLEN_MASK 0x0000ffff /* buffer length in samples */ u32 control;};/* an instance of the i810 channel */#define SG_LEN 32struct i810_channel { /* these sg guys should probably be allocated separately as nocache. Must be 8 byte aligned */ struct sg_item sg[SG_LEN]; /* 32*8 */ u32 offset; /* 4 */ u32 port; /* 4 */ u32 used; u32 num;};/* * we have 3 separate dma engines. pcm in, pcm out, and mic. * each dma engine has controlling registers. These goofy * names are from the datasheet, but make it easy to write * code while leafing through it. * * ICH4 has 6 dma engines, pcm in, pcm out, mic, pcm in 2, * mic in 2, s/pdif. Of special interest is the fact that * the upper 3 DMA engines on the ICH4 *must* be accessed * via mmio access instead of pio access. */#define ENUM_ENGINE(PRE,DIG) \enum { \ PRE##_BASE = 0x##DIG##0, /* Base Address */ \ PRE##_BDBAR = 0x##DIG##0, /* Buffer Descriptor list Base Address */ \ PRE##_CIV = 0x##DIG##4, /* Current Index Value */ \ PRE##_LVI = 0x##DIG##5, /* Last Valid Index */ \ PRE##_SR = 0x##DIG##6, /* Status Register */ \ PRE##_PICB = 0x##DIG##8, /* Position In Current Buffer */ \ PRE##_PIV = 0x##DIG##a, /* Prefetched Index Value */ \ PRE##_CR = 0x##DIG##b /* Control Register */ \}ENUM_ENGINE(OFF,0); /* Offsets */ENUM_ENGINE(PI,0); /* PCM In */ENUM_ENGINE(PO,1); /* PCM Out */ENUM_ENGINE(MC,2); /* Mic In */enum { GLOB_CNT = 0x2c, /* Global Control */ GLOB_STA = 0x30, /* Global Status */ CAS = 0x34 /* Codec Write Semaphore Register */};ENUM_ENGINE(MC2,4); /* Mic In 2 */ENUM_ENGINE(PI2,5); /* PCM In 2 */ENUM_ENGINE(SP,6); /* S/PDIF */enum { SDM = 0x80 /* SDATA_IN Map Register */};/* interrupts for a dma engine */#define DMA_INT_FIFO (1<<4) /* fifo under/over flow */#define DMA_INT_COMPLETE (1<<3) /* buffer read/write complete and ioc set */#define DMA_INT_LVI (1<<2) /* last valid done */#define DMA_INT_CELV (1<<1) /* last valid is current */#define DMA_INT_DCH (1) /* DMA Controller Halted (happens on LVI interrupts) */#define DMA_INT_MASK (DMA_INT_FIFO|DMA_INT_COMPLETE|DMA_INT_LVI)/* interrupts for the whole chip */#define INT_SEC (1<<11)#define INT_PRI (1<<10)#define INT_MC (1<<7)#define INT_PO (1<<6)#define INT_PI (1<<5)#define INT_MO (1<<2)#define INT_NI (1<<1)#define INT_GPI (1<<0)#define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI)/* magic numbers to protect our data structures */#define I810_CARD_MAGIC 0x5072696E /* "Prin" */#define I810_STATE_MAGIC 0x63657373 /* "cess" */#define I810_DMA_MASK 0xffffffff /* DMA buffer mask for pci_alloc_consist */#define NR_HW_CH 3/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */#define NR_AC97 4/* Please note that an 8bit mono stream is not valid on this card, you must have a 16bit *//* stream at a minimum for this card to be happy */static const unsigned sample_size[] = { 1, 2, 2, 4 };/* Samples are 16bit values, so we are shifting to a word, not to a byte, hence shift *//* values are one less than might be expected */static const unsigned sample_shift[] = { -1, 0, 0, 1 };enum { ICH82801AA = 0, ICH82901AB, INTEL440MX, INTELICH2, INTELICH3, INTELICH4, INTELICH5, SI7012, NVIDIA_NFORCE, AMD768, AMD8111};static char * card_names[] = { "Intel ICH 82801AA", "Intel ICH 82901AB", "Intel 440MX", "Intel ICH2", "Intel ICH3", "Intel ICH4", "Intel ICH5", "SiS 7012", "NVIDIA nForce Audio", "AMD 768", "AMD-8111 IOHub"};/* These are capabilities (and bugs) the chipsets _can_ have */static struct { int16_t nr_ac97;#define CAP_MMIO 0x0001#define CAP_20BIT_AUDIO_SUPPORT 0x0002 u_int16_t flags;} card_cap[] = { { 1, 0x0000 }, /* ICH82801AA */ { 1, 0x0000 }, /* ICH82901AB */ { 1, 0x0000 }, /* INTEL440MX */ { 1, 0x0000 }, /* INTELICH2 */ { 2, 0x0000 }, /* INTELICH3 */ { 3, 0x0003 }, /* INTELICH4 */ { 3, 0x0003 }, /* INTELICH5 */ /*@FIXME to be verified*/ { 2, 0x0000 }, /* SI7012 */ /*@FIXME to be verified*/ { 2, 0x0000 }, /* NVIDIA_NFORCE */ /*@FIXME to be verified*/ { 2, 0x0000 }, /* AMD768 */ /*@FIXME to be verified*/ { 3, 0x0001 }, /* AMD8111 */};static struct pci_device_id i810_pci_tbl [] = { {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ICH82801AA}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ICH82901AB}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_440MX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTEL440MX}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH2}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH3}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH5}, {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SI7012}, {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD768}, {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD8111}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4}, {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, {0,}};MODULE_DEVICE_TABLE (pci, i810_pci_tbl);#ifdef CONFIG_PM#define PM_SUSPENDED(card) (card->pm_suspended)#else#define PM_SUSPENDED(card) (0)#endif/* "software" or virtual channel, an instance of opened /dev/dsp */struct i810_state { unsigned int magic; struct i810_card *card; /* Card info */ /* single open lock mechanism, only used for recording */ struct semaphore open_sem; wait_queue_head_t open_wait; /* file mode */ mode_t open_mode; /* virtual channel number */ int virt;#ifdef CONFIG_PM unsigned int pm_saved_dac_rate,pm_saved_adc_rate;#endif struct dmabuf { /* wave sample stuff */ unsigned int rate; unsigned char fmt, enable, trigger; /* hardware channel */ struct i810_channel *read_channel; struct i810_channel *write_channel; /* OSS buffer management stuff */ void *rawbuf; dma_addr_t dma_handle; unsigned buforder; unsigned numfrag; unsigned fragshift; /* our buffer acts like a circular ring */ unsigned hwptr; /* where dma last started, updated by update_ptr */ unsigned swptr; /* where driver last clear/filled, updated by read/write */ int count; /* bytes to be consumed or been generated by dma machine */ unsigned total_bytes; /* total bytes dmaed by hardware */ unsigned error; /* number of over/underruns */ wait_queue_head_t wait; /* put process on wait queue when no more space in buffer */ /* redundant, but makes calculations easier */ /* what the hardware uses */ unsigned dmasize; unsigned fragsize; unsigned fragsamples; /* what we tell the user to expect */ unsigned userfrags; unsigned userfragsize; /* OSS stuff */ unsigned mapped:1; unsigned ready:1; unsigned update_flag; unsigned ossfragsize; unsigned ossmaxfrags; unsigned subdivision; } dmabuf;};struct i810_card { unsigned int magic; /* We keep i810 cards in a linked list */ struct i810_card *next; /* The i810 has a certain amount of cross channel interaction so we use a single per card lock */ spinlock_t lock; /* Control AC97 access serialization */ spinlock_t ac97_lock; /* PCI device stuff */ struct pci_dev * pci_dev; u16 pci_id; u16 pci_id_internal; /* used to access card_cap[] */#ifdef CONFIG_PM u16 pm_suspended; int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97];#endif /* soundcore stuff */ int dev_audio; /* structures for abstraction of hardware facilities, codecs, banks and channels*/ u16 ac97_id_map[NR_AC97]; struct ac97_codec *ac97_codec[NR_AC97]; struct i810_state *states[NR_HW_CH]; struct i810_channel *channel; /* 1:1 to states[] but diff. lifetime */ dma_addr_t chandma; u16 ac97_features; u16 ac97_status; u16 channels; /* hardware resources */ unsigned long ac97base; unsigned long iobase; u32 irq; unsigned long ac97base_mmio_phys; unsigned long iobase_mmio_phys; u_int8_t __iomem *ac97base_mmio; u_int8_t __iomem *iobase_mmio; int use_mmio; /* Function support */ struct i810_channel *(*alloc_pcm_channel)(struct i810_card *); struct i810_channel *(*alloc_rec_pcm_channel)(struct i810_card *); struct i810_channel *(*alloc_rec_mic_channel)(struct i810_card *); void (*free_pcm_channel)(struct i810_card *, int chan); /* We have a *very* long init time possibly, so use this to block */ /* attempts to open our devices before we are ready (stops oops'es) */ int initializing;};/* extract register offset from codec struct */#define IO_REG_OFF(codec) (((struct i810_card *) codec->private_data)->ac97_id_map[codec->id])#define I810_IOREAD(size, type, card, off) \({ \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -