@@ -79,7 +79,7 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
...
@@ -79,7 +79,7 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
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 is collected to form a segment address space similar to an array for the upper layer to invoke.
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 is 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.
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.
GPIO driver entry example:
GPIO driver entry example:
```
```
struct HdfDriverEntry g_gpioDriverEntry = {
struct HdfDriverEntry g_gpioDriverEntry = {
...
@@ -108,9 +108,9 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
...
@@ -108,9 +108,9 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
priority = 50;
priority = 50;
device_gpio :: device {
device_gpio :: device {
device0 :: deviceNode {
device0 :: deviceNode {
policy = 0; // No service is published.
policy = 0; // No service is published.
priority = 10; // Driver startup priority.
priority = 10; // Driver startup priority.
permission = 0644; // Permission to create device nodes for the driver.
permission = 0644; // Permission to create device nodes for the driver.
moduleName = "hisi_pl061_driver"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
moduleName = "hisi_pl061_driver"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
deviceMatchAttr = "hisilicon_hi35xx_pl061"; // (Mandatory) Private data of the controller. The value must be the same as the controller information in gpio_config.hcs.
deviceMatchAttr = "hisilicon_hi35xx_pl061"; // (Mandatory) Private data of the controller. The value must be the same as the controller information in gpio_config.hcs.
// Add private information about all controllers in this file.
// Add private information about all controllers in this file.
...
@@ -128,12 +128,12 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
...
@@ -128,12 +128,12 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
gpio_config {
gpio_config {
controller_0x120d0000 {
controller_0x120d0000 {
match_attr = "hisilicon_hi35xx_pl061"; // (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs.
match_attr = "hisilicon_hi35xx_pl061"; // (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs.
groupNum = 12; // (Mandatory) GPIO group number.
groupNum = 12; // (Mandatory) GPIO group number.
bitNum = 8; // (Mandatory) Number of GPIO pins in each group.
bitNum = 8; // (Mandatory) Number of GPIO pins in each group.
regBase = 0x120d0000; // (Mandatory) Physical base address.
regBase = 0x120d0000; // (Mandatory) Physical base address.
irqShare = 0; // (Mandatory) Whether to share an interrupt.
irqShare = 0; // (Mandatory) Whether to share an interrupt.
}
}
}
}
}
}
...
@@ -201,13 +201,13 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
...
@@ -201,13 +201,13 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
-**Init** function
-**Init** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
HDF_STATUS<br/>The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
**HDF_STATUS**<br/>The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
**Table 2** HDF_STATUS
**Table 2** HDF_STATUS
...
@@ -220,7 +220,7 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
...
@@ -220,7 +220,7 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
| HDF_SUCCESS | Initialization successful.|
| HDF_SUCCESS | Initialization successful.|
| HDF_FAILURE | Initialization failed.|
| HDF_FAILURE | Initialization failed.|
Function description:
**Function description**:
Initializes the custom structure object and **GpioCntlr**, calls the **GpioCntlrAdd** function at the core layer, and (optional) connects to the virtual file system (VFS).
Initializes the custom structure object and **GpioCntlr**, calls the **GpioCntlrAdd** function at the core layer, and (optional) connects to the virtual file system (VFS).
...
@@ -241,11 +241,11 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
...
@@ -241,11 +241,11 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
...
...
ret = Pl061GpioInitCntlrMem(pl061); // Allocate memory.
ret = Pl061GpioInitCntlrMem(pl061); // Allocate memory.
...
...
pl061->cntlr.count = pl061->groupNum x pl061->bitNum;// (Mandatory) Calculate the number of pins.
pl061->cntlr.count = pl061->groupNum * pl061->bitNum;// (Mandatory) Calculate the number of pins.
pl061->cntlr.priv = (void *)device->property; // (Mandatory) Store device attributes.
pl061->cntlr.priv = (void *)device->property; // (Mandatory) Store device attributes.
pl061->cntlr.ops = &g_method; // (Mandatory) Attach the GpioMethod instance.
pl061->cntlr.ops = &g_method; // (Mandatory) Attach the GpioMethod instance.
pl061->cntlr.device = device; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and GpioCntlr.
pl061->cntlr.device = device; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and GpioCntlr.
ret = GpioCntlrAdd(&pl061->cntlr); // (Mandatory) Call this function to fill the structure of the core layer. The driver accesses the platform core layer only after a success signal is returned.
ret = GpioCntlrAdd(&pl061->cntlr); // (Mandatory) Call this function to fill the structure of the core layer. The driver accesses the platform core layer only after a success signal is returned.
...
...
Pl061GpioDebugCntlr(pl061);
Pl061GpioDebugCntlr(pl061);
#ifdef PL061_GPIO_USER_SUPPORT // (Optional) Access the user-level VFS if it is supported.
#ifdef PL061_GPIO_USER_SUPPORT // (Optional) Access the user-level VFS if it is supported.
...
@@ -258,19 +258,22 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
...
@@ -258,19 +258,22 @@ The following uses **gpio_hi35xx.c** as an example to present the information re
```
```
-**Release** function
-**Release** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
Return value:
**Return value**:
No value is returned.
No value is returned.
Function description:
**Function description**:
Releases the memory and deletes the controller. This function assigns values 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 value assignment operations.
Releases the memory and deletes the controller. This function assigns values 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 **Init()** has the corresponding value assignment operations.
@@ -165,12 +165,12 @@ The HDMI module adaptation involves the following steps:
...
@@ -165,12 +165,12 @@ The HDMI module adaptation involves the following steps:
platform :: host {
platform :: host {
device_hdmi :: device {
device_hdmi :: device {
device0 :: deviceNode {
device0 :: deviceNode {
policy = 2; // Publish services.
policy = 2; // Publish services.
priority = 20; // Driver startup priority.
priority = 20; // Driver startup priority.
permission = 0644; // Permission to create device nodes for the driver.
permission = 0644; // Permission to create device nodes for the driver.
serviceName = "HDF_PLATFORM_HDMI_0"; // (Mandatory) Unique name of the service published by the driver.
serviceName = "HDF_PLATFORM_HDMI_0"; // (Mandatory) Unique name of the service published by the driver.
moduleName = "hdmi_driver"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
moduleName = "hdmi_driver"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
deviceMatchAttr = "adapter_hdmi_driver"; // (Mandatory) Controller private data, which must be same as that of the corresponding controller in hdmi_config.hcs.
deviceMatchAttr = "adapter_hdmi_driver"; // (Mandatory) Controller private data, which must be same as that of the corresponding controller in hdmi_config.hcs.
} // The specific controller information is in hdmi_config.hcs.
} // The specific controller information is in hdmi_config.hcs.
}
}
}
}
...
@@ -183,12 +183,12 @@ The HDMI module adaptation involves the following steps:
...
@@ -183,12 +183,12 @@ The HDMI module adaptation involves the following steps:
root {
root {
platform {
platform {
hdmi_config {
hdmi_config {
template hdmi_controller { // Template configuration. In the template, you can configure the common parameters shared by device 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.
match_attr = ""; // (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs.
index = 0; // (Mandatory) HDMI controller number.
index = 0; // (Mandatory) HDMI controller number.
regBasePhy = 0x10100000; // (Mandatory) Physical base address of the register.
regBasePhy = 0x10100000; // (Mandatory) Physical base address of the register.
regSize = 0xd1; // (Mandatory) Register bit width.
regSize = 0xd1; // (Mandatory) Register bit width.
@@ -241,7 +241,7 @@ The HDMI module adaptation involves the following steps:
...
@@ -241,7 +241,7 @@ The HDMI module adaptation involves the following steps:
struct HdmiAdapterHost {
struct HdmiAdapterHost {
struct HdmiCntlr *cntlr; // (Mandatory) Control object at 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.
volatile unsigned char *regBase;// (Mandatory) Register base address.
uint32_t regBasePhy // (Mandatory) Physical base address of the register.
uint32_t regBasePhy; // (Mandatory) Physical base address of the register.
uint32_t regSize; // (Mandatory) Register bit width.
uint32_t regSize; // (Mandatory) Register bit width.
uint32_t irqNum; // (Mandatory) IRQ number.
uint32_t irqNum; // (Mandatory) IRQ number.
};
};
...
@@ -321,7 +321,7 @@ The HDMI module adaptation involves the following steps:
...
@@ -321,7 +321,7 @@ The HDMI module adaptation involves the following steps:
**Return value**:
**Return value**:
HDF_STATUS
**HDF_STATUS**
The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
...
@@ -356,17 +356,17 @@ The HDMI module adaptation involves the following steps:
...
@@ -356,17 +356,17 @@ The HDMI module adaptation involves the following steps:
HDF_LOGE("%s: malloc host failed!", __func__);
HDF_LOGE("%s: malloc host failed!", __func__);
return HDF_ERR_MALLOC_FAIL;
return HDF_ERR_MALLOC_FAIL;
}
}
cntlr->priv = (void *)host; // (Mandatory) Store host to the private data of cntlr.
cntlr->priv = (void *)host; // (Mandatory) Store host to the private data of cntlr.
cntlr->ops = &g_hdmiHostOps; // (Mandatory) Connect to the HdmiCntlrOps instance.
cntlr->ops = &g_hdmiHostOps; // (Mandatory) Connect to the HdmiCntlrOps instance.
cntlr->hdfDevObj = obj; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and HdmiCntlr.
cntlr->hdfDevObj = obj; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and HdmiCntlr.
obj->service = &cntlr->service; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and HdmiCntlr.
obj->service = &cntlr->service; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and HdmiCntlr.
ret = HdmiAdapterCntlrParse(cntlr, obj); // (Mandatory) Initialize cntlr. If the operation fails, execute goto __ERR.
ret = HdmiAdapterCntlrParse(cntlr, obj); // (Mandatory) Initialize cntlr. If the operation fails, execute goto __ERR.
...
...
ret = HdmiAdapterHostParse(host, obj); // (Mandatory) Initialize the attributes of the host object. If the operation fails, execute goto__ERR.
ret = HdmiAdapterHostParse(host, obj); // (Mandatory) Initialize the attributes of the host object. If the operation fails, execute goto__ERR.
...
...
ret = HdmiAdapterHostInit(host, cntlr); // Initialize the custom structure. If the operation fails, execute goto __ERR.
ret = HdmiAdapterHostInit(host, cntlr); // Initialize the custom structure. If the operation fails, execute goto __ERR.
...
...
ret = HdmiCntlrAdd(cntlr); // Call the functions at the core layer. If the operation fails, execute goto__ERR.
ret = HdmiCntlrAdd(cntlr); // Call the functions at the core layer. If the operation fails, execute goto__ERR.
...
...
HDF_LOGD("HdmiAdapterBind: success.");
HDF_LOGD("HdmiAdapterBind: success.");
return HDF_SUCCESS;
return HDF_SUCCESS;
...
@@ -385,7 +385,7 @@ The HDMI module adaptation involves the following steps:
...
@@ -385,7 +385,7 @@ The HDMI module adaptation involves the following steps:
**Return value**:
**Return value**:
HDF_STATUS
**HDF_STATUS**
**Function description**:
**Function description**:
...
@@ -412,16 +412,16 @@ The HDMI module adaptation involves the following steps:
...
@@ -412,16 +412,16 @@ The HDMI module adaptation involves the following steps:
Releases the memory and deletes the controller. This function assigns values to the **Release** callback in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
Releases the memory and deletes the controller. This function assigns values to the **Release** callback in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
> All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
cntlr = (struct MmcCntlr *)obj->service;// Forcibly convert HdfDeviceObject to HdmiCntlr by using service. For details about the value assignment, see the Bind function.
cntlr = (struct HdmiCntlr *)obj->service;// Forcibly convert HdfDeviceObject to HdmiCntlr by using service. For details about the value assignment, see the Bind function.
...
...
HimciDeleteHost((struct HimciAdapterHost *)cntlr->priv);// Customized memory release function. A forced conversion from HdmiCntlr to HimciAdapterHost is involved in the process.
HimciDeleteHost((struct HimciAdapterHost *)cntlr->priv);// Customized memory release function. A forced conversion from HdmiCntlr to HimciAdapterHost is involved in the process.
> All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
The Inter-Integrated Circuit (I2C) bus is a simple and bidirectional two-wire synchronous serial bus developed by Philips. In the Hardware Driver Foundation (HDF), the I2C module uses the unified service mode for API adaptation. In this mode, a device service is used as the I2C 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 I2C module 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.
The Inter-Integrated Circuit (I2C) bus is a simple and bidirectional two-wire synchronous serial bus developed by Philips. In the Hardware Driver Foundation (HDF), the I2C module uses the unified service mode for API adaptation. In this mode, a device service is used as the I2C 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 I2C module 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.
**Figure 1** Unified service mode
**Figure 1** Unified service mode
![image](figures/unified-service-mode.png"I2C Unified Service Mode")
![image](figures/unified-service-mode.png"I2C Unified Service Mode")
...
@@ -59,42 +59,46 @@ The I2C module adaptation involves the following steps:
...
@@ -59,42 +59,46 @@ The I2C module adaptation involves the following steps:
The following uses **i2c_hi35xx.c** as an example to present the information required for implementing device functions.
The following uses **i2c_hi35xx.c** as an example to present the information required for implementing device functions.
1. Instantiate the driver entry.<br/>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 is 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 is 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.
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.
I2C driver entry example:
I2C driver entry example:
An I2C controller may be connected with multiple devices. You need to create a manager object in the HDF and publish a manager service to handle external access requests in a unified manner. Before a device is used, the manager service must be obtained first. Then, the manager service locates the target device based on the specified parameters.
An I2C controller may be connected with multiple devices. You need to create a manager object in the HDF and publish a manager service to handle external access requests in a unified manner. Before a device is used, the manager service must be obtained first. Then, the manager service locates the target device based on the specified parameters.
The driver of the I2C manager is implemented by the core layer. Vendors do not need to care about the implementation of this part. However, the **Init** function must call the **I2cCntlrAdd** function of the core layer to implement corresponding features.
The driver of the I2C manager is implemented by the core layer. Vendors do not need to care about the implementation of this part. However, the **Init** function must call the **I2cCntlrAdd** function of the core layer to implement corresponding features.
```
```
struct HdfDriverEntry g_i2cDriverEntry = {
struct HdfDriverEntry g_i2cDriverEntry = {
.moduleVersion = 1,
.moduleVersion = 1,
.Init = Hi35xxI2cInit,
.Init = Hi35xxI2cInit,
.Release = Hi35xxI2cRelease,
.Release = Hi35xxI2cRelease,
.moduleName = "hi35xx_i2c_driver",// (Mandatory) The value must be the same as that in the config.hcs file.
.moduleName = "hi35xx_i2c_driver", // (Mandatory) The value must be the same as that in the config.hcs file.
};
};
HDF_INIT(g_i2cDriverEntry); // Call HDF_INIT to register the driver entry with the HDF.
HDF_INIT(g_i2cDriverEntry); // Call HDF_INIT to register the driver entry with the HDF.
// Driver entry of the i2c_core.c manager service at the core layer
// Driver entry of the i2c_core.c manager service at the core layer
struct HdfDriverEntry g_i2cManagerEntry = {
struct HdfDriverEntry g_i2cManagerEntry = {
.moduleVersion = 1,
.moduleVersion = 1,
.Bind = I2cManagerBind,
.Bind = I2cManagerBind,
.Init = I2cManagerInit,
.Init = I2cManagerInit,
.Release = I2cManagerRelease,
.Release = I2cManagerRelease,
.moduleName = "HDF_PLATFORM_I2C_MANAGER",// This parameter corresponds to device0 in the device_info file.
.moduleName = "HDF_PLATFORM_I2C_MANAGER", // This parameter corresponds to device0 in the device_info file.
};
};
HDF_INIT(g_i2cManagerEntry);
HDF_INIT(g_i2cManagerEntry);
```
```
2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **i2c_config.hcs** file.
2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **i2c_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 value ranges of the **I2cCntlr** members at the core layer.
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 value ranges of the **I2cCntlr** members at the core layer.
In the unified service mode, the first device node in the **device_info** file must be the I2C manager. The table below lists the settings of its parameters.
In the unified service mode, the first device node in the **device_info** file must be the I2C manager. The table below lists the settings of its parameters.
**Table 2** Settings of the I2C manager
**Table 2** Settings of the I2C manager
| Parameter| Value|
| Parameter| Value|
...
@@ -102,12 +106,12 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
...
@@ -102,12 +106,12 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
| moduleName | **HDF_PLATFORM_I2C_MANAGER**|
| moduleName | **HDF_PLATFORM_I2C_MANAGER**|
| serviceName | **HDF_PLATFORM_I2C_MANAGER**|
| serviceName | **HDF_PLATFORM_I2C_MANAGER**|
| policy | **1** or **2**, depending on whether the service is published to the user mode.|
| policy | **1** or **2**, depending on whether the service is published to the user mode.|
| deviceMatchAttr | This parameter is reserved.|
| deviceMatchAttr | Reserved|
Configure I2C controller information from the second node. This node specifies a type of I2C controllers rather than a specific I2C controller. The controllers are distinguishes by **busID** and **reg_pbase**, which can be seen in the **i2c_config** file.
Configure I2C controller information from the second node. This node specifies a type of I2C controllers rather than a specific I2C controller. The controllers are distinguishes by **busID** and **reg_pbase**, which can be seen in the **i2c_config** file.
-**device_info.hcs** configuration example
-**device_info.hcs** configuration example
```
```
root {
root {
...
@@ -123,21 +127,21 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
...
@@ -123,21 +127,21 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
deviceMatchAttr = "hdf_platform_i2c_manager";
deviceMatchAttr = "hdf_platform_i2c_manager";
}
}
device1 :: deviceNode {
device1 :: deviceNode {
policy = 0; // The value 0 indicates that no service needs to be published.
policy = 0; // The value 0 indicates that no service needs to be published.
priority = 55; // Driver startup priority.
priority = 55; // Driver startup priority.
permission = 0644; // Permission for the driver to create a device node.
permission = 0644; // Permission for the driver to create a device node.
moduleName = "hi35xx_i2c_driver"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
moduleName = "hi35xx_i2c_driver"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
serviceName = "HI35XX_I2C_DRIVER"; // (Mandatory) Unique name of the service published by the driver.
serviceName = "HI35XX_I2C_DRIVER"; // (Mandatory) Unique name of the service published by the driver.
deviceMatchAttr = "hisilicon_hi35xx_i2c"; // (Mandatory) Used to configure the private data of the controller. The value must be the same as the controller information in i2c_config.hcs.
deviceMatchAttr = "hisilicon_hi35xx_i2c"; // (Mandatory) Used to configure the private data of the controller. The value must be the same as the controller information in i2c_config.hcs.
//The specific controller information is stored in i2c_config.hcs.
//The specific controller information is stored in i2c_config.hcs.
}
}
}
}
}
}
}
}
```
```
-**i2c_config.hcs** configuration example
-**i2c_config.hcs** configuration example
```
```
root {
root {
...
@@ -182,7 +186,7 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
...
@@ -182,7 +186,7 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
uint32_t clk; // (Optional) Customized.
uint32_t clk; // (Optional) Customized.
uint32_t freq; // (Optional) Customized.
uint32_t freq; // (Optional) Customized.
uint32_t irq; // (Optional) Customized.
uint32_t irq; // (Optional) Customized.
uint32_t regBasePhy // (Mandatory) Physical base address of the register.
uint32_t regBasePhy; // (Mandatory) Physical base address of the register.
};
};
// I2cCntlr is a controller structure at the core layer. The Init function assigns values to the members of I2cCntlr.
// I2cCntlr is a controller structure at the core layer. The Init function assigns values to the members of I2cCntlr.
...
@@ -205,19 +209,19 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
...
@@ -205,19 +209,19 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
};
};
static const struct I2cLockMethod g_lockOps = {
static const struct I2cLockMethod g_lockOps = {
.lock = Hi35xxI2cLock, // Lock function
.lock = Hi35xxI2cLock, // Lock function
.unlock = Hi35xxI2cUnlock,// Unlock function
.unlock = Hi35xxI2cUnlock,// Unlock function
};
};
```
```
-**Init** function
-**Init** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
HDF_STATUS<br/>The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
**HDF_STATUS**<br/>The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
**Table 3** HDF_STATUS
**Table 3** HDF_STATUS
...
@@ -230,7 +234,7 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
...
@@ -230,7 +234,7 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
| HDF_SUCCESS | Transmission successful.|
| HDF_SUCCESS | Transmission successful.|
| HDF_FAILURE | Transmission failed.|
| HDF_FAILURE | Transmission failed.|
Function description:
**Function description**:
Initializes the custom structure object and **I2cCntlr**, calls the **I2cCntlrAdd** function at the core layer, and mounts the VFS (optional).
Initializes the custom structure object and **I2cCntlr**, calls the **I2cCntlrAdd** function at the core layer, and mounts the VFS (optional).
...
@@ -255,20 +259,20 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
...
@@ -255,20 +259,20 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
hi35xx->cntlr.busId = hi35xx->bus; // (Mandatory) Initialize busId in I2cCntlr.
hi35xx->cntlr.busId = hi35xx->bus; // (Mandatory) Initialize busId in I2cCntlr.
hi35xx->cntlr.ops = &g_method; // (Mandatory) Hook the I2cMethod instance.
hi35xx->cntlr.ops = &g_method; // (Mandatory) Hook the I2cMethod instance.
hi35xx->cntlr.lockOps = &g_lockOps; // (Mandatory) Hook the I2cLockMethod instance.
hi35xx->cntlr.lockOps = &g_lockOps; // (Mandatory) Hook the I2cLockMethod instance.
(void)OsalSpinInit(&hi35xx->spin); // (Mandatory) Initialize the lock.
(void)OsalSpinInit(&hi35xx->spin); // (Mandatory) Initialize the lock.
ret = I2cCntlrAdd(&hi35xx->cntlr); // (Mandatory) Call this function to set the structure of the core layer. The driver accesses the platform core layer only after a success signal is returned.
ret = I2cCntlrAdd(&hi35xx->cntlr); // (Mandatory) Call this function to set the structure of the core layer. The driver accesses the platform core layer only after a success signal is returned.
...
...
#ifdef USER_VFS_SUPPORT
#ifdef USER_VFS_SUPPORT
(void)I2cAddVfsById(hi35xx->cntlr.busId);// (Optional) Mount the user-level VFS if required.
(void)I2cAddVfsById(hi35xx->cntlr.busId);// (Optional) Mount the user-level VFS if required.
#endif
#endif
return HDF_SUCCESS;
return HDF_SUCCESS;
__ERR__: // If the operation fails, execute the initialization functions reversely.
__ERR__: // If the operation fails, execute the initialization functions reversely.
if (hi35xx != NULL) {
if (hi35xx != NULL) {
if (hi35xx->regBase != NULL) {
if (hi35xx->regBase != NULL) {
OsalIoUnmap((void *)hi35xx->regBase);
OsalIoUnmap((void *)hi35xx->regBase);
...
@@ -282,15 +286,15 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
...
@@ -282,15 +286,15 @@ The following uses **i2c_hi35xx.c** as an example to present the information req
```
```
-**Release** function
-**Release** function
Input parameter:
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Return value:
**Return value**:
No value is returned.
No value is returned.
Function description:
**Function description**:
Releases the memory and deletes the controller. This function assigns values 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.
Releases the memory and deletes the controller. This function assigns values 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.