[PATCH] ASoC: nau8540: Add self recovery to improve capture quility
Reading the peak data to detect abnormal data in the ADC channel. If abnormal data occurs, the driver takes recovery actions to refresh the ADC channel.
Signed-off-by: David Lin CTLIN0@nuvoton.com --- sound/soc/codecs/nau8540.c | 49 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/nau8540.h | 15 ++++++++++++ 2 files changed, 64 insertions(+)
diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c index 5cf28d034f09..f66417a0f29f 100644 --- a/sound/soc/codecs/nau8540.c +++ b/sound/soc/codecs/nau8540.c @@ -530,12 +530,61 @@ static int nau8540_set_tdm_slot(struct snd_soc_dai *dai, return 0; }
+static int nau8540_dai_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); + struct regmap *regmap = nau8540->regmap; + unsigned int val; + int ret = 0; + + /* Reading the peak data to detect abnormal data in the ADC channel. + * If abnormal data happens, the driver takes recovery actions to + * refresh the ADC channel. + */ + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL, + NAU8540_CLK_AGC_EN, NAU8540_CLK_AGC_EN); + regmap_update_bits(regmap, NAU8540_REG_ALC_CONTROL_3, + NAU8540_ALC_CH_ALL_EN, NAU8540_ALC_CH_ALL_EN); + + regmap_read(regmap, NAU8540_REG_PEAK_CH1, &val); + dev_dbg(nau8540->dev, "1.ADC CH1 peak data %x", val); + if (!val) { + regmap_update_bits(regmap, NAU8540_REG_MUTE, + NAU8540_PGA_CH_ALL_MUTE, NAU8540_PGA_CH_ALL_MUTE); + regmap_update_bits(regmap, NAU8540_REG_MUTE, + NAU8540_PGA_CH_ALL_MUTE, 0); + regmap_write(regmap, NAU8540_REG_RST, 0x1); + regmap_write(regmap, NAU8540_REG_RST, 0); + regmap_read(regmap, NAU8540_REG_PEAK_CH1, &val); + dev_dbg(nau8540->dev, "2.ADC CH1 peak data %x", val); + if (!val) { + dev_err(nau8540->dev, "Channel recovery failed!!"); + ret = -EIO; + } + } + regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL, + NAU8540_CLK_AGC_EN, 0); + regmap_update_bits(regmap, NAU8540_REG_ALC_CONTROL_3, + NAU8540_ALC_CH_ALL_EN, 0); + break; + + default: + break; + } + + return ret; +}
static const struct snd_soc_dai_ops nau8540_dai_ops = { .startup = nau8540_dai_startup, .hw_params = nau8540_hw_params, .set_fmt = nau8540_set_fmt, .set_tdm_slot = nau8540_set_tdm_slot, + .trigger = nau8540_dai_trigger, };
#define NAU8540_RATES SNDRV_PCM_RATE_8000_48000 diff --git a/sound/soc/codecs/nau8540.h b/sound/soc/codecs/nau8540.h index 305ea9207cf0..2ce6063d462b 100644 --- a/sound/soc/codecs/nau8540.h +++ b/sound/soc/codecs/nau8540.h @@ -85,6 +85,7 @@
/* CLOCK_CTRL (0x02) */ #define NAU8540_CLK_ADC_EN (0x1 << 15) +#define NAU8540_CLK_AGC_EN (0x1 << 3) #define NAU8540_CLK_I2S_EN (0x1 << 1)
/* CLOCK_SRC (0x03) */ @@ -168,6 +169,13 @@ #define NAU8540_TDM_OFFSET_EN (0x1 << 14) #define NAU8540_TDM_TX_MASK 0xf
+/* ALC_CONTROL_3 (0x22) */ +#define NAU8540_ALC_CH1_EN (0x1 << 12) +#define NAU8540_ALC_CH2_EN (0x1 << 13) +#define NAU8540_ALC_CH3_EN (0x1 << 14) +#define NAU8540_ALC_CH4_EN (0x1 << 15) +#define NAU8540_ALC_CH_ALL_EN (0xf << 12) + /* ADC_SAMPLE_RATE (0x3A) */ #define NAU8540_CH_SYNC (0x1 << 14) #define NAU8540_ADC_OSR_MASK 0x3 @@ -181,6 +189,13 @@ #define NAU8540_VMID_SEL_SFT 4 #define NAU8540_VMID_SEL_MASK (0x3 << NAU8540_VMID_SEL_SFT)
+/* MUTE (0x61) */ +#define NAU8540_PGA_CH1_MUTE 0x1 +#define NAU8540_PGA_CH2_MUTE 0x2 +#define NAU8540_PGA_CH3_MUTE 0x4 +#define NAU8540_PGA_CH4_MUTE 0x8 +#define NAU8540_PGA_CH_ALL_MUTE 0xf + /* MIC_BIAS (0x67) */ #define NAU8540_PU_PRE (0x1 << 8)
On Wed, 08 Nov 2023 14:16:59 +0800, David Lin wrote:
Reading the peak data to detect abnormal data in the ADC channel. If abnormal data occurs, the driver takes recovery actions to refresh the ADC channel.
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/1] ASoC: nau8540: Add self recovery to improve capture quility commit: a60a609b7f548050d1e84c7aa1c0a57d5d7e22d5
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
David Lin
-
Mark Brown