Skip to content

Commit a60a609

Browse files
David Linbroonie
authored andcommitted
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> Link: https://lore.kernel.org/r/20231108061658.1265065-1-CTLIN0@nuvoton.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 45f2f28 commit a60a609

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

sound/soc/codecs/nau8540.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,12 +530,61 @@ static int nau8540_set_tdm_slot(struct snd_soc_dai *dai,
530530
return 0;
531531
}
532532

533+
static int nau8540_dai_trigger(struct snd_pcm_substream *substream,
534+
int cmd, struct snd_soc_dai *dai)
535+
{
536+
struct snd_soc_component *component = dai->component;
537+
struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);
538+
struct regmap *regmap = nau8540->regmap;
539+
unsigned int val;
540+
int ret = 0;
541+
542+
/* Reading the peak data to detect abnormal data in the ADC channel.
543+
* If abnormal data happens, the driver takes recovery actions to
544+
* refresh the ADC channel.
545+
*/
546+
switch (cmd) {
547+
case SNDRV_PCM_TRIGGER_START:
548+
regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL,
549+
NAU8540_CLK_AGC_EN, NAU8540_CLK_AGC_EN);
550+
regmap_update_bits(regmap, NAU8540_REG_ALC_CONTROL_3,
551+
NAU8540_ALC_CH_ALL_EN, NAU8540_ALC_CH_ALL_EN);
552+
553+
regmap_read(regmap, NAU8540_REG_PEAK_CH1, &val);
554+
dev_dbg(nau8540->dev, "1.ADC CH1 peak data %x", val);
555+
if (!val) {
556+
regmap_update_bits(regmap, NAU8540_REG_MUTE,
557+
NAU8540_PGA_CH_ALL_MUTE, NAU8540_PGA_CH_ALL_MUTE);
558+
regmap_update_bits(regmap, NAU8540_REG_MUTE,
559+
NAU8540_PGA_CH_ALL_MUTE, 0);
560+
regmap_write(regmap, NAU8540_REG_RST, 0x1);
561+
regmap_write(regmap, NAU8540_REG_RST, 0);
562+
regmap_read(regmap, NAU8540_REG_PEAK_CH1, &val);
563+
dev_dbg(nau8540->dev, "2.ADC CH1 peak data %x", val);
564+
if (!val) {
565+
dev_err(nau8540->dev, "Channel recovery failed!!");
566+
ret = -EIO;
567+
}
568+
}
569+
regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL,
570+
NAU8540_CLK_AGC_EN, 0);
571+
regmap_update_bits(regmap, NAU8540_REG_ALC_CONTROL_3,
572+
NAU8540_ALC_CH_ALL_EN, 0);
573+
break;
574+
575+
default:
576+
break;
577+
}
578+
579+
return ret;
580+
}
533581

534582
static const struct snd_soc_dai_ops nau8540_dai_ops = {
535583
.startup = nau8540_dai_startup,
536584
.hw_params = nau8540_hw_params,
537585
.set_fmt = nau8540_set_fmt,
538586
.set_tdm_slot = nau8540_set_tdm_slot,
587+
.trigger = nau8540_dai_trigger,
539588
};
540589

541590
#define NAU8540_RATES SNDRV_PCM_RATE_8000_48000

sound/soc/codecs/nau8540.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585

8686
/* CLOCK_CTRL (0x02) */
8787
#define NAU8540_CLK_ADC_EN (0x1 << 15)
88+
#define NAU8540_CLK_AGC_EN (0x1 << 3)
8889
#define NAU8540_CLK_I2S_EN (0x1 << 1)
8990

9091
/* CLOCK_SRC (0x03) */
@@ -168,6 +169,13 @@
168169
#define NAU8540_TDM_OFFSET_EN (0x1 << 14)
169170
#define NAU8540_TDM_TX_MASK 0xf
170171

172+
/* ALC_CONTROL_3 (0x22) */
173+
#define NAU8540_ALC_CH1_EN (0x1 << 12)
174+
#define NAU8540_ALC_CH2_EN (0x1 << 13)
175+
#define NAU8540_ALC_CH3_EN (0x1 << 14)
176+
#define NAU8540_ALC_CH4_EN (0x1 << 15)
177+
#define NAU8540_ALC_CH_ALL_EN (0xf << 12)
178+
171179
/* ADC_SAMPLE_RATE (0x3A) */
172180
#define NAU8540_CH_SYNC (0x1 << 14)
173181
#define NAU8540_ADC_OSR_MASK 0x3
@@ -181,6 +189,13 @@
181189
#define NAU8540_VMID_SEL_SFT 4
182190
#define NAU8540_VMID_SEL_MASK (0x3 << NAU8540_VMID_SEL_SFT)
183191

192+
/* MUTE (0x61) */
193+
#define NAU8540_PGA_CH1_MUTE 0x1
194+
#define NAU8540_PGA_CH2_MUTE 0x2
195+
#define NAU8540_PGA_CH3_MUTE 0x4
196+
#define NAU8540_PGA_CH4_MUTE 0x8
197+
#define NAU8540_PGA_CH_ALL_MUTE 0xf
198+
184199
/* MIC_BIAS (0x67) */
185200
#define NAU8540_PU_PRE (0x1 << 8)
186201

0 commit comments

Comments
 (0)