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

📄 pcxhr_mixer.c

📁 linux2.6.16版本
💻 C
📖 第 1 页 / 共 3 页
字号:
				struct snd_ctl_elem_value *ucontrol){	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);	int i, err, rate;	down(&mgr->mixer_mutex);	for(i = 0; i < 3 + mgr->capture_chips; i++) {		if (i == PCXHR_CLOCK_TYPE_INTERNAL)			rate = mgr->sample_rate_real;		else {			err = pcxhr_get_external_clock(mgr, i, &rate);			if (err)				break;		}		ucontrol->value.integer.value[i] = rate;	}	up(&mgr->mixer_mutex);	return 0;}static struct snd_kcontrol_new pcxhr_control_clock_rate = {	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.iface =	SNDRV_CTL_ELEM_IFACE_CARD,	.name =		"Clock Rates",	.info =		pcxhr_clock_rate_info,	.get =		pcxhr_clock_rate_get,};/* * IEC958 status bits */static int pcxhr_iec958_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 pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char* aes_bits){	int i, err;	unsigned char temp;	struct pcxhr_rmh rmh;	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);	rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;	switch (chip->chip_idx) {	case 0:	rmh.cmd[1] = CS8420_01_CS; break;	/* use CS8416_01_CS for AES SYNC plug */	case 1:	rmh.cmd[1] = CS8420_23_CS; break;	case 2:	rmh.cmd[1] = CS8420_45_CS; break;	case 3:	rmh.cmd[1] = CS8420_67_CS; break;	default: return -EINVAL;	}	switch (aes_idx) {	case 0:	rmh.cmd[2] = CS8420_CSB0; break;	/* use CS8416_CSBx for AES SYNC plug */	case 1:	rmh.cmd[2] = CS8420_CSB1; break;	case 2:	rmh.cmd[2] = CS8420_CSB2; break;	case 3:	rmh.cmd[2] = CS8420_CSB3; break;	case 4:	rmh.cmd[2] = CS8420_CSB4; break;	default: return -EINVAL;	}	rmh.cmd[1] &= 0x0fffff;			/* size and code the chip id for the fpga */	rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI;	/* chip signature + map for spi read */	rmh.cmd_len = 3;	err = pcxhr_send_msg(chip->mgr, &rmh);	if (err)		return err;	temp = 0;	for (i = 0; i < 8; i++) {		/* attention : reversed bit order (not with CS8416_01_CS) */		temp <<= 1;		if (rmh.stat[1] & (1 << i))			temp |= 1;	}	snd_printdd("read iec958 AES %d byte %d = 0x%x\n", chip->chip_idx, aes_idx, temp);	*aes_bits = temp;	return 0;}static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);	unsigned char aes_bits;	int i, err;	down(&chip->mgr->mixer_mutex);	for(i = 0; i < 5; i++) {		if (kcontrol->private_value == 0)	/* playback */			aes_bits = chip->aes_bits[i];		else {				/* capture */			err = pcxhr_iec958_capture_byte(chip, i, &aes_bits);			if (err)				break;		}		ucontrol->value.iec958.status[i] = aes_bits;	}	up(&chip->mgr->mixer_mutex);        return 0;}static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,				 struct snd_ctl_elem_value *ucontrol){	int i;	for (i = 0; i < 5; i++)		ucontrol->value.iec958.status[i] = 0xff;        return 0;}static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char aes_bits){	int i, err, cmd;	unsigned char new_bits = aes_bits;	unsigned char old_bits = chip->aes_bits[aes_idx];	struct pcxhr_rmh rmh;	for (i = 0; i < 8; i++) {		if ((old_bits & 0x01) != (new_bits & 0x01)) {			cmd = chip->chip_idx & 0x03;		/* chip index 0..3 */			if(chip->chip_idx > 3)				/* new bit used if chip_idx>3 (PCX1222HR) */				cmd |= 1 << 22;			cmd |= ((aes_idx << 3) + i) << 2;	/* add bit offset */			cmd |= (new_bits & 0x01) << 23;		/* add bit value */			pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);			rmh.cmd[0] |= IO_NUM_REG_CUER;			rmh.cmd[1] = cmd;			rmh.cmd_len = 2;			snd_printdd("write iec958 AES %d byte %d bit %d (cmd %x)\n",				    chip->chip_idx, aes_idx, i, cmd);			err = pcxhr_send_msg(chip->mgr, &rmh);			if (err)				return err;		}		old_bits >>= 1;		new_bits >>= 1;	}	chip->aes_bits[aes_idx] = aes_bits;	return 0;}static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,			    struct snd_ctl_elem_value *ucontrol){	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);	int i, changed = 0;	/* playback */	down(&chip->mgr->mixer_mutex);	for (i = 0; i < 5; i++) {		if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {			pcxhr_iec958_update_byte(chip, i, ucontrol->value.iec958.status[i]);			changed = 1;		}	}	up(&chip->mgr->mixer_mutex);	return changed;}static struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = {	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),	.info =		pcxhr_iec958_info,	.get =		pcxhr_iec958_mask_get};static struct snd_kcontrol_new pcxhr_control_playback_iec958 = {	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),	.info =         pcxhr_iec958_info,	.get =          pcxhr_iec958_get,	.put =          pcxhr_iec958_put,	.private_value = 0 /* playback */};static struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = {	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),	.info =		pcxhr_iec958_info,	.get =		pcxhr_iec958_mask_get};static struct snd_kcontrol_new pcxhr_control_capture_iec958 = {	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =         SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),	.info =         pcxhr_iec958_info,	.get =          pcxhr_iec958_get,	.private_value = 1 /* capture */};static void pcxhr_init_audio_levels(struct snd_pcxhr *chip){	int i;	for (i = 0; i < 2; i++) {		if (chip->nb_streams_play) {			int j;			/* at boot time the digital volumes are unmuted 0dB */			for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) {				chip->digital_playback_active[j][i] = 1;				chip->digital_playback_volume[j][i] = PCXHR_DIGITAL_ZERO_LEVEL;			}			/* after boot, only two bits are set on the uer interface */			chip->aes_bits[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_FS_48000;/* only for test purpose, remove later */#ifdef CONFIG_SND_DEBUG			/* analog volumes for playback (is LEVEL_MIN after boot) */			chip->analog_playback_active[i] = 1;			chip->analog_playback_volume[i] = PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL;			pcxhr_update_analog_audio_level(chip, 0, i);#endif/* test end */		}		if (chip->nb_streams_capt) {			/* at boot time the digital volumes are unmuted 0dB */			chip->digital_capture_volume[i] = PCXHR_DIGITAL_ZERO_LEVEL;/* only for test purpose, remove later */#ifdef CONFIG_SND_DEBUG			/* analog volumes for playback (is LEVEL_MIN after boot) */			chip->analog_capture_volume[i]  = PCXHR_ANALOG_CAPTURE_ZERO_LEVEL;			pcxhr_update_analog_audio_level(chip, 1, i);#endif/* test end */		}	}	return;}int pcxhr_create_mixer(struct pcxhr_mgr *mgr){	struct snd_pcxhr *chip;	int err, i;	init_MUTEX(&mgr->mixer_mutex); /* can be in another place */	for (i = 0; i < mgr->num_cards; i++) {		struct snd_kcontrol_new temp;		chip = mgr->chip[i];		if (chip->nb_streams_play) {			/* analog output level control */			temp = pcxhr_control_analog_level;			temp.name = "Master Playback Volume";			temp.private_value = 0; /* playback */			if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)				return err;			/* output mute controls */			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_output_switch,							    chip))) < 0)				return err;						temp = snd_pcxhr_pcm_vol;			temp.name = "PCM Playback Volume";			temp.count = PCXHR_PLAYBACK_STREAMS;			temp.private_value = 0; /* playback */			if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)				return err;			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_pcm_switch,							    chip))) < 0)				return err;			/* IEC958 controls */			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_playback_iec958_mask,							    chip))) < 0)				return err;			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_playback_iec958,							    chip))) < 0)				return err;		}		if (chip->nb_streams_capt) {			/* analog input level control only on first two chips !*/			temp = pcxhr_control_analog_level;			temp.name = "Master Capture Volume";			temp.private_value = 1; /* capture */			if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)				return err;			temp = snd_pcxhr_pcm_vol;			temp.name = "PCM Capture Volume";			temp.count = 1;			temp.private_value = 1; /* capture */			if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)				return err;			/* Audio source */			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_audio_src,							    chip))) < 0)				return err;			/* IEC958 controls */			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_capture_iec958_mask,							    chip))) < 0)				return err;			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_capture_iec958,							    chip))) < 0)				return err;		}		/* monitoring only if playback and capture device available */		if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) {			/* monitoring */			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_monitor_vol,							    chip))) < 0)				return err;			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_monitor_sw,							    chip))) < 0)				return err;		}		if (i == 0) {			/* clock mode only one control per pcxhr */			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_clock_type,							    mgr))) < 0)				return err;			/* non standard control used to scan the external clock presence/frequencies */			if ((err = snd_ctl_add(chip->card,					       snd_ctl_new1(&pcxhr_control_clock_rate,							    mgr))) < 0)				return err;		}		/* init values for the mixer data */		pcxhr_init_audio_levels(chip);	}	return 0;}

⌨️ 快捷键说明

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