[Sound-open-firmware] [RFC PATCH 0/6] Hostless pipeline updates
This set of patches make changes to the tone component, pipeline and generic component to support hostless pipelines.
The changes to component and pipeline are mainly to avoid errors when the user repeatedly triggers the pipeline on/off.
Ranjani Sridharan (6): ipc: skip host page table set up for hostless tone pipeline tone: add command handler to return tone state and compute tone sample rate pipeline: ignore request for pipeline_prepare() if the pipeline is running comp: ignore state set request when the old state is unchanged ipc: add sample_rate member to ipc tone comp def tone: set sample rate from topology
src/audio/component.c | 19 +++++++++++ src/audio/pipeline.c | 5 +++ src/audio/tone.c | 26 ++++++++++++++- src/include/uapi/ipc.h | 1 + src/ipc/handler.c | 76 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 125 insertions(+), 2 deletions(-)
Hostless pipelines such as the tone pipeline do not need host page table while setting up pcm params. Walk pipeline in both directions to ensure it is hostless.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/ipc/handler.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/src/ipc/handler.c b/src/ipc/handler.c index 581ce9e..8c46cc2 100644 --- a/src/ipc/handler.c +++ b/src/ipc/handler.c @@ -34,6 +34,7 @@ * */
+#include <stdbool.h> #include <sof/debug.h> #include <sof/timer.h> #include <sof/interrupt.h> @@ -83,6 +84,71 @@ static inline struct sof_ipc_hdr *mailbox_validate(void) return hdr; }
+/* check if a pipeline is hostless when walking downstream */ +static bool is_hostless_downstream(struct comp_dev *current) +{ + struct list_item *clist; + + /* check if current is a HOST comp */ + if (current->comp.type == SOF_COMP_HOST || + current->comp.type == SOF_COMP_SG_HOST) + return false; + + /* check if the pipeline has a HOST comp downstream */ + list_for_item(clist, ¤t->bsink_list) { + struct comp_buffer *buffer; + + buffer = container_of(clist, struct comp_buffer, source_list); + + /* don't go downstream if this component is not connected */ + if (!buffer->connected) + continue; + + /* dont go downstream if this comp belongs to another pipe */ + if (buffer->sink->comp.pipeline_id != current->comp.pipeline_id) + continue; + + /* return if there's a host comp downstream */ + if (!is_hostless_downstream(buffer->sink)) + return false; + } + + return true; +} + +/* check if a pipeline is hostless when walking upstream */ +static bool is_hostless_upstream(struct comp_dev *current) +{ + struct list_item *clist; + + /* check if current is a HOST comp */ + if (current->comp.type == SOF_COMP_HOST || + current->comp.type == SOF_COMP_SG_HOST) + return false; + + /* check if the pipeline has a HOST comp upstream */ + list_for_item(clist, ¤t->bsource_list) { + struct comp_buffer *buffer; + + buffer = container_of(clist, struct comp_buffer, source_list); + + /* don't go upstream if this component is not connected */ + if (!buffer->connected) + continue; + + /* dont go upstream if this comp belongs to another pipeline */ + if (buffer->source->comp.pipeline_id != + current->comp.pipeline_id) + continue; + + /* return if there is a host comp upstream */ + if (!is_hostless_upstream(buffer->sink)) + return false; + } + + return true; +} + /* * Stream IPC Operations. */ @@ -125,8 +191,14 @@ static int ipc_stream_pcm_params(uint32_t stream) cd = pcm_dev->cd; cd->params = pcm_params->params;
-#ifdef CONFIG_HOST_PTABLE + /* + * walk in both directions to check if the pipeline is hostless + * skip page table set up if it is + */ + if (is_hostless_downstream(cd) && is_hostless_upstream(cd)) + goto pipe_params;
+#ifdef CONFIG_HOST_PTABLE list_init(&elem_list);
/* use DMA to read in compressed page table ringbuffer from host */ @@ -163,6 +235,8 @@ static int ipc_stream_pcm_params(uint32_t stream) } #endif
+pipe_params: + /* configure pipeline audio params */ err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd, pcm_params); if (err < 0) {
On 2018年06月14日 11:29, Ranjani Sridharan wrote:
Hostless pipelines such as the tone pipeline do not need host page table while setting up pcm params. Walk pipeline in both directions to ensure it is hostless.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com
src/ipc/handler.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/src/ipc/handler.c b/src/ipc/handler.c index 581ce9e..8c46cc2 100644 --- a/src/ipc/handler.c +++ b/src/ipc/handler.c @@ -34,6 +34,7 @@
*/
+#include <stdbool.h> #include <sof/debug.h> #include <sof/timer.h> #include <sof/interrupt.h> @@ -83,6 +84,71 @@ static inline struct sof_ipc_hdr *mailbox_validate(void) return hdr; }
+/* check if a pipeline is hostless when walking downstream */ +static bool is_hostless_downstream(struct comp_dev *current) +{
- struct list_item *clist;
- /* check if current is a HOST comp */
- if (current->comp.type == SOF_COMP_HOST ||
current->comp.type == SOF_COMP_SG_HOST)
return false;
- /* check if the pipeline has a HOST comp downstream */
- list_for_item(clist, ¤t->bsink_list) {
struct comp_buffer *buffer;
buffer = container_of(clist, struct comp_buffer, source_list);
/* don't go downstream if this component is not connected */
if (!buffer->connected)
continue;
/* dont go downstream if this comp belongs to another pipe */
if (buffer->sink->comp.pipeline_id != current->comp.pipeline_id)
continue;
/* return if there's a host comp downstream */
if (!is_hostless_downstream(buffer->sink))
return false;
- }
- return true;
+}
+/* check if a pipeline is hostless when walking upstream */ +static bool is_hostless_upstream(struct comp_dev *current) +{
- struct list_item *clist;
- /* check if current is a HOST comp */
- if (current->comp.type == SOF_COMP_HOST ||
current->comp.type == SOF_COMP_SG_HOST)
return false;
- /* check if the pipeline has a HOST comp upstream */
- list_for_item(clist, ¤t->bsource_list) {
struct comp_buffer *buffer;
buffer = container_of(clist, struct comp_buffer, source_list);
I think it should be: buffer = container_of(clist, struct comp_buffer, sink_list);
thanks ~zhigang
/* don't go upstream if this component is not connected */
if (!buffer->connected)
continue;
/* dont go upstream if this comp belongs to another pipeline */
if (buffer->source->comp.pipeline_id !=
current->comp.pipeline_id)
continue;
/* return if there is a host comp upstream */
if (!is_hostless_upstream(buffer->sink))
return false;
- }
- return true;
+}
- /*
*/
- Stream IPC Operations.
@@ -125,8 +191,14 @@ static int ipc_stream_pcm_params(uint32_t stream) cd = pcm_dev->cd; cd->params = pcm_params->params;
-#ifdef CONFIG_HOST_PTABLE
- /*
* walk in both directions to check if the pipeline is hostless
* skip page table set up if it is
*/
- if (is_hostless_downstream(cd) && is_hostless_upstream(cd))
goto pipe_params;
+#ifdef CONFIG_HOST_PTABLE list_init(&elem_list);
/* use DMA to read in compressed page table ringbuffer from host */ @@ -163,6 +235,8 @@ static int ipc_stream_pcm_params(uint32_t stream) } #endif
+pipe_params:
- /* configure pipeline audio params */ err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd, pcm_params); if (err < 0) {
On Thu, 2018-06-14 at 14:08 +0800, zhigangw wrote:
On 2018年06月14日 11:29, Ranjani Sridharan wrote:
Hostless pipelines such as the tone pipeline do not need host page table while setting up pcm params. Walk pipeline in both directions to ensure it is hostless.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com
src/ipc/handler.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/src/ipc/handler.c b/src/ipc/handler.c index 581ce9e..8c46cc2 100644 --- a/src/ipc/handler.c +++ b/src/ipc/handler.c @@ -34,6 +34,7 @@
*/
+#include <stdbool.h> #include <sof/debug.h> #include <sof/timer.h> #include <sof/interrupt.h> @@ -83,6 +84,71 @@ static inline struct sof_ipc_hdr *mailbox_validate(void) return hdr; }
+/* check if a pipeline is hostless when walking downstream */ +static bool is_hostless_downstream(struct comp_dev *current) +{
- struct list_item *clist;
- /* check if current is a HOST comp */
- if (current->comp.type == SOF_COMP_HOST ||
current->comp.type == SOF_COMP_SG_HOST)
return false;
- /* check if the pipeline has a HOST comp downstream */
- list_for_item(clist, ¤t->bsink_list) {
struct comp_buffer *buffer;
buffer = container_of(clist, struct comp_buffer,
source_list);
/* don't go downstream if this component is not
connected */
if (!buffer->connected)
continue;
/* dont go downstream if this comp belongs to
another pipe */
if (buffer->sink->comp.pipeline_id != current-
comp.pipeline_id)
continue;
/* return if there's a host comp downstream */
if (!is_hostless_downstream(buffer->sink))
return false;
- }
- return true;
+}
+/* check if a pipeline is hostless when walking upstream */ +static bool is_hostless_upstream(struct comp_dev *current) +{
- struct list_item *clist;
- /* check if current is a HOST comp */
- if (current->comp.type == SOF_COMP_HOST ||
current->comp.type == SOF_COMP_SG_HOST)
return false;
- /* check if the pipeline has a HOST comp upstream */
- list_for_item(clist, ¤t->bsource_list) {
struct comp_buffer *buffer;
buffer = container_of(clist, struct comp_buffer,
source_list);
I think it should be: buffer = container_of(clist, struct comp_buffer, sink_list);
Oh yes, Thanks Zhigang. The dangers of copy & paste :)
thanks ~zhigang
/* don't go upstream if this component is not
connected */
if (!buffer->connected)
continue;
/* dont go upstream if this comp belongs to
another pipeline */
if (buffer->source->comp.pipeline_id !=
current->comp.pipeline_id)
continue;
/* return if there is a host comp upstream */
if (!is_hostless_upstream(buffer->sink))
return false;
- }
- return true;
+}
- /*
*/
- Stream IPC Operations.
@@ -125,8 +191,14 @@ static int ipc_stream_pcm_params(uint32_t stream) cd = pcm_dev->cd; cd->params = pcm_params->params;
-#ifdef CONFIG_HOST_PTABLE
- /*
* walk in both directions to check if the pipeline is
hostless
* skip page table set up if it is
*/
- if (is_hostless_downstream(cd) &&
is_hostless_upstream(cd))
goto pipe_params;
+#ifdef CONFIG_HOST_PTABLE list_init(&elem_list);
/* use DMA to read in compressed page table ringbuffer from host */ @@ -163,6 +235,8 @@ static int ipc_stream_pcm_params(uint32_t stream) } #endif
+pipe_params:
- /* configure pipeline audio params */ err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd,
pcm_params); if (err < 0) {
On 2018年06月14日 14:13, Ranjani Sridharan wrote:
On Thu, 2018-06-14 at 14:08 +0800, zhigangw wrote:
On 2018年06月14日 11:29, Ranjani Sridharan wrote:
Hostless pipelines such as the tone pipeline do not need host page table while setting up pcm params. Walk pipeline in both directions to ensure it is hostless.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com
src/ipc/handler.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/src/ipc/handler.c b/src/ipc/handler.c index 581ce9e..8c46cc2 100644 --- a/src/ipc/handler.c +++ b/src/ipc/handler.c @@ -34,6 +34,7 @@ * */
+#include <stdbool.h> #include <sof/debug.h> #include <sof/timer.h> #include <sof/interrupt.h> @@ -83,6 +84,71 @@ static inline struct sof_ipc_hdr *mailbox_validate(void) return hdr; }
+/* check if a pipeline is hostless when walking downstream */ +static bool is_hostless_downstream(struct comp_dev *current) +{
- struct list_item *clist;
- /* check if current is a HOST comp */
- if (current->comp.type == SOF_COMP_HOST ||
current->comp.type == SOF_COMP_SG_HOST)
return false;
- /* check if the pipeline has a HOST comp downstream */
- list_for_item(clist, ¤t->bsink_list) {
struct comp_buffer *buffer;
buffer = container_of(clist, struct comp_buffer,
source_list);
/* don't go downstream if this component is not
connected */
if (!buffer->connected)
continue;
/* dont go downstream if this comp belongs to
another pipe */
if (buffer->sink->comp.pipeline_id != current-
comp.pipeline_id)
continue;
/* return if there's a host comp downstream */
if (!is_hostless_downstream(buffer->sink))
return false;
- }
- return true;
+}
+/* check if a pipeline is hostless when walking upstream */ +static bool is_hostless_upstream(struct comp_dev *current) +{
- struct list_item *clist;
- /* check if current is a HOST comp */
- if (current->comp.type == SOF_COMP_HOST ||
current->comp.type == SOF_COMP_SG_HOST)
return false;
- /* check if the pipeline has a HOST comp upstream */
- list_for_item(clist, ¤t->bsource_list) {
struct comp_buffer *buffer;
buffer = container_of(clist, struct comp_buffer,
source_list);
I think it should be: buffer = container_of(clist, struct comp_buffer, sink_list);
Oh yes, Thanks Zhigang. The dangers of copy & paste :)
there is another location which has the similarly issue;
it should be: if (!is_hostless_upstream(buffer->source)) thanks ~zhigang
thanks ~zhigang
/* don't go upstream if this component is not
connected */
if (!buffer->connected)
continue;
/* dont go upstream if this comp belongs to
another pipeline */
if (buffer->source->comp.pipeline_id !=
current->comp.pipeline_id)
continue;
/* return if there is a host comp upstream */
if (!is_hostless_upstream(buffer->sink))
return false;
- }
- return true;
+}
- /*
*/
- Stream IPC Operations.
@@ -125,8 +191,14 @@ static int ipc_stream_pcm_params(uint32_t stream) cd = pcm_dev->cd; cd->params = pcm_params->params;
-#ifdef CONFIG_HOST_PTABLE
- /*
* walk in both directions to check if the pipeline is
hostless
* skip page table set up if it is
*/
- if (is_hostless_downstream(cd) &&
is_hostless_upstream(cd))
goto pipe_params;
+#ifdef CONFIG_HOST_PTABLE list_init(&elem_list);
/* use DMA to read in compressed page table ringbuffer
from host */ @@ -163,6 +235,8 @@ static int ipc_stream_pcm_params(uint32_t stream) } #endif
+pipe_params:
- /* configure pipeline audio params */ err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd,
pcm_params); if (err < 0) {
On Thu, 2018-06-14 at 14:38 +0800, zhigangw wrote:
On 2018年06月14日 14:13, Ranjani Sridharan wrote:
On Thu, 2018-06-14 at 14:08 +0800, zhigangw wrote:
On 2018年06月14日 11:29, Ranjani Sridharan wrote:
Hostless pipelines such as the tone pipeline do not need host page table while setting up pcm params. Walk pipeline in both directions to ensure it is hostless.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel .com
src/ipc/handler.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/src/ipc/handler.c b/src/ipc/handler.c index 581ce9e..8c46cc2 100644 --- a/src/ipc/handler.c +++ b/src/ipc/handler.c @@ -34,6 +34,7 @@ * */
+#include <stdbool.h> #include <sof/debug.h> #include <sof/timer.h> #include <sof/interrupt.h> @@ -83,6 +84,71 @@ static inline struct sof_ipc_hdr *mailbox_validate(void) return hdr; }
+/* check if a pipeline is hostless when walking downstream */ +static bool is_hostless_downstream(struct comp_dev *current) +{
- struct list_item *clist;
- /* check if current is a HOST comp */
- if (current->comp.type == SOF_COMP_HOST ||
current->comp.type == SOF_COMP_SG_HOST)
return false;
- /* check if the pipeline has a HOST comp downstream */
- list_for_item(clist, ¤t->bsink_list) {
struct comp_buffer *buffer;
buffer = container_of(clist, struct
comp_buffer, source_list);
/* don't go downstream if this component is
not connected */
if (!buffer->connected)
continue;
/* dont go downstream if this comp belongs to
another pipe */
if (buffer->sink->comp.pipeline_id != current-
comp.pipeline_id)
continue;
/* return if there's a host comp downstream */
if (!is_hostless_downstream(buffer->sink))
return false;
- }
- return true;
+}
+/* check if a pipeline is hostless when walking upstream */ +static bool is_hostless_upstream(struct comp_dev *current) +{
- struct list_item *clist;
- /* check if current is a HOST comp */
- if (current->comp.type == SOF_COMP_HOST ||
current->comp.type == SOF_COMP_SG_HOST)
return false;
- /* check if the pipeline has a HOST comp upstream */
- list_for_item(clist, ¤t->bsource_list) {
struct comp_buffer *buffer;
buffer = container_of(clist, struct
comp_buffer, source_list);
I think it should be: buffer = container_of(clist, struct comp_buffer, sink_list);
Oh yes, Thanks Zhigang. The dangers of copy & paste :)
there is another location which has the similarly issue;
it should be: if (!is_hostless_upstream(buffer->source))
Thanks, again!
thanks ~zhigang
thanks ~zhigang
/* don't go upstream if this component is not
connected */
if (!buffer->connected)
continue;
/* dont go upstream if this comp belongs to
another pipeline */
if (buffer->source->comp.pipeline_id !=
current->comp.pipeline_id)
continue;
/* return if there is a host comp upstream */
if (!is_hostless_upstream(buffer->sink))
return false;
- }
- return true;
+}
- /*
*/
- Stream IPC Operations.
@@ -125,8 +191,14 @@ static int ipc_stream_pcm_params(uint32_t stream) cd = pcm_dev->cd; cd->params = pcm_params->params;
-#ifdef CONFIG_HOST_PTABLE
- /*
* walk in both directions to check if the pipeline is
hostless
* skip page table set up if it is
*/
- if (is_hostless_downstream(cd) &&
is_hostless_upstream(cd))
goto pipe_params;
+#ifdef CONFIG_HOST_PTABLE list_init(&elem_list);
/* use DMA to read in compressed page table
ringbuffer from host */ @@ -163,6 +235,8 @@ static int ipc_stream_pcm_params(uint32_t stream) } #endif
+pipe_params:
- /* configure pipeline audio params */ err = pipeline_params(pcm_dev->cd->pipeline,
pcm_dev->cd, pcm_params); if (err < 0) {
Sound-open-firmware mailing list Sound-open-firmware@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/sound-open-firmware
This patch adds the get() handler to respond to requests for the current tone state.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/audio/tone.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/src/audio/tone.c b/src/audio/tone.c index eee6091..d02e35f 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -462,6 +462,25 @@ static int tone_params(struct comp_dev *dev) return 0; }
+static int tone_cmd_get_value(struct comp_dev *dev, + struct sof_ipc_ctrl_data *cdata) +{ + struct comp_data *cd = comp_get_drvdata(dev); + int j; + + trace_tone("mgt"); + + if (cdata->cmd == SOF_CTRL_CMD_SWITCH) { + for (j = 0; j < cdata->num_elems; j++) { + cdata->chanv[j].channel = j; + cdata->chanv[j].value = !cd->sg[j].mute; + trace_value(j); + trace_value(cd->sg[j].mute); + } + } + return 0; +} + static int tone_cmd_set_value(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata) { struct comp_data *cd = comp_get_drvdata(dev); @@ -480,6 +499,7 @@ static int tone_cmd_set_value(struct comp_dev *dev, struct sof_ipc_ctrl_data *cd trace_tone_error("che"); return -EINVAL; } + if (val) tonegen_unmute(&cd->sg[ch]); else @@ -583,6 +603,9 @@ static int tone_cmd(struct comp_dev *dev, int cmd, void *data) case COMP_CMD_SET_VALUE: ret = tone_cmd_set_value(dev, cdata); break; + case COMP_CMD_GET_VALUE: + ret = tone_cmd_get_value(dev, cdata); + break; }
return ret;
Ignore pipeline_prepare() calls when the pipeline is running already. This is to prevent errors in the case of hostless pipelines when the user tries to enable the pipeline when it is already active.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/audio/pipeline.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index a59e4ea..f014aa5 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -382,6 +382,11 @@ static int component_op_downstream(struct op_data *op_data, op_data->cmd); break; case COMP_OPS_PREPARE: + + /* don't do prepare downstream if current is running */ + if (current->state == COMP_STATE_ACTIVE) + return 0; + /* prepare the component */ err = comp_prepare(current); break;
On Wed, 2018-06-13 at 20:29 -0700, Ranjani Sridharan wrote:
Ignore pipeline_prepare() calls when the pipeline is running already. This is to prevent errors in the case of hostless pipelines when the user tries to enable the pipeline when it is already active.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com
Could you explain how this can happen ? What action must the user take to do this ?
Thanks
Liam
On Thu, 2018-06-14 at 08:32 +0100, Liam Girdwood wrote:
On Wed, 2018-06-13 at 20:29 -0700, Ranjani Sridharan wrote:
Ignore pipeline_prepare() calls when the pipeline is running already. This is to prevent errors in the case of hostless pipelines when the user tries to enable the pipeline when it is already active.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com
Could you explain how this can happen ? What action must the user take to do this ?
Hi Liam,
This happens when the user sets the kcontrol value to ON repeatedly with amixer.
But, with xiuli's suggestion to fix the kcontrol IO, i think I can remove this. I will send you a v2 when I can make the tone audible on the up squared.
Thanks
Liam
On Thu, 2018-06-14 at 09:36 -0700, Ranjani Sridharan wrote:
Could you explain how this can happen ? What action must the user take to do this ?
Hi Liam,
This happens when the user sets the kcontrol value to ON repeatedly with amixer.
But, with xiuli's suggestion to fix the kcontrol IO, i think I can remove this. I will send you a v2 when I can make the tone audible on the up squared.
Would they not have to switch it OFF before they switch it on every time ?
The IPC reply should probably block until starting or stopping tone has completed (i.e. DMA has flushed last pipeline period).
Liam
Component should ignore repeated requests to set the same state and return with a value >0 so the state doesn't get propagated further down the pipeline.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/audio/component.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/src/audio/component.c b/src/audio/component.c index 319b401..8f8ddde 100644 --- a/src/audio/component.c +++ b/src/audio/component.c @@ -122,6 +122,15 @@ int comp_set_state(struct comp_dev *dev, int cmd)
switch (cmd) { case COMP_TRIGGER_START: + + /* + * No state change. + * Return a value >0 so the state won't be propagated further + */ + if (dev->state == COMP_STATE_ACTIVE) + return 1; + + /* Set new state */ if (dev->state == COMP_STATE_PREPARE || dev->state == COMP_STATE_PAUSED) { dev->state = COMP_STATE_ACTIVE; @@ -132,6 +141,7 @@ int comp_set_state(struct comp_dev *dev, int cmd) } break; case COMP_TRIGGER_RELEASE: + if (dev->state == COMP_STATE_PAUSED) { dev->state = COMP_STATE_ACTIVE; } else { @@ -142,6 +152,15 @@ int comp_set_state(struct comp_dev *dev, int cmd) break; case COMP_TRIGGER_STOP: case COMP_TRIGGER_XRUN: + + /* + * No state change. + * Return a value >0 so the state won't be propagated further + */ + if (dev->state == COMP_STATE_PREPARE) + return 1; + + /* set new state */ if (dev->state == COMP_STATE_ACTIVE) { dev->state = COMP_STATE_PREPARE; } else {
add sample_rate memeber in tone ipc comp def to read in the value from topology.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/include/uapi/ipc.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h index 8895ff3..b5e8d17 100644 --- a/src/include/uapi/ipc.h +++ b/src/include/uapi/ipc.h @@ -715,6 +715,7 @@ struct sof_ipc_comp_mux { struct sof_ipc_comp_tone { struct sof_ipc_comp comp; struct sof_ipc_comp_config config; + int32_t sample_rate; int32_t frequency; int32_t amplitude; int32_t freq_mult;
set the sample rate from the value set in topology.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- src/audio/tone.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/audio/tone.c b/src/audio/tone.c index d02e35f..eb060bd 100644 --- a/src/audio/tone.c +++ b/src/audio/tone.c @@ -422,6 +422,8 @@ static struct comp_dev *tone_new(struct sof_ipc_comp *comp) comp_set_drvdata(dev, cd); cd->tone_func = tone_s32_default;
+ cd->rate = ipc_tone->sample_rate; + /* Reset tone generator and set channels volumes to default */ for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) tonegen_reset(&cd->sg[i]); @@ -664,7 +666,6 @@ static int tone_prepare(struct comp_dev * dev) return ret;
cd->channels = dev->params.channels; - cd->rate = dev->params.rate; tracev_value(cd->channels); tracev_value(cd->rate);
participants (3)
-
Liam Girdwood
-
Ranjani Sridharan
-
zhigangw