ASoC: nau8821: Improve AMIC recording performance.
authorSeven Lee <wtli@nuvoton.com>
Wed, 23 Aug 2023 07:12:44 +0000 (15:12 +0800)
committerMark Brown <broonie@kernel.org>
Wed, 23 Aug 2023 12:27:22 +0000 (13:27 +0100)
Since the hardware may be designed as a single-ended input, the headset mic
record only supports single-ended input on the left side. This patch
will enhance microphone recording performance for single-end.

Signed-off-by: Seven Lee <wtli@nuvoton.com>
Link: https://lore.kernel.org/r/20230823071244.1861487-2-wtli@nuvoton.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/nau8821.c
sound/soc/codecs/nau8821.h

index ca6beb2..f307374 100644 (file)
@@ -624,6 +624,36 @@ static int system_clock_control(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
+static int nau8821_left_fepga_event(struct snd_soc_dapm_widget *w,
+               struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+       struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component);
+
+       if (!nau8821->left_input_single_end)
+               return 0;
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               regmap_update_bits(nau8821->regmap, NAU8821_R77_FEPGA,
+                       NAU8821_ACDC_CTRL_MASK | NAU8821_FEPGA_MODEL_MASK,
+                       NAU8821_ACDC_VREF_MICN | NAU8821_FEPGA_MODEL_AAF);
+               regmap_update_bits(nau8821->regmap, NAU8821_R76_BOOST,
+                       NAU8821_HP_BOOST_DISCHRG_EN, NAU8821_HP_BOOST_DISCHRG_EN);
+               break;
+       case SND_SOC_DAPM_POST_PMD:
+               regmap_update_bits(nau8821->regmap, NAU8821_R77_FEPGA,
+                       NAU8821_ACDC_CTRL_MASK | NAU8821_FEPGA_MODEL_MASK, 0);
+               regmap_update_bits(nau8821->regmap, NAU8821_R76_BOOST,
+                       NAU8821_HP_BOOST_DISCHRG_EN, 0);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 static const struct snd_soc_dapm_widget nau8821_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("System Clock", SND_SOC_NOPM, 0, 0,
                system_clock_control, SND_SOC_DAPM_POST_PMD),
@@ -635,8 +665,10 @@ static const struct snd_soc_dapm_widget nau8821_dapm_widgets[] = {
                NAU8821_POWERUP_ADCL_SFT, 0),
        SND_SOC_DAPM_ADC("ADCR Power", NULL, NAU8821_R72_ANALOG_ADC_2,
                NAU8821_POWERUP_ADCR_SFT, 0),
+       /* single-ended design only on the left */
        SND_SOC_DAPM_PGA_S("Frontend PGA L", 1, NAU8821_R7F_POWER_UP_CONTROL,
-               NAU8821_PUP_PGA_L_SFT, 0, NULL, 0),
+               NAU8821_PUP_PGA_L_SFT, 0, nau8821_left_fepga_event,
+               SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
        SND_SOC_DAPM_PGA_S("Frontend PGA R", 1, NAU8821_R7F_POWER_UP_CONTROL,
                NAU8821_PUP_PGA_R_SFT, 0, NULL, 0),
        SND_SOC_DAPM_PGA_S("ADCL Digital path", 0, NAU8821_R01_ENA_CTRL,
@@ -1677,6 +1709,8 @@ static int nau8821_read_device_properties(struct device *dev,
                "nuvoton,jkdet-pull-up");
        nau8821->key_enable = device_property_read_bool(dev,
                "nuvoton,key-enable");
+       nau8821->left_input_single_end = device_property_read_bool(dev,
+               "nuvoton,left-input-single-end");
        ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity",
                &nau8821->jkdet_polarity);
        if (ret)
@@ -1760,6 +1794,12 @@ static void nau8821_init_regs(struct nau8821 *nau8821)
                NAU8821_ADC_SYNC_DOWN_MASK, NAU8821_ADC_SYNC_DOWN_64);
        regmap_update_bits(regmap, NAU8821_R2C_DAC_CTRL1,
                NAU8821_DAC_OVERSAMPLE_MASK, NAU8821_DAC_OVERSAMPLE_64);
+       if (nau8821->left_input_single_end) {
+               regmap_update_bits(regmap, NAU8821_R6B_PGA_MUTE,
+                       NAU8821_MUTE_MICNL_EN, NAU8821_MUTE_MICNL_EN);
+               regmap_update_bits(regmap, NAU8821_R74_MIC_BIAS,
+                       NAU8821_MICBIAS_LOWNOISE_EN, NAU8821_MICBIAS_LOWNOISE_EN);
+       }
 }
 
 static int nau8821_setup_irq(struct nau8821 *nau8821)
index d962293..00a888e 100644 (file)
 #define NAU8821_DAC_CAPACITOR_MSB              (0x1 << 1)
 #define NAU8821_DAC_CAPACITOR_LSB              0x1
 
+/* MUTE_MIC_L_N (0x6b) */
+#define NAU8821_MUTE_MICNL_SFT         5
+#define NAU8821_MUTE_MICNL_EN           (0x1 << NAU8821_MUTE_MICNL_SFT)
+#define NAU8821_MUTE_MICNR_SFT          4
+#define NAU8821_MUTE_MICNR_EN           (0x1 << NAU8821_MUTE_MICNR_SFT)
+#define NAU8821_MUTE_MICRP_SFT          2
+#define NAU8821_MUTE_MICRP_EN           (0x1 << NAU8821_MUTE_MICRP_SFT)
+
 /* ANALOG_ADC_1 (0x71) */
 #define NAU8821_MICDET_EN_SFT          0
 #define NAU8821_MICDET_MASK            0x1
 
 /* MIC_BIAS (0x74) */
 #define NAU8821_MICBIAS_JKR2           (0x1 << 12)
+#define NAU8821_MICBIAS_LOWNOISE_SFT   10
+#define NAU8821_MICBIAS_LOWNOISE_EN    (0x1 << NAU8821_MICBIAS_LOWNOISE_SFT)
 #define NAU8821_MICBIAS_POWERUP_SFT    8
+#define NAU8821_MICBIAS_POWERUP_EN     (0x1 << NAU8821_MICBIAS_POWERUP_SFT)
 #define NAU8821_MICBIAS_VOLTAGE_SFT    0
 #define NAU8821_MICBIAS_VOLTAGE_MASK   0x7
 
 /* BOOST (0x76) */
 #define NAU8821_PRECHARGE_DIS          (0x1 << 13)
 #define NAU8821_GLOBAL_BIAS_EN         (0x1 << 12)
+#define NAU8821_HP_BOOST_DISCHRG_SFT   11
+#define NAU8821_HP_BOOST_DISCHRG_EN    (0x1 << NAU8821_HP_BOOST_DISCHRG_SFT)
 #define NAU8821_HP_BOOST_DIS_SFT       9
 #define NAU8821_HP_BOOST_DIS           (0x1 << NAU8821_HP_BOOST_DIS_SFT)
 #define NAU8821_HP_BOOST_G_DIS         (0x1 << 8)
 #define NAU8821_SHORT_SHUTDOWN_EN      (0x1 << 6)
 
 /* FEPGA (0x77) */
+#define NAU8821_ACDC_CTRL_SFT          14
+#define NAU8821_ACDC_CTRL_MASK         (0x3 << NAU8821_ACDC_CTRL_SFT)
+#define NAU8821_ACDC_VREF_MICP         (0x1 << NAU8821_ACDC_CTRL_SFT)
+#define NAU8821_ACDC_VREF_MICN         (0x2 << NAU8821_ACDC_CTRL_SFT)
 #define NAU8821_FEPGA_MODEL_SFT                4
 #define NAU8821_FEPGA_MODEL_MASK       (0xf << NAU8821_FEPGA_MODEL_SFT)
+#define NAU8821_FEPGA_MODEL_AAF                (0x1 << NAU8821_FEPGA_MODEL_SFT)
+#define NAU8821_FEPGA_MODEL_DIS                (0x2 << NAU8821_FEPGA_MODEL_SFT)
+#define NAU8821_FEPGA_MODEL_IMP12K     (0x8 << NAU8821_FEPGA_MODEL_SFT)
 #define NAU8821_FEPGA_MODER_SFT                0
 #define NAU8821_FEPGA_MODER_MASK       0xf
+#define NAU8821_FEPGA_MODER_AAF                0x1
+#define NAU8821_FEPGA_MODER_DIS                0x2
+#define NAU8821_FEPGA_MODER_IMP12K     0x8
+
 
 /* PGA_GAIN (0x7e) */
 #define NAU8821_PGA_GAIN_L_SFT         8
@@ -543,6 +567,7 @@ struct nau8821 {
        bool jkdet_enable;
        bool jkdet_pull_enable;
        bool jkdet_pull_up;
+       bool left_input_single_end;
        int jkdet_polarity;
        int jack_insert_debounce;
        int jack_eject_debounce;