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

📄 ak4114.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
static int snd_ak4114_spdif_mask_get(snd_kcontrol_t * kcontrol,				      snd_ctl_elem_value_t * ucontrol){	memset(ucontrol->value.iec958.status, 0xff, AK4114_REG_RXCSB_SIZE);	return 0;}static int snd_ak4114_spdif_pinfo(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = 0xffff;	uinfo->count = 4;	return 0;}static int snd_ak4114_spdif_pget(snd_kcontrol_t * kcontrol,				 snd_ctl_elem_value_t * ucontrol){	ak4114_t *chip = snd_kcontrol_chip(kcontrol);	unsigned short tmp;	ucontrol->value.integer.value[0] = 0xf8f2;	ucontrol->value.integer.value[1] = 0x4e1f;	tmp = reg_read(chip, AK4114_REG_Pc0) | (reg_read(chip, AK4114_REG_Pc1) << 8);	ucontrol->value.integer.value[2] = tmp;	tmp = reg_read(chip, AK4114_REG_Pd0) | (reg_read(chip, AK4114_REG_Pd1) << 8);	ucontrol->value.integer.value[3] = tmp;	return 0;}static int snd_ak4114_spdif_qinfo(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;	uinfo->count = AK4114_REG_QSUB_SIZE;	return 0;}static int snd_ak4114_spdif_qget(snd_kcontrol_t * kcontrol,				 snd_ctl_elem_value_t * ucontrol){	ak4114_t *chip = snd_kcontrol_chip(kcontrol);	unsigned i;	for (i = 0; i < AK4114_REG_QSUB_SIZE; i++)		ucontrol->value.bytes.data[i] = reg_read(chip, AK4114_REG_QSUB_ADDR + i);	return 0;}/* Don't forget to change AK4114_CONTROLS define!!! */static snd_kcontrol_new_t snd_ak4114_iec958_controls[] = {{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 Parity Errors",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_in_error_info,	.get =		snd_ak4114_in_error_get,	.private_value = offsetof(ak4114_t, parity_errors),},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 V-Bit Errors",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_in_error_info,	.get =		snd_ak4114_in_error_get,	.private_value = offsetof(ak4114_t, v_bit_errors),},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 C-CRC Errors",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_in_error_info,	.get =		snd_ak4114_in_error_get,	.private_value = offsetof(ak4114_t, ccrc_errors),},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 Q-CRC Errors",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_in_error_info,	.get =		snd_ak4114_in_error_get,	.private_value = offsetof(ak4114_t, qcrc_errors),},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 External Rate",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_rate_info,	.get =		snd_ak4114_rate_get,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.info =		snd_ak4114_spdif_mask_info,	.get =		snd_ak4114_spdif_mask_get,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_spdif_info,	.get =		snd_ak4114_spdif_playback_get,	.put =		snd_ak4114_spdif_playback_put,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.info =		snd_ak4114_spdif_mask_info,	.get =		snd_ak4114_spdif_mask_get,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_spdif_info,	.get =		snd_ak4114_spdif_get,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 Preample Capture Default",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_spdif_pinfo,	.get =		snd_ak4114_spdif_pget,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 Q-subcode Capture Default",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_spdif_qinfo,	.get =		snd_ak4114_spdif_qget,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 Audio",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_in_bit_info,	.get =		snd_ak4114_in_bit_get,	.private_value = (1<<31) | (1<<8) | AK4114_REG_RCS0,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 Non-PCM Bitstream",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_in_bit_info,	.get =		snd_ak4114_in_bit_get,	.private_value = (6<<8) | AK4114_REG_RCS1,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 DTS Bitstream",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4114_in_bit_info,	.get =		snd_ak4114_in_bit_get,	.private_value = (3<<8) | AK4114_REG_RCS1,}};int snd_ak4114_build(ak4114_t *ak4114,		     snd_pcm_substream_t *ply_substream,		     snd_pcm_substream_t *cap_substream){	snd_kcontrol_t *kctl;	unsigned int idx;	int err;	snd_assert(cap_substream, return -EINVAL);	ak4114->playback_substream = ply_substream;	ak4114->capture_substream = cap_substream;	for (idx = 0; idx < AK4114_CONTROLS; idx++) {		kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114);		if (kctl == NULL)			return -ENOMEM;		if (!strstr(kctl->id.name, "Playback")) {			if (ply_substream == NULL) {				snd_ctl_free_one(kctl);				ak4114->kctls[idx] = NULL;				continue;			}			kctl->id.device = ply_substream->pcm->device;			kctl->id.subdevice = ply_substream->number;		} else {			kctl->id.device = cap_substream->pcm->device;			kctl->id.subdevice = cap_substream->number;		}		err = snd_ctl_add(ak4114->card, kctl);		if (err < 0)			return err;		ak4114->kctls[idx] = kctl;	}	return 0;}int snd_ak4114_external_rate(ak4114_t *ak4114){	unsigned char rcs1;	rcs1 = reg_read(ak4114, AK4114_REG_RCS1);	return external_rate(rcs1);}int snd_ak4114_check_rate_and_errors(ak4114_t *ak4114, unsigned int flags){	snd_pcm_runtime_t *runtime = ak4114->capture_substream ? ak4114->capture_substream->runtime : NULL;	unsigned long _flags;	int res = 0;	unsigned char rcs0, rcs1;	unsigned char c0, c1;	rcs1 = reg_read(ak4114, AK4114_REG_RCS1);	if (flags & AK4114_CHECK_NO_STAT)		goto __rate;	rcs0 = reg_read(ak4114, AK4114_REG_RCS0);	spin_lock_irqsave(&ak4114->lock, _flags);	if (rcs0 & AK4114_PAR)		ak4114->parity_errors++;	if (rcs1 & AK4114_V)		ak4114->v_bit_errors++;	if (rcs1 & AK4114_CCRC)		ak4114->ccrc_errors++;	if (rcs1 & AK4114_QCRC)		ak4114->qcrc_errors++;	c0 = (ak4114->rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)) ^                     (rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK));	c1 = (ak4114->rcs1 & 0xf0) ^ (rcs1 & 0xf0);	ak4114->rcs0 = rcs0 & ~(AK4114_QINT | AK4114_CINT);	ak4114->rcs1 = rcs1;	spin_unlock_irqrestore(&ak4114->lock, _flags);	if (rcs0 & AK4114_PAR)		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[0]->id);	if (rcs0 & AK4114_V)		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[1]->id);	if (rcs1 & AK4114_CCRC)		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[2]->id);	if (rcs1 & AK4114_QCRC)		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[3]->id);	/* rate change */	if (c1 & 0xf0)		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[4]->id);	if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[9]->id);	if (c0 & AK4114_QINT)		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[10]->id);	if (c0 & AK4114_AUDION)		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[11]->id);	if (c0 & AK4114_AUTO)		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[12]->id);	if (c0 & AK4114_DTSCD)		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id);	if (ak4114->change_callback && (c0 | c1) != 0)		ak4114->change_callback(ak4114, c0, c1);      __rate:	/* compare rate */	res = external_rate(rcs1);	if (!(flags & AK4114_CHECK_NO_RATE) && runtime && runtime->rate != res) {		snd_pcm_stream_lock_irqsave(ak4114->capture_substream, _flags);		if (snd_pcm_running(ak4114->capture_substream)) {			// printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);			snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING);			res = 1;		}		snd_pcm_stream_unlock_irqrestore(ak4114->capture_substream, _flags);	}	return res;}static void ak4114_stats(void *data){	ak4114_t *chip = (ak4114_t *)data;	if (chip->init)		return;	snd_ak4114_check_rate_and_errors(chip, 0);	queue_delayed_work(chip->workqueue, &chip->work, HZ / 10);}EXPORT_SYMBOL(snd_ak4114_create);EXPORT_SYMBOL(snd_ak4114_reg_write);EXPORT_SYMBOL(snd_ak4114_reinit);EXPORT_SYMBOL(snd_ak4114_build);EXPORT_SYMBOL(snd_ak4114_external_rate);EXPORT_SYMBOL(snd_ak4114_check_rate_and_errors);

⌨️ 快捷键说明

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