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

📄 ak4117.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	uinfo->count = 1;	return 0;}static int snd_ak4117_spdif_mask_get(snd_kcontrol_t * kcontrol,				      snd_ctl_elem_value_t * ucontrol){	memset(ucontrol->value.iec958.status, 0xff, AK4117_REG_RXCSB_SIZE);	return 0;}static int snd_ak4117_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_ak4117_spdif_pget(snd_kcontrol_t * kcontrol,				 snd_ctl_elem_value_t * ucontrol){	ak4117_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, AK4117_REG_Pc0) | (reg_read(chip, AK4117_REG_Pc1) << 8);	ucontrol->value.integer.value[2] = tmp;	tmp = reg_read(chip, AK4117_REG_Pd0) | (reg_read(chip, AK4117_REG_Pd1) << 8);	ucontrol->value.integer.value[3] = tmp;	return 0;}static int snd_ak4117_spdif_qinfo(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;	uinfo->count = AK4117_REG_QSUB_SIZE;	return 0;}static int snd_ak4117_spdif_qget(snd_kcontrol_t * kcontrol,				 snd_ctl_elem_value_t * ucontrol){	ak4117_t *chip = snd_kcontrol_chip(kcontrol);	unsigned i;	for (i = 0; i < AK4117_REG_QSUB_SIZE; i++)		ucontrol->value.bytes.data[i] = reg_read(chip, AK4117_REG_QSUB_ADDR + i);	return 0;}/* Don't forget to change AK4117_CONTROLS define!!! */static snd_kcontrol_new_t snd_ak4117_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_ak4117_in_error_info,	.get =		snd_ak4117_in_error_get,	.private_value = offsetof(ak4117_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_ak4117_in_error_info,	.get =		snd_ak4117_in_error_get,	.private_value = offsetof(ak4117_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_ak4117_in_error_info,	.get =		snd_ak4117_in_error_get,	.private_value = offsetof(ak4117_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_ak4117_in_error_info,	.get =		snd_ak4117_in_error_get,	.private_value = offsetof(ak4117_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_ak4117_rate_info,	.get =		snd_ak4117_rate_get,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),	.access =	SNDRV_CTL_ELEM_ACCESS_READ,	.info =		snd_ak4117_spdif_mask_info,	.get =		snd_ak4117_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_ak4117_spdif_info,	.get =		snd_ak4117_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_ak4117_spdif_pinfo,	.get =		snd_ak4117_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_ak4117_spdif_qinfo,	.get =		snd_ak4117_spdif_qget,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"IEC958 Audio",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,	.info =		snd_ak4117_in_bit_info,	.get =		snd_ak4117_in_bit_get,	.private_value = (1<<31) | (3<<8) | AK4117_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_ak4117_in_bit_info,	.get =		snd_ak4117_in_bit_get,	.private_value = (5<<8) | AK4117_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_ak4117_in_bit_info,	.get =		snd_ak4117_in_bit_get,	.private_value = (6<<8) | AK4117_REG_RCS1,},{	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,	.name =		"AK4117 Input Select",	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,	.info =		snd_ak4117_rx_info,	.get =		snd_ak4117_rx_get,	.put =		snd_ak4117_rx_put,}};int snd_ak4117_build(ak4117_t *ak4117, snd_pcm_substream_t *cap_substream){	snd_kcontrol_t *kctl;	unsigned int idx;	int err;	snd_assert(cap_substream, return -EINVAL);	ak4117->substream = cap_substream;	for (idx = 0; idx < AK4117_CONTROLS; idx++) {		kctl = snd_ctl_new1(&snd_ak4117_iec958_controls[idx], ak4117);		if (kctl == NULL)			return -ENOMEM;		kctl->id.device = cap_substream->pcm->device;		kctl->id.subdevice = cap_substream->number;		err = snd_ctl_add(ak4117->card, kctl);		if (err < 0)			return err;		ak4117->kctls[idx] = kctl;	}	return 0;}int snd_ak4117_external_rate(ak4117_t *ak4117){	unsigned char rcs1;	rcs1 = reg_read(ak4117, AK4117_REG_RCS1);	return external_rate(rcs1);}int snd_ak4117_check_rate_and_errors(ak4117_t *ak4117, unsigned int flags){	snd_pcm_runtime_t *runtime = ak4117->substream ? ak4117->substream->runtime : NULL;	unsigned long _flags;	int res = 0;	unsigned char rcs0, rcs1, rcs2;	unsigned char c0, c1;	rcs1 = reg_read(ak4117, AK4117_REG_RCS1);	if (flags & AK4117_CHECK_NO_STAT)		goto __rate;	rcs0 = reg_read(ak4117, AK4117_REG_RCS0);	rcs2 = reg_read(ak4117, AK4117_REG_RCS2);	// printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);	spin_lock_irqsave(&ak4117->lock, _flags);	if (rcs0 & AK4117_PAR)		ak4117->parity_errors++;	if (rcs0 & AK4117_V)		ak4117->v_bit_errors++;	if (rcs2 & AK4117_CCRC)		ak4117->ccrc_errors++;	if (rcs2 & AK4117_QCRC)		ak4117->qcrc_errors++;	c0 = (ak4117->rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)) ^                     (rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK));	c1 = (ak4117->rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)) ^	             (rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f));	ak4117->rcs0 = rcs0 & ~(AK4117_QINT | AK4117_CINT | AK4117_STC);	ak4117->rcs1 = rcs1;	ak4117->rcs2 = rcs2;	spin_unlock_irqrestore(&ak4117->lock, _flags);	if (rcs0 & AK4117_PAR)		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[0]->id);	if (rcs0 & AK4117_V)		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[1]->id);	if (rcs2 & AK4117_CCRC)		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[2]->id);	if (rcs2 & AK4117_QCRC)		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[3]->id);	/* rate change */	if (c1 & 0x0f)		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[4]->id);	if ((c1 & AK4117_PEM) | (c0 & AK4117_CINT))		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[6]->id);	if (c0 & AK4117_QINT)		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[8]->id);	if (c0 & AK4117_AUDION)		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[9]->id);	if (c1 & AK4117_NPCM)		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[10]->id);	if (c1 & AK4117_DTSCD)		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[11]->id);			if (ak4117->change_callback && (c0 | c1) != 0)		ak4117->change_callback(ak4117, c0, c1);      __rate:	/* compare rate */	res = external_rate(rcs1);	if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) {		snd_pcm_stream_lock_irqsave(ak4117->substream, _flags);		if (snd_pcm_running(ak4117->substream)) {			// printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);			snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING);			wake_up(&runtime->sleep);			res = 1;		}		snd_pcm_stream_unlock_irqrestore(ak4117->substream, _flags);	}	return res;}static void snd_ak4117_timer(unsigned long data){	ak4117_t *chip = (ak4117_t *)data;	if (chip->init)		return;	snd_ak4117_check_rate_and_errors(chip, 0);	chip->timer.expires = 1 + jiffies;	add_timer(&chip->timer);}EXPORT_SYMBOL(snd_ak4117_create);EXPORT_SYMBOL(snd_ak4117_reg_write);EXPORT_SYMBOL(snd_ak4117_reinit);EXPORT_SYMBOL(snd_ak4117_build);EXPORT_SYMBOL(snd_ak4117_external_rate);EXPORT_SYMBOL(snd_ak4117_check_rate_and_errors);

⌨️ 快捷键说明

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