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 |
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; >
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 --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;
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(-)