【MTK】ES7210、ES7243E Driver调试

1.概要

由于项目需要实现 4 路MIC 以及 2 路Speaker回采输入android系统,硬件是一个ES7210用来采集4路MIC,一个ES7243E用来采集2路Speaker回采,组成类似6路麦克风输入系统。系统SoC无法支持TDM,所以只能将两个设备挂I2S上进行来调试。本文说说驱动调试过程,对遇见的问题做一个记录。

2.整体架构流程

在这里插入图片描述
系统播放音频时,ES7243E回采数据,通过I2S传送给ES7210, 同时ES7210通过录音获取到4路MIC的数据,总共6路数据通过I2S传输给系统,系统通过算法将数据以16000hz来将数据分成6个通道的数据,其中4路为MIC,2路为Speaker。从而可以使用这数据进行录音降噪处理。

3. ES7210、ES7243E Driver

1.编译配置:

原厂提供了E7210、ES7243E 二合一 Driver 代码,将对应的driver代码放置如下路径,并配置好编译宏控。

kernel-4.14/sound/soc/codecs/

修改kernel-4.14/sound/soc/codecs/Makefile

obj-$(CONFIG_STARMINI_ES7210) += es7210/

2.配置设备树DTS:
提供过来的代码默认采用过的是I2C_detect方式注册。
可以通过宏控改dts方式注册

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

代码默认配置是用DTS方式注册I2C。

因此需要在对应项目的DTS内,写上对应的设备节点:

	MicArray_1@40 {
		compatible = "MicArray_1"; /* ES7210 这里是根据驱动内的of_device_id来配置*/
		reg = <0x40>;
		status = "okay";
	};
	es7243e@10 {
		compatible = "es7243e"; 
		reg = <0x10>;
		status = "okay";
	};

3. 驱动挂载:
因默认没有驱动内没有针对ES7243E DTS注册I2C的驱动代码,需要自己简单写下ES7243E注册设备的驱动代码。

static int es7243e_i2c_probe(struct i2c_client *i2c,
				   const struct i2c_device_id *i2c_id)
{
	struct es7210_priv *es7243e;
		
	SMLOG("begin->>>>>>>>>>!\n");
	
	es7243e = devm_kzalloc(&i2c->dev, sizeof(struct es7210_priv), GFP_KERNEL);
	if (es7243e == NULL)
		return -ENOMEM;
  	es7243e->i2c = i2c;
	es7243e->tdm_mode =  ES7210_WORK_MODE;  //to set tdm mode or normal mode
	dev_set_drvdata(&i2c->dev, es7243e);
	i2c_clt1[1] = i2c;  /* 原厂驱动默认是通过这个i2c_client数组来控制分别控制 ES7210、ES7243E  */
	SMLOG("end->>>>>>>>>>!\n");
	return 0;
}
static int __exit es7243e_i2c_remove(struct i2c_client *i2c)
{
	SMLOG("\n");
	kfree(i2c_get_clientdata(i2c));
	return 0;
}
static const struct i2c_device_id es7243e_i2c_id[] = {
	{ "es7243e", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, es7243e_i2c_id);
static const struct of_device_id es7243e_dt_ids[] = {
	{ .compatible = "es7243e", },//es7210_0
};
MODULE_DEVICE_TABLE(of, es7243e_dt_ids);
static struct i2c_driver es7243e_i2c_driver = {
	.driver = {
        .name = "es7243e",
        .owner = THIS_MODULE,
        .of_match_table = es7243e_dt_ids,
    },
	.probe = es7243e_i2c_probe,
	.remove = __exit_p(es7243e_i2c_remove),
	.class  = I2C_CLASS_HWMON,
	.id_table = es7243e_i2c_id,

};

/* 在如下代码内加上对ES7243E的注册函数  */

static int __init es7210_modinit(void)
{
	int ret;
	//,i;
	//struct i2c_adapter *adapter;
    //	struct i2c_client *client;
	SMLOG("%s enter es7210\n",__func__);
#ifdef !ES7210_MATCH_DTS_EN
	adapter = i2c_get_adapter(ES7210_I2C_BUS_NUM);
    	if (!adapter) {
        	printk("i2c_get_adapter() fail!\n");
        	return -ENODEV;
    	}
	printk("%s() begin0000",__func__);

    	for(i = 0; i < ADC_DEV_MAXNUM; i++) {
        	client = i2c_new_device(adapter, &es7210_i2c_board_info[i]);
        	printk("%s() i2c_new_device\n",__func__);
        	if (!client)
            	return -ENODEV;
    	}
	i2c_put_adapter(adapter);
#endif
	ret = i2c_add_driver(&es7243e_i2c_driver); /* add ES7243E driver */
	if (ret != 0)
		pr_err("Failed to register es7243E i2c driver : %d \n", ret);
	ret = i2c_add_driver(&es7210_i2c_driver);
	if (ret != 0)
		pr_err("Failed to register es7210 i2c driver : %d \n", ret);
	return ret;
}

4. 驱动配置:

/* 4路MIC 2路Speaker 则相当于有6路MIC进入 */
#define ES7210_TDM_ENABLE	ENABLE
#define ES7210_CHANNELS_MAX	MIC_CHN_6
/* 由于项目只用了一路I2S来抓取录音,需要配置将TDM的模式配置*/
#define ES7210_WORK_MODE    ES7210_TDM_NLRCK_I2S
/* 这里根据LRCK、MCLK 频率来设置,具体要根据data sheet 跟示波器测量后来设置 */
#define ES7210_MCLK_LRCK_RATIO   RATIO_768

/* 配置codec */
kernel-4.14/sound/soc/mediatek/common_int/mtk-soc-machine.c
static struct snd_soc_dai_link mt_soc_extspk_dai[] = {
	{
	.....
	{
		.name = "I2S1_AWB_CAPTURE",
		.stream_name = MT_SOC_I2S2ADC2_STREAM_NAME,
		.cpu_dai_name = MT_SOC_I2S2ADC2DAI_NAME,
		.platform_name = MT_SOC_I2S2_ADC2_PCM,
#ifdef CONFIG_STARMINI_ES7210
		.codec_dai_name = "ES7210 4CH ADC 1", /* 需要与ES7210 driver 内的名字一样 */
		.codec_name = "es7210.1-0040",   /* 这里注意需要配置成ES7210内的一样,否则无法挂载*/
#else
		.codec_dai_name = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
#endif
		.ops = &mt_machine_audio_ops,
	},
	....
};
这里配置好,开机就会自动去挂载ES7210 4CH ADC 1 这个codec。

4. 调试过程中的问题点

  1. 查看ES7210/ES7243E I2C是否正常挂载上,如果没有挂载上,需要查看串口log找出挂载失败的原因并解决。
  2. 查看声卡是否正常注册上 cat /proc/asound/pcm,如果没有注册上声卡,还是需要通过log查看原因。
tb8788p1_64_wifi:/ # cat /proc/asound/pcm                                      
00-00: MultiMedia1_PLayback mt-soc-codec-tx-dai-0 :  : playback 1
.....
00-31: I2S2ADC2_Capture ES7210 4CH ADC 1-31 :  : capture 1  /* 此处为挂载成功的声卡 */
tb8788p1_64_wifi:/ #                        
  1. 在确保声卡挂载上后,就可以通过tinycap去录音:
tinycap /sdcard/file.wav -D 0 -d 31 -c 2 -r 48000  /* 参数具体含义,自行查询 */

如果录制出来的的文件内容都是全0的文件,就得排查,I2S的信号是否正常。

  1. MCLK没有波形:通过示波器抓波形,MCLK波形不起来,只有BCLK、LRCK有波形,TDM out(data pin)处于常高状态,顺芯FAE:如果MCLK没有起来的状况下可以通过将BCLK与MCLK短接,使得BCLK复用成MCLK。
    尝试了短接BCLK MCLK 但是PCMIN(data pin)还是处于常高状态,当时没有去排查是不是ES7210的寄存器是否正常。最终还是使用MCLK来调试的,具体的MCLK打开,需要跟平台走的I2S通道来配置。
    MCLK如果有打不开的情况,可以提CR咨询MTK协助处理,调试的时候,MCLK这块调试了好几天才出来。
kernel-4.14/sound/soc/mediatek/mt6771/mtk-auddrv-clk.c
void EnableI2SCLKDiv(unsigned int I2snum, bool bEnable) /* 通过该函数来打开MCLK */
void EnableALLbySampleRate(unsigned int SampleRate)    /* 通过该函数来修改MCLK频率 */

注意事项: MTK平台的I2S一般都是4组,I2S0/I2S2只支持输入,I2S1/I2S3只支持输出。
MCLK需要达到12.288Mhz

在这里插入图片描述

在I2S/PCM接口的ADC/DAC系统中,除了BCLK和FS(LRCLK)外,CODEC经常还需要控制器提供MCLK (Master Clock),这是由CODEC内部基于Delta-Sigma (ΔΣ)的架构设计要求使然。MCLK时钟频率一般为256*FS,具体参考特定器件手册。(硬件需要连接MCLK)

  1. 在确保MCLK LRCK BCLK 都有正常的波形后,TDM out(data pin)就有波形。但是录制出来的文件,导出来的文件还是全0状态。 这种情况就的排查ES7210的寄存器,这一步得更具规格书来调整ES7210寄存器的值。最终还是根据FAE提供的ES7210的寄存器初始化解决录制文件为全0的情况。
 通过i2cdump指令来查看 寄存器是否正确
130|tb8788p1_64_wifi:/ # i2cdump  -y -f 1 0x40                                 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 41 20 c3 04 01 00 04 20 30 30 30 02 00 09 ff ff    A ???.? 000?.???
10: 00 60 07 00 00 00 00 00 f7 f7 00 bf bf bf bf ff    .`?.....??.?????
20: 0a 2a 0a 2a 11 ff ff 0a ff ff ff 2a ff ff ff 2a    ?*?*???????*???*
30: ff ff ff 2a ff ff ff 2a ff ff ff ff ff 72 10 02    ???*???*?????r??
40: 42 70 70 1e 1e 1e 1e 08 08 08 08 00 00 ff ff ff    Bpp????????..???
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ????????????????
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ????????????????
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ????????????????
80: 41 20 c3 04 01 00 04 20 30 30 30 02 00 09 ff ff    A ???.? 000?.???
90: 00 60 07 00 00 00 00 00 f7 f7 00 bf bf bf bf ff    .`?.....??.?????
a0: 0a 2a 0a 2a 11 ff ff 0a ff ff ff 2a ff ff ff 2a    ?*?*???????*???*
b0: ff ff ff 2a ff ff ff 2a ff ff ff ff ff 72 10 02    ???*???*?????r??
c0: 42 70 70 1e 1e 1e 1e 08 08 08 08 00 00 ff ff ff    Bpp????????..???
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ????????????????
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ????????????????
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ????????????????


  1. 因为ES7243E跟ES7210是用的同一组I2S调试就很顺畅,只需要来简单配置寄存器正常初始化就可以正常回采数据了。

  2. 第一次录制回采都正常,第二次录制回采无效,初步判断,ES7243没有正常复位。通过代码重新复位初始化就正常了。

  3. 解决使用APK录音依旧无法录音问题

vendor/mediatek/proprietary/hardware/audio/common/V3/aud_drv/AudioALSACaptureDataProviderNormal.cpp
-    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmUl1Capture);
-    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmUl1Capture);
+    int pcmindex = AudioALSADeviceParser::getInstance()->GetPcmIndexByString(keypcmI2S2ADCCapture);
+    int cardindex = AudioALSADeviceParser::getInstance()->GetCardIndexByString(keypcmI2S2ADCCapture);
+    ALOGD("Healer %s: Capture card switch I2S2(+)", __FUNCTION__);
+

小结

调试ES7210、ES7243E Driver花了很长一段时间,主要时间还是花费在I2S这块,第一次调试,调试了一两天才知道接出来的I2S 不支持输入,后面飞线又改板才使用正确的I2S, 在MCLK这里有卡住了,最终还是寻求MTK才解决MCLK不出来的问题,主要还是因为很少调试I2S设备,基本都是LCD/TP/Camer/Sensor的调试,还有很多细节就没有写了,具体还是根据自身的调试情况来处理。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Healer_S

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值