diff options
author | David Lin <CTLIN0@nuvoton.com> | 2024-01-16 10:45:20 +0800 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2024-01-22 00:06:40 +0000 |
commit | 9423d7b9edba043c39f1607c752677c8b769922f (patch) | |
tree | daada5eff495b234a2fd2a2ce9835966920277b6 /sound/soc/codecs | |
parent | 90050b8d2e1556238d4c69abc11270de523bf955 (diff) |
ASoC: nau8540: Add pre-charge actions for input
Adding pre-charge mechanism to make FEPGA power stable faster. It
not only improved the recording quality at the beginning but also
meaningfully decreased the final adc delay time.
Signed-off-by: David Lin <CTLIN0@nuvoton.com>
Link: https://msgid.link/r/20240116024519.24569-1-CTLIN0@nuvoton.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/nau8540.c | 116 | ||||
-rw-r--r-- | sound/soc/codecs/nau8540.h | 13 |
2 files changed, 92 insertions, 37 deletions
diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c index f66417a0f29f..22251fb2fa1f 100644 --- a/sound/soc/codecs/nau8540.c +++ b/sound/soc/codecs/nau8540.c @@ -26,7 +26,6 @@ #include <sound/tlv.h> #include "nau8540.h" - #define NAU_FREF_MAX 13500000 #define NAU_FVCO_MAX 100000000 #define NAU_FVCO_MIN 90000000 @@ -230,6 +229,49 @@ static SOC_ENUM_SINGLE_DECL( static const struct snd_kcontrol_new digital_ch1_mux = SOC_DAPM_ENUM("Digital CH1 Select", digital_ch1_enum); +static int nau8540_fepga_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(nau8540->regmap, NAU8540_REG_FEPGA2, + NAU8540_ACDC_CTL_MASK, NAU8540_ACDC_CTL_MIC1P_VREF | + NAU8540_ACDC_CTL_MIC1N_VREF | NAU8540_ACDC_CTL_MIC2P_VREF | + NAU8540_ACDC_CTL_MIC2N_VREF | NAU8540_ACDC_CTL_MIC3P_VREF | + NAU8540_ACDC_CTL_MIC3N_VREF | NAU8540_ACDC_CTL_MIC4P_VREF | + NAU8540_ACDC_CTL_MIC4N_VREF); + break; + default: + break; + } + return 0; +} + +static int nau8540_precharge_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(nau8540->regmap, NAU8540_REG_REFERENCE, + NAU8540_DISCHRG_EN, NAU8540_DISCHRG_EN); + msleep(40); + regmap_update_bits(nau8540->regmap, NAU8540_REG_REFERENCE, + NAU8540_DISCHRG_EN, 0); + regmap_update_bits(nau8540->regmap, NAU8540_REG_FEPGA2, + NAU8540_ACDC_CTL_MASK, 0); + break; + default: + break; + } + return 0; +} + static int adc_power_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { @@ -237,8 +279,10 @@ static int adc_power_control(struct snd_soc_dapm_widget *w, struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component); if (SND_SOC_DAPM_EVENT_ON(event)) { - msleep(300); + msleep(160); /* DO12 and DO34 pad output enable */ + regmap_update_bits(nau8540->regmap, NAU8540_REG_POWER_MANAGEMENT, + NAU8540_ADC_ALL_EN, NAU8540_ADC_ALL_EN); regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1, NAU8540_I2S_DO12_TRI, 0); regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, @@ -248,6 +292,8 @@ static int adc_power_control(struct snd_soc_dapm_widget *w, NAU8540_I2S_DO12_TRI, NAU8540_I2S_DO12_TRI); regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, NAU8540_I2S_DO34_TRI, NAU8540_I2S_DO34_TRI); + regmap_update_bits(nau8540->regmap, NAU8540_REG_POWER_MANAGEMENT, + NAU8540_ADC_ALL_EN, 0); } return 0; } @@ -274,28 +320,26 @@ static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = { SND_SOC_DAPM_INPUT("MIC3"), SND_SOC_DAPM_INPUT("MIC4"), - SND_SOC_DAPM_PGA("Frontend PGA1", NAU8540_REG_PWR, 12, 0, NULL, 0), - SND_SOC_DAPM_PGA("Frontend PGA2", NAU8540_REG_PWR, 13, 0, NULL, 0), - SND_SOC_DAPM_PGA("Frontend PGA3", NAU8540_REG_PWR, 14, 0, NULL, 0), - SND_SOC_DAPM_PGA("Frontend PGA4", NAU8540_REG_PWR, 15, 0, NULL, 0), - - SND_SOC_DAPM_ADC_E("ADC1", NULL, - NAU8540_REG_POWER_MANAGEMENT, 0, 0, adc_power_control, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_ADC_E("ADC2", NULL, - NAU8540_REG_POWER_MANAGEMENT, 1, 0, adc_power_control, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_ADC_E("ADC3", NULL, - NAU8540_REG_POWER_MANAGEMENT, 2, 0, adc_power_control, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_ADC_E("ADC4", NULL, - NAU8540_REG_POWER_MANAGEMENT, 3, 0, adc_power_control, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - - SND_SOC_DAPM_PGA("ADC CH1", NAU8540_REG_ANALOG_PWR, 0, 0, NULL, 0), - SND_SOC_DAPM_PGA("ADC CH2", NAU8540_REG_ANALOG_PWR, 1, 0, NULL, 0), - SND_SOC_DAPM_PGA("ADC CH3", NAU8540_REG_ANALOG_PWR, 2, 0, NULL, 0), - SND_SOC_DAPM_PGA("ADC CH4", NAU8540_REG_ANALOG_PWR, 3, 0, NULL, 0), + SND_SOC_DAPM_PGA_S("Frontend PGA1", 0, NAU8540_REG_PWR, 12, 0, + nau8540_fepga_event, SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PGA_S("Frontend PGA2", 0, NAU8540_REG_PWR, 13, 0, + nau8540_fepga_event, SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PGA_S("Frontend PGA3", 0, NAU8540_REG_PWR, 14, 0, + nau8540_fepga_event, SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PGA_S("Frontend PGA4", 0, NAU8540_REG_PWR, 15, 0, + nau8540_fepga_event, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_PGA_S("Precharge", 1, SND_SOC_NOPM, 0, 0, + nau8540_precharge_event, SND_SOC_DAPM_POST_PMU), + + SND_SOC_DAPM_PGA_S("ADC CH1", 2, NAU8540_REG_ANALOG_PWR, 0, 0, + adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PGA_S("ADC CH2", 2, NAU8540_REG_ANALOG_PWR, 1, 0, + adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PGA_S("ADC CH3", 2, NAU8540_REG_ANALOG_PWR, 2, 0, + adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PGA_S("ADC CH4", 2, NAU8540_REG_ANALOG_PWR, 3, 0, + adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_MUX("Digital CH4 Mux", SND_SOC_NOPM, 0, 0, &digital_ch4_mux), @@ -316,20 +360,20 @@ static const struct snd_soc_dapm_route nau8540_dapm_routes[] = { {"Frontend PGA3", NULL, "MIC3"}, {"Frontend PGA4", NULL, "MIC4"}, - {"ADC1", NULL, "Frontend PGA1"}, - {"ADC2", NULL, "Frontend PGA2"}, - {"ADC3", NULL, "Frontend PGA3"}, - {"ADC4", NULL, "Frontend PGA4"}, + {"Precharge", NULL, "Frontend PGA1"}, + {"Precharge", NULL, "Frontend PGA2"}, + {"Precharge", NULL, "Frontend PGA3"}, + {"Precharge", NULL, "Frontend PGA4"}, - {"ADC CH1", NULL, "ADC1"}, - {"ADC CH2", NULL, "ADC2"}, - {"ADC CH3", NULL, "ADC3"}, - {"ADC CH4", NULL, "ADC4"}, + {"ADC CH1", NULL, "Precharge"}, + {"ADC CH2", NULL, "Precharge"}, + {"ADC CH3", NULL, "Precharge"}, + {"ADC CH4", NULL, "Precharge"}, - {"ADC1", NULL, "MICBIAS1"}, - {"ADC2", NULL, "MICBIAS1"}, - {"ADC3", NULL, "MICBIAS2"}, - {"ADC4", NULL, "MICBIAS2"}, + {"ADC CH1", NULL, "MICBIAS1"}, + {"ADC CH2", NULL, "MICBIAS1"}, + {"ADC CH3", NULL, "MICBIAS2"}, + {"ADC CH4", NULL, "MICBIAS2"}, {"Digital CH1 Mux", "ADC channel 1", "ADC CH1"}, {"Digital CH1 Mux", "ADC channel 2", "ADC CH2"}, diff --git a/sound/soc/codecs/nau8540.h b/sound/soc/codecs/nau8540.h index 2ce6063d462b..762bb93b06fd 100644 --- a/sound/soc/codecs/nau8540.h +++ b/sound/soc/codecs/nau8540.h @@ -78,6 +78,7 @@ /* POWER_MANAGEMENT (0x01) */ +#define NAU8540_ADC_ALL_EN 0xf #define NAU8540_ADC4_EN (0x1 << 3) #define NAU8540_ADC3_EN (0x1 << 2) #define NAU8540_ADC2_EN (0x1 << 1) @@ -202,6 +203,7 @@ /* REFERENCE (0x68) */ #define NAU8540_PRECHARGE_DIS (0x1 << 13) #define NAU8540_GLOBAL_BIAS_EN (0x1 << 12) +#define NAU8540_DISCHRG_EN (0x1 << 11) /* FEPGA1 (0x69) */ #define NAU8540_FEPGA1_MODCH2_SHT_SFT 7 @@ -214,7 +216,16 @@ #define NAU8540_FEPGA2_MODCH4_SHT (0x1 << NAU8540_FEPGA2_MODCH4_SHT_SFT) #define NAU8540_FEPGA2_MODCH3_SHT_SFT 3 #define NAU8540_FEPGA2_MODCH3_SHT (0x1 << NAU8540_FEPGA2_MODCH3_SHT_SFT) - +#define NAU8540_ACDC_CTL_SFT 8 +#define NAU8540_ACDC_CTL_MASK (0xff << NAU8540_ACDC_CTL_SFT) +#define NAU8540_ACDC_CTL_MIC4N_VREF (0x1 << 15) +#define NAU8540_ACDC_CTL_MIC4P_VREF (0x1 << 14) +#define NAU8540_ACDC_CTL_MIC3N_VREF (0x1 << 13) +#define NAU8540_ACDC_CTL_MIC3P_VREF (0x1 << 12) +#define NAU8540_ACDC_CTL_MIC2N_VREF (0x1 << 11) +#define NAU8540_ACDC_CTL_MIC2P_VREF (0x1 << 10) +#define NAU8540_ACDC_CTL_MIC1N_VREF (0x1 << 9) +#define NAU8540_ACDC_CTL_MIC1P_VREF (0x1 << 8) /* System Clock Source */ enum { |