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

📄 hdsp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	snd_hdsp_midi_output_trigger (substream, 0);	hmidi = (hdsp_midi_t *) substream->rmidi->private_data;	spin_lock_irq (&hmidi->lock);	hmidi->output = NULL;	spin_unlock_irq (&hmidi->lock);	return 0;}static snd_rawmidi_ops_t snd_hdsp_midi_output ={	.open =		snd_hdsp_midi_output_open,	.close =	snd_hdsp_midi_output_close,	.trigger =	snd_hdsp_midi_output_trigger,};static snd_rawmidi_ops_t snd_hdsp_midi_input ={	.open =		snd_hdsp_midi_input_open,	.close =	snd_hdsp_midi_input_close,	.trigger =	snd_hdsp_midi_input_trigger,};static int __devinit snd_hdsp_create_midi (snd_card_t *card, hdsp_t *hdsp, int id){	char buf[32];	hdsp->midi[id].id = id;	hdsp->midi[id].rmidi = NULL;	hdsp->midi[id].input = NULL;	hdsp->midi[id].output = NULL;	hdsp->midi[id].hdsp = hdsp;	hdsp->midi[id].istimer = 0;	hdsp->midi[id].pending = 0;	spin_lock_init (&hdsp->midi[id].lock);	sprintf (buf, "%s MIDI %d", card->shortname, id+1);	if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)		return -1;	sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);	hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];	snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output);	snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_hdsp_midi_input);	hdsp->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |		SNDRV_RAWMIDI_INFO_INPUT |		SNDRV_RAWMIDI_INFO_DUPLEX;	return 0;}/*-----------------------------------------------------------------------------  Control Interface  ----------------------------------------------------------------------------*/static u32 snd_hdsp_convert_from_aes(snd_aes_iec958_t *aes){	u32 val = 0;	val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? HDSP_SPDIFProfessional : 0;	val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? HDSP_SPDIFNonAudio : 0;	if (val & HDSP_SPDIFProfessional)		val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? HDSP_SPDIFEmphasis : 0;	else		val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? HDSP_SPDIFEmphasis : 0;	return val;}static void snd_hdsp_convert_to_aes(snd_aes_iec958_t *aes, u32 val){	aes->status[0] = ((val & HDSP_SPDIFProfessional) ? IEC958_AES0_PROFESSIONAL : 0) |			 ((val & HDSP_SPDIFNonAudio) ? IEC958_AES0_NONAUDIO : 0);	if (val & HDSP_SPDIFProfessional)		aes->status[0] |= (val & HDSP_SPDIFEmphasis) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;	else		aes->status[0] |= (val & HDSP_SPDIFEmphasis) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;}static int snd_hdsp_control_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_hdsp_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);		snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif);	return 0;}static int snd_hdsp_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);	int change;	u32 val;		val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);	spin_lock_irq(&hdsp->lock);	change = val != hdsp->creg_spdif;	hdsp->creg_spdif = val;	spin_unlock_irq(&hdsp->lock);	return change;}static int snd_hdsp_control_spdif_stream_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_hdsp_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);		snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif_stream);	return 0;}static int snd_hdsp_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);	int change;	u32 val;		val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958);	spin_lock_irq(&hdsp->lock);	change = val != hdsp->creg_spdif_stream;	hdsp->creg_spdif_stream = val;	hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis);	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register |= val);	spin_unlock_irq(&hdsp->lock);	return change;}static int snd_hdsp_control_spdif_mask_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_hdsp_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	ucontrol->value.iec958.status[0] = kcontrol->private_value;	return 0;}#define HDSP_SPDIF_IN(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \  .name = xname, \  .index = xindex, \  .info = snd_hdsp_info_spdif_in, \  .get = snd_hdsp_get_spdif_in, \  .put = snd_hdsp_put_spdif_in }static unsigned int hdsp_spdif_in(hdsp_t *hdsp){	return hdsp_decode_spdif_in(hdsp->control_register & HDSP_SPDIFInputMask);}static int hdsp_set_spdif_input(hdsp_t *hdsp, int in){	hdsp->control_register &= ~HDSP_SPDIFInputMask;	hdsp->control_register |= hdsp_encode_spdif_in(in);	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);	return 0;}static int snd_hdsp_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[4] = {"Optical", "Coaxial", "Internal", "AES"};	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = ((hdsp->io_type == H9632) ? 4 : 3);	if (uinfo->value.enumerated.item > ((hdsp->io_type == H9632) ? 3 : 2))		uinfo->value.enumerated.item = ((hdsp->io_type == H9632) ? 3 : 2);	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static int snd_hdsp_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);		ucontrol->value.enumerated.item[0] = hdsp_spdif_in(hdsp);	return 0;}static int snd_hdsp_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;		if (!snd_hdsp_use_is_exclusive(hdsp))		return -EBUSY;	val = ucontrol->value.enumerated.item[0] % ((hdsp->io_type == H9632) ? 4 : 3);	spin_lock_irq(&hdsp->lock);	change = val != hdsp_spdif_in(hdsp);	if (change)		hdsp_set_spdif_input(hdsp, val);	spin_unlock_irq(&hdsp->lock);	return change;}#define HDSP_SPDIF_OUT(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_hdsp_info_spdif_bits, \  .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out }static int hdsp_spdif_out(hdsp_t *hdsp){	return (hdsp->control_register & HDSP_SPDIFOpticalOut) ? 1 : 0;}static int hdsp_set_spdif_output(hdsp_t *hdsp, int out){	if (out)		hdsp->control_register |= HDSP_SPDIFOpticalOut;	else		hdsp->control_register &= ~HDSP_SPDIFOpticalOut;	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);	return 0;}static int snd_hdsp_info_spdif_bits(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_hdsp_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);		ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp);	return 0;}static int snd_hdsp_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;		if (!snd_hdsp_use_is_exclusive(hdsp))		return -EBUSY;	val = ucontrol->value.integer.value[0] & 1;	spin_lock_irq(&hdsp->lock);	change = (int)val != hdsp_spdif_out(hdsp);	hdsp_set_spdif_output(hdsp, val);	spin_unlock_irq(&hdsp->lock);	return change;}#define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_hdsp_info_spdif_bits, \  .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional }static int hdsp_spdif_professional(hdsp_t *hdsp){	return (hdsp->control_register & HDSP_SPDIFProfessional) ? 1 : 0;}static int hdsp_set_spdif_professional(hdsp_t *hdsp, int val){	if (val)		hdsp->control_register |= HDSP_SPDIFProfessional;	else		hdsp->control_register &= ~HDSP_SPDIFProfessional;	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);	return 0;}static int snd_hdsp_get_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);		ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp);	return 0;}static int snd_hdsp_put_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;		if (!snd_hdsp_use_is_exclusive(hdsp))		return -EBUSY;	val = ucontrol->value.integer.value[0] & 1;	spin_lock_irq(&hdsp->lock);	change = (int)val != hdsp_spdif_professional(hdsp);	hdsp_set_spdif_professional(hdsp, val);	spin_unlock_irq(&hdsp->lock);	return change;}#define HDSP_SPDIF_EMPHASIS(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_hdsp_info_spdif_bits, \  .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis }static int hdsp_spdif_emphasis(hdsp_t *hdsp){	return (hdsp->control_register & HDSP_SPDIFEmphasis) ? 1 : 0;}static int hdsp_set_spdif_emphasis(hdsp_t *hdsp, int val){	if (val)		hdsp->control_register |= HDSP_SPDIFEmphasis;	else		hdsp->control_register &= ~HDSP_SPDIFEmphasis;	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);	return 0;}static int snd_hdsp_get_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);		ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp);	return 0;}static int snd_hdsp_put_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;		if (!snd_hdsp_use_is_exclusive(hdsp))		return -EBUSY;	val = ucontrol->value.integer.value[0] & 1;	spin_lock_irq(&hdsp->lock);	change = (int)val != hdsp_spdif_emphasis(hdsp);	hdsp_set_spdif_emphasis(hdsp, val);	spin_unlock_irq(&hdsp->lock);	return change;}#define HDSP_SPDIF_NON_AUDIO(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_hdsp_info_spdif_bits, \  .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio }static int hdsp_spdif_nonaudio(hdsp_t *hdsp){	return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0;}static int hdsp_set_spdif_nonaudio(hdsp_t *hdsp, int val){	if (val)		hdsp->control_register |= HDSP_SPDIFNonAudio;	else		hdsp->control_register &= ~HDSP_SPDIFNonAudio;	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);	return 0;}static int snd_hdsp_get_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);		ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp);	return 0;}static int snd_hdsp_put_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;		if (!snd_hdsp_use_is_exclusive(hdsp))		return -EBUSY;	val = ucontrol->value.integer.value[0] & 1;	spin_lock_irq(&hdsp->lock);	change = (int)val != hdsp_spdif_nonaudio(hdsp);	hdsp_set_spdif_nonaudio(hdsp, val);	spin_unlock_irq(&hdsp->lock);	return change;}#define HDSP_SPDIF_SAMPLE_RATE(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \  .name = xname, \  .index = xindex, \  .access = SNDRV_CTL_ELEM_ACCESS_READ, \  .info = snd_hdsp_info_spdif_sample_rate, \  .get = snd_hdsp_get_spdif_sample_rate \}static int snd_hdsp_info_spdif_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"};	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = (hdsp->io_type == H9632) ? 10 : 7;	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_hdsp_get_spdif_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);		switch (hdsp_spdif_sample_rate(hdsp)) {	case 32000:		ucontrol->value.enumerated.item[0] = 0;		break;	case 44100:		ucontrol->value.enumerated.item[0] = 1;		break;	case 48000:		ucontrol->value.enumerated.item[0] = 2;		break;	case 64000:		ucontrol->value.enumerated.item[0] = 3;		break;	case 88200:		ucontrol->value.enumerated.item[0] = 4;		break;	case 96000:		ucontrol->value.enumerated.item[0] = 5;		break;	case 128000:		ucontrol->value.enumerated.item[0] = 7;

⌨️ 快捷键说明

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