diff mbox series

[1/4] ASoC: cs42l42: Fix 1536000 Bit Clock instability

Message ID 20210525090822.64577-1-tanureal@opensource.cirrus.com (mailing list archive)
State New, archived
Headers show
Series [1/4] ASoC: cs42l42: Fix 1536000 Bit Clock instability | expand

Commit Message

Lucas Tanure May 25, 2021, 9:08 a.m. UTC
The 16 Bits, 2 channels, 48K sample rate use case needs
to configure a safer pll_divout during the start of PLL
After 800us from the start of PLL the correct pll_divout
can be set

Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com>
---
 sound/soc/codecs/cs42l42.c | 47 +++++++++++++++++++++++++-------------
 sound/soc/codecs/cs42l42.h |  2 ++
 2 files changed, 33 insertions(+), 16 deletions(-)

Comments

Richard Fitzgerald May 25, 2021, 9:12 a.m. UTC | #1
Reviewed-by: Richard Fitzgerald <rf@opensource.cirrus.com>

On 25/05/2021 10:08, Lucas Tanure wrote:
> The 16 Bits, 2 channels, 48K sample rate use case needs
> to configure a safer pll_divout during the start of PLL
> After 800us from the start of PLL the correct pll_divout
> can be set
> 
> Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com>
> ---
>   sound/soc/codecs/cs42l42.c | 47 +++++++++++++++++++++++++-------------
>   sound/soc/codecs/cs42l42.h |  2 ++
>   2 files changed, 33 insertions(+), 16 deletions(-)
> 
> diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
> index b084acd1e86b..94788a55fa3b 100644
> --- a/sound/soc/codecs/cs42l42.c
> +++ b/sound/soc/codecs/cs42l42.c
> @@ -589,6 +589,7 @@ struct cs42l42_pll_params {
>   	u8 pll_divout;
>   	u32 mclk_int;
>   	u8 pll_cal_ratio;
> +	u8 n;
>   };
> 
>   /*
> @@ -596,21 +597,21 @@ struct cs42l42_pll_params {
>    * Table 4-5 from the Datasheet
>    */
>   static const struct cs42l42_pll_params pll_ratio_table[] = {
> -	{ 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125 },
> -	{ 2822400, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128 },
> -	{ 3000000, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128 },
> -	{ 3072000, 0, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125 },
> -	{ 4000000, 0, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96 },
> -	{ 4096000, 0, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94 },
> -	{ 5644800, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128 },
> -	{ 6000000, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128 },
> -	{ 6144000, 0, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125 },
> -	{ 11289600, 0, 0, 0, 0, 0, 0, 0, 11289600, 0 },
> -	{ 12000000, 0, 0, 0, 0, 0, 0, 0, 12000000, 0 },
> -	{ 12288000, 0, 0, 0, 0, 0, 0, 0, 12288000, 0 },
> -	{ 22579200, 1, 0, 0, 0, 0, 0, 0, 22579200, 0 },
> -	{ 24000000, 1, 0, 0, 0, 0, 0, 0, 24000000, 0 },
> -	{ 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0 }
> +	{ 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2},
> +	{ 2822400, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
> +	{ 3000000, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
> +	{ 3072000, 0, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
> +	{ 4000000, 0, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000,  96, 1},
> +	{ 4096000, 0, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000,  94, 1},
> +	{ 5644800, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
> +	{ 6000000, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
> +	{ 6144000, 0, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
> +	{ 11289600, 0, 0, 0, 0, 0, 0, 0, 11289600, 0, 1},
> +	{ 12000000, 0, 0, 0, 0, 0, 0, 0, 12000000, 0, 1},
> +	{ 12288000, 0, 0, 0, 0, 0, 0, 0, 12288000, 0, 1},
> +	{ 22579200, 1, 0, 0, 0, 0, 0, 0, 22579200, 0, 1},
> +	{ 24000000, 1, 0, 0, 0, 0, 0, 0, 24000000, 0, 1},
> +	{ 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0, 1}
>   };
>   
>   static int cs42l42_pll_config(struct snd_soc_component *component)
> @@ -746,8 +747,12 @@ static int cs42l42_pll_config(struct snd_soc_component *component)
>   				snd_soc_component_update_bits(component,
>   					CS42L42_PLL_CTL3,
>   					CS42L42_PLL_DIVOUT_MASK,
> -					pll_ratio_table[i].pll_divout
> +					(pll_ratio_table[i].pll_divout * pll_ratio_table[i].n)
>   					<< CS42L42_PLL_DIVOUT_SHIFT);
> +				if (pll_ratio_table[i].n != 1)
> +					cs42l42->pll_divout = pll_ratio_table[i].pll_divout;
> +				else
> +					cs42l42->pll_divout = 0;
>   				snd_soc_component_update_bits(component,
>   					CS42L42_PLL_CAL_RATIO,
>   					CS42L42_PLL_CAL_RATIO_MASK,
> @@ -902,6 +907,16 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
>   			if ((cs42l42->bclk < 11289600) && (cs42l42->sclk < 11289600)) {
>   				snd_soc_component_update_bits(component, CS42L42_PLL_CTL1,
>   							      CS42L42_PLL_START_MASK, 1);
> +
> +				if (cs42l42->pll_divout) {
> +					usleep_range(CS42L42_PLL_DIVOUT_TIME_US,
> +						     CS42L42_PLL_DIVOUT_TIME_US * 2);
> +					snd_soc_component_update_bits(component, CS42L42_PLL_CTL3,
> +								      CS42L42_PLL_DIVOUT_MASK,
> +								      cs42l42->pll_divout <<
> +								      CS42L42_PLL_DIVOUT_SHIFT);
> +				}
> +
>   				ret = regmap_read_poll_timeout(cs42l42->regmap,
>   							       CS42L42_PLL_LOCK_STATUS,
>   							       regval,
> diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h
> index 24f7be228d5f..7bf05ff05f74 100644
> --- a/sound/soc/codecs/cs42l42.h
> +++ b/sound/soc/codecs/cs42l42.h
> @@ -755,6 +755,7 @@
>   
>   #define CS42L42_NUM_SUPPLIES	5
>   #define CS42L42_BOOT_TIME_US	3000
> +#define CS42L42_PLL_DIVOUT_TIME_US	800
>   #define CS42L42_CLOCK_SWITCH_DELAY_US 150
>   #define CS42L42_PLL_LOCK_POLL_US	250
>   #define CS42L42_PLL_LOCK_TIMEOUT_US	1250
> @@ -777,6 +778,7 @@ struct  cs42l42_private {
>   	int bclk;
>   	u32 sclk;
>   	u32 srate;
> +	u8 pll_divout;
>   	u8 plug_state;
>   	u8 hs_type;
>   	u8 ts_inv;
>
Mark Brown May 25, 2021, 2:09 p.m. UTC | #2
On Tue, May 25, 2021 at 10:12:39AM +0100, Richard Fitzgerald wrote:
> Reviewed-by: Richard Fitzgerald <rf@opensource.cirrus.com>
> 
> On 25/05/2021 10:08, Lucas Tanure wrote:
> > The 16 Bits, 2 channels, 48K sample rate use case needs
> > to configure a safer pll_divout during the start of PLL

Please delete unneeded context from mails when replying.  Doing this
makes it much easier to find your reply in the message, helping ensure
it won't be missed by people scrolling through the irrelevant quoted
material.
diff mbox series

Patch

diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
index b084acd1e86b..94788a55fa3b 100644
--- a/sound/soc/codecs/cs42l42.c
+++ b/sound/soc/codecs/cs42l42.c
@@ -589,6 +589,7 @@  struct cs42l42_pll_params {
 	u8 pll_divout;
 	u32 mclk_int;
 	u8 pll_cal_ratio;
+	u8 n;
 };

 /*
@@ -596,21 +597,21 @@  struct cs42l42_pll_params {
  * Table 4-5 from the Datasheet
  */
 static const struct cs42l42_pll_params pll_ratio_table[] = {
-	{ 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125 },
-	{ 2822400, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128 },
-	{ 3000000, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128 },
-	{ 3072000, 0, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125 },
-	{ 4000000, 0, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96 },
-	{ 4096000, 0, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94 },
-	{ 5644800, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128 },
-	{ 6000000, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128 },
-	{ 6144000, 0, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125 },
-	{ 11289600, 0, 0, 0, 0, 0, 0, 0, 11289600, 0 },
-	{ 12000000, 0, 0, 0, 0, 0, 0, 0, 12000000, 0 },
-	{ 12288000, 0, 0, 0, 0, 0, 0, 0, 12288000, 0 },
-	{ 22579200, 1, 0, 0, 0, 0, 0, 0, 22579200, 0 },
-	{ 24000000, 1, 0, 0, 0, 0, 0, 0, 24000000, 0 },
-	{ 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0 }
+	{ 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2},
+	{ 2822400, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
+	{ 3000000, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
+	{ 3072000, 0, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
+	{ 4000000, 0, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000,  96, 1},
+	{ 4096000, 0, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000,  94, 1},
+	{ 5644800, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
+	{ 6000000, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
+	{ 6144000, 0, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
+	{ 11289600, 0, 0, 0, 0, 0, 0, 0, 11289600, 0, 1},
+	{ 12000000, 0, 0, 0, 0, 0, 0, 0, 12000000, 0, 1},
+	{ 12288000, 0, 0, 0, 0, 0, 0, 0, 12288000, 0, 1},
+	{ 22579200, 1, 0, 0, 0, 0, 0, 0, 22579200, 0, 1},
+	{ 24000000, 1, 0, 0, 0, 0, 0, 0, 24000000, 0, 1},
+	{ 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0, 1}
 };
 
 static int cs42l42_pll_config(struct snd_soc_component *component)
@@ -746,8 +747,12 @@  static int cs42l42_pll_config(struct snd_soc_component *component)
 				snd_soc_component_update_bits(component,
 					CS42L42_PLL_CTL3,
 					CS42L42_PLL_DIVOUT_MASK,
-					pll_ratio_table[i].pll_divout
+					(pll_ratio_table[i].pll_divout * pll_ratio_table[i].n)
 					<< CS42L42_PLL_DIVOUT_SHIFT);
+				if (pll_ratio_table[i].n != 1)
+					cs42l42->pll_divout = pll_ratio_table[i].pll_divout;
+				else
+					cs42l42->pll_divout = 0;
 				snd_soc_component_update_bits(component,
 					CS42L42_PLL_CAL_RATIO,
 					CS42L42_PLL_CAL_RATIO_MASK,
@@ -902,6 +907,16 @@  static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
 			if ((cs42l42->bclk < 11289600) && (cs42l42->sclk < 11289600)) {
 				snd_soc_component_update_bits(component, CS42L42_PLL_CTL1,
 							      CS42L42_PLL_START_MASK, 1);
+
+				if (cs42l42->pll_divout) {
+					usleep_range(CS42L42_PLL_DIVOUT_TIME_US,
+						     CS42L42_PLL_DIVOUT_TIME_US * 2);
+					snd_soc_component_update_bits(component, CS42L42_PLL_CTL3,
+								      CS42L42_PLL_DIVOUT_MASK,
+								      cs42l42->pll_divout <<
+								      CS42L42_PLL_DIVOUT_SHIFT);
+				}
+
 				ret = regmap_read_poll_timeout(cs42l42->regmap,
 							       CS42L42_PLL_LOCK_STATUS,
 							       regval,
diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h
index 24f7be228d5f..7bf05ff05f74 100644
--- a/sound/soc/codecs/cs42l42.h
+++ b/sound/soc/codecs/cs42l42.h
@@ -755,6 +755,7 @@ 
 
 #define CS42L42_NUM_SUPPLIES	5
 #define CS42L42_BOOT_TIME_US	3000
+#define CS42L42_PLL_DIVOUT_TIME_US	800
 #define CS42L42_CLOCK_SWITCH_DELAY_US 150
 #define CS42L42_PLL_LOCK_POLL_US	250
 #define CS42L42_PLL_LOCK_TIMEOUT_US	1250
@@ -777,6 +778,7 @@  struct  cs42l42_private {
 	int bclk;
 	u32 sclk;
 	u32 srate;
+	u8 pll_divout;
 	u8 plug_state;
 	u8 hs_type;
 	u8 ts_inv;