Platform: RK3399
OS: Android 7.1
Kernel: v4.4.83

需求:

默认codec的clock source是从I2S1的mclk获取,由于I2S0和I2S1的mclk是共用同一个,
而且同一时刻只有一个I2S模块才能使用,而I2S0需要接麦克阵列,因此I2S1接的RT5640 Codec的时钟源改从BCLK1来获取。


信号源选择方法:

参考RT5640 codec的数据手册中的图,clock source可以从MCLK也可以从PLL获取。


原理图:

5640和cpu的接法如下:


修改:

移除之前对I2S1修改的patch以及添加对5640 clock source的控制。

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
index 8a98bbc..0546ed2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
@@ -89,12 +89,12 @@assigned-clock-parents = <&cru PLL_GPLL>;};-/* Kris,180906, Fix playback noise issue.
+&i2s1 {assigned-clocks = <&cru SCLK_I2S1_DIV>;assigned-clock-parents = <&cru PLL_GPLL>;};
-*/
+&i2s2 {assigned-clocks = <&cru SCLK_I2S2_DIV>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 5bf6cb9..109d8ce 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1693,9 +1693,6 @@dma-names = "tx", "rx";clock-names = "i2s_clk", "i2s_hclk";clocks = <&cru SCLK_I2S1_8CH>, <&cru HCLK_I2S1_8CH>;
-       //Kris,180706, porting rt5640 on i2s1.
-       assigned-clocks = <&cru SCLK_I2S_8CH>;
-       assigned-clock-parents = <&cru SCLK_I2S1_8CH>;pinctrl-names = "default";pinctrl-0 = <&i2s1_2ch_bus>;power-domains = <&power RK3399_PD_SDIOAUDIO>;
diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
index e2d872f..cd7b268 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -711,9 +711,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {&rk3399_i2s2_fracmux),GATE(SCLK_I2S2_8CH, "clk_i2s2", "clk_i2s2_mux", CLK_SET_RATE_PARENT,RK3399_CLKGATE_CON(8), 11, GFLAGS),
-   //Kris,180706, porting rt5640 on i2s1.
-   //MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT,
-   MUX(SCLK_I2S_8CH, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT,
+  MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT,RK3399_CLKSEL_CON(31), 0, 2, MFLAGS),COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT,RK3399_CLKSEL_CON(30), 8, 2, MFLAGS,
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 08179f5..1e5c79b 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1169,16 +1169,6 @@ static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run,off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);off += _emit_ST(dry_run, &buf[off], ALWAYS);
-#ifdef CONFIG_ARCH_ROCKCHIP
-       /*
-        * Make suree dma has finish transmission, or later flush may
-        * cause dma second transmission,and fifo is overrun.
-        */
-       off += _emit_WMB(dry_run, &buf[off]);
-       off += _emit_NOP(dry_run, &buf[off]);
-       off += _emit_WMB(dry_run, &buf[off]);
-       off += _emit_NOP(dry_run, &buf[off]);
-#endifif (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))off += _emit_FLUSHP(dry_run, &buf[off],
@@ -1199,16 +1189,6 @@ static inline int _ldst_memtodev(struct pl330_dmac *pl330,off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);off += _emit_LD(dry_run, &buf[off], ALWAYS);off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
-#ifdef CONFIG_ARCH_ROCKCHIP
-       /*
-        * Make suree dma has finish transmission, or later flush may
-        * cause dma second transmission,and fifo is overrun.
-        */
-       off += _emit_WMB(dry_run, &buf[off]);
-       off += _emit_NOP(dry_run, &buf[off]);
-       off += _emit_WMB(dry_run, &buf[off]);
-       off += _emit_NOP(dry_run, &buf[off]);
-#endifif (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))off += _emit_FLUSHP(dry_run, &buf[off],
@@ -1347,11 +1327,7 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run,/* forever loop */off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr);off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
-#ifdef CONFIG_ARCH_ROCKCHIP
-   if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
-       off += _emit_FLUSHP(dry_run, &buf[off],
-                   pxs->desc->peri);
-#endif
+/* loop0 */off += _emit_LP(dry_run, &buf[off], 0,  lcnt0);ljmp0 = off;
@@ -1390,7 +1366,7 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run,ccr &= ~(0xf << CC_SRCBRSTLEN_SHFT);ccr &= ~(0xf << CC_DSTBRSTLEN_SHFT);off += _emit_MOV(dry_run, &buf[off], CCR, ccr);
-           off += _emit_LP(dry_run, &buf[off], 1, c);
+          off += _emit_LP(dry_run, &buf[off], 1, c - 1);ljmp1 = off;off += _bursts(pl330, dry_run, &buf[off], pxs, 1);lpend.cond = ALWAYS;
@@ -1427,11 +1403,7 @@ static inline int _setup_loops(struct pl330_dmac *pl330,u32 ccr = pxs->ccr;unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr);int off = 0;
-#ifdef CONFIG_ARCH_ROCKCHIP
-   if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
-       off += _emit_FLUSHP(dry_run, &buf[off],
-                   pxs->desc->peri);
-#endif
+while (bursts) {c = bursts;off += _loop(pl330, dry_run, &buf[off], &c, pxs);
@@ -1785,17 +1757,16 @@ static int pl330_update(struct pl330_dmac *pl330)/* Detach the req */descdone = thrd->req[active].desc;
-           if (descdone) {
-               if (!descdone->cyclic) {
-                   thrd->req[active].desc = NULL;
-                   thrd->req_running = -1;
-                   /* Get going again ASAP */
-                   _start(thrd);
-               }-              /* For now, just make a list of callbacks to be done */
-               list_add_tail(&descdone->rqd, &pl330->req_done);
+          if (!descdone->cyclic) {
+              thrd->req[active].desc = NULL;
+              thrd->req_running = -1;
+              /* Get going again ASAP */
+              _start(thrd);}
+
+          /* For now, just make a list of callbacks to be done */
+          list_add_tail(&descdone->rqd, &pl330->req_done);}}@@ -1846,6 +1817,7 @@ static bool _chan_ns(const struct pl330_dmac *pl330, int i)static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330){struct pl330_thread *thrd = NULL;
+  unsigned long flags;int chans, i;if (pl330->state == DYING)
@@ -1853,6 +1825,8 @@ static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330)chans = pl330->pcfg.num_chan;+   spin_lock_irqsave(&pl330->lock, flags);
+for (i = 0; i < chans; i++) {thrd = &pl330->channels[i];if ((thrd->free) && (!_manager_ns(thrd) ||
@@ -1870,6 +1844,8 @@ static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330)thrd = NULL;}+  spin_unlock_irqrestore(&pl330->lock, flags);
+return thrd;}@@ -1887,6 +1863,7 @@ static inline void _free_event(struct pl330_thread *thrd, int ev)static void pl330_release_channel(struct pl330_thread *thrd){struct pl330_dmac *pl330;
+  unsigned long flags;if (!thrd || thrd->free)return;
@@ -1898,8 +1875,10 @@ static void pl330_release_channel(struct pl330_thread *thrd)pl330 = thrd->dmac;+   spin_lock_irqsave(&pl330->lock, flags);_free_event(thrd, thrd->ev);thrd->free = true;
+  spin_unlock_irqrestore(&pl330->lock, flags);}/* Initialize the structure for PL330 configuration, that can be used
@@ -2269,19 +2248,19 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)struct pl330_dmac *pl330 = pch->dmac;unsigned long flags;- spin_lock_irqsave(&pl330->lock, flags);
+  spin_lock_irqsave(&pch->lock, flags);dma_cookie_init(chan);pch->thread = pl330_request_channel(pl330);if (!pch->thread) {
-       spin_unlock_irqrestore(&pl330->lock, flags);
+      spin_unlock_irqrestore(&pch->lock, flags);return -ENOMEM;}tasklet_init(&pch->task, pl330_tasklet, (unsigned long) pch);-  spin_unlock_irqrestore(&pl330->lock, flags);
+  spin_unlock_irqrestore(&pch->lock, flags);return 1;}
@@ -2384,20 +2363,19 @@ static int pl330_pause(struct dma_chan *chan)static void pl330_free_chan_resources(struct dma_chan *chan){struct dma_pl330_chan *pch = to_pchan(chan);
-   struct pl330_dmac *pl330 = pch->dmac;unsigned long flags;tasklet_kill(&pch->task);pm_runtime_get_sync(pch->dmac->ddma.dev);
-   spin_lock_irqsave(&pl330->lock, flags);
+  spin_lock_irqsave(&pch->lock, flags);pl330_release_channel(pch->thread);pch->thread = NULL;list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool);-   spin_unlock_irqrestore(&pl330->lock, flags);
+  spin_unlock_irqrestore(&pch->lock, flags);pm_runtime_mark_last_busy(pch->dmac->ddma.dev);pm_runtime_put_autosuspend(pch->dmac->ddma.dev);}
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index ee9d1ba..985f9ee 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -1797,6 +1797,10 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream,snd_soc_update_bits(codec, RT5640_ADDA_CLK1, mask_clk, val_clk);}//理论上,PLL的计算是动态自适应的,可能驱动有问题导致计算不对。//后来是找realtek FAE拿的参数数据
+  /*Kris, 181128, Use BCLK1 as clock source. {*/
+  snd_soc_update_bits(codec, RT5640_ADDA_CLK1, 0xffff, 0000);
+  /*Kris, 181128, Use BCLK1 as clock source. }*/
+return 0;}@@ -1969,12 +1973,22 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),pll_code.n_code, pll_code.k_code);//理论上,PLL的计算是动态自适应的,可能驱动有问题导致计算不对。//后来是找realtek FAE拿的参数数据
+/*Kris, 181128, Use BCLK1 as clock source. {*/
+#if 0snd_soc_write(codec, RT5640_PLL_CTRL1,pll_code.n_code << RT5640_PLL_N_SFT | pll_code.k_code);snd_soc_write(codec, RT5640_PLL_CTRL2,(pll_code.m_bp ? 0 : pll_code.m_code) << RT5640_PLL_M_SFT |pll_code.m_bp << RT5640_PLL_M_BP_SFT);+#else
+  snd_soc_write(codec, RT5640_GLB_CLK, 0x5000);
+  snd_soc_write(codec, RT5640_PLL_CTRL1, 0x0f06);
+  snd_soc_write(codec, RT5640_PLL_CTRL2, 0x0800);
+#endif
+/*Kris, 181128, Use BCLK1 as clock source. }*/
+
+rt5640->pll_in = freq_in;rt5640->pll_out = freq_out;rt5640->pll_src = source;
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index dc971a0..d84eefc 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -21,6 +21,11 @@#include <sound/soc-dai.h>#include <sound/soc.h>+#include "../codecs/rt5640.h"
+
+
+
+struct simple_card_data {struct snd_soc_card snd_card;struct simple_dai_props {
@@ -90,8 +95,25 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,if (mclk_fs) {mclk = params_rate(params) * mclk_fs;
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
-                        SND_SOC_CLOCK_IN);
+
+/*Kris, 181128, Use BCLK1 as clock source. {*/
//修改对应的时钟源
+#if 0
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN);
+#else
+      ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, mclk * 2, SND_SOC_CLOCK_IN);
+      if (ret < 0) {
+              dev_err(codec_dai->dev, "codec_dai sys clock not set\n");
+              return ret;
+      }
+
+      ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1, mclk, mclk *2);
+      if (ret < 0) {
+              dev_err(codec_dai->dev, "codec_dai pll clock not set\n");
+              return ret;
+      }
+#endif
+/*Kris, 181128, Use BCLK1 as clock source. }*/
+if (ret && ret != -ENOTSUPP)goto err;

遗留问题:

RT5640 codec中的BLKC1是指pin脚,那么80h寄存器选的是BCLK2,为什么还能工作?

[RK3399][Android7.1] 调试笔记 --- Audio codec时钟源从BCLK1获取相关推荐

  1. [RK3399][Android7.1] 调试笔记 --- 系统默认时钟配置

    OS: Android 7.1 Board: Firefly-RK3399 Kernel: v4.4.55 分两个模块,一个是cpu,还有一个是pmu模块,这里只举例cpu,cpu又分在两个文件中定义 ...

  2. android手机底噪,[RK3399][Android7.1] 调试笔记 --- Codec播放音乐会有底噪

    Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 背景: 移植完Codec RT5640之后,发现播放声音的时候底部有噪声. 用示波器测量到的左右声道波 ...

  3. [RK3399][Android7.1] 调试笔记 --- I2S1工作输出是12MHz问题

    Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 现象: 使用I2S1通道,测量到的I2S MCLK是12MHz. 理论上应该是11.288MHz. 原 ...

  4. [RK3399][Android7.1] 调试笔记 --- 解决开关按键时产生的Pop声

    Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 背景: 按键音在打开和关闭的时候,会有pop声. 原因: audio codec后面有个功放,功放一直 ...

  5. [RK3399][Android7.1] 调试笔记 --- sdcard守护进程启动位置

    Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 Board: Firefly-RK3399 之前版本sdcard守护进程都是放在init.rc中启动: ...

  6. [RK3399][Android7.1] 调试笔记 --- 使用ADC芯片ES7243遇到的问题

    Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 用途: ES7243模块用于环形麦克场景时,采集的是音频播放的声音,然后采到之后回送到CPU,和麦克录 ...

  7. [RK3399][Android7.1] 调试笔记 --- USB type-c插入后无法识别到

    Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 现象: 用update.img制作了一个升级包之后可以升级,但是无法识别到type-c. Log: 插 ...

  8. android dts配置_「7.1」[RK3399][Android7.1] 移植笔记 --- 音频Codec RT5640添加 - seo实验室...

    7.1 Platform: RK3399 Kernel: v4.4.83 原理图: 数据走I2S1通道 控制走I2C1通道 输出走HPOUTL/HPOUTR 改动: DTS配置: //Kris,180 ...

  9. android 修改系统参数设置,2021-05-15 [RK3399][Android7.1] 调试笔记 ---显示参数动态设置接口...

    系统环境: Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 接口代码所在位置为: /frameworks/base/core/java/android ...

最新文章

  1. python【力扣LeetCode算法题库】69-x 的平方根
  2. 怎么在idea中找实现类
  3. 【Spring MVC】文件上传、文件下载
  4. MySQL和Oracle的添加字段的处理差别
  5. 在填写表单中输入全角数字的解决方案
  6. 基于matlab的电力系统输电仿真,基于MATLAB电力系统线路运行的仿真与分析
  7. 雷达信号处理基础 ch1 note1
  8. Hive-之即席查询引擎选型考量
  9. 计算机纳入高考作文,高考作文听人家说今年的高考作文是用计算机批 – 手机爱问...
  10. unity游戏开发之谷歌上架准备
  11. ZZ GP技术的展望——道生一,一生二
  12. 导向滤波原理(Guided Filter)
  13. bzoj-4318 OSU! 【数学期望】
  14. 企业微信被别人登录了怎么办?有风险吗?
  15. PwC普华永道——招聘
  16. ITK入门教程(11)点集之创建一个点集
  17. Error(1.0.5 1107071739): D:\SAE_SDK_Windows_1.0.5\apps\/divjs/1/config.yaml is not existed解决方法...
  18. 用matlab画图像,用MATLAB画出图像的幅度和方向角的图像并画出它们的直方图
  19. 青岛物联网关键技术资源发展路线图发布
  20. IE浏览器提示网站还原错误

热门文章

  1. jetson nano运行darknet_ros的环境配置
  2. 用c语言编写打印机输出程序,C语言编写银行打印程序实例参考
  3. Android 听筒模式和扬声器模式切换的 实现
  4. 入手评测 RTX3060性能相当于什么水平
  5. error C2679: binary ‘<<‘ : no operator defined which takes a right-hand operand of type ‘class s
  6. 图像处理之K-Means算法演示
  7. SAP ABAP 热咖啡报表模板
  8. 长发变短发,卷发变直发,坚持每天梳头
  9. time_expire时间过短,刷卡至少1分钟,其他5分钟
  10. ZYNQ产品生产拷机问题思考