目录
一、初始i2c查看寄存器
扩展 :设备的添加流程
二、i2c_probe成功,component_probe没有执行
三:无法开机日志报错Unable to handle kernel paging request at virtual address
四、正常probe后,查看日志输出
1、adb查看声卡注册信息
2、tinymix工具使用
测试
author | daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 daisy.skye_嵌入式,Linux,Qt-CSDN博客daisy.skye擅长嵌入式,Linux,Qt,等方面的知识https://blog.csdn.net/qq_40715266?type=blog |
即便设备的i2c驱动和device驱动都没有probe注册初始化,也可以通过i2c-tools工具进行i2c的访问和寄存器查看。可以初始排查以下几点内容:
i2c节点 |
&i2c4 { status = "okay"; es8316: es8316@10 { status = "okay"; #sound-dai-cells = <0>; compatible = "everest,es8316"; reg = <0x10>; //clocks = <&cru I2S1_MCLKOUT>; //clock-names = "mclk"; //assigned-clocks = <&cru I2S1_MCLKOUT>,<&cru I2S1_MCLK_TX_IOE>; //assigned-clock-rates = <12288000>; //assigned-clock-parents = <&cru I2S1_MCLKOUT_TX>, <&cru I2S1_MCLKOUT_TX>; // pinctrl-0 = <&i2s1m2_mclk>; pinctrl-names = "default"; }; }; 注释的内容在i2c节点这块非必备内容,也就是说你没有添加注释的内容,i2c节点也正常输出。 |
查看寄存器值 |
确保i2c以及供电线正常,这样才能查看到寄存器 |
kernel/drivers/base/devres.c
void devres_add(struct device *dev, void *res)
{
struct devres *dr = container_of(res, struct devres, data);
unsigned long flags;
spin_lock_irqsave(&dev->devres_lock, flags);
add_dr(dev, &dr->node);
spin_unlock_irqrestore(&dev->devres_lock, flags);
}
EXPORT_SYMBOL_GPL(devres_add);这段代码是 Linux 内核中的一个函数,用于向设备添加资源。该函数接收两个参数,一个是设备结构体的指针 dev,另一个是资源指针 res。这段代码的功能是向指定的设备添加一个资源,并保证在添加过程中对资源的互斥访问。当设备不再需要这个资源时,相关的释放函数会被自动调用,并且资源会被自动释放。
i2c注册和device注册是两个内容,一个是将设备的地址绑定到i2c总线上,一个是对设备参数进行初始化注册过程。有可能i2c正常初始化,device未正常probe;也可能device正常probe而i2c没有被probe。
检查代码编译的文件kernel/arch/arm64/boot/dts/rockchip/.rk3568.dtb.dts.tmp
是否含有es8316_sound 相关参数,如果没有说明你对应的dtsi的配置文件没有加上,或者是加的地方不对,并不是代码执行时所引用的地方
代码路径 |
kernel/arch/arm64/boot/dts/rockchip/rk3568.dtsi |
es8316_sound:es8316-sound{
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "rockchip,es8316";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,widgets =
"Microphone", "Microphone Jack",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"Microphone Jack", "MICBIAS1",
"MIC1", "Microphone Jack",
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR";
simple-audio-card,cpu {
sound-dai = <&i2s1_8ch>;
};
simple-audio-card,codec {
sound-dai = <&es8316>;
};
};
//注意要加 状态配置okay
&es8316_sound{
status = "okay";
};
mclk-fs的值256代表mclk是256倍的fs。fs一般等于LRCK,即采样率。
代码烧录后,无法开机,并且adb 无响应。不用太过慌张,可以使用串口工具进行查看日志输出,跟踪pc的位置进行分析clk_prepare引起的报错,也可以短接设备的触点进入maskrom模式,回退到上一个版本的镜像。
[ 3.392888] es8316 4-0010: daisy soc_probe_component name is es8316.4-0010
[ 3.392957] es8316 4-0010: daisy snd_soc_dapm_new_controls ret is 0
[ 3.392972] es8316 4-0010: daisy snd_soc_dapm_new_dai_widgets ret is 0
[ 3.393005] Unable to handle kernel paging request at virtual address fffffffffffffffe
[ 3.405482] Mem abort info:
[ 3.405737] ESR = 0x96000005
[ 3.406014] Exception class = DABT (current EL), IL = 32 bits
[ 3.406540] SET = 0, FnV = 0
[ 3.406815] EA = 0, S1PTW = 0
[ 3.407091] Data abort info:
[ 3.407374] ISV = 0, ISS = 0x00000005
[ 3.407758] CM = 0, WnR = 0
[ 3.408039] swapper pgtable: 4k pages, 39-bit VAs, pgdp = 00000000fb1c34fa
[ 3.408658] [fffffffffffffffe] pgd=0000000000000000, pud=0000000000000000
[ 3.409269] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[ 3.409766] Modules linked in:
[ 3.410044] Process kworker/0:0 (pid: 5, stack limit = 0x00000000fd129240)
[ 3.410654] CPU: 0 PID: 5 Comm: kworker/0:0 Not tainted 4.19.193 #117
[ 3.411224] Hardware name: Rockchip RK3568 EVB2 LP4X V10 Board (DT)
[ 3.411802] Workqueue: events deferred_probe_work_func
[ 3.412261] pstate: 20c00009 (nzCv daif +PAN +UAO)
[ 3.412695] pc : clk_prepare+0x14/0x40
[ 3.413036] lr : es8316_probe+0x40/0x110
[ 3.413381] sp : ffffff8009eeb9a0s
查看代码的位置哪里包含clk_prepare相关的内容以及上下文代码,可以分析时mclk的问题,说明在dtsi关于es8316的mclk没有正确的赋值引起的问题
static int es8316_probe(struct snd_soc_component *component)
{
struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
int ret = 0;
int ES8316_SERDATA1_mode;
es8316->mclk = devm_clk_get(component->dev, "mclk");
if (PTR_ERR(es8316->mclk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
ret = clk_prepare_enable(es8316->mclk);
……
}
查看内核时钟输出 |
cat /sys/kernel/debug/clk/clk_summary |
大部分是我自己加的日志方便看初始化过程中错误的位置
[ 3.284498] es8316 4-0010: daisy es8316 i2c probe
[ 3.284698] es8316 4-0010: daisy snd_soc_component_initialize ret is 0
[ 3.284713] es8316 4-0010: daisy dai name is ES8316 HiFi dai is -133767808
[ 3.284729] es8316 4-0010: daisy snd_soc_register_dais ret is 0
[ 3.284745] es8316 4-0010: daisy component list is es8316.4-0010
[ 3.284757] es8316 4-0010: daisy snd_soc_component_add
[ 3.284769] es8316 4-0010: daisy ret_es8316
[ 3.385761] asoc-simple-card es8316-sound: daisy card prob ret is 0 name is rockchip,es8316
[ 3.385839] es8316 4-0010: daisy soc_probe_component name is es8316.4-0010
[ 3.385914] es8316 4-0010: daisy snd_soc_dapm_new_controls ret is 0
[ 3.385930] es8316 4-0010: daisy snd_soc_dapm_new_dai_widgets ret is 0
[ 3.428644] vendor storage:20190527 ret = 0
[ 3.430264] es8316 4-0010: ES8316_SERDATA1_mode is 1
[ 3.430279] es8316 4-0010: daisy driver->probe name is es8316.4-0010 ret is 0
[ 3.433128] rockchip-i2s-tdm fe410000.i2s: daisy soc_probe_component name is fe410000.i2s
[ 3.433204] rockchip-i2s-tdm fe410000.i2s: daisy driver probe fe410000.i2s ret is 0
[ 3.436185] asoc-simple-card es8316-sound: ES8316 HiFi <-> fe410000.i2s mapping ok
rk3568_r:/ # cat /proc/asound/cards
0 [rockchipes8316 ]: rockchip_es8316 - rockchip,es8316
rockchip,es8316
1 [rockchiphdmi ]: rockchip_hdmi - rockchip,hdmi
rockchip,hdmi
设备信息
rk3568_r:/proc/asound # ls
card0 cards hwdep rockchipes8316 timers
card1 devices pcm rockchiphdmi version
rk3568_r:/proc/asound/rockchipes8316/pcm0c # cat info
card: 0
device: 0
subdevice: 0
stream: CAPTURE
id: fe410000.i2s-ES8316 HiFi ES8316 HiFi-0
name: fe410000.i2s-ES8316 HiFi ES8316 HiFi-0
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 1
tinymix查看声卡信息,下面的信息就是对应es8316部分的寄存器内容
tinymix 介绍 |
tinymix和音频控制:完整的指南_笔记大全_设计学院 |
rk3568_r:/ # tinymix Mixer name: 'rockchip,es8316' Number of controls: 34 ctl type num name value 0 INT 2 Headphone Playback Volume 3 3 1 INT 2 Headphone Mixer Volume -1 -1 2 ENUM 1 Playback Polarity Normal 3 INT 2 DAC Playback Volume -1 -1 4 BOOL 1 DAC Soft Ramp Switch Off 5 INT 1 DAC Soft Ramp Rate 4 6 BOOL 1 DAC Notch Filter Switch On 7 BOOL 1 DAC Double Fs Switch On 8 INT 1 DAC Stereo Enhancement -1 9 ENUM 1 Capture Polarity (null) 10 BOOL 1 Mic Boost Switch On 11 INT 1 ADC Capture Volume -1 12 INT 1 ADC PGA Gain Volume -1 13 BOOL 1 ADC Soft Ramp Switch On 14 BOOL 1 ADC Double Fs Switch Off 15 BOOL 1 ALC Capture Switch On 16 INT 1 ALC Capture Max Volume -1 17 INT 1 ALC Capture Min Volume -1 18 INT 1 ALC Capture Target Volume -1 19 INT 1 ALC Capture Hold Time -1 20 INT 1 ALC Capture Decay Time -1 21 INT 1 ALC Capture Attack Time -1 22 BOOL 1 ALC Capture Noise Gate Switch On 23 INT 1 ALC Capture Noise Gate Threshold -1 24 ENUM 1 ALC Capture Noise Gate Type (null) 25 ENUM 1 Differential Mux lin1-rin1 26 ENUM 1 Digital Mic Mux dmic disable 27 ENUM 1 DAC Source Mux LDATA TO LDAC, RDATA TO RDAC 28 ENUM 1 Left Headphone Mux lin1-rin1 29 ENUM 1 Right Headphone Mux lin1-rin1 30 BOOL 1 Left Headphone Mixer LLIN Switch Off 31 BOOL 1 Left Headphone Mixer Left DAC Switch Off 32 BOOL 1 Right Headphone Mixer RLIN Switch Off 33 BOOL 1 Right Headphone Mixer Right DAC Switch Off
C:\Users\fujy>adb shell rk3568_r:/ # tinypcminfo -D 0 -d 0 Info for card 0, device 0: PCM out: Access: 0x000009 Format[0]: 0x000044 Format[1]: 0x000010 Format Name: S16_LE, S24_LE, S20_3LE Subformat: 0x000001 Rate: min=16000Hz max=48000Hz Channels: min=2 max=2 Sample bits: min=16 max=32 Period size: min=4 max=65536 Period count: min=2 max=4096 PCM in: Access: 0x000009 Format[0]: 0x000044 Format[1]: 0x000010 Format Name: S16_LE, S24_LE, S20_3LE Subformat: 0x000001 Rate: min=16000Hz max=48000Hz Channels: min=2 max=2 Sample bits: min=16 max=32 Period size: min=4 max=65536 Period count: min=2 max=4096
C:\Users\fujy>adb shell rk3568_r:/ # cat proc/asound/pcm 00-00: fe410000.i2s-ES8316 HiFi ES8316 HiFi-0 : fe410000.i2s-ES8316 HiFi ES8316 HiFi-0 : playback 1 : capture 1 01-00: fe400000.i2s-i2s-hifi i2s-hifi-0 : fe400000.i2s-i2s-hifi i2s-hifi-0 : playback 1
rk3568_r:/ # adb push C:\Users\fujy\Desktop\1k.wav /data
rk3568_r:/ # tinyplay /data/1k.wav -D 0 -d 0 -p 1024 -n 3
Unable to open PCM device 0 (cannot set hw params: Invalid argument)
rk3568_r:/ # tinyplay /data/1k.wav -D 1 -d 0 -c 8 -r 16000
Playing sample: 2 ch, 44100 hz, 16 bit 10584000 bytes
rk3568_r:/sdcard # tinyplay /data/1k.wav -D 1 -d 0 -c 4
Unable to open PCM device (cannot open device '/dev/snd/pcmC1D0c': No such file or directory)
Captured 0 frames
rk3568_r:/ $ ls -l /dev/snd
total 0
crw-rw---- 1 system audio 116, 3 2023-12-22 14:37 controlC0
crw-rw---- 1 system audio 116, 6 2023-12-22 14:37 controlC1
crw-rw---- 1 system audio 116, 2 2023-12-22 14:37 pcmC0D0p
crw-rw---- 1 system audio 116, 5 2023-12-22 14:37 pcmC1D0c
crw-rw---- 1 system audio 116, 4 2023-12-22 14:37 pcmC1D0p
crw-rw---- 1 system audio 116, 33 2023-12-22 14:37 timer
rk3568_r:/ $ cat /proc/asound/ca
card0/ card1/ cards
rk3568_r:/ $ cat /proc/asound/cards
0 [rockchiphdmi ]: rockchip_hdmi - rockchip,hdmi
rockchip,hdmi
1 [rockchiprk809co]: rockchip_rk809- - rockchip,rk809-codec
rockchip,rk809-codec
rk3568_r:/ $ dmesg | grep 8316
rk3568_r:/sdcard # chmod 666 /dev/snd/controlC0
rk3568_r:/sdcard # chmod 666 /dev/snd/pcmC0D0c
rk3568_r:/sdcard # tinycap /sdcard/Music/22.wav -D 0 -d 0 -r 16000 -b 16 -T 5
Capturing sample: 2 ch, 16000 hz, 16 bit
Captured 81920 frames
rk3568_r:/ # tinyplay /data/16-2.wav -D 0 -d 0 -r 16000 -b 16 -T 5
Playing sample: 2 ch, 16000 hz, 16 bit 326404 bytes
参数解析 |
名称解析 |
-D card 声卡 -d device 设备 -c channels 通道 -r rate 采样率 -b bits pcm 位宽 -p period_size 一次中断的帧数 -n n_periods 周期数 |
controlC0: 起控制作用,C0表示Card0 pcmC0D0c: Card 0,Device 0 capture,用来录音。 pcmC0D0p: Card 0,Device 0 playback,用来录音。 pcmC0D1c: Card 0,Device 1 capture,用来录音。 pcmC0D1p: Card 0,Device 1 playback,用来录音。 对应的card的内容可以通过 |
参考文档 |
linux rk3568 es8326声卡移植 rk3399添加ES7210+ES8156录音/播放测试 rk3399 Android7.1音频底层调试tinyalsa |