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

📄 emumixer.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	EMU1010_ADC_PADS("ADC3 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD3),	EMU1010_ADC_PADS("ADC1 14dB PAD 0202 Capture Switch", EMU_HANA_0202_ADC_PAD1),};#define snd_emu1010_dac_pads_info	snd_ctl_boolean_mono_infostatic int snd_emu1010_dac_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	unsigned int mask = kcontrol->private_value & 0xff;	ucontrol->value.integer.value[0] = (emu->emu1010.dac_pads & mask) ? 1 : 0;	return 0;}static int snd_emu1010_dac_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	unsigned int mask = kcontrol->private_value & 0xff;	unsigned int val, cache;	val = ucontrol->value.integer.value[0];	cache = emu->emu1010.dac_pads;	if (val == 1) 		cache = cache | mask;	else		cache = cache & ~mask;	if (cache != emu->emu1010.dac_pads) {		snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, cache );	        emu->emu1010.dac_pads = cache;	}	return 0;}#define EMU1010_DAC_PADS(xname,chid) \{								\	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,		\	.info =  snd_emu1010_dac_pads_info,			\	.get =   snd_emu1010_dac_pads_get,			\	.put =   snd_emu1010_dac_pads_put,			\	.private_value = chid					\}static struct snd_kcontrol_new snd_emu1010_dac_pads[] __devinitdata = {	EMU1010_DAC_PADS("DAC1 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD1),	EMU1010_DAC_PADS("DAC2 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD2),	EMU1010_DAC_PADS("DAC3 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD3),	EMU1010_DAC_PADS("DAC4 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD4),	EMU1010_DAC_PADS("DAC1 0202 14dB PAD Playback Switch", EMU_HANA_0202_DAC_PAD1),};static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol,					  struct snd_ctl_elem_info *uinfo){	static char *texts[4] = {		"44100", "48000", "SPDIF", "ADAT"	};			uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 4;	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;		}static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol,					struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	ucontrol->value.enumerated.item[0] = emu->emu1010.internal_clock;	return 0;}static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol,					struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change = 0;	val = ucontrol->value.enumerated.item[0] ;	/* Limit: uinfo->value.enumerated.items = 4; */	if (val >= 4)		return -EINVAL;	change = (emu->emu1010.internal_clock != val);	if (change) {		emu->emu1010.internal_clock = val;		switch (val) {		case 0:			/* 44100 */			/* Mute all */			snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );			/* Default fallback clock 48kHz */			snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_44_1K );			/* Word Clock source, Internal 44.1kHz x1 */			snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,			EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X );			/* Set LEDs on Audio Dock */			snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,				EMU_HANA_DOCK_LEDS_2_44K | EMU_HANA_DOCK_LEDS_2_LOCK );			/* Allow DLL to settle */			msleep(10);			/* Unmute all */			snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );			break;		case 1:			/* 48000 */			/* Mute all */			snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );			/* Default fallback clock 48kHz */			snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );			/* Word Clock source, Internal 48kHz x1 */			snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,				EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X );			/* Set LEDs on Audio Dock */			snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,				EMU_HANA_DOCK_LEDS_2_48K | EMU_HANA_DOCK_LEDS_2_LOCK );			/* Allow DLL to settle */			msleep(10);			/* Unmute all */			snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );			break;					case 2: /* Take clock from S/PDIF IN */			/* Mute all */			snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );			/* Default fallback clock 48kHz */			snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );			/* Word Clock source, sync to S/PDIF input */			snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,				EMU_HANA_WCLOCK_HANA_SPDIF_IN | EMU_HANA_WCLOCK_1X );			/* Set LEDs on Audio Dock */			snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,				EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );			/* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */				/* Allow DLL to settle */			msleep(10);			/* Unmute all */			snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );			break;				case 3: 						/* Take clock from ADAT IN */			/* Mute all */			snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );			/* Default fallback clock 48kHz */			snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );			/* Word Clock source, sync to ADAT input */			snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,				EMU_HANA_WCLOCK_HANA_ADAT_IN | EMU_HANA_WCLOCK_1X );			/* Set LEDs on Audio Dock */			snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );			/* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */				/* Allow DLL to settle */			msleep(10);			/*   Unmute all */			snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );			 						break;				}	}        return change;}static struct snd_kcontrol_new snd_emu1010_internal_clock ={	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,	.name =         "Clock Internal Rate",	.count =	1,	.info =         snd_emu1010_internal_clock_info,	.get =          snd_emu1010_internal_clock_get,	.put =          snd_emu1010_internal_clock_put};static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol,					  struct snd_ctl_elem_info *uinfo){#if 0	static char *texts[4] = {		"Unknown1", "Unknown2", "Mic", "Line"	};#endif	static char *texts[2] = {		"Mic", "Line"	};	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 2;	if (uinfo->value.enumerated.item > 1)                uinfo->value.enumerated.item = 1;	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static int snd_audigy_i2c_capture_source_get(struct snd_kcontrol *kcontrol,					struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;	return 0;}static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol,					struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	unsigned int source_id;	unsigned int ngain, ogain;	u32 gpio;	int change = 0;	unsigned long flags;	u32 source;	/* If the capture source has changed,	 * update the capture volume from the cached value	 * for the particular source.	 */	source_id = ucontrol->value.enumerated.item[0];	/* Limit: uinfo->value.enumerated.items = 2; */	/*        emu->i2c_capture_volume */	if (source_id >= 2)		return -EINVAL;	change = (emu->i2c_capture_source != source_id);	if (change) {		snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */		spin_lock_irqsave(&emu->emu_lock, flags);		gpio = inl(emu->port + A_IOCFG);		if (source_id==0)			outl(gpio | 0x4, emu->port + A_IOCFG);		else			outl(gpio & ~0x4, emu->port + A_IOCFG);		spin_unlock_irqrestore(&emu->emu_lock, flags);		ngain = emu->i2c_capture_volume[source_id][0]; /* Left */		ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */		if (ngain != ogain)			snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));		ngain = emu->i2c_capture_volume[source_id][1]; /* Right */		ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */		if (ngain != ogain)			snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));		source = 1 << (source_id + 2);		snd_emu10k1_i2c_write(emu, ADC_MUX, source); /* Set source */		emu->i2c_capture_source = source_id;	}        return change;}static struct snd_kcontrol_new snd_audigy_i2c_capture_source ={		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,		.name =		"Capture Source",		.info =		snd_audigy_i2c_capture_source_info,		.get =		snd_audigy_i2c_capture_source_get,		.put =		snd_audigy_i2c_capture_source_put};static int snd_audigy_i2c_volume_info(struct snd_kcontrol *kcontrol,				  struct snd_ctl_elem_info *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;	uinfo->count = 2;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = 255;	return 0;}static int snd_audigy_i2c_volume_get(struct snd_kcontrol *kcontrol,				 struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	unsigned int source_id;	source_id = kcontrol->private_value;	/* Limit: emu->i2c_capture_volume */        /*        capture_source: uinfo->value.enumerated.items = 2 */	if (source_id >= 2)		return -EINVAL;	ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];	ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];	return 0;}static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol,				 struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	unsigned int ogain;	unsigned int ngain;	unsigned int source_id;	int change = 0;	source_id = kcontrol->private_value;	/* Limit: emu->i2c_capture_volume */        /*        capture_source: uinfo->value.enumerated.items = 2 */	if (source_id >= 2)		return -EINVAL;	ogain = emu->i2c_capture_volume[source_id][0]; /* Left */	ngain = ucontrol->value.integer.value[0];	if (ngain > 0xff)		return 0;	if (ogain != ngain) {		if (emu->i2c_capture_source == source_id)			snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );		emu->i2c_capture_volume[source_id][0] = ngain;		change = 1;	}	ogain = emu->i2c_capture_volume[source_id][1]; /* Right */	ngain = ucontrol->value.integer.value[1];	if (ngain > 0xff)		return 0;	if (ogain != ngain) {		if (emu->i2c_capture_source == source_id)			snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));		emu->i2c_capture_volume[source_id][1] = ngain;		change = 1;	}	return change;}#define I2C_VOLUME(xname,chid) \{								\	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |		\	          SNDRV_CTL_ELEM_ACCESS_TLV_READ,		\	.info =  snd_audigy_i2c_volume_info,			\	.get =   snd_audigy_i2c_volume_get,			\	.put =   snd_audigy_i2c_volume_put,			\	.tlv = { .p = snd_audigy_db_scale2 },			\	.private_value = chid					\}static struct snd_kcontrol_new snd_audigy_i2c_volume_ctls[] __devinitdata = {	I2C_VOLUME("Mic Capture Volume", 0),	I2C_VOLUME("Line Capture Volume", 0)};#if 0static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	static char *texts[] = {"44100", "48000", "96000"};	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 3;	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static int snd_audigy_spdif_output_rate_get(struct snd_kcontrol *kcontrol,                                 struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	unsigned int tmp;	unsigned long flags;		spin_lock_irqsave(&emu->reg_lock, flags);	tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);	switch (tmp & A_SPDIF_RATE_MASK) {	case A_SPDIF_44100:		ucontrol->value.enumerated.item[0] = 0;		break;	case A_SPDIF_48000:		ucontrol->value.enumerated.item[0] = 1;		break;	case A_SPDIF_96000:		ucontrol->value.enumerated.item[0] = 2;		break;	default:		ucontrol->value.enumerated.item[0] = 1;	}	spin_unlock_irqrestore(&emu->reg_lock, flags);	return 0;}static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol,                                 struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	int change;	unsigned int reg, val, tmp;	unsigned long flags;	switch(ucontrol->value.enumerated.item[0]) {	case 0:		val = A_SPDIF_44100;		break;	case 1:		val = A_SPDIF_48000;		break;	case 2:		val = A_SPDIF_96000;		break;	default:		val = A_SPDIF_48000;		break;	}		spin_lock_irqsave(&emu->reg_lock, flags);	reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);	tmp = reg & ~A_SPDIF_RATE_MASK;	tmp |= val;	if ((change = (tmp != reg)))		snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);	spin_unlock_irqrestore(&emu->reg_lock, flags);	return change;}static struct snd_kcontrol_new snd_audigy_spdif_output_rate ={	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,	.name =         "Audigy SPDIF Output Sample Rate",	.count =	1,	.info =         snd_audigy_spdif_output_rate_info,	.get =          snd_audigy_spdif_output_rate_get,	.put =          snd_audigy_spdif_output_rate_put};#endifstatic int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol,                                 struct snd_ctl_elem_value *ucontrol){	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);	int change;	unsigned int val;	unsigned long flags;	/* Limit: emu->spdif_bits */	if (idx >= 3)		return -EINVAL;	val = (ucontrol->value.iec958.status[0] << 0) |	      (ucontrol->value.iec958.status[1] << 8) |	      (ucontrol->value.iec958.status[2] << 16) |	      (ucontrol->value.iec958.status[3] << 24);	spin_lock_irqsave(&emu->reg_lock, flags);	change = val != emu->spdif_bits[idx];	if (change) {		snd_emu10k1_ptr_write(emu, SPCS0 + idx, 0, val);		emu->spdif_bits[idx] = val;	}	spin_unlock_irqrestore(&emu->reg_lock, flags);	return change;}static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control ={

⌨️ 快捷键说明

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