summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/fsl_xcvr.c
diff options
context:
space:
mode:
authorViorel Suman <viorel.suman@nxp.com>2020-03-24 13:31:25 +0200
committerViorel Suman <viorel.suman@nxp.com>2020-03-25 10:49:09 +0200
commitff5a36241f007be167ec7a23a3812de5229f515b (patch)
tree6d1b307f80d9a515191e46c526a1755dabd942b4 /sound/soc/fsl/fsl_xcvr.c
parent8a05c23ef23ae22285b34e66cb622a4af1e049c4 (diff)
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 <viorel.suman@nxp.com> Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Diffstat (limited to 'sound/soc/fsl/fsl_xcvr.c')
-rw-r--r--sound/soc/fsl/fsl_xcvr.c138
1 files changed, 70 insertions, 68 deletions
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;
}