From ff5a36241f007be167ec7a23a3812de5229f515b Mon Sep 17 00:00:00 2001 From: Viorel Suman Date: Tue, 24 Mar 2020 13:31:25 +0200 Subject: MLK-23603-3: ASoC: fsl_xcvr: prepare for suspend/resume "startup" callback is not called in a subsequent "runtime_resume" sequence, so move IP init code into "prepare" callback. Aside of this move constraint check code from "prepare" to "startup" since constraint checking is required once at stream startup. Signed-off-by: Viorel Suman Reviewed-by: Shengjiu Wang --- sound/soc/fsl/fsl_xcvr.c | 138 ++++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 68 deletions(-) (limited to 'sound/soc/fsl/fsl_xcvr.c') diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index 7b715b3030c8..7dd5087c6511 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -82,6 +82,63 @@ static int fsl_xcvr_phy_write(struct fsl_xcvr *xcvr, int reg, int data, int pll_ return 0; } +static int fsl_xcvr_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; + u32 m_ctl = 0, v_ctl = 0, m_isr = 0, v_isr = 0; + int ret = 0; + + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, + FSL_XCVR_IRQ_EARC_ALL, FSL_XCVR_IRQ_EARC_ALL); + if (ret < 0) { + dev_err(dai->dev, "Error while setting IER0: %d\n", ret); + return ret; + } + + /* configure EXT_CTRL */ + switch (xcvr->mode & FSL_XCVR_AMODE_MASK) { + case FSL_XCVR_AMODE_SPDIF: + /* set SPDIF MODE */ + m_ctl |= FSL_XCVR_EXT_CTRL_SPDIF_MODE; + v_ctl |= FSL_XCVR_EXT_CTRL_SPDIF_MODE; + m_isr |= FSL_XCVR_ISR_SET_SPDIF_MODE(tx); + v_isr |= FSL_XCVR_ISR_SET_SPDIF_MODE(tx); + if (xcvr->streams == 3) { // both Tx and Rx are in use + m_isr |= FSL_XCVR_ISR_DMAC_SPARE_INT; + v_isr |= FSL_XCVR_ISR_DMAC_SPARE_INT; + } + break; + case FSL_XCVR_AMODE_ARC: + /* Enable ISR */ + break; + case FSL_XCVR_AMODE_EARC: + /* clear CMDC RESET */ + m_ctl |= FSL_XCVR_EXT_CTRL_CMDC_RESET(tx); + /* set TX_RX_MODE */ + m_ctl |= FSL_XCVR_EXT_CTRL_TX_RX_MODE; + v_ctl |= (tx ? FSL_XCVR_EXT_CTRL_TX_RX_MODE : 0); + break; + } + + /* clear DPATH RESET */ + m_ctl |= FSL_XCVR_EXT_CTRL_DPTH_RESET(tx); + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, m_ctl, v_ctl); + if (ret < 0) { + dev_err(dai->dev, "Error while setting EXT_CTRL: %d\n", ret); + return ret; + } + + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_ISR_SET, m_isr, v_isr); + if (ret < 0) { + dev_err(dai->dev, "Error while setting MO ISR: %d\n", ret); + return ret; + } + + return 0; +} + static int fsl_xcvr_constr(const struct snd_pcm_substream *substream, const struct snd_pcm_hw_constraint_list *bits, const struct snd_pcm_hw_constraint_list *channels, @@ -108,12 +165,24 @@ static int fsl_xcvr_constr(const struct snd_pcm_substream *substream, return 0; } -static int fsl_xcvr_prepare(struct snd_pcm_substream *substream, +static int fsl_xcvr_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; int ret = 0; + /* check stream direction is enabled in DTS */ + if (!(xcvr->mode & BIT(substream->stream))) { + dev_err(dai->dev, "%sX not supported\n", tx ? "T" : "R"); + return -EINVAL; + } + + if (xcvr->streams & BIT(substream->stream)) { + dev_err(dai->dev, "%sX busy\n", tx ? "T" : "R"); + return -EBUSY; + } + switch (xcvr->mode & FSL_XCVR_AMODE_MASK) { case FSL_XCVR_AMODE_SPDIF: case FSL_XCVR_AMODE_ARC: @@ -128,27 +197,6 @@ static int fsl_xcvr_prepare(struct snd_pcm_substream *substream, if (ret < 0) return ret; - return 0; -} - -static int fsl_xcvr_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai); - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - u32 m_ctl = 0, v_ctl = 0, m_isr = 0, v_isr = 0; - int ret; - - /* check stream direction is enabled in DTS */ - if (!(xcvr->mode & BIT(substream->stream))) { - dev_err(dai->dev, "%sX not supported\n", tx ? "T" : "R"); - return -EINVAL; - } - - if (xcvr->streams & BIT(substream->stream)) { - dev_err(dai->dev, "%sX busy\n", tx ? "T" : "R"); - return -EBUSY; - } xcvr->streams |= BIT(substream->stream); switch (xcvr->mode & FSL_XCVR_AMODE_MASK) { @@ -190,52 +238,6 @@ static int fsl_xcvr_startup(struct snd_pcm_substream *substream, break; } - ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, - FSL_XCVR_IRQ_EARC_ALL, FSL_XCVR_IRQ_EARC_ALL); - if (ret < 0) { - dev_err(dai->dev, "Error while setting IER0: %d\n", ret); - return ret; - } - - /* configure EXT_CTRL */ - switch (xcvr->mode & FSL_XCVR_AMODE_MASK) { - case FSL_XCVR_AMODE_SPDIF: - /* set SPDIF MODE */ - m_ctl |= FSL_XCVR_EXT_CTRL_SPDIF_MODE; - v_ctl |= FSL_XCVR_EXT_CTRL_SPDIF_MODE; - m_isr |= FSL_XCVR_ISR_SET_SPDIF_MODE(tx); - v_isr |= FSL_XCVR_ISR_SET_SPDIF_MODE(tx); - if (xcvr->streams == 3) { // both Tx and Rx are in use - m_isr |= FSL_XCVR_ISR_DMAC_SPARE_INT; - v_isr |= FSL_XCVR_ISR_DMAC_SPARE_INT; - } - break; - case FSL_XCVR_AMODE_ARC: - /* Enable ISR */ - break; - case FSL_XCVR_AMODE_EARC: - /* clear CMDC RESET */ - m_ctl |= FSL_XCVR_EXT_CTRL_CMDC_RESET(tx); - /* set TX_RX_MODE */ - m_ctl |= FSL_XCVR_EXT_CTRL_TX_RX_MODE; - v_ctl |= (tx ? FSL_XCVR_EXT_CTRL_TX_RX_MODE : 0); - break; - } - - /* clear DPATH RESET */ - m_ctl |= FSL_XCVR_EXT_CTRL_DPTH_RESET(tx); - ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, m_ctl, v_ctl); - if (ret < 0) { - dev_err(dai->dev, "Error while setting EXT_CTRL: %d\n", ret); - return ret; - } - - ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_ISR_SET, m_isr, v_isr); - if (ret < 0) { - dev_err(dai->dev, "Error while setting MO ISR: %d\n", ret); - return ret; - } - return 0; } -- cgit v1.2.3