文章目录
1 acdb介绍
参考文章:qcom 音频相关的dsp driver笔记(基于msm8996平台)
这个文章介绍的特别详细。
acdb,全称:audio calibration database(重点在calibration)
总结:acdb就是dsp的参数配置文件,主要用于控制dsp的内部通路
2 文件目录
2.1 codebase中存放位置
使用版本:android 10
目录:android\vendor\qcom\proprietary\mm-audio-cal\audcal\acdbdata
使用版本:android 8
目录:android\vendor\qcom\proprietary\mm-audio\audcal\family-b\acdbdata
[注]具体要看codebase版本,实在找不到的话,可以直接在vendor目录下搜索acdbdata目录
在acdbdata目录下会有很多版本,选择自己对应的芯片
进入到项目目录后可以看见两个文件夹一个android.mk文件
acdbdata/chip_name目录
QRD,全称为Qualcomm Reference Design。
QRD就是高通参考设计(Qualcomm Reference Design)。QRD提供完整的参考设计平台,包括硬件、软件和用户界面,类似一个“交钥匙”或者“一站式”解决方案。
MTP目前没有找到对应的全称。
[注]如何区分选择哪个文件参见2.2介绍
在QRD目录中存放了声卡同名的目录,以及默认的acdb文件(QRD目录下直接存放的),我们实际项目加载的就是对应声卡目录下的acdb文件,所以在新项目中我们需要在QRD/MTP目录下创建和声卡同名的目录,并将找到的acdb文件放在其中。
[注]acdb文件查找参见
2.2如何区分选择哪个文件夹
cat sys/devices/soc0/hw_platform
在codebase中查找acdb_loader.c文件,如下代码显示将打开sys/devices/soc0/hw_platform文件,直接使用cat 命令,可以查看到在QRD还是MTP目录。
其实QRD和MTP就是不同版本的硬件平台,项目中都会遇见,具体如何区分,以后再找时间介绍
2.3如何获取acdb文件
方法一:向高通发case询问
方法二:在codebase中会有几个参考文件,比如QRD目录下的acdb文件,或者声卡同名目录下的。
【注】需要根据自己项目的特点去选择,需要区分好这几个参考文件的区别,选择合适的。
在dts中查找到声卡名,查看参考文件声卡名下选择slimbus还是soundwire,还有内部or外部codec,等等。对照自己的项目要求选择。
3 如何加载acdb文件
3.1 文件信息
处理函数:get_files_from_device_tree()
@acdb_loader.c
在acdb_loader.c文件中找到get_files_from_device_tree()函数,该函数内会获取文件名(文件的名字及文件路径)
【注】声卡同名目录下的文件名获取成功后就直接跳出该函数,下面的其他版本不处理。
重点看下处理函数
/* Try board directory with soundcard name */
if (snd_card_name != NULL) {
result = snprintf(dir_path, sizeof(dir_path), "%s/%s/%s", ACDB_BIN_PATH, board_type, snd_card_name);
if (result < 0) {
LOGE("ACDB -> Error: snprintf failed for snd card %s, error: %d\n", snd_card_name, result);
result = -ENODEV;
goto done;
}
result = get_acdb_files_in_directory(acdb_init_cmd, dir_path);
if (result > 0)
goto done;
}
snd_card_name:声卡名
board_type:从hw_platform获取的(QRD/MTP)
ACDB_BIN_PATH:默认路径,没有找到定义,如果有找到的可以交流一下在哪个文件中 。推测应该就是vendor/etc/acdbdata(这个是终端中的路径)
【补充】找到了ACDB_BIN_PATH的定义,在Makefile.am中
路径为android\vendor\qcom\proprietary\mm-audio-cal\audio-acdb-util\acdb-loader\src\Makefile.am
在上一级目录中的Android.mk文件会重新定义,此定义会覆盖掉
android\vendor\qcom\proprietary\mm-audio-cal\audio-acdb-util\acdb-loader\Android.mk
将上面三个参数存入dir_path,然后执行get_acdb_files_in_directory()函数就可以打开该目录,将文件名存放到acdb_init_cmd变量中
acdb_init_cmd类型
/**
Query command structure for the command ACDB_CMD_INITIALIZE_V2.
*/
struct _AcdbInitCmdType {
uint32_t nNoOfFiles;
/**< Number of ACDB files to read from the acdbFiles array. */
AcdbFileName acdbFiles[20];
/**< Array of ACDB file names. A maximum of 20 ACDB files can be
provided at one time to be initialized. */
}
可以发现该变量中包含了AcdbFileName类型,这就是用来存放acdb文件名的,这里文件名包含了路径。
3.2 解析文件函数及调用流程
3.2.1 acdb 加载流程
上一小节获取到了文件路径及文件名,之后就会对这些acdb文件进行解析,然后存储。本小节重点介绍如何存放数据
建议找到acdb_loader.c文件中的acdb_loader_init_v3()函数,对照上图查看代码会更清楚。
acdb load初始化流程
- 存储文件名
acdb_load_files()函数会执行上节介绍的get_files_from_device_tree(),用于存储文件名。 - 解析文件
注意这里是用的acdb_ioctl(ACDB_CMD_INITIALIZE_V2…),要找到对应的处理情况(acdb_command.c)。最终会执行到AcdbCmdInitializeAcdb(),最终解析文件的就是这个函数。
下一节的重点就在这里。 - 打开字符设备存放
最开始介绍了acdb的全称,其中重点在于calibration,这里我们就可以看到为什么。
open("/dev/msm_audio_cal"),打开该设备,然后将open后的fd传给全局变量cal_driver_handle,注意,这个全局变量用于send calibration。之后send_audio_calibration_XXX()函数会访问这个全局变量,然后将数据存放到该dev中。
3.2.2 解析后的数据存放
找到acdb_command.c文件中的AcdbCmdInitializeAcdb()函数
简单介绍下流程,不细讲了。
- 创建两个临时变量用于存放数据
- 遍历每个acdb文件,将文件中数据存放到临时变量中
- acdbdata_ioctl()使用cmd命令将临时变量中的内容存放到全局变量中
acdb文件 -> 临时变量pCmdFileInfos -> 全局变量gDataFileInfo
具体调用感兴趣可以细看下代码,这一块主要就是用acdbdata_ioctl(),可能会有点绕(其实简单的,主要是了解这个机制),要根据命令找到对应的处理情况,然后再找到处理函数。
小结:至此我们就将acdb文件中的数据提取出来了。当然,这一块只是初始化部分,之后还会有数据的修改。
3.2.3 再上级函数调用
这节也只是简单介绍下流程,如果有人想要详细的介绍我到时候再写吧。
刚刚我们看完了acdb_loader_init_v3()函数,加载acdb文件,这里看看这个函数如何被调用到的。
第一步:acdb_loader_init_v3()哪来的
在acdb_init()或者acdb_init_v2()函数中
- 获取platform_info,这里主要是为了2
- 加载platform_info.xml文件,处理snd_dev和acdb_id映射关系
- 打开libacdbloader.so库,提取函数句柄(acdb_loader_init_v3就是从库里提取出来的)
- 获取声卡名
- 初始化acdb_platform_data
- 灯灯灯,acdb文件加载acdb_loader_init_v3()
注意,加载函数有好几种,要看清最终使用的是哪个
第二步:acdb_init()/acdb_init_v2()在哪里调用
我们极其重要的函数platform_init()登场了。@platform.c
- 处理platform_info.xml文件
- acdb文件加载(上面介绍的内容)
- 打开hw_dep文件传输calibration
这里有个很关键的设备处理函数audio_hwdep_send_cal(),会将calibration数据从上文提及的全局变量中提取出来。
这一块主要就是将calibration从全局变量中取出来,然后存放到hwC0D1000中
全局变量gDataFileInfo -> hwC0D1000
4 总结
本文从acdb文件的存放,到文件名的获取,再到acdb文件的加载流程进行了介绍。重点部分是文件的加载流程。
数据的flow
acdb文件 -> 临时变量pCmdFileInfos -> 全局变量gDataFileInfo -> hwC0D1000
遗留的问题:hwC0D1000之后如何对数据进行处理,这一块就要看具体的驱动怎么写的了,之后有空再分析。
至此acdb文件的初始化基本有了了解,具体的调试部分有空再整理。
建议阅读文章:
[Linux Audio Driver] ACDB文件加载流程(完结篇)
[Linux Audio Driver] ACDB文件加载流程(二)
[Linux Audio Driver] ACDB文件加载流程(一)
这三篇文章相对详细的介绍了相关函数