[Sound-open-firmware] [PATCH 14/25] host: cleanup host_cmd() cases
Keyon Jie
yang.jie at linux.intel.com
Tue Feb 7 15:03:01 CET 2017
1. only pause at running stage;
2. resetting buffer pointers and local_elem for stopping, to let next
starting begin from original position;
3. adding processes for COMP_CMD_IPC_MMAP_WPOS and
COMP_CMD_AVAIL_UPDATE.
Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
---
src/audio/host.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 58 insertions(+), 4 deletions(-)
diff --git a/src/audio/host.c b/src/audio/host.c
index 8e13391..4b60943 100644
--- a/src/audio/host.c
+++ b/src/audio/host.c
@@ -43,6 +43,7 @@
#include <reef/wait.h>
#include <reef/audio/component.h>
#include <reef/audio/pipeline.h>
+#include <uapi/intel-ipc.h>
#include <platform/dma.h>
#define trace_host(__e) trace_event(TRACE_CLASS_HOST, __e)
@@ -651,22 +652,67 @@ static struct comp_dev* host_volume_component(struct comp_dev *host)
return comp_dev;
}
+static int host_stop(struct comp_dev *dev)
+{
+ struct host_data *hd = comp_get_drvdata(dev);
+ struct dma_sg_elem *source_elem, *sink_elem, *local_elem;
+
+ /* reset buffer pointers */
+ if (hd->host_pos)
+ *hd->host_pos = 0;
+ if (hd->host_app_pos)
+ *hd->host_app_pos = 0;
+ hd->host_pos_read = 0;
+ hd->host_period_pos = 0;
+ host_update_buffer_consume(hd);
+
+ /* reset buffer pointers and local_elem, to let next start
+ from original one */
+
+ /* setup elem to point to first source elem */
+ source_elem = list_first_item(&hd->source->elem_list,
+ struct dma_sg_elem, list);
+ hd->source->current = &source_elem->list;
+ hd->source->current_end = source_elem->src + source_elem->size;
+
+ /* setup elem to point to first sink elem */
+ sink_elem = list_first_item(&hd->sink->elem_list,
+ struct dma_sg_elem, list);
+ hd->sink->current = &sink_elem->list;
+ hd->sink->current_end = sink_elem->dest + sink_elem->size;
+
+ /* local element */
+ local_elem = list_first_item(&hd->config.elem_list,
+ struct dma_sg_elem, list);
+ local_elem->dest = sink_elem->dest;
+ local_elem->size = hd->period->size;
+ local_elem->src = source_elem->src;
+ hd->next_inc = hd->period->size;
+
+ dev->state = COMP_STATE_STOPPED;
+ return 0;
+}
+
/* used to pass standard and bespoke commands (with data) to component */
static int host_cmd(struct comp_dev *dev, int cmd, void *data)
{
struct host_data *hd = comp_get_drvdata(dev);
struct comp_dev *vol_dev = NULL;
+ struct ipc_intel_ipc_stream_set_position *app_pos;
int ret = 0;
// TODO: align cmd macros.
switch (cmd) {
case COMP_CMD_PAUSE:
- /* channel is paused by DAI */
- dev->state = COMP_STATE_PAUSED;
+ /* only support pausing for running, channel is paused by DAI */
+ if (dev->state == COMP_STATE_RUNNING)
+ dev->state = COMP_STATE_PAUSED;
break;
case COMP_CMD_STOP:
- /* stop any new DMA copies (let existing finish though) */
- dev->state = COMP_STATE_STOPPED;
+ if (dev->state == COMP_STATE_RUNNING ||
+ dev->state == COMP_STATE_DRAINING ||
+ dev->state == COMP_STATE_PAUSED)
+ ret = host_stop(dev);
break;
case COMP_CMD_RELEASE:
/* channel is released by DAI */
@@ -681,6 +727,14 @@ static int host_cmd(struct comp_dev *dev, int cmd, void *data)
case COMP_CMD_IPC_MMAP_RPOS:
hd->host_pos = data;
break;
+ case COMP_CMD_IPC_MMAP_WPOS:
+ hd->host_app_pos = data;
+ break;
+ case COMP_CMD_AVAIL_UPDATE:
+ app_pos = (struct ipc_intel_ipc_stream_set_position *)data;
+ *hd->host_app_pos = app_pos->position;
+ host_update_buffer_produce(hd);
+ break;
case COMP_CMD_VOLUME:
vol_dev = host_volume_component(dev);
if (vol_dev != NULL)
--
2.7.4
More information about the Sound-open-firmware
mailing list