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

Richard Fitzgerald rf at opensource.cirrus.com
Tue May 25 11:12:39 CEST 2021


Reviewed-by: Richard Fitzgerald <rf at 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 at 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;
> 


More information about the Alsa-devel mailing list