• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# HDMI
2
3
4## Overview
5
6### HDMI
7
8High Definition Multimedia Interface (HDMI) is an audio and video transmission protocol jointly released by Hitachi, Panasonic, Philips, Silicon Image, Sony, Thomson and Toshiba. It is used to transmit audio and video data from a source device, such as a DVD player or set-top box (STB), to a sink device, such as a TV or display. The transmission process complies with the Transition-minimized Differential Signaling (TMDS).
9
10### Basic Concepts
11
12- TMDS<br>Transmits audio, video, and various auxiliary data.
13
14- Display data channel (DDC)<br>Allows the TX and RX ends to obtain the transmitting and receiving capabilities. However, HDMI only needs to unidirectionally obtain the capabilities of the RX end (display).
15
16- Consumer Electronics Control (CEC)<br> Enables interaction between the HDMI TX and RX devices.
17
18- Fixed rate link (FRL)<br>Allows the maximum TMDS bandwidth to be increased from 18 Gbit/s to 48 Gbit/s.
19- High-bandwidth Digital Content Protection (HDCP)<br>Prevents copying of digital audio and video content being transmitted across devices.
20
21
22### Working Principles
23
24In the HDF, the HDMI module uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device, which increases memory usage.
25
26 **Figure 1** Independent service mode
27
28![image1](figures/independent-service-mode.png)
29
30### Constraints
31
32Currently, the HDMI module supports only the kernels (LiteOS) of mini and small systems.
33
34## Development Guidelines
35
36### When to Use
37
38HDMI features high transmission rate, wide transmission bandwidth, high compatibility, and can transmit uncompressed audio and video signals. Compared with the traditional full analog interface, HDMI simplifies connection between devices and provides HDMI-specific intelligent features, which are ideal for high-quality audio and video transmission of small-sized devices.
39
40### Available APIs
41
42**HdmiCntlrOps**:
43```c
44struct HdmiCntlrOps {
45    void (*hardWareInit)(struct HdmiCntlr *cntlr);
46    void (*hardWareStatusGet)(struct HdmiCntlr *cntlr, struct HdmiHardwareStatus *status);
47    void (*controllerReset)(struct HdmiCntlr *cntlr);
48    bool (*hotPlugStateGet)(struct HdmiCntlr *cntlr);
49    bool (*hotPlugInterruptStateGet)(struct HdmiCntlr *cntlr);
50    void (*lowPowerSet)(struct HdmiCntlr *cntlr, bool enable);
51    void (*tmdsModeSet)(struct HdmiCntlr *cntlr, enum HdmiTmdsModeType mode);
52    int32_t (*tmdsConfigSet)(struct HdmiCntlr *cntlr, struct HdmiTmdsConfig mode);
53    void (*infoFrameEnable)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoFrameType, bool enable);
54    int32_t (*infoFrameSend)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoFrameType, uint8_t *data, uint32_t len);
55    int32_t (*infoFrameDataSet)(struct HdmiCntlr *cntlr, uint32_t type, uint8_t *data, uint32_t len);
56    int32_t (*cecMsgSend)(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg);
57    void (*audioPathEnable)(struct HdmiCntlr *cntlr, bool enable);
58    void (*audioPathSet)(struct HdmiCntlr *cntlr, struct HdmiAudioConfigInfo *config);
59    void (*phyOutputEnable)(struct HdmiCntlr *cntlr, bool enable);
60    void (*phyOutputSet)(struct HdmiCntlr *cntlr, struct HdmiPhyCfg *cfg);
61    void (*blackDataSet)(struct HdmiCntlr *cntlr, bool enable);
62    void (*videoMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
63    void (*videoPathSet)(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr);
64    void (*audioMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
65    void (*avmuteSet)(struct HdmiCntlr *cntlr, bool enable);
66    int32_t (*ddcTransfer)(struct HdmiCntlr *cntlr, struct HdmiDdcCfg *ddcCfg);
67    bool (*scdcSourceScrambleGet)(struct HdmiCntlr *cntlr);
68    int32_t (*scdcSourceScrambleSet)(struct HdmiCntlr *cntlr, bool enable);
69    void (*frlSet)(struct HdmiCntlr *cntlr);
70    int32_t (*frlEnable)(struct HdmiCntlr *cntlr, bool enable);
71    int32_t (*audioNctsSet)(struct HdmiCntlr *cntlr, struct HdmiFrlAudioNctsConfig *cfg);
72    void (*frlTrainingConfigSet)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainConfig *cfg);
73    void (*frlTrainingStart)(struct HdmiCntlr *cntlr);
74    void (*frlGetTriningRslt)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainRslt *rslt);
75    void (*hdcpRegInit)(struct HdmiCntlr *cntlr);
76    int32_t (*hdcpGenerateAksvAndAn)(struct HdmiCntlr *cntlr);
77    int32_t (*hdcpOptReg)(struct HdmiCntlr *cntlr, enum HdmiHdcpRegOptType type, uint8_t *data, uint32_t len);
78    void (*hdrTimerSet)(struct HdmiCntlr *cntlr, struct HdmiHdrTimerConfig *config);
79};
80```
81
82**Table 1** Description of the callback functions in HdmiCntlrOps
83
84| Function                | Input Parameter                                                        | Output Parameter                                  | Return Value            | Description                                              |
85| ------------------------ | ------------------------------------------------------------ | -------------------------------------- | ------------------ | -------------------------------------------------- |
86| hardWareInit             | **cntlr**: structure pointer to an HDMI controller at the core layer.| –| –| Initializes the HDMI hardware.|
87| hardWareStatusGet        | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>| **status**: pointer to the HDMI hardware status.| –| Obtains the HDMI hardware status.|
88| controllerReset          | **cntlr**: structure pointer to an HDMI controller at the core layer.| –| –| Resets an HDMI controller.|
89| hotPlugStateGet          | **cntlr**: structure pointer to an HDMI controller at the core layer.| –| **bool**: HDMI hot-plug status.| Obtains the HDMI hot-plug status.|
90| hotPlugInterruptStateGet | **cntlr**: structure pointer to an HDMI controller at the core layer.| –| **bool**: HDMI hot-plug interrupt status.| Obtains the HDMI hot-plug interrupt status.|
91| lowPowerSet              | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**enable**: whether to enable low power consumption.| –| –| Enables or disables low power consumption.|
92| tmdsModeSet              | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**mode**: TMDS mode.| –| –| Sets the TMDS mode.|
93| tmdsConfigSet | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**mode**: TMDS parameters.| –| HDF_STATUS| Sets TMDS parameters.|
94| infoFrameEnable | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**infoFrameType**: packet type.<br>**enable**: whether to enable infoFrame.| –| –| Enables or disables infoFrame.|
95| infoFrameSend | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**infoFrameType**: packet type.<br>**data**: pointer to infoFrame data.<br>**len**: data length.| –| HDF_STATUS| Sends an infoFrame.|
96|cecMsgSend|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**msg**: pointer to the CEC message|–|HDF_STATUS|Sends a CEC message.|
97|audioPathEnable|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**enable**: whether to enable the audio path.|–|–|Enables or disables the audio path.|
98| audioPathSet | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**config**: pointer to the audio path configuration.| –| –| Sets the audio path.|
99|phyOutputEnable|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**enable**: whether to enable the physical layer output.|–|–|Enables or disables the physical layer output.|
100| phyOutputSet | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**cfg**: pointer to the physical layer configuration.| –| –| Sets the physical layer information.|
101|blackDataSet|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**enable**: whether to enable the black screen.|–|–|Sets the black screen.|
102|videoMuteEnable|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**enable**: whether to enable the video mute feature.|–|–|Enables or disables the video mute feature.|
103| videoPathSet | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**attr**: pointer to the video path configuration.| –| –| Sets the video path.|
104|audioMuteEnable|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**enable**: whether to enable the audio mute feature.|–|–|Enables or disables the audio mute feature.|
105|avmuteSet|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**enable**: whether to enable the AV mute feature.|–|–|Enables or disables the AV mute feature.|
106|ddcTransfer|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**ddcCfg**: pointer to the DDC configuration.|**ddcCfg**: DDC configuration.|HDF_STATUS|Reads and writes data through the DDC.|
107| scdcSourceScrambleGet | **cntlr**: structure pointer to an HDMI controller at the core layer.| –| Scrambling status of the source.| Obtains the scrambling status of the source.|
108|scdcSourceScrambleSet|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**enable**: whether to enable the scrambling for the source.|–|HDF_STATUS|Enables or disable scrambling for the source.|
109|frlEnable|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**enable**: whether to enable the FRL.|–|HDF_STATUS|Enables or disables the FRL.|
110| audioNctsSet | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**cfg**: pointer to the N/CTS configuration.| –| HDF_STATUS| Sets the audio N/CTS information.|
111|frlTrainingConfigSet|**cntlr**: structure pointer to an HDMI controller at the core layer.<br>**cfg**: pointer to the FRL training configuration.|–|–|Sets FRL training information.|
112| frlTrainingStart | **cntlr**: structure pointer to an HDMI controller at the core layer.| –| –| Starts FRL training.|
113| frlGetTriningRslt | **cntlr**: structure pointer to an HDMI controller at the core layer.| **rslt**: FRL training result.| –| Obtains the FRL training result.|
114| hdcpRegInit | **cntlr**: structure pointer to an HDMI controller at the core layer.| –| –| Initializes registers related to the High-bandwidth Digital Content Protection (HDCP) process.|
115|hdcpGenerateAksvAndAn |**cntlr**: structure pointer to an HDMI controller at the core layer.| –| HDF_STATUS| Generates the **Aksv** and **An** in the HDCP process.|
116| hdcpOptReg | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**type**: operation type.<br>**data**: register data.<br>**len**: data length.| **data**: register data.| HDF_STATUS| Reads or writes the registers during the HDCP process.|
117| hdrTimerSet | **cntlr**: structure pointer to an HDMI controller at the core layer.<br>**config**: pointer to the timer configuration| –| –| Sets the HDR-related timer.|
118
119
120### How to Develop
121
122The HDMI module adaptation involves the following steps:
123
1241. Instantiate the driver entry.
125   - Instantiate the **HdfDriverEntry** structure.
126   - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
1272. Configure attribute files.
128   - Add the **deviceNode** information to the **device_info.hcs** file.
129   - (Optional) Add the **hdmi_config.hcs** file.
1303. Instantiate the HDMI controller object.
131   - Initialize **HdmiCntlr**.
132   - Instantiate **HdmiCntlrOps** in **HdmiCntlr**.
133
134### Development Example
135
1361. Instantiate the driver entry.
137
138    The driver entry must be a global variable of the **HdfDriverEntry** type (which is defined in **hdf_device_desc.h**), and the value of **moduleName** must be the same as that in **device_info.hcs**. In the HDF, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke.
139
140    Generally, the HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
141
142    HDMI driver entry example:
143
144    ```c
145    struct HdfDriverEntry g_hdmiDriverEntry = {
146        .moduleVersion = 1,
147        .Bind = HdmiAdapterBind,
148        .Init = HdmiAdapterInit,
149        .Release = HdmiAdapterRelease,
150        .moduleName = "adapter_hdmi_driver",// (mandatory) The value must be the same as that in the .hcs file.
151    };
152    HDF_INIT(g_hdmiDriverEntry);            // Call HDF_INIT to register the driver entry with the HDF.
153    ```
154
1552. Configure attribute files.
156
157    Add **deviceNode** to the **device_info.hcs** file, and configure the device attributes in the **hdmi_config.hcs** file. The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the driver implementation and the default values or restriction ranges of the **HdmiCntlr** members at the core layer.
158
159    Configure HDMI controller information from the first node. This node specifies a type of HDMI controllers rather than a specific HDMI controller. In this example, there is only one HDMI controller. If there are multiple HDMI controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **hdmi_config** file.
160
161    - **device_info.hcs** configuration example
162
163        ```c
164        root {
165            platform :: host {
166                 device_hdmi :: device {
167                    device0 :: deviceNode {
168                        policy = 2;                               // Publish services.
169                        priority = 20;                            // Driver startup priority.
170                        permission = 0644;                        // Permission to create device nodes for the driver.
171                        serviceName = "HDF_PLATFORM_HDMI_0";      // (Mandatory) Unique name of the service published by the driver.
172                        moduleName = "hdmi_driver";               // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
173                        deviceMatchAttr = "adapter_hdmi_driver";  // (Mandatory) Controller private data, which must be same as that of the corresponding controller in hdmi_config.hcs.
174                    }                                             // The specific controller information is in hdmi_config.hcs.
175                 }
176            }
177        }
178        ```
179
180    - **hdmi_config.hcs** configuration example
181
182        ```c
183         root {
184             platform {
185                hdmi_config {
186                    template hdmi_controller {     // Template configuration. In the template, you can configure the common parameters shared by device nodes.
187                        match_attr = "";           // (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs.
188                        index = 0;                 // (Mandatory) HDMI controller number.
189                        regBasePhy = 0x10100000;   // (Mandatory) Physical base address of the register.
190                        regSize = 0xd1;            // (Mandatory) Register bit width.
191                        irqNum = 100;              //(Mandatory) Interrupt request (IRQ) number.
192                        maxTmdsClock = 300;
193                        videoTiming = 10;
194                        quantization = 1;
195                        colorSpace = 0;
196                        colorimetry = 0;
197                        audioIfType = 0;
198                        audioBitDepth = 1;
199                        audioSampleRate = 2;
200                        audioChannels = 1;
201                        hdrColorimetry = 4;
202                        hdrUserMode = 1;
203                        cap = 0xd001e045;
204                    }
205                    controller_0x10100000 :: hdmi_controller {
206                        match_attr = "adapter_hdmi_driver";
207                        index = 0;
208                        regBasePhy = 0x10100000;
209                        irqNum = 100;
210                        maxTmdsClock = 400;
211                        defTmdsClock = 300;
212                        maxFrlRate = 600;
213                        videoTiming = 10;
214                        quantization = 1;
215                        colorSpace = 0;
216                        colorimetry = 0;
217                        audioIfType = 0;
218                        audioSampleRate = 2;
219                        audioChannels = 1;
220                        hdrColorimetry = 4;
221                        hdrUserMode = 1;
222                        cap = 0xd001e045;
223                    }
224                }
225            }
226        }
227        ```
228
2293. Instantiate the **HdmiCntlr** object.
230
231    Initialize the **HdmiCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init** and **Release**) to instantiate **HdmiCntlrOps** in **HdmiCntlr** (so that the underlying driver functions can be called).
232
233    - Defining the custom structure
234
235        > ![](../public_sys-resources/icon-note.gif) **NOTE**
236        >
237        >
238        > To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **hdmi_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the device number and bus number, to the **HdmiCntlr** object at the core layer.
239
240        ```c
241        struct HdmiAdapterHost {
242            struct HdmiCntlr *cntlr;        // (Mandatory) Control object at the core layer. The details are as follows:
243            volatile unsigned char *regBase;// (Mandatory) Register base address.
244            uint32_t regBasePhy;            // (Mandatory) Physical base address of the register.
245            uint32_t regSize;               // (Mandatory) Register bit width.
246            uint32_t irqNum;                // (Mandatory) IRQ number.
247        };
248
249        /* HdmiCntlr is the controller structure at the core layer. The Init function assigns values to the members of HdmiCntlr. */
250        struct HdmiCntlr {
251            struct IDeviceIoService service;
252            struct HdfDeviceObject *hdfDevObj;
253            struct PlatformDevice device;
254            struct OsalMutex mutex;
255            struct PlatformQueue *msgQueue;
256            struct HdmiCntlrCap cap;
257            struct HdmiAttr attr;
258            struct HdmiCntlrOps *ops;
259            uint32_t deviceIndex;
260            uint32_t state;                 // Controller status.
261            enum HdmiTmdsModeType tmdsMode;
262            struct HdmiDevice *hdmi;
263            struct HdmiInfoframe infoframe;
264            struct HdmiScdc *scdc;
265            struct HdmiDdc ddc;
266            struct HdmiFrl *frl;
267            struct HdmiHdcp *hdcp;
268            struct HdmiCec *cec;
269            struct HdmiEvent event;
270            struct HdmiHdr *hdr;
271            void *priv;
272        };
273        ```
274
275    -  Instantiating **HdmiCntlrOps** in **HdmiCntlr**
276
277        ```c
278        static struct HdmiCntlrOps g_hdmiAdapterHostOps = {
279            .hardWareInit = HdmiAdapterHardWareInit,
280            .hardWareStatusGet = HdmiAdapterHardWareStatusGet,
281            .controllerReset = HdmiAdapterControllerReset,
282            .hotPlugStateGet = HdmiAdapterHotPlugStateGet,
283            .hotPlugInterruptStateGet = HdmiAdapterHotPlugInterruptStateGet,
284            .lowPowerSet = HdmiAdapterLowPowerSet,
285            .tmdsModeSet = HdmiAdapterTmdsModeSet,
286            .tmdsConfigSet = HdmiAdapterTmdsConfigSet,
287            .infoframeEnable = HdmiAdapterInfoframeEnable,
288            .infoframeSend = HdmiAdapterInfoframeSend,
289            .infoframeDataSet = HdmiAdapterInfoframeDataSet,
290            .cecMsgSend = HdmiAdapterCecMsgSend,
291            .audioPathEnable = HdmiAdapterAudioPathEnable,
292            .audioPathSet = HdmiAdapterAudioPathSet,
293            .phyOutputEnable = HdmiAdapterPhyOutputEnable,
294            .phyOutputSet = HdmiAdapterPhyOutputSet,
295            .blackDataSet = HdmiAdapterBlackDataSet,
296            .videoMuteEnable = HdmiAdapterVideoMuteEnable,
297            .videoPathSet = HdmiAdapterVideoPathSet,
298            .audioMuteEnable = HdmiAdapterAudioMuteEnable,
299            .avmuteSet = HdmiAdapterAvmuteSet,
300            .ddcTransfer = HdmiAdapterDdcTransfer,
301            .scdcSourceScrambleGet = HdmiAdapterScdcSourceScrambleGet,
302            .scdcSourceScrambleSet = HdmiAdapterScdcSourceScrambleSet,
303            .frlSet = HdmiAdapterFrlSet,
304            .frlEnable = HdmiAdapterFrlEnable,
305            .audioNctsSet = HdmiAdapterAudioNctsSet,
306            .frlTrainingConfigSet = HdmiAdapterFrlTrainingConfigSet,
307            .frlTrainingStart = HdmiAdapterFrlTrainingStart,
308            .frlGetTriningRslt = HdmiAdapterFrlGetTriningRslt,
309            .hdcpRegInit = HdmiAdapterHdcpRegInit,
310            .hdcpGenerateAksvAndAn = HdmiAdapterHdcpGenerateAksvAndAn,
311            .hdcpOptReg = HdmiAdapterHdcpOptReg,
312            .hdrTimerSet = HdmiAdapterHdrTimerSet,
313        };
314        ```
315
316    - **Bind** function
317
318        **Input parameter**:
319
320        **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
321
322        **Return value**:
323
324        **HDF_STATUS**
325
326        The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
327
328        |Status|Description|
329        |:-|:-|
330        |HDF_ERR_INVALID_OBJECT|Invalid controller object.|
331        |HDF_ERR_INVALID_PARAM |Invalid parameter.|
332        |HDF_ERR_MALLOC_FAIL   |Failed to allocate memory.|
333        |HDF_ERR_IO            |I/O error.|
334        |HDF_SUCCESS           |Transmission successful.|
335        |HDF_FAILURE           |Transmission failed.|
336
337        **Function description**:
338
339        Initializes the custom structure object **HdmiAdapterHost** and **HdmiCntlr**, and calls the **HdmiCntlrAdd** function to add the HDMI controller to the core layer.
340
341        The **HdmiCntlr**, **HdmiAdapterHost**, and **HdfDeviceObject** assign values with each other so that other functions can be converted successfully.
342
343        ```c
344        static int32_t HdmiAdapterBind(struct HdfDeviceObject *obj)
345        {
346            struct HdmiCntlr *cntlr = NULL;
347            struct HimciAdapterHost *host = NULL;
348            int32_t ret;
349            cntlr = (struct HdmiCntlr *)OsalMemCalloc(sizeof(struct HdmiCntlr));
350            if (cntlr == NULL) {
351                HDF_LOGE("%s: malloc cntlr failed!", __func__);
352                return HDF_ERR_MALLOC_FAIL;
353            }
354            host = (struct HimciAdapterHost *)OsalMemCalloc(sizeof(struct HimciAdapterHost));
355            if (host == NULL) {
356                HDF_LOGE("%s: malloc host failed!", __func__);
357                return HDF_ERR_MALLOC_FAIL;
358            }
359            cntlr->priv = (void *)host;              // (Mandatory) Store host to the private data of cntlr.
360            cntlr->ops = &g_hdmiHostOps;             // (Mandatory) Connect to the HdmiCntlrOps instance.
361            cntlr->hdfDevObj = obj;                  // (Mandatory) Prerequisites for conversion between HdfDeviceObject and HdmiCntlr.
362            obj->service = &cntlr->service;          // (Mandatory) Prerequisites for conversion between HdfDeviceObject and HdmiCntlr.
363            ret = HdmiAdapterCntlrParse(cntlr, obj); // (Mandatory) Initialize cntlr. If the operation fails, execute goto __ERR.
364            ...
365            ret = HdmiAdapterHostParse(host, obj);   // (Mandatory) Initialize the attributes of the host object. If the operation fails, execute goto__ERR.
366            ...
367            ret = HdmiAdapterHostInit(host, cntlr);  // Initialize the custom structure. If the operation fails, execute goto __ERR.
368            ...
369            ret = HdmiCntlrAdd(cntlr);               // Call the functions at the core layer. If the operation fails, execute goto__ERR.
370            ...
371            HDF_LOGD("HdmiAdapterBind: success.");
372            return HDF_SUCCESS;
373        __ERR:
374            HdmiAdapterDeleteHost(host);
375            HDF_LOGD("HdmiAdapterBind: fail, err = %d.", ret);
376            return ret;
377        }
378        ```
379
380    - **Init** function
381
382        **Input parameter**:
383
384        **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
385
386        **Return value**:
387
388        **HDF_STATUS**
389
390        **Function description**:
391
392        Implements the **HdmiAdapterInit** function.
393
394        ```c
395        static int32_t HdmiAdapterInit(struct HdfDeviceObject *obj)
396        {
397            return HDF_SUCCESS;
398        }
399        ```
400
401    - **Release** function
402
403        **Input parameter**:
404
405       **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
406
407        **Return value**:
408
409        No value is returned.
410
411        **Function description**:
412
413        Releases the memory and deletes the controller. This function assigns values to the **Release** callback in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
414
415        > ![](../public_sys-resources/icon-note.gif) **NOTE**<br>
416        > All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
417        ```c
418        static void HdmiAdapterRelease(struct HdfDeviceObject *obj)
419        {
420            struct HdmiCntlr *cntlr = NULL;
421            ...
422            cntlr = (struct HdmiCntlr *)obj->service;// Forcibly convert HdfDeviceObject to HdmiCntlr by using service. For details about the value assignment, see the Bind function.
423            ...
424            HimciDeleteHost((struct HimciAdapterHost *)cntlr->priv);// Customized memory release function. A forced conversion from HdmiCntlr to HimciAdapterHost is involved in the process.
425        }
426        ```
427
428