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

📄 ice1712.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;		spin_lock_irq(&ice->reg_lock);	ucontrol->value.integer.value[0] = !((ice->pro_volumes[index] >> 15) & 1);	ucontrol->value.integer.value[1] = !((ice->pro_volumes[index] >> 31) & 1);	spin_unlock_irq(&ice->reg_lock);	return 0;}static int snd_ice1712_pro_mixer_switch_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;	unsigned int nval, change;	nval = (ucontrol->value.integer.value[0] ? 0 : 0x00008000) |	       (ucontrol->value.integer.value[1] ? 0 : 0x80000000);	spin_lock_irq(&ice->reg_lock);	nval |= ice->pro_volumes[index] & ~0x80008000;	change = nval != ice->pro_volumes[index];	ice->pro_volumes[index] = nval;	snd_ice1712_update_volume(ice, index);	spin_unlock_irq(&ice->reg_lock);	return change;}static int snd_ice1712_pro_mixer_volume_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 = 96;	return 0;}static int snd_ice1712_pro_mixer_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;		spin_lock_irq(&ice->reg_lock);	ucontrol->value.integer.value[0] = (ice->pro_volumes[index] >> 0) & 127;	ucontrol->value.integer.value[1] = (ice->pro_volumes[index] >> 16) & 127;	spin_unlock_irq(&ice->reg_lock);	return 0;}static int snd_ice1712_pro_mixer_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;	unsigned int nval, change;	nval = (ucontrol->value.integer.value[0] & 127) |	       ((ucontrol->value.integer.value[1] & 127) << 16);	spin_lock_irq(&ice->reg_lock);	nval |= ice->pro_volumes[index] & ~0x007f007f;	change = nval != ice->pro_volumes[index];	ice->pro_volumes[index] = nval;	snd_ice1712_update_volume(ice, index);	spin_unlock_irq(&ice->reg_lock);	return change;}static snd_kcontrol_new_t snd_ice1712_multi_playback_ctrls[] __devinitdata = {	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Multi Playback Switch",		.info = snd_ice1712_pro_mixer_switch_info,		.get = snd_ice1712_pro_mixer_switch_get,		.put = snd_ice1712_pro_mixer_switch_put,		.private_value = 0,		.count = 10,	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Multi Playback Volume",		.info = snd_ice1712_pro_mixer_volume_info,		.get = snd_ice1712_pro_mixer_volume_get,		.put = snd_ice1712_pro_mixer_volume_put,		.private_value = 0,		.count = 10,	},};static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_switch __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "H/W Multi Capture Switch",	.info = snd_ice1712_pro_mixer_switch_info,	.get = snd_ice1712_pro_mixer_switch_get,	.put = snd_ice1712_pro_mixer_switch_put,	.private_value = 10,};static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_switch __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH),	.info = snd_ice1712_pro_mixer_switch_info,	.get = snd_ice1712_pro_mixer_switch_get,	.put = snd_ice1712_pro_mixer_switch_put,	.private_value = 18,	.count = 2,};static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_volume __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "H/W Multi Capture Volume",	.info = snd_ice1712_pro_mixer_volume_info,	.get = snd_ice1712_pro_mixer_volume_get,	.put = snd_ice1712_pro_mixer_volume_put,	.private_value = 10,};static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_volume __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME),	.info = snd_ice1712_pro_mixer_volume_info,	.get = snd_ice1712_pro_mixer_volume_get,	.put = snd_ice1712_pro_mixer_volume_put,	.private_value = 18,	.count = 2,};static int __devinit snd_ice1712_build_pro_mixer(ice1712_t *ice){	snd_card_t * card = ice->card;	unsigned int idx;	int err;	/* multi-channel mixer */	for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_multi_playback_ctrls); idx++) {		err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_playback_ctrls[idx], ice));		if (err < 0)			return err;	}		if (ice->num_total_adcs > 0) {		snd_kcontrol_new_t tmp = snd_ice1712_multi_capture_analog_switch;		tmp.count = ice->num_total_adcs;		err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));		if (err < 0)			return err;	}	err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_switch, ice));	if (err < 0)		return err;	if (ice->num_total_adcs > 0) {		snd_kcontrol_new_t tmp = snd_ice1712_multi_capture_analog_volume;		tmp.count = ice->num_total_adcs;		err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));		if (err < 0)			return err;	}	err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_volume, ice));	if (err < 0)		return err;	/* initialize volumes */	for (idx = 0; idx < 10; idx++) {		ice->pro_volumes[idx] = 0x80008000;	/* mute */		snd_ice1712_update_volume(ice, idx);	}	for (idx = 10; idx < 10 + ice->num_total_adcs; idx++) {		ice->pro_volumes[idx] = 0x80008000;	/* mute */		snd_ice1712_update_volume(ice, idx);	}	for (idx = 18; idx < 20; idx++) {		ice->pro_volumes[idx] = 0x80008000;	/* mute */		snd_ice1712_update_volume(ice, idx);	}	return 0;}static void snd_ice1712_mixer_free_ac97(ac97_t *ac97){	ice1712_t *ice = ac97->private_data;	ice->ac97 = NULL;}static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice){	int err, bus_num = 0;	ac97_template_t ac97;	ac97_bus_t *pbus;	static ac97_bus_ops_t con_ops = {		.write = snd_ice1712_ac97_write,		.read = snd_ice1712_ac97_read,	};	static ac97_bus_ops_t pro_ops = {		.write = snd_ice1712_pro_ac97_write,		.read = snd_ice1712_pro_ac97_read,	};	if (ice_has_con_ac97(ice)) {		if ((err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus)) < 0)			return err;		memset(&ac97, 0, sizeof(ac97));		ac97.private_data = ice;		ac97.private_free = snd_ice1712_mixer_free_ac97;		if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)			printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n");		else {			if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0)				return err;			return 0;		}	}	if (! (ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) {		if ((err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus)) < 0)			return err;		memset(&ac97, 0, sizeof(ac97));		ac97.private_data = ice;		ac97.private_free = snd_ice1712_mixer_free_ac97;		if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)			printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");		else			return 0;	}	/* I2S mixer only */	strcat(ice->card->mixername, "ICE1712 - multitrack");	return 0;}/* * */static inline unsigned int eeprom_double(ice1712_t *ice, int idx){	return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8);}static void snd_ice1712_proc_read(snd_info_entry_t *entry, 				  snd_info_buffer_t * buffer){	ice1712_t *ice = entry->private_data;	unsigned int idx;	snd_iprintf(buffer, "%s\n\n", ice->card->longname);	snd_iprintf(buffer, "EEPROM:\n");	snd_iprintf(buffer, "  Subvendor        : 0x%x\n", ice->eeprom.subvendor);	snd_iprintf(buffer, "  Size             : %i bytes\n", ice->eeprom.size);	snd_iprintf(buffer, "  Version          : %i\n", ice->eeprom.version);	snd_iprintf(buffer, "  Codec            : 0x%x\n", ice->eeprom.data[ICE_EEP1_CODEC]);	snd_iprintf(buffer, "  ACLink           : 0x%x\n", ice->eeprom.data[ICE_EEP1_ACLINK]);	snd_iprintf(buffer, "  I2S ID           : 0x%x\n", ice->eeprom.data[ICE_EEP1_I2SID]);	snd_iprintf(buffer, "  S/PDIF           : 0x%x\n", ice->eeprom.data[ICE_EEP1_SPDIF]);	snd_iprintf(buffer, "  GPIO mask        : 0x%x\n", ice->eeprom.gpiomask);	snd_iprintf(buffer, "  GPIO state       : 0x%x\n", ice->eeprom.gpiostate);	snd_iprintf(buffer, "  GPIO direction   : 0x%x\n", ice->eeprom.gpiodir);	snd_iprintf(buffer, "  AC'97 main       : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_MAIN_LO));	snd_iprintf(buffer, "  AC'97 pcm        : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_PCM_LO));	snd_iprintf(buffer, "  AC'97 record     : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_REC_LO));	snd_iprintf(buffer, "  AC'97 record src : 0x%x\n", ice->eeprom.data[ICE_EEP1_AC97_RECSRC]);	for (idx = 0; idx < 4; idx++)		snd_iprintf(buffer, "  DAC ID #%i        : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_DAC_ID + idx]);	for (idx = 0; idx < 4; idx++)		snd_iprintf(buffer, "  ADC ID #%i        : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_ADC_ID + idx]);	for (idx = 0x1c; idx < ice->eeprom.size; idx++)		snd_iprintf(buffer, "  Extra #%02i        : 0x%x\n", idx, ice->eeprom.data[idx]);	snd_iprintf(buffer, "\nRegisters:\n");	snd_iprintf(buffer, "  PSDOUT03         : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_PSDOUT03)));	snd_iprintf(buffer, "  CAPTURE          : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE)));	snd_iprintf(buffer, "  SPDOUT           : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT)));	snd_iprintf(buffer, "  RATE             : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));}static void __devinit snd_ice1712_proc_init(ice1712_t * ice){	snd_info_entry_t *entry;	if (! snd_card_proc_new(ice->card, "ice1712", &entry))		snd_info_set_text_ops(entry, ice, 1024, snd_ice1712_proc_read);}/* * */static int snd_ice1712_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;	uinfo->count = sizeof(ice1712_eeprom_t);	return 0;}static int snd_ice1712_eeprom_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);		memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));	return 0;}static snd_kcontrol_new_t snd_ice1712_eeprom __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_CARD,	.name = "ICE1712 EEPROM",	.access = SNDRV_CTL_ELEM_ACCESS_READ,	.info = snd_ice1712_eeprom_info,	.get = snd_ice1712_eeprom_get};/* */static int snd_ice1712_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_ice1712_spdif_default_get(snd_kcontrol_t * kcontrol,					 snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	if (ice->spdif.ops.default_get)		ice->spdif.ops.default_get(ice, ucontrol); 	return 0;}static int snd_ice1712_spdif_default_put(snd_kcontrol_t * kcontrol,					 snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	if (ice->spdif.ops.default_put)		return ice->spdif.ops.default_put(ice, ucontrol);	return 0;}static snd_kcontrol_new_t snd_ice1712_spdif_default __devinitdata ={	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),	.info =		snd_ice1712_spdif_info,	.get =		snd_ice1712_spdif_default_get,	.put =		snd_ice1712_spdif_default_put};static int snd_ice1712_spdif_maskc_get(snd_kcontrol_t * kcontrol,				       snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	if (ice->spdif.ops.default_get) {		ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |						     IEC958_AES0_PROFESSIONAL |						     IEC958_AES0_CON_NOT_COPYRIGHT |						     IEC958_AES0_CON_EMPHASIS;		ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL |						     IEC958_AES1_CON_CATEGORY;		ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;	} else {		ucontrol->value.iec958.status[0] = 0xff;		ucontrol->value.iec958.status[1] = 0xff;		ucontrol->value.iec958.status[2] = 0xff;		ucontrol->value.iec958.status[3] = 0xff;		ucontrol->value.iec958.status[4] = 0xff;	}	return 0;}static int snd_ice1712_spdif_maskp_get(snd_kcontrol_t * kcontrol,				       snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	if (ice->spdif.ops.default_get) {		ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |						     IEC958_AES0_PROFESSIONAL |						     IEC958_AES0_PRO_FS |						     IEC958_AES0_PRO_EMPHASIS;		ucontrol->value.iec958.status[1] = IEC958_AES1_PRO_MODE;	} else {		ucontrol->value.iec958.status[0] = 0xff;		ucontrol->value.iec958.status[1] = 0xff;		ucontrol->value.iec958.status[2] = 0xff;		ucontrol->value.iec958.status[3] = 0xff;		ucontrol->value.iec958.status[4] = 0xff;	}	return 0;}static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata ={	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),	.info =		snd_ice1712_spdif_info,	.get =		snd_ice1712_spdif_maskc_get,};static snd_kcontrol_new_t snd_ice1712_spdif_maskp __devinitdata ={	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),	.info =		snd_ice1712_spdif_info,	.get =		snd_ice1712_spdif_maskp_get,};static int snd_ice1712_spdif_stream_get(snd_kcontrol_t * kcontrol,					snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	if (ice->spdif.ops.stream_get)		ice->spdif.ops.stream_get(ice, ucontrol);	return 0;}static int snd_ice1712_spdif_stream_put(snd_kcontrol_t * kcontrol,					snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	if (ice->spdif.ops.stream_put)		return ice->spdif.ops.stream_put(ice, ucontrol);	return 0;}static snd_kcontrol_new_t snd_ice1712_spdif_stream __devinitdata ={	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),	.info =		snd_ice1712_spdif_info,	.get =		snd_ice1712_spdif_stream_get,	.put =		snd_ice1712_spdif_stream_put};int snd_ice1712_gpio_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;

⌨️ 快捷键说明

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