• Aidan MacDonald's avatar
    ASoC: jz4740-i2s: Make I2S divider calculations more robust · ad721bc9
    Aidan MacDonald authored
    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
    ad721bc9
jz4740-i2s.c 16 KB