ASoC: msm-cpe: Fix sequence for data channel teardown
The data channel for buffering has two endpoints, one on the MSM and another on the codec. When codec endpoint is torn down, it waits for an interrupt for channel teardown from hardware. But, since MSM endpoint is still connected, the interrupt is never receieved and the codec wait gets timed out. This adds delay in data channel teardown. Fix this issue by making sure the MSM endpoint is torn down first and then the codec endpoint gets torn down. CRs-fixed: 940132 Change-Id: Ie6529e9269aa29fb3d312b816c3d83e9e3e6e10e Signed-off-by: Bhalchandra Gajare <gajare@codeaurora.org>
This commit is contained in:
parent
b9d096ab5e
commit
7a75d9ed2a
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014,2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -16,6 +16,12 @@
|
|||
|
||||
#include <linux/slimbus/slimbus.h>
|
||||
|
||||
enum msm_dai_slim_event {
|
||||
MSM_DAI_SLIM_ENABLE = 1,
|
||||
MSM_DAI_SLIM_PRE_DISABLE,
|
||||
MSM_DAI_SLIM_DISABLE,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct msm_slim_dma_data - DMA data for slimbus data transfer
|
||||
*
|
||||
|
@ -38,7 +44,8 @@ struct msm_slim_dma_data {
|
|||
|
||||
/* Callback for data channel control */
|
||||
int (*dai_channel_ctl) (struct msm_slim_dma_data *dma_data,
|
||||
struct snd_soc_dai *dai, bool enable);
|
||||
struct snd_soc_dai *dai,
|
||||
enum msm_dai_slim_event event);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -392,6 +392,14 @@ static int msm_cpe_lsm_lab_stop(struct snd_pcm_substream *substream)
|
|||
}
|
||||
}
|
||||
|
||||
rc = dma_data->dai_channel_ctl(dma_data, rtd->cpu_dai,
|
||||
MSM_DAI_SLIM_PRE_DISABLE);
|
||||
if (rc)
|
||||
dev_err(rtd->dev,
|
||||
"%s: PRE_DISABLE failed, err = %d\n",
|
||||
__func__, rc);
|
||||
|
||||
/* continue with teardown even if any intermediate step fails */
|
||||
rc = lsm_ops->lab_ch_setup(cpe->core_handle,
|
||||
session,
|
||||
WCD_CPE_PRE_DISABLE);
|
||||
|
@ -399,11 +407,13 @@ static int msm_cpe_lsm_lab_stop(struct snd_pcm_substream *substream)
|
|||
dev_err(rtd->dev,
|
||||
"%s: PRE ch teardown failed, err = %d\n",
|
||||
__func__, rc);
|
||||
/* continue with teardown even if any intermediate step fails */
|
||||
rc = dma_data->dai_channel_ctl(dma_data, rtd->cpu_dai, false);
|
||||
|
||||
rc = dma_data->dai_channel_ctl(dma_data, rtd->cpu_dai,
|
||||
MSM_DAI_SLIM_DISABLE);
|
||||
if (rc)
|
||||
dev_err(rtd->dev,
|
||||
"%s: open data failed %d\n", __func__, rc);
|
||||
"%s: DISABLE failed, err = %d\n",
|
||||
__func__, rc);
|
||||
dma_data->ph = 0;
|
||||
|
||||
/*
|
||||
|
@ -616,7 +626,8 @@ static int msm_cpe_lab_thread(void *data)
|
|||
goto done;
|
||||
}
|
||||
|
||||
rc = dma_data->dai_channel_ctl(dma_data, rtd->cpu_dai, true);
|
||||
rc = dma_data->dai_channel_ctl(dma_data, rtd->cpu_dai,
|
||||
MSM_DAI_SLIM_ENABLE);
|
||||
if (rc) {
|
||||
dev_err(rtd->dev,
|
||||
"%s: open data failed %d\n", __func__, rc);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -89,7 +89,8 @@ struct msm_slim_dai_data *msm_slim_get_dai_data(
|
|||
}
|
||||
|
||||
static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data,
|
||||
struct snd_soc_dai *dai, bool enable)
|
||||
struct snd_soc_dai *dai,
|
||||
enum msm_dai_slim_event event)
|
||||
{
|
||||
struct slim_device *sdev;
|
||||
struct msm_dai_slim_drv_data *drv_data;
|
||||
|
@ -114,11 +115,12 @@ static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data,
|
|||
}
|
||||
|
||||
dev_dbg(&sdev->dev,
|
||||
"%s: enable = %s, rate = %u\n", __func__,
|
||||
enable ? "true" : "false",
|
||||
dai_data->rate);
|
||||
"%s: event = 0x%x, rate = %u\n", __func__,
|
||||
event, dai_data->rate);
|
||||
|
||||
switch (event) {
|
||||
case MSM_DAI_SLIM_ENABLE:
|
||||
|
||||
if (enable) {
|
||||
if (!(dai_data->status & DAI_STATE_PREPARED)) {
|
||||
dev_err(&sdev->dev,
|
||||
"%s: dai id (%d) has invalid state 0x%x\n",
|
||||
|
@ -171,7 +173,9 @@ static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data,
|
|||
}
|
||||
/* Mark dai status as running */
|
||||
SET_DAI_STATE(dai_data->status, DAI_STATE_RUNNING);
|
||||
} else {
|
||||
break;
|
||||
|
||||
case MSM_DAI_SLIM_PRE_DISABLE:
|
||||
if (!(dai_data->status & DAI_STATE_RUNNING)) {
|
||||
dev_err(&sdev->dev,
|
||||
"%s: dai id (%d) has invalid state 0x%x\n",
|
||||
|
@ -188,6 +192,9 @@ static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data,
|
|||
__func__, rc);
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSM_DAI_SLIM_DISABLE:
|
||||
|
||||
rc = slim_dealloc_mgrports(sdev,
|
||||
&dma_data->ph, 1);
|
||||
|
@ -199,6 +206,14 @@ static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data,
|
|||
}
|
||||
/* clear running state for dai*/
|
||||
CLR_DAI_STATE(dai_data->status, DAI_STATE_RUNNING);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(&sdev->dev,
|
||||
"%s: Unhandled event 0x%x\n",
|
||||
__func__, event);
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
Loading…
Reference in New Issue