@@ -117,6 +117,8 @@ struct sdw_intel {
struct sdw_cdns cdns;
int instance;
struct sdw_intel_link_res *link_res;
+ struct snd_pcm_hw_params *hw_params;
+ struct sdw_cdns_pdi *pdi;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
@@ -813,6 +815,8 @@ static int intel_hw_params(struct snd_pcm_substream *substream,
intel_pdi_alh_configure(sdw, pdi);
sdw_cdns_config_stream(cdns, ch, dir, pdi);
+ sdw->pdi = pdi;
+ sdw->hw_params = params;
/* Inform DSP about PDI stream number */
ret = intel_params_stream(sdw, substream, dai, params,
@@ -856,7 +860,11 @@ static int intel_hw_params(struct snd_pcm_substream *substream,
static int intel_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
+ struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
+ struct sdw_intel *sdw = cdns_to_intel(cdns);
struct sdw_cdns_dma_data *dma;
+ int ch, dir;
+ int ret;
dma = snd_soc_dai_get_dma_data(dai, substream);
if (!dma) {
@@ -865,7 +873,35 @@ static int intel_prepare(struct snd_pcm_substream *substream,
return -EIO;
}
- return sdw_prepare_stream(dma->stream);
+ /*
+ * .prepare() is called after system resume, where we need to
+ * reinitialize the SHIM/ALH/Cadence IP. To avoid dealing with
+ * complicated state machines, we just re-initialize in all
+ * cases since there are no side effects.
+ */
+
+ /* configure stream */
+ ch = params_channels(sdw->hw_params);
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ dir = SDW_DATA_DIR_RX;
+ else
+ dir = SDW_DATA_DIR_TX;
+
+ intel_pdi_shim_configure(sdw, sdw->pdi);
+ intel_pdi_alh_configure(sdw, sdw->pdi);
+ sdw_cdns_config_stream(cdns, ch, dir, sdw->pdi);
+
+ /* Inform DSP about PDI stream number */
+ ret = intel_params_stream(sdw, substream, dai, sdw->hw_params,
+ sdw->instance,
+ sdw->pdi->intel_alh_id);
+ if (ret)
+ goto err;
+
+ ret = sdw_prepare_stream(dma->stream);
+
+err:
+ return ret;
}
static int intel_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -936,6 +972,8 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
return ret;
}
+ sdw->hw_params = NULL;
+ sdw->pdi = NULL;
sdw_release_stream(dma->stream);
return 0;