From: Richard Fitzgerald Date: Fri, 15 Oct 2021 13:36:15 +0000 (+0100) Subject: ASoC: cs42l42: Allow time for HP/ADC to power-up after enable X-Git-Tag: v6.1-rc5~2159^2~83^2~1^2~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4ae1d8f911d6fc20baefd5eb061bf6964fa22a32;p=platform%2Fkernel%2Flinux-starfive.git ASoC: cs42l42: Allow time for HP/ADC to power-up after enable After enabling the HP or ADC by writing the corresponding PDN=0, it takes around 20 milliseconds for it to power up and the midrail supply to be stable. Add this wait into a DAPM widget callback. If HP and ADC are both powering up in a DAPM sequence, there's no need to do the wait twice. The widget will perform one wait in the POST_PMU if there was a PRE_PMU for one or both. Signed-off-by: Richard Fitzgerald Link: https://lore.kernel.org/r/20211015133619.4698-13-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 4ec7fdc..d6d74a7 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -435,10 +435,36 @@ static const struct snd_kcontrol_new cs42l42_snd_controls[] = { 0x3f, 1, mixer_tlv) }; +static int cs42l42_hp_adc_ev(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 cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + cs42l42->hp_adc_up_pending = true; + break; + case SND_SOC_DAPM_POST_PMU: + /* Only need one delay if HP and ADC are both powering-up */ + if (cs42l42->hp_adc_up_pending) { + usleep_range(CS42L42_HP_ADC_EN_TIME_US, + CS42L42_HP_ADC_EN_TIME_US + 1000); + cs42l42->hp_adc_up_pending = false; + } + break; + default: + break; + } + + return 0; +} + static const struct snd_soc_dapm_widget cs42l42_dapm_widgets[] = { /* Playback Path */ SND_SOC_DAPM_OUTPUT("HP"), - SND_SOC_DAPM_DAC("DAC", NULL, CS42L42_PWR_CTL1, CS42L42_HP_PDN_SHIFT, 1), + SND_SOC_DAPM_DAC_E("DAC", NULL, CS42L42_PWR_CTL1, CS42L42_HP_PDN_SHIFT, 1, + cs42l42_hp_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_MIXER("MIXER", CS42L42_PWR_CTL1, CS42L42_MIXER_PDN_SHIFT, 1, NULL, 0), SND_SOC_DAPM_AIF_IN("SDIN1", NULL, 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("SDIN2", NULL, 1, SND_SOC_NOPM, 0, 0), @@ -448,7 +474,8 @@ static const struct snd_soc_dapm_widget cs42l42_dapm_widgets[] = { /* Capture Path */ SND_SOC_DAPM_INPUT("HS"), - SND_SOC_DAPM_ADC("ADC", NULL, CS42L42_PWR_CTL1, CS42L42_ADC_PDN_SHIFT, 1), + SND_SOC_DAPM_ADC_E("ADC", NULL, CS42L42_PWR_CTL1, CS42L42_ADC_PDN_SHIFT, 1, + cs42l42_hp_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_AIF_OUT("SDOUT1", NULL, 0, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH1_SHIFT, 0), SND_SOC_DAPM_AIF_OUT("SDOUT2", NULL, 1, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH2_SHIFT, 0), diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index 8734f68..ded61af 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -761,6 +761,7 @@ #define CS42L42_CLOCK_SWITCH_DELAY_US 150 #define CS42L42_PLL_LOCK_POLL_US 250 #define CS42L42_PLL_LOCK_TIMEOUT_US 1250 +#define CS42L42_HP_ADC_EN_TIME_US 20000 static const char *const cs42l42_supply_names[CS42L42_NUM_SUPPLIES] = { "VA", @@ -794,6 +795,7 @@ struct cs42l42_private { u8 hs_bias_ramp_time; u8 hs_bias_sense_en; u8 stream_use; + bool hp_adc_up_pending; }; #endif /* __CS42L42_H__ */