diff --git a/src/audio/dai.c b/src/audio/dai.c index ac6abe23d20a..fcf16c38766f 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -613,7 +613,7 @@ static int dai_comp_trigger(struct comp_dev *dev, int cmd) case COMP_TRIGGER_STOP: comp_info(dev, "dai_comp_trigger(), PAUSE/STOP"); ret = dma_stop(dd->chan); - dai_trigger(dd->dai, COMP_TRIGGER_STOP, dev->direction); + dai_trigger(dd->dai, cmd, dev->direction); break; default: break; diff --git a/src/drivers/intel/baytrail/ssp.c b/src/drivers/intel/baytrail/ssp.c index cf98c532cf77..b1efc197a0e1 100644 --- a/src/drivers/intel/baytrail/ssp.c +++ b/src/drivers/intel/baytrail/ssp.c @@ -543,33 +543,43 @@ static void ssp_stop(struct dai *dai, int direction) /* stop Rx if neeed */ if (direction == DAI_DIR_CAPTURE && - ssp->state[SOF_IPC_STREAM_CAPTURE] == COMP_STATE_ACTIVE) { + ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_PREPARE) { ssp_update_bits(dai, SSCR1, SSCR1_RSRE, 0); ssp_empty_rx_fifo(dai); - ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PAUSED; + ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PREPARE; dai_info(dai, "ssp_stop(), RX stop"); } /* stop Tx if needed */ if (direction == DAI_DIR_PLAYBACK && - ssp->state[SOF_IPC_STREAM_PLAYBACK] == COMP_STATE_ACTIVE) { + ssp->state[SOF_IPC_STREAM_PLAYBACK] != COMP_STATE_PREPARE) { ssp_update_bits(dai, SSCR1, SSCR1_TSRE, 0); - ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PAUSED; + ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PREPARE; dai_info(dai, "ssp_stop(), TX stop"); } /* disable SSP port if no users */ - if (ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_ACTIVE && - ssp->state[SOF_IPC_STREAM_PLAYBACK] != COMP_STATE_ACTIVE) { + if (ssp->state[SOF_IPC_STREAM_CAPTURE] == COMP_STATE_PREPARE && + ssp->state[SOF_IPC_STREAM_PLAYBACK] == COMP_STATE_PREPARE) { ssp_update_bits(dai, SSCR0, SSCR0_SSE, 0); - ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PREPARE; - ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PREPARE; dai_info(dai, "ssp_stop(), SSP port disabled"); } spin_unlock(&dai->lock); } +static void ssp_pause(struct dai *dai, int direction) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + + if (direction == SOF_IPC_STREAM_CAPTURE) + dai_info(dai, "ssp_pause(), RX"); + else + dai_info(dai, "ssp_pause(), TX"); + + ssp->state[direction] = COMP_STATE_PAUSED; +} + static int ssp_trigger(struct dai *dai, int cmd, int direction) { struct ssp_pdata *ssp = dai_get_drvdata(dai); @@ -588,9 +598,11 @@ static int ssp_trigger(struct dai *dai, int cmd, int direction) ssp_start(dai, direction); break; case COMP_TRIGGER_STOP: - case COMP_TRIGGER_PAUSE: ssp_stop(dai, direction); break; + case COMP_TRIGGER_PAUSE: + ssp_pause(dai, direction); + break; case COMP_TRIGGER_RESUME: ssp_context_restore(dai); break; diff --git a/src/drivers/intel/cavs/ssp.c b/src/drivers/intel/cavs/ssp.c index 494fdbe699ba..da0328febef2 100644 --- a/src/drivers/intel/cavs/ssp.c +++ b/src/drivers/intel/cavs/ssp.c @@ -697,36 +697,46 @@ static void ssp_stop(struct dai *dai, int direction) /* stop Rx if neeed */ if (direction == DAI_DIR_CAPTURE && - ssp->state[SOF_IPC_STREAM_CAPTURE] == COMP_STATE_ACTIVE) { + ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_PREPARE) { ssp_update_bits(dai, SSCR1, SSCR1_RSRE, 0); ssp_update_bits(dai, SSRSA, SSRSA_RXEN, 0); ssp_empty_rx_fifo(dai); - ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PAUSED; + ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PREPARE; dai_info(dai, "ssp_stop(), RX stop"); } /* stop Tx if needed */ if (direction == DAI_DIR_PLAYBACK && - ssp->state[SOF_IPC_STREAM_PLAYBACK] == COMP_STATE_ACTIVE) { + ssp->state[SOF_IPC_STREAM_PLAYBACK] != COMP_STATE_PREPARE) { ssp_empty_tx_fifo(dai); ssp_update_bits(dai, SSCR1, SSCR1_TSRE, 0); ssp_update_bits(dai, SSTSA, SSTSA_TXEN, 0); - ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PAUSED; + ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PREPARE; dai_info(dai, "ssp_stop(), TX stop"); } /* disable SSP port if no users */ - if (ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_ACTIVE && - ssp->state[SOF_IPC_STREAM_PLAYBACK] != COMP_STATE_ACTIVE) { + if (ssp->state[SOF_IPC_STREAM_CAPTURE] == COMP_STATE_PREPARE && + ssp->state[SOF_IPC_STREAM_PLAYBACK] == COMP_STATE_PREPARE) { ssp_update_bits(dai, SSCR0, SSCR0_SSE, 0); - ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PREPARE; - ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PREPARE; dai_info(dai, "ssp_stop(), SSP port disabled"); } spin_unlock(&dai->lock); } +static void ssp_pause(struct dai *dai, int direction) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + + if (direction == SOF_IPC_STREAM_CAPTURE) + dai_info(dai, "ssp_pause(), RX"); + else + dai_info(dai, "ssp_pause(), TX"); + + ssp->state[direction] = COMP_STATE_PAUSED; +} + static int ssp_trigger(struct dai *dai, int cmd, int direction) { struct ssp_pdata *ssp = dai_get_drvdata(dai); @@ -745,9 +755,11 @@ static int ssp_trigger(struct dai *dai, int cmd, int direction) ssp_start(dai, direction); break; case COMP_TRIGGER_STOP: - case COMP_TRIGGER_PAUSE: ssp_stop(dai, direction); break; + case COMP_TRIGGER_PAUSE: + ssp_pause(dai, direction); + break; case COMP_TRIGGER_RESUME: ssp_context_restore(dai); break; diff --git a/src/drivers/intel/haswell/ssp.c b/src/drivers/intel/haswell/ssp.c index 6218ae0a363a..936903befc54 100644 --- a/src/drivers/intel/haswell/ssp.c +++ b/src/drivers/intel/haswell/ssp.c @@ -459,34 +459,44 @@ static void ssp_stop(struct dai *dai, int direction) /* stop Rx if neeed */ if (direction == DAI_DIR_CAPTURE && - ssp->state[SOF_IPC_STREAM_CAPTURE] == COMP_STATE_ACTIVE) { + ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_PREPARE) { ssp_update_bits(dai, SSCR1, SSCR1_RSRE, 0); ssp_update_bits(dai, SSCR0, SSCR0_RIM, SSCR0_RIM); - ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PAUSED; + ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PREPARE; dai_info(dai, "ssp_stop(), RX stop"); } /* stop Tx if needed */ if (direction == DAI_DIR_PLAYBACK && - ssp->state[SOF_IPC_STREAM_PLAYBACK] == COMP_STATE_ACTIVE) { + ssp->state[SOF_IPC_STREAM_PLAYBACK] != COMP_STATE_PREPARE) { ssp_update_bits(dai, SSCR1, SSCR1_TSRE, 0); ssp_update_bits(dai, SSCR0, SSCR0_TIM, SSCR0_TIM); - ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PAUSED; + ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PREPARE; dai_info(dai, "ssp_stop(), TX stop"); } /* disable SSP port if no users */ - if (ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_ACTIVE && - ssp->state[SOF_IPC_STREAM_PLAYBACK] != COMP_STATE_ACTIVE) { + if (ssp->state[SOF_IPC_STREAM_CAPTURE] == COMP_STATE_PREPARE && + ssp->state[SOF_IPC_STREAM_PLAYBACK] == COMP_STATE_PREPARE) { ssp_update_bits(dai, SSCR0, SSCR0_SSE, 0); - ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PREPARE; - ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PREPARE; dai_info(dai, "ssp_stop(), SSP port disabled"); } spin_unlock(&dai->lock); } +static void ssp_pause(struct dai *dai, int direction) +{ + struct ssp_pdata *ssp = dai_get_drvdata(dai); + + if (direction == SOF_IPC_STREAM_CAPTURE) + dai_info(dai, "ssp_pause(), RX"); + else + dai_info(dai, "ssp_pause(), TX"); + + ssp->state[direction] = COMP_STATE_PAUSED; +} + static int ssp_trigger(struct dai *dai, int cmd, int direction) { struct ssp_pdata *ssp = dai_get_drvdata(dai); @@ -505,9 +515,11 @@ static int ssp_trigger(struct dai *dai, int cmd, int direction) ssp_start(dai, direction); break; case COMP_TRIGGER_STOP: - case COMP_TRIGGER_PAUSE: ssp_stop(dai, direction); break; + case COMP_TRIGGER_PAUSE: + ssp_pause(dai, direction); + break; case COMP_TRIGGER_RESUME: ssp_context_restore(dai); break;