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

📄 rme9652.c

📁 底层驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
	if ((restart = s->running)) {		rme9652_stop(s);	}	frames >>= 7;	n = 0;	while (frames) {		n++;		frames >>= 1;	}	s->control_register &= ~RME9652_latency;	s->control_register |= rme9652_encode_latency(n);	rme9652_write(s, RME9652_control_register, s->control_register);	rme9652_compute_period_size(s);	if (restart)		rme9652_start(s);	spin_unlock_irq(&s->lock);	return 0;}static int rme9652_set_rate(rme9652_t *rme9652, int rate){	int restart;	int reject_if_open = 0;	int xrate;	if (!snd_rme9652_use_is_exclusive (rme9652)) {		return -EBUSY;	}	/* Changing from a "single speed" to a "double speed" rate is	   not allowed if any substreams are open. This is because	   such a change causes a shift in the location of 	   the DMA buffers and a reduction in the number of available	   buffers. 	   Note that a similar but essentially insoluble problem	   exists for externally-driven rate changes. All we can do	   is to flag rate changes in the read/write routines.	 */	spin_lock_irq(&rme9652->lock);	xrate = rme9652_adat_sample_rate(rme9652);	switch (rate) {	case 44100:		if (xrate > 48000) {			reject_if_open = 1;		}		rate = 0;		break;	case 48000:		if (xrate > 48000) {			reject_if_open = 1;		}		rate = RME9652_freq;		break;	case 88200:		if (xrate < 48000) {			reject_if_open = 1;		}		rate = RME9652_DS;		break;	case 96000:		if (xrate < 48000) {			reject_if_open = 1;		}		rate = RME9652_DS | RME9652_freq;		break;	default:		spin_unlock_irq(&rme9652->lock);		return -EINVAL;	}	if (reject_if_open && (rme9652->capture_pid >= 0 || rme9652->playback_pid >= 0)) {		spin_unlock_irq(&rme9652->lock);		return -EBUSY;	}	if ((restart = rme9652->running)) {		rme9652_stop(rme9652);	}	rme9652->control_register &= ~(RME9652_freq | RME9652_DS);	rme9652->control_register |= rate;	rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);	if (restart) {		rme9652_start(rme9652);	}	if (rate & RME9652_DS) {		if (rme9652->ss_channels == RME9652_NCHANNELS) {			rme9652->channel_map = channel_map_9652_ds;		} else {			rme9652->channel_map = channel_map_9636_ds;		}	} else {		if (rme9652->ss_channels == RME9652_NCHANNELS) {			rme9652->channel_map = channel_map_9652_ss;		} else {			rme9652->channel_map = channel_map_9636_ss;		}	}	spin_unlock_irq(&rme9652->lock);	return 0;}static void rme9652_set_thru(rme9652_t *rme9652, int channel, int enable){	int i;	rme9652->passthru = 0;	if (channel < 0) {		/* set thru for all channels */		if (enable) {			for (i = 0; i < RME9652_NCHANNELS; i++) {				rme9652->thru_bits |= (1 << i);				rme9652_write(rme9652, RME9652_thru_base + i * 4, 1);			}		} else {			for (i = 0; i < RME9652_NCHANNELS; i++) {				rme9652->thru_bits &= ~(1 << i);				rme9652_write(rme9652, RME9652_thru_base + i * 4, 0);			}		}	} else {		int mapped_channel;		snd_assert(channel == RME9652_NCHANNELS, return);		mapped_channel = rme9652->channel_map[channel];		if (enable) {			rme9652->thru_bits |= (1 << mapped_channel);		} else {			rme9652->thru_bits &= ~(1 << mapped_channel);		}		rme9652_write(rme9652,			       RME9652_thru_base + mapped_channel * 4,			       enable ? 1 : 0);			       	}}static int rme9652_set_passthru(rme9652_t *rme9652, int onoff){	if (onoff) {		rme9652_set_thru(rme9652, -1, 1);		/* we don't want interrupts, so do a		   custom version of rme9652_start().		*/		rme9652->control_register =			RME9652_inp_0 | 			rme9652_encode_latency(7) |			RME9652_start_bit;		rme9652_reset_hw_pointer(rme9652);		rme9652_write(rme9652, RME9652_control_register,			      rme9652->control_register);		rme9652->passthru = 1;	} else {		rme9652_set_thru(rme9652, -1, 0);		rme9652_stop(rme9652);				rme9652->passthru = 0;	}	return 0;}static void rme9652_spdif_set_bit (rme9652_t *rme9652, int mask, int onoff){	if (onoff) 		rme9652->control_register |= mask;	else 		rme9652->control_register &= ~mask;			rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);}static void rme9652_spdif_write_byte (rme9652_t *rme9652, const int val){	long mask;	long i;	for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {		if (val & mask)			rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 1);		else 			rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 0);		rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1);		rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0);	}}static int rme9652_spdif_read_byte (rme9652_t *rme9652){	long mask;	long val;	long i;	val = 0;	for (i = 0, mask = 0x80;  i < 8; i++, mask >>= 1) {		rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1);		if (rme9652_read (rme9652, RME9652_status_register) & RME9652_SPDIF_READ)			val |= mask;		rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0);	}	return val;}static void rme9652_write_spdif_codec (rme9652_t *rme9652, const int address, const int data){	rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);	rme9652_spdif_write_byte (rme9652, 0x20);	rme9652_spdif_write_byte (rme9652, address);	rme9652_spdif_write_byte (rme9652, data);	rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);}static int rme9652_spdif_read_codec (rme9652_t *rme9652, const int address){	int ret;	rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);	rme9652_spdif_write_byte (rme9652, 0x20);	rme9652_spdif_write_byte (rme9652, address);	rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);	rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);	rme9652_spdif_write_byte (rme9652, 0x21);	ret = rme9652_spdif_read_byte (rme9652);	rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);	return ret;}static void rme9652_initialize_spdif_receiver (rme9652_t *rme9652){	/* XXX what unsets this ? */	rme9652->control_register |= RME9652_SPDIF_RESET;	rme9652_write_spdif_codec (rme9652, 4, 0x40);	rme9652_write_spdif_codec (rme9652, 17, 0x13);	rme9652_write_spdif_codec (rme9652, 6, 0x02);}static inline int rme9652_spdif_sample_rate(rme9652_t *s){	unsigned int rate_bits;	if (rme9652_read(s, RME9652_status_register) & RME9652_ERF) {		return -1;	/* error condition */	}		if (s->hw_rev == 15) {		int x, y, ret;				x = rme9652_spdif_read_codec (s, 30);		if (x != 0) 			y = 48000 * 64 / x;		else			y = 0;		if      (y > 30400 && y < 33600)  ret = 32000; 		else if (y > 41900 && y < 46000)  ret = 44100;		else if (y > 46000 && y < 50400)  ret = 48000;		else if (y > 60800 && y < 67200)  ret = 64000;		else if (y > 83700 && y < 92000)  ret = 88200;		else if (y > 92000 && y < 100000) ret = 96000;		else                              ret = 0;		return ret;	}	rate_bits = rme9652_read(s, RME9652_status_register) & RME9652_F;	switch (rme9652_decode_spdif_rate(rate_bits)) {	case 0x7:		return 32000;		break;	case 0x6:		return 44100;		break;	case 0x5:		return 48000;		break;	case 0x4:		return 88200;		break;	case 0x3:		return 96000;		break;	case 0x0:		return 64000;		break;	default:		snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",			   s->card_name, rate_bits);		return 0;		break;	}}/*-----------------------------------------------------------------------------  Control Interface  ----------------------------------------------------------------------------*/static u32 snd_rme9652_convert_from_aes(snd_aes_iec958_t *aes){	u32 val = 0;	val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME9652_PRO : 0;	val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? RME9652_Dolby : 0;	if (val & RME9652_PRO)		val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME9652_EMP : 0;	else		val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME9652_EMP : 0;	return val;}static void snd_rme9652_convert_to_aes(snd_aes_iec958_t *aes, u32 val){	aes->status[0] = ((val & RME9652_PRO) ? IEC958_AES0_PROFESSIONAL : 0) |			 ((val & RME9652_Dolby) ? IEC958_AES0_NONAUDIO : 0);	if (val & RME9652_PRO)		aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0;	else		aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;}static int snd_rme9652_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_rme9652_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);		snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif);	return 0;}static int snd_rme9652_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	int change;	u32 val;		val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);	spin_lock_irq(&rme9652->lock);	change = val != rme9652->creg_spdif;	rme9652->creg_spdif = val;	spin_unlock_irq(&rme9652->lock);	return change;}static int snd_rme9652_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_rme9652_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);		snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif_stream);	return 0;}static int snd_rme9652_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	int change;	u32 val;		val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958);	spin_lock_irq(&rme9652->lock);	change = val != rme9652->creg_spdif_stream;	rme9652->creg_spdif_stream = val;	rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP);	rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= val);	spin_unlock_irq(&rme9652->lock);	return change;}static int snd_rme9652_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_rme9652_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 RME9652_ADAT1_IN(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_rme9652_info_adat1_in, \  .get = snd_rme9652_get_adat1_in, \  .put = snd_rme9652_put_adat1_in }static unsigned int rme9652_adat1_in(rme9652_t *rme9652){	if (rme9652->control_register & RME9652_ADAT1_INTERNAL)		return 1; 	return 0;}static int rme9652_set_adat1_input(rme9652_t *rme9652, int internal){	int restart = 0;	if (internal) {		rme9652->control_register |= RME9652_ADAT1_INTERNAL;	} else {		rme9652->control_register &= ~RME9652_ADAT1_INTERNAL;	}	/* XXX do we actually need to stop the card when we do this ? */	if ((restart = rme9652->running)) {		rme9652_stop(rme9652);	}

⌨️ 快捷键说明

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