On Fri, Jun 28, 2024 at 5:44 PM Chancel Liu <chancel.liu@xxxxxxx> wrote: > > In the current flow all interrupts are disabled in runtime suspend > phase. However interrupts enablement only exists in fsl_xcvr_prepare(). > After resume fsl_xcvr_prepare() may not be called so it will cause all > interrupts still disabled even if resume from suspend. Interrupts > should be explictily enabled after resume. > > Also, DPATH reset setting only exists in fsl_xcvr_prepare(). After > resume from suspend DPATH should be reset otherwise there'll be channel > swap issue. > > Signed-off-by: Chancel Liu <chancel.liu@xxxxxxx> Acked-by: Shengjiu Wang <shengjiu.wang@xxxxxxxxx> Best regards Shengjiu Wang > --- > sound/soc/fsl/fsl_xcvr.c | 43 +++++++++++++++++++++------------------- > 1 file changed, 23 insertions(+), 20 deletions(-) > > diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c > index 337da46a2f90..bf9a4e90978e 100644 > --- a/sound/soc/fsl/fsl_xcvr.c > +++ b/sound/soc/fsl/fsl_xcvr.c > @@ -529,16 +529,6 @@ static int fsl_xcvr_prepare(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; > - } > - > - /* set DPATH RESET */ > - m_ctl |= FSL_XCVR_EXT_CTRL_DPTH_RESET(tx); > - v_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); > @@ -679,6 +669,15 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd, > case SNDRV_PCM_TRIGGER_START: > case SNDRV_PCM_TRIGGER_RESUME: > case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: > + /* set DPATH RESET */ > + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, > + FSL_XCVR_EXT_CTRL_DPTH_RESET(tx), > + FSL_XCVR_EXT_CTRL_DPTH_RESET(tx)); > + if (ret < 0) { > + dev_err(dai->dev, "Failed to set DPATH RESET: %d\n", ret); > + return ret; > + } > + > if (tx) { > switch (xcvr->mode) { > case FSL_XCVR_MODE_EARC: > @@ -711,6 +710,13 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd, > return ret; > } > > + 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; > + } > + > /* clear DPATH RESET */ > ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, > FSL_XCVR_EXT_CTRL_DPTH_RESET(tx), > @@ -733,6 +739,13 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd, > return ret; > } > > + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, > + FSL_XCVR_IRQ_EARC_ALL, 0); > + if (ret < 0) { > + dev_err(dai->dev, "Failed to clear IER0: %d\n", ret); > + return ret; > + } > + > if (tx) { > switch (xcvr->mode) { > case FSL_XCVR_MODE_SPDIF: > @@ -1411,16 +1424,6 @@ static int fsl_xcvr_runtime_suspend(struct device *dev) > struct fsl_xcvr *xcvr = dev_get_drvdata(dev); > int ret; > > - /* > - * Clear interrupts, when streams starts or resumes after > - * suspend, interrupts are enabled in prepare(), so no need > - * to enable interrupts in resume(). > - */ > - ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, > - FSL_XCVR_IRQ_EARC_ALL, 0); > - if (ret < 0) > - dev_err(dev, "Failed to clear IER0: %d\n", ret); > - > if (!xcvr->soc_data->spdif_only) { > /* Assert M0+ reset */ > ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, > -- > 2.43.0 >