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

📄 ens1370.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	unsigned int ctrl;	/* control register */	unsigned int sctrl;	/* serial control register */	unsigned int cssr;	/* control status register */	unsigned int uartc;	/* uart control register */	unsigned int rev;	/* chip revision */	union {#ifdef CHIP1371		struct {			struct snd_ac97 *ac97;		} es1371;#else		struct {			int pclkdiv_lock;			struct snd_ak4531 *ak4531;		} es1370;#endif	} u;	struct pci_dev *pci;	struct snd_card *card;	struct snd_pcm *pcm1;	/* DAC1/ADC PCM */	struct snd_pcm *pcm2;	/* DAC2 PCM */	struct snd_pcm_substream *playback1_substream;	struct snd_pcm_substream *playback2_substream;	struct snd_pcm_substream *capture_substream;	unsigned int p1_dma_size;	unsigned int p2_dma_size;	unsigned int c_dma_size;	unsigned int p1_period_size;	unsigned int p2_period_size;	unsigned int c_period_size;	struct snd_rawmidi *rmidi;	struct snd_rawmidi_substream *midi_input;	struct snd_rawmidi_substream *midi_output;	unsigned int spdif;	unsigned int spdif_default;	unsigned int spdif_stream;#ifdef CHIP1370	struct snd_dma_buffer dma_bug;#endif#ifdef SUPPORT_JOYSTICK	struct gameport *gameport;#endif};static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id);static struct pci_device_id snd_audiopci_ids[] = {#ifdef CHIP1370	{ 0x1274, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },	/* ES1370 */#endif#ifdef CHIP1371	{ 0x1274, 0x1371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },	/* ES1371 */	{ 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },	/* ES1373 - CT5880 */	{ 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },	/* Ectiva EV1938 */#endif	{ 0, }};MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);/* *  constants */#define POLL_COUNT	0xa000#ifdef CHIP1370static unsigned int snd_es1370_fixed_rates[] =	{5512, 11025, 22050, 44100};static struct snd_pcm_hw_constraint_list snd_es1370_hw_constraints_rates = {	.count = 4, 	.list = snd_es1370_fixed_rates,	.mask = 0,};static struct snd_ratnum es1370_clock = {	.num = ES_1370_SRCLOCK,	.den_min = 29, 	.den_max = 353,	.den_step = 1,};static struct snd_pcm_hw_constraint_ratnums snd_es1370_hw_constraints_clock = {	.nrats = 1,	.rats = &es1370_clock,};#elsestatic struct snd_ratden es1371_dac_clock = {	.num_min = 3000 * (1 << 15),	.num_max = 48000 * (1 << 15),	.num_step = 3000,	.den = 1 << 15,};static struct snd_pcm_hw_constraint_ratdens snd_es1371_hw_constraints_dac_clock = {	.nrats = 1,	.rats = &es1371_dac_clock,};static struct snd_ratnum es1371_adc_clock = {	.num = 48000 << 15,	.den_min = 32768, 	.den_max = 393216,	.den_step = 1,};static struct snd_pcm_hw_constraint_ratnums snd_es1371_hw_constraints_adc_clock = {	.nrats = 1,	.rats = &es1371_adc_clock,};#endifstatic const unsigned int snd_ensoniq_sample_shift[] =	{0, 1, 1, 2};/* *  common I/O routines */#ifdef CHIP1371static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq){	unsigned int t, r = 0;	for (t = 0; t < POLL_COUNT; t++) {		r = inl(ES_REG(ensoniq, 1371_SMPRATE));		if ((r & ES_1371_SRC_RAM_BUSY) == 0)			return r;		cond_resched();	}	snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n",		   ES_REG(ensoniq, 1371_SMPRATE), r);	return 0;}static unsigned int snd_es1371_src_read(struct ensoniq * ensoniq, unsigned short reg){	unsigned int temp, i, orig, r;	/* wait for ready */	temp = orig = snd_es1371_wait_src_ready(ensoniq);	/* expose the SRC state bits */	r = temp & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |		    ES_1371_DIS_P2 | ES_1371_DIS_R1);	r |= ES_1371_SRC_RAM_ADDRO(reg) | 0x10000;	outl(r, ES_REG(ensoniq, 1371_SMPRATE));	/* now, wait for busy and the correct time to read */	temp = snd_es1371_wait_src_ready(ensoniq);		if ((temp & 0x00870000) != 0x00010000) {		/* wait for the right state */		for (i = 0; i < POLL_COUNT; i++) {			temp = inl(ES_REG(ensoniq, 1371_SMPRATE));			if ((temp & 0x00870000) == 0x00010000)				break;		}	}	/* hide the state bits */		r = orig & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |		   ES_1371_DIS_P2 | ES_1371_DIS_R1);	r |= ES_1371_SRC_RAM_ADDRO(reg);	outl(r, ES_REG(ensoniq, 1371_SMPRATE));		return temp;}static void snd_es1371_src_write(struct ensoniq * ensoniq,				 unsigned short reg, unsigned short data){	unsigned int r;	r = snd_es1371_wait_src_ready(ensoniq) &	    (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |	     ES_1371_DIS_P2 | ES_1371_DIS_R1);	r |= ES_1371_SRC_RAM_ADDRO(reg) | ES_1371_SRC_RAM_DATAO(data);	outl(r | ES_1371_SRC_RAM_WE, ES_REG(ensoniq, 1371_SMPRATE));}#endif /* CHIP1371 */#ifdef CHIP1370static void snd_es1370_codec_write(struct snd_ak4531 *ak4531,				   unsigned short reg, unsigned short val){	struct ensoniq *ensoniq = ak4531->private_data;	unsigned long end_time = jiffies + HZ / 10;#if 0	printk("CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x\n",	       reg, val, ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));#endif	do {		if (!(inl(ES_REG(ensoniq, STATUS)) & ES_1370_CSTAT)) {			outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));			return;		}		schedule_timeout_uninterruptible(1);	} while (time_after(end_time, jiffies));	snd_printk(KERN_ERR "codec write timeout, status = 0x%x\n",		   inl(ES_REG(ensoniq, STATUS)));}#endif /* CHIP1370 */#ifdef CHIP1371static void snd_es1371_codec_write(struct snd_ac97 *ac97,				   unsigned short reg, unsigned short val){	struct ensoniq *ensoniq = ac97->private_data;	unsigned int t, x;	mutex_lock(&ensoniq->src_mutex);	for (t = 0; t < POLL_COUNT; t++) {		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {			/* save the current state for latter */			x = snd_es1371_wait_src_ready(ensoniq);			outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |			           ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,			     ES_REG(ensoniq, 1371_SMPRATE));			/* wait for not busy (state 0) first to avoid			   transition states */			for (t = 0; t < POLL_COUNT; t++) {				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==				    0x00000000)					break;			}			/* wait for a SAFE time to write addr/data and then do it, dammit */			for (t = 0; t < POLL_COUNT; t++) {				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==				    0x00010000)					break;			}			outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC));			/* restore SRC reg */			snd_es1371_wait_src_ready(ensoniq);			outl(x, ES_REG(ensoniq, 1371_SMPRATE));			mutex_unlock(&ensoniq->src_mutex);			return;		}	}	mutex_unlock(&ensoniq->src_mutex);	snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n",		   ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));}static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,					    unsigned short reg){	struct ensoniq *ensoniq = ac97->private_data;	unsigned int t, x, fail = 0;      __again:	mutex_lock(&ensoniq->src_mutex);	for (t = 0; t < POLL_COUNT; t++) {		if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) {			/* save the current state for latter */			x = snd_es1371_wait_src_ready(ensoniq);			outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 |			           ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000,			     ES_REG(ensoniq, 1371_SMPRATE));			/* wait for not busy (state 0) first to avoid			   transition states */			for (t = 0; t < POLL_COUNT; t++) {				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==				    0x00000000)					break;			}			/* wait for a SAFE time to write addr/data and then do it, dammit */			for (t = 0; t < POLL_COUNT; t++) {				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==				    0x00010000)					break;			}			outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC));			/* restore SRC reg */			snd_es1371_wait_src_ready(ensoniq);			outl(x, ES_REG(ensoniq, 1371_SMPRATE));			/* wait for WIP again */			for (t = 0; t < POLL_COUNT; t++) {				if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP))					break;					}			/* now wait for the stinkin' data (RDY) */			for (t = 0; t < POLL_COUNT; t++) {				if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) {					mutex_unlock(&ensoniq->src_mutex);					return ES_1371_CODEC_READ(x);				}			}			mutex_unlock(&ensoniq->src_mutex);			if (++fail > 10) {				snd_printk(KERN_ERR "codec read timeout (final) "					   "at 0x%lx, reg = 0x%x [0x%x]\n",					   ES_REG(ensoniq, 1371_CODEC), reg,					   inl(ES_REG(ensoniq, 1371_CODEC)));				return 0;			}			goto __again;		}	}	mutex_unlock(&ensoniq->src_mutex);	snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n",		   ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));	return 0;}static void snd_es1371_codec_wait(struct snd_ac97 *ac97){	msleep(750);	snd_es1371_codec_read(ac97, AC97_RESET);	snd_es1371_codec_read(ac97, AC97_VENDOR_ID1);	snd_es1371_codec_read(ac97, AC97_VENDOR_ID2);	msleep(50);}static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate){	unsigned int n, truncm, freq, result;	mutex_lock(&ensoniq->src_mutex);	n = rate / 3000;	if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))		n--;	truncm = (21 * n - 1) | 1;	freq = ((48000UL << 15) / rate) * n;	result = (48000UL << 15) / (freq / n);	if (rate >= 24000) {		if (truncm > 239)			truncm = 239;		snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,				(((239 - truncm) >> 1) << 9) | (n << 4));	} else {		if (truncm > 119)			truncm = 119;		snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,				0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));	}	snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,			     (snd_es1371_src_read(ensoniq, ES_SMPREG_ADC +						  ES_SMPREG_INT_REGS) & 0x00ff) |			     ((freq >> 5) & 0xfc00));	snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8);	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8);	mutex_unlock(&ensoniq->src_mutex);}static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate){	unsigned int freq, r;	mutex_lock(&ensoniq->src_mutex);	freq = ((rate << 15) + 1500) / 3000;	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |						   ES_1371_DIS_P2 | ES_1371_DIS_R1)) |		ES_1371_DIS_P1;	outl(r, ES_REG(ensoniq, 1371_SMPRATE));	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS,			     (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC1 +						  ES_SMPREG_INT_REGS) & 0x00ff) |			     ((freq >> 5) & 0xfc00));	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |						   ES_1371_DIS_P2 | ES_1371_DIS_R1));	outl(r, ES_REG(ensoniq, 1371_SMPRATE));	mutex_unlock(&ensoniq->src_mutex);}static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate){	unsigned int freq, r;	mutex_lock(&ensoniq->src_mutex);	freq = ((rate << 15) + 1500) / 3000;	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |						   ES_1371_DIS_P1 | ES_1371_DIS_R1)) |		ES_1371_DIS_P2;	outl(r, ES_REG(ensoniq, 1371_SMPRATE));	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS,			     (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC2 +						  ES_SMPREG_INT_REGS) & 0x00ff) |			     ((freq >> 5) & 0xfc00));	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC,			     freq & 0x7fff);	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |						   ES_1371_DIS_P1 | ES_1371_DIS_R1));	outl(r, ES_REG(ensoniq, 1371_SMPRATE));	mutex_unlock(&ensoniq->src_mutex);

⌨️ 快捷键说明

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