[Sound-open-firmware] [PATCH] dai: cleanup dai component status

Keyon Jie yang.jie at linux.intel.com
Mon Oct 24 04:42:48 CEST 2016


Only use 4 states for dai component:
init, prepare, runing, paused.

Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
---
 src/audio/dai.c | 108 ++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 69 insertions(+), 39 deletions(-)

diff --git a/src/audio/dai.c b/src/audio/dai.c
index 6b2c83b..afa1be1 100644
--- a/src/audio/dai.c
+++ b/src/audio/dai.c
@@ -217,20 +217,22 @@ static int dai_playback_params(struct comp_dev *dev,
 	dma_period_desc = &dma_buffer->desc.sink_period;
 	dma_buffer->params = *params;
 
-	/* set up cyclic list of DMA elems */
-	for (i = 0; i < dma_period_desc->number; i++) {
+	if (list_is_empty(&config->elem_list)) {
+		/* set up cyclic list of DMA elems */
+		for (i = 0; i < dma_period_desc->number; i++) {
 
-		elem = rzalloc(RZONE_MODULE, RMOD_SYS, sizeof(*elem));
-		if (elem == NULL)
-			goto err_unwind;
+			elem = rzalloc(RZONE_MODULE, RMOD_SYS, sizeof(*elem));
+			if (elem == NULL)
+				goto err_unwind;
 
-		elem->size = dma_period_desc->size;
-		elem->src = (uint32_t)(dma_buffer->r_ptr) +
-			i * dma_period_desc->size;
+			elem->size = dma_period_desc->size;
+			elem->src = (uint32_t)(dma_buffer->r_ptr) +
+				i * dma_period_desc->size;
 
-		elem->dest = dai_fifo(dd->ssp, params->direction);
+			elem->dest = dai_fifo(dd->ssp, params->direction);
 
-		list_item_append(&elem->list, &config->elem_list);
+			list_item_append(&elem->list, &config->elem_list);
+		}
 	}
 
 	/* set write pointer to start of buffer */
@@ -273,18 +275,20 @@ static int dai_capture_params(struct comp_dev *dev,
 	dma_period_desc = &dma_buffer->desc.source_period;
 	dma_buffer->params = *params;
 
-	/* set up cyclic list of DMA elems */
-	for (i = 0; i < dma_period_desc->number; i++) {
+	if (list_is_empty(&config->elem_list)) {
+		/* set up cyclic list of DMA elems */
+		for (i = 0; i < dma_period_desc->number; i++) {
 
-		elem = rzalloc(RZONE_MODULE, RMOD_SYS, sizeof(*elem));
-		if (elem == NULL)
-			goto err_unwind;
+			elem = rzalloc(RZONE_MODULE, RMOD_SYS, sizeof(*elem));
+			if (elem == NULL)
+				goto err_unwind;
 
-		elem->size = dma_period_desc->size;
-		elem->dest = (uint32_t)(dma_buffer->w_ptr) +
-			i * dma_period_desc->size;
-		elem->src = dai_fifo(dd->ssp, params->direction);
-		list_item_append(&elem->list, &config->elem_list);
+			elem->size = dma_period_desc->size;
+			elem->dest = (uint32_t)(dma_buffer->w_ptr) +
+				i * dma_period_desc->size;
+			elem->src = dai_fifo(dd->ssp, params->direction);
+			list_item_append(&elem->list, &config->elem_list);
+		}
 	}
 
 	/* set write pointer to start of buffer */
@@ -306,6 +310,11 @@ static int dai_params(struct comp_dev *dev,
 {
 	struct comp_buffer *dma_buffer;
 
+	/* can set params on only init state */
+	if (dev->state != COMP_STATE_INIT) {
+		trace_dai_error("wdp");
+		return -EINVAL;
+	}
 	if (params->direction == STREAM_DIRECTION_PLAYBACK) {
 		dma_buffer = list_first_item(&dev->bsource_list,
 			struct comp_buffer, sink_list);
@@ -323,14 +332,22 @@ static int dai_params(struct comp_dev *dev,
 
 static int dai_prepare(struct comp_dev *dev)
 {
+	int ret = 0;
 	struct dai_data *dd = comp_get_drvdata(dev);
 
+	if (list_is_empty(&dd->config.elem_list)) {
+		trace_dai_error("wdm");
+		return -EINVAL;
+	}
+
 	dd->dai_pos_blks = 0;
 
 	if (dd->dai_pos)
 		*dd->dai_pos = 0;
 
-	return dma_set_config(dd->dma, dd->chan, &dd->config);
+	ret = dma_set_config(dd->dma, dd->chan, &dd->config);
+	dev->state = COMP_STATE_PREPARE;
+	return ret;
 }
 
 static int dai_reset(struct comp_dev *dev)
@@ -364,30 +381,43 @@ static int dai_cmd(struct comp_dev *dev, int cmd, void *data)
 	switch (cmd) {
 
 	case COMP_CMD_PAUSE:
-		dma_pause(dd->dma, dd->chan);
-		dai_trigger(dd->ssp, cmd, dd->direction);
-		dev->state = COMP_STATE_PAUSED;
+		if (dev->state == COMP_STATE_RUNNING) {
+			dma_pause(dd->dma, dd->chan);
+			dai_trigger(dd->ssp, cmd, dd->direction);
+			dev->state = COMP_STATE_PAUSED;
+		}
 		break;
 	case COMP_CMD_STOP:
-		if (dev->state == COMP_STATE_RUNNING)
-			dma_stop(dd->dma, dd->chan, 1);
-		else if (dev->state == COMP_STATE_PAUSED)
-			dma_stop(dd->dma, dd->chan, 0);
-
-		dai_trigger(dd->ssp, cmd, dd->direction);
-		dev->state = COMP_STATE_STOPPED;
+		switch (dev->state) {
+		case COMP_STATE_RUNNING:
+		case COMP_STATE_PAUSED:
+			dma_stop(dd->dma, dd->chan,
+				dev->state == COMP_STATE_RUNNING ? 1 : 0);
+			/* need stop ssp */
+			dai_trigger(dd->ssp, cmd, dd->direction);
+		/* go through */
+		case COMP_STATE_PREPARE:
+			dev->state = COMP_STATE_INIT;
+			break;
+		}
 		break;
 	case COMP_CMD_RELEASE:
-		dai_trigger(dd->ssp, cmd, dd->direction);
-		dma_release(dd->dma, dd->chan);
-		dev->state = COMP_STATE_RUNNING;
+		/* only release from paused*/
+		if (dev->state == COMP_STATE_PAUSED) {
+			dai_trigger(dd->ssp, cmd, dd->direction);
+			dma_release(dd->dma, dd->chan);
+			dev->state = COMP_STATE_RUNNING;
+		}
 		break;
 	case COMP_CMD_START:
-		ret = dma_start(dd->dma, dd->chan);
-		if (ret < 0)
-			return ret;
-		dai_trigger(dd->ssp, cmd, dd->direction);
-		dev->state = COMP_STATE_RUNNING;
+		/* only start from prepared*/
+		if (dev->state == COMP_STATE_PREPARE) {
+			ret = dma_start(dd->dma, dd->chan);
+			if (ret < 0)
+				return ret;
+			dai_trigger(dd->ssp, cmd, dd->direction);
+			dev->state = COMP_STATE_RUNNING;
+		}
 		break;
 	case COMP_CMD_SUSPEND:
 	case COMP_CMD_RESUME:
-- 
2.5.0



More information about the Sound-open-firmware mailing list