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

📄 ens1370.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 {			ac97_t *ac97;		} es1371;#else		struct {			int pclkdiv_lock;			ak4531_t *ak4531;		} es1370;#endif	} u;	struct pci_dev *pci;	unsigned short subsystem_vendor_id;	unsigned short subsystem_device_id;	snd_card_t *card;	snd_pcm_t *pcm1;	/* DAC1/ADC PCM */	snd_pcm_t *pcm2;	/* DAC2 PCM */	snd_pcm_substream_t *playback1_substream;	snd_pcm_substream_t *playback2_substream;	snd_pcm_substream_t *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;	snd_rawmidi_t *rmidi;	snd_rawmidi_substream_t *midi_input;	snd_rawmidi_substream_t *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, struct pt_regs *regs);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 snd_pcm_hw_constraint_list_t snd_es1370_hw_constraints_rates = {	.count = 4, 	.list = snd_es1370_fixed_rates,	.mask = 0,};static ratnum_t es1370_clock = {	.num = ES_1370_SRCLOCK,	.den_min = 29, 	.den_max = 353,	.den_step = 1,};static snd_pcm_hw_constraint_ratnums_t snd_es1370_hw_constraints_clock = {	.nrats = 1,	.rats = &es1370_clock,};#elsestatic ratden_t es1371_dac_clock = {	.num_min = 3000 * (1 << 15),	.num_max = 48000 * (1 << 15),	.num_step = 3000,	.den = 1 << 15,};static snd_pcm_hw_constraint_ratdens_t snd_es1371_hw_constraints_dac_clock = {	.nrats = 1,	.rats = &es1371_dac_clock,};static ratnum_t es1371_adc_clock = {	.num = 48000 << 15,	.den_min = 32768, 	.den_max = 393216,	.den_step = 1,};static snd_pcm_hw_constraint_ratnums_t 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(ensoniq_t * 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;	}	snd_printk("wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);	return 0;}static unsigned int snd_es1371_src_read(ensoniq_t * 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(ensoniq_t * 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(ak4531_t *ak4531,				   unsigned short reg, unsigned short val){	ensoniq_t *ensoniq = ak4531->private_data;	unsigned long flags;	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 {		spin_lock_irqsave(&ensoniq->reg_lock, flags);		if (!(inl(ES_REG(ensoniq, STATUS)) & ES_1370_CSTAT)) {			outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));			spin_unlock_irqrestore(&ensoniq->reg_lock, flags);			return;		}		spin_unlock_irqrestore(&ensoniq->reg_lock, flags);#if 0		set_current_state(TASK_UNINTERRUPTIBLE);		schedule_timeout(1);#endif	} while (time_after(end_time, jiffies));	snd_printk("codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));}#endif /* CHIP1370 */#ifdef CHIP1371static void snd_es1371_codec_write(ac97_t *ac97,				   unsigned short reg, unsigned short val){	ensoniq_t *ensoniq = ac97->private_data;	unsigned long flags;	unsigned int t, x;	for (t = 0; t < POLL_COUNT; t++) {		spin_lock_irqsave(&ensoniq->reg_lock, flags);		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));			spin_unlock_irqrestore(&ensoniq->reg_lock, flags);			return;		}		spin_unlock_irqrestore(&ensoniq->reg_lock, flags);	}	snd_printk("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(ac97_t *ac97,					    unsigned short reg){	ensoniq_t *ensoniq = ac97->private_data;	unsigned long flags;	unsigned int t, x, fail = 0;      __again:	for (t = 0; t < POLL_COUNT; t++) {		spin_lock_irqsave(&ensoniq->reg_lock, flags);		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) {					spin_unlock_irqrestore(&ensoniq->reg_lock, flags);					return ES_1371_CODEC_READ(x);				}			}			spin_unlock_irqrestore(&ensoniq->reg_lock, flags);			if (++fail > 10) {				snd_printk("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;		}		spin_unlock_irqrestore(&ensoniq->reg_lock, flags);	}	snd_printk("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_adc_rate(ensoniq_t * ensoniq, unsigned int rate){	unsigned int n, truncm, freq, result;	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);}static void snd_es1371_dac1_rate(ensoniq_t * ensoniq, unsigned int rate){	unsigned int freq, r;	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));}static void snd_es1371_dac2_rate(ensoniq_t * ensoniq, unsigned int rate){	unsigned int freq, r;	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));}#endif /* CHIP1371 */static int snd_ensoniq_trigger(snd_pcm_substream_t *substream, int cmd){	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);	switch (cmd) {	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:	{		unsigned int what = 0;		struct list_head *pos;		snd_pcm_substream_t *s;		snd_pcm_group_for_each(pos, substream) {			s = snd_pcm_group_substream_entry(pos);			if (s == ensoniq->playback1_substream) {				what |= ES_P1_PAUSE;				snd_pcm_trigger_done(s, substream);			} else if (s == ensoniq->playback2_substream) {				what |= ES_P2_PAUSE;

⌨️ 快捷键说明

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