summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZidan Wang <zidan.wang@freescale.com>2015-04-10 10:34:25 +0800
committerFrank Li <Frank.Li@freescale.com>2015-04-24 23:03:43 +0800
commitd70a9d9f4236f8bb5d4e6618ba8ffd66cac4f813 (patch)
tree55941571dfca27fcc71b66b3fd4a38bc0d929c03
parent3fccc2e9b5426c9dbdbb128c1c7a13c430188995 (diff)
MLK-10611-3 ASoC: imx-wm8960: forbid using SAI when SAI is being used by other device
imx7d-sdb board using one SAI for wm8960 and sii902x hdmi audio, wm8960 using SAI as slave mode and sii902x hdmi audio using SAI as master mode, so SAI can't be used at the same time. Forbid palyback(capture) when SAI is being used capture(playback) by other device. Signed-off-by: Zidan Wang <zidan.wang@freescale.com>
-rw-r--r--sound/soc/fsl/imx-wm8960.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sound/soc/fsl/imx-wm8960.c b/sound/soc/fsl/imx-wm8960.c
index 8eeeb98585b8..e77136ef7ee5 100644
--- a/sound/soc/fsl/imx-wm8960.c
+++ b/sound/soc/fsl/imx-wm8960.c
@@ -23,6 +23,7 @@
#include <sound/soc-dapm.h>
#include <linux/pinctrl/consumer.h>
#include "../codecs/wm8960.h"
+#include "fsl_sai.h"
#define DAI_NAME_SIZE 32
#define DEFAULT_MCLK_FREQ (12000000)
@@ -36,6 +37,7 @@ struct imx_wm8960_data {
unsigned int clk_frequency;
bool is_codec_master;
bool is_stream_in_use[2];
+ bool is_stream_opened[2];
};
struct imx_priv {
@@ -199,9 +201,44 @@ static int imx_hifi_hw_free(struct snd_pcm_substream *substream)
return 0;
}
+static int imx_hifi_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = codec_dai->codec->card;
+ struct imx_wm8960_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
+ int ret = 0;
+
+ data->is_stream_opened[tx] = true;
+ if (data->is_stream_opened[tx] != sai->is_stream_opened[tx] ||
+ data->is_stream_opened[!tx] != sai->is_stream_opened[!tx]) {
+ data->is_stream_opened[tx] = false;
+ return -EBUSY;
+ }
+
+ return ret;
+}
+
+
+static void imx_hifi_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_card *card = codec_dai->codec->card;
+ struct imx_wm8960_data *data = snd_soc_card_get_drvdata(card);
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+
+ data->is_stream_opened[tx] = false;
+}
+
static struct snd_soc_ops imx_hifi_ops = {
.hw_params = imx_hifi_hw_params,
.hw_free = imx_hifi_hw_free,
+ .startup = imx_hifi_startup,
+ .shutdown = imx_hifi_shutdown,
};
static const struct snd_soc_dapm_route imx_wm8960_dapm_route[] = {