[ 物联网篇 ] 28 - Linux ES7210 Driver 调试

news/2024/11/24 7:43:38/

目录

  • 前言
    • 一、ES7210 简介
    • 二、ES7210 Driver Porting
      • 1. Broadcom 平台 集成 ES7210
      • 2. Broadcom 平台定制化参数
      • 3. 排查 ES7210 无法正常工作
      • 4. ES7210 Gain Channels Adjust
    • 总结


前言

项目开发过程中,由于Broadcom平台音频数字接口比较少,所以采用模拟麦克风作为输入端,经顺芯ES7210 ADC 转换送至Broadcom PCM 数字音频接口。

模拟麦克风
ES7210 ADC
CPU 主控 / PCM

提示:本文记录了调试ES7210 Driver 过程中的问题与收获。


一、ES7210 简介

在这里插入图片描述
ES7210 是一款高性能四通道音频ADC,支持I2S / PCM / TDM 模式,可支持多个ES7210级连模式。常用于智能音箱领域。

二、ES7210 Driver Porting

1. Broadcom 平台 集成 ES7210

ES7210 Driver 需要顺芯原厂提供,虽然Linux 先的音频框架是一样的,但是芯片内部会有一系列寄存器需要设置。

  • 将ES7210.c和ES7210.h复制到src/kernel/linux/v4.4/sound/soc/codecs/路径下
  • 修改src/kernel/linux/v4.4/sound/soc/codecs/Makefile,
#obj-$(CONFIG_SND_SOC_ES7243)   += es7243.o
obj-$(CONFIG_SND_SOC_ES7210)    += es7210.o

默认驱动ees7210.c中采用过的是I2C_detect方式注册,

如有需要用dts方式注册,请将ES7210_MATCH_DTS_EN赋值为1.

#define ES7210_MATCH_DTS_EN		1	
//ES7210 match method select: 0: i2c_detect, 1:of_device_id

2. Broadcom 平台定制化参数

/*  to set internal mclk and adclrclk ratio   */#define RATIO_768  0xC3
#define RATIO_256  0xC1
#define RATIO_128  0x01
#define RATIO_64   0x41 /* mclk from bclk pin */#define ES7210_MCLK_LRCK_RATIO   RATIO_128

Broadcom 平台 LRCK 默认是16KHz , 通过逻辑仪看到LRCK的频率为2.04MHz。故ES7210_MCLK_LRCK_RATIO 需要设置为RATIO_128

3. 排查 ES7210 无法正常工作

通过逻辑分析仪观察到波形,PCM In 一直没有数据,相当于ES7210 没有正常工作。

在这里插入图片描述
根据 调试笔记 — 使用ADC芯片ES7243遇到的问题 的分析,快速验证了I2C , 可以正常工作。

参考数字音频接口
在这里插入图片描述
找到ES7210 Datasheet ,TDM参考设计。MCLK 需要连接
在这里插入图片描述

而Broadcom 中的ES7210 中的MCLK 是悬空的, 这个时候找顺芯FAE 咨询了下,MCLK 不能悬空,一般是LRCLK的256倍。如果没有MCLK,需要将BCLK短接到MCLK。

在这里插入图片描述
通过飞线将MCLK与BCLK连接在一起, 通过逻辑分析仪抓取波形,发现PCM Data 一直都是某个bit持续为高电平,其它为低电平。感觉ES7210 还是没有工作起来。跟顺芯FAE沟通了解. 驱动中不需要更改。

在这里插入图片描述
想起来之前,驱动代码中一旦使能 clk_prepare_enable(es7210->mclk),kernel 会立即发生崩溃。顺芯FAE 解释说 本身提供的是的RK 平台的驱动代码,针对博通平台,需要去掉该操作,只要主控能送出BCLK 就可以,其他不会有影响,代码只是使能MCLK

ssoc-audio soc-audio: ASoC: machine MapleTree should use snd_soc_register_card()
########### debug 1es7210_probe!
Unable to handle kernel paging request at virtual address fffffffe
pgd = c0014000
[fffffffe] *pgd=1fffd821, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.1.52 #8
Hardware name: Generic DT based system
task: df422c00 ti: df43a000 task.ti: df43a000
PC is at clk_prepare+0x14/0x2c
LR is at clk_prepare_lock+0x10/0xf8
pc : [<c02721b8>]    lr : [<c02710f8>]    psr: 60000113
sp : df43bdb0  ip : 00000000  fp : 00000000
r10: df4c4e20  r9 : df4c4c58  r8 : fffffffe
r7 : df4c4c00  r6 : df4c3d90  r5 : c07b6ca0  r4 : fffffffe
r3 : df422c00  r2 : 00000001  r1 : 00000000  r0 : 00000001
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 10c5387d  Table: 0001404a  DAC: 00000015
Process swapper/0 (pid: 1, stack limit = 0xdf43a210)
Stack: (0xdf43bdb0 to 0xdf43c000)
bda0:                                     df4c4c10 c02bb894 df4c4c10 df4c4c28
.....
[<c02721b8>] (clk_prepare) from [<c02bb894>] (es7210_probe+0x58/0x110)
[<c02bb894>] (es7210_probe) from [<c028d3bc>] (soc_probe_component+0x1f0/0x320)
[<c028d3bc>] (soc_probe_component) from [<c028ff7c>] (snd_soc_register_card+0x8b0/0xfc0)
[<c028ff7c>] (snd_soc_register_card) from [<c02186fc>] (platform_drv_probe+0x2c/0x60)
[<c02186fc>] (platform_drv_probe) from [<c02172a0>] (really_probe+0x190/0x290)
[<c02172a0>] (really_probe) from [<c0215a0c>] (bus_for_each_drv+0x60/0x94)
[<c0215a0c>] (bus_for_each_drv) from [<c0217108>] (device_attach+0x84/0x8c)
[<c0217108>] (device_attach) from [<c02167f8>] (bus_probe_device+0x84/0xa8)
[<c02167f8>] (bus_probe_device) from [<c0214b30>] (device_add+0x358/0x544)
[<c0214b30>] (device_add) from [<c02184c8>] (platform_device_add+0x110/0x220)
[<c02184c8>] (platform_device_add) from [<c05c3a6c>] (bcm63xx_audio_init+0x38/0x60)
[<c05c3a6c>] (bcm63xx_audio_init) from [<c001973c>] (do_one_initcall+0x8c/0x1d4)
[<c001973c>] (do_one_initcall) from [<c05a9dcc>] (kernel_init_freeable+0x148/0x1e8)
[<c05a9dcc>] (kernel_init_freeable) from [<c0446484>] (kernel_init+0x8/0xe8)
[<c0446484>] (kernel_init) from [<c001f4e8>] (ret_from_fork+0x14/0x2c)
Code: 012fff1e e92d4010 e1a04000 ebfffbcb (e5940000) 
---[ end trace 0daed059f560601b ]---
Kernel panic - not syncing: Fatal exception
CPU3: stopping
CPU: 3 PID: 0 Comm: swapper/3 Tainted: G      D         4.1.52 #8
Hardware name: Generic DT based system
[<c0026be0>] (unwind_backtrace) from [<c00229c8>] (show_stack+0x10/0x14)
[<c00229c8>] (show_stack) from [<c044a57c>] (dump_stack+0x8c/0xa0)
[<c044a57c>] (dump_stack) from [<c00253a4>] (handle_IPI+0x148/0x158)
[<c00253a4>] (handle_IPI) from [<c001941c>] (gic_handle_irq+0x5c/0x60)
[<c001941c>] (gic_handle_irq) from [<c00234c0>] (__irq_svc+0x40/0x74)
Exception stack(0xdf45ff88 to 0xdf45ffd0)
ff80:                   00000001 00000000 00000000 c002bd00 df45e000 c05dc4b0
ffa0: c0450704 00000000 df45ffd8 c05d7200 00000000 00000001 01000000 df45ffd0
ffc0: c00205f0 c00205f4 60000113 ffffffff
[<c00234c0>] (__irq_svc) from [<c00205f4>] (arch_cpu_idle+0x38/0x3c)
[<c00205f4>] (arch_cpu_idle) from [<c005ce60>] (cpu_startup_entry+0x15c/0x264)
[<c005ce60>] (cpu_startup_entry) from [<000194ac>] (0x194ac)                                         
CPU0: stopping                                                                                       
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G      D         4.1.52 #8                                    
Hardware name: Generic DT based system                                                               
[<c0026be0>] (unwind_backtrace) from [<c00229c8>] (show_stack+0x10/0x14)
[<c00229c8>] (show_stack) from [<c044a57c>] (dump_stack+0x8c/0xa0)
[<c044a57c>] (dump_stack) from [<c00253a4>] (handle_IPI+0x148/0x158)
[<c00253a4>] (handle_IPI) from [<c001941c>] (gic_handle_irq+0x5c/0x60)
[<c001941c>] (gic_handle_irq) from [<c00234c0>] (__irq_svc+0x40/0x74)
Exception stack(0xc05dbf28 to 0xc05dbf70)
bf20:                   c05dbf70 00000018 312acb4c 00000000 dfbc9910 00000001
bf40: 3124e81c 00000000 312acb4c 00000000 c0602f54 c05d9200 14000000 c05dbf70
bf60: fffffff8 c0267dac 00000113 ffffffff
[<c00234c0>] (__irq_svc) from [<c0267dac>] (cpuidle_enter_state+0xd8/0x20c)
[<c0267dac>] (cpuidle_enter_state) from [<c005cf08>] (cpu_startup_entry+0x204/0x264)
[<c005cf08>] (cpu_startup_entry) from [<c05a9c78>] (start_kernel+0x3a8/0x3b4)
[<c05a9c78>] (start_kernel) from [<0001807c>] (0x1807c)
CPU2: stopping
CPU: 2 PID: 371 Comm: ubi_bgt0d Tainted: G      D         4.1.52 #8
Hardware name: Generic DT based system
[<c0026be0>] (unwind_backtrace) from [<c00229c8>] (show_stack+0x10/0x14)
[<c00229c8>] (show_stack) from [<c044a57c>] (dump_stack+0x8c/0xa0)
[<c044a57c>] (dump_stack) from [<c00253a4>] (handle_IPI+0x148/0x158)
[<c00253a4>] (handle_IPI) from [<c001941c>] (gic_handle_irq+0x5c/0x60)
[<c001941c>] (gic_handle_irq) from [<c00234c0>] (__irq_svc+0x40/0x74)
Exception stack(0xd965fe20 to 0xd965fe68)
fe20: c07aeafc 80000193 00000001 20000113 dfbc3f08 00000005 00000035 c07906b8
fe40: 00000000 00000006 00000000 00000100 00000002 d965fe68 c0061710 c0062310
fe60: 60000113 ffffffff
[<c00234c0>] (__irq_svc) from [<c0062310>] (console_unlock+0x33c/0x4f8)
[<c0062310>] (console_unlock) from [<c0062814>] (vprintk_emit+0x348/0x5a0)
[<c0062814>] (vprintk_emit) from [<c0062b8c>] (vprintk_default+0x20/0x28)
[<c0062b8c>] (vprintk_default) from [<c0448810>] (printk+0x6c/0x7c)
[<c0448810>] (printk) from [<c02495c4>] (ubi_thread+0x40/0x174)
[<c02495c4>] (ubi_thread) from [<c0046da8>] (kthread+0xdc/0xf4)
[<c0046da8>] (kthread) from [<c001f4e8>] (ret_from_fork+0x14/0x2c)
Rebooting in 5 seconds..

然后查看原理图,发现有MIC_EN引脚,连接的是ES7210中断引脚,咨询TP硬件之后,发现这个脚目前是悬空状态,因此排除中断引脚的问题。
在这里插入图片描述
发现该排查的问题已经排查完成,先和FAE沟通,看还有哪些忽略的点,FAE说打开调试信息,查看Reg的值,沟通之后,了解方法之后,查看代码。通过应用层操作可以看出全部寄存器的数值。

1721 static struct attribute_group es7210_debug_attr_group = {
1722         .name   = "es7210_debug",
1723         .attrs  = es7210_debug_attrs,
1724 };
static DEVICE_ATTR(es7210, 0644, es7210_show, es7210_store);06 static ssize_t es7210_show(struct device *dev, struct device_attribute *attr, char *buf)
1707 {
1708         printk("echo flag|reg|val > es7210\n");
1709         printk("eg read star address=0x06,count 0x10:echo 0610 >es7210\n");
1710         printk("eg write star address=0x90,value=0x3c,count=4:echo 4903c >es7210\n");
1711         return 0;
1712 }

/由于echo flag打印的寄存器不全,需要用 echo 0x47可以打印出全部寄存器


echo 0x4f > /sys/devices/platform/ubus@ff800000/ff802100.i2c/i2c-0/0-0040/es7210_debug/es7210Read: start REG:0x00,count:0x4f
REG[0x00]: 0x41;  REG[0x01]: 0x20;  REG[0x02]: 0xc3;  REG[0x03]: 0x04;  
REG[0x04]: 0x01;  REG[0x05]: 0x00;  REG[0x06]: 0x00;  REG[0x07]: 0x20;  
REG[0x08]: 0x20;  REG[0x09]: 0x30;  REG[0x0a]: 0x30;  REG[0x0b]: 0x02;  
REG[0x0c]: 0x00;  REG[0x0d]: 0x09;  REG[0x0e]: 0xff;  REG[0x0f]: 0xff;  
REG[0x10]: 0x00;  REG[0x11]: 0x63;  REG[0x12]: 0x07;  REG[0x13]: 0x00;  
REG[0x14]: 0x03;  REG[0x15]: 0x03;  REG[0x16]: 0x00;  REG[0x17]: 0x00;  
REG[0x18]: 0xf7;  REG[0x19]: 0xf7;  REG[0x1a]: 0x00;  REG[0x1b]: 0xbf;  
REG[0x1c]: 0xbf;  REG[0x1d]: 0xbf;  REG[0x1e]: 0xbf;  REG[0x1f]: 0xff;  
REG[0x20]: 0x0a;  REG[0x21]: 0x2a;  REG[0x22]: 0x0a;  REG[0x23]: 0x2a;  
REG[0x24]: 0x11;  REG[0x25]: 0xff;  REG[0x26]: 0xff;  REG[0x27]: 0x0a;  
REG[0x28]: 0xff;  REG[0x29]: 0xff;  REG[0x2a]: 0xff;  REG[0x2b]: 0x2a;  
REG[0x2c]: 0xff;  REG[0x2d]: 0xff;  REG[0x2e]: 0xff;  REG[0x2f]: 0x2a;  
REG[0x30]: 0xff;  REG[0x31]: 0xff;  REG[0x32]: 0xff;  REG[0x33]: 0x2a;  
REG[0x34]: 0xff;  REG[0x35]: 0xff;  REG[0x36]: 0xff;  REG[0x37]: 0x2a;  
REG[0x38]: 0xff;  REG[0x39]: 0xff;  REG[0x3a]: 0xff;  REG[0x3b]: 0xff;  
REG[0x3c]: 0xff;  REG[0x3d]: 0x72;  REG[0x3e]: 0x10;  REG[0x3f]: 0x01;  
REG[0x40]: 0x42;  REG[0x41]: 0x70;  REG[0x42]: 0x70;  REG[0x43]: 0x1c;  
REG[0x44]: 0x1c;  REG[0x45]: 0x1c;  REG[0x46]: 0x1c;  REG[0x47]: 0x08;  
REG[0x48]: 0x08;  REG[0x49]: 0x08;  REG[0x4a]: 0x08;  REG[0x4b]: 0x00;  
REG[0x4c]: 0x00;  REG[0x4d]: 0xff;  REG[0x4e]: 0xff; 

根据寄存器的值判断ES7210的工作状态,这个时候想到确实应该这样操作,FAE确实从其中发现了问题:

通过寄存器0x14和0x15发现处于Mute状态。

同时0x02寄存器值不对,没匹配到没有mclk的值。这才真正的问题所在,这个时候思考为什么会导致这样的情况发生?

FAE推测到 说明没执行到es7210_pcm_startup()或者录音没有跑这个7210的声卡。这个时候最终明白问题所在了。

目前ES7210只走初始化流程,并不走es7210_pcm_startup() 这个时候明白了问题所在。

在这里插入图片描述

当初最初设计的方案 :

● ES7210 只需要走初始化流程,不需要完全对接Alsa的应用层,因为ES7210 SOC 是被动的,最终是Broadcom SOC PCM 接口去ES7210 获取数据的。
● Broadcom SOC 不需要通过Alsa 应用层,可以先通过bhDsphal.c应用程序调试看PCM是否又音频数据。

而ES7210中是对接的Alsa Lib接口,当通过arecord 录音的时候,Alsa Driver 是需要调用
es7210_pcm_startup(),而该函数的功能是启动延迟队列,执行 umute 操作。

通过这样的分析,解释了为什么ES7210 没数据的问题,主要是驱动初始化执行了mute操作,当arecoed的时候执行umut操作。而BCM6755 PCM 并没有走Alsa流程,导致一直处于mute状态。

 831 static struct snd_soc_dai_ops es7210_ops = {832         .startup = es7210_pcm_startup,833         .hw_params = es7210_pcm_hw_params,834         .set_fmt = es7210_set_dai_fmt,835         .set_sysclk = es7210_set_dai_sysclk,836         .digital_mute = es7210_mute,837 };static int es7210_pcm_startup(struct snd_pcm_substream *substream,struct snd_soc_dai *dai)
{struct snd_soc_codec *codec = dai->codec;struct es7210_priv *es7210 =                        snd_soc_codec_get_drvdata(codec);if (es7210_init_reg == 0) {schedule_delayed_work(&es7210->pcm_pop_work, msecs_to_jiffies(100));}return 0;
}
// 延迟队列执行函数747 static void pcm_pop_work_events(struct work_struct *work)748 {749         printk("enter into %s\n", __func__);750         es7210_unmute();751         es7210_init_reg = 1;752 }

4. ES7210 Gain Channels Adjust

// 由于echo flag打印的寄存器不全,需要用 echo 0x47可以打印出全部寄存器
echo 0x4f > /sys/devices/platform/ubus@ff800000/ff802100.i2c/i2c-0/
0-0040/es7210_debug/es7210
//寄存器列表如下图 

在这里插入图片描述

//需要调整ES7210 通道的GAIN数值#define ES7210_MIC1_GAIN_REG43		0x43
#define ES7210_MIC2_GAIN_REG44		0x44
#define ES7210_MIC3_GAIN_REG45		0x45
#define ES7210_MIC4_GAIN_REG46		0x46#define ES7210_MIC_GAIN 0x1c  // need check hw design and channel
#define ES7210_AEC_GAIN 0x13  // need check hw design and channeles7210_write(ES7210_MIC1_GAIN_REG43, ES7210_MIC_GAIN, i2c_clt1[i]);
es7210_write(ES7210_MIC2_GAIN_REG44, ES7210_MIC_GAIN, i2c_clt1[i]);
es7210_write(ES7210_MIC3_GAIN_REG45, ES7210_MIC_GAIN, i2c_clt1[i]);
es7210_write(ES7210_MIC4_GAIN_REG46, ES7210_MIC_GAIN, i2c_clt1[i]);// 根据寄存器可以分析出,增益值现在为34.5dB, 根据算法的要求,麦克风的录音数据应该是不需要添加任何增益的,需要改为0
i2cset -f -y 0 0x40 0x43 0x10
i2cset -f -y 0 0x40 0x44 0x10
i2cset -f -y 0 0x40 0x45 0x10
i2cset -f -y 0 0x40 0x46 0x10

在这里插入图片描述


总结

调试ES7210 Driver 前后花费了一周的时间,过程中遇到的很多问题,所以每次交付的时间都Delay。主要这个Broadcom平台对接的是TDM接口以及走的ALSA 接口有区别,很多东西不是很熟悉,解决问题过程中需要去弄明白才能快速的解决问题。


http://www.ppmy.cn/news/625861.html

相关文章

[RK3399][Android7.1] 4通道ADC芯片ES7210驱动源码

Platform: RK3399 OS: Android 7.1 Kernel: v4.4.83 说明: 内核里并没有关于ADC芯片ES7210的源码&#xff0c;驱动基于ES7243&#xff0c;分享给大家。 /** ALSA SoC ES7210 adc driver** Author: David Yang, <yangxiaohuaeverest-semi.com>* Copyright: (C) 2…

ES7210 高性能四通道音频ADC

ES7210 是一款用于麦克风阵列应用的高性能、低功耗 4 通道音频模数转换器&#xff0c;同时具备声学回声消除 (AEC) 功能&#xff0c;非常适合音乐和语音应用。 该设备支持标准音频时钟(64Fs, 128Fs, 256Fs, 384Fs, 512Fs等)&#xff0c;USB时钟 (12/24 MHz)&#xff0c;以及一…

六、MT8168/MT8175 音频驱动之TDM(ES7210)

1.简介 本章主要介绍MT8175(MT8168)平台ES7210驱动移植方法。通过本章学习,可以了解到TDM接口配置方法,ES7210驱动移植方法,tinymix调试方法。 2.ES7210移植指南 2.1 添加驱动文件 kernel-4.14/sound/soc/codecs/es7210.h kernel-4.14/sound/soc/codecs/es7210.c 2.…

【RK3399】Android平台增加一款声卡设备(ES7210+ES8156),进行录音/播放测试。

文章目录 前言一、开发环境二、概述三、硬件介绍1、ES72102、ES81563、数字麦克风阵列4、音频示意图 四、下载SDK五、编译、烧写1、u-boot2、kernel3、Android SDK4、烧写分区5、烧写固件 六、声卡驱动1、添加codec代码2、修改Kconfig3、修改Makefile4、修改rockchip_defconfig…

简单的手机记事本哪个好用?

在快节奏的现代生活中&#xff0c;我们经常需要记录下来重要的信息&#xff0c;而手机记事本成为了不可或缺的工具。然而&#xff0c;市面上琳琅满目的手机记事本软件&#xff0c;让人眼花缭乱&#xff0c;不知道该选择哪一个。 敬业签是功能强大、操作简单的手机记事本&#…

九、文字到语音模型库之PaddleSpeech

前述SunoAI之Bark,听起来总有点老外说中文的味道,很不地道纯正。下面玩一玩百度飞桨--PaddleSpeech,这是一个简单易用的all-in-one 的语音工具箱,支持语音识别,语音合成,声纹识别,声音分类,语音翻译,标点恢复,语音唤醒等多个方向的开发工作。 项目地址:https://gith…

Origin 绘图与数据分析操作学习

Origin 引言基本操作数据导入origin中的数据格式数据处理曲线拟合统计分析结果导出绘图基本设置绘图基本元素图页面图层框架数据的操作和管理工作簿的操作工作表的操作矩阵簿和矩阵表数据转换不同格式之间的转换数据的查找2D和3D绘图数据分析线性拟合操作

【已解决】执行apt-get update报错404 Not Found的解决方案——docker 镜像下安装报错

问题描述 docker容器中安装vim报错 执行apt-get install vim后报错&#xff1a; E: Unable to locate package vim更新安装源也报错 docker容器中执行apt-get update后报错&#xff1a; #进入镜像命令#docker exec -it 镜像Id或镜像name /bin/bash [roottdengine ~]# docke…