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

📄 rme96.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	return change;}static intsnd_rme96_info_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	static char *_texts[5] = { "Optical", "Coaxial", "Internal", "XLR", "Analog" };	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	char *texts[5] = { _texts[0], _texts[1], _texts[2], _texts[3], _texts[4] };		uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	switch (rme96->pci->device) {	case PCI_DEVICE_ID_RME_DIGI96:	case PCI_DEVICE_ID_RME_DIGI96_8:		uinfo->value.enumerated.items = 3;		break;	case PCI_DEVICE_ID_RME_DIGI96_8_PRO:		uinfo->value.enumerated.items = 4;		break;	case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:		if (rme96->rev > 4) {			/* PST */			uinfo->value.enumerated.items = 4;			texts[3] = _texts[4]; /* Analog instead of XLR */		} else {			/* PAD */			uinfo->value.enumerated.items = 5;		}		break;	default:		snd_BUG();		break;	}	if (uinfo->value.enumerated.item > uinfo->value.enumerated.items - 1) {		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;	}	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static intsnd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	unsigned int items = 3;		spin_lock_irq(&rme96->lock);	ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96);		switch (rme96->pci->device) {	case PCI_DEVICE_ID_RME_DIGI96:	case PCI_DEVICE_ID_RME_DIGI96_8:		items = 3;		break;	case PCI_DEVICE_ID_RME_DIGI96_8_PRO:		items = 4;		break;	case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:		if (rme96->rev > 4) {			/* for handling PST case, (INPUT_ANALOG is moved to INPUT_XLR */			if (ucontrol->value.enumerated.item[0] == RME96_INPUT_ANALOG) {				ucontrol->value.enumerated.item[0] = RME96_INPUT_XLR;			}			items = 4;		} else {			items = 5;		}		break;	default:		snd_BUG();		break;	}	if (ucontrol->value.enumerated.item[0] >= items) {		ucontrol->value.enumerated.item[0] = items - 1;	}		spin_unlock_irq(&rme96->lock);	return 0;}static intsnd_rme96_put_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change, items = 3;		switch (rme96->pci->device) {	case PCI_DEVICE_ID_RME_DIGI96:	case PCI_DEVICE_ID_RME_DIGI96_8:		items = 3;		break;	case PCI_DEVICE_ID_RME_DIGI96_8_PRO:		items = 4;		break;	case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST:		if (rme96->rev > 4) {			items = 4;		} else {			items = 5;		}		break;	default:		snd_BUG();		break;	}	val = ucontrol->value.enumerated.item[0] % items;		/* special case for PST */	if (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && rme96->rev > 4) {		if (val == RME96_INPUT_XLR) {			val = RME96_INPUT_ANALOG;		}	}		spin_lock_irq(&rme96->lock);	change = (int)val != snd_rme96_getinputtype(rme96);	snd_rme96_setinputtype(rme96, val);	spin_unlock_irq(&rme96->lock);	return change;}static intsnd_rme96_info_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	static char *texts[3] = { "AutoSync", "Internal", "Word" };		uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 3;	if (uinfo->value.enumerated.item > 2) {		uinfo->value.enumerated.item = 2;	}	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static intsnd_rme96_get_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);		spin_lock_irq(&rme96->lock);	ucontrol->value.enumerated.item[0] = snd_rme96_getclockmode(rme96);	spin_unlock_irq(&rme96->lock);	return 0;}static intsnd_rme96_put_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change;		val = ucontrol->value.enumerated.item[0] % 3;	spin_lock_irq(&rme96->lock);	change = (int)val != snd_rme96_getclockmode(rme96);	snd_rme96_setclockmode(rme96, val);	spin_unlock_irq(&rme96->lock);	return change;}static intsnd_rme96_info_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	static char *texts[4] = { "0 dB", "-6 dB", "-12 dB", "-18 dB" };		uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 4;	if (uinfo->value.enumerated.item > 3) {		uinfo->value.enumerated.item = 3;	}	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static intsnd_rme96_get_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);		spin_lock_irq(&rme96->lock);	ucontrol->value.enumerated.item[0] = snd_rme96_getattenuation(rme96);	spin_unlock_irq(&rme96->lock);	return 0;}static intsnd_rme96_put_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change;		val = ucontrol->value.enumerated.item[0] % 4;	spin_lock_irq(&rme96->lock);	change = (int)val != snd_rme96_getattenuation(rme96);	snd_rme96_setattenuation(rme96, val);	spin_unlock_irq(&rme96->lock);	return change;}static intsnd_rme96_info_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	static char *texts[4] = { "1+2", "3+4", "5+6", "7+8" };		uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 4;	if (uinfo->value.enumerated.item > 3) {		uinfo->value.enumerated.item = 3;	}	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static intsnd_rme96_get_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);		spin_lock_irq(&rme96->lock);	ucontrol->value.enumerated.item[0] = snd_rme96_getmontracks(rme96);	spin_unlock_irq(&rme96->lock);	return 0;}static intsnd_rme96_put_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change;		val = ucontrol->value.enumerated.item[0] % 4;	spin_lock_irq(&rme96->lock);	change = (int)val != snd_rme96_getmontracks(rme96);	snd_rme96_setmontracks(rme96, val);	spin_unlock_irq(&rme96->lock);	return change;}static u32 snd_rme96_convert_from_aes(struct snd_aes_iec958 *aes){	u32 val = 0;	val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME96_WCR_PRO : 0;	val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? RME96_WCR_DOLBY : 0;	if (val & RME96_WCR_PRO)		val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME96_WCR_EMP : 0;	else		val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME96_WCR_EMP : 0;	return val;}static void snd_rme96_convert_to_aes(struct snd_aes_iec958 *aes, u32 val){	aes->status[0] = ((val & RME96_WCR_PRO) ? IEC958_AES0_PROFESSIONAL : 0) |			 ((val & RME96_WCR_DOLBY) ? IEC958_AES0_NONAUDIO : 0);	if (val & RME96_WCR_PRO)		aes->status[0] |= (val & RME96_WCR_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;	else		aes->status[0] |= (val & RME96_WCR_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;}static int snd_rme96_control_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;	uinfo->count = 1;	return 0;}static int snd_rme96_control_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);		snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif);	return 0;}static int snd_rme96_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	int change;	u32 val;		val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);	spin_lock_irq(&rme96->lock);	change = val != rme96->wcreg_spdif;	rme96->wcreg_spdif = val;	spin_unlock_irq(&rme96->lock);	return change;}static int snd_rme96_control_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;	uinfo->count = 1;	return 0;}static int snd_rme96_control_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);		snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif_stream);	return 0;}static int snd_rme96_control_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	int change;	u32 val;		val = snd_rme96_convert_from_aes(&ucontrol->value.iec958);	spin_lock_irq(&rme96->lock);	change = val != rme96->wcreg_spdif_stream;	rme96->wcreg_spdif_stream = val;	rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);	rme96->wcreg |= val;	writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);	spin_unlock_irq(&rme96->lock);	return change;}static int snd_rme96_control_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;	uinfo->count = 1;	return 0;}static int snd_rme96_control_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	ucontrol->value.iec958.status[0] = kcontrol->private_value;	return 0;}static intsnd_rme96_dac_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;        uinfo->count = 2;        uinfo->value.integer.min = 0;	uinfo->value.integer.max = RME96_185X_MAX_OUT(rme96);        return 0;}static intsnd_rme96_dac_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);	spin_lock_irq(&rme96->lock);        u->value.integer.value[0] = rme96->vol[0];        u->value.integer.value[1] = rme96->vol[1];	spin_unlock_irq(&rme96->lock);        return 0;}static intsnd_rme96_dac_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u){	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);        int change = 0;	if (!RME96_HAS_ANALOG_OUT(rme96)) {		return -EINVAL;	}	spin_lock_irq(&rme96->lock);        if (u->value.integer.value[0] != rme96->vol[0]) {		rme96->vol[0] = u->value.integer.value[0];                change = 1;        }        if (u->value.integer.value[1] != rme96->vol[1]) {		rme96->vol[1] = u->value.integer.value[1];                change = 1;        }	if (change) {		snd_rme96_apply_dac_volume(rme96);	}	spin_unlock_irq(&rme96->lock);        return change;}static struct snd_kcontrol_new snd_rme96_controls[] = {{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),	.info =		snd_rme96_control_spdif_info,	.get =		snd_rme96_control_spdif_get,	.put =		snd_rme96_control_spdif_put},{	.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_rme96_control_spdif_stream_info,	.get =		snd_rme96_control_spdif_stream_get,	.put =		snd_rme96_control_spdif_stream_put},{	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),	.info =		snd_rme96_control_spdif_mask_info,	.get =		snd_rme96_control_spdif_mask_get,	.private_value = IEC958_AES0_NONAUDIO |			IEC958_AES0_PROFESSIONAL |			IEC958_AES0_CON_EMPHASIS},{	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),	.info =		snd_rme96_control_spdif_mask_info,	.get =		snd_rme96_control_spdif_mask_get,	.private_value = IEC958_AES0_NONAUDIO |			IEC958_AES0_PROFESSIONAL |			IEC958_AES0_PRO_EMPHASIS},{        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,	.name =         "Input Connector",	.info =         snd_rme96_info_inputtype_control, 	.get =          snd_rme96_get_inputtype_control,	.put =          snd_rme96_put_inputtype_control },{        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,	.name =         "Loopback Input",	.info =         snd_rme96_info_loopback_control,	.get =          snd_rme96_get_loopback_control,	.put =          snd_rme96_put_loopback_control},{        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,	.name =         "Sample Clock Source",	.info =         snd_rme96_info_clockmode_control, 	.get =          snd_rme96_get_clockmode_control,	.put =          snd_rme96_put_clockmode_control},{        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,	.name =         "Monitor Tracks",	.info =         snd_rme96_info_montracks_control, 	.get =          snd_rme96_get_montracks_control,	.put =          snd_rme96_put_montracks_control},{        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,	.name =         "Attenuation",	.info =         snd_rme96_info_attenuation_control, 	.get =          snd_rme96_get_attenuation_control,	.put =   

⌨️ 快捷键说明

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