ite8172.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,258 行 · 第 1/4 页

C
2,258
字号
/* *      ite8172.c  --  ITE IT8172G Sound Driver. * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. *         	stevel@mvista.com or source@mvista.com * *  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  SOFTWARE  IS PROVIDED   ``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  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. * *  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. * * * Module command line parameters: * *  Supported devices: *  /dev/dsp    standard OSS /dev/dsp device *  /dev/mixer  standard OSS /dev/mixer device * * Notes: * *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are *     taken, slightly modified or not at all, from the ES1371 driver, *     so refer to the credits in es1371.c for those. The rest of the *     code (probe, open, read, write, the ISR, etc.) is new. *  2. The following support is untested: *      * Memory mapping the audio buffers, and the ioctl controls that go *        with it. *      * S/PDIF output. *      * I2S support. *  3. The following is not supported: *      * legacy audio mode. *  4. Support for volume button interrupts is implemented but doesn't *     work yet. * *  Revision history *    02.08.2001  Initial release *    06.22.2001  Added I2S support *    07.30.2003  Removed initialisation to zero for static variables *		   (spdif[NR_DEVICE], i2s_fmt[NR_DEVICE], and devindex) */#include <linux/module.h>#include <linux/string.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/init.h>#include <linux/poll.h>#include <linux/bitops.h>#include <linux/proc_fs.h>#include <linux/spinlock.h>#include <linux/smp_lock.h>#include <linux/ac97_codec.h>#include <linux/interrupt.h>#include <asm/io.h>#include <asm/dma.h>#include <asm/uaccess.h>#include <asm/it8172/it8172.h>/* --------------------------------------------------------------------- */#undef OSS_DOCUMENTED_MIXER_SEMANTICS#define IT8172_DEBUG#undef IT8172_VERBOSE_DEBUG#define DBG(x) {}#define IT8172_MODULE_NAME "IT8172 audio"#define PFX IT8172_MODULE_NAME#ifdef IT8172_DEBUG#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)#else#define dbg(format, arg...) do {} while (0)#endif#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)static const unsigned sample_shift[] = { 0, 1, 1, 2 };/* * Audio Controller register bit definitions follow. See * include/asm/it8172/it8172.h for register offsets. *//* PCM Out Volume Reg */#define PCMOV_PCMOM	(1<<15)	/* PCM Out Mute default 1: mute */#define	PCMOV_PCMRCG_BIT 8	/* PCM Right channel Gain */#define	PCMOV_PCMRCG_MASK (0x1f<<PCMOV_PCMRCG_BIT)#define PCMOV_PCMLCG_BIT 0	/* PCM Left channel gain  */#define PCMOV_PCMLCG_MASK 0x1f/* FM Out Volume Reg */#define FMOV_FMOM       (1<<15)	/* FM Out Mute default 1: mute */#define	FMOV_FMRCG_BIT	8	/* FM Right channel Gain */#define	FMOV_FMRCG_MASK (0x1f<<FMOV_FMRCG_BIT)#define FMOV_FMLCG_BIT	0	/* FM Left channel gain  */#define FMOV_FMLCG_MASK 0x1f/* I2S Out Volume Reg */#define I2SV_I2SOM	 (1<<15) /* I2S Out Mute default 1: mute */#define	I2SV_I2SRCG_BIT	 8	 /* I2S Right channel Gain */#define	I2SV_I2SRCG_MASK (0x1f<<I2SV_I2SRCG_BIT)#define I2SV_I2SLCG_BIT	 0	 /* I2S Left channel gain  */#define I2SV_I2SLCG_MASK 0x1f/* Digital Recording Source Select Reg */#define	DRSS_BIT   0#define	DRSS_MASK  0x07#define   DRSS_AC97_PRIM 0#define   DRSS_FM        1#define   DRSS_I2S       2#define   DRSS_PCM       3#define   DRSS_AC97_SEC  4/* Playback/Capture Channel Control Registers */#define	CC_SM	        (1<<15)	/* Stereo, Mone 0: mono 1: stereo */#define	CC_DF	        (1<<14)	/* Data Format 0: 8 bit 1: 16 bit */#define CC_FMT_BIT      14#define CC_FMT_MASK     (0x03<<CC_FMT_BIT)#define CC_CF_BIT       12      /* Channel format (Playback only) */#define CC_CF_MASK      (0x03<<CC_CF_BIT)#define	  CC_CF_2	0#define   CC_CF_4	(1<<CC_CF_BIT)#define   CC_CF_6	(2<<CC_CF_BIT)#define CC_SR_BIT       8       /* sample Rate */#define CC_SR_MASK      (0x0f<<CC_SR_BIT)#define	  CC_SR_5500	0#define	  CC_SR_8000	(1<<CC_SR_BIT)#define	  CC_SR_9600	(2<<CC_SR_BIT)#define	  CC_SR_11025	(3<<CC_SR_BIT)#define	  CC_SR_16000	(4<<CC_SR_BIT)#define	  CC_SR_19200	(5<<CC_SR_BIT)#define	  CC_SR_22050	(6<<CC_SR_BIT)#define	  CC_SR_32000	(7<<CC_SR_BIT)#define	  CC_SR_38400	(8<<CC_SR_BIT)#define	  CC_SR_44100	(9<<CC_SR_BIT)#define	  CC_SR_48000	(10<<CC_SR_BIT)#define	CC_CSP	        (1<<7)	/* Channel stop 				 * 0: End of Current buffer				 * 1: Immediately stop when rec stop */#define CC_CP	        (1<<6)	/* Channel pause 0: normal, 1: pause */#define	CC_CA	        (1<<5)	/* Channel Action 0: Stop , 1: start */#define	CC_CB2L         (1<<2)	/* Cur. buf. 2 xfr is last 0: No, 1: Yes */#define CC_CB1L         (1<<1)	/* Cur. buf. 1 xfr is last 0: No, 1: Yes */#define CC_DE	        1	/* DFC/DFIFO Data Empty 1: empty, 0: not empty				 * (Playback only)				 *//* Codec Control Reg */#define CODECC_GME	(1<<9)	/* AC97 GPIO Mode enable */#define	CODECC_ATM	(1<<8)	/* AC97 ATE test mode 0: test 1: normal */#define	CODECC_WR	(1<<6)	/* AC97 Warn reset 1: warm reset , 0: Normal */#define	CODECC_CR	(1<<5)	/* AC97 Cold reset 1: Cold reset , 0: Normal *//* I2S Control Reg	*/#define	I2SMC_SR_BIT	 6	/* I2S Sampling rate 				 * 00: 48KHz, 01: 44.1 KHz, 10: 32 32 KHz */#define	I2SMC_SR_MASK    (0x03<<I2SMC_SR_BIT)#define	  I2SMC_SR_48000 0#define	  I2SMC_SR_44100 (1<<I2SMC_SR_BIT)#define	  I2SMC_SR_32000 (2<<I2SMC_SR_BIT)#define	I2SMC_SRSS	 (1<<5)	/* Sample Rate Source Select 1:S/W, 0: H/W */#define I2SMC_I2SF_BIT	 0	/* I2S Format */#define I2SMC_I2SF_MASK  0x03#define   I2SMC_I2SF_DAC 0#define   I2SMC_I2SF_ADC 2#define   I2SMC_I2SF_I2S 3/* Volume up, Down, Mute */#define	VS_VMP	(1<<2)	/* Volume mute 1: pushed, 0: not */#define	VS_VDP	(1<<1)	/* Volume Down 1: pushed, 0: not */#define VS_VUP	1	/* Volime Up 1: pushed, 0: not *//* SRC, Mixer test control/DFC status reg */#define SRCS_DPUSC      (1<<5)	/* DFC Playback underrun Status/clear */#define	SRCS_DCOSC	(1<<4)	/* DFC Capture Overrun Status/clear */#define SRCS_SIS	(1<<3)	/* SRC input select 1: Mixer, 0: Codec I/F */#define SRCS_CDIS_BIT	0	/* Codec Data Input Select */#define SRCS_CDIS_MASK  0x07#define   SRCS_CDIS_MIXER 0#define   SRCS_CDIS_PCM   1#define   SRCS_CDIS_I2S   2#define   SRCS_CDIS_FM    3#define   SRCS_CDIS_DFC   4/* Codec Index Reg command Port */#define CIRCP_CID_BIT   10#define CIRCP_CID_MASK  (0x03<<CIRCP_CID_BIT)#define CIRCP_CPS	(1<<9)	/* Command Port Status 0: ready, 1: busy */#define	CIRCP_DPVF	(1<<8)	/* Data Port Valid Flag 0: invalis, 1: valid */#define CIRCP_RWC	(1<<7)	/* Read/write command */#define CIRCP_CIA_BIT   0#define CIRCP_CIA_MASK  0x007F	/* Codec Index Address *//* Test Mode Control/Test group Select Control *//* General Control Reg */#define GC_VDC_BIT	6	/* Volume Division Control */#define GC_VDC_MASK     (0x03<<GC_VDC_BIT)#define   GC_VDC_NONE   0#define   GC_VDC_DIV2   (1<<GC_VDC_BIT)#define   GC_VDC_DIV4   (2<<GC_VDC_BIT)#define	GC_SOE	        (1<<2)	/* S/PDIF Output enable */#define	GC_SWR	        1	/* Software warn reset *//* Interrupt mask Control Reg */#define	IMC_VCIM	(1<<6)	/* Volume CNTL interrupt mask */#define	IMC_CCIM	(1<<1)	/* Capture Chan. iterrupt mask */#define	IMC_PCIM	1	/* Playback Chan. interrupt mask *//* Interrupt status/clear reg */#define	ISC_VCI	        (1<<6)	/* Volume CNTL interrupt 1: clears */#define	ISC_CCI	        (1<<1)	/* Capture Chan. interrupt 1: clears  */#define	ISC_PCI	        1	/* Playback Chan. interrupt 1: clears *//* misc stuff */#define POLL_COUNT   0x5000/* --------------------------------------------------------------------- *//* * Define DIGITAL1 as the I2S channel, since it is not listed in * soundcard.h. */#define SOUND_MIXER_I2S        SOUND_MIXER_DIGITAL1#define SOUND_MASK_I2S         SOUND_MASK_DIGITAL1#define SOUND_MIXER_READ_I2S   MIXER_READ(SOUND_MIXER_I2S)#define SOUND_MIXER_WRITE_I2S  MIXER_WRITE(SOUND_MIXER_I2S)/* --------------------------------------------------------------------- */struct it8172_state {	/* list of it8172 devices */	struct list_head devs;	/* the corresponding pci_dev structure */	struct pci_dev *dev;	/* soundcore stuff */	int dev_audio;	/* hardware resources */	unsigned long io;	unsigned int irq;	/* PCI ID's */	u16 vendor;	u16 device;	u8 rev; /* the chip revision */	/* options */	int spdif_volume; /* S/PDIF output is enabled if != -1 */	int i2s_volume;   /* current I2S out volume, in OSS format */	int i2s_recording;/* 1 = recording from I2S, 0 = not */    #ifdef IT8172_DEBUG	/* debug /proc entry */	struct proc_dir_entry *ps;	struct proc_dir_entry *ac97_ps;#endif /* IT8172_DEBUG */	struct ac97_codec *codec;	unsigned short pcc, capcc;	unsigned dacrate, adcrate;	spinlock_t lock;	struct semaphore open_sem;	mode_t open_mode;	wait_queue_head_t open_wait;	struct dmabuf {		void *rawbuf;		dma_addr_t dmaaddr;		unsigned buforder;		unsigned numfrag;		unsigned fragshift;		void* nextIn;		void* nextOut;		int count;		int curBufPtr;		unsigned total_bytes;		unsigned error; /* over/underrun */		wait_queue_head_t wait;		/* redundant, but makes calculations easier */		unsigned fragsize;		unsigned dmasize;		unsigned fragsamples;		/* OSS stuff */		unsigned mapped:1;		unsigned ready:1;		unsigned stopped:1;		unsigned ossfragshift;		int ossmaxfrags;		unsigned subdivision;	} dma_dac, dma_adc;};/* --------------------------------------------------------------------- */static LIST_HEAD(devs);/* --------------------------------------------------------------------- */static inline unsigned ld2(unsigned int x){	unsigned r = 0;		if (x >= 0x10000) {		x >>= 16;		r += 16;	}	if (x >= 0x100) {		x >>= 8;		r += 8;	}	if (x >= 0x10) {		x >>= 4;		r += 4;	}	if (x >= 4) {		x >>= 2;		r += 2;	}	if (x >= 2)		r++;	return r;}/* --------------------------------------------------------------------- */static void it8172_delay(int msec){	unsigned long tmo;	signed long tmo2;	if (in_interrupt())		return;    	tmo = jiffies + (msec*HZ)/1000;	for (;;) {		tmo2 = tmo - jiffies;		if (tmo2 <= 0)			break;		schedule_timeout(tmo2);	}}static unsigned shortget_compat_rate(unsigned* rate){	unsigned rate_out = *rate;	unsigned short sr;    	if (rate_out >= 46050) {		sr = CC_SR_48000; rate_out = 48000;	} else if (rate_out >= 41250) {		sr = CC_SR_44100; rate_out = 44100;	} else if (rate_out >= 35200) {		sr = CC_SR_38400; rate_out = 38400;	} else if (rate_out >= 27025) {		sr = CC_SR_32000; rate_out = 32000;	} else if (rate_out >= 20625) {		sr = CC_SR_22050; rate_out = 22050;	} else if (rate_out >= 17600) {		sr = CC_SR_19200; rate_out = 19200;	} else if (rate_out >= 13513) {		sr = CC_SR_16000; rate_out = 16000;	} else if (rate_out >= 10313) {		sr = CC_SR_11025; rate_out = 11025;	} else if (rate_out >= 8800) {		sr = CC_SR_9600; rate_out = 9600;	} else if (rate_out >= 6750) {		sr = CC_SR_8000; rate_out = 8000;	} else {		sr = CC_SR_5500; rate_out = 5500;	}	*rate = rate_out;	return sr;}static void set_adc_rate(struct it8172_state *s, unsigned rate){	unsigned long flags;	unsigned short sr;    	sr = get_compat_rate(&rate);	spin_lock_irqsave(&s->lock, flags);	s->capcc &= ~CC_SR_MASK;	s->capcc |= sr;	outw(s->capcc, s->io+IT_AC_CAPCC);	spin_unlock_irqrestore(&s->lock, flags);	s->adcrate = rate;}static void set_dac_rate(struct it8172_state *s, unsigned rate){	unsigned long flags;	unsigned short sr;    	sr = get_compat_rate(&rate);	spin_lock_irqsave(&s->lock, flags);	s->pcc &= ~CC_SR_MASK;	s->pcc |= sr;	outw(s->pcc, s->io+IT_AC_PCC);	spin_unlock_irqrestore(&s->lock, flags);	s->dacrate = rate;}/* --------------------------------------------------------------------- */static u16 rdcodec(struct ac97_codec *codec, u8 addr){	struct it8172_state *s = (struct it8172_state *)codec->private_data;	unsigned long flags;	unsigned short circp, data;	int i;    	spin_lock_irqsave(&s->lock, flags);	for (i = 0; i < POLL_COUNT; i++)		if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))			break;	if (i == POLL_COUNT)		err("rdcodec: codec ready poll expired!");	circp = addr & CIRCP_CIA_MASK;	circp |= (codec->id << CIRCP_CID_BIT);	circp |= CIRCP_RWC; // read command	outw(circp, s->io+IT_AC_CIRCP);	/* now wait for the data */	for (i = 0; i < POLL_COUNT; i++)		if (inw(s->io+IT_AC_CIRCP) & CIRCP_DPVF)			break;	if (i == POLL_COUNT)		err("rdcodec: read poll expired!");	data = inw(s->io+IT_AC_CIRDP);	spin_unlock_irqrestore(&s->lock, flags);	return data;}static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data){	struct it8172_state *s = (struct it8172_state *)codec->private_data;	unsigned long flags;	unsigned short circp;	int i;    	spin_lock_irqsave(&s->lock, flags);	for (i = 0; i < POLL_COUNT; i++)		if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))			break;	if (i == POLL_COUNT)		err("wrcodec: codec ready poll expired!");	circp = addr & CIRCP_CIA_MASK;	circp |= (codec->id << CIRCP_CID_BIT);	circp &= ~CIRCP_RWC; // write command	outw(data,  s->io+IT_AC_CIRDP);  // send data first	outw(circp, s->io+IT_AC_CIRCP);	spin_unlock_irqrestore(&s->lock, flags);}static void waitcodec(struct ac97_codec *codec){	unsigned short temp;	/* codec_wait is used to wait for a ready state after	   an AC97_RESET. */	it8172_delay(10);	temp = rdcodec(codec, 0x26);	// If power down, power up	if (temp & 0x3f00) {		// Power on		wrcodec(codec, 0x26, 0);		it8172_delay(100);		// Reread		temp = rdcodec(codec, 0x26);	}    	// Check if Codec REF,ANL,DAC,ADC ready***/	if ((temp & 0x3f0f) != 0x000f) {		err("codec reg 26 status (0x%x) not ready!!", temp);		return;	}}/* --------------------------------------------------------------------- */static inline void stop_adc(struct it8172_state *s){	struct dmabuf* db = &s->dma_adc;	unsigned long flags;	unsigned char imc;    	if (db->stopped)		return;	spin_lock_irqsave(&s->lock, flags);	s->capcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);	s->capcc |= CC_CSP;	outw(s->capcc, s->io+IT_AC_CAPCC);    	// disable capture interrupt	imc = inb(s->io+IT_AC_IMC);	outb(imc | IMC_CCIM, s->io+IT_AC_IMC);	db->stopped = 1;	spin_unlock_irqrestore(&s->lock, flags);}	static inline void stop_dac(struct it8172_state *s){	struct dmabuf* db = &s->dma_dac;	unsigned long flags;	unsigned char imc;    	if (db->stopped)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?