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

📄 trident_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		return;	channel &= 0x1f;	if (trident->ChanMap[T4D_BANK_A] & (1 << channel)) {		trident->ChanMap[T4D_BANK_A] &= ~(1 << channel);		trident->synth.ChanSynthCount--;	}}/*---------------------------------------------------------------------------   snd_trident_write_voice_regs     Description: This routine will complete and write the 5 hardware channel                registers to hardware.     Paramters:   trident - pointer to target device class for 4DWave.                voice - synthesizer voice structure                Each register field.    ---------------------------------------------------------------------------*/void snd_trident_write_voice_regs(trident_t * trident,				  snd_trident_voice_t * voice){	unsigned int FmcRvolCvol;	unsigned int regs[5];	regs[1] = voice->LBA;	regs[4] = (voice->GVSel << 31) |		  ((voice->Pan & 0x0000007f) << 24) |		  ((voice->CTRL & 0x0000000f) << 12);	FmcRvolCvol = ((voice->FMC & 3) << 14) |	              ((voice->RVol & 0x7f) << 7) |	              (voice->CVol & 0x7f);	switch (trident->device) {	case TRIDENT_DEVICE_ID_SI7018:		regs[4] |= voice->number > 31 ?				(voice->Vol & 0x000003ff) :				((voice->Vol & 0x00003fc) << (16-2)) |				(voice->EC & 0x00000fff);		regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);		regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);		regs[3] = (voice->Attribute << 16) | FmcRvolCvol;		break;	case TRIDENT_DEVICE_ID_DX:		regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |			   (voice->EC & 0x00000fff);		regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);		regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);		regs[3] = FmcRvolCvol;		break;	case TRIDENT_DEVICE_ID_NX:		regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |			   (voice->EC & 0x00000fff);		regs[0] = (voice->Delta << 24) | (voice->CSO & 0x00ffffff);		regs[2] = ((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff);		regs[3] = (voice->Alpha << 20) | ((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol;		break;	default:		snd_BUG();		return;	}	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));	outl(regs[0], TRID_REG(trident, CH_START + 0));	outl(regs[1], TRID_REG(trident, CH_START + 4));	outl(regs[2], TRID_REG(trident, CH_START + 8));	outl(regs[3], TRID_REG(trident, CH_START + 12));	outl(regs[4], TRID_REG(trident, CH_START + 16));#if 0	printk("written %i channel:\n", voice->number);	printk("  regs[0] = 0x%x/0x%x\n", regs[0], inl(TRID_REG(trident, CH_START + 0)));	printk("  regs[1] = 0x%x/0x%x\n", regs[1], inl(TRID_REG(trident, CH_START + 4)));	printk("  regs[2] = 0x%x/0x%x\n", regs[2], inl(TRID_REG(trident, CH_START + 8)));	printk("  regs[3] = 0x%x/0x%x\n", regs[3], inl(TRID_REG(trident, CH_START + 12)));	printk("  regs[4] = 0x%x/0x%x\n", regs[4], inl(TRID_REG(trident, CH_START + 16)));#endif}/*---------------------------------------------------------------------------   snd_trident_write_cso_reg     Description: This routine will write the new CSO offset                register to hardware.     Paramters:   trident - pointer to target device class for 4DWave.                voice - synthesizer voice structure                CSO - new CSO value    ---------------------------------------------------------------------------*/static void snd_trident_write_cso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CSO){	voice->CSO = CSO;	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));	if (trident->device != TRIDENT_DEVICE_ID_NX) {		outw(voice->CSO, TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2);	} else {		outl((voice->Delta << 24) | (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO));	}}/*---------------------------------------------------------------------------   snd_trident_write_eso_reg     Description: This routine will write the new ESO offset                register to hardware.     Paramters:   trident - pointer to target device class for 4DWave.                voice - synthesizer voice structure                ESO - new ESO value    ---------------------------------------------------------------------------*/static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int ESO){	voice->ESO = ESO;	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));	if (trident->device != TRIDENT_DEVICE_ID_NX) {		outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2);	} else {		outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_ESO));	}}/*---------------------------------------------------------------------------   snd_trident_write_vol_reg     Description: This routine will write the new voice volume                register to hardware.     Paramters:   trident - pointer to target device class for 4DWave.                voice - synthesizer voice structure                Vol - new voice volume    ---------------------------------------------------------------------------*/static void snd_trident_write_vol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Vol){	voice->Vol = Vol;	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));	switch (trident->device) {	case TRIDENT_DEVICE_ID_DX:	case TRIDENT_DEVICE_ID_NX:		outb(voice->Vol >> 2, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 2));		break;	case TRIDENT_DEVICE_ID_SI7018:		// printk("voice->Vol = 0x%x\n", voice->Vol);		outw((voice->CTRL << 12) | voice->Vol, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));		break;	}}/*---------------------------------------------------------------------------   snd_trident_write_pan_reg     Description: This routine will write the new voice pan                register to hardware.     Paramters:   trident - pointer to target device class for 4DWave.                voice - synthesizer voice structure                Pan - new pan value    ---------------------------------------------------------------------------*/static void snd_trident_write_pan_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Pan){	voice->Pan = Pan;	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));	outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f), TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3));}/*---------------------------------------------------------------------------   snd_trident_write_rvol_reg     Description: This routine will write the new reverb volume                register to hardware.     Paramters:   trident - pointer to target device class for 4DWave.                voice - synthesizer voice structure                RVol - new reverb volume    ---------------------------------------------------------------------------*/static void snd_trident_write_rvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int RVol){	voice->RVol = RVol;	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));	outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),	     TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));}/*---------------------------------------------------------------------------   snd_trident_write_cvol_reg     Description: This routine will write the new chorus volume                register to hardware.     Paramters:   trident - pointer to target device class for 4DWave.                voice - synthesizer voice structure                CVol - new chorus volume    ---------------------------------------------------------------------------*/static void snd_trident_write_cvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CVol){	voice->CVol = CVol;	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));	outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),	     TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));}/*---------------------------------------------------------------------------   snd_trident_convert_rate   Description: This routine converts rate in HZ to hardware delta value.     Paramters:   trident - pointer to target device class for 4DWave.                rate - Real or Virtual channel number.     Returns:     Delta value.    ---------------------------------------------------------------------------*/static unsigned int snd_trident_convert_rate(unsigned int rate){	unsigned int delta;	// We special case 44100 and 8000 since rounding with the equation	// does not give us an accurate enough value. For 11025 and 22050	// the equation gives us the best answer. All other frequencies will	// also use the equation. JDW	if (rate == 44100)		delta = 0xeb3;	else if (rate == 8000)		delta = 0x2ab;	else if (rate == 48000)		delta = 0x1000;	else		delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff;	return delta;}/*---------------------------------------------------------------------------   snd_trident_convert_adc_rate   Description: This routine converts rate in HZ to hardware delta value.     Paramters:   trident - pointer to target device class for 4DWave.                rate - Real or Virtual channel number.     Returns:     Delta value.    ---------------------------------------------------------------------------*/static unsigned int snd_trident_convert_adc_rate(unsigned int rate){	unsigned int delta;	// We special case 44100 and 8000 since rounding with the equation	// does not give us an accurate enough value. For 11025 and 22050	// the equation gives us the best answer. All other frequencies will	// also use the equation. JDW	if (rate == 44100)		delta = 0x116a;	else if (rate == 8000)		delta = 0x6000;	else if (rate == 48000)		delta = 0x1000;	else		delta = ((48000 << 12) / rate) & 0x0000ffff;	return delta;}/*---------------------------------------------------------------------------   snd_trident_spurious_threshold   Description: This routine converts rate in HZ to spurious threshold.     Paramters:   trident - pointer to target device class for 4DWave.                rate - Real or Virtual channel number.     Returns:     Delta value.    ---------------------------------------------------------------------------*/static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size){	unsigned int res = (rate * period_size) / 48000;	if (res < 64)		res = res / 2;	else		res -= 32;	return res;}/*---------------------------------------------------------------------------   snd_trident_control_mode   Description: This routine returns a control mode for a PCM channel.     Paramters:   trident - pointer to target device class for 4DWave.                substream  - PCM substream     Returns:     Control value.    ---------------------------------------------------------------------------*/static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream){	unsigned int CTRL;	snd_pcm_runtime_t *runtime = substream->runtime;	/* set ctrl mode	   CTRL default: 8-bit (unsigned) mono, loop mode enabled	 */	CTRL = 0x00000001;	if (snd_pcm_format_width(runtime->format) == 16)		CTRL |= 0x00000008;	// 16-bit data	if (snd_pcm_format_signed(runtime->format))		CTRL |= 0x00000002;	// signed data	if (runtime->channels > 1)		CTRL |= 0x00000004;	// stereo data	return CTRL;}/* *  PCM part *//*---------------------------------------------------------------------------   snd_trident_ioctl     Description: Device I/O control handler for playback/capture parameters.     Paramters:   substream  - PCM substream class                cmd     - what ioctl message to process                arg     - additional message infoarg          Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_ioctl(snd_pcm_substream_t * substream,			     unsigned int cmd,			     void *arg){	/* FIXME: it seems that with small periods the behaviour of	          trident hardware is unpredictable and interrupt generator	          is broken */	return snd_pcm_lib_ioctl(substream, cmd, arg);}/*---------------------------------------------------------------------------   snd_trident_allocate_pcm_mem     Description: Allocate PCM ring buffer for given substream     Parameters:  substream  - PCM substream class		hw_params  - hardware parameters     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,					snd_pcm_hw_params_t * hw_params){	trident_t *trident = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;	int err;	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)		return err;	if (trident->tlb.entries) {		if (err > 0) { /* change */			if (voice->memblk)				snd_trident_free_pages(trident, voice->memblk);			voice->memblk = snd_trident_alloc_pages(trident, substream);			if (voice->memblk == NULL)				return -ENOMEM;		}	}	return 0;}/*---------------------------------------------------------------------------   snd_trident_allocate_evoice     Description: Allocate extra voice as interrupt generator     Parameters:  substream  - PCM substream class		hw_params  - hardware parameters     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,				       snd_pcm_hw_params_t * hw_params){	trident_t *trident = snd_pcm_substream_chip(substream);	snd_pcm_runtime_t *runtime = substream->runtime;	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;	snd_trident_voice_t *evoice = voice->extra;	/* voice management */	if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) {		if (evoice == NULL) {			evoice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);			if (evoice == NULL)				return -ENOMEM;			voice->extra = evoice;			evoice->substream = substream;		}

⌨️ 快捷键说明

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