From: Pan Xiuli xiuli.pan@linux.intel.com
Add ssp_get_loopback_mode and refine ssp_set_loopback_mode function to support SSP loopback mode.
Signed-off-by: Pan Xiuli xiuli.pan@linux.intel.com --- Work with patch set: SOF-Kernel(6): ASoC: SOF: Add debug_mode flag in sof dev ASoC: SOF: debug: add debugmode debugfs for sof_dev debug_mode ASoC: SOF: uapi: topology: Add SOF_TKN_DAI_SSP_LBM for ssp loopback mode ASoC: SOF: add headers for lbm control callback functions ASoC: SOF: add lbm kcontrol callback functions ASoC: SOF: topology: Add topology handler for dai ssp loopback mode
SOF(5): dai: add lbm status for dai ssp dai: add get_loopback_mode function DMIC: add empty get_loopback_mode function SSP: support for get/set_loopback_mode functions dai: add dai_cmd support for loopback mode switch
SOF-Tools(3): topology: Add SOF_TKN_DAI_SSP_LBM for ssp loopback mode topology: m4: Add DAI_OUT_SSP_LOOPBACK marco for SSP LOOPBACK dai comp topology: test: Add loopback topology
test & santity test with: Mininow max rt5651 and UP2 Hifiberry PRO and CNL nocodec SOF master: 48d2a1c551d7b3c8f76d44f3c04dd59a37ff6a8f SOF-Tool master: bd7dc88231f31d385340310cef467f211a739eeb https://github.com/plbossart/sound/tree/topic/sof-v4.14: 0d51a5ed28c5e97f09b59c4cafaddfb9d3b24b77 --- src/drivers/apl-ssp.c | 22 +++++++++++++++++++--- src/drivers/byt-ssp.c | 22 +++++++++++++++++++--- src/drivers/hsw-ssp.c | 22 +++++++++++++++++++--- 3 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/src/drivers/apl-ssp.c b/src/drivers/apl-ssp.c index 6571b90..e94d676 100644 --- a/src/drivers/apl-ssp.c +++ b/src/drivers/apl-ssp.c @@ -564,16 +564,31 @@ static inline int ssp_set_loopback_mode(struct dai *dai, uint32_t lbm) { struct ssp_pdata *ssp = dai_get_drvdata(dai);
- trace_ssp("loo"); - spin_lock(&ssp->lock); + trace_ssp("los");
- ssp_update_bits(dai, SSCR1, SSCR1_LBM, lbm ? SSCR1_LBM : 0); + if (ssp->lbm == lbm) + return 0;
+ spin_lock(&ssp->lock); + ssp->lbm = lbm; + ssp_update_bits(dai, SSCR1, SSCR1_LBM, lbm ? SSCR1_LBM : 0); spin_unlock(&ssp->lock);
return 0; }
+static inline int ssp_get_loopback_mode(struct dai *dai) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + int ret; + + trace_ssp("log"); + spin_lock(&ssp->lock); + ret = ssp->lbm; + spin_unlock(&ssp->lock); + return ret; +} + /* start the SSP for either playback or capture */ static void ssp_start(struct dai *dai, int direction) { @@ -711,4 +726,5 @@ const struct dai_ops ssp_ops = { .pm_context_restore = ssp_context_restore, .probe = ssp_probe, .set_loopback_mode = ssp_set_loopback_mode, + .get_loopback_mode = ssp_get_loopback_mode, }; diff --git a/src/drivers/byt-ssp.c b/src/drivers/byt-ssp.c index d058c5f..d55dc8b 100644 --- a/src/drivers/byt-ssp.c +++ b/src/drivers/byt-ssp.c @@ -472,16 +472,31 @@ static inline int ssp_set_loopback_mode(struct dai *dai, uint32_t lbm) { struct ssp_pdata *ssp = dai_get_drvdata(dai);
- trace_ssp("loo"); - spin_lock(&ssp->lock); + trace_ssp("los");
- ssp_update_bits(dai, SSCR1, SSCR1_LBM, lbm ? SSCR1_LBM : 0); + if (ssp->lbm == lbm) + return 0;
+ spin_lock(&ssp->lock); + ssp->lbm = lbm; + ssp_update_bits(dai, SSCR1, SSCR1_LBM, lbm ? SSCR1_LBM : 0); spin_unlock(&ssp->lock);
return 0; }
+static inline int ssp_get_loopback_mode(struct dai *dai) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + int ret; + + trace_ssp("log"); + spin_lock(&ssp->lock); + ret = ssp->lbm; + spin_unlock(&ssp->lock); + return ret; +} + /* start the SSP for either playback or capture */ static void ssp_start(struct dai *dai, int direction) { @@ -623,4 +638,5 @@ const struct dai_ops ssp_ops = { .pm_context_restore = ssp_context_restore, .probe = ssp_probe, .set_loopback_mode = ssp_set_loopback_mode, + .get_loopback_mode = ssp_get_loopback_mode, }; diff --git a/src/drivers/hsw-ssp.c b/src/drivers/hsw-ssp.c index 0d74e7d..91af784 100644 --- a/src/drivers/hsw-ssp.c +++ b/src/drivers/hsw-ssp.c @@ -395,16 +395,31 @@ static inline int ssp_set_loopback_mode(struct dai *dai, uint32_t lbm) { struct ssp_pdata *ssp = dai_get_drvdata(dai);
- trace_ssp("loo"); - spin_lock(&ssp->lock); + trace_ssp("los");
- ssp_update_bits(dai, SSCR1, SSCR1_LBM, lbm ? SSCR1_LBM : 0); + if (ssp->lbm == lbm) + return 0;
+ spin_lock(&ssp->lock); + ssp->lbm = lbm; + ssp_update_bits(dai, SSCR1, SSCR1_LBM, lbm ? SSCR1_LBM : 0); spin_unlock(&ssp->lock);
return 0; }
+static inline int ssp_get_loopback_mode(struct dai *dai) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + int ret; + + trace_ssp("log"); + spin_lock(&ssp->lock); + ret = ssp->lbm; + spin_unlock(&ssp->lock); + return ret; +} + /* start the SSP for either playback or capture */ static void ssp_start(struct dai *dai, int direction) { @@ -550,4 +565,5 @@ const struct dai_ops ssp_ops = { .pm_context_restore = ssp_context_restore, .probe = ssp_probe, .set_loopback_mode = ssp_set_loopback_mode, + .get_loopback_mode = ssp_get_loopback_mode, };