diff options
author | Fabio Estevam <fabio.estevam@nxp.com> | 2016-05-04 18:33:59 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-05-05 11:44:22 -0400 |
commit | 4d2458507d0b465c62ae80f3e81b8c008ec96b05 (patch) | |
tree | 8cee8aa3c236270a174063cc5cdd95f8a94808fc | |
parent | 1593af62b694b3638edf577e3b763fa1a4ca3d76 (diff) |
ASoC: fsl_sai: Allow setting the SAI MCLK direction
On mx6ul the General Purpose Register 1 (GPR1) contains the following
bits for configuring the direction of the SAI MCLKs:
SAI1_MCLK_DIR, SAI2_MCLK_DIR, SAI3_MCLK_DIR
Introduce the "fsl,sai-mclk-direction-output" optional property to allow
configuring the SAI_MCLK outputs.
Tested on a imx6ul-evk board.
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | Documentation/devicetree/bindings/sound/fsl-sai.txt | 5 | ||||
-rw-r--r-- | include/linux/mfd/syscon/imx6q-iomuxc-gpr.h | 6 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 20 |
3 files changed, 31 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 777b941d6cbe..740b467adf7d 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt | |||
@@ -48,6 +48,11 @@ Required properties: | |||
48 | receive data by following their own bit clocks and | 48 | receive data by following their own bit clocks and |
49 | frame sync clocks separately. | 49 | frame sync clocks separately. |
50 | 50 | ||
51 | Optional properties (for mx6ul): | ||
52 | |||
53 | - fsl,sai-mclk-direction-output: This is a boolean property. If present, | ||
54 | indicates that SAI will output the SAI MCLK clock. | ||
55 | |||
51 | Note: | 56 | Note: |
52 | - If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the | 57 | - If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the |
53 | default synchronous mode (sync Rx with Tx) will be used, which means both | 58 | default synchronous mode (sync Rx with Tx) will be used, which means both |
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h index 238c8db953eb..68353822afce 100644 --- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h +++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h | |||
@@ -447,5 +447,11 @@ | |||
447 | #define IMX6UL_GPR1_ENET2_CLK_OUTPUT (0x1 << 18) | 447 | #define IMX6UL_GPR1_ENET2_CLK_OUTPUT (0x1 << 18) |
448 | #define IMX6UL_GPR1_ENET_CLK_DIR (0x3 << 17) | 448 | #define IMX6UL_GPR1_ENET_CLK_DIR (0x3 << 17) |
449 | #define IMX6UL_GPR1_ENET_CLK_OUTPUT (0x3 << 17) | 449 | #define IMX6UL_GPR1_ENET_CLK_OUTPUT (0x3 << 17) |
450 | #define IMX6UL_GPR1_SAI1_MCLK_DIR (0x1 << 19) | ||
451 | #define IMX6UL_GPR1_SAI2_MCLK_DIR (0x1 << 20) | ||
452 | #define IMX6UL_GPR1_SAI3_MCLK_DIR (0x1 << 21) | ||
453 | #define IMX6UL_GPR1_SAI_MCLK_MASK (0x7 << 19) | ||
454 | #define MCLK_DIR(x) (x == 1 ? IMX6UL_GPR1_SAI1_MCLK_DIR : x == 2 ? \ | ||
455 | IMX6UL_GPR1_SAI2_MCLK_DIR : IMX6UL_GPR1_SAI3_MCLK_DIR) | ||
450 | 456 | ||
451 | #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ | 457 | #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ |
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index d8b673f7c577..2147994ab46f 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <sound/core.h> | 21 | #include <sound/core.h> |
22 | #include <sound/dmaengine_pcm.h> | 22 | #include <sound/dmaengine_pcm.h> |
23 | #include <sound/pcm_params.h> | 23 | #include <sound/pcm_params.h> |
24 | #include <linux/mfd/syscon.h> | ||
25 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | ||
24 | 26 | ||
25 | #include "fsl_sai.h" | 27 | #include "fsl_sai.h" |
26 | #include "imx-pcm.h" | 28 | #include "imx-pcm.h" |
@@ -786,10 +788,12 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
786 | { | 788 | { |
787 | struct device_node *np = pdev->dev.of_node; | 789 | struct device_node *np = pdev->dev.of_node; |
788 | struct fsl_sai *sai; | 790 | struct fsl_sai *sai; |
791 | struct regmap *gpr; | ||
789 | struct resource *res; | 792 | struct resource *res; |
790 | void __iomem *base; | 793 | void __iomem *base; |
791 | char tmp[8]; | 794 | char tmp[8]; |
792 | int irq, ret, i; | 795 | int irq, ret, i; |
796 | int index; | ||
793 | 797 | ||
794 | sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); | 798 | sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); |
795 | if (!sai) | 799 | if (!sai) |
@@ -878,6 +882,22 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
878 | fsl_sai_dai.symmetric_samplebits = 0; | 882 | fsl_sai_dai.symmetric_samplebits = 0; |
879 | } | 883 | } |
880 | 884 | ||
885 | if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && | ||
886 | of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) { | ||
887 | gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); | ||
888 | if (IS_ERR(gpr)) { | ||
889 | dev_err(&pdev->dev, "cannot find iomuxc registers\n"); | ||
890 | return PTR_ERR(gpr); | ||
891 | } | ||
892 | |||
893 | index = of_alias_get_id(np, "sai"); | ||
894 | if (index < 0) | ||
895 | return index; | ||
896 | |||
897 | regmap_update_bits(gpr, IOMUXC_GPR1, MCLK_DIR(index), | ||
898 | MCLK_DIR(index)); | ||
899 | } | ||
900 | |||
881 | sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; | 901 | sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; |
882 | sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; | 902 | sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; |
883 | sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; | 903 | sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; |