[alsa-devel] [PATCH v3 0/2] ASoC: fsl_sai: Add bus clock and mclks with clock controls
This series of patches add clock controls to fsl_sai driver and updates the vf610.dtsi accordingly.
Changelog v3: * Use int type for ret instead of u32. * Added Acked-by and Tested-by from Xiubo Li. v2: * Appended two extra mclks to the driver since SAI actually has three. * Renamed clock name to 'bus' and 'mclk' according to the reference manual.
Nicolin Chen (2): ASoC: fsl_sai: Add clock controls for SAI ARM: dts: Append clock bindings for sai2 on VF610 platform
.../devicetree/bindings/sound/fsl-sai.txt | 8 ++-- arch/arm/boot/dts/vf610.dtsi | 6 ++- sound/soc/fsl/fsl_sai.c | 51 ++++++++++++++++++++-- sound/soc/fsl/fsl_sai.h | 4 ++ 4 files changed, 60 insertions(+), 9 deletions(-)
The SAI mainly has the following clocks: bus clock control and configuration registers and to generate synchronous interrupts and DMA requests.
mclk1, mclk2, mclk3 to generate the bit clock when the receiver or transmitter is configured for an internally generated bit clock.
So this patch adds these clocks to the driver and their clock controls.
Signed-off-by: Nicolin Chen Guangyu.Chen@freescale.com Acked-by: Xiubo Li Li.Xiubo@freescale.com --- .../devicetree/bindings/sound/fsl-sai.txt | 8 ++-- sound/soc/fsl/fsl_sai.c | 51 ++++++++++++++++++++-- sound/soc/fsl/fsl_sai.h | 4 ++ 3 files changed, 56 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 35c09fe..8a273bc 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -10,7 +10,8 @@ Required properties: - compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai". - reg: Offset and length of the register set for the device. - clocks: Must contain an entry for each entry in clock-names. -- clock-names : Must include the "sai" entry. +- clock-names : Must include the "bus" for register access and "mclk1" "mclk2" + "mclk3" for bit clock and frame clock providing. - dmas : Generic dma devicetree binding as described in Documentation/devicetree/bindings/dma/dma.txt. - dma-names : Two dmas have to be defined, "tx" and "rx". @@ -30,8 +31,9 @@ sai2: sai@40031000 { reg = <0x40031000 0x1000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai2_1>; - clocks = <&clks VF610_CLK_SAI2>; - clock-names = "sai"; + clocks = <&clks VF610_CLK_SAI2>, <&clks VF610_CLK_SAI2> + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; dma-names = "tx", "rx"; dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>, <&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>; diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 9cd1764..2dae440 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -401,7 +401,23 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 reg; + struct device *dev = &sai->pdev->dev; + u32 reg, i; + int ret; + + ret = clk_prepare_enable(sai->bus_clk); + if (ret) { + dev_err(dev, "failed to enable bus clock\n"); + return ret; + } + + for (i = 0; i < FSL_SAI_MCLK_MAX; i++) { + ret = clk_prepare_enable(sai->mclk_clk[i]); + if (ret) { + dev_err(dev, "failed to enable mclk%d clock\n", i + 1); + goto err; + } + }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) reg = FSL_SAI_TCR3; @@ -412,13 +428,20 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, FSL_SAI_CR3_TRCE);
return 0; + +err: + for (; i > 0; i--) + clk_disable_unprepare(sai->mclk_clk[i - 1]); + clk_disable_unprepare(sai->bus_clk); + + return ret; }
static void fsl_sai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 reg; + u32 reg, i;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) reg = FSL_SAI_TCR3; @@ -427,6 +450,10 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, ~FSL_SAI_CR3_TRCE); + + for (i = 0; i < FSL_SAI_MCLK_MAX; i++) + clk_disable_unprepare(sai->mclk_clk[i]); + clk_disable_unprepare(sai->bus_clk); }
static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { @@ -559,7 +586,8 @@ static int fsl_sai_probe(struct platform_device *pdev) struct fsl_sai *sai; struct resource *res; void __iomem *base; - int irq, ret; + char tmp[8]; + int irq, ret, i;
sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); if (!sai) @@ -582,12 +610,27 @@ static int fsl_sai_probe(struct platform_device *pdev) return PTR_ERR(base);
sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, - "sai", base, &fsl_sai_regmap_config); + "bus", base, &fsl_sai_regmap_config); if (IS_ERR(sai->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); return PTR_ERR(sai->regmap); }
+ sai->bus_clk = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(sai->bus_clk)) { + dev_err(&pdev->dev, "failed to get bus clock\n"); + return PTR_ERR(sai->bus_clk); + } + + for (i = 0; i < FSL_SAI_MCLK_MAX; i++) { + sprintf(tmp, "mclk%d", i + 1); + sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp); + if (IS_ERR(sai->mclk_clk[i])) { + dev_err(&pdev->dev, "failed to get mclk%d clock\n", i + 1); + return PTR_ERR(sai->mclk_clk[i]); + } + } + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 677670d..0e6c9f5 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -119,6 +119,8 @@ #define FSL_SAI_CLK_MAST2 2 #define FSL_SAI_CLK_MAST3 3
+#define FSL_SAI_MCLK_MAX 3 + /* SAI data transfer numbers per DMA request */ #define FSL_SAI_MAXBURST_TX 6 #define FSL_SAI_MAXBURST_RX 6 @@ -126,6 +128,8 @@ struct fsl_sai { struct platform_device *pdev; struct regmap *regmap; + struct clk *bus_clk; + struct clk *mclk_clk[FSL_SAI_MCLK_MAX];
bool big_endian_regs; bool big_endian_data;
Since we added fours clock to the DT binding, we should update the current SAI dts/dtsi so as not to break their functions.
Signed-off-by: Nicolin Chen Guangyu.Chen@freescale.com Tested-by: Xiubo Li Li.Xiubo@freescale.com --- arch/arm/boot/dts/vf610.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index d31ce1b..9fd0007 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -139,8 +139,10 @@ compatible = "fsl,vf610-sai"; reg = <0x40031000 0x1000>; interrupts = <0 86 0x04>; - clocks = <&clks VF610_CLK_SAI2>; - clock-names = "sai"; + clocks = <&clks VF610_CLK_SAI2>, + <&clks VF610_CLK_SAI2>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; status = "disabled"; };
On Fri, Apr 04, 2014 at 06:08:13PM +0800, Nicolin Chen wrote:
Since we added fours clock to the DT binding, we should update the current SAI dts/dtsi so as not to break their functions.
If so, shouldn't the change be in the same patch as driver change?
Shawn
Signed-off-by: Nicolin Chen Guangyu.Chen@freescale.com Tested-by: Xiubo Li Li.Xiubo@freescale.com
arch/arm/boot/dts/vf610.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index d31ce1b..9fd0007 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -139,8 +139,10 @@ compatible = "fsl,vf610-sai"; reg = <0x40031000 0x1000>; interrupts = <0 86 0x04>;
clocks = <&clks VF610_CLK_SAI2>;
clock-names = "sai";
clocks = <&clks VF610_CLK_SAI2>,
<&clks VF610_CLK_SAI2>,
<&clks 0>, <&clks 0>;
clock-names = "bus", "mclk1", "mclk2", "mclk3"; status = "disabled"; };
-- 1.8.4
On Wed, Apr 09, 2014 at 03:58:15PM +0800, Shawn Guo wrote:
On Fri, Apr 04, 2014 at 06:08:13PM +0800, Nicolin Chen wrote:
Since we added fours clock to the DT binding, we should update the current SAI dts/dtsi so as not to break their functions.
If so, shouldn't the change be in the same patch as driver change?
Okay..I'd like to merge them into one patch.
Thank you, Nicolin
Shawn
Signed-off-by: Nicolin Chen Guangyu.Chen@freescale.com Tested-by: Xiubo Li Li.Xiubo@freescale.com
arch/arm/boot/dts/vf610.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index d31ce1b..9fd0007 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -139,8 +139,10 @@ compatible = "fsl,vf610-sai"; reg = <0x40031000 0x1000>; interrupts = <0 86 0x04>;
clocks = <&clks VF610_CLK_SAI2>;
clock-names = "sai";
clocks = <&clks VF610_CLK_SAI2>,
<&clks VF610_CLK_SAI2>,
<&clks 0>, <&clks 0>;
clock-names = "bus", "mclk1", "mclk2", "mclk3"; status = "disabled"; };
-- 1.8.4
On Fri, Apr 04, 2014 at 06:08:13PM +0800, Nicolin Chen wrote:
Since we added fours clock to the DT binding, we should update the current SAI dts/dtsi so as not to break their functions.
For the record, you're asking my ACK to have the dts change go via sound tree for not breaking vf610 function on the sound branch, while ignoring the fact that the existing DTB will break with the new kernel anyway.
I'm not completely happy with the approach, but considering that the existing binding is incorrect, I'm fine with it as long as people agree to go this way.
Shawn
Signed-off-by: Nicolin Chen Guangyu.Chen@freescale.com Tested-by: Xiubo Li Li.Xiubo@freescale.com
arch/arm/boot/dts/vf610.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index d31ce1b..9fd0007 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -139,8 +139,10 @@ compatible = "fsl,vf610-sai"; reg = <0x40031000 0x1000>; interrupts = <0 86 0x04>;
clocks = <&clks VF610_CLK_SAI2>;
clock-names = "sai";
clocks = <&clks VF610_CLK_SAI2>,
<&clks VF610_CLK_SAI2>,
<&clks 0>, <&clks 0>;
clock-names = "bus", "mclk1", "mclk2", "mclk3"; status = "disabled"; };
-- 1.8.4
Hi Shawn,
On Wed, Apr 09, 2014 at 04:11:38PM +0800, Shawn Guo wrote:
On Fri, Apr 04, 2014 at 06:08:13PM +0800, Nicolin Chen wrote:
Since we added fours clock to the DT binding, we should update the current SAI dts/dtsi so as not to break their functions.
For the record, you're asking my ACK to have the dts change go via sound tree for not breaking vf610 function on the sound branch, while ignoring the fact that the existing DTB will break with the new kernel anyway.
I'm not completely happy with the approach, but considering that the existing binding is incorrect, I'm fine with it as long as people agree to go this way.
Although I'm not a big fan of explaining, yet, I still want to say that actually I've balanced this way and your last suggestion against the v1.
It'd be surely better to distinguish two platforms as you suggested if we are looking at this change alone since the change is nearly tiny and the code to specify them wouldn't be quite a lot. However, there's more work to do based on this patch, an auto-selecting clock source mechanism for SAI as a DAI master for example, which would need to drop the existing code and to add the new one. If vf610 is still using the old one, it would not benefit from the further feature and the code would be definitely ugly as we would have to add too many platform checks. So personally I prefer this reasonable change than the little sacrifice we're going to make here.
Right now I feel grateful for what Sascha suggested to the DT bindings of fsl-spdif. It was a painstaking experience when getting it upstream last year but what's done at that moment makes the driver more flexible. So I think we should do the strict and comprehensive review for the clock part to every module from now on since an once-defined-DT-binding would be so painful to improved for us.
Thank you, Nicolin
Shawn
Signed-off-by: Nicolin Chen Guangyu.Chen@freescale.com Tested-by: Xiubo Li Li.Xiubo@freescale.com
arch/arm/boot/dts/vf610.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index d31ce1b..9fd0007 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -139,8 +139,10 @@ compatible = "fsl,vf610-sai"; reg = <0x40031000 0x1000>; interrupts = <0 86 0x04>;
clocks = <&clks VF610_CLK_SAI2>;
clock-names = "sai";
clocks = <&clks VF610_CLK_SAI2>,
<&clks VF610_CLK_SAI2>,
<&clks 0>, <&clks 0>;
clock-names = "bus", "mclk1", "mclk2", "mclk3"; status = "disabled"; };
-- 1.8.4
participants (2)
-
Nicolin Chen
-
Shawn Guo