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

📄 rme32.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		break;	case RME32_INPUT_XLR:		snd_iprintf(buffer, "  input: XLR");		break;	}	if (snd_rme32_capture_getrate(rme32, &n) < 0) {		snd_iprintf(buffer, "\n  sample rate: no valid signal\n");	} else {		if (n) {			snd_iprintf(buffer, " (8 channels)\n");		} else {			snd_iprintf(buffer, " (2 channels)\n");		}		snd_iprintf(buffer, "  sample rate: %d Hz\n",			    snd_rme32_capture_getrate(rme32, &n));	}	snd_iprintf(buffer, "\nOutput settings\n");	if (rme32->wcreg & RME32_WCR_SEL) {		snd_iprintf(buffer, "  output signal: normal playback");	} else {		snd_iprintf(buffer, "  output signal: same as input");	}	if (rme32->wcreg & RME32_WCR_MUTE) {		snd_iprintf(buffer, " (muted)\n");	} else {		snd_iprintf(buffer, "\n");	}	/* master output frequency */	if (!	    ((!(rme32->wcreg & RME32_WCR_FREQ_0))	     && (!(rme32->wcreg & RME32_WCR_FREQ_1)))) {		snd_iprintf(buffer, "  sample rate: %d Hz\n",			    snd_rme32_playback_getrate(rme32));	}	if (rme32->rcreg & RME32_RCR_KMODE) {		snd_iprintf(buffer, "  sample clock source: AutoSync\n");	} else {		snd_iprintf(buffer, "  sample clock source: Internal\n");	}	if (rme32->wcreg & RME32_WCR_PRO) {		snd_iprintf(buffer, "  format: AES/EBU (professional)\n");	} else {		snd_iprintf(buffer, "  format: IEC958 (consumer)\n");	}	if (rme32->wcreg & RME32_WCR_EMP) {		snd_iprintf(buffer, "  emphasis: on\n");	} else {		snd_iprintf(buffer, "  emphasis: off\n");	}}static void __devinit snd_rme32_proc_init(struct rme32 * rme32){	struct snd_info_entry *entry;	if (! snd_card_proc_new(rme32->card, "rme32", &entry))		snd_info_set_text_ops(entry, rme32, snd_rme32_proc_read);}/* * control interface */#define snd_rme32_info_loopback_control		snd_ctl_boolean_mono_infostatic intsnd_rme32_get_loopback_control(struct snd_kcontrol *kcontrol,			       struct snd_ctl_elem_value *ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	spin_lock_irq(&rme32->lock);	ucontrol->value.integer.value[0] =	    rme32->wcreg & RME32_WCR_SEL ? 0 : 1;	spin_unlock_irq(&rme32->lock);	return 0;}static intsnd_rme32_put_loopback_control(struct snd_kcontrol *kcontrol,			       struct snd_ctl_elem_value *ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change;	val = ucontrol->value.integer.value[0] ? 0 : RME32_WCR_SEL;	spin_lock_irq(&rme32->lock);	val = (rme32->wcreg & ~RME32_WCR_SEL) | val;	change = val != rme32->wcreg;	if (ucontrol->value.integer.value[0])		val &= ~RME32_WCR_MUTE;	else		val |= RME32_WCR_MUTE;	rme32->wcreg = val;	writel(val, rme32->iobase + RME32_IO_CONTROL_REGISTER);	spin_unlock_irq(&rme32->lock);	return change;}static intsnd_rme32_info_inputtype_control(struct snd_kcontrol *kcontrol,				 struct snd_ctl_elem_info *uinfo){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	static char *texts[4] = { "Optical", "Coaxial", "Internal", "XLR" };	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	switch (rme32->pci->device) {	case PCI_DEVICE_ID_RME_DIGI32:	case PCI_DEVICE_ID_RME_DIGI32_8:		uinfo->value.enumerated.items = 3;		break;	case PCI_DEVICE_ID_RME_DIGI32_PRO:		uinfo->value.enumerated.items = 4;		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_rme32_get_inputtype_control(struct snd_kcontrol *kcontrol,				struct snd_ctl_elem_value *ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	unsigned int items = 3;	spin_lock_irq(&rme32->lock);	ucontrol->value.enumerated.item[0] = snd_rme32_getinputtype(rme32);	switch (rme32->pci->device) {	case PCI_DEVICE_ID_RME_DIGI32:	case PCI_DEVICE_ID_RME_DIGI32_8:		items = 3;		break;	case PCI_DEVICE_ID_RME_DIGI32_PRO:		items = 4;		break;	default:		snd_BUG();		break;	}	if (ucontrol->value.enumerated.item[0] >= items) {		ucontrol->value.enumerated.item[0] = items - 1;	}	spin_unlock_irq(&rme32->lock);	return 0;}static intsnd_rme32_put_inputtype_control(struct snd_kcontrol *kcontrol,				struct snd_ctl_elem_value *ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change, items = 3;	switch (rme32->pci->device) {	case PCI_DEVICE_ID_RME_DIGI32:	case PCI_DEVICE_ID_RME_DIGI32_8:		items = 3;		break;	case PCI_DEVICE_ID_RME_DIGI32_PRO:		items = 4;		break;	default:		snd_BUG();		break;	}	val = ucontrol->value.enumerated.item[0] % items;	spin_lock_irq(&rme32->lock);	change = val != (unsigned int)snd_rme32_getinputtype(rme32);	snd_rme32_setinputtype(rme32, val);	spin_unlock_irq(&rme32->lock);	return change;}static intsnd_rme32_info_clockmode_control(struct snd_kcontrol *kcontrol,				 struct snd_ctl_elem_info *uinfo){	static char *texts[4] = { "AutoSync", 				  "Internal 32.0kHz", 				  "Internal 44.1kHz", 				  "Internal 48.0kHz" };	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_rme32_get_clockmode_control(struct snd_kcontrol *kcontrol,				struct snd_ctl_elem_value *ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	spin_lock_irq(&rme32->lock);	ucontrol->value.enumerated.item[0] = snd_rme32_getclockmode(rme32);	spin_unlock_irq(&rme32->lock);	return 0;}static intsnd_rme32_put_clockmode_control(struct snd_kcontrol *kcontrol,				struct snd_ctl_elem_value *ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	unsigned int val;	int change;	val = ucontrol->value.enumerated.item[0] % 3;	spin_lock_irq(&rme32->lock);	change = val != (unsigned int)snd_rme32_getclockmode(rme32);	snd_rme32_setclockmode(rme32, val);	spin_unlock_irq(&rme32->lock);	return change;}static u32 snd_rme32_convert_from_aes(struct snd_aes_iec958 * aes){	u32 val = 0;	val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME32_WCR_PRO : 0;	if (val & RME32_WCR_PRO)		val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME32_WCR_EMP : 0;	else		val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME32_WCR_EMP : 0;	return val;}static void snd_rme32_convert_to_aes(struct snd_aes_iec958 * aes, u32 val){	aes->status[0] = ((val & RME32_WCR_PRO) ? IEC958_AES0_PROFESSIONAL : 0);	if (val & RME32_WCR_PRO)		aes->status[0] |= (val & RME32_WCR_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;	else		aes->status[0] |= (val & RME32_WCR_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;}static int snd_rme32_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_rme32_control_spdif_get(struct snd_kcontrol *kcontrol,				       struct snd_ctl_elem_value *ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	snd_rme32_convert_to_aes(&ucontrol->value.iec958,				 rme32->wcreg_spdif);	return 0;}static int snd_rme32_control_spdif_put(struct snd_kcontrol *kcontrol,				       struct snd_ctl_elem_value *ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	int change;	u32 val;	val = snd_rme32_convert_from_aes(&ucontrol->value.iec958);	spin_lock_irq(&rme32->lock);	change = val != rme32->wcreg_spdif;	rme32->wcreg_spdif = val;	spin_unlock_irq(&rme32->lock);	return change;}static int snd_rme32_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_rme32_control_spdif_stream_get(struct snd_kcontrol *kcontrol,					      struct snd_ctl_elem_value *					      ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	snd_rme32_convert_to_aes(&ucontrol->value.iec958,				 rme32->wcreg_spdif_stream);	return 0;}static int snd_rme32_control_spdif_stream_put(struct snd_kcontrol *kcontrol,					      struct snd_ctl_elem_value *					      ucontrol){	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);	int change;	u32 val;	val = snd_rme32_convert_from_aes(&ucontrol->value.iec958);	spin_lock_irq(&rme32->lock);	change = val != rme32->wcreg_spdif_stream;	rme32->wcreg_spdif_stream = val;	rme32->wcreg &= ~(RME32_WCR_PRO | RME32_WCR_EMP);	rme32->wcreg |= val;	writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);	spin_unlock_irq(&rme32->lock);	return change;}static int snd_rme32_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_rme32_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 struct snd_kcontrol_new snd_rme32_controls[] = {	{		.iface = SNDRV_CTL_ELEM_IFACE_PCM,		.name =	SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),		.info =	snd_rme32_control_spdif_info,		.get =	snd_rme32_control_spdif_get,		.put =	snd_rme32_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_rme32_control_spdif_stream_info,		.get =	snd_rme32_control_spdif_stream_get,		.put =	snd_rme32_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_rme32_control_spdif_mask_info,		.get =	snd_rme32_control_spdif_mask_get,		.private_value = 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_rme32_control_spdif_mask_info,		.get =	snd_rme32_control_spdif_mask_get,		.private_value = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_EMPHASIS	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name =	"Input Connector",		.info =	snd_rme32_info_inputtype_control,		.get =	snd_rme32_get_inputtype_control,		.put =	snd_rme32_put_inputtype_control	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name =	"Loopback Input",		.info =	snd_rme32_info_loopback_control,		.get =	snd_rme32_get_loopback_control,		.put =	snd_rme32_put_loopback_control	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name =	"Sample Clock Source",		.info =	snd_rme32_info_clockmode_control,		.get =	snd_rme32_get_clockmode_control,		.put =	snd_rme32_put_clockmode_control	}};static int snd_rme32_create_switches(struct snd_card *card, struct rme32 * rme32){	int idx, err;	struct snd_kcontrol *kctl;	for (idx = 0; idx < (int)ARRAY_SIZE(snd_rme32_controls); idx++) {		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme32_controls[idx], rme32))) < 0)			return err;		if (idx == 1)	/* IEC958 (S/PDIF) Stream */			rme32->spdif_ctl = kctl;	}	return 0;}/* * Card initialisation */static void snd_rme32_card_free(struct snd_card *card){	snd_rme32_free(card->private_data);}static int __devinitsnd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id){	static int dev;	struct rme32 *rme32;	struct snd_card *card;	int err;	if (dev >= SNDRV_CARDS) {		return -ENODEV;	}	if (!enable[dev]) {		dev++;		return -ENOENT;	}	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,				 sizeof(struct rme32))) == NULL)		return -ENOMEM;	card->private_free = snd_rme32_card_free;	rme32 = (struct rme32 *) card->private_data;	rme32->card = card;	rme32->pci = pci;	snd_card_set_dev(card, &pci->dev);        if (fullduplex[dev])		rme32->fullduplex_mode = 1;	if ((err = snd_rme32_create(rme32)) < 0) {		snd_card_free(card);		return err;	}	strcpy(card->driver, "Digi32");	switch (rme32->pci->device) {	case PCI_DEVICE_ID_RME_DIGI32:		strcpy(card->shortname, "RME Digi32");		break;	case PCI_DEVICE_ID_RME_DIGI32_8:		strcpy(card->shortname, "RME Digi32/8");		break;	case PCI_DEVICE_ID_RME_DIGI32_PRO:		strcpy(card->shortname, "RME Digi32 PRO");		break;	}	sprintf(card->longname, "%s (Rev. %d) at 0x%lx, irq %d",		card->shortname, rme32->rev, rme32->port, rme32->irq);	if ((err = snd_card_register(card)) < 0) {		snd_card_free(card);		return err;	}	pci_set_drvdata(pci, card);	dev++;	return 0;}static void __devexit snd_rme32_remove(struct pci_dev *pci){	snd_card_free(pci_get_drvdata(pci));	pci_set_drvdata(pci, NULL);}static struct pci_driver driver = {	.name =		"RME Digi32",	.id_table =	snd_rme32_ids,	.probe =	snd_rme32_probe,	.remove =	__devexit_p(snd_rme32_remove),};static int __init alsa_card_rme32_init(void){	return pci_register_driver(&driver);}static void __exit alsa_card_rme32_exit(void){	pci_unregister_driver(&driver);}module_init(alsa_card_rme32_init)module_exit(alsa_card_rme32_exit)

⌨️ 快捷键说明

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