NVIDIA: SAUCE: ASoC: soc-pcm: Fix hw_params() and DAPM widget sequence

Issue:
 Tegra audio usecase throws pcm_write error intermittently incase
 common BE DAI is used, for example below usecase throws the error:
  aplay(2 streams) -> AMX(mux) -> ADX(demux) -> arecord(2 streams),
  here, 'AMX TX' and 'ADX RX' are common BE DAIs.

 The problem occurs when streams sharing a common BE DAI are started
 simultaneously. This intermittently results in the common BE DAI
 widget being enabled before its hw_params are configured.

For above usecase when failure happens below sequence is observed:
 aplay(1) FE open()
  - BE DAI callbacks added to the list
  - BE DAI state = SND_SOC_DPCM_STATE_OPEN
 aplay(2) FE open()
  - BE DAI callbacks are not added to the list as the state is
    already SND_SOC_DPCM_STATE_OPEN during aplay(1) FE open().
 aplay(2) FE hw_params()
  - BE DAI hw_params() callback ignored
 aplay(2) FE prepare()
  - Widget is powered ON without BE DAI hw_params() call
 aplay(1) FE hw_params()
  - BE DAI hw_params() is now called

Fix:
 - Add BE DAIs if its state is either SND_SOC_DPCM_STATE_OPEN or
   SND_SOC_DPCM_STATE_HW_PARAMS as well.
 - Additionally, while calling hw_params() for BE DAI, the
   SND_SOC_DPCM_STATE_HW_PARAMS state check is not correct, as the
   state will change once the BE DAI hw_params() callback is completed.
   It avoids multiple times same BE DAI hw_params() call.

The BE DAI callbacks are only called once due to the state check in
the PCM BE DAI calls and will not break the existing flow, but it
ensures the sequence will not break for the shared BE DAIs.

http://nvbugs/4596841

Signed-off-by: Sheetal <sheetal@nvidia.com>
Reviewed-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-by: Mohan kumar <mkumard@nvidia.com>
Reviewed-by: Kartik Rajput <kkartik@nvidia.com>
Tested-by: Kartik Rajput <kkartik@nvidia.com>
Signed-off-by: Vishwaroop A <va@nvidia.com>
Acked-by: Noah Wager <noah.wager@canonical.com>
Acked-by: Jacob Martin <jacob.martin@canonical.com>
Signed-off-by: Noah Wager <noah.wager@canonical.com>
This commit is contained in:
Sheetal
2025-02-01 02:38:51 +00:00
committed by Noah Wager
parent 5695de5b72
commit d3be95d58c
+4 -2
View File
@@ -1550,10 +1550,13 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
/*
* Filter for systems with 'component_chaining' enabled.
* This helps to avoid unnecessary re-configuration of an
* already active BE on such systems.
* already active BE on such systems and ensures the BE DAI
* widget power ON after all BE DAI callbacks.
*/
if (fe->card->component_chaining &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE))
continue;
@@ -2075,7 +2078,6 @@ int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream)
continue;
if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE))
continue;