ASoC: jz4740-i2s: Make I2S divider calculations more robust
authorAidan MacDonald <aidanmacdonald.0x0@gmail.com>
Tue, 9 May 2023 12:51:34 +0000 (13:51 +0100)
committerMark Brown <broonie@kernel.org>
Thu, 11 May 2023 01:17:58 +0000 (10:17 +0900)
commitad721bc919edfd8b4b06977458a412011e2f0c50
treee31a408fe1e969352e58bedd0837af04a0628dd6
parent051d71e073614a72ad423d6dacba37a7eeff274d
ASoC: jz4740-i2s: Make I2S divider calculations more robust

When the CPU supplies bit/frame clocks, the system clock (clk_i2s)
is divided to produce the bit clock. This is a simple 1/N divider
with a fairly limited range, so for a given system clock frequency
only a few sample rates can be produced. Usually a wider range of
sample rates is supported by varying the system clock frequency.

The old calculation method was not very robust and could easily
produce the wrong clock rate, especially with non-standard rates.
For example, if the system clock is 1.99x the target bit clock
rate, the divider would be calculated as 1 instead of the more
accurate 2.

Instead, use a more accurate method that considers two adjacent
divider settings and selects the one that produces the least error
versus the requested rate. If the error is 5% or higher then the
rate setting is rejected to prevent garbled audio.

Skip divider calculation when the codec is supplying both the bit
and frame clock; in that case, the divider outputs are unused and
we don't want to constrain the sample rate.

Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com
Link: https://lore.kernel.org/r/20230509125134.208129-1-aidanmacdonald.0x0@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org
sound/soc/jz4740/jz4740-i2s.c