brintos

brintos / linux-shallow public Read only

0
0
Text · 17.3 KiB · c1f7447 Raw
639 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *  Routines for control of the AK4113 via I2C/4-wire serial interface4 *  IEC958 (S/PDIF) receiver by Asahi Kasei5 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>6 *  Copyright (c) by Pavel Hofman <pavel.hofman@ivitera.com>7 */8 9#include <linux/slab.h>10#include <linux/delay.h>11#include <linux/module.h>12#include <sound/core.h>13#include <sound/control.h>14#include <sound/pcm.h>15#include <sound/ak4113.h>16#include <sound/asoundef.h>17#include <sound/info.h>18 19MODULE_AUTHOR("Pavel Hofman <pavel.hofman@ivitera.com>");20MODULE_DESCRIPTION("AK4113 IEC958 (S/PDIF) receiver by Asahi Kasei");21MODULE_LICENSE("GPL");22 23#define AK4113_ADDR			0x00 /* fixed address */24 25static void ak4113_stats(struct work_struct *work);26static void ak4113_init_regs(struct ak4113 *chip);27 28 29static void reg_write(struct ak4113 *ak4113, unsigned char reg,30		unsigned char val)31{32	ak4113->write(ak4113->private_data, reg, val);33	if (reg < sizeof(ak4113->regmap))34		ak4113->regmap[reg] = val;35}36 37static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg)38{39	return ak4113->read(ak4113->private_data, reg);40}41 42static void snd_ak4113_free(struct ak4113 *chip)43{44	atomic_inc(&chip->wq_processing);	/* don't schedule new work */45	cancel_delayed_work_sync(&chip->work);46	kfree(chip);47}48 49static int snd_ak4113_dev_free(struct snd_device *device)50{51	struct ak4113 *chip = device->device_data;52	snd_ak4113_free(chip);53	return 0;54}55 56int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,57		ak4113_write_t *write, const unsigned char *pgm,58		void *private_data, struct ak4113 **r_ak4113)59{60	struct ak4113 *chip;61	int err;62	unsigned char reg;63	static const struct snd_device_ops ops = {64		.dev_free =     snd_ak4113_dev_free,65	};66 67	chip = kzalloc(sizeof(*chip), GFP_KERNEL);68	if (chip == NULL)69		return -ENOMEM;70	spin_lock_init(&chip->lock);71	chip->card = card;72	chip->read = read;73	chip->write = write;74	chip->private_data = private_data;75	INIT_DELAYED_WORK(&chip->work, ak4113_stats);76	atomic_set(&chip->wq_processing, 0);77	mutex_init(&chip->reinit_mutex);78 79	for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)80		chip->regmap[reg] = pgm[reg];81	ak4113_init_regs(chip);82 83	chip->rcs0 = reg_read(chip, AK4113_REG_RCS0) & ~(AK4113_QINT |84			AK4113_CINT | AK4113_STC);85	chip->rcs1 = reg_read(chip, AK4113_REG_RCS1);86	chip->rcs2 = reg_read(chip, AK4113_REG_RCS2);87	err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops);88	if (err < 0)89		goto __fail;90 91	if (r_ak4113)92		*r_ak4113 = chip;93	return 0;94 95__fail:96	snd_ak4113_free(chip);97	return err;98}99EXPORT_SYMBOL_GPL(snd_ak4113_create);100 101void snd_ak4113_reg_write(struct ak4113 *chip, unsigned char reg,102		unsigned char mask, unsigned char val)103{104	if (reg >= AK4113_WRITABLE_REGS)105		return;106	reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val);107}108EXPORT_SYMBOL_GPL(snd_ak4113_reg_write);109 110static void ak4113_init_regs(struct ak4113 *chip)111{112	unsigned char old = chip->regmap[AK4113_REG_PWRDN], reg;113 114	/* bring the chip to reset state and powerdown state */115	reg_write(chip, AK4113_REG_PWRDN, old & ~(AK4113_RST|AK4113_PWN));116	udelay(200);117	/* release reset, but leave powerdown */118	reg_write(chip, AK4113_REG_PWRDN, (old | AK4113_RST) & ~AK4113_PWN);119	udelay(200);120	for (reg = 1; reg < AK4113_WRITABLE_REGS; reg++)121		reg_write(chip, reg, chip->regmap[reg]);122	/* release powerdown, everything is initialized now */123	reg_write(chip, AK4113_REG_PWRDN, old | AK4113_RST | AK4113_PWN);124}125 126void snd_ak4113_reinit(struct ak4113 *chip)127{128	if (atomic_inc_return(&chip->wq_processing) == 1)129		cancel_delayed_work_sync(&chip->work);130	mutex_lock(&chip->reinit_mutex);131	ak4113_init_regs(chip);132	mutex_unlock(&chip->reinit_mutex);133	/* bring up statistics / event queing */134	if (atomic_dec_and_test(&chip->wq_processing))135		schedule_delayed_work(&chip->work, HZ / 10);136}137EXPORT_SYMBOL_GPL(snd_ak4113_reinit);138 139static unsigned int external_rate(unsigned char rcs1)140{141	switch (rcs1 & (AK4113_FS0|AK4113_FS1|AK4113_FS2|AK4113_FS3)) {142	case AK4113_FS_8000HZ:143		return 8000;144	case AK4113_FS_11025HZ:145		return 11025;146	case AK4113_FS_16000HZ:147		return 16000;148	case AK4113_FS_22050HZ:149		return 22050;150	case AK4113_FS_24000HZ:151		return 24000;152	case AK4113_FS_32000HZ:153		return 32000;154	case AK4113_FS_44100HZ:155		return 44100;156	case AK4113_FS_48000HZ:157		return 48000;158	case AK4113_FS_64000HZ:159		return 64000;160	case AK4113_FS_88200HZ:161		return 88200;162	case AK4113_FS_96000HZ:163		return 96000;164	case AK4113_FS_176400HZ:165		return 176400;166	case AK4113_FS_192000HZ:167		return 192000;168	default:169		return 0;170	}171}172 173static int snd_ak4113_in_error_info(struct snd_kcontrol *kcontrol,174				    struct snd_ctl_elem_info *uinfo)175{176	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;177	uinfo->count = 1;178	uinfo->value.integer.min = 0;179	uinfo->value.integer.max = LONG_MAX;180	return 0;181}182 183static int snd_ak4113_in_error_get(struct snd_kcontrol *kcontrol,184				   struct snd_ctl_elem_value *ucontrol)185{186	struct ak4113 *chip = snd_kcontrol_chip(kcontrol);187 188	spin_lock_irq(&chip->lock);189	ucontrol->value.integer.value[0] =190		chip->errors[kcontrol->private_value];191	chip->errors[kcontrol->private_value] = 0;192	spin_unlock_irq(&chip->lock);193	return 0;194}195 196#define snd_ak4113_in_bit_info		snd_ctl_boolean_mono_info197 198static int snd_ak4113_in_bit_get(struct snd_kcontrol *kcontrol,199				 struct snd_ctl_elem_value *ucontrol)200{201	struct ak4113 *chip = snd_kcontrol_chip(kcontrol);202	unsigned char reg = kcontrol->private_value & 0xff;203	unsigned char bit = (kcontrol->private_value >> 8) & 0xff;204	unsigned char inv = (kcontrol->private_value >> 31) & 1;205 206	ucontrol->value.integer.value[0] =207		((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv;208	return 0;209}210 211static int snd_ak4113_rx_info(struct snd_kcontrol *kcontrol,212			      struct snd_ctl_elem_info *uinfo)213{214	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;215	uinfo->count = 1;216	uinfo->value.integer.min = 0;217	uinfo->value.integer.max = 5;218	return 0;219}220 221static int snd_ak4113_rx_get(struct snd_kcontrol *kcontrol,222			     struct snd_ctl_elem_value *ucontrol)223{224	struct ak4113 *chip = snd_kcontrol_chip(kcontrol);225 226	ucontrol->value.integer.value[0] =227		(AK4113_IPS(chip->regmap[AK4113_REG_IO1]));228	return 0;229}230 231static int snd_ak4113_rx_put(struct snd_kcontrol *kcontrol,232			     struct snd_ctl_elem_value *ucontrol)233{234	struct ak4113 *chip = snd_kcontrol_chip(kcontrol);235	int change;236	u8 old_val;237 238	spin_lock_irq(&chip->lock);239	old_val = chip->regmap[AK4113_REG_IO1];240	change = ucontrol->value.integer.value[0] != AK4113_IPS(old_val);241	if (change)242		reg_write(chip, AK4113_REG_IO1,243				(old_val & (~AK4113_IPS(0xff))) |244				(AK4113_IPS(ucontrol->value.integer.value[0])));245	spin_unlock_irq(&chip->lock);246	return change;247}248 249static int snd_ak4113_rate_info(struct snd_kcontrol *kcontrol,250				struct snd_ctl_elem_info *uinfo)251{252	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;253	uinfo->count = 1;254	uinfo->value.integer.min = 0;255	uinfo->value.integer.max = 192000;256	return 0;257}258 259static int snd_ak4113_rate_get(struct snd_kcontrol *kcontrol,260			       struct snd_ctl_elem_value *ucontrol)261{262	struct ak4113 *chip = snd_kcontrol_chip(kcontrol);263 264	ucontrol->value.integer.value[0] = external_rate(reg_read(chip,265				AK4113_REG_RCS1));266	return 0;267}268 269static int snd_ak4113_spdif_info(struct snd_kcontrol *kcontrol,270		struct snd_ctl_elem_info *uinfo)271{272	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;273	uinfo->count = 1;274	return 0;275}276 277static int snd_ak4113_spdif_get(struct snd_kcontrol *kcontrol,278				struct snd_ctl_elem_value *ucontrol)279{280	struct ak4113 *chip = snd_kcontrol_chip(kcontrol);281	unsigned i;282 283	for (i = 0; i < AK4113_REG_RXCSB_SIZE; i++)284		ucontrol->value.iec958.status[i] = reg_read(chip,285				AK4113_REG_RXCSB0 + i);286	return 0;287}288 289static int snd_ak4113_spdif_mask_info(struct snd_kcontrol *kcontrol,290		struct snd_ctl_elem_info *uinfo)291{292	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;293	uinfo->count = 1;294	return 0;295}296 297static int snd_ak4113_spdif_mask_get(struct snd_kcontrol *kcontrol,298				      struct snd_ctl_elem_value *ucontrol)299{300	memset(ucontrol->value.iec958.status, 0xff, AK4113_REG_RXCSB_SIZE);301	return 0;302}303 304static int snd_ak4113_spdif_pinfo(struct snd_kcontrol *kcontrol,305		struct snd_ctl_elem_info *uinfo)306{307	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;308	uinfo->value.integer.min = 0;309	uinfo->value.integer.max = 0xffff;310	uinfo->count = 4;311	return 0;312}313 314static int snd_ak4113_spdif_pget(struct snd_kcontrol *kcontrol,315				 struct snd_ctl_elem_value *ucontrol)316{317	struct ak4113 *chip = snd_kcontrol_chip(kcontrol);318	unsigned short tmp;319 320	ucontrol->value.integer.value[0] = 0xf8f2;321	ucontrol->value.integer.value[1] = 0x4e1f;322	tmp = reg_read(chip, AK4113_REG_Pc0) |323		(reg_read(chip, AK4113_REG_Pc1) << 8);324	ucontrol->value.integer.value[2] = tmp;325	tmp = reg_read(chip, AK4113_REG_Pd0) |326		(reg_read(chip, AK4113_REG_Pd1) << 8);327	ucontrol->value.integer.value[3] = tmp;328	return 0;329}330 331static int snd_ak4113_spdif_qinfo(struct snd_kcontrol *kcontrol,332		struct snd_ctl_elem_info *uinfo)333{334	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;335	uinfo->count = AK4113_REG_QSUB_SIZE;336	return 0;337}338 339static int snd_ak4113_spdif_qget(struct snd_kcontrol *kcontrol,340				 struct snd_ctl_elem_value *ucontrol)341{342	struct ak4113 *chip = snd_kcontrol_chip(kcontrol);343	unsigned i;344 345	for (i = 0; i < AK4113_REG_QSUB_SIZE; i++)346		ucontrol->value.bytes.data[i] = reg_read(chip,347				AK4113_REG_QSUB_ADDR + i);348	return 0;349}350 351/* Don't forget to change AK4113_CONTROLS define!!! */352static const struct snd_kcontrol_new snd_ak4113_iec958_controls[] = {353{354	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,355	.name =		"IEC958 Parity Errors",356	.access =	SNDRV_CTL_ELEM_ACCESS_READ |357		SNDRV_CTL_ELEM_ACCESS_VOLATILE,358	.info =		snd_ak4113_in_error_info,359	.get =		snd_ak4113_in_error_get,360	.private_value = AK4113_PARITY_ERRORS,361},362{363	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,364	.name =		"IEC958 V-Bit Errors",365	.access =	SNDRV_CTL_ELEM_ACCESS_READ |366		SNDRV_CTL_ELEM_ACCESS_VOLATILE,367	.info =		snd_ak4113_in_error_info,368	.get =		snd_ak4113_in_error_get,369	.private_value = AK4113_V_BIT_ERRORS,370},371{372	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,373	.name =		"IEC958 C-CRC Errors",374	.access =	SNDRV_CTL_ELEM_ACCESS_READ |375		SNDRV_CTL_ELEM_ACCESS_VOLATILE,376	.info =		snd_ak4113_in_error_info,377	.get =		snd_ak4113_in_error_get,378	.private_value = AK4113_CCRC_ERRORS,379},380{381	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,382	.name =		"IEC958 Q-CRC Errors",383	.access =	SNDRV_CTL_ELEM_ACCESS_READ |384		SNDRV_CTL_ELEM_ACCESS_VOLATILE,385	.info =		snd_ak4113_in_error_info,386	.get =		snd_ak4113_in_error_get,387	.private_value = AK4113_QCRC_ERRORS,388},389{390	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,391	.name =		"IEC958 External Rate",392	.access =	SNDRV_CTL_ELEM_ACCESS_READ |393		SNDRV_CTL_ELEM_ACCESS_VOLATILE,394	.info =		snd_ak4113_rate_info,395	.get =		snd_ak4113_rate_get,396},397{398	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,399	.name =		SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),400	.access =	SNDRV_CTL_ELEM_ACCESS_READ,401	.info =		snd_ak4113_spdif_mask_info,402	.get =		snd_ak4113_spdif_mask_get,403},404{405	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,406	.name =		SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),407	.access =	SNDRV_CTL_ELEM_ACCESS_READ |408		SNDRV_CTL_ELEM_ACCESS_VOLATILE,409	.info =		snd_ak4113_spdif_info,410	.get =		snd_ak4113_spdif_get,411},412{413	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,414	.name =		"IEC958 Preamble Capture Default",415	.access =	SNDRV_CTL_ELEM_ACCESS_READ |416		SNDRV_CTL_ELEM_ACCESS_VOLATILE,417	.info =		snd_ak4113_spdif_pinfo,418	.get =		snd_ak4113_spdif_pget,419},420{421	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,422	.name =		"IEC958 Q-subcode Capture Default",423	.access =	SNDRV_CTL_ELEM_ACCESS_READ |424		SNDRV_CTL_ELEM_ACCESS_VOLATILE,425	.info =		snd_ak4113_spdif_qinfo,426	.get =		snd_ak4113_spdif_qget,427},428{429	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,430	.name =		"IEC958 Audio",431	.access =	SNDRV_CTL_ELEM_ACCESS_READ |432		SNDRV_CTL_ELEM_ACCESS_VOLATILE,433	.info =		snd_ak4113_in_bit_info,434	.get =		snd_ak4113_in_bit_get,435	.private_value = (1<<31) | (1<<8) | AK4113_REG_RCS0,436},437{438	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,439	.name =		"IEC958 Non-PCM Bitstream",440	.access =	SNDRV_CTL_ELEM_ACCESS_READ |441		SNDRV_CTL_ELEM_ACCESS_VOLATILE,442	.info =		snd_ak4113_in_bit_info,443	.get =		snd_ak4113_in_bit_get,444	.private_value = (0<<8) | AK4113_REG_RCS1,445},446{447	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,448	.name =		"IEC958 DTS Bitstream",449	.access =	SNDRV_CTL_ELEM_ACCESS_READ |450		SNDRV_CTL_ELEM_ACCESS_VOLATILE,451	.info =		snd_ak4113_in_bit_info,452	.get =		snd_ak4113_in_bit_get,453	.private_value = (1<<8) | AK4113_REG_RCS1,454},455{456	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,457	.name =		"AK4113 Input Select",458	.access =	SNDRV_CTL_ELEM_ACCESS_READ |459		SNDRV_CTL_ELEM_ACCESS_WRITE,460	.info =		snd_ak4113_rx_info,461	.get =		snd_ak4113_rx_get,462	.put =		snd_ak4113_rx_put,463}464};465 466static void snd_ak4113_proc_regs_read(struct snd_info_entry *entry,467		struct snd_info_buffer *buffer)468{469	struct ak4113 *ak4113 = entry->private_data;470	int reg, val;471	/* all ak4113 registers 0x00 - 0x1c */472	for (reg = 0; reg < 0x1d; reg++) {473		val = reg_read(ak4113, reg);474		snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val);475	}476}477 478static void snd_ak4113_proc_init(struct ak4113 *ak4113)479{480	snd_card_ro_proc_new(ak4113->card, "ak4113", ak4113,481			     snd_ak4113_proc_regs_read);482}483 484int snd_ak4113_build(struct ak4113 *ak4113,485		struct snd_pcm_substream *cap_substream)486{487	struct snd_kcontrol *kctl;488	unsigned int idx;489	int err;490 491	if (snd_BUG_ON(!cap_substream))492		return -EINVAL;493	ak4113->substream = cap_substream;494	for (idx = 0; idx < AK4113_CONTROLS; idx++) {495		kctl = snd_ctl_new1(&snd_ak4113_iec958_controls[idx], ak4113);496		if (kctl == NULL)497			return -ENOMEM;498		kctl->id.device = cap_substream->pcm->device;499		kctl->id.subdevice = cap_substream->number;500		err = snd_ctl_add(ak4113->card, kctl);501		if (err < 0)502			return err;503		ak4113->kctls[idx] = kctl;504	}505	snd_ak4113_proc_init(ak4113);506	/* trigger workq */507	schedule_delayed_work(&ak4113->work, HZ / 10);508	return 0;509}510EXPORT_SYMBOL_GPL(snd_ak4113_build);511 512int snd_ak4113_external_rate(struct ak4113 *ak4113)513{514	unsigned char rcs1;515 516	rcs1 = reg_read(ak4113, AK4113_REG_RCS1);517	return external_rate(rcs1);518}519EXPORT_SYMBOL_GPL(snd_ak4113_external_rate);520 521int snd_ak4113_check_rate_and_errors(struct ak4113 *ak4113, unsigned int flags)522{523	struct snd_pcm_runtime *runtime =524		ak4113->substream ? ak4113->substream->runtime : NULL;525	unsigned long _flags;526	int res = 0;527	unsigned char rcs0, rcs1, rcs2;528	unsigned char c0, c1;529 530	rcs1 = reg_read(ak4113, AK4113_REG_RCS1);531	if (flags & AK4113_CHECK_NO_STAT)532		goto __rate;533	rcs0 = reg_read(ak4113, AK4113_REG_RCS0);534	rcs2 = reg_read(ak4113, AK4113_REG_RCS2);535	spin_lock_irqsave(&ak4113->lock, _flags);536	if (rcs0 & AK4113_PAR)537		ak4113->errors[AK4113_PARITY_ERRORS]++;538	if (rcs0 & AK4113_V)539		ak4113->errors[AK4113_V_BIT_ERRORS]++;540	if (rcs2 & AK4113_CCRC)541		ak4113->errors[AK4113_CCRC_ERRORS]++;542	if (rcs2 & AK4113_QCRC)543		ak4113->errors[AK4113_QCRC_ERRORS]++;544	c0 = (ak4113->rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |545				AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK)) ^546		(rcs0 & (AK4113_QINT | AK4113_CINT | AK4113_STC |547			 AK4113_AUDION | AK4113_AUTO | AK4113_UNLCK));548	c1 = (ak4113->rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |549				AK4113_DAT | 0xf0)) ^550		(rcs1 & (AK4113_DTSCD | AK4113_NPCM | AK4113_PEM |551			 AK4113_DAT | 0xf0));552	ak4113->rcs0 = rcs0 & ~(AK4113_QINT | AK4113_CINT | AK4113_STC);553	ak4113->rcs1 = rcs1;554	ak4113->rcs2 = rcs2;555	spin_unlock_irqrestore(&ak4113->lock, _flags);556 557	if (rcs0 & AK4113_PAR)558		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,559				&ak4113->kctls[0]->id);560	if (rcs0 & AK4113_V)561		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,562				&ak4113->kctls[1]->id);563	if (rcs2 & AK4113_CCRC)564		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,565				&ak4113->kctls[2]->id);566	if (rcs2 & AK4113_QCRC)567		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,568				&ak4113->kctls[3]->id);569 570	/* rate change */571	if (c1 & 0xf0)572		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,573				&ak4113->kctls[4]->id);574 575	if ((c1 & AK4113_PEM) | (c0 & AK4113_CINT))576		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,577				&ak4113->kctls[6]->id);578	if (c0 & AK4113_QINT)579		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,580				&ak4113->kctls[8]->id);581 582	if (c0 & AK4113_AUDION)583		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,584				&ak4113->kctls[9]->id);585	if (c1 & AK4113_NPCM)586		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,587				&ak4113->kctls[10]->id);588	if (c1 & AK4113_DTSCD)589		snd_ctl_notify(ak4113->card, SNDRV_CTL_EVENT_MASK_VALUE,590				&ak4113->kctls[11]->id);591 592	if (ak4113->change_callback && (c0 | c1) != 0)593		ak4113->change_callback(ak4113, c0, c1);594 595__rate:596	/* compare rate */597	res = external_rate(rcs1);598	if (!(flags & AK4113_CHECK_NO_RATE) && runtime &&599			(runtime->rate != res)) {600		snd_pcm_stream_lock_irqsave(ak4113->substream, _flags);601		if (snd_pcm_running(ak4113->substream)) {602			snd_pcm_stop(ak4113->substream,603					SNDRV_PCM_STATE_DRAINING);604			wake_up(&runtime->sleep);605			res = 1;606		}607		snd_pcm_stream_unlock_irqrestore(ak4113->substream, _flags);608	}609	return res;610}611EXPORT_SYMBOL_GPL(snd_ak4113_check_rate_and_errors);612 613static void ak4113_stats(struct work_struct *work)614{615	struct ak4113 *chip = container_of(work, struct ak4113, work.work);616 617	if (atomic_inc_return(&chip->wq_processing) == 1)618		snd_ak4113_check_rate_and_errors(chip, chip->check_flags);619 620	if (atomic_dec_and_test(&chip->wq_processing))621		schedule_delayed_work(&chip->work, HZ / 10);622}623 624#ifdef CONFIG_PM625void snd_ak4113_suspend(struct ak4113 *chip)626{627	atomic_inc(&chip->wq_processing); /* don't schedule new work */628	cancel_delayed_work_sync(&chip->work);629}630EXPORT_SYMBOL(snd_ak4113_suspend);631 632void snd_ak4113_resume(struct ak4113 *chip)633{634	atomic_dec(&chip->wq_processing);635	snd_ak4113_reinit(chip);636}637EXPORT_SYMBOL(snd_ak4113_resume);638#endif639