ASoC: tlv320adcx140: Add DRE and AGC support

The TLV320ADCx140 parts support Dynamic Range Enhancer (DRE) as defined
in Section 8.3.2 of the data sheets.

The DRE achieves a complete-channel dynamic range as high as 120 dB.
At a system level, the DRE scheme enables far-field, high-fidelity recording
of audio signals in very quiet environments and low-distortion recording in
loud environments.

There are 2 enables for DRE.  The first is a global setting that enables
the DRE engine in the device and the other enable is per channel.  If
the DRE is enabled globally then either DRE or AGC can be used per each
configured channel.  If global DRE is disabled then even setting the DRE
enable bit in the channel config register will have no effect.

Signed-off-by: Dan Murphy <dmurphy@ti.com>
Link: https://lore.kernel.org/r/20200221181358.22526-1-dmurphy@ti.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Dan Murphy 2020-02-21 12:13:57 -06:00 committed by Mark Brown
parent b38c4a8a02
commit 8a329dbd4a
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
2 changed files with 56 additions and 0 deletions

View File

@ -108,6 +108,7 @@ static const struct reg_default adcx140_reg_defaults[] = {
{ ADCX140_DSP_CFG0, 0x01 }, { ADCX140_DSP_CFG0, 0x01 },
{ ADCX140_DSP_CFG1, 0x40 }, { ADCX140_DSP_CFG1, 0x40 },
{ ADCX140_DRE_CFG0, 0x7b }, { ADCX140_DRE_CFG0, 0x7b },
{ ADCX140_AGC_CFG0, 0xe7 },
{ ADCX140_IN_CH_EN, 0xf0 }, { ADCX140_IN_CH_EN, 0xf0 },
{ ADCX140_ASI_OUT_CH_EN, 0x00 }, { ADCX140_ASI_OUT_CH_EN, 0x00 },
{ ADCX140_PWR_CFG, 0x00 }, { ADCX140_PWR_CFG, 0x00 },
@ -158,6 +159,16 @@ static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10000, 50, 0);
/* ADC gain. From 0 to 42 dB in 1 dB steps */ /* ADC gain. From 0 to 42 dB in 1 dB steps */
static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0); static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
/* DRE Level. From -12 dB to -66 dB in 1 dB steps */
static DECLARE_TLV_DB_SCALE(dre_thresh_tlv, -6600, 100, 0);
/* DRE Max Gain. From 2 dB to 26 dB in 2 dB steps */
static DECLARE_TLV_DB_SCALE(dre_gain_tlv, 200, 200, 0);
/* AGC Level. From -6 dB to -36 dB in 2 dB steps */
static DECLARE_TLV_DB_SCALE(agc_thresh_tlv, -3600, 200, 0);
/* AGC Max Gain. From 3 dB to 42 dB in 3 dB steps */
static DECLARE_TLV_DB_SCALE(agc_gain_tlv, 300, 300, 0);
static const char * const resistor_text[] = { static const char * const resistor_text[] = {
"2.5 kOhm", "10 kOhm", "20 kOhm" "2.5 kOhm", "10 kOhm", "20 kOhm"
}; };
@ -281,6 +292,18 @@ static const struct snd_kcontrol_new adcx140_dapm_ch3_en_switch =
static const struct snd_kcontrol_new adcx140_dapm_ch4_en_switch = static const struct snd_kcontrol_new adcx140_dapm_ch4_en_switch =
SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 4, 1, 0); SOC_DAPM_SINGLE("Switch", ADCX140_ASI_OUT_CH_EN, 4, 1, 0);
static const struct snd_kcontrol_new adcx140_dapm_ch1_dre_en_switch =
SOC_DAPM_SINGLE("Switch", ADCX140_CH1_CFG0, 0, 1, 0);
static const struct snd_kcontrol_new adcx140_dapm_ch2_dre_en_switch =
SOC_DAPM_SINGLE("Switch", ADCX140_CH2_CFG0, 0, 1, 0);
static const struct snd_kcontrol_new adcx140_dapm_ch3_dre_en_switch =
SOC_DAPM_SINGLE("Switch", ADCX140_CH3_CFG0, 0, 1, 0);
static const struct snd_kcontrol_new adcx140_dapm_ch4_dre_en_switch =
SOC_DAPM_SINGLE("Switch", ADCX140_CH4_CFG0, 0, 1, 0);
static const struct snd_kcontrol_new adcx140_dapm_dre_en_switch =
SOC_DAPM_SINGLE("Switch", ADCX140_DSP_CFG1, 3, 1, 0);
/* Output Mixer */ /* Output Mixer */
static const struct snd_kcontrol_new adcx140_output_mixer_controls[] = { static const struct snd_kcontrol_new adcx140_output_mixer_controls[] = {
SOC_DAPM_SINGLE("Digital CH1 Switch", 0, 0, 0, 0), SOC_DAPM_SINGLE("Digital CH1 Switch", 0, 0, 0, 0),
@ -361,6 +384,18 @@ static const struct snd_soc_dapm_widget adcx140_dapm_widgets[] = {
SND_SOC_DAPM_SWITCH("CH4_ASI_EN", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_SWITCH("CH4_ASI_EN", SND_SOC_NOPM, 0, 0,
&adcx140_dapm_ch4_en_switch), &adcx140_dapm_ch4_en_switch),
SND_SOC_DAPM_SWITCH("DRE_ENABLE", SND_SOC_NOPM, 0, 0,
&adcx140_dapm_dre_en_switch),
SND_SOC_DAPM_SWITCH("CH1_DRE_EN", SND_SOC_NOPM, 0, 0,
&adcx140_dapm_ch1_dre_en_switch),
SND_SOC_DAPM_SWITCH("CH2_DRE_EN", SND_SOC_NOPM, 0, 0,
&adcx140_dapm_ch2_dre_en_switch),
SND_SOC_DAPM_SWITCH("CH3_DRE_EN", SND_SOC_NOPM, 0, 0,
&adcx140_dapm_ch3_dre_en_switch),
SND_SOC_DAPM_SWITCH("CH4_DRE_EN", SND_SOC_NOPM, 0, 0,
&adcx140_dapm_ch4_dre_en_switch),
SND_SOC_DAPM_MUX("IN1 Analog Mic Resistor", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("IN1 Analog Mic Resistor", SND_SOC_NOPM, 0, 0,
in1_resistor_controls), in1_resistor_controls),
SND_SOC_DAPM_MUX("IN2 Analog Mic Resistor", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("IN2 Analog Mic Resistor", SND_SOC_NOPM, 0, 0,
@ -383,6 +418,16 @@ static const struct snd_soc_dapm_route adcx140_audio_map[] = {
{"CH3_ASI_EN", "Switch", "CH3_ADC"}, {"CH3_ASI_EN", "Switch", "CH3_ADC"},
{"CH4_ASI_EN", "Switch", "CH4_ADC"}, {"CH4_ASI_EN", "Switch", "CH4_ADC"},
{"DRE_ENABLE", "Switch", "CH1_DRE_EN"},
{"DRE_ENABLE", "Switch", "CH2_DRE_EN"},
{"DRE_ENABLE", "Switch", "CH3_DRE_EN"},
{"DRE_ENABLE", "Switch", "CH4_DRE_EN"},
{"CH1_DRE_EN", "Switch", "CH1_ADC"},
{"CH2_DRE_EN", "Switch", "CH2_ADC"},
{"CH3_DRE_EN", "Switch", "CH3_ADC"},
{"CH4_DRE_EN", "Switch", "CH4_ADC"},
/* Mic input */ /* Mic input */
{"CH1_ADC", NULL, "MIC_GAIN_CTL_CH1"}, {"CH1_ADC", NULL, "MIC_GAIN_CTL_CH1"},
{"CH2_ADC", NULL, "MIC_GAIN_CTL_CH2"}, {"CH2_ADC", NULL, "MIC_GAIN_CTL_CH2"},
@ -455,6 +500,16 @@ static const struct snd_kcontrol_new adcx140_snd_controls[] = {
SOC_SINGLE_TLV("Analog CH4 Mic Gain Volume", ADCX140_CH1_CFG4, 2, 42, 0, SOC_SINGLE_TLV("Analog CH4 Mic Gain Volume", ADCX140_CH1_CFG4, 2, 42, 0,
adc_tlv), adc_tlv),
SOC_SINGLE_TLV("DRE Threshold", ADCX140_DRE_CFG0, 4, 9, 0,
dre_thresh_tlv),
SOC_SINGLE_TLV("DRE Max Gain", ADCX140_DRE_CFG0, 0, 12, 0,
dre_gain_tlv),
SOC_SINGLE_TLV("AGC Threshold", ADCX140_AGC_CFG0, 4, 15, 0,
agc_thresh_tlv),
SOC_SINGLE_TLV("AGC Max Gain", ADCX140_AGC_CFG0, 0, 13, 0,
agc_gain_tlv),
SOC_SINGLE_TLV("Digital CH1 Out Volume", ADCX140_CH1_CFG2, SOC_SINGLE_TLV("Digital CH1 Out Volume", ADCX140_CH1_CFG2,
0, 0xff, 0, dig_vol_tlv), 0, 0xff, 0, dig_vol_tlv),
SOC_SINGLE_TLV("Digital CH2 Out Volume", ADCX140_CH2_CFG2, SOC_SINGLE_TLV("Digital CH2 Out Volume", ADCX140_CH2_CFG2,

View File

@ -84,6 +84,7 @@
#define ADCX140_DSP_CFG0 0x6b #define ADCX140_DSP_CFG0 0x6b
#define ADCX140_DSP_CFG1 0x6c #define ADCX140_DSP_CFG1 0x6c
#define ADCX140_DRE_CFG0 0x6d #define ADCX140_DRE_CFG0 0x6d
#define ADCX140_AGC_CFG0 0x70
#define ADCX140_IN_CH_EN 0x73 #define ADCX140_IN_CH_EN 0x73
#define ADCX140_ASI_OUT_CH_EN 0x74 #define ADCX140_ASI_OUT_CH_EN 0x74
#define ADCX140_PWR_CFG 0x75 #define ADCX140_PWR_CFG 0x75