From 0bb1306f22fb8da72f3d1ba63854489cc8cfe0dd Mon Sep 17 00:00:00 2001 From: Nikita Yushchenko Date: Thu, 28 Nov 2019 16:54:47 +0300 Subject: ASoC: tlv320aic31xx: Add HP output driver pop reduction controls HP output driver has two parameters that can be configured to reduce pop noise: power-on delay and ramp-up step time. Two new kcontrols have been added to set these parameters. Also have to alter timeout in aic31xx_dapm_power_event() because default timeout does fire when higher supported power-on delay are configured. Signed-off-by: Nikita Yushchenko Link: https://lore.kernel.org/r/20191128135447.26458-1-nikita.yoush@cogentembedded.com Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic31xx.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'sound/soc/codecs/tlv320aic31xx.c') diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index f6f19fdc72f5..d6c462f21370 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -262,6 +262,19 @@ static SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, static SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, mic_select_text); +static const char * const hp_poweron_time_text[] = { + "0us", "15.3us", "153us", "1.53ms", "15.3ms", "76.2ms", + "153ms", "304ms", "610ms", "1.22s", "3.04s", "6.1s" }; + +static SOC_ENUM_SINGLE_DECL(hp_poweron_time_enum, AIC31XX_HPPOP, 3, + hp_poweron_time_text); + +static const char * const hp_rampup_step_text[] = { + "0ms", "0.98ms", "1.95ms", "3.9ms" }; + +static SOC_ENUM_SINGLE_DECL(hp_rampup_step_enum, AIC31XX_HPPOP, 1, + hp_rampup_step_text); + static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0); static const DECLARE_TLV_DB_SCALE(adc_fgain_tlv, 0, 10, 0); static const DECLARE_TLV_DB_SCALE(adc_cgain_tlv, -2000, 50, 0); @@ -285,6 +298,14 @@ static const struct snd_kcontrol_new common31xx_snd_controls[] = { SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL, AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv), + + /* HP de-pop control: apply power not immediately but via ramp + * function with these psarameters. Note that power up sequence + * has to wait for this to complete; this is implemented by + * polling HP driver status in aic31xx_dapm_power_event() + */ + SOC_ENUM("HP Output Driver Power-On time", hp_poweron_time_enum), + SOC_ENUM("HP Output Driver Ramp-up step", hp_rampup_step_enum), }; static const struct snd_kcontrol_new aic31xx_snd_controls[] = { @@ -357,6 +378,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component); unsigned int reg = AIC31XX_DACFLAG1; unsigned int mask; + unsigned int timeout = 500 * USEC_PER_MSEC; switch (WIDGET_BIT(w->reg, w->shift)) { case WIDGET_BIT(AIC31XX_DACSETUP, 7): @@ -367,9 +389,13 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, break; case WIDGET_BIT(AIC31XX_HPDRIVER, 7): mask = AIC31XX_HPLDRVPWRSTATUS_MASK; + if (event == SND_SOC_DAPM_POST_PMU) + timeout = 7 * USEC_PER_SEC; break; case WIDGET_BIT(AIC31XX_HPDRIVER, 6): mask = AIC31XX_HPRDRVPWRSTATUS_MASK; + if (event == SND_SOC_DAPM_POST_PMU) + timeout = 7 * USEC_PER_SEC; break; case WIDGET_BIT(AIC31XX_SPKAMP, 7): mask = AIC31XX_SPLDRVPWRSTATUS_MASK; @@ -389,9 +415,11 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: - return aic31xx_wait_bits(aic31xx, reg, mask, mask, 5000, 100); + return aic31xx_wait_bits(aic31xx, reg, mask, mask, + 5000, timeout / 5000); case SND_SOC_DAPM_POST_PMD: - return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100); + return aic31xx_wait_bits(aic31xx, reg, mask, 0, + 5000, timeout / 5000); default: dev_dbg(component->dev, "Unhandled dapm widget event %d from %s\n", -- cgit v1.2.3