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

📄 ice1724.c

📁 linux2.6.16版本
💻 C
📖 第 1 页 / 共 5 页
字号:
static void decode_spdif_bits(struct snd_aes_iec958 *diga, unsigned int val){	memset(diga->status, 0, sizeof(diga->status));	diga->status[0] = val & 0x03; /* professional, non-audio */	if (val & 0x01) {		/* professional */		if (val & (1U << 3))			diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015;		switch ((val >> 12) & 0x7) {		case 0:			break;		case 2:			diga->status[0] |= IEC958_AES0_PRO_FS_32000;			break;		default:			diga->status[0] |= IEC958_AES0_PRO_FS_48000;			break;		}	} else {		/* consumer */		diga->status[0] |= val & (1U << 2); /* copyright */		if (val & (1U << 3))			diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015;		diga->status[1] |= (val >> 4) & 0x3f; /* category */		diga->status[3] |= (val >> 12) & 0x07; /* fs */	}}static int snd_vt1724_spdif_default_get(struct snd_kcontrol *kcontrol,					struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);	unsigned int val;	val = inw(ICEMT1724(ice, SPDIF_CTRL));	decode_spdif_bits(&ucontrol->value.iec958, val);	return 0;}static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,					 struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);	unsigned int val, old;	val = encode_spdif_bits(&ucontrol->value.iec958);	spin_lock_irq(&ice->reg_lock);	old = inw(ICEMT1724(ice, SPDIF_CTRL));	if (val != old)		update_spdif_bits(ice, val);	spin_unlock_irq(&ice->reg_lock);	return (val != old);}static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata ={	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),	.info =		snd_vt1724_spdif_info,	.get =		snd_vt1724_spdif_default_get,	.put =		snd_vt1724_spdif_default_put};static int snd_vt1724_spdif_maskc_get(struct snd_kcontrol *kcontrol,				       struct snd_ctl_elem_value *ucontrol){	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;	return 0;}static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol,				       struct snd_ctl_elem_value *ucontrol){	ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |						     IEC958_AES0_PROFESSIONAL |						     IEC958_AES0_PRO_FS |						     IEC958_AES0_PRO_EMPHASIS;	return 0;}static struct snd_kcontrol_new snd_vt1724_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_vt1724_spdif_info,	.get =		snd_vt1724_spdif_maskc_get,};static struct snd_kcontrol_new snd_vt1724_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_vt1724_spdif_info,	.get =		snd_vt1724_spdif_maskp_get,};static int snd_vt1724_spdif_sw_info(struct snd_kcontrol *kcontrol,				    struct snd_ctl_elem_info *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_vt1724_spdif_sw_get(struct snd_kcontrol *kcontrol,				   struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);	ucontrol->value.integer.value[0] = inb(ICEREG1724(ice, SPDIF_CFG)) &		VT1724_CFG_SPDIF_OUT_EN ? 1 : 0;	return 0;}static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,				   struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);	unsigned char old, val;	spin_lock_irq(&ice->reg_lock);	old = val = inb(ICEREG1724(ice, SPDIF_CFG));	val &= ~VT1724_CFG_SPDIF_OUT_EN;	if (ucontrol->value.integer.value[0])		val |= VT1724_CFG_SPDIF_OUT_EN;	if (old != val)		outb(val, ICEREG1724(ice, SPDIF_CFG));	spin_unlock_irq(&ice->reg_lock);	return old != val;}static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata ={	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,	/* FIXME: the following conflict with IEC958 Playback Route */	// .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),	.name =         SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),	.info =		snd_vt1724_spdif_sw_info,	.get =		snd_vt1724_spdif_sw_get,	.put =		snd_vt1724_spdif_sw_put};#if 0 /* NOT USED YET *//* * GPIO access from extern */int snd_vt1724_gpio_info(struct snd_kcontrol *kcontrol,			 struct snd_ctl_elem_info *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;	uinfo->count = 1;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = 1;	return 0;}int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol,			struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);	int shift = 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) & (1 << shift) ? 1 : 0) ^ invert;	snd_ice1712_restore_gpio_status(ice);	return 0;}int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol,			 struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);	int shift = 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] ? (1 << shift) : 0) ^ invert;	snd_ice1712_save_gpio_status(ice);	val = snd_ice1712_gpio_read(ice);	nval |= val & ~(1 << shift);	if (val != nval)		snd_ice1712_gpio_write(ice, nval);	snd_ice1712_restore_gpio_status(ice);	return val != nval;}#endif /* NOT USED YET *//* *  rate */static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,					      struct snd_ctl_elem_info *uinfo){	static char *texts_1724[] = {		"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 */		"176400",	/* 13: 12 */		"192000",	/* 14: 14 */		"IEC958 Input",	/* 15: -- */	};	static char *texts_1720[] = {		"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: -- */	};	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = ice->vt1720 ? 14 : 16;	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;	strcpy(uinfo->value.enumerated.name,	       ice->vt1720 ? texts_1720[uinfo->value.enumerated.item] :	       texts_1724[uinfo->value.enumerated.item]);	return 0;}static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,					     struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);	static unsigned char xlate[16] = {		9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 13, 255, 14, 10	};	unsigned char val;		spin_lock_irq(&ice->reg_lock);	if (is_spdif_master(ice)) {		ucontrol->value.enumerated.item[0] = ice->vt1720 ? 13 : 15;	} else {		val = xlate[inb(ICEMT1724(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_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,					     struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);	unsigned char oval;	int rate;	int change = 0;	int spdif = ice->vt1720 ? 13 : 15;	spin_lock_irq(&ice->reg_lock);	oval = inb(ICEMT1724(ice, RATE));	if (ucontrol->value.enumerated.item[0] == spdif) {		outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));	} else {		rate = rates[ucontrol->value.integer.value[0] % 15];		if (rate <= get_max_rate(ice)) {			PRO_RATE_DEFAULT = rate;			spin_unlock_irq(&ice->reg_lock);			snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 1);			spin_lock_irq(&ice->reg_lock);		}	}	change = inb(ICEMT1724(ice, RATE)) != oval;	spin_unlock_irq(&ice->reg_lock);	if ((oval & VT1724_SPDIF_MASTER) !=	    (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER)) {		/* notify akm chips 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 struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "Multi Track Internal Clock",	.info = snd_vt1724_pro_internal_clock_info,	.get = snd_vt1724_pro_internal_clock_get,	.put = snd_vt1724_pro_internal_clock_put};static int snd_vt1724_pro_rate_locking_info(struct snd_kcontrol *kcontrol,					    struct snd_ctl_elem_info *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_vt1724_pro_rate_locking_get(struct snd_kcontrol *kcontrol,					   struct snd_ctl_elem_value *ucontrol){	ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;	return 0;}static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,					   struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *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 struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "Multi Track Rate Locking",	.info = snd_vt1724_pro_rate_locking_info,	.get = snd_vt1724_pro_rate_locking_get,	.put = snd_vt1724_pro_rate_locking_put};static int snd_vt1724_pro_rate_reset_info(struct snd_kcontrol *kcontrol,					  struct snd_ctl_elem_info *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_vt1724_pro_rate_reset_get(struct snd_kcontrol *kcontrol,					 struct snd_ctl_elem_value *ucontrol){	ucontrol->value.integer.value[0] = PRO_RATE_RESET ? 1 : 0;	return 0;}static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,					 struct snd_ctl_elem_value *ucontrol){	struct snd_ice1712 *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 struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	.name = "Multi Track Rate Reset",	.info = snd_vt1724_pro_rate_reset_info,	.get = snd_vt1724_pro_rate_reset_get,	.put = snd_vt1724_pro_rate_reset_put};/* * routing */static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol,				     struct snd_ctl_elem_info *uinfo){	static char *texts[] = {		"PCM Out", /* 0 */		"H/W In 0", "H/W In 1", /* 1-2 */		"IEC958 In L", "IEC958 In R", /* 3-4 */	};		uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 5;	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 inline int analog_route_shift(int idx){	return (idx % 2) * 12 + ((idx / 2) * 3) + 8;}static inline int digital_route_shift(int idx){	return idx * 3;}static int get_route_val(struct snd_ice1712 *ice, int shift){	unsigned long val;	unsigned char eitem;	static unsigned char xlate[8] = {		0, 255, 1, 2, 255, 255, 3, 4,	};	val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));	val >>= shift;	val &= 7;	//we now have 3 bits per output	eitem = xlate[val];	if (eitem == 255) {		snd_BUG();		return 0;	}	return eitem;}static int put_route_val(struct snd_ice1712 *ice, unsigned int val, int shift){	unsigned int old_val, nval;	int change;

⌨️ 快捷键说明

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