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

📄 ice1712.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	return 0;}int snd_ice1712_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	unsigned char mask = kcontrol->private_value & 0xff;	int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;		snd_ice1712_save_gpio_status(ice);	ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert;	snd_ice1712_restore_gpio_status(ice);	return 0;}int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	unsigned char mask = kcontrol->private_value & 0xff;	int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;	unsigned int val, nval;	if (kcontrol->private_value & (1 << 31))		return -EPERM;	nval = (ucontrol->value.integer.value[0] ? mask : 0) ^ invert;	snd_ice1712_save_gpio_status(ice);	val = snd_ice1712_gpio_read(ice);	nval |= val & ~mask;	if (val != nval)		snd_ice1712_gpio_write(ice, nval);	snd_ice1712_restore_gpio_status(ice);	return val != nval;}/* *  rate */static int snd_ice1712_pro_internal_clock_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[] = {		"8000",		/* 0: 6 */		"9600",		/* 1: 3 */		"11025",	/* 2: 10 */		"12000",	/* 3: 2 */		"16000",	/* 4: 5 */		"22050",	/* 5: 9 */		"24000",	/* 6: 1 */		"32000",	/* 7: 4 */		"44100",	/* 8: 8 */		"48000",	/* 9: 0 */		"64000",	/* 10: 15 */		"88200",	/* 11: 11 */		"96000",	/* 12: 7 */		"IEC958 Input",	/* 13: -- */	};	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 14;	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_ice1712_pro_internal_clock_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	static unsigned char xlate[16] = {		9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10	};	unsigned char val;		spin_lock_irq(&ice->reg_lock);	if (is_spdif_master(ice)) {		ucontrol->value.enumerated.item[0] = 13;	} else {		val = xlate[inb(ICEMT(ice, RATE)) & 15];		if (val == 255) {			snd_BUG();			val = 0;		}		ucontrol->value.enumerated.item[0] = val;	}	spin_unlock_irq(&ice->reg_lock);	return 0;}static int snd_ice1712_pro_internal_clock_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	static unsigned int xrate[13] = {		8000, 9600, 11025, 12000, 1600, 22050, 24000,		32000, 44100, 48000, 64000, 88200, 96000	};	unsigned char oval;	int change = 0;	spin_lock_irq(&ice->reg_lock);	oval = inb(ICEMT(ice, RATE));	if (ucontrol->value.enumerated.item[0] == 13) {		outb(oval | ICE1712_SPDIF_MASTER, ICEMT(ice, RATE));	} else {		PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13];		spin_unlock_irq(&ice->reg_lock);		snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 1);		spin_lock_irq(&ice->reg_lock);	}	change = inb(ICEMT(ice, RATE)) != oval;	spin_unlock_irq(&ice->reg_lock);	if ((oval & ICE1712_SPDIF_MASTER) != (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) {		/* change CS8427 clock source too */		if (ice->cs8427) {			snd_ice1712_cs8427_set_input_clock(ice, is_spdif_master(ice));		}		/* notify ak4524 chip as well */		if (is_spdif_master(ice)) {			unsigned int i;			for (i = 0; i < ice->akm_codecs; i++) {				if (ice->akm[i].ops.set_rate_val)					ice->akm[i].ops.set_rate_val(&ice->akm[i], 0);			}		}	}	return change;}static snd_kcontrol_new_t snd_ice1712_pro_internal_clock __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "Multi Track Internal Clock",	.info = snd_ice1712_pro_internal_clock_info,	.get = snd_ice1712_pro_internal_clock_get,	.put = snd_ice1712_pro_internal_clock_put};static int snd_ice1712_pro_internal_clock_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[] = {		"8000",		/* 0: 6 */		"9600",		/* 1: 3 */		"11025",	/* 2: 10 */		"12000",	/* 3: 2 */		"16000",	/* 4: 5 */		"22050",	/* 5: 9 */		"24000",	/* 6: 1 */		"32000",	/* 7: 4 */		"44100",	/* 8: 8 */		"48000",	/* 9: 0 */		"64000",	/* 10: 15 */		"88200",	/* 11: 11 */		"96000",	/* 12: 7 */		// "IEC958 Input",	/* 13: -- */	};	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 13;	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_ice1712_pro_internal_clock_default_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	int val;	static unsigned int xrate[13] = {		8000, 9600, 11025, 12000, 1600, 22050, 24000,		32000, 44100, 48000, 64000, 88200, 96000	};	for (val = 0; val < 13; val++) {		if (xrate[val] == PRO_RATE_DEFAULT)			break;	}	ucontrol->value.enumerated.item[0] = val;	return 0;}static int snd_ice1712_pro_internal_clock_default_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	static unsigned int xrate[13] = {		8000, 9600, 11025, 12000, 1600, 22050, 24000,		32000, 44100, 48000, 64000, 88200, 96000	};	unsigned char oval;	int change = 0;	oval = PRO_RATE_DEFAULT;	PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13];	change = PRO_RATE_DEFAULT != oval;	return change;}static snd_kcontrol_new_t snd_ice1712_pro_internal_clock_default __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "Multi Track Internal Clock Default",	.info = snd_ice1712_pro_internal_clock_default_info,	.get = snd_ice1712_pro_internal_clock_default_get,	.put = snd_ice1712_pro_internal_clock_default_put};static int snd_ice1712_pro_rate_locking_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_ice1712_pro_rate_locking_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;	return 0;}static int snd_ice1712_pro_rate_locking_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int change = 0, nval;	nval = ucontrol->value.integer.value[0] ? 1 : 0;	spin_lock_irq(&ice->reg_lock);	change = PRO_RATE_LOCKED != nval;	PRO_RATE_LOCKED = nval;	spin_unlock_irq(&ice->reg_lock);	return change;}static snd_kcontrol_new_t snd_ice1712_pro_rate_locking __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "Multi Track Rate Locking",	.info = snd_ice1712_pro_rate_locking_info,	.get = snd_ice1712_pro_rate_locking_get,	.put = snd_ice1712_pro_rate_locking_put};static int snd_ice1712_pro_rate_reset_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_ice1712_pro_rate_reset_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ucontrol->value.integer.value[0] = PRO_RATE_RESET;	return 0;}static int snd_ice1712_pro_rate_reset_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int change = 0, nval;	nval = ucontrol->value.integer.value[0] ? 1 : 0;	spin_lock_irq(&ice->reg_lock);	change = PRO_RATE_RESET != nval;	PRO_RATE_RESET = nval;	spin_unlock_irq(&ice->reg_lock);	return change;}static snd_kcontrol_new_t snd_ice1712_pro_rate_reset __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "Multi Track Rate Reset",	.info = snd_ice1712_pro_rate_reset_info,	.get = snd_ice1712_pro_rate_reset_get,	.put = snd_ice1712_pro_rate_reset_put};/* * routing */static int snd_ice1712_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[] = {		"PCM Out", /* 0 */		"H/W In 0", "H/W In 1", "H/W In 2", "H/W In 3", /* 1-4 */		"H/W In 4", "H/W In 5", "H/W In 6", "H/W In 7", /* 5-8 */		"IEC958 In L", "IEC958 In R", /* 9-10 */		"Digital Mixer", /* 11 - optional */	};		uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11;	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_ice1712_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);	unsigned int val, cval;	spin_lock_irq(&ice->reg_lock);	val = inw(ICEMT(ice, ROUTE_PSDOUT03));	cval = inl(ICEMT(ice, ROUTE_CAPTURE));	spin_unlock_irq(&ice->reg_lock);	val >>= ((idx % 2) * 8) + ((idx / 2) * 2);	val &= 3;	cval >>= ((idx / 2) * 8) + ((idx % 2) * 4);	if (val == 1 && idx < 2)		ucontrol->value.enumerated.item[0] = 11;	else if (val == 2)		ucontrol->value.enumerated.item[0] = (cval & 7) + 1;	else if (val == 3)		ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;	else		ucontrol->value.enumerated.item[0] = 0;	return 0;}static int snd_ice1712_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int change, shift;	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);	unsigned int val, old_val, nval;		/* update PSDOUT */	if (ucontrol->value.enumerated.item[0] >= 11)		nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */	else if (ucontrol->value.enumerated.item[0] >= 9)		nval = 3; /* spdif in */	else if (ucontrol->value.enumerated.item[0] >= 1)		nval = 2; /* analog in */	else		nval = 0; /* pcm */	shift = ((idx % 2) * 8) + ((idx / 2) * 2);	spin_lock_irq(&ice->reg_lock);	val = old_val = inw(ICEMT(ice, ROUTE_PSDOUT03));	val &= ~(0x03 << shift);	val |= nval << shift;	change = val != old_val;	if (change)		outw(val, ICEMT(ice, ROUTE_PSDOUT03));	spin_unlock_irq(&ice->reg_lock);	if (nval < 2) /* dig mixer of pcm */		return change;	/* update CAPTURE */	spin_lock_irq(&ice->reg_lock);	val = old_val = inl(ICEMT(ice, ROUTE_CAPTURE));	shift = ((idx / 2) * 8) + ((idx % 2) * 4);	if (nval == 2) { /* analog in */		nval = ucontrol->value.enumerated.item[0] - 1;		val &= ~(0x07 << shift);		val |= nval << shift;	} else { /* spdif in */		nval = (ucontrol->value.enumerated.item[0] - 9) << 3;		val &= ~(0x08 << shift);		val |= nval << shift;	}	if (val != old_val) {		change = 1;		outl(val, ICEMT(ice, ROUTE_CAPTURE));	}	spin_unlock_irq(&ice->reg_lock);	return change;}static int snd_ice1712_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);	unsigned int val, cval;	val = inw(ICEMT(ice, ROUTE_SPDOUT));	cval = (val >> (idx * 4 + 8)) & 0x0f;	val = (val >> (idx * 2)) & 0x03;	if (val == 1)		ucontrol->value.enumerated.item[0] = 11;	else if (val == 2)		ucontrol->value.enumerated.item[0] = (cval & 7) + 1;	else if (val == 3)		ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;	else		ucontrol->value.enumerated.item[0] = 0;	return 0;}static int snd_ice1712_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	int change, shift;	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);	unsigned int val, old_val, nval;		/* update SPDOUT */	spin_lock_irq(&ice->reg_lock);	val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT));	if (ucontrol->value.enumerated.item[0] >= 11)		nval = 1;	else if (ucontrol->value.enumerated.item[0] >= 9)		nval = 3;	else if (ucontrol->value.enumerated.item[0] >= 1)		nval = 2;	else		nval = 0;	shift = idx * 2;	val &= ~(0x03 << shift);	val |= nval << shift;	shift = idx * 4 + 8;	if (nval == 2) {		nval = ucontrol->value.enumerated.item[0] - 1;		val &= ~(0x07 << shift);		val |= nval << shift;	} else if (nval == 3) {		nval = (ucontrol->value.enumerated.item[0] - 9) << 3;		val &= ~(0x08 << shift);		val |= nval << shift;	}	change = val != old_val;	if (change)		outw(val, ICEMT(ice, ROUTE_SPDOUT));	spin_unlock_irq(&ice->reg_lock);	return change;}static snd_kcontrol_new_t snd_ice1712_mixer_pro_analog_route __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "H/W Playback Route",	.info = snd_ice1712_pro_route_info,	.get = snd_ice1712_pro_route_analog_get,	.put = snd_ice1712_pro_route_analog_put,};static snd_kcontrol_new_t snd_ice1712_mixer_pro_spdif_route __devinitda

⌨️ 快捷键说明

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