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