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