Re: [PATCH v2 2/4] ASoC: es8316: Enable support for MCLK div by 2

From: Marian Postevca
Date: Sun Aug 27 2023 - 17:54:00 EST


Mark Brown <broonie@xxxxxxxxxx> writes:


> Given that the datasheet quotes a maximum MCLK of 51.2MHz I suspect that
> this is far too high and that performance is degrading well before this
> point, it sounds like it just so happens that you noticed issues on a
> machine with this MCLK rather than that's based on the spec. I would
> instead suggest applying the MCLK divider in any case where we can do so
> and still generate suitable clocking for the rest of the system, or at
> least hit 256fs (the datasheet quotes 256/384fs on the front page which
> suggests it's targetting 256fs, that'd be a fairly normal number, and
> there's mention of 12/24MHz USB clocks being directly usable). Doing
> this should either make no odds or result in better performance.

Not 100% sure what checks should be done for a MCLK to determine if it
generates suitable clocking. Would something along this patch make
sense?

diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index a8f347f1affb..667648de8105 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -470,19 +470,36 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
u8 bclk_divider;
u16 lrck_divider;
int i;
+ unsigned int clk = es8316->sysclk / 2;
+ bool clk_valid = false;
+
+ do {
+ /* Validate supported sample rates that are autodetected from MCLK */
+ for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) {
+ const unsigned int ratio = supported_mclk_lrck_ratios[i];
+
+ if (clk % ratio != 0)
+ continue;
+ if (clk / ratio == params_rate(params))
+ break;
+ }
+ if (i == NR_SUPPORTED_MCLK_LRCK_RATIOS) {
+ if (clk == es8316->sysclk)
+ return -EINVAL;
+ else
+ clk = es8316->sysclk;
+ } else {
+ clk_valid = true;
+ }
+ } while(!clk_valid);

- /* Validate supported sample rates that are autodetected from MCLK */
- for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) {
- const unsigned int ratio = supported_mclk_lrck_ratios[i];
-
- if (es8316->sysclk % ratio != 0)
- continue;
- if (es8316->sysclk / ratio == params_rate(params))
- break;
+ if (clk != es8316->sysclk) {
+ snd_soc_component_update_bits(component, ES8316_CLKMGR_CLKSW,
+ ES8316_CLKMGR_CLKSW_MCLK_DIV,
+ ES8316_CLKMGR_CLKSW_MCLK_DIV);
}
- if (i == NR_SUPPORTED_MCLK_LRCK_RATIOS)
- return -EINVAL;
- lrck_divider = es8316->sysclk / params_rate(params);
+
+ lrck_divider = clk / params_rate(params);
bclk_divider = lrck_divider / 4;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE: