【Audio Driver】ACDB文件加载

文章目录

  • 1 acdb介绍
  • 2 文件目录
    • 2.1 codebase中存放位置
    • 2.2如何区分选择哪个文件夹
    • 2.3如何获取acdb文件
  • 3 如何加载acdb文件
    • 3.1 文件信息
    • 3.2 解析文件函数及调用流程
      • 3.2.1 acdb 加载流程
      • 3.2.2 解析后的数据存放
      • 3.2.3 再上级函数调用
  • 4 总结

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目录下会有很多版本,选择自己对应的芯片

【Audio Driver】ACDB文件加载_第1张图片

进入到项目目录后可以看见两个文件夹一个android.mk文件
acdbdata/chip_name目录
【Audio Driver】ACDB文件加载_第2张图片

QRD,全称为Qualcomm Reference Design。
QRD就是高通参考设计(Qualcomm Reference Design)。QRD提供完整的参考设计平台,包括硬件、软件和用户界面,类似一个“交钥匙”或者“一站式”解决方案。
MTP目前没有找到对应的全称。
[注]如何区分选择哪个文件参见2.2介绍

【Audio Driver】ACDB文件加载_第3张图片
在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就是不同版本的硬件平台,项目中都会遇见,具体如何区分,以后再找时间介绍
【Audio Driver】ACDB文件加载_第4张图片

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()函数,该函数内会获取文件名(文件的名字及文件路径)
【Audio Driver】ACDB文件加载_第5张图片
【注】声卡同名目录下的文件名获取成功后就直接跳出该函数,下面的其他版本不处理。

重点看下处理函数

	/* 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
【Audio Driver】ACDB文件加载_第6张图片

将上面三个参数存入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 加载流程

【Audio Driver】ACDB文件加载_第7张图片
上一小节获取到了文件路径及文件名,之后就会对这些acdb文件进行解析,然后存储。本小节重点介绍如何存放数据

建议找到acdb_loader.c文件中的acdb_loader_init_v3()函数,对照上图查看代码会更清楚。

acdb load初始化流程

  1. 存储文件名
    acdb_load_files()函数会执行上节介绍的get_files_from_device_tree(),用于存储文件名。
  2. 解析文件
    注意这里是用的acdb_ioctl(ACDB_CMD_INITIALIZE_V2…),要找到对应的处理情况(acdb_command.c)。最终会执行到AcdbCmdInitializeAcdb(),最终解析文件的就是这个函数。
    下一节的重点就在这里。
  3. 打开字符设备存放
    最开始介绍了acdb的全称,其中重点在于calibration,这里我们就可以看到为什么。
    open("/dev/msm_audio_cal"),打开该设备,然后将open后的fd传给全局变量cal_driver_handle,注意,这个全局变量用于send calibration。之后send_audio_calibration_XXX()函数会访问这个全局变量,然后将数据存放到该dev中。

3.2.2 解析后的数据存放

【Audio Driver】ACDB文件加载_第8张图片
找到acdb_command.c文件中的AcdbCmdInitializeAcdb()函数
简单介绍下流程,不细讲了。

  1. 创建两个临时变量用于存放数据
  2. 遍历每个acdb文件,将文件中数据存放到临时变量中
  3. acdbdata_ioctl()使用cmd命令将临时变量中的内容存放到全局变量中

acdb文件 -> 临时变量pCmdFileInfos -> 全局变量gDataFileInfo

具体调用感兴趣可以细看下代码,这一块主要就是用acdbdata_ioctl(),可能会有点绕(其实简单的,主要是了解这个机制),要根据命令找到对应的处理情况,然后再找到处理函数。

小结:至此我们就将acdb文件中的数据提取出来了。当然,这一块只是初始化部分,之后还会有数据的修改。

3.2.3 再上级函数调用

【Audio Driver】ACDB文件加载_第9张图片
这节也只是简单介绍下流程,如果有人想要详细的介绍我到时候再写吧。

刚刚我们看完了acdb_loader_init_v3()函数,加载acdb文件,这里看看这个函数如何被调用到的。

第一步:acdb_loader_init_v3()哪来的
在acdb_init()或者acdb_init_v2()函数中

  1. 获取platform_info,这里主要是为了2
  2. 加载platform_info.xml文件,处理snd_dev和acdb_id映射关系
  3. 打开libacdbloader.so库,提取函数句柄(acdb_loader_init_v3就是从库里提取出来的)
  4. 获取声卡名
  5. 初始化acdb_platform_data
  6. 灯灯灯,acdb文件加载acdb_loader_init_v3()
    注意,加载函数有好几种,要看清最终使用的是哪个

第二步:acdb_init()/acdb_init_v2()在哪里调用
我们极其重要的函数platform_init()登场了。@platform.c

  1. 处理platform_info.xml文件
  2. acdb文件加载(上面介绍的内容)
  3. 打开hw_dep文件传输calibration
    这里有个很关键的设备处理函数audio_hwdep_send_cal(),会将calibration数据从上文提及的全局变量中提取出来。
    【Audio Driver】ACDB文件加载_第10张图片
    这一块主要就是将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文件加载流程(一)
这三篇文章相对详细的介绍了相关函数

你可能感兴趣的:(audio)