cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ak4117.c (16097B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Routines for control of the AK4117 via 4-wire serial interface
      4 *  IEC958 (S/PDIF) receiver by Asahi Kasei
      5 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
      6 */
      7
      8#include <linux/slab.h>
      9#include <linux/delay.h>
     10#include <linux/module.h>
     11#include <sound/core.h>
     12#include <sound/control.h>
     13#include <sound/pcm.h>
     14#include <sound/ak4117.h>
     15#include <sound/asoundef.h>
     16
     17MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
     18MODULE_DESCRIPTION("AK4117 IEC958 (S/PDIF) receiver by Asahi Kasei");
     19MODULE_LICENSE("GPL");
     20
     21#define AK4117_ADDR			0x00 /* fixed address */
     22
     23static void snd_ak4117_timer(struct timer_list *t);
     24
     25static void reg_write(struct ak4117 *ak4117, unsigned char reg, unsigned char val)
     26{
     27	ak4117->write(ak4117->private_data, reg, val);
     28	if (reg < sizeof(ak4117->regmap))
     29		ak4117->regmap[reg] = val;
     30}
     31
     32static inline unsigned char reg_read(struct ak4117 *ak4117, unsigned char reg)
     33{
     34	return ak4117->read(ak4117->private_data, reg);
     35}
     36
     37#if 0
     38static void reg_dump(struct ak4117 *ak4117)
     39{
     40	int i;
     41
     42	printk(KERN_DEBUG "AK4117 REG DUMP:\n");
     43	for (i = 0; i < 0x1b; i++)
     44		printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0);
     45}
     46#endif
     47
     48static void snd_ak4117_free(struct ak4117 *chip)
     49{
     50	del_timer_sync(&chip->timer);
     51	kfree(chip);
     52}
     53
     54static int snd_ak4117_dev_free(struct snd_device *device)
     55{
     56	struct ak4117 *chip = device->device_data;
     57	snd_ak4117_free(chip);
     58	return 0;
     59}
     60
     61int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t *write,
     62		      const unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117)
     63{
     64	struct ak4117 *chip;
     65	int err = 0;
     66	unsigned char reg;
     67	static const struct snd_device_ops ops = {
     68		.dev_free =     snd_ak4117_dev_free,
     69	};
     70
     71	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
     72	if (chip == NULL)
     73		return -ENOMEM;
     74	spin_lock_init(&chip->lock);
     75	chip->card = card;
     76	chip->read = read;
     77	chip->write = write;
     78	chip->private_data = private_data;
     79	timer_setup(&chip->timer, snd_ak4117_timer, 0);
     80
     81	for (reg = 0; reg < 5; reg++)
     82		chip->regmap[reg] = pgm[reg];
     83	snd_ak4117_reinit(chip);
     84
     85	chip->rcs0 = reg_read(chip, AK4117_REG_RCS0) & ~(AK4117_QINT | AK4117_CINT | AK4117_STC);
     86	chip->rcs1 = reg_read(chip, AK4117_REG_RCS1);
     87	chip->rcs2 = reg_read(chip, AK4117_REG_RCS2);
     88
     89	err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops);
     90	if (err < 0)
     91		goto __fail;
     92
     93	if (r_ak4117)
     94		*r_ak4117 = chip;
     95	return 0;
     96
     97      __fail:
     98	snd_ak4117_free(chip);
     99	return err;
    100}
    101
    102void snd_ak4117_reg_write(struct ak4117 *chip, unsigned char reg, unsigned char mask, unsigned char val)
    103{
    104	if (reg >= 5)
    105		return;
    106	reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val);
    107}
    108
    109void snd_ak4117_reinit(struct ak4117 *chip)
    110{
    111	unsigned char old = chip->regmap[AK4117_REG_PWRDN], reg;
    112
    113	del_timer(&chip->timer);
    114	chip->init = 1;
    115	/* bring the chip to reset state and powerdown state */
    116	reg_write(chip, AK4117_REG_PWRDN, 0);
    117	udelay(200);
    118	/* release reset, but leave powerdown */
    119	reg_write(chip, AK4117_REG_PWRDN, (old | AK4117_RST) & ~AK4117_PWN);
    120	udelay(200);
    121	for (reg = 1; reg < 5; reg++)
    122		reg_write(chip, reg, chip->regmap[reg]);
    123	/* release powerdown, everything is initialized now */
    124	reg_write(chip, AK4117_REG_PWRDN, old | AK4117_RST | AK4117_PWN);
    125	chip->init = 0;
    126	mod_timer(&chip->timer, 1 + jiffies);
    127}
    128
    129static unsigned int external_rate(unsigned char rcs1)
    130{
    131	switch (rcs1 & (AK4117_FS0|AK4117_FS1|AK4117_FS2|AK4117_FS3)) {
    132	case AK4117_FS_32000HZ: return 32000;
    133	case AK4117_FS_44100HZ: return 44100;
    134	case AK4117_FS_48000HZ: return 48000;
    135	case AK4117_FS_88200HZ: return 88200;
    136	case AK4117_FS_96000HZ: return 96000;
    137	case AK4117_FS_176400HZ: return 176400;
    138	case AK4117_FS_192000HZ: return 192000;
    139	default:		return 0;
    140	}
    141}
    142
    143static int snd_ak4117_in_error_info(struct snd_kcontrol *kcontrol,
    144				    struct snd_ctl_elem_info *uinfo)
    145{
    146	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    147	uinfo->count = 1;
    148	uinfo->value.integer.min = 0;
    149	uinfo->value.integer.max = LONG_MAX;
    150	return 0;
    151}
    152
    153static int snd_ak4117_in_error_get(struct snd_kcontrol *kcontrol,
    154				   struct snd_ctl_elem_value *ucontrol)
    155{
    156	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
    157
    158	spin_lock_irq(&chip->lock);
    159	ucontrol->value.integer.value[0] =
    160		       chip->errors[kcontrol->private_value];
    161	chip->errors[kcontrol->private_value] = 0;
    162	spin_unlock_irq(&chip->lock);
    163	return 0;
    164}
    165
    166#define snd_ak4117_in_bit_info		snd_ctl_boolean_mono_info
    167
    168static int snd_ak4117_in_bit_get(struct snd_kcontrol *kcontrol,
    169				 struct snd_ctl_elem_value *ucontrol)
    170{
    171	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
    172	unsigned char reg = kcontrol->private_value & 0xff;
    173	unsigned char bit = (kcontrol->private_value >> 8) & 0xff;
    174	unsigned char inv = (kcontrol->private_value >> 31) & 1;
    175
    176	ucontrol->value.integer.value[0] = ((reg_read(chip, reg) & (1 << bit)) ? 1 : 0) ^ inv;
    177	return 0;
    178}
    179
    180static int snd_ak4117_rx_info(struct snd_kcontrol *kcontrol,
    181			      struct snd_ctl_elem_info *uinfo)
    182{
    183	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    184	uinfo->count = 1;
    185	uinfo->value.integer.min = 0;
    186	uinfo->value.integer.max = 1;
    187	return 0;
    188}
    189
    190static int snd_ak4117_rx_get(struct snd_kcontrol *kcontrol,
    191			     struct snd_ctl_elem_value *ucontrol)
    192{
    193	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
    194
    195	ucontrol->value.integer.value[0] = (chip->regmap[AK4117_REG_IO] & AK4117_IPS) ? 1 : 0;
    196	return 0;
    197}
    198
    199static int snd_ak4117_rx_put(struct snd_kcontrol *kcontrol,
    200			     struct snd_ctl_elem_value *ucontrol)
    201{
    202	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
    203	int change;
    204	u8 old_val;
    205	
    206	spin_lock_irq(&chip->lock);
    207	old_val = chip->regmap[AK4117_REG_IO];
    208	change = !!ucontrol->value.integer.value[0] != ((old_val & AK4117_IPS) ? 1 : 0);
    209	if (change)
    210		reg_write(chip, AK4117_REG_IO, (old_val & ~AK4117_IPS) | (ucontrol->value.integer.value[0] ? AK4117_IPS : 0));
    211	spin_unlock_irq(&chip->lock);
    212	return change;
    213}
    214
    215static int snd_ak4117_rate_info(struct snd_kcontrol *kcontrol,
    216				struct snd_ctl_elem_info *uinfo)
    217{
    218	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    219	uinfo->count = 1;
    220	uinfo->value.integer.min = 0;
    221	uinfo->value.integer.max = 192000;
    222	return 0;
    223}
    224
    225static int snd_ak4117_rate_get(struct snd_kcontrol *kcontrol,
    226			       struct snd_ctl_elem_value *ucontrol)
    227{
    228	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
    229
    230	ucontrol->value.integer.value[0] = external_rate(reg_read(chip, AK4117_REG_RCS1));
    231	return 0;
    232}
    233
    234static int snd_ak4117_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
    235{
    236	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
    237	uinfo->count = 1;
    238	return 0;
    239}
    240
    241static int snd_ak4117_spdif_get(struct snd_kcontrol *kcontrol,
    242				struct snd_ctl_elem_value *ucontrol)
    243{
    244	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
    245	unsigned i;
    246
    247	for (i = 0; i < AK4117_REG_RXCSB_SIZE; i++)
    248		ucontrol->value.iec958.status[i] = reg_read(chip, AK4117_REG_RXCSB0 + i);
    249	return 0;
    250}
    251
    252static int snd_ak4117_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
    253{
    254	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
    255	uinfo->count = 1;
    256	return 0;
    257}
    258
    259static int snd_ak4117_spdif_mask_get(struct snd_kcontrol *kcontrol,
    260				      struct snd_ctl_elem_value *ucontrol)
    261{
    262	memset(ucontrol->value.iec958.status, 0xff, AK4117_REG_RXCSB_SIZE);
    263	return 0;
    264}
    265
    266static int snd_ak4117_spdif_pinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
    267{
    268	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    269	uinfo->value.integer.min = 0;
    270	uinfo->value.integer.max = 0xffff;
    271	uinfo->count = 4;
    272	return 0;
    273}
    274
    275static int snd_ak4117_spdif_pget(struct snd_kcontrol *kcontrol,
    276				 struct snd_ctl_elem_value *ucontrol)
    277{
    278	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
    279	unsigned short tmp;
    280
    281	ucontrol->value.integer.value[0] = 0xf8f2;
    282	ucontrol->value.integer.value[1] = 0x4e1f;
    283	tmp = reg_read(chip, AK4117_REG_Pc0) | (reg_read(chip, AK4117_REG_Pc1) << 8);
    284	ucontrol->value.integer.value[2] = tmp;
    285	tmp = reg_read(chip, AK4117_REG_Pd0) | (reg_read(chip, AK4117_REG_Pd1) << 8);
    286	ucontrol->value.integer.value[3] = tmp;
    287	return 0;
    288}
    289
    290static int snd_ak4117_spdif_qinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
    291{
    292	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
    293	uinfo->count = AK4117_REG_QSUB_SIZE;
    294	return 0;
    295}
    296
    297static int snd_ak4117_spdif_qget(struct snd_kcontrol *kcontrol,
    298				 struct snd_ctl_elem_value *ucontrol)
    299{
    300	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
    301	unsigned i;
    302
    303	for (i = 0; i < AK4117_REG_QSUB_SIZE; i++)
    304		ucontrol->value.bytes.data[i] = reg_read(chip, AK4117_REG_QSUB_ADDR + i);
    305	return 0;
    306}
    307
    308/* Don't forget to change AK4117_CONTROLS define!!! */
    309static const struct snd_kcontrol_new snd_ak4117_iec958_controls[] = {
    310{
    311	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    312	.name =		"IEC958 Parity Errors",
    313	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    314	.info =		snd_ak4117_in_error_info,
    315	.get =		snd_ak4117_in_error_get,
    316	.private_value = AK4117_PARITY_ERRORS,
    317},
    318{
    319	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    320	.name =		"IEC958 V-Bit Errors",
    321	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    322	.info =		snd_ak4117_in_error_info,
    323	.get =		snd_ak4117_in_error_get,
    324	.private_value = AK4117_V_BIT_ERRORS,
    325},
    326{
    327	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    328	.name =		"IEC958 C-CRC Errors",
    329	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    330	.info =		snd_ak4117_in_error_info,
    331	.get =		snd_ak4117_in_error_get,
    332	.private_value = AK4117_CCRC_ERRORS,
    333},
    334{
    335	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    336	.name =		"IEC958 Q-CRC Errors",
    337	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    338	.info =		snd_ak4117_in_error_info,
    339	.get =		snd_ak4117_in_error_get,
    340	.private_value = AK4117_QCRC_ERRORS,
    341},
    342{
    343	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    344	.name =		"IEC958 External Rate",
    345	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    346	.info =		snd_ak4117_rate_info,
    347	.get =		snd_ak4117_rate_get,
    348},
    349{
    350	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    351	.name =		SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
    352	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
    353	.info =		snd_ak4117_spdif_mask_info,
    354	.get =		snd_ak4117_spdif_mask_get,
    355},
    356{
    357	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    358	.name =		SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
    359	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    360	.info =		snd_ak4117_spdif_info,
    361	.get =		snd_ak4117_spdif_get,
    362},
    363{
    364	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    365	.name =		"IEC958 Preamble Capture Default",
    366	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    367	.info =		snd_ak4117_spdif_pinfo,
    368	.get =		snd_ak4117_spdif_pget,
    369},
    370{
    371	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    372	.name =		"IEC958 Q-subcode Capture Default",
    373	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    374	.info =		snd_ak4117_spdif_qinfo,
    375	.get =		snd_ak4117_spdif_qget,
    376},
    377{
    378	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    379	.name =		"IEC958 Audio",
    380	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    381	.info =		snd_ak4117_in_bit_info,
    382	.get =		snd_ak4117_in_bit_get,
    383	.private_value = (1<<31) | (3<<8) | AK4117_REG_RCS0,
    384},
    385{
    386	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    387	.name =		"IEC958 Non-PCM Bitstream",
    388	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    389	.info =		snd_ak4117_in_bit_info,
    390	.get =		snd_ak4117_in_bit_get,
    391	.private_value = (5<<8) | AK4117_REG_RCS1,
    392},
    393{
    394	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    395	.name =		"IEC958 DTS Bitstream",
    396	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
    397	.info =		snd_ak4117_in_bit_info,
    398	.get =		snd_ak4117_in_bit_get,
    399	.private_value = (6<<8) | AK4117_REG_RCS1,
    400},
    401{
    402	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
    403	.name =		"AK4117 Input Select",
    404	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE,
    405	.info =		snd_ak4117_rx_info,
    406	.get =		snd_ak4117_rx_get,
    407	.put =		snd_ak4117_rx_put,
    408}
    409};
    410
    411int snd_ak4117_build(struct ak4117 *ak4117, struct snd_pcm_substream *cap_substream)
    412{
    413	struct snd_kcontrol *kctl;
    414	unsigned int idx;
    415	int err;
    416
    417	if (snd_BUG_ON(!cap_substream))
    418		return -EINVAL;
    419	ak4117->substream = cap_substream;
    420	for (idx = 0; idx < AK4117_CONTROLS; idx++) {
    421		kctl = snd_ctl_new1(&snd_ak4117_iec958_controls[idx], ak4117);
    422		if (kctl == NULL)
    423			return -ENOMEM;
    424		kctl->id.device = cap_substream->pcm->device;
    425		kctl->id.subdevice = cap_substream->number;
    426		err = snd_ctl_add(ak4117->card, kctl);
    427		if (err < 0)
    428			return err;
    429		ak4117->kctls[idx] = kctl;
    430	}
    431	return 0;
    432}
    433
    434int snd_ak4117_external_rate(struct ak4117 *ak4117)
    435{
    436	unsigned char rcs1;
    437
    438	rcs1 = reg_read(ak4117, AK4117_REG_RCS1);
    439	return external_rate(rcs1);
    440}
    441
    442int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags)
    443{
    444	struct snd_pcm_runtime *runtime = ak4117->substream ? ak4117->substream->runtime : NULL;
    445	unsigned long _flags;
    446	int res = 0;
    447	unsigned char rcs0, rcs1, rcs2;
    448	unsigned char c0, c1;
    449
    450	rcs1 = reg_read(ak4117, AK4117_REG_RCS1);
    451	if (flags & AK4117_CHECK_NO_STAT)
    452		goto __rate;
    453	rcs0 = reg_read(ak4117, AK4117_REG_RCS0);
    454	rcs2 = reg_read(ak4117, AK4117_REG_RCS2);
    455	// printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
    456	spin_lock_irqsave(&ak4117->lock, _flags);
    457	if (rcs0 & AK4117_PAR)
    458		ak4117->errors[AK4117_PARITY_ERRORS]++;
    459	if (rcs0 & AK4117_V)
    460		ak4117->errors[AK4117_V_BIT_ERRORS]++;
    461	if (rcs2 & AK4117_CCRC)
    462		ak4117->errors[AK4117_CCRC_ERRORS]++;
    463	if (rcs2 & AK4117_QCRC)
    464		ak4117->errors[AK4117_QCRC_ERRORS]++;
    465	c0 = (ak4117->rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)) ^
    466                     (rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK));
    467	c1 = (ak4117->rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)) ^
    468	             (rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f));
    469	ak4117->rcs0 = rcs0 & ~(AK4117_QINT | AK4117_CINT | AK4117_STC);
    470	ak4117->rcs1 = rcs1;
    471	ak4117->rcs2 = rcs2;
    472	spin_unlock_irqrestore(&ak4117->lock, _flags);
    473
    474	if (rcs0 & AK4117_PAR)
    475		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[0]->id);
    476	if (rcs0 & AK4117_V)
    477		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[1]->id);
    478	if (rcs2 & AK4117_CCRC)
    479		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[2]->id);
    480	if (rcs2 & AK4117_QCRC)
    481		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[3]->id);
    482
    483	/* rate change */
    484	if (c1 & 0x0f)
    485		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[4]->id);
    486
    487	if ((c1 & AK4117_PEM) | (c0 & AK4117_CINT))
    488		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[6]->id);
    489	if (c0 & AK4117_QINT)
    490		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[8]->id);
    491
    492	if (c0 & AK4117_AUDION)
    493		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[9]->id);
    494	if (c1 & AK4117_NPCM)
    495		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[10]->id);
    496	if (c1 & AK4117_DTSCD)
    497		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[11]->id);
    498		
    499	if (ak4117->change_callback && (c0 | c1) != 0)
    500		ak4117->change_callback(ak4117, c0, c1);
    501
    502      __rate:
    503	/* compare rate */
    504	res = external_rate(rcs1);
    505	if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) {
    506		snd_pcm_stream_lock_irqsave(ak4117->substream, _flags);
    507		if (snd_pcm_running(ak4117->substream)) {
    508			// printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
    509			snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING);
    510			wake_up(&runtime->sleep);
    511			res = 1;
    512		}
    513		snd_pcm_stream_unlock_irqrestore(ak4117->substream, _flags);
    514	}
    515	return res;
    516}
    517
    518static void snd_ak4117_timer(struct timer_list *t)
    519{
    520	struct ak4117 *chip = from_timer(chip, t, timer);
    521
    522	if (chip->init)
    523		return;
    524	snd_ak4117_check_rate_and_errors(chip, 0);
    525	mod_timer(&chip->timer, 1 + jiffies);
    526}
    527
    528EXPORT_SYMBOL(snd_ak4117_create);
    529EXPORT_SYMBOL(snd_ak4117_reg_write);
    530EXPORT_SYMBOL(snd_ak4117_reinit);
    531EXPORT_SYMBOL(snd_ak4117_build);
    532EXPORT_SYMBOL(snd_ak4117_external_rate);
    533EXPORT_SYMBOL(snd_ak4117_check_rate_and_errors);