if (ret < 0)
return ret;
+ spcm->prepared[substream->stream] = true;
+
/* save pcm hw_params */
memcpy(&spcm->params[substream->stream], params, sizeof(*params));
- /* clear hw_params_upon_resume flag */
- spcm->hw_params_upon_resume[substream->stream] = 0;
-
return ret;
}
if (!spcm)
return -EINVAL;
+ if (!spcm->prepared[substream->stream])
+ return 0;
+
dev_dbg(sdev->dev, "pcm: free stream %d dir %d\n", spcm->pcm.pcm_id,
substream->stream);
if (ret < 0)
dev_err(sdev->dev, "error: platform hw free failed\n");
+ spcm->prepared[substream->stream] = false;
+
return ret;
}
if (!spcm)
return -EINVAL;
- /*
- * check if hw_params needs to be set-up again.
- * This is only needed when resuming from system sleep.
- */
- if (!spcm->hw_params_upon_resume[substream->stream])
+ if (spcm->prepared[substream->stream])
return 0;
dev_dbg(sdev->dev, "pcm: prepare stream %d dir %d\n", spcm->pcm.pcm_id,
struct snd_sof_pcm *spcm;
struct sof_ipc_stream stream;
struct sof_ipc_reply reply;
+ bool reset_hw_params = false;
int ret;
/* nothing to do for BE */
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP;
+ reset_hw_params = true;
break;
default:
dev_err(sdev->dev, "error: unhandled trigger cmd %d\n", cmd);
ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
sizeof(stream), &reply, sizeof(reply));
- if (ret < 0 || cmd != SNDRV_PCM_TRIGGER_SUSPEND)
+ if (ret < 0 || !reset_hw_params)
return ret;
/*
- * The hw_free op is usually called when the pcm stream is closed.
- * Since the stream is not closed during suspend, the DSP needs to be
- * notified explicitly to free pcm to prevent errors upon resume.
+ * In case of stream is stopped, DSP must be reprogrammed upon
+ * restart, so free PCM here.
*/
stream.hdr.size = sizeof(stream);
stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
stream.comp_id = spcm->stream[substream->stream].comp_id;
+ spcm->prepared[substream->stream] = false;
/* send IPC to the DSP */
return sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
spcm->stream[substream->stream].posn.host_posn = 0;
spcm->stream[substream->stream].posn.dai_posn = 0;
spcm->stream[substream->stream].substream = substream;
+ spcm->prepared[substream->stream] = false;
ret = snd_sof_pcm_platform_open(sdev, substream);
if (ret < 0)