写点什么

OpenHarmony 支持 HDMI 接口声卡适配说明

  • 2023-05-23
    中国香港
  • 本文字数:7705 字

    阅读完需:约 25 分钟

OpenHarmony支持HDMI接口声卡适配说明

高清多媒体接口(High Definition Multimedia Interface,HDMI )是一种全数字化视频和声音发送接口,可以发送未压缩的音频及视频信号。HDMI 可用于机顶盒、DVD 播放机、个人计算机、电视、游戏主机、综合扩大机、数字音响与电视机等设备。HDMI 可以同时发送音频和视频信号,由于音频和视频信号采用同一条线材,大大简化系统线路的安装难度。这块是百度百科对 HDMI 的简单介绍,我们再看看 HDMI 不同版本对音频的支持情况:



当前我们使用最多的是 2.0 版本,本文介绍了 OpenHarmony 系统支持 HDMI 声卡的适配过程,带有 HDMI 声卡的设备包括电视、投影仪和一些带有音响的显示器。

1 功能描述

OpenHarmony 系统中音频系统使用 ADM 框架,下面是 ADM 框架的组成:



ADM 框架是基于 HDF 系统框架开发,Card Manager 是用来管理多个声卡链表,Controller 是声卡的控制模块包含了音量、静音、通路选择等控制功能。


Audio Control Dispath 是控制功能的中转站负责接收 HDI 下发的控制命令和将控制命令转发给各个声卡组件。


Audio Stream Dispatch 是数据流的中转站,播放过程中负责接收 HDI 的数据流,在录音过程中负责上传声卡的录音数据流。


Run Time Device 中包括的这些模块就是一个声卡工作需要的驱动服务。其中 codec 编解码模块驱动服务、dai 数字音频接口驱动服务和 platform 片上系统也就是 DMA 模块驱动服务是大多数声卡所必须的。HDMI 声卡和其他声卡一样由三个模块组成 codec 编解码模块、dai 数字音频接口和 platform 片上系统也就是 DMA 模块。


HDMI 的 codec 是集成在 HDMI 转换芯片内部的我们只需要将 PCM 音频流给到 HDMI 转换芯片就可以。DAI 这块使用的是 I2S 总线连接 HDMI 芯片和 platform。要实现对 HDMI 声卡的支持,就需要将这几个模块的驱动注册到 ADM 框架中。


本文基于 3 月 1 日的 OpenHarmony master 分支进行介绍。基于 yangfan 平台介绍,如适配其他平台相关配置根据具体平台进行修改。


OpenHarmony 系统支持 HDMI 声卡的插拔识别,支持 HDMI 声卡的播放功能,包括启动、停止、暂停、恢复功能。


2 准备工作

2.1 查询物理连接



这是一个 HDMI 设备模块的逻辑试图,图中可以看到音频数据可以通过两种接口 I2S 或者 SPIDIF 将音频数据传给 HDMI 设备,此处我们使用的是 I2S 总线。



首先需要查看芯片手册 HDMI 模块和 SOC 是如何连接的,找到音频数据传输相应的 I2S 总线,这块是更具 rk3568 芯片查到的数据,I2S0 连接的是 HDMI。



2.2 查询寄存器地址

因为我们使用 I2S 总线就要对其进行配置所以我们需要找到 I2S 总线的基地址和 I2S 总线的寄存器说明。查看芯片手册找到 I2S 总线对应的寄存器基地址。


3 代码介绍

HDMI 的驱动 codec 的代码 ADM 框架中已经实现了,我们只需要根据不同的单板平台修改平台下面的配置文件。Dai 和 platform 的驱动代码需要根据各自平台自行开发。yangfan 开发板 Dai 和 platform 驱动代码路径在 device\board\isoftstone\yangfan\kernel\hdf\drivers\audio 下面的 dai 和 soc 目录下面。


涉及到的配置文件如下:

├── audio_config.hcs   // 此配置文件配置声卡信息├── codec_config.hcs   // 此配置文件配置codec信息├── dai_config.hcs     // 此配置文件配置dai信息└── dma_config.hcs    // 此配置文件配置platform信息vendor/isoftstone/yangfan/hdf_config/khdf/device_info/device_info.hcs  //此配置文件配置声卡驱动服务信息
复制代码


修改涉及的代码仓:device_board_hihope、vendor_isoftstone 和 kernel_linux_config

4 构建开关

OpenHarmony 系统要支持 HDMI 声卡首先要打开构建开关:在文件 kernel/linux/config/linux-5.10/arch/arm64/configs/rockchip_standard_defconfig 添加:CONFIG_DRIVERS_HDF_AUDIO_HDMI=y

5 功能配置

HCS(HDF Configuration Source)是 HDF 驱动框架的配置描述源码,内容以 Key-Value 为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。


5.1 配置文件:device_info.hcs 添加 hdmi 声卡节点信息。

文件路径:vendor/isoftstone/yangfan/hdf_config/khdf/device_info/

HDMI 声卡插入后系统会根据此处配置的声卡节点加载 HDMI 声卡驱动。


audio :: host {            hostName = "audio_host";            priority = 110;            device_dai :: device {...                device_hdmi :: deviceNode {                    policy = 1;                    priority = 50;                    preload = 0;                    permission = 0666;                    moduleName = "DAI_RK3568";                    serviceName = "hdmi_dai_service";                    deviceMatchAttr = "hdf_hdmi_dai_driver";                }            }            device_codec :: device {...                device_hdmi :: deviceNode {                    policy = 1;                    priority = 50;                    preload = 0;                    permission = 0666;                    moduleName = "AUDIO_HDMI_CODEC";                    serviceName = "codec_service_1";                    deviceMatchAttr = "hdf_codec_driver_1";                }...            }...            device_dma :: device {...                device_hdmi :: deviceNode {                    policy = 1;                    priority = 50;                    preload = 0;                    permission = 0666;                    moduleName = "DMA_RK3568";                    serviceName = "hdmi_dma_service_0";                    deviceMatchAttr = "hdf_hdmi_dma_driver";                }...            }
device_audio :: device {... device_hdmi :: deviceNode { policy = 2; priority = 60; preload = 2; permission = 0666; moduleName = "HDF_AUDIO"; deviceMatchAttr = "hdf_audio_driver_1"; serviceName = "hdf_audio_codec_hdmi_dev0"; }... }... }
复制代码


moduleName 配置组件名称,和驱动代码中的 moduleName 相对应,系统会根据此名称加载驱动。

deviceMatchAttr 私有配置的属性名称,根据此名称可以找到相应的私有配置。

serviceName 驱动服务名称,根据此名称可以使用对应的驱动。

preload 配置加载方式,2 为动态加载,当 HDMI 声卡插入时加载 HDMI 声卡驱动。

此文件中首先配置了文件首先先配置了 HDMI 的 dai、codec 和 dma 驱动服务,最后配置了 HDMI 声卡设备。


5.2 配置文件:audio_config.hcs 添加 hdmi 声卡服务信息。

文件路径:vendor/isoftstone/yangfan/hdf_config/khdf/audio/

此处配置一个 HDMI 声卡驱动包括哪些驱动服务。

root {    platform {...        controller_0x120c1001 :: card_controller {            match_attr = "hdf_audio_driver_1";            serviceName = "hdf_audio_codec_hdmi_dev0";            codecName = "codec_service_1";            platformName = "hdmi_dma_service_0";            cpuDaiName = "hdmi_dai_service";            codecDaiName = "hdmi_codec_dai";        }...    }}
复制代码


card_controller 配置项根据声卡包含的驱动服务进行配置,不同声卡包含的驱动服务可能不同,HDMI 声卡包含 platform、dai 和 codec 所以需要配置 codecName codec 驱动服务名称,platformName platform 驱动服务名称、cpuDaiName platform 侧 dai 服务名称、codecDaiName codec 侧驱动服务名称。


match_attr 配置项名称和 HDMI 声卡设备的私有配置名称相匹配,声卡设备可以根据这个私有配置找到声卡对应的 codec、dai、platform 驱动服务。


serviceName HDMI 声卡服务名称,声卡加载成功后会生成/dev/hdf_audio_codec_hdmi_dev0 结点。


5.3 配置文件:dma_config.hcs 添加 HDMI 声卡硬件信息。

文件路径:vendor/isoftstone/yangfan/hdf_config/khdf/audio/

此文件配置和 HDMI 声卡连接的 SOC 侧的 DMA 信息。具体信息可以通过查看 cpu 芯片手册得到。

        root {    platform {        template dma_controller {            match_attr = "";            serviceName = "";        }...        controller_0x120c1011 :: dma_controller {            match_attr = "hdf_hdmi_dma_driver";            serviceName = "hdmi_dma_service_0";
idInfo { chipName = "/i2s@fe400000"; // 根据hdmi驱动芯片连接的I2S总线地址进行配置 chipIdRegister = 0xfe400000; // 根据hdmi驱动芯片连接的I2S总线地址进行配置 chipIdSize = 0x1000; } regConfig { daiStartupSeqConfig = [ 0x00, 0x00, 0, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0x0, //Transmit Operation Init ]; } } }}
复制代码


此文件配置了 HDMI 声卡使用的 dma 信息。

match_attr 配置项名称和 HDMI 声卡设备的 dma 服务私有配置名称相匹配。serviceName HDMI 声卡 dma 驱动服务名称需要和 device_info 配置文件中 HDMI 声卡的 dma 驱动服务名称相同。

HDMI 模块只需要配置 idInfo 配置项信息,其他配置项 HDMI 模块未使用。


5.4 配置文件:dai_config.hcs 添加 HDMI 声卡硬件信息。

文件路径:vendor/isoftstone/yangfan/hdf_config/khdf/audio/

此文件配置和 HDMI 声卡连接的 SOC 侧的 i2s 信息。具体信息可以通过查看 cpu 芯片手册得到。

       root {    platform {        template dai_controller {            match_attr = "";            serviceName = "";        }...        controller_0x120c1021 :: dai_controller {            match_attr = "hdf_hdmi_dai_driver";            serviceName = "hdmi_dai_service";
idInfo { chipName = "/i2s@fe400000"; // 根据hdmi驱动芯片连接的I2S总线地址进行配置 chipIdRegister = 0xfe400000; // 根据hdmi驱动芯片连接的I2S总线地址进行配置 chipIdSize = 0x1000; } regConfig { daiStartupSeqConfig = [ 0x00, 0x00, 0, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF, 0, 0x0, //Transmit Operation Init ]; } } }}
复制代码


此文件配置了 HDMI 声卡使用的 dai 信息。match_attr 配置项名称和 HDMI 声卡设备的 dai 服务私有配置名称相匹配。serviceName HDMI 声卡 dai 驱动服务名称需要和 device_info 配置文件中 HDMI 声卡的 dai 驱动服务名称相同。

chipIdRegister HDMI 驱动芯片连接的 I2S 总线地址,此信息可以通过 cpu 的芯片手册获取。

chipIdSize 物理地址映射的虚拟地址大小。


5.5 配置文件:codec_config.hcs 添加 HDMI 声卡硬件信息。

文件路径:vendor/isoftstone/yangfan/hdf_config/khdf/audio/

此文件配置 HDMI 声卡信息。由于 HDMI 声卡只支持播放,此处只配置了播放的参数信息。

     root {    platform {        template codec_controller {            match_attr = "";            serviceName = "";            codecDaiName = "";        }...        controller_0x120c1031 :: codec_controller {            match_attr = "hdf_codec_driver_1";            serviceName = "codec_service_1";            codecDaiName = "hdmi_codec_dai";
hwInfo = [ /* Playback/Captrue, formats, rates, rate_min, rate_max, channels_min, channels_max, buffer_bytes_max, period_bytes_min, period_bytes_max, periods_min, periods_max */ 1, 0xF, 0xFF, 8000, 96000, 1, 2, 1, 2, 3, 4, 5 ]; }...}
复制代码


此文件配置了 HDMI 声卡使用的 codec 信息。

match_attr 配置项名称和 HDMI 声卡设备的 codec 服务私有配置名称相匹配。serviceName HDMI 声卡 codec 驱动服务名称需要和 device_info 配置文件中 HDMI 声卡的 codec 驱动服务名称相同。

codecDaiName HDMI 声卡使用的 codec dai 的设备名称,此处名称需要和 audio_config 配置文件中的 codecDaiName 名称相同。

hwInfo 配置声卡的信息,包括声卡播放和录音支持的格式、采样率范围、通道范围、缓存 buffer 最大值、每个周期的字节范围、周期的范围。第一个配置项 Playback 对应的值为 1,Captrue 对应的值为 2。其他配置项没有使用。

HDMI 声卡只支持播放,这里只配置了播放,有些参数没有生效可以随便配置。

6 应用样例

audio_sample_render 是用来测试录音功能的工具,audio_sample_capture 是用来测试播放功能的工具,audio_sample_event 是用来检测 USB 插拔事件上报的工具。这两个工具可以通过编译得到,编译命令如下:

./build.sh --product-name yangfan -T audio_sample_render -T audio_sample_capture -T audio_sample_eventhdc shellcd /data/./audio_sample_render YoungForYou.wav
复制代码


7 功能验证

使用 hdc 工具推送 audio_sample_render 和 audio_sample_event 和 wav 音频文件到开发板 data 目录下:

hdc file send E:\audio_sample_render /datahdc file send E:\audio_sample_event /datahdc file send E:\xxx.wav /data
复制代码


HDMI 音频类设备插拔检测

进入 shell 端口进行一次 HDMI 设备插入、拔出流程。

hdc shell# cd /data/# chmod +x audio_sample_event#./audio_sample_event
复制代码


插入打印:


===============================================================================@@@@@ serviceName: audio_hdi_pnp_service@@@@@ deviceClass: 32@@@@@ status     : 1@@@@@ info       : EVENT_TYPE=0x1;DEVICE_TYPE=0x400===============================================================================
复制代码


拔出打印:


===============================================================================@@@@@ serviceName: audio_hdi_pnp_service@@@@@ deviceClass: 32@@@@@ status     : 1@@@@@ info       : EVENT_TYPE=0x2;DEVICE_TYPE=0x400===============================================================================
复制代码


HDMI 音频类设备放音

进入 shell 端口进行一次完整的播放、停止、退出流程。


hdc shell# cd /data/# chmod +x audio_sample_render## ./audio_sample_render YoungForYou.wav ==================== Loading Mode ===================| 1. Passthrough Loading                               || 2. IPC Loading                                       | ======================================================Please enter your choice:2 ================= Select Audio Card ================== 1. primary 2. primary1 3. hdmi 4. usb 5. a2dp ======================================================Please enter your choice:3 ================== Play Render Menu ==================| 1. Render Start                                      || 2. Render Stop                                       || 3. Render Resume                                     || 4. Render Pause                                      || 5. Render SetVolume                                  || 6. Render GetGain                                    || 7. Render SetMute                                    || 8. Render SetAttributes                              || 9. Render SelectScene                                || 10. Render getEXtParams                              || 11. Render getMmapPosition                           || 12.Exit                                              | ======================================================your choice is:1Music channels = 2Music Rate     = 44100 HzMusic Bit      = 16 bit ============= Play Render Mode ==========| 1. Render non-mmap                     || 2. Render mmap                         | ========================================Please enter your choice:1Start Successful,Music is playing ================== Play Render Menu ==================| 1. Render Start                                      || 2. Render Stop                                       || 3. Render Resume                                     || 4. Render Pause                                      || 5. Render SetVolume                                  || 6. Render GetGain                                    || 7. Render SetMute                                    || 8. Render SetAttributes                              || 9. Render SelectScene                                || 10. Render getEXtParams                              || 11. Render getMmapPosition                           || 12.Exit                                              | ======================================================your choice is:2Stop Successful ================== Play Render Menu ==================| 1. Render Start                                      || 2. Render Stop                                       || 3. Render Resume                                     || 4. Render Pause                                      || 5. Render SetVolume                                  || 6. Render GetGain                                    || 7. Render SetMute                                    || 8. Render SetAttributes                              || 9. Render SelectScene                                || 10. Render getEXtParams                              || 11. Render getMmapPosition                           || 12.Exit                                              | ======================================================your choice is:12
复制代码


8 总结

本文没有介绍 HDMI 声卡 codec 驱动的具体实现,代码路径 drivers/hdf_core/framework/model/audio/hdmi。平台适配支持 HDMI 声卡可以不用关注驱动的具体实现。


支持 HDMI 声卡是 OpenHarmony 系统使用中不可或缺的一部分,是 OpenHarmony 系统用于投影仪、电视显示和生活场景的重要功能,本文介绍了 OpenHarmony 系统支持 HDMI 声卡的适配步骤希望对您有所帮助。



用户头像

OpenHarmony开发者官方账号 2021-12-15 加入

OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代,基于开源的方式,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展

评论

发布
暂无评论
OpenHarmony支持HDMI接口声卡适配说明_OpenHarmony_OpenHarmony开发者_InfoQ写作社区