⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmpci.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *      cmpci.c  --  C-Media PCI audio driver. * *      Copyright (C) 1999  C-media support (support@cmedia.com.tw) * *      Based on the PCI drivers by Thomas Sailer (sailer@ife.ee.ethz.ch) * * 	For update, visit: * 		http://www.cmedia.com.tw * *      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. * * Special thanks to David C. Niemi, Jan Pfeifer * * * Module command line parameters: *   none so far * * *  Supported devices: *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible *  /dev/midi   simple MIDI UART interface, no ioctl * *  The card has both an FM and a Wavetable synth, but I have to figure *  out first how to drive them... * *  Revision history *    06.05.98   0.1   Initial release *    10.05.98   0.2   Fixed many bugs, esp. ADC rate calculation *                     First stab at a simple midi interface (no bells&whistles) *    13.05.98   0.3   Fix stupid cut&paste error: set_adc_rate was called instead of *                     set_dac_rate in the FMODE_WRITE case in cm_open *                     Fix hwptr out of bounds (now mpg123 works) *    14.05.98   0.4   Don't allow excessive interrupt rates *    08.06.98   0.5   First release using Alan Cox' soundcore instead of miscdevice *    03.08.98   0.6   Do not include modversions.h *                     Now mixer behaviour can basically be selected between *                     "OSS documented" and "OSS actual" behaviour *    31.08.98   0.7   Fix realplayer problems - dac.count issues *    10.12.98   0.8   Fix drain_dac trying to wait on not yet initialized DMA *    16.12.98   0.9   Fix a few f_file & FMODE_ bugs *    06.01.99   0.10  remove the silly SA_INTERRUPT flag. *                     hopefully killed the egcs section type conflict *    12.03.99   0.11  cinfo.blocks should be reset after GETxPTR ioctl. *                     reported by Johan Maes <joma@telindus.be> *    22.03.99   0.12  return EAGAIN instead of EBUSY when O_NONBLOCK *                     read/write cannot be executed *    18.08.99   1.5   Only deallocate DMA buffer when unloading. *    02.09.99   1.6   Enable SPDIF LOOP *                     Change the mixer read back *    21.09.99   2.33  Use RCS version as driver version. *                     Add support for modem, S/PDIF loop and 4 channels. *                     (8738 only) *                     Fix bug cause x11amp cannot play. * *    Fixes: *    Arnaldo Carvalho de Melo <acme@conectiva.com.br> *    18/05/2001 - .bss nitpicks, fix a bug in set_dac_channels where it *    		   was calling prog_dmabuf with s->lock held, call missing *    		   unlock_kernel in cm_midi_release *    08/10/2001 - use set_current_state in some more places * *	Carlos Eduardo Gorges <carlos@techlinux.com.br> *	Fri May 25 2001 *	- SMP support ( spin[un]lock* revision ) *	- speaker mixer support *	Mon Aug 13 2001 *	- optimizations and cleanups * *    03/01/2003 - open_mode fixes from Georg Acher <acher@in.tum.de> *	Simon Braunschmidt <brasimon@web.de> *     Sat Jan 31 2004 *	- provide support for opl3 FM by releasing IO range after initialization * *    ChenLi Tien <cltien@cmedia.com.tw> *    Mar 9 2004 *	- Fix S/PDIF out if spdif_loop enabled *	- Load opl3 driver if enabled (fmio in proper range) *	- Load mpu401 if enabled (mpuio in proper range) *    Apr 5 2004 *	- Fix DUAL_DAC dma synchronization bug *	- Check exist FM/MPU401 I/O before activate. *	- Add AFTM_S16_BE format support, so MPlayer/Xine can play AC3/mutlichannel *	  on Mac *	- Change to support kernel 2.6 so only small patch needed *	- All parameters default to 0 *	- Add spdif_out to send PCM through S/PDIF out jack *	- Add hw_copy to get 4-spaker output for general PCM/analog output * *    Stefan Thater <stefan.thaeter@gmx.de> *    Apr 5 2004 *	- Fix mute single channel for CD/Line-in/AUX-in *//*****************************************************************************/#include <linux/config.h>#include <linux/module.h>#include <linux/string.h>#include <linux/interrupt.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/spinlock.h>#include <linux/smp_lock.h>#include <linux/bitops.h>#include <linux/wait.h>#include <asm/io.h>#include <asm/page.h>#include <asm/uaccess.h>#ifdef CONFIG_SOUND_CMPCI_MIDI#include "sound_config.h"#include "mpu401.h"#endif#ifdef CONFIG_SOUND_CMPCI_FM#include "opl3.h"#endif#ifdef CONFIG_SOUND_CMPCI_JOYSTICK#include <linux/gameport.h>#endif/* --------------------------------------------------------------------- */#undef OSS_DOCUMENTED_MIXER_SEMANTICS#undef DMABYTEIO#define	DBG(x) {}/* --------------------------------------------------------------------- */#define CM_MAGIC  ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)/* CM8338 registers definition ****************/#define CODEC_CMI_FUNCTRL0		(0x00)#define CODEC_CMI_FUNCTRL1		(0x04)#define CODEC_CMI_CHFORMAT		(0x08)#define CODEC_CMI_INT_HLDCLR		(0x0C)#define CODEC_CMI_INT_STATUS		(0x10)#define CODEC_CMI_LEGACY_CTRL		(0x14)#define CODEC_CMI_MISC_CTRL		(0x18)#define CODEC_CMI_TDMA_POS		(0x1C)#define CODEC_CMI_MIXER			(0x20)#define CODEC_SB16_DATA			(0x22)#define CODEC_SB16_ADDR			(0x23)#define CODEC_CMI_MIXER1		(0x24)#define CODEC_CMI_MIXER2		(0x25)#define CODEC_CMI_AUX_VOL		(0x26)#define CODEC_CMI_MISC			(0x27)#define CODEC_CMI_AC97			(0x28)#define CODEC_CMI_CH0_FRAME1		(0x80)#define CODEC_CMI_CH0_FRAME2		(0x84)#define CODEC_CMI_CH1_FRAME1		(0x88)#define CODEC_CMI_CH1_FRAME2		(0x8C)#define CODEC_CMI_SPDIF_CTRL		(0x90)#define CODEC_CMI_MISC_CTRL2		(0x92)#define CODEC_CMI_EXT_REG		(0xF0)/*  Mixer registers for SB16 ******************/#define DSP_MIX_DATARESETIDX		((unsigned char)(0x00))#define DSP_MIX_MASTERVOLIDX_L		((unsigned char)(0x30))#define DSP_MIX_MASTERVOLIDX_R		((unsigned char)(0x31))#define DSP_MIX_VOICEVOLIDX_L		((unsigned char)(0x32))#define DSP_MIX_VOICEVOLIDX_R		((unsigned char)(0x33))#define DSP_MIX_FMVOLIDX_L		((unsigned char)(0x34))#define DSP_MIX_FMVOLIDX_R		((unsigned char)(0x35))#define DSP_MIX_CDVOLIDX_L		((unsigned char)(0x36))#define DSP_MIX_CDVOLIDX_R		((unsigned char)(0x37))#define DSP_MIX_LINEVOLIDX_L		((unsigned char)(0x38))#define DSP_MIX_LINEVOLIDX_R		((unsigned char)(0x39))#define DSP_MIX_MICVOLIDX		((unsigned char)(0x3A))#define DSP_MIX_SPKRVOLIDX		((unsigned char)(0x3B))#define DSP_MIX_OUTMIXIDX		((unsigned char)(0x3C))#define DSP_MIX_ADCMIXIDX_L		((unsigned char)(0x3D))#define DSP_MIX_ADCMIXIDX_R		((unsigned char)(0x3E))#define DSP_MIX_INGAINIDX_L		((unsigned char)(0x3F))#define DSP_MIX_INGAINIDX_R		((unsigned char)(0x40))#define DSP_MIX_OUTGAINIDX_L		((unsigned char)(0x41))#define DSP_MIX_OUTGAINIDX_R		((unsigned char)(0x42))#define DSP_MIX_AGCIDX			((unsigned char)(0x43))#define DSP_MIX_TREBLEIDX_L		((unsigned char)(0x44))#define DSP_MIX_TREBLEIDX_R		((unsigned char)(0x45))#define DSP_MIX_BASSIDX_L		((unsigned char)(0x46))#define DSP_MIX_BASSIDX_R		((unsigned char)(0x47))#define DSP_MIX_EXTENSION		((unsigned char)(0xf0))// pseudo register for AUX#define	DSP_MIX_AUXVOL_L		((unsigned char)(0x50))#define	DSP_MIX_AUXVOL_R		((unsigned char)(0x51))// I/O length#define CM_EXTENT_CODEC	  0x100#define CM_EXTENT_MIDI	  0x2#define CM_EXTENT_SYNTH	  0x4#define CM_EXTENT_GAME	  0x8// Function Control Register 0 (00h)#define CHADC0    	0x01#define CHADC1    	0x02#define PAUSE0	  	0x04#define PAUSE1	  	0x08// Function Control Register 0+2 (02h)#define CHEN0     	0x01#define CHEN1     	0x02#define RST_CH0	  	0x04#define RST_CH1	  	0x08// Function Control Register 1 (04h)#define JYSTK_EN	0x02#define UART_EN		0x04#define	SPDO2DAC	0x40#define	SPDFLOOP	0x80// Function Control Register 1+1 (05h)#define	SPDF_0		0x01#define	SPDF_1		0x02#define	ASFC		0x1c#define	DSFC		0xe0#define	SPDIF2DAC	(SPDF_1 << 8 | SPDO2DAC)// Channel Format Register (08h)#define CM_CFMT_STEREO	0x01#define CM_CFMT_16BIT	0x02#define CM_CFMT_MASK	0x03#define	POLVALID	0x20#define	INVSPDIFI	0x80// Channel Format Register+2 (0ah)#define SPD24SEL	0x20// Channel Format Register+3 (0bh)#define CHB3D		0x20#define CHB3D5C		0x80// Interrupt Hold/Clear Register+2 (0eh)#define	CH0_INT_EN	0x01#define	CH1_INT_EN	0x02// Interrupt Register (10h)#define CHINT0		0x01#define CHINT1		0x02#define	CH0BUSY		0x04#define	CH1BUSY		0x08// Legacy Control/Status Register+1 (15h)#define	EXBASEN		0x10#define	BASE2LIN	0x20#define	CENTR2LIN	0x40#define	CB2LIN		(BASE2LIN | CENTR2LIN)#define	CHB3D6C		0x80// Legacy Control/Status Register+2 (16h)#define	DAC2SPDO	0x20#define	SPDCOPYRHT	0x40#define	ENSPDOUT	0x80// Legacy Control/Status Register+3 (17h)#define	FMSEL		0x03#define	VSBSEL		0x0c#define	VMPU		0x60#define	NXCHG		0x80// Miscellaneous Control Register (18h)#define	REAR2LIN	0x20#define	MUTECH1		0x40#define	ENCENTER	0x80// Miscellaneous Control Register+1 (19h)#define	SELSPDIFI2	0x01#define	SPDF_AC97	0x80// Miscellaneous Control Register+2 (1ah)#define	AC3_EN		0x04#define	FM_EN		0x08#define	SPD32SEL	0x20#define	XCHGDAC		0x40#define	ENDBDAC		0x80// Miscellaneous Control Register+3 (1bh)#define	SPDIFI48K	0x01#define	SPDO5V		0x02#define	N4SPK3D		0x04#define	RESET		0x40#define	PWD		0x80#define	SPDIF48K	(SPDIFI48K << 24 | SPDF_AC97 << 8)// Mixer1 (24h)#define	CDPLAY		0x01#define	X3DEN		0x02#define	REAR2FRONT	0x10#define	SPK4		0x20#define	WSMUTE		0x40#define	FMMUTE		0x80// Miscellaneous Register (27h)#define	SPDVALID	0x02#define	CENTR2MIC	0x04// Miscellaneous Register2 (92h)#define	SPD32KFMT	0x10#define CM_CFMT_DACSHIFT   2#define CM_CFMT_ADCSHIFT   0#define CM_FREQ_DACSHIFT   5#define CM_FREQ_ADCSHIFT   2#define	RSTDAC	RST_CH1#define	RSTADC	RST_CH0#define	ENDAC	CHEN1#define	ENADC	CHEN0#define	PAUSEDAC	PAUSE1#define	PAUSEADC	PAUSE0#define CODEC_CMI_ADC_FRAME1	CODEC_CMI_CH0_FRAME1#define CODEC_CMI_ADC_FRAME2	CODEC_CMI_CH0_FRAME2#define CODEC_CMI_DAC_FRAME1	CODEC_CMI_CH1_FRAME1#define CODEC_CMI_DAC_FRAME2	CODEC_CMI_CH1_FRAME2#define	DACINT	CHINT1#define	ADCINT	CHINT0#define	DACBUSY	CH1BUSY#define	ADCBUSY	CH0BUSY#define	ENDACINT	CH1_INT_EN#define	ENADCINT	CH0_INT_ENstatic const unsigned sample_size[] = { 1, 2, 2, 4 };static const unsigned sample_shift[]	= { 0, 1, 1, 2 };#define SND_DEV_DSP16   5#define NR_DEVICE 3		/* maximum number of devices */#define	set_dac1_rate	set_adc_rate#define	set_dac1_rate_unlocked	set_adc_rate_unlocked#define	stop_dac1	stop_adc#define	stop_dac1_unlocked	stop_adc_unlocked#define	get_dmadac1	get_dmaadcstatic unsigned int devindex = 0;//*********************************************/struct cm_state {	/* magic */	unsigned int magic;	/* list of cmedia devices */	struct list_head devs;	/* the corresponding pci_dev structure */	struct pci_dev *dev;	int dev_audio;			/* soundcore stuff */	int dev_mixer;	unsigned int iosb, iobase, iosynth,			 iomidi, iogame, irq;	/* hardware resources */	unsigned short deviceid;		/* pci_id */        struct {				/* mixer stuff */                unsigned int modcnt;		unsigned short vol[13];        } mix;	unsigned int rateadc, ratedac;		/* wave stuff */	unsigned char fmt, enable;	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;		unsigned hwptr, swptr;		unsigned total_bytes;		int count;		unsigned error;		/* over/underrun */		wait_queue_head_t wait;		unsigned fragsize;	/* redundant, but makes calculations easier */		unsigned dmasize;		unsigned fragsamples;		unsigned dmasamples;		unsigned mapped:1;	/* OSS stuff */		unsigned ready:1;		unsigned endcleared:1;		unsigned enabled:1;		unsigned ossfragshift;		int ossmaxfrags;		unsigned subdivision;	} dma_dac, dma_adc;#ifdef CONFIG_SOUND_CMPCI_MIDI	int midi_devc;	struct address_info mpu_data;#endif#ifdef CONFIG_SOUND_CMPCI_JOYSTICK	struct gameport gameport;#endif	int	chip_version;	int	max_channels;	int	curr_channels;	int	capability;		/* HW capability, various for chip versions */	int	status;			/* HW or SW state */	int	spdif_counter;		/* spdif frame counter */};/* flags used for capability */#define	CAN_AC3_HW		0x00000001		/* 037 or later */#define	CAN_AC3_SW		0x00000002		/* 033 or later */#define	CAN_AC3			(CAN_AC3_HW | CAN_AC3_SW)#define CAN_DUAL_DAC		0x00000004		/* 033 or later */#define	CAN_MULTI_CH_HW		0x00000008		/* 039 or later */#define	CAN_MULTI_CH		(CAN_MULTI_CH_HW | CAN_DUAL_DAC)#define	CAN_LINE_AS_REAR	0x00000010		/* 033 or later */#define	CAN_LINE_AS_BASS	0x00000020		/* 039 or later */#define	CAN_MIC_AS_BASS		0x00000040		/* 039 or later *//* flags used for status */#define	DO_AC3_HW		0x00000001#define	DO_AC3_SW		0x00000002#define	DO_AC3			(DO_AC3_HW | DO_AC3_SW)#define	DO_DUAL_DAC		0x00000004#define	DO_MULTI_CH_HW		0x00000008

⌨️ 快捷键说明

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