summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/fsl_sai.c
diff options
context:
space:
mode:
authorNicolin Chen <Guangyu.Chen@freescale.com>2014-08-05 07:32:05 (GMT)
committerMark Brown <broonie@linaro.org>2014-08-16 22:06:23 (GMT)
commit08fdf65e37d560581233e06a659f73deeb3766f9 (patch)
treebc00286a0de8e4acaf70a62beb01b83723ad1f3c /sound/soc/fsl/fsl_sai.c
parentaf96ff5b7448dc776dc24a5c4313c6ec1ee94e53 (diff)
downloadlinux-08fdf65e37d560581233e06a659f73deeb3766f9.tar.xz
ASoC: fsl_sai: Add asynchronous mode support
SAI supports these operation modes: 1) asynchronous mode Both Tx and Rx are set to be asynchronous. 2) synchronous mode (Rx sync with Tx) Tx is set to be asynchronous, Rx is set to be synchronous. 3) synchronous mode (Tx sync with Rx) Rx is set to be asynchronous, Tx is set to be synchronous. 4) synchronous mode (Tx/Rx sync with another SAI's Tx) 5) synchronous mode (Tx/Rx sync with another SAI's Rx) * 4) and 5) are beyond this patch because they are related with another SAI. As the initial version of this SAI driver, it supported 2) as default while the others were totally missing. So this patch just adds supports for 1) and 3). Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/fsl/fsl_sai.c')
-rw-r--r--sound/soc/fsl/fsl_sai.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 3d865ad..ef7c758 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -330,12 +330,14 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
u32 xcsr, count = 100;
/*
- * The transmitter bit clock and frame sync are to be
- * used by both the transmitter and receiver.
+ * Asynchronous mode: Clear SYNC for both Tx and Rx.
+ * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
+ * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
*/
- regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 0);
+ regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
+ sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
- FSL_SAI_CR2_SYNC);
+ sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
/*
* It is recommended that the transmitter is the last enabled
@@ -625,6 +627,26 @@ static int fsl_sai_probe(struct platform_device *pdev)
return ret;
}
+ /* Sync Tx with Rx as default by following old DT binding */
+ sai->synchronous[RX] = true;
+ sai->synchronous[TX] = false;
+ fsl_sai_dai.symmetric_rates = 1;
+ fsl_sai_dai.symmetric_channels = 1;
+ fsl_sai_dai.symmetric_samplebits = 1;
+
+ if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) {
+ /* Sync Rx with Tx */
+ sai->synchronous[RX] = false;
+ sai->synchronous[TX] = true;
+ } else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) {
+ /* Discard all settings for asynchronous mode */
+ sai->synchronous[RX] = false;
+ sai->synchronous[TX] = false;
+ fsl_sai_dai.symmetric_rates = 0;
+ fsl_sai_dai.symmetric_channels = 0;
+ fsl_sai_dai.symmetric_samplebits = 0;
+ }
+
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;