高清多媒体接口(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目录上面。

波及到的配置文件如下:vendor/isoftstone/yangfan/hdf_config/khdf/audio$ tree

├── 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声卡的适配步骤心愿对您有所帮忙。