首页 > 其他分享 >Rockchip RK3399 - ALC5651音频调试

Rockchip RK3399 - ALC5651音频调试

时间:2023-07-31 19:33:41浏览次数:50  
标签:snd Rockchip ALC5651 soc RK3399 rk3399 tracing root numid

----------------------------------------------------------------------------------------------------------------------------

开发板 :NanoPC-T4开发板
eMMC :16GB
LPDDR3 :4GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot :2023.04
linux :6.3
----------------------------------------------------------------------------------------------------------------------------

一、内核配置

1.1 配置内核

修改sound/soc/codecs/Kconfig文件,搜索config SND_SOC_RT5651,将该项修

config SND_SOC_RT5651
        tristate
        depends on I2C

改为,如果不修改的话,make menuconfig是看不到该配置项的;

config SND_SOC_RT5651
        tristate "Realtek ALC5651 CODEC"
        depends on I2C

在linux内核根目录下执行make menuconfig配置以下选项:

Device Drivers --->
  <*> Sound card support  --->
     <*> Advanced Linux Sound Architecture  ---> 
<*> Sequencer support <*> ALSA for SoC audio support ---> <*> ASoC support for Rockchip {*} Rockchip I2S Device Driver CODEC drivers ---> <*> Realtek RT5651 CODEC <*> ASoC Simple sound card support

至于为啥配这些,可以看下面的介绍。

1.1.1 支持simple-audio-card驱动

要想将sound/soc/generic/simple-card.c文件对应的驱动编译到内核,我们需要配置CONFIG_SND_SIMPLE_CARD,我们定位到sound/soc/generic/Makefile文件;

# SPDX-License-Identifier: GPL-3.0
snd-soc-simple-card-utils-objs  := simple-card-utils.o
snd-soc-simple-card-objs        := simple-card.o
snd-soc-audio-graph-card-objs   := audio-graph-card.o

obj-$(CONFIG_SND_SIMPLE_CARD_UTILS)     += snd-soc-simple-card-utils.o
obj-$(CONFIG_SND_SIMPLE_CARD)           += snd-soc-simple-card.o
obj-$(CONFIG_SND_AUDIO_GRAPH_CARD)      += snd-soc-audio-graph-card.o

这里定义了snd-soc-simple-card.o的生成规则:

snd-soc-simple-card-objs := simple-card.o

它表示将当前目录下的 simple-card.o文件编译成一个snd-soc-simple-card.o。我们可以查看sound/soc/generic/.snd-soc-simple-card.o.cmd文件找到编译命令:

root@zhengyang:/work/sambashare/rk3399/linux-5.3.8# cat  sound/soc/generic/.snd-soc-simple-card.o.cmd
cmd_sound/soc/generic/snd-soc-simple-card.o := arm-linux-ld  -EL  -maarch64elf    -r -o sound/soc/generic/snd-soc-simple-card.o sound/soc/generic/simple-card.o
1.1.2 支持I2S驱动

要想将sound/soc/rockchip/rockchip_i2s.c文件对应的驱动编译到内核,我们需要配置CONFIG_SND_SOC_ROCKCHIP_I2S,我们定位到sound/soc/rockchip/Makefile文件;

# SPDX-License-Identifier: GPL-3.0
# ROCKCHIP Platform Support
snd-soc-rockchip-i2s-objs := rockchip_i2s.o
snd-soc-rockchip-pcm-objs := rockchip_pcm.o
snd-soc-rockchip-pdm-objs := rockchip_pdm.o
snd-soc-rockchip-spdif-objs := rockchip_spdif.o

obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o snd-soc-rockchip-pcm.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_PDM) += snd-soc-rockchip-pdm.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o

这里定义了snd-soc-rockchip-i2s.o的生成规则:

snd-soc-rockchip-i2s-objs := rockchip_i2s.o

它表示将当前目录下的rockchip_i2s.o文件编译成一个snd-soc-rockchip-i2s.o。

1.1.3 支持rt5651驱动

要想将sound/soc/codecs/rt5651.c文件对应的驱动编译到内核,我们需要配置CONFIG_SND_SOC_RT5651,我们定位到sound/soc/codecs/文件;

snd-soc-rt5651-objs := rt5651.o
obj-$(CONFIG_SND_SOC_RT5651)    += snd-soc-rt5651.o

这里定义了snd-soc-rt5651.o的生成规则:

snd-soc-rt5651-objs := rt5651.o

它表示将当前目录下的rt5651.o文件编译成一个snd-soc-rt5651.o。

1.1.4 支持seq

在 sound/core/Makefile文件中,如果配置CONFIG_SND_SEQUENCER,将seq编译到内核,这个文件作用后面有时间再研究;

obj-$(CONFIG_SND_SEQUENCER)     += seq/

1.2 保存配置

配置完内核之后记得保存配置:

存档:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# mv rk3399_defconfig ./arch/arm64/configs/

重新配置内核:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# make rk3399_defconfig

1.3 编译内核

在linux内核根目录下执行如下命令进行编译内核:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# make -j8

u-boot-2024.04路径下的mkimage工具拷贝过来,然后在命令行使用mkimage工具编译即可:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp ../u-boot-2023.04/tools/mkimage ./
root@zhengyang:/work/sambashare/rk3399/linux-6.3# ./mkimage -f kernel.its kernel.itb

1.4 通过tftp烧录内核

给开发板上电,同时连接上网线,进入uboot命令行。我们将内核拷贝到tftp文件目录:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp kernel.itb /work/tftpboot/

接着给开发板上电。通过uboot命令行将kernel.itb下到内存地址0x10000000处:

=> tftp 0x10000000 kernel.itb

通过mmc write命令将内核镜像烧录到eMMC第0x8000个扇区处:

=> mmc erase 0x8000 0xA000
=> mmc write 0x10000000 0x8000 0xA000

1.5 启动内核

我们重新启动开发板,如果声卡驱动正常加载,我们会看到类似下面的日志:

二、查看声卡设备

2.1 查看音频设备节点:

查看音频设备节点:

root@rk3399:/# ll /dev/snd
total 0
drwxr-xr-x  2 root root       60 Jul 26 23:31 by-path/
crw-rw----  1 root audio 116,  4 Jul 26 23:31 controlC0
crw-rw----  1 root audio 116,  3 Jul 26 23:31 pcmC0D0c
crw-rw----  1 root audio 116,  2 Jul 26 23:31 pcmC0D0p
crw-rw----  1 root audio 116,  1 Jul 26 23:31 seq
crw-rw----  1 root audio 116, 33 Jul 26 23:31 timer

其中:

  • controlC0:用于声卡的控制,例如通道选择,混音,麦克控制,音量加减,开关等;
  • pcmC0D0c:用于录音的pcm设备;
  • pcmC0D0p:用于播放的pcm设备;
  • seq:音序器;
  • timer:定时器;

C0D0代表的是声卡0中的设备0,pcmC0D0c最后一个c代表capture,pcmC0D0p最后一个p代表playback,这些都是alsa-driver中的命名规则。

从上面的列表可以看出,我的声卡下挂了5个设备,根据声卡的实际能力,驱动实际上可以挂载更多种类的设备,我们通常更关心的是pcm和control这两种设备,默认一个声卡对应一个Control设备。

2.2 查看所有声卡

查看所有声卡:

root@rk3399:/# cat /proc/asound/cards
 0 [realtekrt5651co]: simple-card - realtek,rt5651-codec
                      realtek,rt5651-codec

0为声卡编号,realtekrt5651co为ALSA声卡的唯一标识,因为struct snd_card  id字段其长度为16,所以存放的就是realtek,rt5651-codec去除特殊字符之后的的前15个字符。

声卡分两种通道,一种是Capture、一种是Playback。Capture是输入通道,Playback是输出通道;我们以声卡0为例;

root@rk3399:/# ll /proc/asound/card0
-r--r--r-- 1 root root 0 Jul 23 16:02 id
dr-xr-xr-x 4 root root 0 Jul 23 16:02 pcm0c/
dr-xr-xr-x 4 root root 0 Jul 23 16:02 pcm0p/
root@rk3399:/# cat /proc/asound/card0/id
realtekrt5651co

pcm0p属于声卡0输出通道,pcm0c属于声卡0输入通道。

2.2.1 查看播放设备
root@rk3399:/# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: realtekrt5651co [realtek,rt5651-codec], device 0: ff880000.i2s-rt5651-aif1 rt5651-aif1-0 [ff880000.i2s-rt5651-aif1 rt5651-aif1-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
2.2.2 查看录音设备
root@rk3399:/# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: realtekrt5651co [realtek,rt5651-codec], device 0: ff880000.i2s-rt5651-aif1 rt5651-aif1-0 [ff880000.i2s-rt5651-aif1 rt5651-aif1-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

2.3 查看pcm设备列表

root@rk3399:/# cat /proc/asound/pcm
00-00: ff880000.i2s-rt5651-aif1 rt5651-aif1-0 : ff880000.i2s-rt5651-aif1 rt5651-aif1-0 : playback 1 : capture 1

三、音频调试

3.1 下载工具

播放视频,音频文件时没声音的,需要用alsamixer来配置,过程如下:

root@rk3399:/# apt-get install alsa-base alsa-utils alsa-oss alsa-tools

3.2 amixer 命令

3.2.1 amixer controls

通过amixer controls显示控制接口(这个对应的应该就是我们在声卡驱动中注册的kcontrol):

root@rk3399:/# amixer controls
numid=1,iface=CARD,name='Headphones Jack'
numid=13,iface=MIXER,name='Mono ADC Capture Volume'
numid=6,iface=MIXER,name='Mono DAC Playback Volume'
numid=14,iface=MIXER,name='ADC Boost Gain'
numid=18,iface=MIXER,name='ADC IF2 Data Switch'
numid=11,iface=MIXER,name='ADC Capture Switch'
numid=12,iface=MIXER,name='ADC Capture Volume'
numid=19,iface=MIXER,name='DAC IF2 Data Switch'
numid=51,iface=MIXER,name='DAC L2 Mux'
numid=48,iface=MIXER,name='DAC MIXL INF1 Switch'
numid=47,iface=MIXER,name='DAC MIXL Stereo ADC Switch'
numid=50,iface=MIXER,name='DAC MIXR INF1 Switch'
numid=49,iface=MIXER,name='DAC MIXR Stereo ADC Switch'
....

比如我们以DAC MIXR INF1 Switch为例:

numid=50,iface=MIXER,name='DAC MIXR INF1 Switch'

其中INF1 Switch为kcontrol的名称,DAC MIXR为kcontrol所属widget的名称,iface=MIXER表示kcontrol的类型为Mixer、numid为kcontrol的编码;

// kcontrol
 SOC_DAPM_SINGLE("INF1 Switch", RT5651_AD_DA_MIXER,        // 寄存器配置为RT5651_AD_DA_MIXER=0x29,偏移位配置为14
                        RT5651_M_IF1_DAC_L_SFT, 1, 1)

// 输出端widget
SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,               // 寄存器设置为SND_SOC_NOPM,表示没有寄存器可以控制该widget的上下电 
                   rt5651_dac_l_mix, ARRAY_SIZE(rt5651_dac_l_mix)); // Left DAC Mixer包含2个kcontrol,每个kcontrol控制着Mixer的一个输入端的开启和关闭

// route
{"DAC MIXL", "INF1 Switch", "IF1 DAC1 L"}
3.2.2 amixer content

通过amixer contents查看所有的配置参数:

root@rk3399:/# amixer contents
numid=1,iface=CARD,name='Headphones Jack'
  ; type=BOOLEAN,access=r-------,values=1
  : values=on
numid=13,iface=MIXER,name='Mono ADC Capture Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=127,step=0
  : values=47,47
  | dBminmax-min=-17.62dB,max=30.00dB
numid=6,iface=MIXER,name='Mono DAC Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=175,step=0
  : values=175,175
  | dBminmax-min=-65.62dB,max=0.00dB
numid=14,iface=MIXER,name='ADC Boost Gain'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=3,step=0
  : values=3,3
  | dBscale-min=0.00dB,step=12.00dB,mute=0
numid=18,iface=MIXER,name='ADC IF2 Data Switch'
  ; type=ENUMERATED,access=rw------,values=1,items=4
  ; Item #0 'Normal'
  ; Item #1 'Swap'
  ; Item #2 'left copy to right'
  ; Item #3 'right copy to left'
  : values=0
numid=11,iface=MIXER,name='ADC Capture Switch'
  ; type=BOOLEAN,access=rw------,values=2
  : values=on,on
numid=12,iface=MIXER,name='ADC Capture Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=127,step=0
.......

Rockchip RK3399 - Codec驱动( Realtek ALC5651)我们分析了音频播放右通道路径:

  • AIF1 Playback(snd_soc_dapm_dai_in类型的playback dai widget) --> AIF1RX :AIF表示音频数字接口;
  • AIF1RX --> IF1 DAC;
  • IF1 DAC --> IF1 DAC1 L;
  • IF1 DAC1 L --> DAC MIXL:通过rt5651_dac_l_mix(名称为INF1 Switch)控制通断,由MX29寄存器位14来实现静音控制(0非静音,1静音);
  •  DAC MIXL -->  Stereo DAC MIXR:通过rt5651_sto_dac_r_mix(名称DAC L1 Switch)控制通断,由MX2A寄存器位1来实现静音控制(0非静音,1静音);
  •  Stereo DAC MIXR --> DAC R1;
  • DAC R1 --> OUT MIXR :通过rt5651_out_r_mix(名称为DAC R1 Switch)控制通断,由MX4F寄存器位0来实现静音控制(0非静音,1静音);
  • OUT MIXR -->  HPOVOL R:通过hpovol_r_control(名称为Switch)控制通断,由MX02寄存器位6来实现静音控制(0非静音,1静音);
  •  HPOVOL R --> HPOR MIX:通过rt5651_hpo_mix(名称为HPO MIX HPVOL Switch)控制通断,由MX45寄存器位13来实现静音控制(0非静音,1静音);
  • HPOR MIX --> HP Amp;
  • HP Amp -> HPO R Playback:通过hpo_r_mute_control(名称为Switch)控制通断,由MX02寄存器位7来实现静音控制(0非静音,1静音);
  • HPO R Playback --> HPOR ;
  • HPOR  --> Headphones(最后一个path定义在Machine驱动中);

我们需要设置该条路径上的kcontrol设置为连接状态;

(1) 打开DAC MIXL INF1 Switch、DAC MIXR INF1 Switch:

root@rk3399:/# amixer cset numid=48 1
numid=48,iface=MIXER,name='DAC MIXL INF1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
root@rk3399:/# amixer cset numid=50 1
numid=50,iface=MIXER,name='DAC MIXR INF1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on

我们可以查看MX29寄存器位14,看看是不是已经设置为0(非静音);

root@rk3399:/# cat /sys/kernel/debug/regmap/1-001a/registers | grep 029    
029: 8080           #1000 0000 1000 0000

如果有兴趣的话,我们可以通过关闭DAC MIXL INF1 Switch,查看MX29寄存器位14是不是已经设置为1(静音);

root@rk3399:/# amixer cset numid=48 0
numid=48,iface=MIXER,name='DAC MIXL INF1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
root@rk3399:/# cat /sys/kernel/debug/regmap/1-001a/registers | grep 029
029: c080
root@rk3399:/# amixer cset numid=48 1
numid=48,iface=MIXER,name='DAC MIXL INF1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on

(2) 打开Stereo DAC MIXR DAC L1 Switch、Stereo DAC MIXL DAC R1 Switch:

root@rk3399:/# amixer cset numid=55 1
numid=55,iface=MIXER,name='Stereo DAC MIXL DAC R1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
root@rk3399:/# amixer cset numid=58 1
numid=58,iface=MIXER,name='Stereo DAC MIXR DAC L1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on

(3) 打开OUT MIXR DAC R1 Switch、OUT MIXL DAC L1 Switch:

root@rk3399:/# amixer cset numid=74 1
numid=74,iface=MIXER,name='OUT MIXR DAC R1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
root@rk3399:/# amixer cset numid=69 1
numid=69,iface=MIXER,name='OUT MIXL DAC L1 Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on

(4) 打开HPOVOL L Switch、HPOVOL R Switch:

root@rk3399:/# amixer cset numid=77 1
numid=77,iface=MIXER,name='HPOVOL L Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
root@rk3399:/# amixer cset numid=78 1
numid=78,iface=MIXER,name='HPOVOL R Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on

(5) 打开HPO MIX HPVOL Switch:

root@rk3399:/# amixer cset numid=80 1
numid=80,iface=MIXER,name='HPO MIX HPVOL Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on

(6) 打开HPO L Playback Switch、HPO R Playback Switch:

root@rk3399:/# amixer cset numid=85 1
numid=85,iface=MIXER,name='HPO L Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
root@rk3399:/# amixer cset numid=86 1
numid=86,iface=MIXER,name='HPO R Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on

找到一个音频文件,播放音频:

root@rk3399:/# cd /
root@rk3399:/# aplay AbuduOffice.mp3
Playing raw data 'AbuduOffice.mp3' : Signed 16 bit Little Endian, rATE 8000 Hz, Mono

插入耳机,如果我们发现耳机并没有声音,说明音频播放失败,关于问题定位参考Frace调试小节。

3.3 查看寄存器值

3.3.1 查看ALC5651寄存器值

运行如下命令查看ALC5651寄存器值,1-001a中的1为I2C适配器的编号,即I2C1,001a为I2C1总线上的从设备地址;

root@rk3399:/# cat /sys/kernel/debug/regmap/1-001a/registers
000: 0000
002: 81c1
003: c8c8
005: 0000
00d: 0000
00e: 0000
00f: 0808
010: 0808
019: afaf
01a: afaf
01b: 0c00
01c: 2f2f
01d: 2f2f
......

四、Ftrace调试

Ftrace 是一个内核中的追踪器,用于帮助系统开发者或设计者查看内核运行情况,它可以被用来调试或者分析延迟/性能问题。最早ftrace是一个function tracer,仅能够记录内核的函数调用流程。如今ftrace已经成为一个framework,采用plugin的方式支持开发人员添加更多种类的trace功能。

4.1 配置内核

运行make menuconfig,配置以下选项:

Kernel hacking  --->
    [*] Tracers  ---> 
           [*]   Kernel Function Tracer                                                                    
           [*]     Kernel Function Graph Tracer (NEW)                                                              
           -*-     enable/disable function tracing dynamically         
Device Drivers --->
  <*> Sound card support  --->
     <*> Advanced Linux Sound Architecture  ---> 
           [*]   Debug
           [*]   More verbose debug                                                                    
           [*]   Enable PCM ring buffer overrun/underrun debugging                                
           [*]   Validate input data to control API                                                    
           [*]   Enable debugging feature for control API                                          
           [*]   Sound jack injection interface via debugfs

编译内核,并烧录到开发板。

4.2 Ftrace使用

Ftrace通过debugfs向用户态提供访问接口。配置内核时激活debugfs后会创建目录/sys/kernel/debug ,debugfs文件系统就是挂载到该目录。

4.2.1 运行时挂载

官方挂载方法 :

root@rk3399:/# mount -t debugfs nodev /sys/kernel/debug
mount: /sys/kernel/debug: nodev already mounted or mount point busy.
root@rk3399:/# cd /sys/kernel/debug/tracing

debugfs挂载路径下的tracing是ftrace的根路径。

4.2.2 系统启动自动挂载

要在系统启动自动挂载debugfs,需要将如下内容添加到/etc/fstab 文件:

debugfs  /sys/kernel/debug  debugfs  defaults  0  0
4.2.3 选择一种 tracer

查看当前追踪器:

root@rk3399:/sys/kernel/debug/tracing# cat current_tracer
nop

查看当前内核中可用跟踪器:

root@rk3399:/sys/kernel/debug/tracing# cat available_tracers
function_graph function nop

我们选用 function_graph 追踪器:

root@rk3399:/sys/kernel/debug/tracing# echo function_graph > current_tracer
4.2.4 打开/关闭跟踪

在老一点版本的内核上tracing目录下有tracing_enabled,需要给tracing_enabled和tracing_on同时赋值1才能打开追踪,而在比较新的内核上已经去掉tracing_enabled ,我们只需要控制tracing_on即可打开关闭追踪。

打开跟踪:

root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/tracing_on

关闭跟踪:

root@rk3399:/sys/kernel/debug/tracing# echo 0 > /sys/kernel/debug/tracing/tracing_on

追踪指定的进程:

root@rk3399:/sys/kernel/debug/tracing# echo pid > /sys/kernel/debug/tracing/set_ftrace_pid

我们写程序时可以使用getpid获取进程PID,然后使用write将pid 写入 /sys/kernel/debug/tracing/set_ftrace_pid ,并使用write写1到tracing_on打开追踪(因为在用户空间使用不了tracing_on函数),此时即可追踪当前这个进程。

4.2.5 跟踪事件

首先查看事件文件夹下面有哪些选项:

root@rk3399:/sys/kernel/debug/tracing# ls /sys/kernel/debug/tracing/events/
9p            cros_ec       filelock       interconnect  mdio       nfs             rcu        smbus                    timer
alarmtimer    dev           filemap        io_uring      migrate    nfs4            regmap     sock                     tlb
asoc          devfreq       ftrace         iomap         mmap       oom             regulator  spi                      udp
block         devlink       gadget         iommu         mmap_lock  optee           rpcgss     spmi                     ufs
bpf_test_run  dma_fence     gpio           ipi           mmc        page_isolation  rpm        sunrpc                   vmalloc
bpf_trace     dpaa2_eth     gpu_scheduler  irq           module     page_pool       rpmh       swiotlb                  vmscan
bridge        dpaa_eth      header_event   jbd2          mtu3       pagemap         rseq       task                     watchdog
cgroup        drm           header_page    kmem          musb       percpu          rtc        tcp                      workqueue
chipidea      dwc3          huge_memory    kvm           napi       power           sched      tegra_apb_dma            writeback
clk           enable        hwmon          kyber         neigh      printk          scmi       thermal                  xdp
cma           error_report  i2c            libata        net        qdisc           scsi       thermal_power_allocator  xhci-hcd
compaction    ext4          i2c_slave      lock          netfs      ras             signal     thermal_pressure
cpuhp         fib           initcall       maple_tree    netlink    raw_syscalls    skb        thp
root@rk3399:/sys/kernel/debug/tracing# ls /sys/kernel/debug/tracing/events/asoc
enable                   snd_soc_bias_level_start  snd_soc_dapm_path       snd_soc_dapm_widget_event_done   snd_soc_jack_irq
filter                   snd_soc_dapm_connected    snd_soc_dapm_start      snd_soc_dapm_widget_event_start  snd_soc_jack_notify
snd_soc_bias_level_done  snd_soc_dapm_done         snd_soc_dapm_walk_done  snd_soc_dapm_widget_power        snd_soc_jack_report

关闭所有事件跟踪:

root@rk3399:/sys/kernel/debug/tracing# echo 0 > /sys/kernel/debug/tracing/events/enable

追踪若干事件:

root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_path/enable
root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_start/enable
root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_walk_done/enable
root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_widget_power/enable

追踪某一类事件:

root@rk3399:/sys/kernel/debug/tracing# echo 1 > /sys/kernel/debug/tracing/events/asoc/enable
4.2.6 查看跟踪结果

ftrace 的输出信息主要保存在3个文件中;

  • trace:该文件保存ftrace的输出信息,其内容可以直接阅读;
  • trace_pipe:是一个管道文件,主要为了方便应用程序读取trace内容,算是扩展接口吧;

所以可以直接查看trace追踪文件,也可以在追踪之前使用trace_pipe将追踪结果直接导向其他的文件。

比如:cat trace_pipe > /tmp/log &  使用trace_pipe将跟踪结果导入/tmp/log 里,我们可以直接cat /tmp/log” 查看跟踪信息。

当然也可以直接查看trace文件cat trace或者使用cat trace  > /tmp/log将跟踪信息导入 /tmp/log。

4.3 跟踪音频

4.3.1 打开trace开关
echo 0 > /sys/kernel/debug/tracing/events/enable
echo 1 > /sys/kernel/debug/tracing/tracing_on
echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_path/enable
echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_start/enable
echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_walk_done/enable
echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_widget_power/enable
4.3.2 激活音频流

找到一个音频文件,播放音频:

root@rk3399:/# cd /
root@rk3399:/# aplay AbuduOffice.mp3
Playing raw data 'AbuduOffice.mp3' : Signed 16 bit Little Endian, rATE 8000 Hz, Mono

查看/sys/kernel/debug/tracing/trace:

root@rk3399:/# cat sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 142/142   #P:6
#
#                                _-----=> irqs-off/BH-disabled
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |
          amixer-4948    [004] .....  5890.895606: snd_soc_dapm_start: card=realtek,rt5651-codec
          amixer-4948    [004] .....  5890.895631: snd_soc_dapm_path: *Audio DSP <- (direct) <- DAC MIXR
          amixer-4948    [004] .....  5890.895633: snd_soc_dapm_path: *Audio DSP <- (direct) <- DAC MIXL
          amixer-4948    [004] .....  5890.895636: snd_soc_dapm_path:  Stereo DAC MIXL <- DAC R1 Switch <- DAC MIXR
          amixer-4948    [004] .....  5890.895638: snd_soc_dapm_path:  Stereo DAC MIXL <- DAC L2 Switch <- DAC L2 Volume
          amixer-4948    [004] .....  5890.895639: snd_soc_dapm_path:  Stereo DAC MIXL <- DAC L1 Switch <- Audio DSP
          amixer-4948    [004] .....  5890.895660: snd_soc_dapm_walk_done: realtek,rt5651-codec: checks 2 power, 2 path, 7 neighbour
          amixer-4949    [005] .....  5893.861746: snd_soc_dapm_start: card=realtek,rt5651-codec
          amixer-4949    [005] .....  5893.861788: snd_soc_dapm_walk_done: realtek,rt5651-codec: checks 2 power, 0 path, 0 neighbour
          amixer-4955    [005] .....  5999.186695: snd_soc_dapm_start: card=realtek,rt5651-codec
          amixer-4955    [005] .....  5999.186723: snd_soc_dapm_path: *DAC R1 <- (direct) <- Stereo DAC MIXR
          amixer-4955    [005] .....  5999.186726: snd_soc_dapm_path: *Stereo DAC MIXR <- DAC L1 Switch <- DAC MIXL
          amixer-4955    [005] .....  5999.186728: snd_soc_dapm_path:  Stereo DAC MIXR <- DAC R2 Switch <- DAC R2 Volume
          amixer-4955    [005] .....  5999.186730: snd_soc_dapm_path:  Stereo DAC MIXR <- DAC R1 Switch <- Audio DSP
          amixer-4955    [005] .....  5999.186732: snd_soc_dapm_path: *OUT MIXR <- DAC R1 Switch <- DAC R1
          amixer-4955    [005] .....  5999.186734: snd_soc_dapm_path:  OUT MIXR <- REC MIXR Switch <- RECMIXR
          amixer-4955    [005] .....  5999.186736: snd_soc_dapm_path:  OUT MIXR <- INR1 Switch <- INR1 VOL
          amixer-4955    [005] .....  5999.186737: snd_soc_dapm_path:  OUT MIXR <- BST1 Switch <- BST1
          amixer-4955    [005] .....  5999.186739: snd_soc_dapm_path:  OUT MIXR <- BST2 Switch <- BST2
          amixer-4955    [005] .....  5999.186761: snd_soc_dapm_walk_done: realtek,rt5651-codec: checks 2 power, 3 path, 12 neighbour
           aplay-4959    [004] .....  6120.491037: snd_soc_dapm_start: card=realtek,rt5651-codec
           aplay-4959    [004] .....  6120.491064: snd_soc_dapm_widget_power: widget=Playback val=1
           aplay-4959    [004] .....  6120.491066: snd_soc_dapm_widget_power: widget=AIF1 Playback val=1
           aplay-4959    [004] .....  6120.491069: snd_soc_dapm_path: *AIF1RX <- (direct) <- AIF1 Playback
           aplay-4959    [004] .....  6120.491071: snd_soc_dapm_widget_power: widget=AIF1RX val=1
           aplay-4959    [004] .....  6120.491073: snd_soc_dapm_path: *IF1 DAC <- (direct) <- AIF1RX
           aplay-4959    [004] .....  6120.491074: snd_soc_dapm_widget_power: widget=IF1 DAC val=1
           aplay-4959    [004] .....  6120.491078: snd_soc_dapm_widget_power: widget=I2S1 val=1
           aplay-4959    [004] .....  6120.491080: snd_soc_dapm_path: *IF1 DAC2 R <- (direct) <- IF1 DAC
           aplay-4959    [004] .....  6120.491082: snd_soc_dapm_path: *IF1 DAC2 L <- (direct) <- IF1 DAC
           aplay-4959    [004] .....  6120.491084: snd_soc_dapm_path: *IF1 DAC1 R <- (direct) <- IF1 DAC
           aplay-4959    [004] .....  6120.491085: snd_soc_dapm_widget_power: widget=IF1 DAC1 R val=1
           aplay-4959    [004] .....  6120.491087: snd_soc_dapm_path: *IF1 DAC1 L <- (direct) <- IF1 DAC
           aplay-4959    [004] .....  6120.491088: snd_soc_dapm_widget_power: widget=IF1 DAC1 L val=1
           aplay-4959    [004] .....  6120.491091: snd_soc_dapm_widget_power: widget=I2S1 ASRC val=1
           aplay-4959    [004] .....  6120.491094: snd_soc_dapm_path: *DAC MIXR <- INF1 Switch <- IF1 DAC1 R
           aplay-4959    [004] .....  6120.491097: snd_soc_dapm_path:  DAC MIXR <- Stereo ADC Switch <- Stereo1 ADC MIXR
           aplay-4959    [004] .....  6120.491098: snd_soc_dapm_widget_power: widget=DAC MIXR val=1
           aplay-4959    [004] .....  6120.491100: snd_soc_dapm_path: *DAC MIXL <- INF1 Switch <- IF1 DAC1 L
           aplay-4959    [004] .....  6120.491102: snd_soc_dapm_path:  DAC MIXL <- Stereo ADC Switch <- Stereo1 ADC MIXL
           aplay-4959    [004] .....  6120.491104: snd_soc_dapm_widget_power: widget=DAC MIXL val=1
           aplay-4959    [004] .....  6120.491106: snd_soc_dapm_path: *PDM R Mux <- DD MIX <- DAC MIXR
           aplay-4959    [004] .....  6120.491107: snd_soc_dapm_path:  PDM R Mux <- Stereo DAC MIX <- Stereo DAC MIXR
           aplay-4959    [004] .....  6120.491109: snd_soc_dapm_widget_power: widget=PDM R Mux val=1
           aplay-4959    [004] .....  6120.491111: snd_soc_dapm_path: *Stereo DAC MIXL <- DAC R1 Switch <- DAC MIXR
           aplay-4959    [004] .....  6120.491113: snd_soc_dapm_path:  Stereo DAC MIXL <- DAC L2 Switch <- DAC L2 Volume
           aplay-4959    [004] .....  6120.491114: snd_soc_dapm_path:  Stereo DAC MIXL <- DAC L1 Switch <- Audio DSP
           aplay-4959    [004] .....  6120.491116: snd_soc_dapm_path: *Audio DSP <- (direct) <- DAC MIXR
           aplay-4959    [004] .....  6120.491117: snd_soc_dapm_path: *Audio DSP <- (direct) <- DAC MIXL
           aplay-4959    [004] .....  6120.491119: snd_soc_dapm_path: *PDM L Mux <- DD MIX <- DAC MIXL
           aplay-4959    [004] .....  6120.491121: snd_soc_dapm_path:  PDM L Mux <- Stereo DAC MIX <- Stereo DAC MIXL
           aplay-4959    [004] .....  6120.491122: snd_soc_dapm_widget_power: widget=PDM L Mux val=1
           aplay-4959    [004] .....  6120.491124: snd_soc_dapm_path: *Stereo DAC MIXR <- DAC L1 Switch <- DAC MIXL
           aplay-4959    [004] .....  6120.491126: snd_soc_dapm_path:  Stereo DAC MIXR <- DAC R2 Switch <- DAC R2 Volume
           aplay-4959    [004] .....  6120.491128: snd_soc_dapm_path:  Stereo DAC MIXR <- DAC R1 Switch <- Audio DSP
           aplay-4959    [004] .....  6120.491129: snd_soc_dapm_path: *PDMR <- (direct) <- PDM R Mux
           aplay-4959    [004] .....  6120.491131: snd_soc_dapm_widget_power: widget=PDMR val=1
           aplay-4959    [004] .....  6120.491132: snd_soc_dapm_path: *PDML <- (direct) <- PDM L Mux
           aplay-4959    [004] .....  6120.491134: snd_soc_dapm_widget_power: widget=PDML val=1
           aplay-4959    [004] .....  6120.491155: snd_soc_dapm_walk_done: realtek,rt5651-codec: checks 19 power, 17 path, 31 neighbour

alsa在录音/播放前会先检查snd_soc_dapm_path(带"*")能否连成一路完整的routing,如果失败,录音/播放的进程会自动停止。

如果录音/播放的trace不完整,检查codec驱动中的snd_soc_dapm_route,从右到左,能否连接成一路complete path。

参考文章:

[1] 如何查看声卡、pcm设备以及tinyplay、tinymix、tinycap的使用

[2] linux音频 DAPM之二:audio paths与dapm kcontrol

[3] Linux 原生跟踪工具 Ftrace

[4] linux tracers使用介绍

[5] Linux音频调试示例

标签:snd,Rockchip,ALC5651,soc,RK3399,rk3399,tracing,root,numid
From: https://www.cnblogs.com/zyly/p/17591417.html

相关文章

  • Rockchip RK3399 - Machine驱动(simple-card)
     ----------------------------------------------------------------------------------------------------------------------------开发板:NanoPC-T4开发板eMMC:16GBLPDDR3:4GB显示屏:15.6英寸HDMI接口显示屏u-boot:2023.04linux  :6.3------------------------......
  • Rockchip RK3399 - Codec驱动( Realtek ALC5651)
    ----------------------------------------------------------------------------------------------------------------------------开发板:NanoPC-T4开发板eMMC:16GBLPDDR3:4GB显示屏:15.6英寸HDMI接口显示屏u-boot:2023.04linux :6.3----------------------------......
  • Rockchip RK3399 - Platform驱动(DMA&i2s0)
    Platfromdriver提供了配置/使能SoC音频接口的能力;Plaftrom驱动分为两个部分:snd_soc_platform_driver、snd_soc_dai_driver。snd_soc_platform_driver:负责管理音频数据,把音频数据通过DMA或其他操作传送至CPUDAI中;snd_soc_dai_driver:负责完成SoC一侧的DAI参数配置,同时也会通过......
  • Rockchip RK3399 - 音频调试
    一、内核配置1.1配置内核修改sound/soc/codecs/Kconfig文件,搜索configSND_SOC_RT5651,将该项修configSND_SOC_RT5651tristatedependsonI2C改为,如果不修改的话,makemenuconfig是看不到该配置项的;configSND_SOC_RT5651tristate"RealtekAL......
  • Rockchip RK3399 - DAPM
    DAPM是DynamicAudioPowerManagement的缩写,即动态音频电源管理,旨在允许便携式Linux设备在任何时候使用音频子系统中的最小电量。它独立于其他内核PowerManager,故可以很容易地与其他PM系统共存。DAPM对所有用户空间应用程序来说也是完全透明的,因为所有电源切换都是在ASoC核心内......
  • Rockchip RK3399 - Machine驱动
    Machinedriver描述了如何控制platform、codec、cpudai(DigitalAudioInterface,数字音频接口)和codecdai,使得互相配合在一起工作,Machine驱动代码位于sound/soc/generic/simple-card.c文件。一、设备节点1.1设备节点rt5651-sound我们在arch/arm64/boot/dts/rockchip/rk3399-ev......
  • Rockchip RK3399 - Codec驱动基础
    在上一篇博客我们介绍了ALSA子系统的软件架构,同时介绍了ALSACORE核心数据结构和相关API。本节我们将会介绍ASoC软件体系中音频三大驱动模块:Codec、Platform和Machine。一、ASoC核心数据结构我们首先来了解Codec、Platform和Machine驱动中涉及到的数据结构,知道每个数据结构以......
  • Rockchip RK3399 - Platform驱动
    Platfromdriver提供了配置/使能SoC音频接口的能力;Plaftrom驱动分为两个部分:snd_soc_platform_driver、snd_soc_dai_driver。snd_soc_platform_driver:负责管理音频数据,把音频数据通过DMA或其他操作传送至CPUDAI中;snd_soc_dai_driver:负责完成SoC一侧的DAI参数配置,同时也会通过......
  • Rockchip RK3399 - Codec驱动( Realtek ALC5651)
    Codecdriver提供了配置/使能Codec的能力,驱动代码位于sound/soc/codecs/rt5651.c文件。一、设备节点1.1设备节点rt5651我们在arch/arm64/boot/dts/rockchip/rk3399-evb.dts文件添加rt5651设备节点,该节点位于i2c1节点下:&i2c1{status="okay";i2c-scl-rising-time......
  • Rockchip rk3588 U-Boot详解 (三)
    Rockchiprk3588U-Boot详解(三)专栏总目录1.1Environment-VariablesENV(Environment-Variables)是U-Boot支持的一种全局数据管理和传递方式,原理是构建一张HASH映射表,把用户的数据以"键值-数据"作为表项进行管理。EVN通常用于定义平台配置参数:固件加载地址、网络配置(ipaddr、serve......