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

📄 cs46xx_lib.c

📁 鼎力推荐!本程序是基于嵌入式LUNUX系统开发的源程序代码
💻 C
📖 第 1 页 / 共 5 页
字号:
static int snd_cs46xx_vol_iec958_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	int change = 0;	if (chip->dsp_spos_instance->spdif_input_volume_left  != ucontrol->value.integer.value[0] ||	    chip->dsp_spos_instance->spdif_input_volume_right!= ucontrol->value.integer.value[1]) {		cs46xx_dsp_set_iec958_volume (chip,					      ucontrol->value.integer.value[0],					      ucontrol->value.integer.value[1]);		change = 1;	}	return change;}#endifstatic int snd_mixer_boolean_info(snd_kcontrol_t *kcontrol, 				  snd_ctl_elem_info_t *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;	uinfo->count = 1;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = 1;	return 0;}static int snd_cs46xx_iec958_get(snd_kcontrol_t *kcontrol,                                  snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	int reg = kcontrol->private_value;	if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)		ucontrol->value.integer.value[0] = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);	else		ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_status_in;	return 0;}static int snd_cs46xx_iec958_put(snd_kcontrol_t *kcontrol,                                   snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	int change, res;	switch (kcontrol->private_value) {	case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT:		down (&chip->spos_mutex);		change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED);		if (ucontrol->value.integer.value[0] && !change) 			cs46xx_dsp_enable_spdif_out(chip);		else if (change && !ucontrol->value.integer.value[0])			cs46xx_dsp_disable_spdif_out(chip);		res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED));		up (&chip->spos_mutex);		break;	case CS46XX_MIXER_SPDIF_INPUT_ELEMENT:		change = chip->dsp_spos_instance->spdif_status_in;		if (ucontrol->value.integer.value[0] && !change) {			cs46xx_dsp_enable_spdif_in(chip);			/* restore volume */		}		else if (change && !ucontrol->value.integer.value[0])			cs46xx_dsp_disable_spdif_in(chip);				res = (change != chip->dsp_spos_instance->spdif_status_in);		break;	default:		res = -EINVAL;		snd_assert(0, (void)0);	}	return res;}static int snd_cs46xx_adc_capture_get(snd_kcontrol_t *kcontrol,                                       snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	if (ins->adc_input != NULL) 		ucontrol->value.integer.value[0] = 1;	else 		ucontrol->value.integer.value[0] = 0;		return 0;}static int snd_cs46xx_adc_capture_put(snd_kcontrol_t *kcontrol,                                       snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	int change = 0;	if (ucontrol->value.integer.value[0] && !ins->adc_input) {		cs46xx_dsp_enable_adc_capture(chip);		change = 1;	} else  if (!ucontrol->value.integer.value[0] && ins->adc_input) {		cs46xx_dsp_disable_adc_capture(chip);		change = 1;	}	return change;}static int snd_cs46xx_pcm_capture_get(snd_kcontrol_t *kcontrol,                                       snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	if (ins->pcm_input != NULL) 		ucontrol->value.integer.value[0] = 1;	else 		ucontrol->value.integer.value[0] = 0;	return 0;}static int snd_cs46xx_pcm_capture_put(snd_kcontrol_t *kcontrol,                                       snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	int change = 0;	if (ucontrol->value.integer.value[0] && !ins->pcm_input) {		cs46xx_dsp_enable_pcm_capture(chip);		change = 1;	} else  if (!ucontrol->value.integer.value[0] && ins->pcm_input) {		cs46xx_dsp_disable_pcm_capture(chip);		change = 1;	}	return change;}static int snd_herc_spdif_select_get(snd_kcontrol_t *kcontrol,                                      snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);	if (val1 & EGPIODR_GPOE0)		ucontrol->value.integer.value[0] = 1;	else		ucontrol->value.integer.value[0] = 0;	return 0;}/* *	Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial. */ static int snd_herc_spdif_select_put(snd_kcontrol_t *kcontrol,                                        snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);	int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);	if (ucontrol->value.integer.value[0]) {		/* optical is default */		snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, 				   EGPIODR_GPOE0 | val1);  /* enable EGPIO0 output */		snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, 				   EGPIOPTR_GPPT0 | val2); /* open-drain on output */	} else {		/* coaxial */		snd_cs46xx_pokeBA0(chip, BA0_EGPIODR,  val1 & ~EGPIODR_GPOE0); /* disable */		snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, val2 & ~EGPIOPTR_GPPT0); /* disable */	}	/* checking diff from the EGPIO direction register 	   should be enough */	return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR));}static int snd_cs46xx_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;	uinfo->count = 1;	return 0;}static int snd_cs46xx_spdif_default_get(snd_kcontrol_t * kcontrol,					snd_ctl_elem_value_t * ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	down (&chip->spos_mutex);	ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);	ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff);	ucontrol->value.iec958.status[2] = 0;	ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff);	up (&chip->spos_mutex);	return 0;}static int snd_cs46xx_spdif_default_put(snd_kcontrol_t * kcontrol,					snd_ctl_elem_value_t * ucontrol){	cs46xx_t * chip = snd_kcontrol_chip(kcontrol);	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	unsigned int val;	int change;	down (&chip->spos_mutex);	val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |		((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) |		((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3]))  |		/* left and right validity bit */		(1 << 13) | (1 << 12);	change = (unsigned int)ins->spdif_csuv_default != val;	ins->spdif_csuv_default = val;	if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) )		cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);	up (&chip->spos_mutex);	return change;}static int snd_cs46xx_spdif_mask_get(snd_kcontrol_t * kcontrol,				     snd_ctl_elem_value_t * ucontrol){	ucontrol->value.iec958.status[0] = 0xff;	ucontrol->value.iec958.status[1] = 0xff;	ucontrol->value.iec958.status[2] = 0x00;	ucontrol->value.iec958.status[3] = 0xff;	return 0;}static int snd_cs46xx_spdif_stream_get(snd_kcontrol_t * kcontrol,                                         snd_ctl_elem_value_t * ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	down (&chip->spos_mutex);	ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);	ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff);	ucontrol->value.iec958.status[2] = 0;	ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff);	up (&chip->spos_mutex);	return 0;}static int snd_cs46xx_spdif_stream_put(snd_kcontrol_t * kcontrol,                                        snd_ctl_elem_value_t * ucontrol){	cs46xx_t * chip = snd_kcontrol_chip(kcontrol);	dsp_spos_instance_t * ins = chip->dsp_spos_instance;	unsigned int val;	int change;	down (&chip->spos_mutex);	val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) |		((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) |		((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) |		/* left and right validity bit */		(1 << 13) | (1 << 12);	change = ins->spdif_csuv_stream != val;	ins->spdif_csuv_stream = val;	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN )		cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val);	up (&chip->spos_mutex);	return change;}#endif /* CONFIG_SND_CS46XX_NEW_DSP */#ifdef CONFIG_SND_CS46XX_DEBUG_GPIOstatic int snd_cs46xx_egpio_select_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 = 8;	return 0;}static int snd_cs46xx_egpio_select_get(snd_kcontrol_t *kcontrol,                                        snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	ucontrol->value.integer.value[0] = chip->current_gpio;	return 0;}static int snd_cs46xx_egpio_select_put(snd_kcontrol_t *kcontrol,                                        snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	int change = (chip->current_gpio != ucontrol->value.integer.value[0]);	chip->current_gpio = ucontrol->value.integer.value[0];	return change;}static int snd_cs46xx_egpio_get(snd_kcontrol_t *kcontrol,                                        snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	int reg = kcontrol->private_value;	snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio);	ucontrol->value.integer.value[0] = 		(snd_cs46xx_peekBA0(chip, reg) & (1 << chip->current_gpio)) ? 1 : 0;  	return 0;}static int snd_cs46xx_egpio_put(snd_kcontrol_t *kcontrol,                                        snd_ctl_elem_value_t *ucontrol){	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);	int reg = kcontrol->private_value;	int val = snd_cs46xx_peekBA0(chip, reg);	int oldval = val;	snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio);	if (ucontrol->value.integer.value[0])		val |= (1 << chip->current_gpio);	else		val &= ~(1 << chip->current_gpio);	snd_cs46xx_pokeBA0(chip, reg,val);	snd_printdd ("put: val %08x oldval %08x\n",val,oldval);	return (oldval != val);}#endif /* CONFIG_SND_CS46XX_DEBUG_GPIO */static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "DAC Volume",	.info = snd_cs46xx_vol_info,#ifndef CONFIG_SND_CS46XX_NEW_DSP	.get = snd_cs46xx_vol_get,	.put = snd_cs46xx_vol_put,	.private_value = BA1_PVOL,#else	.get = snd_cs46xx_vol_dac_get,	.put = snd_cs46xx_vol_dac_put,#endif},{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "ADC Volume",	.info = snd_cs46xx_vol_info,	.get = snd_cs46xx_vol_get,	.put = snd_cs46xx_vol_put,#ifndef CONFIG_SND_CS46XX_NEW_DSP	.private_value = BA1_CVOL,#else	.private_value = (VARIDECIMATE_SCB_ADDR + 0xE) << 2,#endif},#ifdef CONFIG_SND_CS46XX_NEW_DSP{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "ADC Capture Switch",	.info = snd_mixer_boolean_info,	.get = snd_cs46xx_adc_capture_get,	.put = snd_cs46xx_adc_capture_put},{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "DAC Capture Switch",	.info = snd_mixer_boolean_info,	.get = snd_cs46xx_pcm_capture_get,	.put = snd_cs46xx_pcm_capture_put},{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "IEC958 Output Switch",	.info = snd_mixer_boolean_info,	.get = snd_cs46xx_iec958_get,	.put = snd_cs46xx_iec958_put,	.private_value = CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT,},{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "IEC958 Input Switch",	.info = snd_mixer_boolean_info,	.get = snd_cs46xx_iec958_get,	.put = snd_cs46xx_iec958_put,	.private_value = CS46XX_MIXER_SPDIF_INPUT_ELEMENT,},#if 0/* Input IEC958 volume does not work for the moment. (Benny) */{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "IEC958 Input Volume",	.info = snd_cs46xx_vol_info,	.get = snd_cs46xx_vol_iec958_get,	.put = snd_cs46xx_vol_iec958_put,	.private_value = (ASYNCRX_SCB_ADDR + 0xE) << 2,},#endif{	.iface = SNDRV_CTL_ELEM_IFACE_PCM,	.name =  SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),	.info =	 snd_cs46xx_spdif_info,	.get =	 snd_cs46xx_spdif_default_get,	.put =   snd_cs46xx_spdif_default_put,},{	.iface = SNDRV_CTL_ELEM_IFACE_PCM,	.name =	 SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),	.info =	 snd_cs46xx_spdif_info,        .get =	 snd_cs46xx_spdif_mask_get,	.access = SNDRV_CTL_ELEM_ACCESS_READ},{	.iface = SNDRV_CTL_ELEM_IFACE_PCM,	.name =	 SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),	.info =	 snd_cs46xx_spdif_info,	.get =	 snd_cs46xx_spdif_stream_get,	.put =	 snd_cs46xx_spdif_stream_put},#endif#ifdef CONFIG_SND_CS46XX_DEBUG_GPIO{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "EGPIO select",	.info = snd_cs46xx_egpio_select_info,	.get = snd_cs46xx_egpio_select_get,	.put = snd_cs46xx_egpio_select_

⌨️ 快捷键说明

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