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:
+4
-2
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user