Rockchip RK3399 - 音频调试

发布时间 2023-07-23 18:13:30作者: 大奥特曼打小怪兽

一、内核配置

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  ---> 
         <*> 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.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 下载工具

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

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

2.2 查看声卡设备

2.2.1 查看音频设备节点:

查看音频设备节点:

root@rk3399:/# ll dev/snd
crw-rw----  1 root audio 116,  4 Jul 23 13:55 controlC0
crw-rw----  1 root audio 116,  3 Jul 23 13:55 pcmC0D0c
crw-rw----  1 root audio 116,  2 Jul 23 13:55 pcmC0D0p
crw-rw----  1 root audio 116, 33 Jul 23 13:55 timer

其中:

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

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

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

2.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个字符。

或者通过以下命令查看所有声卡:

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

声卡分两种通道,一种是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.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

2.3 amixer 命令

通过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'
....

 

 

 

通过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
.......

因此从ALC5651数字音频接口到耳机的音频播放路径:AIF1 Playback --> AIF1RX --> IF1 DAC --> IF1 DAC1 L -->  IF1 DAC1 L --> DAC MIXL --> Audio DSP --> Stereo DAC MIXL --> DAC L1 -->OUT MIXL --> HPOVOL L --> HPOL MIX --> HP Amp --> HPO L Playback --> HPOL --> Headphones。

 

参考文章:

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