ASoC: cs42l42: Wait for PLL to lock before switching to it
authorRichard Fitzgerald <rf@opensource.cirrus.com>
Sat, 6 Mar 2021 18:55:53 +0000 (18:55 +0000)
committerMark Brown <broonie@kernel.org>
Wed, 10 Mar 2021 13:14:31 +0000 (13:14 +0000)
The PLL should have locked before using it to supply MCLK.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210306185553.62053-16-tanureal@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/cs42l42.c
sound/soc/codecs/cs42l42.h

index d7a314aa59b73c68b40d0a367bf85c81a324e57b..bf982e145e945f4774d5c306522426f381433c14 100644 (file)
@@ -862,6 +862,7 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
        struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
        unsigned int regval;
        u8 fullScaleVol;
+       int ret;
 
        if (mute) {
                /* Mute the headphone */
@@ -887,9 +888,18 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
        } else {
                if (!cs42l42->stream_use) {
                        /* SCLK must be running before codec unmute */
-                       if ((cs42l42->bclk < 11289600) && (cs42l42->sclk < 11289600))
+                       if ((cs42l42->bclk < 11289600) && (cs42l42->sclk < 11289600)) {
                                snd_soc_component_update_bits(component, CS42L42_PLL_CTL1,
                                                              CS42L42_PLL_START_MASK, 1);
+                               ret = regmap_read_poll_timeout(cs42l42->regmap,
+                                                              CS42L42_PLL_LOCK_STATUS,
+                                                              regval,
+                                                              (regval & 1),
+                                                              CS42L42_PLL_LOCK_POLL_US,
+                                                              CS42L42_PLL_LOCK_TIMEOUT_US);
+                               if (ret < 0)
+                                       dev_warn(component->dev, "PLL failed to lock: %d\n", ret);
+                       }
 
                        /* Mark SCLK as present, turn off internal oscillator */
                        regmap_multi_reg_write(cs42l42->regmap, cs42l42_to_sclk_seq,
index 214cee762709d63cbfdc0d4f5f8932819f7d7f8c..36b763f0d1a064c35e7eccae9701c485b840ab73 100644 (file)
 #define CS42L42_NUM_SUPPLIES   5
 #define CS42L42_BOOT_TIME_US   3000
 #define CS42L42_CLOCK_SWITCH_DELAY_US 150
+#define CS42L42_PLL_LOCK_POLL_US       250
+#define CS42L42_PLL_LOCK_TIMEOUT_US    1250
 
 static const char *const cs42l42_supply_names[CS42L42_NUM_SUPPLIES] = {
        "VA",