diff mbox

ASoC: fsl_sai: Independent TX and RX master slave configuration

Message ID CAC3a_SDR97j8q7wS8up_qpNZOc3Mc0yiWanXF808-ud0_fGxRQ@mail.gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vishal Thanki Jan. 4, 2017, 3:54 p.m. UTC
Hi All,

I am working on a custom board based on i.MX7d SoC from NXP. The
hardware uses SAI (Synchronous Audio Interface) Port 1 of i.MX7d for
playback and recording use cases. The required system configuration
is: SoC should act as I2S master for TX part, and slave for RX part.
However, I could not figure out a clean way to instruct CPU dai driver
(sound/soc/fsl/fsl_sai.c) about different roles for TX and RX of a
same DAI. The .set_fmt DAI op configures the TX and RX registers in
the same manner. In order to achieve the required configuration (TX
master, RX slave), I added a device tree property (i.e.
"fsl,sai-is-rx-slave") and based on that make necessary changes in
.set_fmt DAI operation. Attached is the patch for the same. Is this
the right way to go? Any suggestions would be helpful.

Thanks in advance,
Vishal
diff mbox

Patch

From 7abc0f42a3058641ed5a6c9fee8a602cb92c5959 Mon Sep 17 00:00:00 2001
From: Vishal Thanki <vishalthanki@gmail.com>
Date: Wed, 4 Jan 2017 16:50:36 +0100
Subject: [PATCH] fsl_sai: Adjust SAI RX configuration

If SAI TX and SAI RX are required to operate independently,
the clock settings (BCLK and WSYNC) need to be adjusted
accordingly. This patch adjust RX settings based on a device
tree properly value.

Signed-off-by: Vishal Thanki <vishalthanki@gmail.com>
---
 sound/soc/fsl/fsl_sai.c | 17 ++++++++++++++---
 sound/soc/fsl/fsl_sai.h |  1 +
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 9fadf7e..fd2aee7 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -289,6 +289,11 @@  static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
 		return -EINVAL;
 	}
 
+	if (!tx && sai->is_rx_slave) {
+		val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR;
+		val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
+	}
+
 	regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
 			   FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);
 	regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
@@ -419,7 +424,7 @@  static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
 	if (sai->slot_width)
 		slot_width = sai->slot_width;
 
-	if (!sai->is_slave_mode) {
+	if (!sai->is_slave_mode && (tx || !sai->is_rx_slave)) {
 		ret = fsl_sai_set_bclk(cpu_dai, tx,
 				slots * slot_width * params_rate(params));
 		if (ret)
@@ -532,8 +537,9 @@  static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
 		regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
 				   FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
 
-		regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
-				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+		if (!tx)
+			regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
+					FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
 		regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
 				   FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
 
@@ -898,6 +904,11 @@  static int fsl_sai_probe(struct platform_device *pdev)
 				   MCLK_DIR(index));
 	}
 
+	if (of_find_property(np, "fsl,sai-is-rx-slave", NULL))
+		sai->is_rx_slave = true;
+	else
+		sai->is_rx_slave = false;
+
 	sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
 	sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
 	sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index d9ed7be..0fefd52 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -138,6 +138,7 @@  struct fsl_sai {
 	bool is_slave_mode;
 	bool is_lsb_first;
 	bool is_dsp_mode;
+	bool is_rx_slave;
 	bool sai_on_imx;
 	bool synchronous[2];
 
-- 
2.4.11