提交 99374bba 编写于 作者: A annie_wangli

update docs

Signed-off-by: Nannie_wangli <annie.wangli@huawei.com>
上级 9507cd00
......@@ -266,7 +266,7 @@ A constructor used to create an **authenticator** object.
getVersion() : number
Obtains the authenticator version.
Obtains the authentication executor version.
**Required permissions**: ohos.permission.ACCESS_BIOMETRIC
......@@ -276,7 +276,7 @@ Obtains the authenticator version.
| Type | Description |
| ------ | ---------------------- |
| number | Authenticator version obtained.|
| number | Authentication executor version obtained.|
**Example**
......@@ -429,7 +429,7 @@ Obtains the authentication result.
| Name | Type | Mandatory| Description |
| --------- | -------------------------- | ---- | ------------------------------------------------------------ |
| result | number | Yes | Authentication result obtained. For details, see [ResultCode](#resultcode8). |
| extraInfo | [AuthResult](#authresult8) | Yes | Extended information, which varies depending on the authentication result.<br>If the authentication is successful, the user authentication token will be returned in **extraInfo**.<br>If the authentication fails, the remaining number of authentication times will be returned in **extraInfo**.<br>If the authenticator is locked, the freeze time will be returned in **extraInfo**.|
| extraInfo | [AuthResult](#authresult8) | Yes | Extended information, which varies depending on the authentication result.<br>If the authentication is successful, the user authentication token will be returned in **extraInfo**.<br>If the authentication fails, the remaining number of authentication times will be returned in **extraInfo**.<br>If the authentication executor is locked, the freeze time will be returned in **extraInfo**.|
**Example**
......@@ -477,8 +477,8 @@ Obtains the tip code information during authentication. This function is optiona
| Name | Type | Mandatory| Description |
| --------- | ------ | ---- | ------------------------------ |
| module | number | Yes | Type of the authenticator. |
| acquire | number | Yes | Interaction information of the authenticator during the authentication process.|
| module | number | Yes | Type of the authentication executor. |
| acquire | number | Yes | Interaction information of the authentication executor during the authentication process.|
| extraInfo | any | Yes | Reserved field. |
**Example**
......@@ -543,7 +543,7 @@ Enumerates the operation results.
| TRUST_LEVEL_NOT_SUPPORT | 6 | The authentication trust level is not supported. |
| BUSY | 7 | Indicates the busy state. |
| INVALID_PARAMETERS | 8 | Invalid parameters are detected. |
| LOCKED | 9 | The authenticator is locked. |
| LOCKED | 9 | The authentication executor is locked. |
| NOT_ENROLLED | 10 | The user has not entered the authentication information.|
......
......@@ -34,6 +34,7 @@
- [I3C](driver-platform-i3c-des.md)
- [MIPI CSI](driver-platform-mipicsi-des.md)
- [MIPI DSI](driver-platform-mipidsi-des.md)
- [Pin](driver-platform-pin-des.md)
- [PWM](driver-platform-pwm-des.md)
- [Regulator](driver-platform-regulator-des.md)
- [RTC](driver-platform-rtc-des.md)
......
# Pin
## Overview<a name="section1"></a>
### Pin<a name="section2"></a>
- The pin, also called pin controller, manages pin resources of system on a chip (SoC) vendors and provides the pin multiplexing function.
- The pin module defines a set of common methods for managing pins, including:
- Obtaining or releasing the pin description handle: The kernel compares the pin name passed in with the pin names of each controller in the linked list. If a match is found, a pin description handle is obtained. After the operation on the pin is complete, the pin description handle will be released.
- Setting or obtaining the pull type of a pin: The pull type can be pull-up, pull-down, or floating.
- Setting or obtaining the pull strength of a pin: You can set the pull strength as required.
- Setting or obtaining the functions of a pin to implement pin multiplexing
### Basic Concepts<a name="section3"></a>
Pin, as a software concept, provides APIs for uniformly managing the pins from different SoC vendors, providing the pin multiplexing function, and configuring the electrical features of pins.
- SoC
An SOC is a chip that integrates microprocessors, analog IP cores, digital IP cores, and memory for specific purposes.
- Pin multiplexing
When the number of pins of a chip cannot handle the increasing connection requests, you can set the software registers to make the pins to work in different states.
### Working Principles<a name="section4"></a>
In the HDF, the pin module does not support the user mode and therefore does not need to publish services. It uses the service-free mode in interface adaptation. The service-free mode applies to the devices that do not provide user-mode APIs or the OS that does not distinguish the user mode and the kernel mode. The **DevHandle**, a void pointer, directly points to the kernel mode address of the device object.
The pin module is divided into the following layers:
- Interface layer: provides APIs for obtaining a pin, setting or obtaining the pull type, pull strength, and functions of a pin, and releasing a pin.
- Core layer: provides the capabilities of matching pin resources and adding, removing, and managing pin controllers. The core layer interacts with the adaptation layer by using hooks.
- Adaptation layer: instantiates hooks to implement specific functions.
**Figure 1** Service-free mode<a name="fig14423182615525"></a>
![](figures/service-free-mode.png "pin service-free mode")
### Constraints<a name="section5"></a>
Currently, the pin module supports only the kernels (LiteOS) of mini and small systems.
## Usage Guidelines<a name="section6"></a>
### When to Use<a name="7"></a>
The pin module is a software concept and is used to manage pin resources. You can set the functions, pull type, and pull strength of pins to implement pin multiplexing.
### Available APIs<a name="section8"></a>
The table below describes the APIs of the pin module. For more details, see API Reference.
**Table 1** Pin driver APIs
<a name="table1"></a>
| **API** | **Description** |
| ------------------------------------------------------------ | ---------------- |
| DevHandle PinGet(const char *pinName); | Obtains the pin description handle.|
| void PinPut(DevHandle handle); | Releases the pin description handle.|
| int32_t PinSetPull(DevHandle handle, enum PinPullType pullType); | Sets the pull type of a pin.|
| int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType); | Obtains the pull type of a pin.|
| int32_t PinSetStrength(DevHandle handle, uint32_t strength); | Sets the pull strength of a pin.|
| int32_t PinGetStrength(DevHandle handle, uint32_t *strength); | Obtains the pull strength of a pin.|
| int32_t PinSetFunc(DevHandle handle, const char *funcName); | Sets the pin function. |
| int32_t PinGetFunc(DevHandle handle, const char **funcName); | Obtains the pin functions. |
>![](../public_sys-resources/icon-note.gif) **NOTE**<br/>
>All APIs described in this document can be called only in the kernel space.
### How to Develop<a name="section9"></a>
The figure below shows the process.
**Figure 2** Process of using the pin module<a name="fig2"></a>
![](figures/process-of-using-pin.png "Process of using the pin module")
#### Obtaining the Pin Description Handle
Before performing an operation on a pin, call **PinGet** to obtain the pin description handle. This API returns the pin description handle that matches the input pin name.
```
DevHandle PinGet(const char *pinName);
```
**Table 2** Description of PinGet
<a name="table2"></a>
| Parameter | Description |
| ---------- | ----------------------- |
| pinName | Pointer to the pin name. |
| **Return Value**| **Description** |
| NULL | Failed to obtain the pin description handle.|
| handle | Pin description handle obtained. |
Example: Obtain the handle of P18.
```
DevHandle handle = NULL; /* Pin description handle */
char pinName = "P18"; /* Pin name. */
handle = PinGet(pinName);
if (handle == NULL) {
HDF_LOGE("PinGet: get handle failed!\n");
return;
}
```
#### Setting the Pull Type of a Pin
Call **PinSetPull** to set the pull type of a pin.
```
int32_t PinSetPull(DevHandle handle, enum PinPullType pullType);
```
**Table 3** Description of PinSetPull
<a name="table3"></a>
| Parameter | Description |
| ---------- | ----------------------- |
| handle | Pin description handle. |
| pullType | Pull type to set. |
| **Return Value**| **Description** |
| 0 | The operation is successful.|
| Negative value | The operation fails.|
Example: Set the pull type to pull-up.
```
int32_t ret;
enum PinPullType pullTypeNum;
/* Set the pull type of a pin. */
pullTypeNum = 1;
ret = PinSetPull(handle, pullTypeNum);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinSetPull: failed, ret %d\n", ret);
return ret;
}
```
#### Obtaining the Pull Type of a Pin
Call **PinGetPull** to obtain the pull type of a pin.
```
int32_t PinGetPull(DevHandle handle, enum PinPullType *pullType);
```
**Table 4** Description of PinGetPull
<a name="table4"></a>
| Parameter | Description |
| ---------- | ------------------------- |
| handle | Pin description handle. |
| pullType | Pointer to the pull type obtained.|
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
Example: Obtain the pull type of a pin.
```
int32_t ret;
enum PinPullType pullTypeNum;
/* Obtain the pull type of a pin. */
ret = PinGetPull(handle, &pullTypeNum);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinGetPull: failed, ret %d\n", ret);
return ret;
}
```
#### Setting the Pull Strength of a Pin
Call **PinSetStrength** to set the pull type of a pin.
```
int32_t PinSetStrength(DevHandle handle, uint32_t strength);
```
**Table 5** Description of PinSetStrength
<a name="table5"></a>
| Parameter | Description |
| ---------- | ----------------------- |
| handle | Pin description handle. |
| strength | Pull strength to set. |
| **Return Value**| **Description** |
| 0 | The operation is successful.|
| Negative value | The operation fails.|
Example: Set the pull strength of the pin to 2.
```
int32_t ret;
uint32_t strengthNum;
/* Set the pull strength of the pin. */
strengthNum = 2;
ret = PinSetStrength(handle, strengthNum);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinSetStrength: failed, ret %d\n", ret);
return ret;
}
```
#### Obtaining the Pull Strength of a Pin
Call **PinGetStrength** to obtain the pull strength set.
```
int32_t PinGetStrength(DevHandle handle, uint32_t *strength);
```
**Table 6** Description of PinGetStrength
<a name="table6"></a>
| Parameter | Description |
| ---------- | ------------------------- |
| handle | Pin description handle. |
| strength | Pointer to the pull strength obtained.|
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
Example: Obtain the pull strength of a pin.
```
int32_t ret;
uint32_t strengthNum;
/* Obtain the pull strength of the pin. */
ret = PinGetStrength(handle, &strengthNum);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinGetStrength: failed, ret %d\n", ret);
return ret;
}
```
#### Setting the Pin Function
The pin function refers to the pin multiplexing function. The function of each pin is different. For details about the pin functions, see [pin_config.hcs](https://gitee.com/openharmony/device_soc_hisilicon/blob/master/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs).
Call **PinSetFunc** to set the pin function.
```
int32_t PinSetFunc(DevHandle handle, const char *funcName);
```
**Table 7** Description of PinSetFunc
<a name="table7"></a>
| Parameter | Description |
| ---------- | ------------------- |
| handle | Pin description handle. |
| funcName | Pointer to the pin function to set. |
| **Return Value**| **Description** |
| 0 | The operation is successful.|
| Negative value | The operation fails.|
Example: Set the pin function to LSADC_CH1 (ADC channel 1).
```
int32_t ret;
char funcName = "LSADC_CH1";
/* Sets the pin function. */
ret = PinSetFunc(handle, funcName);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinSetFunc: failed, ret %d\n", ret);
return ret;
}
```
#### Obtaining the Pin Function
Call **PinGetFunc** to obtain the pin function set.
```
int32_t PinGetFunc(DevHandle handle, const char **funcName);
```
**Table 8** Description of PinGetFunc
<a name="table8"></a>
| Parameter | Description |
| ---------- | --------------------- |
| handle | Pin description handle. |
| funcName | Pointer to the function name obtained.|
| **Return Value**| **Description** |
| 0 | The operation is successful. |
| Negative value | The operation fails. |
Example: Obtain the pin function.
```
int32_t ret;
char *funcName;
/* Obtain the pin function. */
ret = PinGetFunc(handle,&funcName);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinGetFunc: failed, ret %d\n", ret);
return ret;
}
```
#### Releasing a Pin Description Handle
After the operations on a pin are complete, call **PinPut** to release the pin description handle.
```
void PinPut(DevHandle handle);
```
**Table 9** Description of PinPut
<a name="table9"></a>
| Parameter | Description |
| ---------- | -------------- |
| handle | Pin description handle. |
| **Return Value**| **Description**|
| NA | No value is returned. |
Example: Release a pin description handle.
```
PinPut(handle);
```
## Development Example<a name="section10"></a>
The procedure is as follows:
1. Pass in the pin name to obtain the pin description handle.
2. Set the pull type of the pin. If the operation fails, release the pin description handle.
3. Obtain the pull type of the pin. If the operation fails, release the pin description handle.
4. Set the pull strength of the pin. If the operation fails, release the pin description handle.
5. Obtain the pin pull strength. If the operation fails, release the pin description handle.
5. Set the pin function. If the operation fails, release the pin description handle.
6. Obtain the pin function. If the operation fails, release the pin description handle.
7. Release the pin description handle if no operation needs to be performed on the pin.
```
#include "hdf_log.h" /* Header file for log APIs */
#include "pin_if.h" /* Header file for standard pin APIs */
int32_t PinTestSample(void)
{
int32_t ret;
uint32_t strengthNum;
enum PinPullType pullTypeNum;
char pinName;
char *funName;
DevHandle handle = NULL;
/* Pin name. Set it to the actual pin name. */
pinName = "P18";
/* Obtain the pin description handle. */
handle = PinGet(pinName);
if (handle == NULL) {
HDF_LOGE("PinGet: failed!\n");
return;
}
/* Set the pull type to pull-up for the pin. */
pullTypeNum = 1;
ret = PinSetPull(handle, pullTypeNum);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinSetPull: failed, ret %d\n", ret);
goto ERR;
}
/* Obtain the pull type of the pin. */
ret = PinGetPull(handle, &pullTypeNum);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinGetPull: failed, ret %d\n", ret);
goto ERR;
}
/* Set the pull strength of the pin to 2. */
strengthNum = 2;
ret = PinSetStrength(handle, strengthNum);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinSetStrength: failed, ret %d\n", ret);
goto ERR;
}
/* Obtain the pull strength of the pin. */
ret = PinGetStrength(handle, &strengthNum);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinGetStrength: failed, ret %d\n", ret);
goto ERR;
}
/* Set the pin function to LSADC_CH1. */
funName = "LSADC_CH1";
ret = PinSetFunc(handle, funName);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinSetFunc: failed, ret %d\n", ret);
goto ERR;
}
/* Obtain the pin function. */
ret = PinGetFunc(handle, &funcName);
if (ret != HDF_SUCCESS) {
HDF_LOGE("PinGetFunc: failed, ret %d\n", ret);
goto ERR;
}
ERR:
/* Release the pin description handle. */
PinPut(handle);
return ret;
}
# Pin<a name="title_PinDevelop"></a>
# Pin
## Overview<a name="section1_PinDevelop"></a>
## Overview
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.
### Pin
The pin, also called pin controller, manages pin resources of system on a chip (SoC) vendors and provides the pin multiplexing function.
Figure 1 Service-free mode
![image1](figures/service-free-mode.png "service-free-mode")
### Basic Concepts
## Available APIs<a name="section2_PinDevelop"></a>
Pin, as a software concept, provides APIs for uniformly managing the pins from different SoC vendors, providing the pin multiplexing function, and configuring the electrical features of pins.
**PinCntlrMethod**:
- SoC
An SOC is a chip that integrates microprocessors, analog IP cores, digital IP cores, and memory for specific purposes.
- Pin multiplexing
When the number of pins of a chip cannot handle the increasing connection requests, you can set the software registers to make the pins to work in different states.
### Working Principles
In the HDF, the pin module does not support the user mode and therefore does not need to publish services. It uses the service-free mode in interface adaptation. The service-free mode applies to the devices that do not provide user-mode APIs or the OS that does not distinguish the user mode and the kernel mode. The **DevHandle**, a void pointer, directly points to the kernel mode address of the device object.
The pin module is divided into the following layers:
- Interface layer: provides APIs for obtaining a pin, setting or obtaining the pull type, pull strength, and functions of a pin, and releasing a pin.
- Core layer: provides the capabilities of matching pin resources and adding, removing, and managing pin controllers. The core layer interacts with the adaptation layer by using hooks. Adaptation layer: instantiates hooks to implement specific functions.
**Figure 1** Service-free mode
![](figures/service-free-mode.png)
### Constraints
Currently, the pin module supports only the kernels (LiteOS) of mini and small systems.
## Development Guidelines
### When to Use
The pin module is used to manage pin resources. When the devices from SoC vendors interconnect with the HDF, the pin driver needs to be adapted.
### Available APIs
The **PinCntlrMethod** APIs are used to call the functions of the pin driver.
**PinCntlrMethod** definition:
```c
struct PinCntlrMethod {
......@@ -25,290 +57,370 @@ struct PinCntlrMethod {
**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.|
| API | Input Parameter | Output 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.| **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.| **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 function.| -| HDF_STATUS| Sets the pin function.|
| GetPinFunc | **cntlr**: structure pointer to the pin controller at the core layer.<br>**index**: pin index, which is a uint32_t variable.| **funcName**: char double pointer to the pin function.| HDF_STATUS| Obtains the pin function.|
### How to Develop
## How to Develop<a name="section3_PinDevelop"></a>
The pin module adaptation procedure is as follows:
The pin module adaptation involves the following steps:
- Instantiate the driver entry.
- Configure attribute files.
- Instantiate the core layer APIs.
- Debug the driver.
1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure.
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**.
- Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files.
Generally, the HDF calls the **Init()** function to load the driver. If **Init()** fails to be called, the HDF calls **Release()** to release driver resources and exit.
```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.
};
HDF_INIT(g_hi35xxPinDriverEntry);// Call HDF_INIT to register the driver entry with the HDF.
```
- Add the **deviceNode** information to the **device_info.hcs** file.
- (Optional) Add the **pin_config.hcs** file.
2. Configure attribute files.
- Add the device node description to the **vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs** file.
```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";
}
......
}
}
}
}
```
- Add the **pin_config.hcs** file.
Configure the device attributes in the **device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs** file. The parameters are set as follows:
```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) Name of the pin.
init = 0; // (Mandatory) Default value of the register.
F0 = ""; // (Mandatory) Function 0.
F1 = ""; // Function 1.
F2 = ""; // Function 2.
F3 = ""; // Function 3.
F4 = ""; // Function 4.
F5 = ""; // Function 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";
}
...... // Correspond to the pins of the pin controller. Add pins according to actual situation.
}
...// Each pin controller corresponds to a controller node. If there are multiple pin controllers, add the corresponding controller nodes one by one.
}
}
}
```
3. Instantiate the pin controller object.
- Initialize the **PinCntlr** object.
- Instantiate **PinCntlrMethod** in the **PinCntlr** object.
>![](../public_sys-resources/icon-note.gif) **NOTE**
Call **Hi35xxPinCntlrInit** to initialize the **PinCntlr** members.
```c
struct Hi35xxPinDesc {
// Pin name.
const char *pinName;
// Initial value.
uint32_t init;
// Index of the pin.
uint32_t index;
// Pull type of the pin.
int32_t pullType;
// Pull strength of the pin.
int32_t strength;
// Array of pin function names.
const char *func[HI35XX_PIN_FUNC_MAX];
};
>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.
struct Hi35xxPinCntlr {
// Pin controller.
struct PinCntlr cntlr;
// Pointer to the pin description structure.
struct Hi35xxPinDesc *desc;
// Register mapping address.
volatile unsigned char *regBase;
// ID of the pin controller.
uint16_t number;
// Start address of the register physical base addresses.
uint32_t regStartBasePhy;
// Register bit width.
uint32_t regSize;
// Number of pins.
uint32_t pinCount;
};
// 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; // Node in the linked list.
OsalSpinlock spin; // Spinlock.
uint16_t number; // ID of the pin controller.
uint16_t pinCount; // Number of pins.
struct PinDesc *pins;
void *priv; // Private data.
};
// Initialize PinCntlr.
static int32_t Hi35xxPinCntlrInit(struct HdfDeviceObject *device, struct Hi35xxPinCntlr *hi35xx)
{
struct DeviceResourceIface *drsOps = NULL;
int32_t ret;
// Read the pin controller attributes from the .hcs file.
drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) {
HDF_LOGE("%s: invalid drs ops fail!", __func__);
return HDF_FAILURE;
}
ret = drsOps->GetUint16(device->property, "number", &hi35xx->number, 0);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: read number failed", __func__);
return ret;
}
ret = drsOps->GetUint32(device->property, "regStartBasePhy", &hi35xx->regStartBasePhy, 0);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: read regStartBasePhy failed", __func__);
return ret;
}
ret = drsOps->GetUint32(device->property, "regSize", &hi35xx->regSize, 0);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: read regSize failed", __func__);
return ret;
}
ret = drsOps->GetUint32(device->property, "pinCount", &hi35xx->pinCount, 0);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: read pinCount failed", __func__);
return ret;
}
// Assign the values read to the members of the pin controller to initialize the pin controller.
hi35xx->cntlr.pinCount = hi35xx->pinCount;
hi35xx->cntlr.number = hi35xx->number;
hi35xx->regBase = OsalIoRemap(hi35xx->regStartBasePhy, hi35xx->regSize); // Pin controller mapping.
if (hi35xx->regBase == NULL) {
HDF_LOGE("%s: remap Pin base failed", __func__);
return HDF_ERR_IO;
}
hi35xx->desc = (struct Hi35xxPinDesc *)OsalMemCalloc(sizeof(struct Hi35xxPinDesc) * hi35xx->pinCount);
hi35xx->cntlr.pins = (struct PinDesc *)OsalMemCalloc(sizeof(struct PinDesc) * hi35xx->pinCount);
return HDF_SUCCESS;
}
```
## Development Example<a name="section4_PinDevelop"></a>
- Instantiate the callback structure **PinCntlrMethod** in **PinCntlr**. Other members are initialized by using the **Init()** function.
The following uses **pin_hi35xx.c** as an example to present the content to be provided by the vendor to implement device functionalities.
```c
// The members of the PinCntlrMethod structure are all callbacks. Vendors need to implement the corresponding functions according to Table 1.
static struct PinCntlrMethod g_method = {
.SetPinPull = Hi35xxPinSetPull, // Set the pull type.
.GetPinPull = Hi35xxPinGetPull, // Obtains the pull type.
.SetPinStrength = Hi35xxPinSetStrength, // Set the pull strength.
.GetPinStrength = Hi35xxPinGetStrength, // Obtains the pull strength.
.SetPinFunc = Hi35xxPinSetFunc, // Set the pin functions.
.GetPinFunc = Hi35xxPinGetFunc, // Obtain the pin functions.
};
```
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.
- **Init()** function
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.
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
Pin driver entry reference:
Return value:
**HDF\_STATUS** (The following table lists some states. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**.)
| **State** | **Description** |
| ---------------------- | -------------- |
| HDF_ERR_INVALID_OBJECT | Invalid controller object.|
| HDF_ERR_MALLOC_FAIL | Failed to allocate memory. |
| HDF_ERR_INVALID_PARAM | Invalid parameter. |
| HDF_ERR_IO | I/O error. |
| HDF_SUCCESS | Initialization successful. |
| HDF_FAILURE | Initialization failed. |
Function description:
Initializes the custom structure object and **PinCntlr** members, and connects to the pin controller by calling the **PinCntlrAdd()** function.
```c
static int32_t Hi35xxPinReadFunc(struct Hi35xxPinDesc *desc, const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps)
{
int32_t ret;
uint32_t funcNum = 0;
// Read the pin function names of the pin controller child nodes from the .hcs file.
ret = drsOps->GetString(node, "F0", &desc->func[funcNum], "NULL");
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: read F0 failed", __func__);
return ret;
}
```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);
```
funcNum++;
ret = drsOps->GetString(node, "F1", &desc->func[funcNum], "NULL");
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: read F1 failed", __func__);
return ret;
}
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.
funcNum++;
......
return HDF_SUCCESS;
}
static int32_t Hi35xxPinParsePinNode(const struct DeviceResourceNode *node, struct Hi35xxPinCntlr *hi35xx, int32_t index)
{
int32_t ret;
struct DeviceResourceIface *drsOps = NULL;
// Read the pin attributes of the pin controller child nodes from the .hcs file.
drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {
HDF_LOGE("%s: invalid drs ops fail!", __func__);
return HDF_FAILURE;
}
ret = drsOps->GetString(node, "pinName", &hi35xx->desc[index].pinName, "NULL");
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: read pinName failed", __func__);
return ret;
}
......
ret = Hi35xxPinReadFunc(&hi35xx->desc[index], node, drsOps);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:Pin read Func failed", __func__);
return ret;
}
hi35xx->cntlr.pins[index].pinName = hi35xx->desc[index].pinName;
hi35xx->cntlr.pins[index].priv = (void *)node;
......
return HDF_SUCCESS;
}
```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:
...
......
ret = Hi35xxPinCntlrInit(device, hi35xx); // Initialize the pin controller.
......
DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { // Traverses each child node of the pin controller.
ret = Hi35xxPinParsePinNode(childNode, hi35xx, index); // Parsing the child nodes.
......
}
hi35xx->cntlr.method = &g_method; // Instantiate OPS.
hi35xx->cntlr.method = &g_method; // Instantiate method.
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.
...
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: add Pin cntlr: failed", __func__);
ret = HDF_FAILURE;
}
return HDF_SUCCESS;
}
```
- **Release** function
- **Release()** function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
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.
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.
...
int32_t ret;
uint16_t number;
struct PinCntlr *cntlr = NULL;
struct Hi35xxPinCntlr *hi35xx = NULL;
struct DeviceResourceIface *drsOps = NULL;
if (device == NULL || device->property == NULL) {
HDF_LOGE("%s: device or property is null", __func__);
return;
}
// Read the pin controller ID from the .hcs file.
drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {
HDF_LOGE("%s: invalid drs ops", __func__);
return;
}
ret = drsOps->GetUint16(device->property, "number", &number, 0);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: read cntlr number failed", __func__);
return;
}
cntlr = PinCntlrGetByNumber(number); // Obtain the pin controller based on the controller ID.
PinCntlrRemove(cntlr);
hi35xx = (struct Hi35xxPinCntlr *)cntlr;
if (hi35xx != NULL) {
if (hi35xx->regBase != NULL) {
OsalIoUnmap((void *)hi35xx->regBase);
}
OsalMemFree(hi35xx);
}
}
```
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.
......@@ -16,6 +16,8 @@
- **[MIPI DSI](driver-platform-mipidsi-des.md)**
- **[Pin](driver-platform-pin-des.md)**
- **[PWM](driver-platform-pwm-des.md)**
- **[RTC](driver-platform-rtc-des.md)**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册