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

📄 trident_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	} else {		if (evoice != NULL) {			snd_trident_free_voice(trident, evoice);			voice->extra = evoice = NULL;		}	}	return 0;}/*---------------------------------------------------------------------------   snd_trident_hw_params     Description: Set the hardware parameters for the playback device.     Parameters:  substream  - PCM substream class		hw_params  - hardware parameters     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_hw_params(snd_pcm_substream_t * substream,				 snd_pcm_hw_params_t * hw_params){	int err;	err = snd_trident_allocate_pcm_mem(substream, hw_params);	if (err >= 0)		err = snd_trident_allocate_evoice(substream, hw_params);	return err;}/*---------------------------------------------------------------------------   snd_trident_playback_hw_free     Description: Release the hardware resources for the playback device.     Parameters:  substream  - PCM substream class     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_hw_free(snd_pcm_substream_t * substream){	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 ? voice->extra : NULL;	if (trident->tlb.entries) {		if (voice && voice->memblk) {			snd_trident_free_pages(trident, voice->memblk);			voice->memblk = NULL;		}	}	snd_pcm_lib_free_pages(substream);	if (evoice != NULL) {		snd_trident_free_voice(trident, evoice);		voice->extra = NULL;	}	return 0;}/*---------------------------------------------------------------------------   snd_trident_playback_prepare     Description: Prepare playback device for playback.     Parameters:  substream  - PCM substream class     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_playback_prepare(snd_pcm_substream_t * substream){	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;	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number];	spin_lock_irq(&trident->reg_lock);		/* set delta (rate) value */	voice->Delta = snd_trident_convert_rate(runtime->rate);	voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);	/* set Loop Begin Address */	if (voice->memblk)		voice->LBA = voice->memblk->offset;	else		voice->LBA = runtime->dma_addr; 	voice->CSO = 0;	voice->ESO = runtime->buffer_size - 1;	/* in samples */	voice->CTRL = snd_trident_control_mode(substream);	voice->FMC = 3;	voice->GVSel = 1;	voice->EC = 0;	voice->Alpha = 0;	voice->FMS = 0;	voice->Vol = mix->vol;	voice->RVol = mix->rvol;	voice->CVol = mix->cvol;	voice->Pan = mix->pan;	voice->Attribute = 0;#if 0	voice->Attribute = (1<<(30-16))|(2<<(26-16))|			   (0<<(24-16))|(0x1f<<(19-16));#else	voice->Attribute = 0;#endif	snd_trident_write_voice_regs(trident, voice);	if (evoice != NULL) {		evoice->Delta = voice->Delta;		evoice->spurious_threshold = voice->spurious_threshold;		evoice->LBA = voice->LBA;		evoice->CSO = 0;		evoice->ESO = (runtime->period_size * 2) + 4 - 1; /* in samples */		evoice->CTRL = voice->CTRL;		evoice->FMC = 3;		evoice->GVSel = trident->device == TRIDENT_DEVICE_ID_SI7018 ? 0 : 1;		evoice->EC = 0;		evoice->Alpha = 0;		evoice->FMS = 0;		evoice->Vol = 0x3ff;			/* mute */		evoice->RVol = evoice->CVol = 0x7f;	/* mute */		evoice->Pan = 0x7f;			/* mute */#if 0		evoice->Attribute = (1<<(30-16))|(2<<(26-16))|				    (0<<(24-16))|(0x1f<<(19-16));#else		evoice->Attribute = 0;#endif		snd_trident_write_voice_regs(trident, evoice);		evoice->isync2 = 1;		evoice->isync_mark = runtime->period_size;		evoice->ESO = (runtime->period_size * 2) - 1;	}	spin_unlock_irq(&trident->reg_lock);	return 0;}/*---------------------------------------------------------------------------   snd_trident_capture_hw_params     Description: Set the hardware parameters for the capture device.     Parameters:  substream  - PCM substream class		hw_params  - hardware parameters     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_capture_hw_params(snd_pcm_substream_t * substream,					 snd_pcm_hw_params_t * hw_params){	return snd_trident_allocate_pcm_mem(substream, hw_params);}/*---------------------------------------------------------------------------   snd_trident_capture_prepare     Description: Prepare capture device for playback.     Parameters:  substream  - PCM substream class     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_capture_prepare(snd_pcm_substream_t * substream){	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;	unsigned int val, ESO_bytes;	spin_lock_irq(&trident->reg_lock);	// Initilize the channel and set channel Mode	outb(0, TRID_REG(trident, LEGACY_DMAR15));	// Set DMA channel operation mode register	outb(0x54, TRID_REG(trident, LEGACY_DMAR11));	// Set channel buffer Address, DMAR0 expects contiguous PCI memory area		voice->LBA = runtime->dma_addr;	outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));	if (voice->memblk)		voice->LBA = voice->memblk->offset;	// set ESO	ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1;	outb((ESO_bytes & 0x00ff0000) >> 16, TRID_REG(trident, LEGACY_DMAR6));	outw((ESO_bytes & 0x0000ffff), TRID_REG(trident, LEGACY_DMAR4));	ESO_bytes++;	// Set channel sample rate, 4.12 format	val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate;	outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R));	// Set channel interrupt blk length	if (snd_pcm_format_width(runtime->format) == 16) {		val = (unsigned short) ((ESO_bytes >> 1) - 1);	} else {		val = (unsigned short) (ESO_bytes - 1);	}	outl((val << 16) | val, TRID_REG(trident, T4D_SBBL_SBCL));	// Right now, set format and start to run captureing, 	// continuous run loop enable.	trident->bDMAStart = 0x19;	// 0001 1001b	if (snd_pcm_format_width(runtime->format) == 16)		trident->bDMAStart |= 0x80;	if (snd_pcm_format_signed(runtime->format))		trident->bDMAStart |= 0x20;	if (runtime->channels > 1)		trident->bDMAStart |= 0x40;	// Prepare capture intr channel	voice->Delta = snd_trident_convert_rate(runtime->rate);	voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);	voice->isync = 1;	voice->isync_mark = runtime->period_size;	voice->isync_max = runtime->buffer_size;	// Set voice parameters	voice->CSO = 0;	voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 6 - 1;	voice->CTRL = snd_trident_control_mode(substream);	voice->FMC = 3;	voice->RVol = 0x7f;	voice->CVol = 0x7f;	voice->GVSel = 1;	voice->Pan = 0x7f;		/* mute */	voice->Vol = 0x3ff;		/* mute */	voice->EC = 0;	voice->Alpha = 0;	voice->FMS = 0;	voice->Attribute = 0;	snd_trident_write_voice_regs(trident, voice);	spin_unlock_irq(&trident->reg_lock);	return 0;}/*---------------------------------------------------------------------------   snd_trident_si7018_capture_hw_params     Description: Set the hardware parameters for the capture device.     Parameters:  substream  - PCM substream class		hw_params  - hardware parameters     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_si7018_capture_hw_params(snd_pcm_substream_t * substream,						snd_pcm_hw_params_t * hw_params){	int err;	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)		return err;	return snd_trident_allocate_evoice(substream, hw_params);}/*---------------------------------------------------------------------------   snd_trident_si7018_capture_hw_free     Description: Release the hardware resources for the capture device.     Parameters:  substream  - PCM substream class     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_si7018_capture_hw_free(snd_pcm_substream_t * substream){	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 ? voice->extra : NULL;	snd_pcm_lib_free_pages(substream);	if (evoice != NULL) {		snd_trident_free_voice(trident, evoice);		voice->extra = NULL;	}	return 0;}/*---------------------------------------------------------------------------   snd_trident_si7018_capture_prepare     Description: Prepare capture device for playback.     Parameters:  substream  - PCM substream class     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream){	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;	spin_lock_irq(&trident->reg_lock);	voice->LBA = runtime->dma_addr;	voice->Delta = snd_trident_convert_adc_rate(runtime->rate);	voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size);	// Set voice parameters	voice->CSO = 0;	voice->ESO = runtime->buffer_size - 1;		/* in samples */	voice->CTRL = snd_trident_control_mode(substream);	voice->FMC = 0;	voice->RVol = 0;	voice->CVol = 0;	voice->GVSel = 1;	voice->Pan = T4D_DEFAULT_PCM_PAN;	voice->Vol = 0;	voice->EC = 0;	voice->Alpha = 0;	voice->FMS = 0;	voice->Attribute = (2 << (30-16)) |			   (2 << (26-16)) |			   (2 << (24-16)) |			   (1 << (23-16));	snd_trident_write_voice_regs(trident, voice);	if (evoice != NULL) {		evoice->Delta = snd_trident_convert_rate(runtime->rate);		evoice->spurious_threshold = voice->spurious_threshold;		evoice->LBA = voice->LBA;		evoice->CSO = 0;		evoice->ESO = (runtime->period_size * 2) + 20 - 1; /* in samples, 20 means correction */		evoice->CTRL = voice->CTRL;		evoice->FMC = 3;		evoice->GVSel = 0;		evoice->EC = 0;		evoice->Alpha = 0;		evoice->FMS = 0;		evoice->Vol = 0x3ff;			/* mute */		evoice->RVol = evoice->CVol = 0x7f;	/* mute */		evoice->Pan = 0x7f;			/* mute */		evoice->Attribute = 0;		snd_trident_write_voice_regs(trident, evoice);		evoice->isync2 = 1;		evoice->isync_mark = runtime->period_size;		evoice->ESO = (runtime->period_size * 2) - 1;	}		spin_unlock_irq(&trident->reg_lock);	return 0;}/*---------------------------------------------------------------------------   snd_trident_foldback_prepare     Description: Prepare foldback capture device for playback.     Parameters:  substream  - PCM substream class     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream){	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;	spin_lock_irq(&trident->reg_lock);	/* Set channel buffer Address */	if (voice->memblk)		voice->LBA = voice->memblk->offset;	else		voice->LBA = runtime->dma_addr;	/* set target ESO for channel */	voice->ESO = runtime->buffer_size - 1;	/* in samples */	/* set sample rate */	voice->Delta = 0x1000;	voice->spurious_threshold = snd_trident_spurious_threshold(48000, runtime->period_size);	voice->CSO = 0;	voice->CTRL = snd_trident_control_mode(substream);

⌨️ 快捷键说明

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