diff --git a/src/audio/component.c b/src/audio/component.c index 319b40153c81..472cb8fa1dc4 100644 --- a/src/audio/component.c +++ b/src/audio/component.c @@ -142,7 +142,8 @@ int comp_set_state(struct comp_dev *dev, int cmd) break; case COMP_TRIGGER_STOP: case COMP_TRIGGER_XRUN: - if (dev->state == COMP_STATE_ACTIVE) { + if (dev->state == COMP_STATE_ACTIVE || + dev->state == COMP_STATE_PREPARE) { dev->state = COMP_STATE_PREPARE; } else { trace_comp_error("CEs"); diff --git a/src/audio/host.c b/src/audio/host.c index 55795673b028..848a33f13dbc 100644 --- a/src/audio/host.c +++ b/src/audio/host.c @@ -740,7 +740,7 @@ static int host_stop(struct comp_dev *dev) /* reset elements, to let next start from original one */ host_elements_reset(dev); - dev->state = COMP_STATE_PAUSED; + dev->state = COMP_STATE_PREPARE; return 0; } diff --git a/src/ipc/handler.c b/src/ipc/handler.c index 3c85097d5149..4cf7260ca11d 100644 --- a/src/ipc/handler.c +++ b/src/ipc/handler.c @@ -449,6 +449,18 @@ static int ipc_stream_trigger(uint32_t header) trace_error_value(ipc_cmd); } + /* when stop command comes, the pipeline has to be prepared. + * This case has to be taken into account: + * when ALSA has XRUN, it will send stop/start commands to FW + * and try to recover the pipepine. If we did not prepare + * the pipeline before start, the recover process will fail. + */ + if (cmd == COMP_TRIGGER_STOP) { + ret = pipeline_prepare(pcm_dev->cd->pipeline, pcm_dev->cd); + if (ret < 0) + trace_ipc_error("eR1"); + } + return ret; }