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

📄 ens1370.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}#endif /* CHIP1371 */static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd){	struct ensoniq *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 snd_pcm_substream *s;		snd_pcm_group_for_each_entry(s, substream) {			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;				snd_pcm_trigger_done(s, substream);			} else if (s == ensoniq->capture_substream)				return -EINVAL;		}		spin_lock(&ensoniq->reg_lock);		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)			ensoniq->sctrl |= what;		else			ensoniq->sctrl &= ~what;		outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));		spin_unlock(&ensoniq->reg_lock);		break;	}	case SNDRV_PCM_TRIGGER_START:	case SNDRV_PCM_TRIGGER_STOP:	{		unsigned int what = 0;		struct snd_pcm_substream *s;		snd_pcm_group_for_each_entry(s, substream) {			if (s == ensoniq->playback1_substream) {				what |= ES_DAC1_EN;				snd_pcm_trigger_done(s, substream);			} else if (s == ensoniq->playback2_substream) {				what |= ES_DAC2_EN;				snd_pcm_trigger_done(s, substream);			} else if (s == ensoniq->capture_substream) {				what |= ES_ADC_EN;				snd_pcm_trigger_done(s, substream);			}		}		spin_lock(&ensoniq->reg_lock);		if (cmd == SNDRV_PCM_TRIGGER_START)			ensoniq->ctrl |= what;		else			ensoniq->ctrl &= ~what;		outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));		spin_unlock(&ensoniq->reg_lock);		break;	}	default:		return -EINVAL;	}	return 0;}/* *  PCM part */static int snd_ensoniq_hw_params(struct snd_pcm_substream *substream,				 struct snd_pcm_hw_params *hw_params){	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));}static int snd_ensoniq_hw_free(struct snd_pcm_substream *substream){	return snd_pcm_lib_free_pages(substream);}static int snd_ensoniq_playback1_prepare(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	unsigned int mode = 0;	ensoniq->p1_dma_size = snd_pcm_lib_buffer_bytes(substream);	ensoniq->p1_period_size = snd_pcm_lib_period_bytes(substream);	if (snd_pcm_format_width(runtime->format) == 16)		mode |= 0x02;	if (runtime->channels > 1)		mode |= 0x01;	spin_lock_irq(&ensoniq->reg_lock);	ensoniq->ctrl &= ~ES_DAC1_EN;#ifdef CHIP1371	/* 48k doesn't need SRC (it breaks AC3-passthru) */	if (runtime->rate == 48000)		ensoniq->ctrl |= ES_1373_BYPASS_P1;	else		ensoniq->ctrl &= ~ES_1373_BYPASS_P1;#endif	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));	outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));	outl(runtime->dma_addr, ES_REG(ensoniq, DAC1_FRAME));	outl((ensoniq->p1_dma_size >> 2) - 1, ES_REG(ensoniq, DAC1_SIZE));	ensoniq->sctrl &= ~(ES_P1_LOOP_SEL | ES_P1_PAUSE | ES_P1_SCT_RLD | ES_P1_MODEM);	ensoniq->sctrl |= ES_P1_INT_EN | ES_P1_MODEO(mode);	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));	outl((ensoniq->p1_period_size >> snd_ensoniq_sample_shift[mode]) - 1,	     ES_REG(ensoniq, DAC1_COUNT));#ifdef CHIP1370	ensoniq->ctrl &= ~ES_1370_WTSRSELM;	switch (runtime->rate) {	case 5512: ensoniq->ctrl |= ES_1370_WTSRSEL(0); break;	case 11025: ensoniq->ctrl |= ES_1370_WTSRSEL(1); break;	case 22050: ensoniq->ctrl |= ES_1370_WTSRSEL(2); break;	case 44100: ensoniq->ctrl |= ES_1370_WTSRSEL(3); break;	default: snd_BUG();	}#endif	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));	spin_unlock_irq(&ensoniq->reg_lock);#ifndef CHIP1370	snd_es1371_dac1_rate(ensoniq, runtime->rate);#endif	return 0;}static int snd_ensoniq_playback2_prepare(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	unsigned int mode = 0;	ensoniq->p2_dma_size = snd_pcm_lib_buffer_bytes(substream);	ensoniq->p2_period_size = snd_pcm_lib_period_bytes(substream);	if (snd_pcm_format_width(runtime->format) == 16)		mode |= 0x02;	if (runtime->channels > 1)		mode |= 0x01;	spin_lock_irq(&ensoniq->reg_lock);	ensoniq->ctrl &= ~ES_DAC2_EN;	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));	outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));	outl(runtime->dma_addr, ES_REG(ensoniq, DAC2_FRAME));	outl((ensoniq->p2_dma_size >> 2) - 1, ES_REG(ensoniq, DAC2_SIZE));	ensoniq->sctrl &= ~(ES_P2_LOOP_SEL | ES_P2_PAUSE | ES_P2_DAC_SEN |			    ES_P2_END_INCM | ES_P2_ST_INCM | ES_P2_MODEM);	ensoniq->sctrl |= ES_P2_INT_EN | ES_P2_MODEO(mode) |			  ES_P2_END_INCO(mode & 2 ? 2 : 1) | ES_P2_ST_INCO(0);	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));	outl((ensoniq->p2_period_size >> snd_ensoniq_sample_shift[mode]) - 1,	     ES_REG(ensoniq, DAC2_COUNT));#ifdef CHIP1370	if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_CAPTURE)) {		ensoniq->ctrl &= ~ES_1370_PCLKDIVM;		ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));		ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_PLAY2;	}#endif	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));	spin_unlock_irq(&ensoniq->reg_lock);#ifndef CHIP1370	snd_es1371_dac2_rate(ensoniq, runtime->rate);#endif	return 0;}static int snd_ensoniq_capture_prepare(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	unsigned int mode = 0;	ensoniq->c_dma_size = snd_pcm_lib_buffer_bytes(substream);	ensoniq->c_period_size = snd_pcm_lib_period_bytes(substream);	if (snd_pcm_format_width(runtime->format) == 16)		mode |= 0x02;	if (runtime->channels > 1)		mode |= 0x01;	spin_lock_irq(&ensoniq->reg_lock);	ensoniq->ctrl &= ~ES_ADC_EN;	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));	outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));	outl(runtime->dma_addr, ES_REG(ensoniq, ADC_FRAME));	outl((ensoniq->c_dma_size >> 2) - 1, ES_REG(ensoniq, ADC_SIZE));	ensoniq->sctrl &= ~(ES_R1_LOOP_SEL | ES_R1_MODEM);	ensoniq->sctrl |= ES_R1_INT_EN | ES_R1_MODEO(mode);	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));	outl((ensoniq->c_period_size >> snd_ensoniq_sample_shift[mode]) - 1,	     ES_REG(ensoniq, ADC_COUNT));#ifdef CHIP1370	if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_PLAY2)) {		ensoniq->ctrl &= ~ES_1370_PCLKDIVM;		ensoniq->ctrl |= ES_1370_PCLKDIVO(ES_1370_SRTODIV(runtime->rate));		ensoniq->u.es1370.pclkdiv_lock |= ES_MODE_CAPTURE;	}#endif	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));	spin_unlock_irq(&ensoniq->reg_lock);#ifndef CHIP1370	snd_es1371_adc_rate(ensoniq, runtime->rate);#endif	return 0;}static snd_pcm_uframes_t snd_ensoniq_playback1_pointer(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	size_t ptr;	spin_lock(&ensoniq->reg_lock);	if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC1_EN) {		outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));		ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC1_SIZE)));		ptr = bytes_to_frames(substream->runtime, ptr);	} else {		ptr = 0;	}	spin_unlock(&ensoniq->reg_lock);	return ptr;}static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	size_t ptr;	spin_lock(&ensoniq->reg_lock);	if (inl(ES_REG(ensoniq, CONTROL)) & ES_DAC2_EN) {		outl(ES_MEM_PAGEO(ES_PAGE_DAC), ES_REG(ensoniq, MEM_PAGE));		ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, DAC2_SIZE)));		ptr = bytes_to_frames(substream->runtime, ptr);	} else {		ptr = 0;	}	spin_unlock(&ensoniq->reg_lock);	return ptr;}static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	size_t ptr;	spin_lock(&ensoniq->reg_lock);	if (inl(ES_REG(ensoniq, CONTROL)) & ES_ADC_EN) {		outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));		ptr = ES_REG_FCURR_COUNTI(inl(ES_REG(ensoniq, ADC_SIZE)));		ptr = bytes_to_frames(substream->runtime, ptr);	} else {		ptr = 0;	}	spin_unlock(&ensoniq->reg_lock);	return ptr;}static struct snd_pcm_hardware snd_ensoniq_playback1 ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER |				 SNDRV_PCM_INFO_MMAP_VALID |				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =#ifndef CHIP1370				SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,#else				(SNDRV_PCM_RATE_KNOT | 	/* 5512Hz rate */				 SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050 | 				 SNDRV_PCM_RATE_44100),#endif	.rate_min =		4000,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};static struct snd_pcm_hardware snd_ensoniq_playback2 ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER |				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | 				 SNDRV_PCM_INFO_SYNC_START),	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,	.rate_min =		4000,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};static struct snd_pcm_hardware snd_ensoniq_capture ={	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |				 SNDRV_PCM_INFO_BLOCK_TRANSFER |				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,	.rate_min =		4000,	.rate_max =		48000,	.channels_min =		1,	.channels_max =		2,	.buffer_bytes_max =	(128*1024),	.period_bytes_min =	64,	.period_bytes_max =	(128*1024),	.periods_min =		1,	.periods_max =		1024,	.fifo_size =		0,};static int snd_ensoniq_playback1_open(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	ensoniq->mode |= ES_MODE_PLAY1;	ensoniq->playback1_substream = substream;	runtime->hw = snd_ensoniq_playback1;	snd_pcm_set_sync(substream);	spin_lock_irq(&ensoniq->reg_lock);	if (ensoniq->spdif && ensoniq->playback2_substream == NULL)		ensoniq->spdif_stream = ensoniq->spdif_default;	spin_unlock_irq(&ensoniq->reg_lock);#ifdef CHIP1370	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				   &snd_es1370_hw_constraints_rates);#else	snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				      &snd_es1371_hw_constraints_dac_clock);#endif	return 0;}static int snd_ensoniq_playback2_open(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	ensoniq->mode |= ES_MODE_PLAY2;	ensoniq->playback2_substream = substream;	runtime->hw = snd_ensoniq_playback2;	snd_pcm_set_sync(substream);	spin_lock_irq(&ensoniq->reg_lock);	if (ensoniq->spdif && ensoniq->playback1_substream == NULL)		ensoniq->spdif_stream = ensoniq->spdif_default;	spin_unlock_irq(&ensoniq->reg_lock);#ifdef CHIP1370	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				      &snd_es1370_hw_constraints_clock);#else	snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				      &snd_es1371_hw_constraints_dac_clock);#endif	return 0;}static int snd_ensoniq_capture_open(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	struct snd_pcm_runtime *runtime = substream->runtime;	ensoniq->mode |= ES_MODE_CAPTURE;	ensoniq->capture_substream = substream;	runtime->hw = snd_ensoniq_capture;	snd_pcm_set_sync(substream);#ifdef CHIP1370	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				      &snd_es1370_hw_constraints_clock);#else	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,				      &snd_es1371_hw_constraints_adc_clock);#endif	return 0;}static int snd_ensoniq_playback1_close(struct snd_pcm_substream *substream){	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);	ensoniq->playback1_substream = NULL;	ensoniq->mode &= ~ES_MODE_PLAY1;	return 0;

⌨️ 快捷键说明

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