RK系列SDK -- i2s mclk 无输出

说明:本文适用于基于 linux 4.4 内核版本开发的 RK 系列 SDK。硬件上,RK 芯片端 i2s mclk 引脚连接外部 codec 芯片 mclk 引脚,为外部芯片提供 mclk 时钟。软件上,需要对 mclk 做使能处理。

DTS配置

不同平台对应的时钟名称不一样,下述只举例 RK3399 和 RK3288 平台配置,其他平台可以去 kernel\drivers\clk\rockchip\clk-rk3xxx.c 中确定。

RK3399:
/{
 	dummy_codec: dummy-codec {
         status = "okay";
         compatible = "rockchip,dummy-codec";
         #sound-dai-cells = <0>;
+        clocks = <&cru SCLK_I2S_8CH_OUT>;
+        clock-names = "mclk";
+        pinctrl-names = "default";
+        pinctrl-0 = <&i2s_8ch_mclk>;
     };
};

RK3288:
/{
    dummy_codec: dummy-codec {
        #sound-dai-cells = <0>;
        compatible = "rockchip,dummy-codec";
+       clocks = <&cru SCLK_I2S0_OUT>;
+       clock-names = "mclk";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2s0_mclk>;
    };
};

codec 驱动

使用 dummy codec driver 需要添加下述patch:

diff --git a/sound/soc/codecs/dummy-codec.c b/sound/soc/codecs/dummy-codec.c
index 2761797..354251c 100644
--- a/sound/soc/codecs/dummy-codec.c
+++ b/sound/soc/codecs/dummy-codec.c
@@ -14,6 +14,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include 
 #include 
 #include 
@@ -23,6 +24,37 @@
 #include 
 #include 
 
+struct dummy_codec_priv {
+	struct snd_soc_codec *codec;
+	struct clk *mclk;
+};
+
+static int dummy_codec_startup(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct dummy_codec_priv *dummy_codec = snd_soc_codec_get_drvdata(codec);
+
+	if (!IS_ERR(dummy_codec->mclk))
+		clk_prepare_enable(dummy_codec->mclk);
+	return 0;
+}
+
+static void dummy_codec_shutdown(struct snd_pcm_substream *substream,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct dummy_codec_priv *dummy_codec = snd_soc_codec_get_drvdata(codec);
+
+	if (!IS_ERR(dummy_codec->mclk))
+		clk_disable_unprepare(dummy_codec->mclk);
+}
+
+static struct snd_soc_dai_ops dummy_codec_dai_ops = {
+	.startup	= dummy_codec_startup,
+	.shutdown	= dummy_codec_shutdown,
+};
+
 struct snd_soc_dai_driver dummy_dai = {
 	.name = "dummy_codec",
 	.playback = {
@@ -45,12 +77,33 @@ struct snd_soc_dai_driver dummy_dai = {
 			    SNDRV_PCM_FMTBIT_S24_LE |
 			    SNDRV_PCM_FMTBIT_S32_LE),
 	},
+	.ops = &dummy_codec_dai_ops,
 };
 
 static struct snd_soc_codec_driver soc_dummy_codec;
 
 static int rockchip_dummy_codec_probe(struct platform_device *pdev)
 {
+	struct dummy_codec_priv *codec_priv;
+
+	codec_priv = devm_kzalloc(&pdev->dev, sizeof(*codec_priv),
+				  GFP_KERNEL);
+	if (!codec_priv)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, codec_priv);
+
+	codec_priv->mclk = devm_clk_get(&pdev->dev, "mclk");
+	if (IS_ERR(codec_priv->mclk)) {
+		/* some devices may not need mclk,so warnnig */
+		dev_warn(&pdev->dev, "Unable to get mclk\n");
+		if (PTR_ERR(codec_priv->mclk) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		else if (PTR_ERR(codec_priv->mclk) != -ENOENT)
+			return -EINVAL;
+	} else {
+		dev_info(&pdev->dev, "get mclk success\n");
+	}
+
 	return snd_soc_register_codec(&pdev->dev, &soc_dummy_codec,
 				      &dummy_dai, 1);
 }

使用外置音频codec芯片均可参照下述 RT5670 driver 的修改:

diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
old mode 100644
new mode 100755
index 49a9e70..8763ea7
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -2654,6 +2654,21 @@ static int rt5670_probe(struct snd_soc_codec *codec)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
+	int ret ;
+
+     /* Check if MCLK provided */
+     rt5670->mclk = devm_clk_get(codec->dev, "mclk");
+     if (PTR_ERR(rt5670->mclk) == -EPROBE_DEFER)
+         return -EPROBE_DEFER;
+ 
+     ret = clk_prepare_enable(rt5670->mclk);
+     if (ret){
+         printk("%s clk_prepare_enable failed!",__func__)
+         return ret;        
+     }

 	switch (snd_soc_read(codec, RT5670_RESET) & RT5670_ID_MASK) {
 	case RT5670_ID_5670:

diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
old mode 100644
new mode 100755
index 3f1b0f1..f8152c4
--- a/sound/soc/codecs/rt5670.h
+++ b/sound/soc/codecs/rt5670.h
@@ -13,6 +13,7 @@
 #define __RT5670_H__
 
 #include 
+#include <linux/clk.h>
 
 /* Info */
 #define RT5670_RESET				0x00
@@ -1990,6 +1991,7 @@ struct rt5670_priv {
 	struct regmap *regmap;
 	struct snd_soc_jack *jack;
 	struct snd_soc_jack_gpio hp_gpio;
+	struct clk *mclk;
 
 	int sysclk;
 	int sysclk_src;

你可能感兴趣的:(RockChip,音频,Rockchip,i2s,mclk,RK3399,mclk,rt5670,mclk)