mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
ASoC: tegra-alt: fix admaif mono/stereo conv
The admaif cif conversion from mono to stereo and vise-versa config will take effect only when client/xbar channels are 1/2 or 2/1. If this condition doesn't satisfy, the configured bit-field for mono_conv and stereo_conv in cif ctrl register will not take effect. Considering this the current code needs to be fixed. - For Playback path: The Client and Audio channels won't be different as the data flows from external memory to ahub. So override channel control have no say on this path, for client_channel=1 and if "mono to stereo conv" control was set then override audio_channel=2 for stereo conversion. - For Capture path: The Client channel will be based on params_channels() and the xbar channels can be different from client channel as it comes from other ahub modules which can output different channel number compared to client, So the "ADMAIFx Channel" wil be used for capture path to feed proper xbar channel available. During stereo to mono conversion i.e when audio_channel=2 and client_channel=1, the configuration in the bitfield mono_conv will take effect. Bug 200500656 Change-Id: Ie61aed848eb35715414a7d8f0e00eae9066b32d3 Signed-off-by: Mohan Kumar <mkumard@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2080175 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Sameer Pujar
parent
95dd5b9e73
commit
834b540cf9
@@ -396,13 +396,6 @@ static int tegra_admaif_hw_params(struct snd_pcm_substream *substream,
|
|||||||
|
|
||||||
memset(&cif_conf, 0, sizeof(struct tegra210_xbar_cif_conf));
|
memset(&cif_conf, 0, sizeof(struct tegra210_xbar_cif_conf));
|
||||||
|
|
||||||
channels = params_channels(params);
|
|
||||||
if (admaif->override_channels[dai->id] > 0)
|
|
||||||
channels = admaif->override_channels[dai->id];
|
|
||||||
|
|
||||||
cif_conf.audio_channels = channels;
|
|
||||||
cif_conf.client_channels = channels;
|
|
||||||
|
|
||||||
switch (params_format(params)) {
|
switch (params_format(params)) {
|
||||||
case SNDRV_PCM_FORMAT_S8:
|
case SNDRV_PCM_FORMAT_S8:
|
||||||
cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_8;
|
cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_8;
|
||||||
@@ -429,30 +422,43 @@ static int tegra_admaif_hw_params(struct snd_pcm_substream *substream,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channels = params_channels(params);
|
||||||
|
cif_conf.client_channels = channels;
|
||||||
|
cif_conf.audio_channels = channels;
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
reg = admaif->soc_data->tx_base +
|
reg = admaif->soc_data->tx_base +
|
||||||
TEGRA_ADMAIF_CHAN_ACIF_TX_CTRL +
|
TEGRA_ADMAIF_CHAN_ACIF_TX_CTRL +
|
||||||
(dai->id * TEGRA_ADMAIF_CHANNEL_REG_STRIDE);
|
(dai->id * TEGRA_ADMAIF_CHANNEL_REG_STRIDE);
|
||||||
/* For playback path, the mono input from client channel
|
/* For playback path, if client channel is 1 and mono to
|
||||||
* can be converted to stereo using cif controls.
|
* stereo control was non-zero, then audio channels will be
|
||||||
*/
|
* set to 2 for mono to stereo conversion.
|
||||||
if (admaif->tx_mono_to_stereo[dai->id] > 0) {
|
*/
|
||||||
|
if ((admaif->tx_mono_to_stereo[dai->id] > 0) &&
|
||||||
|
(channels == 1)) {
|
||||||
cif_conf.mono_conv =
|
cif_conf.mono_conv =
|
||||||
admaif->tx_mono_to_stereo[dai->id] - 1;
|
admaif->tx_mono_to_stereo[dai->id] - 1;
|
||||||
cif_conf.audio_channels = 2;
|
cif_conf.audio_channels = 2;
|
||||||
cif_conf.client_channels = 1;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reg = TEGRA_ADMAIF_CHAN_ACIF_RX_CTRL +
|
reg = TEGRA_ADMAIF_CHAN_ACIF_RX_CTRL +
|
||||||
(dai->id * TEGRA_ADMAIF_CHANNEL_REG_STRIDE);
|
(dai->id * TEGRA_ADMAIF_CHANNEL_REG_STRIDE);
|
||||||
/* For capture path, the stereo audio channel can be
|
|
||||||
* converted to mono using cif controls.
|
/* The override channels are needed only for capture path as
|
||||||
*/
|
* the audio and client channels can be different on RX path.
|
||||||
if (admaif->rx_stereo_to_mono[dai->id] > 0) {
|
*/
|
||||||
|
if (admaif->override_channels[dai->id] > 0) {
|
||||||
|
cif_conf.audio_channels =
|
||||||
|
admaif->override_channels[dai->id];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For capture path, if client channel is 1 and audio channel
|
||||||
|
* is 2, only then stereo to mono settings will take effect.
|
||||||
|
*/
|
||||||
|
if ((admaif->rx_stereo_to_mono[dai->id] > 0) &&
|
||||||
|
(cif_conf.audio_channels == 2) && (channels == 1)) {
|
||||||
cif_conf.stereo_conv =
|
cif_conf.stereo_conv =
|
||||||
admaif->rx_stereo_to_mono[dai->id] - 1;
|
admaif->rx_stereo_to_mono[dai->id] - 1;
|
||||||
cif_conf.audio_channels = 2;
|
|
||||||
cif_conf.client_channels = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user