- 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.
<tdclass="cellrowborder"valign="top"width="53.339999999999996%">Reads the raw EDID from a sink.</p>
</td>
</tr>
<tr><tdclass="cellrowborder"bgcolor="#ffffff"rowspan="2"valign="top"width="18.63%"><p>Registering or unregistering a callback for HDMI hot plug detect</p>
<tr><tdclass="cellrowborder"bgcolor="#ffffff"rowspan="2"valign="top"width="18.63%"><p>Registering or unregistering a callback for HDMI HPD</p>
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.
<tdclass="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).
<tdclass="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).
>- 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>
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>
### 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<aname="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
DevHandleRegulatorOpen(constchar*name);
```
**Table 2** Description of RegulatorOpen
<aname="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. */
constchar*name="regulator_virtual_1";
DevHandlehandle=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
voidRegulatorClose(DevHandlehandle);
```
**Table 3** Description of RegulatorClose
<aname="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_tRegulatorEnable(DevHandlehandle);
```
**Table 4** Description of RegulatorEnable
<aname="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_tret;
/* 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_tRegulatorDisable(DevHandlehandle);
```
**Table 5** Description of RegulatorDisable
<aname="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_tret;
/* 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_tRegulatorForceDisable(DevHandlehandle);
```
**Table 6** Description of RegulatorForceDisable
<aname="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_tret;
/* 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.
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>
| 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.
>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
structHdfDriverEntryg_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.
>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. */
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.
<tdclass="cellrowborder"valign="top"width="50%"headers="mcps1.1.3.1.2 "><pid="entry361497788164144p0"><aname="entry361497788164144p0"></a><aname="entry361497788164144p0"></a>Failed to allocate memory.</p>
Initializes the custom structure and **RegulatorNode** members, and adds the regulator controller by calling the **RegulatorNodeAdd** function at the core layer.