• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# HDMI
2
3
4## 概述
5
6### 功能简介
7
8HDMI(High Definition Multimedia Interface),即高清多媒体接口,是Hitachi、Panasonic、Philips、Silicon Image、Sony、Thomson、Toshiba共同发布的一款音视频传输协议,主要用于DVD、机顶盒等音视频Source设备到TV、显示器等Sink设备的传输。HDMI传输过程遵循TMDS(Transition Minimized Differential Signaling)协议。
9
10### 基本概念
11
12- TMDS(Transition Minimized Differential signal):过渡调制差分信号,也被称为最小化传输差分信号,用于发送音频、视频及各种辅助数据。
13
14- DDC(Display Data Channel):显示数据通道,发送端与接收端可利用DDC通道得知彼此的发送与接收能力,但HDMI仅需单向获知接收端(显示器)的能力。
15
16- CEC(Consumer Electronics Control):消费电子控制,该功能应该能够在连接HDMI的发送设备与接收设备之间实现交互操作。
17
18- FRL(Fixed Rate Link):TMDS的架构进行讯号传输时,最高带宽可达18Gbps,而FRL模式的带宽则提升到48Gbps。
19
20- HDCP(High-bandwidth Digital Content Protection):即高带宽数字内容保护技术,当用户对高清晰信号进行非法复制时,该技术会进行干扰,降低复制出来的影像的质量,从而对内容进行保护。
21
22
23### 运作机制
24
25在HDF框架中,HDMI的接口适配模式采用独立服务模式(如图1)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用率。
26
27 **图 1**  HDMI独立服务模式
28
29![image1](figures/独立服务模式结构图.png)
30
31### 约束与限制
32
33HDMI模块当前仅支持轻量和小型系统内核(LiteOS) 。
34
35## 开发指导
36
37### 场景介绍
38
39HDMI具有体积小、传输速率高、传输带宽宽、兼容性好、能同时传输无压缩音视频信号等优点。与传统的全模拟接口相比,HDMI不但增加了设备间接线的便捷性,还提供了一些HDMI特有的智能化功能,可用于小体积设备进行高质量音视频传输的场景。
40
41### 接口说明
42
43HdmiCntlrOps定义:
44```c
45struct HdmiCntlrOps {
46    void (*hardWareInit)(struct HdmiCntlr *cntlr);
47    void (*hardWareStatusGet)(struct HdmiCntlr *cntlr, struct HdmiHardwareStatus *status);
48    void (*controllerReset)(struct HdmiCntlr *cntlr);
49    bool (*hotPlugStateGet)(struct HdmiCntlr *cntlr);
50    bool (*hotPlugInterruptStateGet)(struct HdmiCntlr *cntlr);
51    void (*lowPowerSet)(struct HdmiCntlr *cntlr, bool enable);
52    void (*tmdsModeSet)(struct HdmiCntlr *cntlr, enum HdmiTmdsModeType mode);
53    int32_t (*tmdsConfigSet)(struct HdmiCntlr *cntlr, struct HdmiTmdsConfig mode);
54    void (*infoFrameEnable)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoFrameType, bool enable);
55    int32_t (*infoFrameSend)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoFrameType, uint8_t *data, uint32_t len);
56    int32_t (*infoFrameDataSet)(struct HdmiCntlr *cntlr, uint32_t type, uint8_t *data, uint32_t len);
57    int32_t (*cecMsgSend)(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg);
58    void (*audioPathEnable)(struct HdmiCntlr *cntlr, bool enable);
59    void (*audioPathSet)(struct HdmiCntlr *cntlr, struct HdmiAudioConfigInfo *config);
60    void (*phyOutputEnable)(struct HdmiCntlr *cntlr, bool enable);
61    void (*phyOutputSet)(struct HdmiCntlr *cntlr, struct HdmiPhyCfg *cfg);
62    void (*blackDataSet)(struct HdmiCntlr *cntlr, bool enable);
63    void (*videoMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
64    void (*videoPathSet)(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr);
65    void (*audioMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
66    void (*avmuteSet)(struct HdmiCntlr *cntlr, bool enable);
67    int32_t (*ddcTransfer)(struct HdmiCntlr *cntlr, struct HdmiDdcCfg *ddcCfg);
68    bool (*scdcSourceScrambleGet)(struct HdmiCntlr *cntlr);
69    int32_t (*scdcSourceScrambleSet)(struct HdmiCntlr *cntlr, bool enable);
70    void (*frlSet)(struct HdmiCntlr *cntlr);
71    int32_t (*frlEnable)(struct HdmiCntlr *cntlr, bool enable);
72    int32_t (*audioNctsSet)(struct HdmiCntlr *cntlr, struct HdmiFrlAudioNctsConfig *cfg);
73    void (*frlTrainingConfigSet)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainConfig *cfg);
74    void (*frlTrainingStart)(struct HdmiCntlr *cntlr);
75    void (*frlGetTriningRslt)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainRslt *rslt);
76    void (*hdcpRegInit)(struct HdmiCntlr *cntlr);
77    int32_t (*hdcpGenerateAksvAndAn)(struct HdmiCntlr *cntlr);
78    int32_t (*hdcpOptReg)(struct HdmiCntlr *cntlr, enum HdmiHdcpRegOptType type, uint8_t *data, uint32_t len);
79    void (*hdrTimerSet)(struct HdmiCntlr *cntlr, struct HdmiHdrTimerConfig *config);
80};
81```
82
83**表1** HdmiCntlrOps结构体成员的回调函数功能说明
84
85| 函数成员                 | 入参                                                         | 出参                                   | 返回值             | 功能                                               |
86| ------------------------ | ------------------------------------------------------------ | -------------------------------------- | ------------------ | -------------------------------------------------- |
87| hardWareInit             | **cntlr**:结构体指针,核心层HDMI控制器 | 无 | 无 | 初始化HDMI硬件 |
88| hardWareStatusGet        | **cntlr**:结构体指针,核心层HDMI控制器<br /> | **status**:HDMI硬件状态 ; | 无 | 获取HDMI当前硬件状态 |
89| controllerReset          | **cntlr**:结构体指针,核心层HDMI控制器 | 无 | 无 | 复位HDMI控制器 |
90| hotPlugStateGet          | **cntlr**:结构体指针,核心层HDMI控制器 | 无 | bool:HDMI热插拔状态 | 获取HDMI热插拔状态 |
91| hotPlugInterruptStateGet | **cntlr**:结构体指针,核心层HDMI控制器 | 无 | bool:HDMI热插拔中断状态 | 获取HDMI热插拔中断状态 |
92| lowPowerSet              | **cntlr**:结构体指针,核心层HDMI控制器<br />**enable**:bool,使能/去使能 | 无 | 无 | 使能/去使能低功耗 |
93| tmdsModeSet              | **cntlr**:结构体指针,核心层HDMI控制器<br />**mode**:TMDS模式 | 无 | 无 | 设置TMDS模式 |
94| tmdsConfigSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**mode**:TMDS参数 | 无 | HDF_STATUS相关状态 | 配置TMDS参数 |
95| infoFrameEnable | **cntlr**:结构体指针,核心层HDMI控制器<br />**infoFrameType**:packet类型<br />**enable**:bool,使能/去使能 | 无 | 无 | 使能/去使能infoFrame |
96| infoFrameSend | **cntlr**:结构体指针,核心层HDMI控制器<br />**infoFrameType**:packet类型<br />**data**:infoFrame数据<br />**len**:数据长度 | 无 | HDF_STATUS相关状态 | 发送infoFrame |
97| cecMsgSend | **cntlr**:结构体指针,核心层HDMI控制器<br />**msg**:CEC消息 | 无 | HDF_STATUS相关状态 | 发送CEC消息 |
98| audioPathEnable | **cntlr**:结构体指针,核心层HDMI控制器<br />**enable**:bool,使能/去使能| 无 | 无 | 使能/去使能audio通路 |
99| audioPathSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**config**:配置信息 | 无 | 无 | 设置audio通路配置信息 |
100| phyOutputEnable | **cntlr**:结构体指针,核心层HDMI控制器<br />**enable**:bool,使能/去使能 | 无 | 无 | 使能/去使能物理层输出状态 |
101| phyOutputSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**cfg**:配置信息 | 无 | 无 | 设置物理层配置信息 |
102| blackDataSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**enable**:bool,使能/去使能 | 无 | 无 | 设置黑屏 |
103| videoMuteEnable | **cntlr**:结构体指针,核心层HDMI控制器<br />**enable**:bool,使能/去使能 | 无 | 无 | 使能/去使能video静音 |
104| videoPathSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**attr**:配置信息| 无 | 无 | 设置video通路配置信息 |
105|audioMuteEnable | **cntlr**:结构体指针,核心层HDMI控制器<br />**enable**:bool,使能/去使能 | 无 | 无 | 使能/去使能audio静音 |
106| avmuteSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**enable**:bool,使能/去使能| 无 | 无 | 使能/去使能声音图像消隐 |
107| ddcTransfer | **cntlr**:结构体指针,核心层HDMI控制器<br />**ddcCfg**:DDC配置参数 |**ddcCfg**:DDC配置参数 |HDF_STATUS相关状态 | 读写DDC数据 |
108| scdcSourceScrambleGet | **cntlr**:结构体指针,核心层HDMI控制器 | 无 | bool,加扰状态 | 获取source端的加扰状态 |
109| scdcSourceScrambleSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**enable**:bool,使能/去使能 | 无 | HDF_STATUS相关状态 | 使能/去使能source端的加扰 |
110| frlEnable | **cntlr**:结构体指针,核心层HDMI控制器<br />**enable**:bool,使能/去使能 | 无 | HDF_STATUS相关状态 | 使能/去使能FRL |
111| audioNctsSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**cfg**:N/CTS配置参数 | 无 | HDF_STATUS相关状态 | 设置audio的N/CTS信息 |
112| frlTrainingConfigSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**cfg**:FRL Training配置参数 | 无 | 无| 设置FRL Training配置信息 |
113| frlTrainingStart | **cntlr**:结构体指针,核心层HDMI控制器 | 无 | 无 | 开始FRL Training流程 |
114| frlGetTriningRslt | **cntlr**:结构体指针,核心层HDMI控制器 | **rslt**:FRL Training结果 | 无 | 获取FRL Training结果 |
115| hdcpRegInit | **cntlr**:结构体指针,核心层HDMI控制器 | 无 | 无 | 初始化HDCP流程相关的寄存器 |
116|hdcpGenerateAksvAndAn |**cntlr**:结构体指针,核心层HDMI控制器 | 无 | HDF_STATUS相关状态 | HDCP流程中生成aksv和an |
117| hdcpOptReg | **cntlr**:结构体指针,核心层HDMI控制器<br />**type**:操作类型<br />**data**:寄存器数据<br />**len**:数据长度 | **data**:寄存器数据 | HDF_STATUS相关状态 | HDCP流程中读写相关寄存器 |
118| hdrTimerSet | **cntlr**:结构体指针,核心层HDMI控制器<br />**config**:timer配置信息 | 无 | 无 | 设置HDR相关的timer配置信息 |
119
120
121### 开发步骤
122
123HDMI模块适配的三个环节是实例化驱动入口、配置属性文件以及实例化HDMI控制器对象。
124
125- 实例化驱动入口:
126    - 实例化HdfDriverEntry结构体成员。
127    - 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。
128
129- 配置属性文件:
130    - 在device_info.hcs文件中添加deviceNode描述。
131    - 【可选】添加hdmi_config.hcs器件属性文件。
132
133- 实例化HDMI控制器对象:
134    - 初始化HdmiCntlr成员。
135    - 实例化HdmiCntlr成员HdmiCntlrOps方法集合。
136
1371. 实例化驱动入口
138
139    驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。
140
141    一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
142
143    HDMI驱动入口参考:
144
145    ```c
146    struct HdfDriverEntry g_hdmiDriverEntry = {
147        .moduleVersion = 1,
148        .Bind = HdmiAdapterBind,
149        .Init = HdmiAdapterInit,
150        .Release = HdmiAdapterRelease,
151        .moduleName = "adapter_hdmi_driver",//【必要】与HCS里面的名字匹配
152    };
153    HDF_INIT(g_hdmiDriverEntry);            // 调用HDF_INIT将驱动入口注册到HDF框架中
154    ```
155
1562. 配置属性文件
157
158    完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在hdmi_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值对于厂商驱动的实现以及核心层HdmiCntlr相关成员的默认值或限制范围有密切关系。
159
160    从第一个节点开始配置具体HDMI控制器信息,此节点并不表示某一路HDMI控制器,而是代表一个资源性质设备,用于描述一类HDMI控制器的信息。本例只有一个HDMI控制器,如有多个控制器,则需要在device_info文件增加deviceNode信息,以及在hdmi_config文件中增加对应的器件属性。
161
162    - device_info.hcs配置参考
163
164        ```c
165        root {
166            platform :: host {
167                 device_hdmi :: device {
168                    device0 :: deviceNode {
169                        policy = 2;                                // 等于2,需要发布服务。
170                        priority = 20;                             // 驱动启动优先级。
171                        permission = 0644;                         // 驱动创建设备节点权限。
172                        serviceName = "HDF_PLATFORM_HDMI_0";       //【必要】驱动对外发布服务的名称,必须唯一。
173                        moduleName = "hdmi_driver";                //【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致。
174                        deviceMatchAttr = "adapter_hdmi_driver";   //【必要】用于配置控制器私有数据,要与hdmi_config.hcs中对应控制器保持一致。
175                    }                                              // 具体的控制器信息在hdmi_config.hcs中。
176                 }
177            }
178        }
179        ```
180
181    - hdmi_config.hcs 配置参考
182
183        ```c
184         root {
185             platform {
186                hdmi_config {
187                    template hdmi_controller {     // 模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省。
188                        match_attr = "";           //【必要】需要和device_info.hcs中的deviceMatchAttr值一致。
189                        index = 0;                 //【必要】hdmi控制器编号
190                        regBasePhy = 0x10100000;   //【必要】寄存器物理基地址
191                        regSize = 0xd1;            //【必要】寄存器位宽
192                        irqNum = 100;              //【必要】中断号
193                        maxTmdsClock = 300;
194                        videoTiming = 10;
195                        quantization = 1;
196                        colorSpace = 0;
197                        colorimetry = 0;
198                        audioIfType = 0;
199                        audioBitDepth = 1;
200                        audioSampleRate = 2;
201                        audioChannels = 1;
202                        hdrColorimetry = 4;
203                        hdrUserMode = 1;
204                        cap = 0xd001e045;
205                    }
206                    controller_0x10100000 :: hdmi_controller {
207                        match_attr = "adapter_hdmi_driver";
208                        index = 0;
209                        regBasePhy = 0x10100000;
210                        irqNum = 100;
211                        maxTmdsClock = 400;
212                        defTmdsClock = 300;
213                        maxFrlRate = 600;
214                        videoTiming = 10;
215                        quantization = 1;
216                        colorSpace = 0;
217                        colorimetry = 0;
218                        audioIfType = 0;
219                        audioSampleRate = 2;
220                        audioChannels = 1;
221                        hdrColorimetry = 4;
222                        hdrUserMode = 1;
223                        cap = 0xd001e045;
224                    }
225                }
226            }
227        }
228        ```
229
2303. 实例化控制器对象
231
232    最后一步,完成驱动入口注册之后,要以核心层HdmiCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化HdmiCntlr成员HdmiCntlrOps(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。
233
234    - 自定义结构体参考
235
236        > ![](../public_sys-resources/icon-note.gif) **说明:**<br>
237        > 从驱动角度看,自定义结构体是参数和数据的载体。HDF会读取hdmi_config.hcs文件中的数值并通过DeviceResourceIface来初始化结构体成员,且其中一些重要数值(例如设备号、总线号等)也会被传递给核心层HdmiCntlr对象。
238
239        ```c
240        struct HdmiAdapterHost {
241            struct HdmiCntlr *cntlr;        //【必要】是核心层控制对象,具体描述如下。
242            volatile unsigned char *regBase;//【必要】寄存器基地址
243            uint32_t regBasePhy;            //【必要】寄存器物理基地址
244            uint32_t regSize;               //【必要】寄存器位宽
245            uint32_t irqNum;                //【必要】中断号
246        };
247
248        /* HdmiCntlr是核心层控制器结构体,其中的成员在Init函数中被赋值。 */
249        struct HdmiCntlr {
250            struct IDeviceIoService service;
251            struct HdfDeviceObject *hdfDevObj;
252            struct PlatformDevice device;
253            struct OsalMutex mutex;
254            struct PlatformQueue *msgQueue;
255            struct HdmiCntlrCap cap;
256            struct HdmiAttr attr;
257            struct HdmiCntlrOps *ops;
258            uint32_t deviceIndex;
259            uint32_t state;                 // 控制器状态
260            enum HdmiTmdsModeType tmdsMode;
261            struct HdmiDevice *hdmi;
262            struct HdmiInfoframe infoframe;
263            struct HdmiScdc *scdc;
264            struct HdmiDdc ddc;
265            struct HdmiFrl *frl;
266            struct HdmiHdcp *hdcp;
267            struct HdmiCec *cec;
268            struct HdmiEvent event;
269            struct HdmiHdr *hdr;
270            void *priv;
271        };
272        ```
273
274    -  HdmiCntlr成员回调函数结构体HdmiCntlrOps的实例化
275
276        ```c
277        static struct HdmiCntlrOps g_hdmiAdapterHostOps = {
278            .hardWareInit = HdmiAdapterHardWareInit,
279            .hardWareStatusGet = HdmiAdapterHardWareStatusGet,
280            .controllerReset = HdmiAdapterControllerReset,
281            .hotPlugStateGet = HdmiAdapterHotPlugStateGet,
282            .hotPlugInterruptStateGet = HdmiAdapterHotPlugInterruptStateGet,
283            .lowPowerSet = HdmiAdapterLowPowerSet,
284            .tmdsModeSet = HdmiAdapterTmdsModeSet,
285            .tmdsConfigSet = HdmiAdapterTmdsConfigSet,
286            .infoframeEnable = HdmiAdapterInfoframeEnable,
287            .infoframeSend = HdmiAdapterInfoframeSend,
288            .infoframeDataSet = HdmiAdapterInfoframeDataSet,
289            .cecMsgSend = HdmiAdapterCecMsgSend,
290            .audioPathEnable = HdmiAdapterAudioPathEnable,
291            .audioPathSet = HdmiAdapterAudioPathSet,
292            .phyOutputEnable = HdmiAdapterPhyOutputEnable,
293            .phyOutputSet = HdmiAdapterPhyOutputSet,
294            .blackDataSet = HdmiAdapterBlackDataSet,
295            .videoMuteEnable = HdmiAdapterVideoMuteEnable,
296            .videoPathSet = HdmiAdapterVideoPathSet,
297            .audioMuteEnable = HdmiAdapterAudioMuteEnable,
298            .avmuteSet = HdmiAdapterAvmuteSet,
299            .ddcTransfer = HdmiAdapterDdcTransfer,
300            .scdcSourceScrambleGet = HdmiAdapterScdcSourceScrambleGet,
301            .scdcSourceScrambleSet = HdmiAdapterScdcSourceScrambleSet,
302            .frlSet = HdmiAdapterFrlSet,
303            .frlEnable = HdmiAdapterFrlEnable,
304            .audioNctsSet = HdmiAdapterAudioNctsSet,
305            .frlTrainingConfigSet = HdmiAdapterFrlTrainingConfigSet,
306            .frlTrainingStart = HdmiAdapterFrlTrainingStart,
307            .frlGetTriningRslt = HdmiAdapterFrlGetTriningRslt,
308            .hdcpRegInit = HdmiAdapterHdcpRegInit,
309            .hdcpGenerateAksvAndAn = HdmiAdapterHdcpGenerateAksvAndAn,
310            .hdcpOptReg = HdmiAdapterHdcpOptReg,
311            .hdrTimerSet = HdmiAdapterHdrTimerSet,
312        };
313        ```
314
315    - Bind函数参考
316
317        **入参:**
318
319        HdfDeviceObject是整个驱动对外呈现的接口参数,具备HCS配置文件的信息。
320
321        **返回值:**
322
323        HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)
324
325        |状态(值)|状态描述|
326        |:-|:-|
327        |HDF_ERR_INVALID_OBJECT|控制器对象非法|
328        |HDF_ERR_INVALID_PARAM |参数非法|
329        |HDF_ERR_MALLOC_FAIL   |内存分配失败|
330        |HDF_ERR_IO            |I/O错误|
331        |HDF_SUCCESS           |传输成功|
332        |HDF_FAILURE           |传输失败|
333
334        **函数说明:**
335
336        初始化自定义结构体对象HdmiAdapterHost,初始化HdmiCntlr成员,调用核心层HdmiCntlrAdd函数。
337
338        HdmiCntlr,HdmiAdapterHost,HdfDeviceObject之间互相赋值,方便其他函数可以相互转化。
339
340        ```c
341        static int32_t HdmiAdapterBind(struct HdfDeviceObject *obj)
342        {
343            struct HdmiCntlr *cntlr = NULL;
344            struct HimciAdapterHost *host = NULL;
345            int32_t ret;
346            cntlr = (struct HdmiCntlr *)OsalMemCalloc(sizeof(struct HdmiCntlr));
347            if (cntlr == NULL) {
348                HDF_LOGE("%s: malloc cntlr failed!", __func__);
349                return HDF_ERR_MALLOC_FAIL;
350            }
351            host = (struct HimciAdapterHost *)OsalMemCalloc(sizeof(struct HimciAdapterHost));
352            if (host == NULL) {
353                HDF_LOGE("%s: malloc host failed!", __func__);
354                return HDF_ERR_MALLOC_FAIL;
355            }
356            cntlr->priv = (void *)host;              //【必要】将host存放至cntlr的私有数据
357            cntlr->ops = &g_hdmiHostOps;             //【必要】HdmiCntlrOps的实例化对象的挂载
358            cntlr->hdfDevObj = obj;                  //【必要】使HdfDeviceObject与HdmiCntlr可以相互转化的前提
359            obj->service = &cntlr->service;          //【必要】使HdfDeviceObject与HdmiCntlr可以相互转化的前提
360            ret = HdmiAdapterCntlrParse(cntlr, obj); //【必要】初始化cntlr,失败则goto __ERR。
361            ...
362            ret = HdmiAdapterHostParse(host, obj);   //【必要】初始化host对象的相关属性,失败则goto __ERR。
363            ...
364            ret = HdmiAdapterHostInit(host, cntlr);  // 厂商自定义的初始化,失败则goto __ERR。
365            ...
366            ret = HdmiCntlrAdd(cntlr);               // 调用核心层函数,失败则goto __ERR。
367            ...
368            HDF_LOGD("HdmiAdapterBind: success.");
369            return HDF_SUCCESS;
370        __ERR:
371            HdmiAdapterDeleteHost(host);
372            HDF_LOGD("HdmiAdapterBind: fail, err = %d.", ret);
373            return ret;
374        }
375        ```
376
377    - Init函数参考
378
379        **入参:**
380
381        HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。
382
383        **返回值:**
384
385        HDF_STATUS相关状态。
386
387        **函数说明**:
388
389        实现HdmiAdapterInit函数。
390
391        ```c
392        static int32_t HdmiAdapterInit(struct HdfDeviceObject *obj)
393        {
394            return HDF_SUCCESS;
395        }
396        ```
397
398    - Release函数参考
399
400        **入参:**
401
402        HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。
403
404        **返回值:**
405
406407
408        **函数说明:**
409
410        释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给Release接口,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。
411
412        > ![](../public_sys-resources/icon-note.gif) **说明:**<br>
413        > 所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。
414
415        ```c
416        static void HdmiAdapterRelease(struct HdfDeviceObject *obj)
417        {
418            struct HdmiCntlr *cntlr = NULL;
419            ...
420            cntlr = (struct HdmiCntlr *)obj->service;               // 这里有HdfDeviceObject到HdmiCntlr的强制转化,通过service成员,赋值见Bind函数。
421            ...
422            HimciDeleteHost((struct HimciAdapterHost *)cntlr->priv);// 厂商自定义的内存释放函数,这里有HdmiCntlr到HimciAdapterHost的强制转化。
423        }
424        ```
425
426
427