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

📄 trident_main.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 5 页
字号:
     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_foldback_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 && 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_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;	unsigned long flags;	spin_lock_irqsave(&trident->reg_lock, flags);	/* 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);	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;	/* set up capture channel */	outb(((voice->number & 0x3f) | 0x80), TRID_REG(trident, T4D_RCI + voice->foldback_chan));	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) - 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 */		evoice->Attribute = 0;		snd_trident_write_voice_regs(trident, evoice);	}	spin_unlock_irqrestore(&trident->reg_lock, flags);	return 0;}/*---------------------------------------------------------------------------   snd_trident_spdif_hw_params     Description: Set the hardware parameters for the spdif device.     Parameters:  substream  - PCM substream class		hw_params  - hardware parameters     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_spdif_hw_params(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;	unsigned long flags;	unsigned int old_bits = 0, change = 0;	int err;	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)		return err;	if (err > 0 && trident->tlb.entries) {		if (voice->memblk)			snd_trident_free_pages(trident, voice->memblk);		spin_lock_irqsave(&trident->reg_lock, flags);		voice->memblk = snd_trident_alloc_pages(trident, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);		spin_unlock_irqrestore(&trident->reg_lock, flags);		if (voice->memblk == NULL)			return -ENOMEM;	}	/* prepare SPDIF channel */	spin_lock_irqsave(&trident->reg_lock, flags);	old_bits = trident->spdif_pcm_bits;	if (old_bits & IEC958_AES0_PROFESSIONAL)		trident->spdif_pcm_bits &= ~IEC958_AES0_PRO_FS;	else		trident->spdif_pcm_bits &= ~(IEC958_AES3_CON_FS << 24);	if (params_rate(hw_params) >= 48000) {		trident->spdif_pcm_ctrl = 0x3c;	// 48000 Hz		trident->spdif_pcm_bits |=			trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?				IEC958_AES0_PRO_FS_48000 :				(IEC958_AES3_CON_FS_48000 << 24);	}	else if (params_rate(hw_params) >= 44100) {		trident->spdif_pcm_ctrl = 0x3e;	// 44100 Hz		trident->spdif_pcm_bits |=			trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?				IEC958_AES0_PRO_FS_44100 :				(IEC958_AES3_CON_FS_44100 << 24);	}	else {		trident->spdif_pcm_ctrl = 0x3d;	// 32000 Hz		trident->spdif_pcm_bits |=			trident->spdif_bits & IEC958_AES0_PROFESSIONAL ?				IEC958_AES0_PRO_FS_32000 :				(IEC958_AES3_CON_FS_32000 << 24);	}	change = old_bits != trident->spdif_pcm_bits;	spin_unlock_irqrestore(&trident->reg_lock, flags);	if (change)		snd_ctl_notify(trident->card, SNDRV_CTL_EVENT_MASK_VALUE, &trident->spdif_pcm_ctl->id);	return 0;}/*---------------------------------------------------------------------------   snd_trident_spdif_hw_free     Description: Release the hardware resources for the spdif device.     Parameters:  substream  - PCM substream class     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_spdif_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;	if (trident->tlb.entries && voice && voice->memblk) {		snd_trident_free_pages(trident, voice->memblk);		voice->memblk = NULL;	}	snd_pcm_lib_free_pages(substream);	return 0;}/*---------------------------------------------------------------------------   snd_trident_spdif_prepare     Description: Prepare SPDIF device for playback.     Parameters:  substream  - PCM substream class     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_spdif_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 RESO, LBAO;	unsigned long flags;	spin_lock_irqsave(&trident->reg_lock, flags);		/* 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 Back Address */	LBAO = runtime->dma_addr;	if (voice->memblk)		voice->LBA = voice->memblk->offset;	else		voice->LBA = LBAO;	/* set target ESO for channel */	RESO = runtime->buffer_size - 1;	voice->ESO = (runtime->period_size * 2) - 1;	/* set ctrl mode */	voice->CTRL = snd_trident_control_mode(substream);	voice->FMC = 3;	voice->RVol = 0x7f;	voice->CVol = 0x7f;	voice->GVSel = 1;	voice->Pan = 0x7f;	voice->Vol = 0x3ff;	voice->EC = 0;	voice->CSO = 0;	voice->Alpha = 0;	voice->FMS = 0;	voice->Attribute = 0;	/* prepare surrogate IRQ channel */	snd_trident_write_voice_regs(trident, voice);	outw((RESO & 0xffff), TRID_REG(trident, NX_SPESO));	outb((RESO >> 16), TRID_REG(trident, NX_SPESO + 2));	outl((LBAO & 0xfffffffc), TRID_REG(trident, NX_SPLBA));	outw((voice->CSO & 0xffff), TRID_REG(trident, NX_SPCTRL_SPCSO));	outb((voice->CSO >> 16), TRID_REG(trident, NX_SPCTRL_SPCSO + 2));	/* set SPDIF setting */	outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));	outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));	spin_unlock_irqrestore(&trident->reg_lock, flags);	return 0;}/*---------------------------------------------------------------------------   snd_trident_trigger     Description: Start/stop devices     Parameters:  substream  - PCM substream class   		cmd	- trigger command (STOP, GO)     Returns:     Error status    ---------------------------------------------------------------------------*/static int snd_trident_trigger(snd_pcm_substream_t *substream,			       int cmd)				    {	trident_t *trident = snd_pcm_substream_chip(substream);	snd_pcm_substream_t *s;	unsigned int what, whati, capture_flag, spdif_flag;	snd_trident_voice_t *voice, *evoice;	unsigned int val, go;	switch (cmd) {	case SNDRV_PCM_TRIGGER_START:	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:	case SNDRV_PCM_TRIGGER_RESUME:		go = 1;		break;	case SNDRV_PCM_TRIGGER_STOP:	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:	case SNDRV_PCM_TRIGGER_SUSPEND:		go = 0;		break;	default:		return -EINVAL;	}	what = whati = capture_flag = spdif_flag = 0;	s = substream;	spin_lock(&trident->reg_lock);	val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;	do {		if ((trident_t *) _snd_pcm_chip(s->pcm) == trident) {			voice = (snd_trident_voice_t *) s->runtime->private_data;			evoice = voice->extra;			what |= 1 << (voice->number & 0x1f);			if (evoice == NULL) {				whati |= 1 << (voice->number & 0x1f);			} else {				what |= 1 << (evoice->number & 0x1f);				whati |= 1 << (evoice->number & 0x1f);			}			if (go) {				voice->running = 1;				voice->stimer = val;			} else {				voice->running = 0;			}			snd_pcm_trigger_done(s, substream);			if (voice->capture)				capture_flag = 1;			if (voice->spdif)				spdif_flag = 1;		}		s = s->link_next;	} while (s != substream);	if (spdif_flag) {		outl(trident->spdif_pcm_bits, TRID_REG(trident, NX_SPCSTATUS));		outb(trident->spdif_pcm_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3));	}	if (!go)		outl(what, TRID_REG(trident, T4D_STOP_B));	val = inl(TRID_REG(trident, T4D_AINTEN_B));	if (go) {		val |= whati;	} else {		val &= ~whati;	}	outl(val, TRID_REG(trident, T4D_AINTEN_B));	if (go) {		outl(what, TRID_REG(trident, T4D_START_B));				if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)			outb(trident->bDMAStart, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));	} else {		if (capture_flag && trident->device != TRIDENT_DEVICE_ID_SI7018)			outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));	}	spin_unlock(&trident->reg_lock);	return 0;}/*---------------------------------------------------------------------------   snd_trident_playback_pointer     Description: This routine return the playback position                   Parameters:	substream  - PCM substream class   Returns:     position of buffer    ---------------------------------------------------------------------------*/static snd_pcm_uframes_t snd_trident_playback_pointer(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 cso;	if (!voice->running)		return 0;	spin_lock(&trident->reg_lock);	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));	if (trident->device != TRIDENT_DEVICE_ID_NX) {		cso = inw(TRID_REG(trident, CH_DX_CSO_ALPHA_FMS + 2));	} else {		// ID_4DWAVE_NX		cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff;	}	if (++cso > runtime->buffer_size)		cso = runtime->buffer_size;	spin_unlock(&trident->reg_lock);	return cso;}/*---------------------------------------------------------------------------   snd_trident_capture_pointer     Description: This routine return the capture position                   Paramters:   pcm1    - PCM device class   Returns:     position of buffer    ---------------------------------------------------------------------------*/static snd_pcm_uframes_t snd_trident_capture_pointer(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 result;	if (!voice->running)

⌨️ 快捷键说明

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