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

📄 vx222_ops.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* `data' is a value between 0x0 and VX2_AKM_LEVEL_MAX = 0x093, in the case of the AKM codecs, we need	   a look up table, as there is no linear matching between the driver codec values	   and the real dBu value	*/	snd_assert(data < sizeof(vx2_akm_gains_lut), return);	switch (reg) {	case XX_CODEC_LEVEL_LEFT_REGISTER:		val = AKM_CODEC_LEFT_LEVEL_CMD;		break;	case XX_CODEC_LEVEL_RIGHT_REGISTER:		val = AKM_CODEC_RIGHT_LEVEL_CMD;		break;	default:		snd_BUG();		return;	}	val |= vx2_akm_gains_lut[data];	vx2_write_codec_reg(chip, val);}/* * write codec bit for old VX222 board */static void vx2_old_write_codec_bit(vx_core_t *chip, int codec, unsigned int data){	int i;	/* activate access to codec registers */	vx_inl(chip, HIFREQ);	for (i = 0; i < 24; i++, data <<= 1)		vx_outl(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));	/* Terminate access to codec registers */	vx_inl(chip, RUER);}/* * reset codec bit */static void vx2_reset_codec(vx_core_t *_chip){	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;	/* Set the reset CODEC bit to 0. */	vx_outl(chip, CDSP, chip->regCDSP &~ VX_CDSP_CODEC_RESET_MASK);	vx_inl(chip, CDSP);	snd_vx_delay(_chip, 10);	/* Set the reset CODEC bit to 1. */	chip->regCDSP |= VX_CDSP_CODEC_RESET_MASK;	vx_outl(chip, CDSP, chip->regCDSP);	vx_inl(chip, CDSP);	if (_chip->type == VX_TYPE_BOARD) {		snd_vx_delay(_chip, 1);		return;	}	snd_vx_delay(_chip, 5);  /* additionnel wait time for AKM's */	vx2_write_codec_reg(_chip, AKM_CODEC_POWER_CONTROL_CMD); /* DAC power up, ADC power up, Vref power down */		vx2_write_codec_reg(_chip, AKM_CODEC_CLOCK_FORMAT_CMD); /* default */	vx2_write_codec_reg(_chip, AKM_CODEC_MUTE_CMD); /* Mute = ON ,Deemphasis = OFF */	vx2_write_codec_reg(_chip, AKM_CODEC_RESET_OFF_CMD); /* DAC and ADC normal operation */	if (_chip->type == VX_TYPE_MIC) {		/* set up the micro input selector */		chip->regSELMIC =  MICRO_SELECT_INPUT_NORM |			MICRO_SELECT_PREAMPLI_G_0 |			MICRO_SELECT_NOISE_T_52DB;		/* reset phantom power supply */		chip->regSELMIC &= ~MICRO_SELECT_PHANTOM_ALIM;		vx_outl(_chip, SELMIC, chip->regSELMIC);	}}/* * change the audio source */static void vx2_change_audio_source(vx_core_t *_chip, int src){	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;	switch (src) {	case VX_AUDIO_SRC_DIGITAL:		chip->regCFG |= VX_CFG_DATAIN_SEL_MASK;		break;	default:		chip->regCFG &= ~VX_CFG_DATAIN_SEL_MASK;		break;	}	vx_outl(chip, CFG, chip->regCFG);}/* * set the clock source */static void vx2_set_clock_source(vx_core_t *_chip, int source){	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;	if (source == INTERNAL_QUARTZ)		chip->regCFG &= ~VX_CFG_CLOCKIN_SEL_MASK;	else		chip->regCFG |= VX_CFG_CLOCKIN_SEL_MASK;	vx_outl(chip, CFG, chip->regCFG);}/* * reset the board */static void vx2_reset_board(vx_core_t *_chip, int cold_reset){	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;	/* initialize the register values */	chip->regCDSP = VX_CDSP_CODEC_RESET_MASK | VX_CDSP_DSP_RESET_MASK ;	chip->regCFG = 0;}/* * input level controls for VX222 Mic *//* Micro level is specified to be adjustable from -96dB to 63 dB (board coded 0x00 ... 318), * 318 = 210 + 36 + 36 + 36   (210 = +9dB variable) (3 * 36 = 3 steps of 18dB pre ampli) * as we will mute if less than -110dB, so let's simply use line input coded levels and add constant offset ! */#define V2_MICRO_LEVEL_RANGE        (318 - 255)static void vx2_set_input_level(struct snd_vx222 *chip){	int i, miclevel, preamp;	unsigned int data;	miclevel = chip->mic_level;	miclevel += V2_MICRO_LEVEL_RANGE; /* add 318 - 0xff */	preamp = 0;        while (miclevel > 210) { /* limitation to +9dB of 3310 real gain */		preamp++;	/* raise pre ampli + 18dB */		miclevel -= (18 * 2);   /* lower level 18 dB (*2 because of 0.5 dB steps !) */        }	snd_assert(preamp < 4, return);	/* set pre-amp level */	chip->regSELMIC &= ~MICRO_SELECT_PREAMPLI_MASK;	chip->regSELMIC |= (preamp << MICRO_SELECT_PREAMPLI_OFFSET) & MICRO_SELECT_PREAMPLI_MASK;	vx_outl(chip, SELMIC, chip->regSELMIC);	data = (unsigned int)miclevel << 16 |		(unsigned int)chip->input_level[1] << 8 |		(unsigned int)chip->input_level[0];	vx_inl(chip, DATA); /* Activate input level programming */	/* We have to send 32 bits (4 x 8 bits) */	for (i = 0; i < 32; i++, data <<= 1)		vx_outl(chip, DATA, ((data & 0x80000000) ? VX_DATA_CODEC_MASK : 0));	vx_inl(chip, RUER); /* Terminate input level programming */}#define MIC_LEVEL_MAX	0xff/* * controls API for input levels *//* input levels */static int vx_input_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;	uinfo->count = 2;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = MIC_LEVEL_MAX;	return 0;}static int vx_input_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;	down(&_chip->mixer_mutex);	ucontrol->value.integer.value[0] = chip->input_level[0];	ucontrol->value.integer.value[1] = chip->input_level[1];	up(&_chip->mixer_mutex);	return 0;}static int vx_input_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;	down(&_chip->mixer_mutex);	if (chip->input_level[0] != ucontrol->value.integer.value[0] ||	    chip->input_level[1] != ucontrol->value.integer.value[1]) {		chip->input_level[0] = ucontrol->value.integer.value[0];		chip->input_level[1] = ucontrol->value.integer.value[1];		vx2_set_input_level(chip);		up(&_chip->mixer_mutex);		return 1;	}	up(&_chip->mixer_mutex);	return 0;}/* mic level */static int vx_mic_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;	uinfo->count = 1;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = MIC_LEVEL_MAX;	return 0;}static int vx_mic_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;	ucontrol->value.integer.value[0] = chip->mic_level;	return 0;}static int vx_mic_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;	down(&_chip->mixer_mutex);	if (chip->mic_level != ucontrol->value.integer.value[0]) {		chip->mic_level = ucontrol->value.integer.value[0];		vx2_set_input_level(chip);		up(&_chip->mixer_mutex);		return 1;	}	up(&_chip->mixer_mutex);	return 0;}static snd_kcontrol_new_t vx_control_input_level = {	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,	.name =		"Capture Volume",	.info =		vx_input_level_info,	.get =		vx_input_level_get,	.put =		vx_input_level_put,};static snd_kcontrol_new_t vx_control_mic_level = {	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,	.name =		"Mic Capture Volume",	.info =		vx_mic_level_info,	.get =		vx_mic_level_get,	.put =		vx_mic_level_put,};/* * FIXME: compressor/limiter implementation is missing yet... */static int vx2_add_mic_controls(vx_core_t *_chip){	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;	int err;	if (_chip->type != VX_TYPE_MIC)		return 0;	/* mute input levels */	chip->input_level[0] = chip->input_level[1] = 0;	chip->mic_level = 0;	vx2_set_input_level(chip);	/* controls */	if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_input_level, chip))) < 0)		return err;	if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip))) < 0)		return err;	return 0;}/* * callbacks */struct snd_vx_ops vx222_ops = {	.in8 = vx2_inb,	.in32 = vx2_inl,	.out8 = vx2_outb,	.out32 = vx2_outl,	.test_and_ack = vx2_test_and_ack,	.validate_irq = vx2_validate_irq,	.akm_write = vx2_write_akm,	.reset_codec = vx2_reset_codec,	.change_audio_source = vx2_change_audio_source,	.set_clock_source = vx2_set_clock_source,	.load_dsp = vx2_load_dsp,	.reset_dsp = vx2_reset_dsp,	.reset_board = vx2_reset_board,	.dma_write = vx2_dma_write,	.dma_read = vx2_dma_read,	.add_controls = vx2_add_mic_controls,};/* for old VX222 board */struct snd_vx_ops vx222_old_ops = {	.in8 = vx2_inb,	.in32 = vx2_inl,	.out8 = vx2_outb,	.out32 = vx2_outl,	.test_and_ack = vx2_test_and_ack,	.validate_irq = vx2_validate_irq,	.write_codec = vx2_old_write_codec_bit,	.reset_codec = vx2_reset_codec,	.change_audio_source = vx2_change_audio_source,	.set_clock_source = vx2_set_clock_source,	.load_dsp = vx2_load_dsp,	.reset_dsp = vx2_reset_dsp,	.reset_board = vx2_reset_board,	.dma_write = vx2_dma_write,	.dma_read = vx2_dma_read,};

⌨️ 快捷键说明

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