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: