• Matthias Reichl's avatar
    ASoC: bcm2835: Add support for TDM modes · 9448572d
    Matthias Reichl authored
    bcm2835 supports arbitrary positioning of channel data within
    a frame and thus is capable of supporting TDM modes. Since
    the driver is limited to 2-channel operations only TDM setups
    with exactly 2 active slots are supported.
    
    Logical TDM slot numbering follows the usual convention:
    
    For I2S-like modes, with a 50% duty-cycle frame clock,
    slots 0, 2, ... are transmitted in the first half of a frame,
    slots 1, 3, ... are transmitted in the second half.
    
    For DSP modes slot numbering is ascending: 0, 1, 2, 3, ...
    
    Channel position calculation has been refactored to use
    TDM info and moved out of hw_params.
    
    set_tdm_slot, set_bclk_ratio and hw_params now check more
    strictly if the configuration is valid. Illegal configurations
    like odd number of slots in I2S mode, data lengths exceeding
    slot width or frame sizes larger than the hardware limit of
    1024 are rejected. Also hw_params now properly checks for
    errors from clk_set_rate.
    
    Allowed PCM formats are already guarded by stream constraints,
    thus the formats check in hw_params has been removed and
    data_length is now retrieved via params_width().
    
    Also standard functions like snd_soc_params_to_bclk are now
    being used instead of manual calculations to make the code
    more readable.
    
    Special care has been taken to ensure that set_bclk_ratio works
    as before. The bclk ratio is mapped to a 2-channel TDM config
    with a slot width of half the ratio. In order to support odd ratios,
    which can't be expressed via a TDM config, the ratio (frame length)
    is stored and used by hw_params.
    Signed-off-by: default avatarMatthias Reichl <hias@horus.com>
    Signed-off-by: default avatarMark Brown <broonie@kernel.org>
    9448572d
bcm2835-i2s.c 22.6 KB