emufx.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 1,794 行 · 第 1/5 页

C
1,794
字号
	down(&emu->fx8010.lock);	if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)		goto __error;	strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));	/* stop FX processor - this may be dangerous, but it's better to miss	   some samples than generate wrong ones - [jk] */	if (emu->audigy)		snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);	else		snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);	/* ok, do the main job */	snd_emu10k1_del_controls(emu, icode);	snd_emu10k1_gpr_poke(emu, icode);	snd_emu10k1_tram_poke(emu, icode);	snd_emu10k1_code_poke(emu, icode);	snd_emu10k1_add_controls(emu, icode);	/* start FX processor when the DSP code is updated */	if (emu->audigy)		snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);	else		snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);      __error:	up(&emu->fx8010.lock);	return err;}static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode){	int err;	down(&emu->fx8010.lock);	strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));	/* ok, do the main job */	snd_emu10k1_gpr_peek(emu, icode);	snd_emu10k1_tram_peek(emu, icode);	snd_emu10k1_code_peek(emu, icode);	err = snd_emu10k1_list_controls(emu, icode);	up(&emu->fx8010.lock);	return err;}static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm){	unsigned int i;	int err = 0;	snd_emu10k1_fx8010_pcm_t *pcm;	if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)		return -EINVAL;	if (ipcm->channels > 32)		return -EINVAL;	pcm = &emu->fx8010.pcm[ipcm->substream];	down(&emu->fx8010.lock);	spin_lock_irq(&emu->reg_lock);	if (pcm->opened) {		err = -EBUSY;		goto __error;	}	if (ipcm->channels == 0) {	/* remove */		pcm->valid = 0;	} else {		/* FIXME: we need to add universal code to the PCM transfer routine */		if (ipcm->channels != 2) {			err = -EINVAL;			goto __error;		}		pcm->valid = 1;		pcm->opened = 0;		pcm->channels = ipcm->channels;		pcm->tram_start = ipcm->tram_start;		pcm->buffer_size = ipcm->buffer_size;		pcm->gpr_size = ipcm->gpr_size;		pcm->gpr_count = ipcm->gpr_count;		pcm->gpr_tmpcount = ipcm->gpr_tmpcount;		pcm->gpr_ptr = ipcm->gpr_ptr;		pcm->gpr_trigger = ipcm->gpr_trigger;		pcm->gpr_running = ipcm->gpr_running;		for (i = 0; i < pcm->channels; i++)			pcm->etram[i] = ipcm->etram[i];	}      __error:	spin_unlock_irq(&emu->reg_lock);	up(&emu->fx8010.lock);	return err;}static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm){	unsigned int i;	int err = 0;	snd_emu10k1_fx8010_pcm_t *pcm;	if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)		return -EINVAL;	pcm = &emu->fx8010.pcm[ipcm->substream];	down(&emu->fx8010.lock);	spin_lock_irq(&emu->reg_lock);	ipcm->channels = pcm->channels;	ipcm->tram_start = pcm->tram_start;	ipcm->buffer_size = pcm->buffer_size;	ipcm->gpr_size = pcm->gpr_size;	ipcm->gpr_ptr = pcm->gpr_ptr;	ipcm->gpr_count = pcm->gpr_count;	ipcm->gpr_tmpcount = pcm->gpr_tmpcount;	ipcm->gpr_trigger = pcm->gpr_trigger;	ipcm->gpr_running = pcm->gpr_running;	for (i = 0; i < pcm->channels; i++)		ipcm->etram[i] = pcm->etram[i];	ipcm->res1 = ipcm->res2 = 0;	ipcm->pad = 0;	spin_unlock_irq(&emu->reg_lock);	up(&emu->fx8010.lock);	return err;}#define SND_EMU10K1_GPR_CONTROLS	41#define SND_EMU10K1_INPUTS		10#define SND_EMU10K1_PLAYBACK_CHANNELS	6#define SND_EMU10K1_CAPTURE_CHANNELS	4static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval){	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;	strcpy(ctl->id.name, name);	ctl->vcount = ctl->count = 1;	ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;	ctl->min = 0;	ctl->max = 100;	ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;	}static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval){	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;	strcpy(ctl->id.name, name);	ctl->vcount = ctl->count = 2;	ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;	ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;	ctl->min = 0;	ctl->max = 100;	ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;}static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval){	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;	strcpy(ctl->id.name, name);	ctl->vcount = ctl->count = 1;	ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;	ctl->min = 0;	ctl->max = 1;	ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;}static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval){	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;	strcpy(ctl->id.name, name);	ctl->vcount = ctl->count = 2;	ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;	ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;	ctl->min = 0;	ctl->max = 1;	ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;}/* * initial DSP configuration for Audigy */static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu){	int err, i, z, gpr, nctl;	const int playback = 10;	const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */	const int stereo_mix = capture + 2;	const int tmp = 0x88;	u32 ptr;	emu10k1_fx8010_code_t *icode;	emu10k1_fx8010_control_gpr_t *controls, *ctl;	mm_segment_t seg;	spin_lock_init(&emu->fx8010.irq_lock);	INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);	if ((icode = snd_kcalloc(sizeof(emu10k1_fx8010_code_t), GFP_KERNEL)) == NULL)		return -ENOMEM;	if ((controls = snd_kcalloc(sizeof(emu10k1_fx8010_control_gpr_t) * SND_EMU10K1_GPR_CONTROLS, GFP_KERNEL)) == NULL) {		kfree(icode);		return -ENOMEM;	}	/* clear free GPRs */	for (i = 0; i < 256; i++)		set_bit(i, icode->gpr_valid);	strcpy(icode->name, "Audigy DSP code for ALSA");	ptr = 0;	nctl = 0;	gpr = stereo_mix + 10;	/* stop FX processor */	snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);	/* PCM front Playback Volume (independent from stereo mix) */	A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));	A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));	snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);	gpr += 2;		/* PCM Surround Playback (independent from stereo mix) */	A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));	A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));	snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);	gpr += 2;	/* PCM Center Playback (independent from stereo mix) */	A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));	snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);	gpr++;	/* PCM LFE Playback (independent from stereo mix) */	A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));	snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);	gpr++;		/*	 * Stereo Mix	 */	/* Wave (PCM) Playback Volume (will be renamed later) */	A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));	A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));	snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);	gpr += 2;	/* Music Playback */	A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));	A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));	snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Playback Volume", gpr, 100);	gpr += 2;	/* Wave (PCM) Capture */	A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));	A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));	snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);	gpr += 2;	/* Music Capture */	A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));	A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));	snd_emu10k1_init_stereo_control(&controls[nctl++], "Music Capture Volume", gpr, 0);	gpr += 2;	/*	 * inputs	 */#define A_ADD_VOLUME_IN(var,vol,input) \A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))	/* AC'97 Playback Volume - used only for mic (renamed later) */	A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);	A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);	snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);	gpr += 2;	/* AC'97 Capture Volume - used only for mic */	A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);	A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);	snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);	gpr += 2;	/* mic capture buffer */		A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));	/* Audigy CD Playback Volume */	A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);	A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);	snd_emu10k1_init_stereo_control(&controls[nctl++],					emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",					gpr, 0);	gpr += 2;	/* Audigy CD Capture Volume */	A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);	A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);	snd_emu10k1_init_stereo_control(&controls[nctl++],					emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",					gpr, 0);	gpr += 2; 	/* Optical SPDIF Playback Volume */	A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);	A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);	snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);	gpr += 2;	/* Optical SPDIF Capture Volume */	A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);	A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);	snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);	gpr += 2;	/* Line2 Playback Volume */	A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);	A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);	snd_emu10k1_init_stereo_control(&controls[nctl++],					emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",					gpr, 0);	gpr += 2;	/* Line2 Capture Volume */	A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);	A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);	snd_emu10k1_init_stereo_control(&controls[nctl++],					emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",					gpr, 0);	gpr += 2;        	/* Philips ADC Playback Volume */	A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);	A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);	snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);	gpr += 2;	/* Philips ADC Capture Volume */	A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);	A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);	snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);	gpr += 2;	/* Aux2 Playback Volume */	A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);	A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);	snd_emu10k1_init_stereo_control(&controls[nctl++],					emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",					gpr, 0);	gpr += 2;	/* Aux2 Capture Volume */	A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);	A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);	snd_emu10k1_init_stereo_control(&controls[nctl++],					emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",					gpr, 0);	gpr += 2;		/* Stereo Mix Front Playback Volume */	A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));	A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));	snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);	gpr += 2;		/* Stereo Mix Surround Playback */	A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));	A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));	snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);	gpr += 2;	/* Stereo Mix Center Playback */	/* Center = sub = Left/2 + Right/2 */	A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));	A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));	snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);

⌨️ 快捷键说明

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