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

📄 rme9652.c

📁 底层驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
	rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);	if (restart) {		rme9652_start(rme9652);	}	return 0;}static int snd_rme9652_info_adat1_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[2] = {"ADAT1", "Internal"};	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 2;	if (uinfo->value.enumerated.item > 1)		uinfo->value.enumerated.item = 1;	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static int snd_rme9652_get_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);		spin_lock_irq(&rme9652->lock);	ucontrol->value.enumerated.item[0] = rme9652_adat1_in(rme9652);	spin_unlock_irq(&rme9652->lock);	return 0;}static int snd_rme9652_put_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;		if (!snd_rme9652_use_is_exclusive(rme9652))		return -EBUSY;	val = ucontrol->value.enumerated.item[0] % 2;	spin_lock_irq(&rme9652->lock);	change = val != rme9652_adat1_in(rme9652);	if (change)		rme9652_set_adat1_input(rme9652, val);	spin_unlock_irq(&rme9652->lock);	return change;}#define RME9652_SPDIF_IN(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_rme9652_info_spdif_in, \  .get = snd_rme9652_get_spdif_in, .put = snd_rme9652_put_spdif_in }static unsigned int rme9652_spdif_in(rme9652_t *rme9652){	return rme9652_decode_spdif_in(rme9652->control_register &				       RME9652_inp);}static int rme9652_set_spdif_input(rme9652_t *rme9652, int in){	int restart = 0;	rme9652->control_register &= ~RME9652_inp;	rme9652->control_register |= rme9652_encode_spdif_in(in);	if ((restart = rme9652->running)) {		rme9652_stop(rme9652);	}	rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);	if (restart) {		rme9652_start(rme9652);	}	return 0;}static int snd_rme9652_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[3] = {"ADAT1", "Coaxial", "Internal"};	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 int snd_rme9652_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);		spin_lock_irq(&rme9652->lock);	ucontrol->value.enumerated.item[0] = rme9652_spdif_in(rme9652);	spin_unlock_irq(&rme9652->lock);	return 0;}static int snd_rme9652_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;		if (!snd_rme9652_use_is_exclusive(rme9652))		return -EBUSY;	val = ucontrol->value.enumerated.item[0] % 3;	spin_lock_irq(&rme9652->lock);	change = val != rme9652_spdif_in(rme9652);	if (change)		rme9652_set_spdif_input(rme9652, val);	spin_unlock_irq(&rme9652->lock);	return change;}#define RME9652_SPDIF_OUT(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_rme9652_info_spdif_out, \  .get = snd_rme9652_get_spdif_out, .put = snd_rme9652_put_spdif_out }static int rme9652_spdif_out(rme9652_t *rme9652){	return (rme9652->control_register & RME9652_opt_out) ? 1 : 0;}static int rme9652_set_spdif_output(rme9652_t *rme9652, int out){	int restart = 0;	if (out) {		rme9652->control_register |= RME9652_opt_out;	} else {		rme9652->control_register &= ~RME9652_opt_out;	}	if ((restart = rme9652->running)) {		rme9652_stop(rme9652);	}	rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);	if (restart) {		rme9652_start(rme9652);	}	return 0;}static int snd_rme9652_info_spdif_out(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_rme9652_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);		spin_lock_irq(&rme9652->lock);	ucontrol->value.integer.value[0] = rme9652_spdif_out(rme9652);	spin_unlock_irq(&rme9652->lock);	return 0;}static int snd_rme9652_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;		if (!snd_rme9652_use_is_exclusive(rme9652))		return -EBUSY;	val = ucontrol->value.integer.value[0] & 1;	spin_lock_irq(&rme9652->lock);	change = (int)val != rme9652_spdif_out(rme9652);	rme9652_set_spdif_output(rme9652, val);	spin_unlock_irq(&rme9652->lock);	return change;}#define RME9652_SYNC_MODE(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_rme9652_info_sync_mode, \  .get = snd_rme9652_get_sync_mode, .put = snd_rme9652_put_sync_mode }static int rme9652_sync_mode(rme9652_t *rme9652){	if (rme9652->control_register & RME9652_wsel) {		return 2;	} else if (rme9652->control_register & RME9652_Master) {		return 1;	} else {		return 0;	}}static int rme9652_set_sync_mode(rme9652_t *rme9652, int mode){	int restart = 0;	switch (mode) {	case 0:		rme9652->control_register &=		    ~(RME9652_Master | RME9652_wsel);		break;	case 1:		rme9652->control_register =		    (rme9652->control_register & ~RME9652_wsel) | RME9652_Master;		break;	case 2:		rme9652->control_register |=		    (RME9652_Master | RME9652_wsel);		break;	}	if ((restart = rme9652->running)) {		rme9652_stop(rme9652);	}	rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);	if (restart) {		rme9652_start(rme9652);	}	return 0;}static int snd_rme9652_info_sync_mode(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[3] = {"AutoSync", "Master", "Word Clock"};	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 int snd_rme9652_get_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);		spin_lock_irq(&rme9652->lock);	ucontrol->value.enumerated.item[0] = rme9652_sync_mode(rme9652);	spin_unlock_irq(&rme9652->lock);	return 0;}static int snd_rme9652_put_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;		val = ucontrol->value.enumerated.item[0] % 3;	spin_lock_irq(&rme9652->lock);	change = (int)val != rme9652_sync_mode(rme9652);	rme9652_set_sync_mode(rme9652, val);	spin_unlock_irq(&rme9652->lock);	return change;}#define RME9652_SYNC_PREF(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_rme9652_info_sync_pref, \  .get = snd_rme9652_get_sync_pref, .put = snd_rme9652_put_sync_pref }static int rme9652_sync_pref(rme9652_t *rme9652){	switch (rme9652->control_register & RME9652_SyncPref_Mask) {	case RME9652_SyncPref_ADAT1:		return RME9652_SYNC_FROM_ADAT1;	case RME9652_SyncPref_ADAT2:		return RME9652_SYNC_FROM_ADAT2;	case RME9652_SyncPref_ADAT3:		return RME9652_SYNC_FROM_ADAT3;	case RME9652_SyncPref_SPDIF:		return RME9652_SYNC_FROM_SPDIF;	}	/* Not reachable */	return 0;}static int rme9652_set_sync_pref(rme9652_t *rme9652, int pref){	int restart;	rme9652->control_register &= ~RME9652_SyncPref_Mask;	switch (pref) {	case RME9652_SYNC_FROM_ADAT1:		rme9652->control_register |= RME9652_SyncPref_ADAT1;		break;	case RME9652_SYNC_FROM_ADAT2:		rme9652->control_register |= RME9652_SyncPref_ADAT2;		break;	case RME9652_SYNC_FROM_ADAT3:		rme9652->control_register |= RME9652_SyncPref_ADAT3;		break;	case RME9652_SYNC_FROM_SPDIF:		rme9652->control_register |= RME9652_SyncPref_SPDIF;		break;	}	if ((restart = rme9652->running)) {		rme9652_stop(rme9652);	}	rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);	if (restart) {		rme9652_start(rme9652);	}	return 0;}static int snd_rme9652_info_sync_pref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	static char *texts[4] = {"IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In"};	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;	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_rme9652_get_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);		spin_lock_irq(&rme9652->lock);	ucontrol->value.enumerated.item[0] = rme9652_sync_pref(rme9652);	spin_unlock_irq(&rme9652->lock);	return 0;}static int snd_rme9652_put_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	int change, max;	unsigned int val;		if (!snd_rme9652_use_is_exclusive(rme9652))		return -EBUSY;	max = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3;	val = ucontrol->value.enumerated.item[0] % max;	spin_lock_irq(&rme9652->lock);	change = (int)val != rme9652_sync_pref(rme9652);	rme9652_set_sync_pref(rme9652, val);	spin_unlock_irq(&rme9652->lock);	return change;}static int snd_rme9652_info_thru(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;	uinfo->count = rme9652->ss_channels;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = 1;	return 0;}static int snd_rme9652_get_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	unsigned int k;	u32 thru_bits = rme9652->thru_bits;	for (k = 0; k < rme9652->ss_channels; ++k) {		ucontrol->value.integer.value[k] = !!(thru_bits & (1 << k));	}	return 0;}static int snd_rme9652_put_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	int change;	unsigned int chn;	u32 thru_bits = 0;	if (!snd_rme9652_use_is_exclusive(rme9652))		return -EBUSY;	for (chn = 0; chn < rme9652->ss_channels; ++chn) {		if (ucontrol->value.integer.value[chn])			thru_bits |= 1 << chn;	}		spin_lock_irq(&rme9652->lock);	change = thru_bits ^ rme9652->thru_bits;	if (change) {		for (chn = 0; chn < rme9652->ss_channels; ++chn) {			if (!(change & (1 << chn)))				continue;			rme9652_set_thru(rme9652,chn,thru_bits&(1<<chn));		}	}	spin_unlock_irq(&rme9652->lock);	return !!change;}#define RME9652_PASSTHRU(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \  .info = snd_rme9652_info_passthru, \  .put = snd_rme9652_put_passthru, \  .get = snd_rme9652_get_passthru }static int snd_rme9652_info_passthru(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_rme9652_get_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	spin_lock_irq(&rme9652->lock);	ucontrol->value.integer.value[0] = rme9652->passthru;	spin_unlock_irq(&rme9652->lock);	return 0;}static int snd_rme9652_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);	int change;	unsigned int val;	int err = 0;	if (!snd_rme9652_use_is_exclusive(rme9652))		return -EBUSY;	val = ucontrol->value.integer.value[0] & 1;	spin_lock_irq(&rme9652->lock);	change = (ucontrol->value.integer.value[0] != rme9652->passthru);	if (change)		err = rme9652_set_passthru(rme9652, val);

⌨️ 快捷键说明

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