[RK3308H_Linux] 关于8+2(8路模拟麦克风 + 2路es7243e回采)的调试心得

问题描述

RK3308H 使用8路个模拟麦克风录音,2路用es7243e做回采


解决方案:

首先先调8路模拟麦克风,根据原理图确定使用的是哪路I2S。
以下为dts配置,acodec的属性注释附上。

&acodec {
	status = "okay";
	rockchip,micbias1;
	rockchip,micbias2;
	// 该属性表明在系统休眠的时候 CODEC 不进入低功耗模式,以适应更快速的响应需求,
	// 适合对功耗不是很在意的场景。
	rockchip,no-deep-low-power;
	// 该属性可以让指定的 ADC group 打开一次之后就常开,主要应用于与 VAD 配合的场
	// 景,即在休眠的时候不关闭与 VAD 相关的 ADC,达到快速响应的功能。
	rockchip,en-always-grps = <0 1 2 3>;
	// 0 MIC1,MIC2
	// 1 MIC3,MIC4
	// 2 MIC5,MIC6
	// 3 MIC7,MIC8
	rockchip,adc-grps-route = <0 1 2 3>;
	// CODEC 就不会去使能 hp-det 的功能。如果目标板硬件上没有用 CODEC
	// 的耳机检测功能,CODEC hp-det pin 悬空,该属性强烈建议加上,否则会引起耳机插入
	// 误报的现象。
	rockchip,no-hp-det;
	// 选用的 PA 的启动时延不同。该属性指定了打开回采后,需要----
	// 等待的稳定时延才重新打开对应的 ADC,避免回采数据抖动。
	// rockchip,delay-loopback-handle-ms= <200>;
	rockchip,delay-start-play-ms = <200>;
	// 指定的是模拟 PA 对应的连接的 ADC group,通过这个属性,codec driver
	// 会在合适的时间打开回采,以节省功耗。
	// rockchip,loopback-grp = <1>;
	// 指定了控制喇叭通路的 gpio pin。在喇叭通路使能下,播放/关闭音乐的时候
	// #spk-ctl-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
};

acodec_sound: acodec-sound {
	compatible = "rockchip,multicodecs-card";
	rockchip,card-name = "rockchip,rk3308-acodec";
	rockchip,codec-hp-det;
	rockchip,mclk-fs = <256>;
	rockchip,cpu = <&i2s_8ch_2>;
	rockchip,codec = <&acodec>;
	status = "okay";
};

&i2s_8ch_2 {
	status = "okay";
};

按照以上配置,使用cat /proc/asound/cards查看声卡是否注册成功,如果没有注册成功,使用dmesg | grep acodec进一步查询未注册成功的原因。
在这里插入图片描述
可以看到我这里是已经注册成功了。然后使用arecord -D hw:0,0 -c 8 -r 16000 -f S16_LE /oem/output.wav命令进行录音。将生成的wav文件通过adb pull出来。使用Audacity音频软件查看。
在这里插入图片描述
可以看到8个声道都能正常录制到声音。

调试过程中遇到问题有:
a.麦克风全是电流声音
b.1/3/5/7路麦克风无声音
c.8/路麦克风声音小
a问题需要让硬件检查麦克风小板的电路电阻
b/c问题是因为我们麦克风小板是手帖非机贴,贴坏了。更换之后就能正常录制到8路声音了

然后需要调试2路走es7243e_sound的回采通路,这里我按照其他dts相关配置配置es7243e_sound,

es7243_sound: es7243-sound {
	status = "okay";
	compatible = "simple-audio-card";
	simple-audio-card,name = "rockchip,es7243e";
	simple-audio-card,format = "i2s";
	simple-audio-card,mclk-fs = <256>;

	simple-audio-card,cpu {
		sound-dai = <&i2s_2ch_0>;
	};
	
	simple-audio-card,codec {
		sound-dai = <&es7243>;
	};
};

&i2s_2ch_0{
	status = "okay";
};

&i2c2 {
	status = "okay";
	es7243e: es7243e@10 {
		status = "okay";
		#sound-dai-cells = <0>;
		compatible = "ES7243E_MicArray_0";
		reg = <0x10>;
	};

	es7243e_11: es7243e@11 {
		status = "okay";
		#sound-dai-cells = <0>;
		compatible = "ES7243E_MicArray_1";
		reg = <0x11>;
	};

	es7243e_12: es7243e@12 {
		status = "okay";
		#sound-dai-cells = <0>;
		compatible = "ES7243E_MicArray_2";
		reg = <0x12>;
	};
};

使用 cat /proc/asound/cards发现声卡已经挂上
在这里插入图片描述
但是I2C2地址全是XX
在这里插入图片描述
这明显不对,从I2C错误码看,并没有识别到正常工作的设备或者从机地址。
然后经过曲折的示波器/逻辑分析仪排查,发现XX贴的是已经停产的es7243而非es7243e。这就很尴尬。然后等新的es7243e样品到了更换之后,I2C通信就正常了。
在这里插入图片描述
I2C通信就正常后,发现rockchip_es7243e声卡可以挂上,但是es7243e驱动在es7243e_read和es7243e_write时还是会报错误
在这里插入图片描述
这是需要找es7243e芯片顺芯FAE那边要5.10版本的7243驱动。按照提供的文档配置dts和es7243l.h。驱动一直打印找不到MCLK
在这里插入图片描述
这是在es7243l_probe里加上这个:
es7243l->sysclk = 12288000;
然后在这里加上system-clock-frequency这个属性,然后录音需要使用48k采样率。

    simple-audio-card,cpu {
        sound-dai = <&i2s3_2ch>;
        system-clock-frequency = <12288000>; 
    };
    simple-audio-card,codec {
        sound-dai = <&dummy_codec>;
        system-clock-frequency = <12288000>;
    };

驱动不提示MCL错误了。使用arecord -D hw:1,0 -c 2 -r 48000 -f S16_LE /oem/es7243.wav命令录制出来的音频无声音。然后各种排查,各种示波器量波形,发现录音时 I2S0压根没任何波形。

最后经过排查原来用的i2s_8ch_0而非i2s_2ch_0,一直以为2路用的是2ch,原来只是使用了8ch里面的2路而已,这里调试这个浪费了很多时间,也希望大家引以为戒,先根据原理图确定到底用的是哪个I2S0
最后附上可以成功使用的dts配置

    es7243e_sound: es7243e-sound {
        status = "okay";
        compatible = "rockchip,multicodecs-card";
        rockchip,card-name = "rockchip,es7243e";
        rockchip,mclk-fs = <256>;
        rockchip,format = "i2s";
		rockchip,cpu = <&i2s_8ch_0>;
        rockchip,codec = <&es7243l>;
    };
    
	// es7243_sound: es7243-sound {
	// 	status = "okay";
	// 	compatible = "simple-audio-card";
	// 	simple-audio-card,name = "rockchip,es7243e";
	// 	simple-audio-card,format = "i2s";
	// 	simple-audio-card,mclk-fs = <256>;
	// 	simple-audio-card,cpu {
	// 		sound-dai = <&i2s_8ch_0>;
	// 	};
	// 	simple-audio-card,codec {
	// 		sound-dai = <&es7243l>;
	// 	};
	// };
	
&i2s_8ch_0 {
	status = "okay";
	#sound-dai-cells = <0>;
	assigned-clocks = <&cru SCLK_I2S0_8CH_RX>;
	assigned-clock-parents = <&cru SCLK_I2S0_8CH_TX_MUX>;
	rockchip,clk-trcm = <1>;
	pinctrl-names = "default";
	pinctrl-0 = <&i2s_8ch_0_sclktx
	&i2s_8ch_0_lrcktx
	&i2s_8ch_0_sdi0
	&i2s_8ch_0_sdo0>;
};

&i2c2 {
	status = "okay";

    es7243l: es7243l@10 {
        status = "okay";
        #sound-dai-cells = <0>;
        compatible = "MicArray_0";
        reg = <0x10>;
        clocks = <&cru SCLK_I2S0_8CH_TX_OUT>;
        clock-names = "mclk";
        pinctrl-names = "default";
        pinctrl-0 = <&i2s_8ch_0_mclk>;
    };
};

其中simple-audio-card和multicodecs-card2个配置都是可以正常录音的。
用TDM格式,单line传输多通道数据的话,就用simple-audio-card
用I2S格式,多line同时使用,并且每条line传输2ch的话,就用multicodecs-card

最后es7243e驱动部分需要注意es7243l.h

#define ES7243l_CHANNELS_MAX    AIN_2_CH
#define VDDA_VOLTAGE	VDDA_3V3

ES7243l_CHANNELS_MAX属性需要根据自己的声道选择,不让会跑飞。
es7243e需要将VDDA_VOLTAGE 改为VDDA_3V3。

es7243l.c驱动部分需要修改

es7243l->sysclk = 12288000;

在es7243l_probe中添加以上属性


这个错误提示意味着es8388驱动没有正确设置主时钟(MCLK)。一般情况下,主时钟是由系统时钟(Sysclk)经过分频得到的。因此,需要在驱动程序中调用set_sysclk()函数来设置系统时钟,然后根据需要计算出主时钟的频率并设置主时钟。以下是一个示例代码片段,以供参考: ``` static int es8388_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct es8388_priv *es8388; int ret; es8388 = devm_kzalloc(&client->dev, sizeof(struct es8388_priv), GFP_KERNEL); if (!es8388) return -ENOMEM; es8388->regmap = devm_regmap_init_i2c(client, &es8388_regmap_config); if (IS_ERR(es8388->regmap)) { dev_err(&client->dev, "Failed to allocate register map\n"); return PTR_ERR(es8388->regmap); } ret = es8388_reset(es8388); if (ret) return ret; ret = es8388_set_fmt(es8388, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret) return ret; ret = es8388_set_sysclk(es8388, ES8388_SYSCLK_MCLK, 256 * 1024 * 1024, 256 * 1024 * 1024); if (ret) return ret; ret = devm_snd_soc_register_component(&client->dev, &es8388_component_driver, es8388_dai, 1); if (ret) { dev_err(&client->dev, "Failed to register component: %d\n", ret); return ret; } return 0; } ``` 在这个代码片段中,我们调用了es8388_set_sysclk()函数来设置主时钟的频率。在这个函数中,第一个参数指定了主时钟的源,第二个参数是主时钟的频率,第三个参数是系统时钟的频率。在这个例子中,我们将主时钟的频率设置为256MHz,系统时钟的频率也为256MHz。 如果您仍然无法解决问题,请查看您的驱动程序代码,确保正确设置了主时钟。如果问题仍然存在,请提供更详细的信息,以便我们更好地帮助您解决问题。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值