未验证 提交 8ea3e5b4 编写于 作者: O openharmony_ci 提交者: Gitee

!2064 #I4U985完成,请审批

Merge pull request !2064 from Annie_wang/PR1290
......@@ -2,16 +2,19 @@
## Overview<a name="section1"></a>
- The High-Definition Multimedia Interface (HDMI) is an audio/video transmission protocol released by Hitachi, Panasonic, Philips, Silicon Image, Sony, Thomson, Toshiba.
- The HDMI works in master/slave mode and usually has a source and a sink.
- The HDMI APIs provide a set of common functions for HDMI transmission, including:
High-Definition Multimedia Interface (HDMI) is an audio/video transmission protocol released by Hitachi, Panasonic, Philips, Silicon Image, Sony, Thomson, and Toshiba.
- Opening and closing an HDMI controller.
- Starting and stopping HDMI transmission.
- Setting audio, video, and High Dynamic Range (HDR) attributes, color depth, and AV mute.
- Reading the raw Extended Display Identification Data (EDID) from a sink.
- Registering and unregistering a callback for HDMI hot plug detect.
- [Figure 1](#fig1) shows the HDMI physical connection.
HDMI works in master/slave mode and usually has a source and a sink.
The HDMI APIs provide a set of common functions for HDMI transmission, including:
- Opening and closing an HDMI controller
- Starting and stopping HDMI transmission
- Setting audio, video, and High Dynamic Range (HDR) attributes, color depth, and AV mute
- Reading the raw Extended Display Identification Data (EDID) from a sink
- Registering and unregistering a callback for HDMI hot plug detect (HPD)
[Figure 1](#fig1) shows the HDMI physical connection.
**Figure 1** HDMI physical connection<a name="fig1"></a>
......@@ -94,16 +97,16 @@
<td class="cellrowborder" valign="top" width="53.339999999999996%">Reads the raw EDID from a sink.</p>
</td>
</tr>
<tr><td class="cellrowborder" bgcolor="#ffffff" rowspan="2" valign="top" width="18.63%"><p>Registering or unregistering a callback for HDMI hot plug detect</p>
<tr><td class="cellrowborder" bgcolor="#ffffff" rowspan="2" valign="top" width="18.63%"><p>Registering or unregistering a callback for HDMI HPD</p>
</td>
<td class="cellrowborder" valign="top" width="28.03%"><p>HdmiRegisterHpdCallbackFunc</p>
</td>
<td class="cellrowborder" valign="top" width="53.339999999999996%">Registers a callback for HDMI hot plug detect.</p>
<td class="cellrowborder" valign="top" width="53.339999999999996%">Registers a callback for HDMI HPD.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top"><p>HdmiUnregisterHpdCallbackFunc</p>
</td>
<td class="cellrowborder" valign="top"><p>Unregisters the callback for HDMI hot plug detect.</p>
<td class="cellrowborder" valign="top"><p>Unregisters the callback for HDMI HPD.</p>
</td>
</tr>
</tbody>
......@@ -121,7 +124,7 @@
### Opening an HDMI Controller<a name="section5"></a>
Before HDMI communication, call **HdmiOpen** to enable an HDMI controller.
Before HDMI communication, call **HdmiOpen** to open an HDMI controller.
```c
DevHandle HdmiOpen(int16_t number);
......@@ -173,7 +176,7 @@ if (hdmiHandle == NULL) {
}
```
### Registering a Callback for Hot Plug Detect<a name="section6"></a>
### Registering a Callback for HPD<a name="section6"></a>
```c
int32_t HdmiRegisterHpdCallbackFunc(DevHandle handle, struct HdmiHpdCallbackInfo *callback);
......@@ -196,7 +199,7 @@ int32_t HdmiRegisterHpdCallbackFunc(DevHandle handle, struct HdmiHpdCallbackInfo
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>callback</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Callback invoked to return the hot plug detect result.</p>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the callback to be invoked to return the HPD result.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
......@@ -217,10 +220,10 @@ int32_t HdmiRegisterHpdCallbackFunc(DevHandle handle, struct HdmiHpdCallbackInfo
</tbody>
</table>
The following is an example of registering a callback for hot plug detect:
The following is an example of registering a callback for HPD:
```c
/* Definition of the callback for hot plug detect */
/* Definition of the callback for HPD */
static void HdmiHpdHandle(void *data, bool hpd)
{
if (data == NULL) {
......@@ -237,7 +240,7 @@ static void HdmiHpdHandle(void *data, bool hpd)
}
}
/* Example of registering a callback for hot plug detect */
/* Example of registering a callback for HPD */
struct HdmiHpdCallbackInfo info = {0};
info.data = handle;
info.callbackFunc = HdmiHpdHandle;
......@@ -247,7 +250,7 @@ static void HdmiHpdHandle(void *data, bool hpd)
}
```
### Reading the EDID<a name="section7"></a>
### Reading the RAW EDID<a name="section7"></a>
```c
int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len);
......@@ -270,7 +273,7 @@ int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len);
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>buffer</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Data buffer.</p>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the data buffer.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>len</p>
......@@ -296,7 +299,7 @@ int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len);
</tbody>
</table>
The following is an example of reading the raw EDID data from a sink:
The following is an example of reading the raw EDID from a sink:
```c
int32_t len;
......@@ -333,7 +336,7 @@ int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr);
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>attr</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p> Audio attributes.</p>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the audio attributes.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
......@@ -394,7 +397,7 @@ int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr);
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>attr</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Video attributes.</p>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the video attributes.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
......@@ -454,7 +457,7 @@ int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr);
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>attr</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>HDR attributes.</p>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the HDR attributes.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
......@@ -627,7 +630,7 @@ int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color);
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>color</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Color depth.</p>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the color depth.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
......@@ -760,7 +763,7 @@ if (ret != 0) {
}
```
### Unregistering the Callback for Hot Plug Detect<a name="section12"></a>
### Unregistering the Callback for HPD<a name="section12"></a>
```c
int32_t HdmiUnregisterHpdCallbackFunc(DevHandle handle);
......@@ -799,7 +802,7 @@ int32_t HdmiUnregisterHpdCallbackFunc(DevHandle handle);
</tbody>
</table>
The following is an example of unregistering the callback for hot plug detect:
The following is an example of unregistering the callback for HPD:
```c
int32_t ret;
......@@ -856,7 +859,7 @@ The sample code is as follows:
```c
#include "hdmi_if.h" /* Header file for HDMI standard APIs */
#include "hdf_log.h" /* Header file for log APIs */
##include "osal_time.h" /* Header file for delay and sleep APIs */
#include "osal_time.h" /* Header file for delay and sleep APIs */
/* Callback for hog plug detect */
static void HdmiHpdHandle(void *data, bool hpd)
......
# HDMI
## Overview<a name="1"></a>
The High-Definition Multimedia Interface (HDMI) is an audio/video transmission protocol released by Hitachi, Panasonic, Philips, SiliconImage, Sony, Thomson and Toshiba. It is used to transmit audio or video data from an audio or video source device, such as a DVD player or STB, to a sink device, such as a TV or monitor. The transmission process complies with the Transition Minimized Differential Signaling (TMDS) protocol.
High-Definition Multimedia Interface (HDMI) is an audio/video transmission protocol released by Hitachi, Panasonic, Philips, Silicon Image, Sony, Thomson, and Toshiba. It is used to transmit audio or video data from an audio or video source device, such as a DVD player or STB, to a sink device, such as a TV or monitor. The transmission process complies with the Transition Minimized Differential Signaling (TMDS) protocol.
In the HDF, the HDMI module uses the independent service mode for API adaptation. In this mode, each device independently publishes a device service to process external access requests. After receiving an access request, the device manager extracts the parameters in the request to call the internal method of the target device. In the independent service mode, the service management capabilities of the HDFDeviceManager can be directly used. However, you need to configure a node for each device, which increases the memory usage.
......@@ -10,23 +11,9 @@ In the HDF, the HDMI module uses the independent service mode for API adaptation
![image1](figures/independent-service-mode.png)
## How to Develop<a name="2"></a>
The HDMI module adaptation involves the following steps:
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
- Add the **deviceNode** information to the **device_info.hcs** file.
- (Optional) Add the **hdmi_config.hcs** file.
3. Instantiate the HDMI controller object.
- Initialize **HdmiCntlr**.
- Instantiate **HdmiCntlrOps** in **HdmiCntlr**. For details, see the following description of **HdmiCntlrOps**.
## Available APIs<a name="2"></a>
HdmiCntlrOps:
**HdmiCntlrOps**:
```c
struct HdmiCntlrOps {
void (*hardWareInit)(struct HdmiCntlr *cntlr);
......@@ -66,46 +53,64 @@ The HDMI module adaptation involves the following steps:
};
```
**Table 1** Callbacks for the members in the HdmiCntlrOps structure
**Table 1** APIs for the members in the HdmiCntlrOps structure
| Function Member| Input Parameter| Output Parameter| Return Value| Description|
| Method| Input Parameter| Output Parameter| Return Value| Description|
| ------------------------ | ------------------------------------------------------------ | -------------------------------------- | ------------------ | -------------------------------------------------- |
| hardWareInit | **cntlr**: structure pointer to an HDMI controller at the core layer.| –| –| Initializes HDMI hardware.|
| hardWareStatusGet | **cntlr**: structure pointer to an HDMI controller at the core layer. <br />| **status**: HDMI hardware status.| –| Obtains the HDMI hardware status.|
| 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.|
| controllerReset | **cntlr**: structure pointer to an HDMI controller at the core layer.| –| –| Resets an HDMI controller.|
| hotPlugStateGet | **cntlr**: structure pointer to an HDMI controller at the core layer.| -| **bool**: HDMI hot-plug status.| Obtains the HDMI hot-plug status.|
| hotPlugStateGet | **cntlr**: structure pointer to an HDMI controller at the core layer.| | **bool**: HDMI hot-plug status.| Obtains the HDMI hot-plug status.|
| 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.|
| lowPowerSet | **cntlr**: structure pointer to an HDMI controller at the core layer.<br /> **enable**: whether low power consumption is enabled.| –| –| Enables or disables low power consumption.|
| tmdsModeSet | **cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **mode**: TMDS mode.| –| –| Set the TMDS mode.|
|tmdsConfigSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **mode**: TMDS mode parameters.|–|HDF_STATUS|Sets TMDS parameters.|
|infoFrameEnable|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **infoFrameType**: packet type. <br /> **enable**: whether infoFrame is enabled.|–|–|Enables or disables infoFrame.|
|infoFrameSend|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **infoFrameType**: packet type. <br /> **data**: infoFrame data. <br /> **len**: data length.|–|HDF_STATUS|Sends an infoFrame.|
|cecMsgSend|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **msg**: Consumer Electronics Control (CEC) message.|–|HDF_STATUS|Sends a CEC message.|
|audioPathEnable|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **enable**: whether the audio path is enabled.|–|–|Enables or disables the audio path.|
|audioPathSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **config**: audio path configuration.|–|–|Sets the audio path.|
|phyOutputEnable|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **enable**: whether the physical layer output is enabled.|–|–|Enables or disables the physical layer output.|
|phyOutputSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **cfg**: physical layer configuration.|–|–|Sets the physical layer information.|
|blackDataSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **enable**: whether the black screen is enabled.|–|–|Sets the black screen.|
|videoMuteEnable|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **enable**: whether the video mute feature is enabled.|–|–|Enables or disables the video mute feature.|
|videoPathSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **attr**: configuration.|–|–|Sets the video path.|
|audioMuteEnable|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **enable**: whether the audio mute feature is enabled.|–|–|Enables or disables the audio mute feature.|
|avmuteSet|**cntlr**: structure pointer to an HDMI controller at the core layer.<br /> **enable**: whether the AV mute feature is enabled.|–|–|Enables or disables the AV mute feature.|
|ddcTransfer|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **ddcCfg**: DDC configuration.|**ddcCfg**: DDC configuration.|HDF_STATUS|Reads and writes data through the display data channel (DDC).|
| 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.|
| tmdsModeSet | **cntlr**: structure pointer to an HDMI controller at the core layer. <br/>**mode**: TMDS mode.| –| –| Sets the TMDS mode. |
|tmdsConfigSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br/>**mode**: TMDS parameters.|–|HDF_STATUS|Sets TMDS parameters.|
|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.|
|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.|
|cecMsgSend|**cntlr**: structure pointer to an HDMI controller at the core layer. <br/>**msg**: pointer to the Consumer Electronics Control (CEC) message.|–|HDF_STATUS|Sends a CEC message.|
|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.|
|audioPathSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br/>**config**: pointer to the audio path configuration.|–|–|Sets the audio path.|
|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.|
|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.|
|blackDataSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br />**enable**: whether to enable the black screen.|–|–|Sets the black screen.|
|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.|
|videoPathSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br/>**attr**: pointer to the video path configuration.|–|–|Sets the video path.|
|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.|
|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.|
|ddcTransfer|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **ddcCfg**: pointer to the display data channel (DDC) configuration.|**ddcCfg**: DDC configuration.|HDF_STATUS|Reads and writes data through the DDC.|
|scdcSourceScrambleGet|**cntlr**: structure pointer to an HDMI controller at the core layer.|–|Scrambling status of the source.|Obtains the scrambling status of the source.|
|scdcSourceScrambleSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **enable**: whether scrambling is enabled for the source.|–|HDF_STATUS|Enables or disable scrambling for the source.|
|frlEnable|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **enable**: whether fixed rate link (FRL) is enabled.|–|HDF_STATUS|Enables or disables the FRL.|
|audioNctsSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **cfg**: N/CTS configuration.|–|HDF_STATUS|Sets the audio N/CTS information.|
|frlTrainingConfigSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **cfg**: FRL training configuration.|–|–|Sets FRL training information.|
|scdcSourceScrambleSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br />**enable**: whether to enable scrambling for the source.|–|HDF_STATUS|Enables or disable scrambling for the source.|
|frlEnable|**cntlr**: structure pointer to an HDMI controller at the core layer. <br />**enable**: whether to enable the fixed rate link (FRL).|–|HDF_STATUS|Enables or disables the FRL.|
|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.|
|frlTrainingConfigSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **cfg**: pointer to the FRL training configuration.|–|–|Sets FRL training information.|
|frlTrainingStart|**cntlr**: structure pointer to an HDMI controller at the core layer.|–|–|Starts FRL training.|
|frlGetTriningRslt|**cntlr**: structure pointer to an HDMI controller at the core layer.|**rslt**: FRL training result.|–|Obtains the FRL training result.|
|hdcpRegInit|**cntlr**: structure pointer to an HDMI controller at the core layer.|–|–|Initializes registers related to the High-bandwidth Digital Content Protection (HDCP) process.|
|hdcpGenerateAksvAndAn|**cntlr**: structure pointer to an HDMI controller at the core layer.|–|HDF_STATUS|Generates the **Aksv** and **An** in the HDCP process.|
|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 in the HDCP process.|
|hdrTimerSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br /> **config**: timer configuration.|–|–|Sets the HDR-related timer.|
|hdcpOptReg|**cntlr**: structure pointer to an HDMI controller at the core layer. <br />**type**: operation type. <br />**data**: pointer to the register data. <br />**len**: data length.|**data**: register data.|HDF_STATUS|Reads or writes the registers in the HDCP process.|
|hdrTimerSet|**cntlr**: structure pointer to an HDMI controller at the core layer. <br />**config**: pointer to the timer configuration.|–|–|Sets the HDR-related timer.|
## Development Example<a name="3"></a>
1. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type (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 are collected to form a segment address space similar to an array for the upper layer to invoke.
## How to Develop<a name="3"></a>
The HDMI module adaptation involves the following steps:
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
- Add the **deviceNode** information to the **device_info.hcs** file.
- (Optional) Add the **hdmi_config.hcs** file.
3. Instantiate the HDMI controller object.
- Initialize **HdmiCntlr**.
- Instantiate **HdmiCntlrOps** in **HdmiCntlr**. For details, see [Available APIs](#available_apis).
## Development Example<a name="4"></a>
1. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type (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 are collected to form a segment address space similar to an array for the upper layer to invoke.
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.
......@@ -122,11 +127,11 @@ The HDMI module adaptation involves the following steps:
HDF_INIT(g_hdmiDriverEntry); // Call HDF_INIT to register the driver entry with the HDF.
```
2. 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.
2. 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.
Configure HDMI controller information from the second 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.
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.
- **device_info.hcs** configuration reference
- **device\_info.hcs** configuration reference
```c
root {
......@@ -151,7 +156,7 @@ The HDMI module adaptation involves the following steps:
root {
platform {
hdmi_config {
template hdmi_controller { // Template configuration. In the template, you can configure the common parameters shared by service nodes.
template hdmi_controller { // Template configuration. In the template, you can configure the common parameters shared by device nodes.
match_attr = ""; // (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs.
index = 0; // (Mandatory) HDMI controller number.
regBasePhy = 0x10100000; // (Mandatory) Physical base address of the register.
......@@ -194,16 +199,17 @@ The HDMI module adaptation involves the following steps:
}
```
3. Initialize the **HdmiCntlr** object at the core layer, including initializing the vendor custom structure (transferring parameters and data) and instantiating the **HdmiCntlrOps** (used to call the underlying functions of the driver). The **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) must be implemented in this step.
3. Initialize the **HdmiCntlr** object at the core layer, including initializing the vendor custom structure (passing parameters and data) and instantiating the **HdmiCntlrOps** (used to call the underlying functions of the driver). The **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) must be implemented in this step.
- Custom structure reference
- Custom structure reference:
> ![](../public_sys-resources/icon-note.gif) **NOTE:**
> To the driver, the custom structure carries parameters and data. The values in the **hdmi_config.hcs** file are read by the HDF, and structure members are initialized by **DeviceResourceIface**. Some important values (such as the device number and bus number) are also passed to the **HdmiCntlr** object of the core layer.
> ![](../public_sys-resources/icon-note.gif) **NOTE**
>
> To the driver, the custom structure carries parameters and data. The values in the **hdmi_config.hcs** file are read by the HDF, and structure members are initialized by **DeviceResourceIface**. Some important values (such as the device number and bus number) are also passed to the **HdmiCntlr** object at the core layer.
```c
struct HdmiAdapterHost {
struct HdmiCntlr *cntlr; // (Mandatory) Control object of the core layer. The details are as follows:
struct HdmiCntlr *cntlr; // (Mandatory) Control object at the core layer. The details are as follows:
volatile unsigned char *regBase;// (Mandatory) Register base address.
uint32_t regBasePhy // (Mandatory) Physical base address of the register.
uint32_t regSize; // (Mandatory) Register bit width.
......@@ -277,15 +283,15 @@ The HDMI module adaptation involves the following steps:
};
```
- **Bind function**
- **Bind** function
> **Input parameter**:
> **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
> Input parameter:
> **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
>
> **Return value**
> **HDF_STATUS** (The following table lists some states. For more details, see **HDF_STATUS** definition in the **/drivers/framework/include/utils/hdf_base.h file**.)
> Return value:
> **HDF\_STATUS** (The following table lists some states. For more details, see **HDF\_STATUS** definition in the **/drivers/framework/include/utils/hdf\_base.h file**.)
|State (Value)|Status|
|State|Description|
|:-|:-|
|HDF_ERR_INVALID_OBJECT|Invalid controller object.|
|HDF_ERR_INVALID_PARAM |Invalid parameter.|
......@@ -294,7 +300,7 @@ The HDMI module adaptation involves the following steps:
|HDF_SUCCESS |Transmission successful.|
|HDF_FAILURE |Transmission failed.|
> **Function description:**
> Function description:
> Initializes the custom structure object **HdmiAdapterHost** and **HdmiCntlr**, and calls the **HdmiCntlrAdd** function to add the HDMI controller to the core layer.
>
> The **HdmiCntlr**, **HdmiAdapterHost**, and **HdfDeviceObject** assign values with each other so that other functions can be converted successfully.
......@@ -323,7 +329,7 @@ The HDMI module adaptation involves the following steps:
...
ret = HdmiAdapterHostParse(host, obj); // (Mandatory) Initialize the attributes of the host object. If the initialization fails, execute goto__ERR.
...
ret = HdmiAdapterHostInit(host, cntlr); // Perform vendor custom initialization. If the initialization fails, execute goto __ERR.
ret = HdmiAdapterHostInit(host, cntlr); // Perform vendor custom structure initialization. If the initialization fails, execute goto __ERR.
...
ret = HdmiCntlrAdd(cntlr); // Call the function at the core layer. If the operation fails, execute goto__ERR.
...
......@@ -336,12 +342,12 @@ The HDMI module adaptation involves the following steps:
}
```
- **Init function**
- **Init** function
>**Input parameter**:
>**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
>Input parameter:
>**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
>
>**Return value**
>Return value:
>HDF_STATUS
>
>Function description:
......@@ -355,16 +361,16 @@ The HDMI module adaptation involves the following steps:
}
```
- **Release function**
- **Release** function
> **Input parameter**:
> **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
> Input parameter:
> **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
>
> **Return value**
> Return value:
> –
>
> **Function description:**
> Releases the memory and deletes the controller. This function assigns a value to the **Release** API in the driver entry structure. When the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
> Function description:
> Releases the memory and deletes the controller. This function assigns a value to the **Release** API 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.
```c
static void HdmiAdapterRelease(struct HdfDeviceObject *obj)
......
......@@ -5,22 +5,20 @@
The Improved Inter-Integrated Circuit (I3C) is a simple and cost-efficient bidirectional 2-wire synchronous serial bus protocol developed by the Mobile Industry Processor Interface (MIPI) Alliance.
I3C is backward compatible with legacy Inter-Integrated Circuit (I2C) devices. Moreover, it provides the in-band interrupt (IBI) function and supports hot-join of I3C devices. This eliminates the need for adding an extra interrupt line to implement interrupts in I2C.
I3C is backward compatible with legacy Inter-Integrated Circuit (I2C). Moreover, it provides the in-band interrupt (IBI) function and supports hot-join of I3C devices. This eliminates the need for adding an extra interrupt line to implement interrupts in I2C.
The I2C device, I3C slave device, and I3C secondary master device can coexist on the I3C bus.
The I3C APIs provide a set of common functions for I3C transfer, including:
- Opening and closing an I3C controller.
- Obtaining and setting I3C controller parameters.
- Performing customized I3C message transfer by using a message array.
- Requesting and releasing an IBI.
- Opening and closing an I3C controller
- Obtaining and setting I3C controller parameters
- Performing custom I3C message transfer by using a message array
- Requesting and releasing an IBI
[Figure 1](#fig1) shows the I3C physical connection.
**Figure 1** I3C physical connection<a name="fig1"></a>
![](figures/I3C_physical_connection.png "I3C_physical_connection.png")
![](figures/I3C_physical_connection.png "I3C_physical_connection")
## Available APIs<a name="section2"></a>
......@@ -83,8 +81,9 @@ The I3C APIs provide a set of common functions for I3C transfer, including:
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>All functions described in this document can be called only in kernel space.
>![](../public_sys-resources/icon-note.gif) **NOTE**
>
>All functions described in this document can be called only in the kernel space.
## Usage Guidelines<a name="section3"></a>
......@@ -93,7 +92,6 @@ The I3C APIs provide a set of common functions for I3C transfer, including:
[Figure 2](#fig2) shows how I3C works.
**Figure 2** How I3C works<a name="fig2"></a>
![](figures/I3C_usage_flowchart.png "I3C_usage_flowchart")
### Opening an I3C Controller<a name="section5"></a>
......@@ -107,7 +105,7 @@ DevHandle I3cOpen(int16_t number);
<a name="table2"></a>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="20.66%"><p> Parameter</strong></p>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="20.66%"><p>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="79.34%"><p><strong>Description</strong></p>
</th>
......@@ -136,7 +134,7 @@ DevHandle I3cOpen(int16_t number);
</tbody>
</table>
In the following example, open I3C controller 1 of the eight I3C controllers (numbered from 0 to 7) in the system.
The following example opens I3C controller 1 of the eight I3C controllers (numbered from 0 to 7) in the system.
```c
DevHandle i3cHandle = NULL; /* I3C controller handle. /
......@@ -173,7 +171,7 @@ int32_t I3cTransfer(DevHandle handle, struct I3cMsg *msgs, int16_t count, enum T
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>msgs</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Message structure array of the data to be transmitted.</p>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the message structure array of the data to be transmitted.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>count</p>
......@@ -183,7 +181,7 @@ int32_t I3cTransfer(DevHandle handle, struct I3cMsg *msgs, int16_t count, enum T
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>mode</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>Transmission mode, where the value 0 indicates the I2C mode, 1 indicates the I3C mode, and 2 indicates transmission of the Common Command Code (CCC).
<td class="cellrowborder" valign="top" width="50%"><p>Transmission mode, where the value <b>0</b> indicates the I2C mode, <b>1</b> indicates the I3C mode, and <b>2</b> indicates transmission of the Common Command Code (CCC).
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
......@@ -211,11 +209,11 @@ int32_t ret;
uint8_t wbuff[2] = { 0x12, 0x13 };
uint8_t rbuff[2] = { 0 };
struct I3cMsg msgs[2]; /* Custom message array for transfer. */
msgs[0].buf = wbuff; /* Data to write */
msgs[0].buf = wbuff; /* Data to write. */
msgs[0].len = 2; /* Length of the data to write. */
msgs[0].addr = 0x3F; /* Address of the device to which the data is written. */
msgs[0].flags = 0; /* Transfer flag. An write operation is performed by default. */
msgs[1].buf = rbuff; /* Data to read */
msgs[0].flags = 0; /* Transfer flag. A write operation is performed by default. */
msgs[1].buf = rbuff; /* Data to read. */
msgs[1].len = 2; /* Length of the data to read. */
msgs[1].addr = 0x3F; /* Address of the device from which the data is read. */
msgs[1].flags = I3C_FLAG_READ /* I3C_FLAG_READ is set. */
......@@ -227,9 +225,10 @@ if (ret != 2) {
}
```
>![](../public_sys-resources/icon-caution.gif) **Caution**
>![](./public_sys-resources/icon-caution.gif) **Caution**
>
>- The device address in the **I3cMsg** structure does not contain the read/write flag bit. The read/write information is passed by the read/write control bit in the member variable **flags**.
>- The **I3cTransfer()** function does not limit the number of message structures or the length of data in each message structure. The I3C controller determines these two parameters.
>- The **I3cTransfer()** function does not limit the number of message structures or the length of data in each message structure. The I3C controller determines these two limits.
>- Using **I3cTransfer()** may cause the system to sleep. Do not call it in the interrupt context.
### Obtaining the I3C Controller Configuration<a name="section7"></a>
......@@ -242,7 +241,7 @@ int32_t I3cGetConfig(DevHandle handle, struct I3cConfig *config);
<a name="table4"></a>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong> Parameter</strong></p>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p>
</th>
......@@ -255,7 +254,7 @@ int32_t I3cGetConfig(DevHandle handle, struct I3cConfig *config);
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>config</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>I3C controller configuration.</p>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the I3C controller configuration.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
......@@ -286,7 +285,7 @@ int32_t I3cSetConfig(DevHandle handle, struct I3cConfig *config);
<a name="table5"></a>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong> Parameter</strong></p>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p>
</th>
......@@ -299,7 +298,7 @@ int32_t I3cSetConfig(DevHandle handle, struct I3cConfig *config);
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p>config</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p>I3C controller configuration.</p>
<td class="cellrowborder" valign="top" width="50%"><p>Pointer to the I3C controller configuration.</p>
</td>
</tr>
<tr><td class="cellrowborder" valign="top" width="50%"><p><strong>Return Value</strong></p>
......@@ -330,7 +329,7 @@ int32_t I3cRequestIbi(DevHandle handle, uint16_t addr, I3cIbiFunc func, uint32_t
<a name="table6"></a>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong> Parameter</strong></p>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p>
</th>
......@@ -418,7 +417,7 @@ int32_t I3cFreeIbi(DevHandle handle, uint16_t addr);
<a name="table7"></a>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong> Parameter</strong></p>
<table><thead align="left"><tr><th class="cellrowborder" valign="top" width="50%"><p><strong>Parameter</strong></p>
</th>
<th class="cellrowborder" valign="top" width="50%"><p><strong>Description</strong></p>
</th>
......@@ -486,7 +485,7 @@ void I3cClose(DevHandle handle);
I3cClose(i3cHandle); /* Close an I3C controller. */
```
## Example<a name="section12"></a>
## Example<a name="section12""></a>
This following example shows how to use I3C APIs to manage an I3C device on a Hi3516D V300 development board.
......@@ -504,7 +503,7 @@ The sample code is as follows:
```c
#include "i3c_if.h" /* Header file for I3C standard APIs */
#include "i3c_ccc.h" /* Header file for I3C CCCs */
#include "i3c_ccc.h" /* Header file for I3C CCC */
#include "hdf_log.h" /* Header file for log APIs */
##include "osal_io.h" /* Header file for I/O read and write APIs */
##include "osal_time.h" /* Header file for delay and sleep APIs */
......
......@@ -4,30 +4,14 @@
The Improved Inter-Integrated Circuit (I3C) is a simple and cost-efficient bidirectional 2-wire synchronous serial bus protocol developed by the Mobile Industry Processor Interface (MIPI) Alliance. In the Hardware Driver Foundation (HDF), the I3C module uses the unified service mode for API adaptation. In this mode, a device service is used as the I3C manager to handle external access requests in a unified manner, which is reflected in the configuration file. The unified service mode applies to the scenario where there are many device objects of the same type, for example, when the I3C has more than 10 controllers. If the independent service mode is used, more device nodes need to be configured and memory resources will be consumed by services.
![image1](figures/unified-service-mode.png)
## How to Develop<a name="2"></a>
The I3C module adaptation involves the following steps:
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
**Figure 1** Unified service mode<a name="fig1"></a>
- Add the **deviceNode** information to the **device_info.hcs** file.
- (Optional) Add the **i3c_config.hcs** file.
![image1](figures/unified-service-mode.png)
3. **Instantiate the I3C controller object.**
- Initialize **I3cCntlr**.
- Instantiate **I3cMethod** in **I3cCntlr**. For details, see the following description of **I3cMethod**.
## Available APIs<a name="2"></a>
4. Register an interrupt handler.
Registers an interrupt handler for the controller to implement the device hot-join and in-band interrupt (IBI) features.
I3cMethod:
**I3cMethod**:
```c
struct I3cMethod {
int32_t (*sendCccCmd)(struct I3cCntlr *cntlr, struct I3cCccCmd *ccc);
......@@ -40,29 +24,52 @@ The I3C module adaptation involves the following steps:
};
```
**Table 1** Callbacks for the members in the I3cMethod structure
**Table 1** APIs for the members in the I3cMethod structure
|Callback|Input Parameter|Output Parameter|Return Value|Description|
|Method|Input Parameter|Output Parameter|Return Value|Description|
|-|-|-|-|-|
|sendCccCmd|**cntlr**: structure pointer to an I3C controller at the core layer. <br> **ccc**: pointer to the input common command code (CCC) structure.|**ccc**: pointer to the output CCC structure.|HDF_STATUS|Sends a CCC.|
|Transfer |**cntlr**: structure pointer to an I3C controller at the core layer. <br>**msgs**: structure pointer to user messages. <br>**count**: number of messages, which is of the int16_t type.|**msgs**: structure pointer to user messages.|HDF_STATUS|Transfers user messages in I3C mode.|
|i2cTransfer |**cntlr**: structure pointer to an I3C controller at the core layer. <br>**msgs**: structure pointer to user messages. <br>**count**: number of messages, which is of the int16_t type.|**msgs**: structure pointer to user messages.|HDF_STATUS|Transfers user messages in I2C mode.|
|setConfig|**cntlr**: structure pointer to an I3C controller at the core layer. <br>**config**: controller configuration parameters.|–|HDF_STATUS|Configures an I3C controller.|
|getConfig|**cntlr**: structure pointer to an I3C controller at the core layer.|**config**: controller configuration parameters.|HDF_STATUS|Obtains the configuration of an I3C controller.|
|sendCccCmd|**cntlr**: structure pointer to an I3C controller at the core layer. <br/>**ccc**: pointer to the input common command code (CCC) structure.|**ccc**: pointer to the output CCC structure.|HDF_STATUS|Sends a CCC.|
|Transfer |**cntlr**: structure pointer to an I3C controller at the core layer. <br/>**msgs**: structure pointer to user messages. <br/>**count**: number of messages, which is of the int16_t type.|**msgs**: structure pointer to user messages.|HDF_STATUS|Transfers user messages in I3C mode.|
|i2cTransfer |**cntlr**: structure pointer to an I3C controller at the core layer. <br/>**msgs**: structure pointer to user messages. <br>**count**: number of messages, which is of the int16_t type.|**msgs**: structure pointer to user messages.|HDF_STATUS|Transfers user messages in I2C mode.|
|setConfig|**cntlr**: structure pointer to an I3C controller at the core layer. <br/>**config**: pointer to controller configuration parameters.|–|HDF_STATUS|Sets an I3C controller.|
|getConfig|**cntlr**: structure pointer to an I3C controller at the core layer.|**config**: pointer to controller configuration parameters.|HDF_STATUS|Obtains the configuration of an I3C controller.|
|requestIbi|**device**: structure pointer to an I3C device at the core layer.|–|HDF_STATUS|Requests an IBI for an I3C device.|
|freeIbi|**device**: structure pointer to an I3C device at the core layer.|–|HDF_STATUS|Releases the IBI for an I3C device.|
## Development Example<a name="3"></a>
## How to Develop<a name="3"></a>
The I3C module adaptation involves the following steps:
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
- Add the **deviceNode** information to the **device_info.hcs** file.
- (Optional) Add the **i3c_config.hcs** file.
3. Instantiate the I3C controller object.
- Initialize **I3cCntlr**.
- Instantiate **I3cMethod** in **I3cCntlr**. For details, see [Available APIs](#Available_apis).
4. Register an interrupt handler.
Register an interrupt handler for the controller to implement the device hot-join and in-band interrupt (IBI) features.
## Development Example<a name="4"></a>
1. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type (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 are collected to form a segment address space similar to an array for the upper layer to invoke.
1. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type (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 are collected to form a segment address space similar to an array for the upper layer to invoke.
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.
I3C driver entry reference
I3C driver entry reference:
> The I3C module may be connected with multiple controllers. Therefore, in the HDF, a manager object is created for the I3C, and a manager service is published to handle external access requests in a unified manner. Before a controller is opened, the manager service is obtained first. Then, the manager service locates the target controller based on the specified parameters.
> The I3C module may be connected with multiple controllers. Therefore, in the HDF, a manager object is created for the I3C, and a manager service is published to handle external access requests in a unified manner. Before a controller is opened, the manager service needs to be obtained first. Then, the manager service locates the target controller based on the specified parameters.
>
> The core layer implements the driver of the I3C manager service. **Vendors do not need to care about the implementation. When **Init()** is implemented, the **I3cCntlrAdd()** function at the core layer needs to be called to implement related features.**
> The core layer implements the driver of the I3C manager service. Vendors do not need to care about the implementation. However, during the implementation of **Init()**, the **I3cCntlrAdd()** function at the core layer needs to be called to implement related features.
```c
static struct HdfDriverEntry g_virtualI3cDriverEntry = {
......@@ -83,18 +90,18 @@ The I3C module adaptation involves the following steps:
HDF_INIT(g_i3cManagerEntry);
```
2. Add **deviceNode** to the **device_info.hcs** file, and configure the device attributes in the **i3c_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 **I3cCntlr** members at the core layer.
2. Add **deviceNode** to the **device\_info.hcs** file, and configure the device attributes in the **i3c\_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 **I3cCntlr** members at the core layer.
In the unified service mode, the first device node in the **device_info** file must be the I3C manager. The I3C manager parameters must be set as follows:
In the unified service mode, the first device node in the **device\_info** file must be the I3C manager. The I3C manager parameters must be set as follows:
|Member|Value|
|-|-|
|moduleName |HDF_PLATFORM_I3C_MANAGER|
|serviceName|- (reserved)|
|serviceName|Reserved|
|policy|0|
|cntlrMatchAttr| - (reserved)|
|cntlrMatchAttr| Reserved |
Configure I3C controller information from the second node. This node specifies a type of I3C controllers rather than a specific I3C controller. In this example, there is only one I3C controller. If there are multiple I3C controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **i3c_config** file.
Configure I3C controller information from the second node. This node specifies a type of I3C controllers rather than a specific I3C controller. In this example, there is only one I3C controller. If there are multiple I3C controllers, you need to add the **deviceNode** information to the **device\_info** file and add the corresponding device attributes to the **i3c\_config** file.
- **device_info.hcs** configuration reference
......@@ -120,14 +127,14 @@ The I3C module adaptation involves the following steps:
}
```
- i3c_config.hcs configuration reference
- **i3c_config.hcs** configuration reference
```c
root {
platform {
i3c_config {
match_attr = "virtual_i3c"; // (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs.
template i3c_controller { // Template configuration. In the template, you can configure the common parameters shared by service nodes.
template i3c_controller { // Template configuration. In the template, you can configure the common parameters shared by device nodes.
busId = 0; // (Mandatory) I3C bus number.
busMode = 0x0; // Bus mode. Which can be 0x0 (pure), 0x1 (mixed-fast), 0x2 (mixed-limited), or 0x3 (mixed-slow).
regBasePhy = 0x120b0000; // (Mandatory) Physical base address.
......@@ -147,17 +154,17 @@ The I3C module adaptation involves the following steps:
}
```
3. Initialize the **I3cCntlr** object at the core layer, including initializing the vendor custom structure (transferring parameters and data) and instantiating **I3cMethod** (used to call the underlying functions of the driver) in **I3cCntlr**.
3. Initialize the **I3cCntlr** object at the core layer, including initializing the custom structure (passing parameters and data) and instantiating **I3cMethod** (used to call the underlying functions of the driver) in **I3cCntlr**.
The **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) must be implemented in this step.
- Custom structure reference
> To the driver, the custom structure carries parameters and data. The values in the **i3c_config.hcs** file are read by the HDF, and the structure members are initialized through **DeviceResourceIface**. Some important values, such as the device number and bus number, are also passed to the **I3cCntlr** object at the core layer.
> The custom structure holds parameters and data for the driver. The HDF reads the values in the **i3c_config.hcs** file and initializes the structure members through **DeviceResourceIface**. Some important values, such as the device number and bus number, are also passed to the **I3cCntlr** object at the core layer.
```c
struct VirtualI3cCntlr {
struct AdcDevice device;// (Mandatory) Control object at the core layer. For details, see the following description of **I3cCntlr**.
struct AdcDevice device;// (Mandatory) Control object at the core layer. For details, see the following description of I3cCntlr.
volatile unsigned char *regBase;// (Mandatory) Register base address.
uint32_t regBasePhy; // (Mandatory) Physical base address of the register.
uint32_t regSize; // (Mandatory) Bit width of the register.
......@@ -184,19 +191,19 @@ The I3C module adaptation involves the following steps:
};
```
> **(Important)** The following shows instantiation of the **I3cCntlr** member callback structure **I3cMethod**. This example does not provide the instantiation of the **I3cLockMethod** callback structure. For details, see the I2C driver development. Other members are initialized in the **Init** function.
> **(Important)** This example does not provide the instantiation of the **I3cLockMethod** callback structure in **I3cCntlr**. For details, see the I2C driver development. Other members are initialized in the **Init** function.
- **Init function**
- **Init** function
> **Input parameter**:
> **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
> Input parameter:
> **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
>
> **Return value**
> **HDF_STATUS** (The following table lists some states. For more details, see **HDF_STATUS** definition in the **/drivers/framework/include/utils/hdf_base.h file**.)
> Return value:
> **HDF_STATUS** (The following table lists some states. For more details, see **HDF\_STATUS** definition in the **/drivers/framework/include/utils/hdf\_base.h file**.)
|State (Value)|Description|
|:-|:-:|
|State|Description|
|:-|:--|
|HDF_ERR_INVALID_OBJECT|Invalid controller object.|
|HDF_ERR_INVALID_PARAM |Invalid parameter.|
|HDF_ERR_MALLOC_FAIL |Failed to allocate memory.|
......@@ -204,8 +211,8 @@ The I3C module adaptation involves the following steps:
|HDF_SUCCESS |Transmission successful.|
|HDF_FAILURE |Transmission failed.|
> **Function description:**
> Initializes the custom structure object and **I3cCntlr**, and calls the **I3cCntlrAdd** function to add the i3C controller to the core layer.
> Function description:
> Initializes the custom structure object and **I3cCntlr**, and calls the **I3cCntlrAdd** function to add the I3C controller to the core layer.
```c
static int32_t VirtualI3cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
......@@ -238,7 +245,7 @@ The I3C module adaptation involves the following steps:
virtual->cntlr.busId = virtual->busId; // (Mandatory) Initialize I3cCntlr.
virtual->cntlr.ops = &g_method; // (Mandatory) Connect to the I3cMethod instance.
(void)OsalSpinInit(&virtual->spin);
ret = I3cCntlrAdd(&virtual->cntlr); // (Mandatory) Call this function to add the controller to the core layer. If a success signal is returned, the driver is completely connected to the core layer of the platform.
ret = I3cCntlrAdd(&virtual->cntlr); // (Mandatory) Call this function to add the controller to the core layer. If a success signal is returned, the driver is completely connected to the core layer.
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: add i3c controller failed! ret = %d", __func__, ret);
(void)OsalSpinDestroy(&virtual->spin);
......@@ -276,16 +283,16 @@ The I3C module adaptation involves the following steps:
}
```
- **Release function**
- **Release** function
> **Input parameter**:
> **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
> Input parameter:
> **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
>
> **Return value**
> Return value:
> None.
>
> **Function description:**
> Releases the memory and deletes the controller. This function assigns a value to the **Release** API in the driver entry structure. When the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. All forcible conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
> Function description:
> Releases the memory and deletes the controller. This function assigns a value to the **Release** function 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. All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
```c
static void VirtualI3cRemoveByNode(const struct DeviceResourceNode *node)
......@@ -313,7 +320,7 @@ The I3C module adaptation involves the following steps:
if (cntlr != NULL && cntlr->priv == node) {
I3cCntlrPut(cntlr);
I3cCntlrRemove(cntlr); // (Mandatory) Remove the I3cCntlr object from the manager driver.
virtual = (struct VirtualI3cCntlr *)cntlr; // (Mandatory) Obtain the custom object through a forcible conversion and perform the release operation.
virtual = (struct VirtualI3cCntlr *)cntlr; // (Mandatory) Obtain the custom object through a forced conversion and perform the release operation.
(void)OsalSpinDestroy(&virtual->spin);
OsalMemFree(virtual);
}
......@@ -381,7 +388,7 @@ The I3C module adaptation involves the following steps:
return HDF_ERR_INVALID_PARAM;
}
virtual = (struct VirtualI3cCntlr *)data;
/* (Mandatory) Obtain the address where the interrupt is generated. Use the CHECK_RESERVED_ADDR macro to determine whether the address is the reserved address of the I3C. */
/* (Mandatory) Obtain the address where the interrupt is generated. Use the CHECK_RESERVED_ADDR macro to determine whether the address is a reserved address of the I3C. */
ibiAddr = VirtualI3cGetIbiAddr();
if (CHECK_RESERVED_ADDR(ibiAddr) == I3C_ADDR_RESERVED) {
HDF_LOGD("%s: Calling VirtualI3cResAddrWorker...", __func__);
......
# Pin<a name="title_PinDevelop"></a>
## Overview<a name="section1_PinDevelop"></a>
The pin module controls the states and functionalities of system pins. In the Hardware Driver Foundation (HDF), the pin module uses the service-free mode for API adaptation. The service-free mode applies to devices that do not provide user-mode APIs or the OS system that does not distinguish the user mode and the kernel mode. In the service-free mode, DevHandle (a void pointer) directly points to the kernel-mode address of the device object.
Figure 1 Service-free mode
![image1](figures/service-free-mode.png "service-free-mode")
## Available APIs<a name="section2_PinDevelop"></a>
**PinCntlrMethod**:
```c
struct PinCntlrMethod {
int32_t (*SetPinPull)(struct PinCntlr *cntlr, uint32_t index, enum PinPullType pullType);
int32_t (*GetPinPull)(struct PinCntlr *cntlr, uint32_t index, enum PinPullType *pullType);
int32_t (*SetPinStrength)(struct PinCntlr *cntlr, uint32_t index, uint32_t strength);
int32_t (*GetPinStrength)(struct PinCntlr *cntlr, uint32_t index, uint32_t *strength);
int32_t (*SetPinFunc)(struct PinCntlr *cntlr, uint32_t index, const char *funcName);
int32_t (*GetPinFunc)(struct PinCntlr *cntlr, uint32_t index, const char **funcName);
};
```
**Table 1** APIs for the members in the PinCntlrMethod structure
| API | Input Parameter | Return Value| Description|
| ------------ | ------------------------------------------- | ------ | ---- |
| SetPinPull | **cntlr**: structure pointer to the pin controller at the core layer.<br>**index**: pin index, which is a uint32_t variable.<br>**pullType**: pull type of the pin. It is an enum constant.|HDF_STATUS|Sets the pull type of a pin.|
| GetPinPull | **cntlr**: structure pointer to the pin controller at the core layer.<br>**index**: pin index, which is a uint32_t variable.<br>**pullType**: pointer to the pull type of the pin.| HDF_STATUS| Obtains the pull type of a pin.|
| SetPinStrength | **cntlr**: structure pointer to the pin controller at the core layer.<br>**index**: pin index, which is a uint32_t variable.<br>**strength**: pull strength of the pin. It is a uint32_t variable.| HDF_STATUS| Sets the pull strength of a pin.|
| GetPinStrength | **cntlr**: structure pointer to the pin controller at the core layer.<br>**index**: pin index, which is a uint32_t variable.<br>**strength**: pointer to the pull strength of the pin.| HDF_STATUS| Obtains the pull strength of a pin.|
| SetPinFunc | **cntlr**: structure pointer to the pin controller at the core layer.<br>**index**: pin index, which is a uint32_t variable.<br>**funcName**: char pointer to the pin functionality.| HDF_STATUS| Sets the pin functionality.|
| GetPinFunc | **cntlr**: structure pointer to the pin controller at the core layer.<br>**index**: pin index, which is a uint32_t variable.<br>**funcName**: char double pointer to the pin functionality.| HDF_STATUS| Obtains the pin functionalities.|
## How to Develop<a name="section3_PinDevelop"></a>
The pin module adaptation involves the following steps:
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
- Add the **deviceNode** information to the **device_info.hcs** file.
- (Optional) Add the **pin_config.hcs** file.
3. Instantiate the pin controller object.
- Initialize the **PinCntlr** object.
- Instantiate **PinCntlrMethod** in the **PinCntlr** object.
>![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#section2_PINDevelop).
4. Debug the driver.
- (Optional) Verify basic functionalities of new drivers. For example, verify the information returned when the driver is loaded and whether data is successfully transmitted.
## Development Example<a name="section4_PinDevelop"></a>
The following uses **pin_hi35xx.c** as an example to present the content to be provided by the vendor to implement device functionalities.
1. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type (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 are collected to form a segment address space similar to an array for the upper layer to invoke.
Generally, the HDF calls the **Bind** function and then the **Init** function to load the driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
Pin driver entry reference:
```c
static struct HdfDriverEntry g_hi35xxPinDriverEntry = {
.moduleVersion = 1,
.Bind = Hi35xxPinBind,
.Init = Hi35xxPinInit,
.Release = Hi35xxPinRelease,
.moduleName = "hi35xx_pin_driver",// (Mandatory) The value must be the same as that of moduleName in the .hcs file.
};
// Call HDF_INIT to register the driver entry with the HDF.
HDF_INIT(g_hi35xxPinDriverEntry);
```
2. Add **deviceNode** to the **device\_info.hcs** file, and set the device attributes in the **pin\_config.hcs** file. The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the default values or value ranges of the **PinCntlr** members at the core layer.
>![](../public_sys-resources/icon-note.gif) **NOTE**
>If there are multiple devices, add the **deviceNode** information to the **device\_info** file and add the corresponding device attributes to the **pin\_config** file.
- **device\_info.hcs** reference:
```c
root {
device_info {
platform :: host {
hostName = "platform_host";
priority = 50;
device_pin :: device {
device0:: deviceNode { // Set an HDF device node for each pin controller.
policy = 0; // 2: visible in user mode; 1: visible in kernel mode; 0: no service required.
priority = 10; // Driver startup priority.
permission = 0644; // Permission to create device nodes for the driver.
/* (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. */
moduleName = "hi35xx_Pin_driver";
/* (Mandatory) Set the controller private data, which must be same as that in Pin_config.hcs. */
deviceMatchAttr = "hisilicon_hi35xx_Pin_0";
}
device1 :: deviceNode {
policy = 0;
priority = 10;
permission = 0644;
moduleName = "hi35xx_Pin_driver";
deviceMatchAttr = "hisilicon_hi35xx_Pin_1";
}
...
}
}
}
}
```
- **Pin\_config.hcs** reference:
```c
root {
platform {
Pin_config_hi35xx {
template Pin_controller { // (Mandatory) Template configuration. In the template, you can configure the common parameters shared by device nodes.
number = 0; // (Mandatory) Controller ID.
regStartBasePhy = 0; // (Mandatory) Start physical base address of the register.
regSize = 0; // (Mandatory) Register bit width.
PinCount = 0; // (Mandatory) Number of pins.
match_attr = "";
template Pin_desc {
PinName = ""; // (Mandatory) Pin name.
init = 0; // (Mandatory) Default value of the register.
F0 = ""; // (Mandatory) Functionality 0.
F1 = ""; // Functionality 1.
F2 = ""; // Functionality 2.
F3 = ""; // Functionality 3.
F4 = ""; // Functionality 4.
F5 = ""; // Functionality 5.
}
}
controller_0 :: Pin_controller {
number = 0;
regStartBasePhy = 0x10FF0000;
regSize = 0x48;
PinCount = 18;
match_attr = "hisilicon_hi35xx_Pin_0";
T1 :: Pin_desc {
PinName = "T1";
init = 0x0600;
F0 = "EMMC_CLK";
F1 = "SFC_CLK";
F2 = "SFC_BOOT_MODE";
}
...
}
...// Each pin controller corresponds to a controller node. If there are multiple pin controllers, add the corresponding controller nodes one by one.
}
}
}
```
3. Initialize the **PinCntlr** object at the core layer, including initializing the vendor custom structure (passing parameters and data), instantiating **PinCntlrMethod** (used to call underlying functions of the driver) in **PinCntlr**, and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**).
- Initializing the vendor custom structure
The **PinCntlr** structure holds parameters and data for the driver. The HDF obtains the values in **pin\_config.hcs** using **DeviceResourceIface**.
```c
// PinCntlr is the controller structure at the core layer. Its members are assigned with values by using the Init function.
struct PinCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *device;
struct PinCntlrMethod *method;
struct DListHead node;
OsalSPinlock sPin;
uint16_t number;
uint16_t PinCount;
struct PinDesc *Pins;
void *priv;
};
struct PinDesc {
const char *PinName; // Pointer to the pin name.
void *priv;
};
```
- Instantiating **PinCntlrMethod** (other members are initialized by **Init**)
```c
// Example of Pin_hi35xx.c: Instantiate the hook.
static struct PinCntlrMethod g_method = {
.SetPinPull = Hi35xxPinSetPull,
.GetPinPull = Hi35xxPinGetPull,
.SetPinStrength = Hi35xxPinSetStrength,
.GetPinStrength = Hi35xxPinGetStrength,
.SetPinFunc = Hi35xxPinSetFunc,
.GetPinFunc = Hi35xxPinGetFunc,
};
```
- **Init** function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
Return value:
**HDF\_STATUS** (The following table lists some states. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**.)
**Table 2** HDF\_STATUS
<table><thead align="left"><tr id="row31521027164144"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="entry1990732428164144p0"><a name="entry1990732428164144p0"></a><a name="entry1990732428164144p0"></a>State</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="entry2123581292164144p0"><a name="entry2123581292164144p0"></a><a name="entry2123581292164144p0"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row1749271383164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry202330388164144p0"><a name="entry202330388164144p0"></a><a name="entry202330388164144p0"></a>HDF_ERR_INVALID_OBJECT</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1717598064164144p0"><a name="entry1717598064164144p0"></a><a name="entry1717598064164144p0"></a>Invalid controller object</p>
</td>
</tr>
<tr id="row1715354988164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry450625221164144p0"><a name="entry450625221164144p0"></a><a name="entry450625221164144p0"></a>HDF_ERR_MALLOC_FAIL</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry361497788164144p0"><a name="entry361497788164144p0"></a><a name="entry361497788164144p0"></a>Failed to allocate memory</p>
</td>
</tr>
<tr id="row1202091366164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry370837906164144p0"><a name="entry370837906164144p0"></a><a name="entry370837906164144p0"></a>HDF_ERR_INVALID_PARAM</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry353311523164144p0"><a name="entry353311523164144p0"></a><a name="entry353311523164144p0"></a>Invalid parameter</p>
</td>
</tr>
<tr id="row602018308164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1984036607164144p0"><a name="entry1984036607164144p0"></a><a name="entry1984036607164144p0"></a>HDF_ERR_IO</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1221756048164144p0"><a name="entry1221756048164144p0"></a><a name="entry1221756048164144p0"></a>I/O error</p>
</td>
</tr>
<tr id="row47997479164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1220816374164144p0"><a name="entry1220816374164144p0"></a><a name="entry1220816374164144p0"></a>HDF_SUCCESS</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1903499126164144p0"><a name="entry1903499126164144p0"></a><a name="entry1903499126164144p0"></a>Initialization successful</p>
</td>
</tr>
<tr id="row2031856197164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry463793674164144p0"><a name="entry463793674164144p0"></a><a name="entry463793674164144p0"></a>HDF_FAILURE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry516362874164144p0"><a name="entry516362874164144p0"></a><a name="entry516362874164144p0"></a>Initialization failed</p>
</td>
</tr>
</tbody>
</table>
Function description:
Initializes the custom structure and **PinCntlr** members, and connects to the pin controller by calling the **PinCntlrAdd** function at the core layer.
```c
static int32_t Hi35xxPinInit(struct HdfDeviceObject *device)
{
...
struct Hi35xxPinCntlr *hi35xx = NULL;
...
ret = Hi35xxPinCntlrInit(device, hi35xx); // Obtain .hcs information.
...
DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
ret = Hi35xxPinParsePinNode(childNode, hi35xx, index); // (Mandatory) The implementation is as follows:
...
}
hi35xx->cntlr.method = &g_method; // Instantiate OPS.
ret = PinCntlrAdd(&hi35xx->cntlr); // Connect to the controller.
...
}
static int32_t Hi35xxPinParsePinNode(const struct DeviceResourceNode *node,
struct Hi35xxPinCntlr *hi35xx,
int32_t index)
{
...
hi35xx->cntlr.Pins[index].PinName = hi35xx->desc[index].PinName; // Instantiate PinName.
hi35xx->cntlr.Pins[index].priv = (void *)node; // Instantiate nodes.
...
}
- **Release** function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
Return value:
Function description:
Releases memory and deletes the controller. This function assigns a value to the **Release** API 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.
```c
static void Hi35xxPinRelease(struct HdfDeviceObject *device)
{
struct PinCntlr *cntlr = NULL;
...
PinCntlrRemove(cntlr);// (Mandatory) Call the function at the core layer to release pin controller devices and services.
...
}
```
# Regulator<a name="title_REGULATOR_des"></a>
## Overview<a name="section1_REGULATOR_des"></a>
The regulator module controls the voltage and current supplies of some devices in the system. In an embedded system (especially a mobile phone), it is important to control the power consumption, which directly affects the battery endurance. You can use a regulator to shut down the power supply to an idle module in the system or reduce the voltage and current for the module.
- The regulator APIs provide a set of functions for managing a regulator, including those for:
- Opening or closing a regulator device handle
- Setting the output voltage and current for a regulator
- Enabling or disabling a regulator
- Obtaining the voltage, current, and status of a regulator
## Available APIs<a name="section2_REGULATOR_des"></a>
**Table 1** Regulator APIs
<a name="table1_REGULATOR_des"></a>
<table border="0" cellpadding="0" cellspacing="0" width="600" style="border-collapse:
collapse;table-layout:fixed;width:855pt">
<colgroup><col width="183" style="mso-width-source:userset;mso-width-alt:5856;width:137pt">
<col width="159" style="mso-width-source:userset;mso-width-alt:5088;width:119pt">
<col width="213" style="mso-width-source:userset;mso-width-alt:6816;width:160pt">
</colgroup><tbody><tr height="19" style="height:14.25pt">
<td height="19" width="183" style="height:14.25pt;width:137pt">Category</td>
<td width="159" style="width:119pt">API</td>
<td width="213" style="width:160pt">Description</td>
</tr>
<tr height="19" style="height:14.25pt">
<td rowspan="2" height="38" class="xl65" style="height:28.5pt">Operating a regulator device handle</td>
<td>RegulatorOpen</td>
<td>Opens a regulator device handle.</td>
</tr>
<tr height="19" style="height:14.25pt">
<td height="19" style="height:14.25pt">RegulatorClose</td>
<td>Closes a regulator device handle.</td>
</tr>
<tr height="19" style="height:14.25pt">
<td rowspan="3" height="57" class="xl65" style="height:42.75pt">Enabling or disable a regulator</td>
<td>RegulatorEnable</td>
<td>Enables a regulator.</td>
</tr>
<tr height="19" style="height:14.25pt">
<td height="19" style="height:14.25pt">RegulatorDisable</td>
<td>Disables a regulator.</td>
</tr>
<tr height="19" style="height:14.25pt">
<td height="19" style="height:14.25pt">RegulatorForceDisable</td>
<td>Forcibly disables a regulator.</td>
</tr>
<tr height="19" style="height:14.25pt">
<td rowspan="2" height="38" class="xl65" style="height:28.5pt">Setting or obtaining the output voltage</td>
<td>RegulatorSetVoltage</td>
<td>Sets the output voltage for a regulator.</td>
</tr>
<tr height="19" style="height:14.25pt">
<td height="19" style="height:14.25pt">RegulatorGetVoltage</td>
<td>Obtains the output voltage of a regulator.</td>
</tr>
<tr height="19" style="height:14.25pt">
<td rowspan="2" height="38" class="xl65" style="height:28.5pt">Setting or obtaining the output current</td>
<td>RegulatorSetCurrent</td>
<td>Sets the output current for a regulator.</td>
</tr>
<tr height="19" style="height:14.25pt">
<td height="19" style="height:14.25pt">RegulatorGetCurrent</td>
<td>Obtains the output current of a regulator.</td>
</tr>
<tr height="19" style="height:14.25pt">
<td height="19" class="xl66" style="height:14.25pt">Querying the regulator status</td>
<td>RegulatorGetStatus</td>
<td>Obtains the regulator status.</td>
</tr>
<!--[if supportMisalignedColumns]-->
<tr height="0" style="display:none">
<td width="183" style="width:137pt"></td>
<td width="159" style="width:119pt"></td>
<td width="213" style="width:160pt"></td>
</tr>
<!--[endif]-->
</tbody></table>
>![](../public_sys-resources/icon-note.gif) **NOTE**
>The regulator module can be used in kernel mode but not in user mode.
## Usage Guidelines<a name="section3_REGULATOR_des"></a>
### How to Use<a name="section3.1_REGULATOR_des"></a>
During the OS startup process, the driver management module loads the regulator driver based on the configuration file. Then, the regulator driver detects the regulator devices and initializes the driver.
The figure below shows the process of using a regulator.
**Figure 1** Process of using a regulator<a name="fig1_regulator_des"></a>
![](figures/process-of-using-regulator.png)
### Opening a Regulator Device Handle<a name="section3.2_REGULATOR_des"></a>
Before operating a regulator, call **RegulatorOpen** to open the device handle of the regulator. This function returns the device handle of the regulator.
```c
DevHandle RegulatorOpen(const char *name);
```
**Table 2** Description of RegulatorOpen
<a name="table2_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ---------- | ----------------------------- |
| name | Name of the target regulator. |
| **Return Value**| **Description** |
| handle | The regulator device handle is returned if the operation is successful.|
| NULL | The operation fails. |
```c
/* Regulator name. */
const char *name = "regulator_virtual_1";
DevHandle handle = NULL;
/* Open the regulator device handle. */
handle = RegulatorOpen(name);
if (handle == NULL) {
/* Error handling. */
}
```
### Closing a Regulator Device Handle<a name="section3.3_REGULATOR_des"></a>
Call **RegulatorClose** to close the regulator device handle to release resources.
```c
void RegulatorClose(DevHandle handle);
```
**Table 3** Description of RegulatorClose
<a name="table3_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ------ | ----------------- |
| handle | Regulator device handle to close.|
```c
/* Close the regulator device handle. */
RegulatorClose(handle);
```
### Enabling a Regulator<a name="section3.4_REGULATOR_des"></a>
Call **RegulatorEnable** to enable a regulator.
```c
int32_t RegulatorEnable(DevHandle handle);
```
**Table 4** Description of RegulatorEnable
<a name="table4_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ---------- | ----------------- |
| handle | Device handle of the regulator to enable.|
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
```c
int32_t ret;
/* Enable the regulator. */
ret = RegulatorEnable(handle);
if (ret != 0) {
/* Error handling. */
}
```
### Disabling a Regulator<a name="section3.5_REGULATOR_des"></a>
Call **RegulatorDisable** to disable a regulator. The operation will fail if the regulator status is set to always on or if a child node of the regulator is not disabled.
```c
int32_t RegulatorDisable(DevHandle handle);
```
**Table 5** Description of RegulatorDisable
<a name="table5_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ---------- | ----------------- |
| handle | Device handle of the regulator to disable.|
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
```c
int32_t ret;
/* Disable the regulator. */
ret = RegulatorDisable(handle);
if (ret != 0) {
/* Error handling. */
}
```
### Forcibly Disabling a Regulator<a name="section3.6_REGULATOR_des"></a>
Call **RegulatorForceDisable** to forcibly disable a regulator. The regulator will be disabled event if its status is set to always on or its child node is still enabled.
```c
int32_t RegulatorForceDisable(DevHandle handle);
```
**Table 6** Description of RegulatorForceDisable
<a name="table6_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ---------- | ----------------- |
| handle | Device handle of the target regulator.|
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
```c
int32_t ret;
/* Forcibly disable the regulator. */
ret = RegulatorForceDisable(handle);
if (ret != 0) {
/* Error handling. */
}
```
### Setting the Output Voltage Range for a Regulator<a name="section3.7_REGULATOR_des"></a>
Call **RegulatorSetVoltage** to set the output voltage range for a regulator.
```c
int32_t RegulatorSetVoltage(DevHandle handle, uint32_t minUv, uint32_t maxUv);
```
**Table 7** Description of RegulatorSetVoltage
<a name="table7_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ---------- | ----------------- |
| handle | Device handle of the target regulator.|
| minUv | Minimum voltage to set. |
| maxUv | Maximum voltage to set. |
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
```c
int32_t ret;
int32_t minUv = 0; // Set the minimum voltage to 0 µV.
int32_t maxUv = 20000; // Set the maximum voltage to 20000 µV.
/* Set the output voltage range for the regulator. */
ret = RegulatorSetVoltage(handle, minUv, maxUv);
if (ret != 0) {
/* Error handling. */
}
```
### Obtaining Regulator Voltage Information<a name="section3.8_REGULATOR_des"></a>
Call **RegulatorGetVoltage** to obtain voltage information of a regulator.
```c
int32_t RegulatorGetVoltage(DevHandle handle, uint32_t *voltage);
```
**Table 8** Description of RegulatorGetVoltage
<a name="table8_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ---------- | ----------------- |
| handle | Device handle of the target regulator.|
| *voltage | Pointer to the regulator voltage information. |
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
```c
int32_t ret;
uint32_t voltage;
/* Obtain the regulator voltage information. */
ret = RegulatorGetVoltage(handle, &voltage);
if (ret != 0) {
/* Error handling. */
}
```
### Setting the Output Current Range for a Regulator<a name="section3.9_REGULATOR_des"></a>
Call **RegulatorSetCurrent** to set the output current range for a regulator.
```c
int32_t RegulatorSetCurrent(DevHandle handle, uint32_t minUa, uint32_t maxUa);
```
**Table 9** Description of RegulatorSetCurrent
<a name="table9_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ---------- | ----------------- |
| handle | Device handle of the target regulator.|
| minUa | Minimum current to set. |
| maxUa | Maximum current to set. |
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
```c
int32_t ret;
int32_t minUa = 0; // Set the minimum current to 0 μA.
int32_t maxUa = 200; // Set the maximum current to 200 μA.
/* Set the output current range for the regulator. */
ret = RegulatorSetCurrent(handle, minUa, maxUa);
if (ret != 0) {
/* Error handling. */
}
```
### Obtaining Regulator Current Information<a name="section3.10_REGULATOR_des"></a>
Call **RegulatorGetCurrent** to obtain current information of a regulator.
```c
int32_t RegulatorGetCurrent(DevHandle handle, uint32_t *regCurrent);
```
**Table 10** Description of RegulatorGetCurrent
<a name="table10_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ----------- | ----------------- |
| handle | Device handle of the target regulator.|
| *regCurrent | Pointer to the regulator current information. |
| **Return Value** | **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
```c
int32_t ret;
uint32_t regCurrent;
/* Obtain the regulator current information. */
ret = RegulatorGetCurrent(handle, &regCurrent);
if (ret != 0) {
/* Error handling. */
}
```
### Obtaining Regulator Status<a name="section3.11_REGULATOR_des"></a>
Call **RegulatorGetStatus** to obtain the regulator status.
```c
int32_t RegulatorGetStatus(DevHandle handle, uint32_t *status);
```
**Table 11** Description of RegulatorGetStatus
<a name="table11_REGULATOR_des"></a>
| **Parameter** | **Description** |
| ---------- | ----------------- |
| handle | Device handle of the target regulator.|
| *status | Pointer to the regulator status information. |
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
```c
int32_t ret;
uint32_t status;
/* Obtain the regulator status. */
ret = RegulatorGetStatus(handle, &status);
if (ret != 0) {
/* Error handling. */
}
```
## Development Example<a name="section4_REGULATOR_des"></a>
The following is an example of using a regulator.
```c
void RegulatorTestSample(void)
{
int32_t ret;
/* Regulator name. */
const char *name = "regulator_virtual_1";
DevHandle handle = NULL;
/* Open the regulator device handle. */
handle = RegulatorOpen(name);
if (handle == NULL) {
HDF_LOGE("RegulatorOpen: failed!\n");
return;
}
/* Enable the regulator. */
ret = RegulatorEnable(handle);
if (ret != 0) {
HDF_LOGE("RegulatorEnable: failed, ret %d\n", ret);
goto _ERR;
}
int32_t minUv = 0; // Set the minimum voltage to 0 µV.
int32_t maxUv = 20000; // Set the maximum voltage to 20000 µV.
/* Set the output voltage range for the regulator. */
ret = RegulatorSetVoltage(handle, minUv, maxUv);
if (ret != 0) {
HDF_LOGE("RegulatorSetVoltage: failed, ret %d\n", ret);
goto _ERR;
}
uint32_t voltage;
/* Obtain the regulator voltage information. */
ret = RegulatorGetVoltage(handle, &voltage);
if (ret != 0) {
HDF_LOGE("RegulatorGetVoltage: failed, ret %d\n", ret);
goto _ERR;
}
uint32_t status;
/* Obtain the regulator status. */
ret = RegulatorGetStatus(handle, &status);
if (ret != 0) {
HDF_LOGE("RegulatorGetStatus: failed, ret %d\n", ret);
goto _ERR;
}
/* Disable the regulator. */
ret = RegulatorDisable(handle);
if (ret != 0) {
HDF_LOGE("RegulatorDisable: failed, ret %d\n", ret);
goto _ERR;
}
_ERR:
/* Close the regulator device handle. */
RegulatorClose(handle);
}
```
# Regulator<a name="title_REGULATORDevelop"></a>
## Overview<a name="section1_REGULATORDevelop"></a>
The regulator module controls the voltage and current supplies of some devices in the system. In the Hardware Driver Foundation (HDF), the regulator module uses the unified service mode for API adaptation. In this mode, a device service is used as the regulator manager to handle external access requests in a unified manner, which is reflected in the configuration file. The unified service mode applies to the scenario where there are many device objects of the same type, for example, when the regulator has more than 10 controllers. If the independent service mode is used, more device nodes need to be configured and more memory resources will be consumed by services.
**Figure 1** Unified service mode
![image1](figures/unified-service-mode.png)
## Available APIs<a name="section2_REGULATORDevelop"></a>
**RegulatorMethod** structure:
```c
struct RegulatorMethod {
int32_t (*open)(struct RegulatorNode *node);
int32_t (*close)(struct RegulatorNode *node);
int32_t (*release)(struct RegulatorNode *node);
int32_t (*enable)(struct RegulatorNode *node);
int32_t (*disable)(struct RegulatorNode *node);
int32_t (*forceDisable)(struct RegulatorNode *node);
int32_t (*setVoltage)(struct RegulatorNode *node, uint32_t minUv, uint32_t maxUv);
int32_t (*getVoltage)(struct RegulatorNode *node, uint32_t *voltage);
int32_t (*setCurrent)(struct RegulatorNode *node, uint32_t minUa, uint32_t maxUa);
int32_t (*getCurrent)(struct RegulatorNode *node, uint32_t *regCurrent);
int32_t (*getStatus)(struct RegulatorNode *node, uint32_t *status);
};
```
**Table 1** APIs for the members in the RegulatorMethod structure
| Method | Input Parameter | Return Value| Description|
| ------------ | ------------------------------------------- | ------ | ---- |
| open | **node**: structure pointer to the regulator node at the core layer.|HDF_STATUS|Opens a device.|
| close | **node**: structure pointer to the regulator node at the core layer.| HDF_STATUS| Closes a device.|
| release | **node**: structure pointer to the regulator node at the core layer.| HDF_STATUS| Releases a device handle.|
| enable | **node**: structure pointer to the regulator node at the core layer.| HDF_STATUS| Enables a device.|
| disable | **node**: structure pointer to the regulator node at the core layer.| HDF_STATUS| Disables a device.|
| forceDisable | **node**: structure pointer to the regulator node at the core layer.| HDF_STATUS| Forcibly disables a device.|
| setVoltage | **node**: structure pointer to the regulator node at the core layer.<br>**minUv**: minimum voltage to set. It is a uint32_t variable.<br>**maxUv**: maximum voltage to set. It is a uint32_t variable.| HDF_STATUS| Sets the output voltage range.|
| getVoltage | **node**: structure pointer to the regulator node at the core layer.<br>**voltage**: pointer to the output voltage value.| HDF_STATUS| Obtains the voltage.|
| setCurrent | **node**: structure pointer to the regulator node at the core layer.<br>**minUa**: minimum current to set. It is a uint32_t variable.<br>**maxUa**: maximum current to set. It is a uint32_t variable.| HDF_STATUS| Sets the output current range.|
| getCurrent | **node**: structure pointer to the regulator node at the core layer.<br>**regCurrent**: pointer to the output current, which is of the uint32_t type.| HDF_STATUS| Obtains the current.|
| getStatus | **node**: structure pointer to the regulator node at the core layer.<br>**status**: pointer to the output status, which is of the uint32_t type.| HDF_STATUS| Obtains the device status.|
## How to Develop<a name="section3_REGULATORDevelop"></a>
The regulator module adaptation involves the following steps:
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
- Add the **deviceNode** information to the **device_info.hcs** file.
- (Optional) Add the **regulator_config.hcs** file.
3. Instantiate the regulator controller object.
- Initialize **RegulatorNode** members.
- Instantiate **RegulatorMethod**.
>![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#section2_REGULATORDevelop).
4. Debug the driver.
- (Optional) Verify basic functionalities of new drivers. For example, verify the information returned when the driver is loaded and whether data is successfully transmitted.
## Development Example<a name="section4_REGULATORDevelop"></a>
The following uses **regulator_virtual.c** as an example to present the content to be provided by the vendor to implement device functionalities.
1. Instantiate the driver entry. The driver entry must be a global variable of the **HdfDriverEntry** type (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 are collected to form a segment address space similar to an array for the upper layer to invoke.
Generally, the HDF calls the **Bind** function and then the **Init** function to load the driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
Regulator driver entry reference:
```c
struct HdfDriverEntry g_regulatorDriverEntry = {
.moduleVersion = 1,
.moduleName = "virtual_regulator_driver",// (Mandatory) The value must be the same as that of moduleName in the .hcs file.
.Init = VirtualRegulatorInit,
.Release = VirtualRegulatorRelease,
};
// Call HDF_INIT to register the driver entry with the HDF framework.
HDF_INIT(g_regulatorDriverEntry);
```
2. Add **deviceNode** to the **device\_info.hcs** file, and set the device attributes in the **regulator\_config.hcs** file. The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the default values or value ranges of the **RegulatorNode** members at the core layer.
>![](W:\doc\docs\en\device-dev\public_sys-resources\icon-note.gif) **NOTE**
>If there are multiple devices, add the **deviceNode** information to the **device\_info** file and add the corresponding device attributes to the **regulator\_config** file.
- **device\_info.hcs** reference:
```c
root {
device_info {
platform :: host {
hostName = "platform_host";
priority = 50;
device_regulator :: device {
device0 :: deviceNode { // Configure an HDF device node for each regulator controller.
policy = 1; // 2: visible in user mode; 1: visible in kernel mode; 0: no service required.
priority = 50; // Driver startup priority.
permission = 0644; // Permission to create device nodes of the driver.
/* (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. */
moduleName = "HDF_PLATFORM_REGULATOR_MANAGER";
serviceName = "HDF_PLATFORM_REGULATOR_MANAGER"; // (Mandatory) Unique name of the service published by the driver.
/* (Mandatory) Set the controller private data, which must be same as that in regulator_config.hcs. */
deviceMatchAttr = "hdf_platform_regulator_manager";
}
device1 :: deviceNode {
policy = 0;
priority = 55;
permission = 0644;
moduleName = "linux_regulator_adapter";
deviceMatchAttr = "linux_regulator_adapter";
}
}
}
}
}
```
- **regulator\_config.hcs** reference:
```c
root {
platform {
regulator_config {
match_attr = "linux_regulator_adapter";
template regulator_controller { // (Mandatory) Template configuration. In the template, you can configure the common parameters shared by device nodes.
device_num = 1;
name = "";
devName = "regulator_adapter_consumer01";
supplyName = "";
mode = 1;
minUv = 0;
maxUv = 20000;
minUa = 0;
maxUa = 0;
}
controller_0x130d0000 :: regulator_controller {
device_num = 1;
name = "regulator_adapter_1";
devName = "regulator_adapter_consumer01";
supplyName = "virtual-regulator-hdf-adapter";
mode = 1;
minUv = 1000;
maxUv = 50000;
minUa = 0;
maxUa = 0;
}
/* Each regulator controller corresponds to a controller node. If there are multiple regulator controllers, add the corresponding controller nodes one by one.*/
controller_0x130d0001 :: regulator_controller {
device_num = 1;
name = "regulator_adapter_2";
devName = "regulator_adapter_consumer01";
supplyName = "virtual2-regulator-hdf-adapter";
mode = 2;
minUv = 0;
maxUv = 0;
minUa = 1000;
maxUa = 50000;
}
}
}
}
```
3. Initialize the **RegulatorNode** object at the core layer, including initializing the vendor custom structure (passing parameters and data), instantiating **RegulatorMethod** (used to call underlying functions of the driver) in **PinCntlr**, and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**).
- Initializing the vendor custom structure
The **RegulatorNode** structure holds parameters and data for the driver. The HDF obtains the values in **regulator\_config.hcs** using **DeviceResourceIface**.
```c
// RegulatorNode is the controller structure at the core layer. Its members are assigned with values by using the Init function.
struct RegulatorNode {
struct RegulatorDesc regulatorInfo;
struct DListHead node;
struct RegulatorMethod *ops;
void *priv;
struct OsalMutex lock;
};
struct RegulatorDesc {
const char *name; /* Regulator name. */
const char *parentName; /* Regulator parent node name. */
struct RegulatorConstraints constraints; /* Regulator constraint information. */
uint32_t minUv; /* Minimum output voltage. */
uint32_t maxUv; /* Maximum output voltage. */
uint32_t minUa; /* Minimum output current. */
uint32_t maxUa; /* Maximum output current. */
uint32_t status; /* Regulator status, which can be on or off. */
int useCount;
int consumerRegNums; /* Number of regulator consumers. */
RegulatorStatusChangecb cb; /* Variable used to notify the regulator status changes. */
};
struct RegulatorConstraints {
uint8_t alwaysOn; /* Whether the regulator is always on. */
uint8_t mode; /* Voltage or current. */
uint32_t minUv; /* Minimum output voltage allowed. */
uint32_t maxUv; /* Maximum output voltage allowed. */
uint32_t minUa; /* Minimum output current allowed. */
uint32_t maxUa; /* Maximum output current allowed. */
};
```
- Instantiating **RegulatorMethod** (other members are initialized by **Init**)
```c
// Example of regulator_virtual.c: Instantiate the hook.
static struct RegulatorMethod g_method = {
.enable = VirtualRegulatorEnable,
.disable = VirtualRegulatorDisable,
.setVoltage = VirtualRegulatorSetVoltage,
.getVoltage = VirtualRegulatorGetVoltage,
.setCurrent = VirtualRegulatorSetCurrent,
.getCurrent = VirtualRegulatorGetCurrent,
.getStatus = VirtualRegulatorGetStatus,
};
```
- **Init** function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
Return value:
**HDF\_STATUS** (The following table lists some states. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**.)
**Table 2** HDF\_STATUS
<table><thead align="left"><tr id="row31521027164144"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="entry1990732428164144p0"><a name="entry1990732428164144p0"></a><a name="entry1990732428164144p0"></a>State</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="entry2123581292164144p0"><a name="entry2123581292164144p0"></a><a name="entry2123581292164144p0"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row1749271383164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry202330388164144p0"><a name="entry202330388164144p0"></a><a name="entry202330388164144p0"></a>HDF_ERR_INVALID_OBJECT</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1717598064164144p0"><a name="entry1717598064164144p0"></a><a name="entry1717598064164144p0"></a>Invalid controller object.</p>
</td>
</tr>
<tr id="row1715354988164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry450625221164144p0"><a name="entry450625221164144p0"></a><a name="entry450625221164144p0"></a>HDF_ERR_MALLOC_FAIL</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry361497788164144p0"><a name="entry361497788164144p0"></a><a name="entry361497788164144p0"></a>Failed to allocate memory.</p>
</td>
</tr>
<tr id="row1202091366164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry370837906164144p0"><a name="entry370837906164144p0"></a><a name="entry370837906164144p0"></a>HDF_ERR_INVALID_PARAM</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry353311523164144p0"><a name="entry353311523164144p0"></a><a name="entry353311523164144p0"></a>Invalid parameter.</p>
</td>
</tr>
<tr id="row602018308164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1984036607164144p0"><a name="entry1984036607164144p0"></a><a name="entry1984036607164144p0"></a>HDF_ERR_IO</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1221756048164144p0"><a name="entry1221756048164144p0"></a><a name="entry1221756048164144p0"></a>I/O error.</p>
</td>
</tr>
<tr id="row47997479164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1220816374164144p0"><a name="entry1220816374164144p0"></a><a name="entry1220816374164144p0"></a>HDF_SUCCESS</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1903499126164144p0"><a name="entry1903499126164144p0"></a><a name="entry1903499126164144p0"></a>Initialization successful.</p>
</td>
</tr>
<tr id="row2031856197164144"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry463793674164144p0"><a name="entry463793674164144p0"></a><a name="entry463793674164144p0"></a>HDF_FAILURE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry516362874164144p0"><a name="entry516362874164144p0"></a><a name="entry516362874164144p0"></a>Initialization failed.</p>
</td>
</tr>
</tbody>
</table>
Function description:
Initializes the custom structure and **RegulatorNode** members, and adds the regulator controller by calling the **RegulatorNodeAdd** function at the core layer.
```c
static int32_t VirtualRegulatorInit(struct HdfDeviceObject *device)
{
int32_t ret;
const struct DeviceResourceNode *childNode = NULL;
...
DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
ret = VirtualRegulatorParseAndInit(device, childNode);// (Mandatory) The implementation is as follows:
...
}
...
}
static int32_t VirtualRegulatorParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
{
int32_t ret;
struct RegulatorNode *regNode = NULL;
(void)device;
regNode = (struct RegulatorNode *)OsalMemCalloc(sizeof(*regNode));// Load the .hcs file.
...
ret = VirtualRegulatorReadHcs(regNode, node);// Read .hcs information.
...
regNode->priv = (void *)node; // Instantiate the node.
regNode->ops = &g_method; // Instantiate OPS.
ret = RegulatorNodeAdd(regNode); // Add the node.
...
}
- **Release** function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
Return value:
Function description:
Releases memory and deletes the controller. This function assigns a value to the **Release** API 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.
```c
static void VirtualRegulatorRelease(struct HdfDeviceObject *device)
{
...
RegulatorNodeRemoveAll();// (Mandatory) Call the function at the core layer to release regulator controller devices and services.
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册