On 04/10/2019 18:03, Ben Dooks wrote:
On 30/09/2019 22:08, Jon Hunter wrote:
On 30/09/2019 17:51, Ben Dooks wrote:
If the hw_params uses a different bit or channel count, then we need to change both the I2S unit's CIF configuration as well as the APBIF one.
To allow changing the APBIF, add a call to reconfigure the RX or TX FIFO without changing the DMA or allocation, and get the I2S driver to call it once the hw params have been calculate.
Signed-off-by: Ben Dooks ben.dooks@codethink.co.uk
sound/soc/tegra/tegra30_ahub.c | 114 ++++++++++++++++++--------------- sound/soc/tegra/tegra30_ahub.h | 5 ++ sound/soc/tegra/tegra30_i2s.c | 2 + 3 files changed, 69 insertions(+), 52 deletions(-)
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 952381260dc3..58e05ceb86da 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -84,12 +84,40 @@ static int tegra30_ahub_runtime_resume(struct device *dev) return 0; } +int tegra30_ahub_setup_rx_fifo(enum tegra30_ahub_rxcif rxcif, + struct tegra30_ahub_cif_conf *cif_conf) +{ + int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; + u32 reg, val;
+ pm_runtime_get_sync(ahub->dev);
+ reg = TEGRA30_AHUB_CHANNEL_CTRL + + (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); + val = tegra30_apbif_read(reg); + val &= ~(TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_MASK | + TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK); + val |= (7 << TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_SHIFT) | + TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN | + TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16; + tegra30_apbif_write(reg, val);
+ cif_conf->direction = TEGRA30_AUDIOCIF_DIRECTION_RX;
+ reg = TEGRA30_AHUB_CIF_RX_CTRL + + (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE); + ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, cif_conf);
+ pm_runtime_put(ahub->dev); + return 0; +} +EXPORT_SYMBOL_GPL(tegra30_ahub_setup_rx_fifo);
int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, char *dmachan, int dmachan_len, dma_addr_t *fiforeg) { int channel; - u32 reg, val; struct tegra30_ahub_cif_conf cif_conf; channel = find_first_zero_bit(ahub->rx_usage, @@ -104,37 +132,14 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO + (channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE); - pm_runtime_get_sync(ahub->dev); + memset(&cif_conf, 0, sizeof(cif_conf)); - reg = TEGRA30_AHUB_CHANNEL_CTRL + - (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); - val = tegra30_apbif_read(reg); - val &= ~(TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_MASK | - TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK); - val |= (7 << TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_SHIFT) | - TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN | - TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16; - tegra30_apbif_write(reg, val);
- cif_conf.threshold = 0; cif_conf.audio_channels = 2; cif_conf.client_channels = 2; cif_conf.audio_bits = TEGRA30_AUDIOCIF_BITS_16; cif_conf.client_bits = TEGRA30_AUDIOCIF_BITS_16; - cif_conf.expand = 0; - cif_conf.stereo_conv = 0; - cif_conf.replicate = 0; - cif_conf.direction = TEGRA30_AUDIOCIF_DIRECTION_RX; - cif_conf.truncate = 0; - cif_conf.mono_conv = 0;
- reg = TEGRA30_AHUB_CIF_RX_CTRL + - (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE); - ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
- pm_runtime_put(ahub->dev); - return 0; + return tegra30_ahub_setup_rx_fifo(*rxcif, &cif_conf);
It seems a bit odd, that you still configure some of the cif_conf members and then call tegra30_ahub_setup_rx_fifo() here. Why not just allocate it and then move all the programming to tegra30_ahub_setup_rx_fifo()?
I was trying to keep the behaviour the same, IIRC the original is first called before the format information is known.
Looks like the I2S driver is the only current user of this, so splitting the function into two could make sense.
Cheers Jon