ASoC: fsl_sai: Allow setting the SAI MCLK direction
authorFabio Estevam <fabio.estevam@nxp.com>
Wed, 4 May 2016 22:33:59 +0000 (19:33 -0300)
committerMark Brown <broonie@kernel.org>
Thu, 5 May 2016 15:44:22 +0000 (16:44 +0100)
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>
Documentation/devicetree/bindings/sound/fsl-sai.txt
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
sound/soc/fsl/fsl_sai.c

index 777b941d6cbe65b930aabb3b941dd173c279cd02..740b467adf7d1d46f318d5a2a6bf74f35cfa80bc 100644 (file)
@@ -48,6 +48,11 @@ Required properties:
                          receive data by following their own bit clocks and
                          frame sync clocks separately.
 
+Optional properties (for mx6ul):
+
+  - fsl,sai-mclk-direction-output: This is a boolean property. If present,
+                        indicates that SAI will output the SAI MCLK clock.
+
 Note:
 - If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the
   default synchronous mode (sync Rx with Tx) will be used, which means both
index 238c8db953eba25d61151709062968d669ae0b6d..68353822afceb7b37b95ee0a2a5e3504823559dc 100644 (file)
 #define IMX6UL_GPR1_ENET2_CLK_OUTPUT           (0x1 << 18)
 #define IMX6UL_GPR1_ENET_CLK_DIR               (0x3 << 17)
 #define IMX6UL_GPR1_ENET_CLK_OUTPUT            (0x3 << 17)
+#define IMX6UL_GPR1_SAI1_MCLK_DIR              (0x1 << 19)
+#define IMX6UL_GPR1_SAI2_MCLK_DIR              (0x1 << 20)
+#define IMX6UL_GPR1_SAI3_MCLK_DIR              (0x1 << 21)
+#define IMX6UL_GPR1_SAI_MCLK_MASK              (0x7 << 19)
+#define MCLK_DIR(x) (x == 1 ? IMX6UL_GPR1_SAI1_MCLK_DIR : x == 2 ? \
+                    IMX6UL_GPR1_SAI2_MCLK_DIR : IMX6UL_GPR1_SAI3_MCLK_DIR)
 
 #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */
index d8b673f7c577733483e179c3c4c7e9165fc9f252..2147994ab46f6826824a3954947ed45285e0baae 100644 (file)
@@ -21,6 +21,8 @@
 #include <sound/core.h>
 #include <sound/dmaengine_pcm.h>
 #include <sound/pcm_params.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 
 #include "fsl_sai.h"
 #include "imx-pcm.h"
@@ -786,10 +788,12 @@ static int fsl_sai_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct fsl_sai *sai;
+       struct regmap *gpr;
        struct resource *res;
        void __iomem *base;
        char tmp[8];
        int irq, ret, i;
+       int index;
 
        sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
        if (!sai)
@@ -878,6 +882,22 @@ static int fsl_sai_probe(struct platform_device *pdev)
                fsl_sai_dai.symmetric_samplebits = 0;
        }
 
+       if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
+           of_device_is_compatible(pdev->dev.of_node, "fsl,imx6ul-sai")) {
+               gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr");
+               if (IS_ERR(gpr)) {
+                       dev_err(&pdev->dev, "cannot find iomuxc registers\n");
+                       return PTR_ERR(gpr);
+               }
+
+               index = of_alias_get_id(np, "sai");
+               if (index < 0)
+                       return index;
+
+               regmap_update_bits(gpr, IOMUXC_GPR1, MCLK_DIR(index),
+                                  MCLK_DIR(index));
+       }
+
        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;