ASoC: cs42l51: manage mclk shutdown delay
authorOlivier Moysan <olivier.moysan@st.com>
Tue, 20 Oct 2020 15:01:09 +0000 (17:01 +0200)
committerMark Brown <broonie@kernel.org>
Fri, 23 Oct 2020 17:28:51 +0000 (18:28 +0100)
A delay must be introduced before the shutdown down of the mclk,
as stated in CS42L51 datasheet. Otherwise the codec may
produce some noise after the end of DAPM power down sequence.
The delay between DAC and CLOCK_SUPPLY widgets is too short.
Add a delay in mclk shutdown request to manage the shutdown delay
explicitly. From experiments, at least 10ms delay is necessary.
Set delay to 20ms as recommended in Documentation/timers/timers-howto.rst
when using msleep().

Signed-off-by: Olivier Moysan <olivier.moysan@st.com>
Link: https://lore.kernel.org/r/20201020150109.482-1-olivier.moysan@st.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/cs42l51.c

index 097c4e8d9950535de336647a42fc37acc0016124..c61b17dc2af876e2d4055f3a3f483317185271d9 100644 (file)
@@ -254,8 +254,28 @@ static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = {
                &cs42l51_adcr_mux_controls),
 };
 
+static int mclk_event(struct snd_soc_dapm_widget *w,
+                     struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
+       struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(comp);
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               return clk_prepare_enable(cs42l51->mclk_handle);
+       case SND_SOC_DAPM_POST_PMD:
+               /* Delay mclk shutdown to fulfill power-down sequence requirements */
+               msleep(20);
+               clk_disable_unprepare(cs42l51->mclk_handle);
+               break;
+       }
+
+       return 0;
+}
+
 static const struct snd_soc_dapm_widget cs42l51_dapm_mclk_widgets[] = {
-       SND_SOC_DAPM_CLOCK_SUPPLY("MCLK")
+       SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, mclk_event,
+                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_route cs42l51_routes[] = {