Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78575960 authored by Bhalchandra Gajare's avatar Bhalchandra Gajare
Browse files

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: default avatarBhalchandra Gajare <gajare@codeaurora.org>
parent 2f49086b
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
/*
 * 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
+16 −5
Original line number Diff line number Diff line
/*
 * 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
@@ -368,6 +368,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);
@@ -375,11 +383,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;

	/*
@@ -591,7 +601,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);
+22 −7
Original line number Diff line number Diff line
/*
 * 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;