You need to sign in or sign up before continuing.
未验证 提交 bc99d0e6 编写于 作者: O openharmony_ci 提交者: Gitee

!5181 【翻译完成】#I57QRA

Merge pull request !5181 from Annie_wang/PR3940A
...@@ -28,7 +28,7 @@ struct GpioMethod { ...@@ -28,7 +28,7 @@ struct GpioMethod {
int32_t (*unsetIrq)(struct GpioCntlr *cntlr, uint16_t local); int32_t (*unsetIrq)(struct GpioCntlr *cntlr, uint16_t local);
int32_t (*enableIrq)(struct GpioCntlr *cntlr, uint16_t local); int32_t (*enableIrq)(struct GpioCntlr *cntlr, uint16_t local);
int32_t (*disableIrq)(struct GpioCntlr *cntlr, uint16_t local); int32_t (*disableIrq)(struct GpioCntlr *cntlr, uint16_t local);
} };
``` ```
**Table 1** Description of the callback functions in GpioMethod **Table 1** Description of the callback functions in GpioMethod
...@@ -63,7 +63,7 @@ The GPIO module adaptation involves the following steps: ...@@ -63,7 +63,7 @@ The GPIO module adaptation involves the following steps:
- Initialize **GpioCntlr**. - Initialize **GpioCntlr**.
- Instantiate **GpioMethod** in the **GpioCntlr** object. - Instantiate **GpioMethod** in the **GpioCntlr** object.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/> For details about the callbacks in **GpioMethod**, see [Available APIs](#available-apis). > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/> For details about the functions in **GpioMethod**, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
...@@ -72,7 +72,7 @@ The GPIO module adaptation involves the following steps: ...@@ -72,7 +72,7 @@ The GPIO module adaptation involves the following steps:
## Development Example ## Development Example
The following uses **gpio_hi35xx.c** as an example to present the information to be provided by the vendor for implementing device functions. The following uses **gpio_hi35xx.c** as an example to present the information required for implementing device functions.
1. Instantiate the driver entry. 1. Instantiate the driver entry.
...@@ -143,7 +143,7 @@ The following uses **gpio_hi35xx.c** as an example to present the information to ...@@ -143,7 +143,7 @@ The following uses **gpio_hi35xx.c** as an example to present the information to
3. Initialize the **GpioCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Init** and **Release**) to instantiate **GpioMethod** in **GpioCntlr** (so that the underlying driver functions can be called). 3. Initialize the **GpioCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Init** and **Release**) to instantiate **GpioMethod** in **GpioCntlr** (so that the underlying driver functions can be called).
- Defining a custom structure - Defining a custom structure
To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **gpio_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the GPIO group number and the number of pins, to the **GpioCntlr** object at the core layer. To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **gpio_config.hcs** file to initialize the members in the custom structure and pass important parameters, such as the GPIO group number and the number of pins, to the **GpioCntlr** object at the core layer.
``` ```
......
...@@ -235,7 +235,7 @@ The HDMI module adaptation involves the following steps: ...@@ -235,7 +235,7 @@ The HDMI module adaptation involves the following steps:
> ![](../public_sys-resources/icon-note.gif) **NOTE** > ![](../public_sys-resources/icon-note.gif) **NOTE**
> >
> >
> To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **hdmi_config.hcs** file to initialize the members in the custom structure and passes important parameters, such as the device number and bus number, to the **HdmiCntlr** object at the core layer. > To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **hdmi_config.hcs** file to initialize the members in the custom structure and pass important parameters, such as the device number and bus number, to the **HdmiCntlr** object at the core layer.
```c ```c
struct HdmiAdapterHost { struct HdmiAdapterHost {
......
# MIPI CSI<a name="title_MIPI_CSIDes"></a> # MIPI CSI
## Overview<a name="section1_MIPI_CSIDes"></a>
## Overview
Defined by the Mobile Industry Processor Interface (MIPI) Alliance, the Camera Serial Interface (CSI) is a specification that allows data to be transmitted from the camera to the host processor on mobile platforms. As the second release, the MIPI CSI-2 consists of the application layer, protocol layer, and physical layer. It supports a maximum of four-lane data transmission and a single-lane transmission rate of 1 Gbit/s. Defined by the Mobile Industry Processor Interface (MIPI) Alliance, the Camera Serial Interface (CSI) is a specification that allows data to be transmitted from the camera to the host processor on mobile platforms. As the second release, the MIPI CSI-2 consists of the application layer, protocol layer, and physical layer. It supports a maximum of four-lane data transmission and a single-lane transmission rate of 1 Gbit/s.
The physical layer supports the high speed (HS) and low power (LP) modes. Using low-voltage differential signaling (LVDS), the HS mode delivers 80 Mbit/s to 1 Gbit/s transmission speed but high power consumption. The unidirectional LP mode provides lower power consumption but lower transmission speed (< 10 Mbit/s). The blend of the two modes ensures high-speed transmission of massive data (such as images) and minimized power consumption when less data is transmitted. The physical layer supports the high speed (HS) and low speed (LS) modes. Using low-voltage differential signaling (LVDS), the HS mode delivers 80 Mbit/s to 1 Gbit/s transmission speed but high power consumption. The unidirectional LS mode provides lower power consumption but lower transmission speed (< 10 Mbit/s). The blend of the two modes ensures high-speed transmission of massive data (such as images) and minimized power consumption when less data is transmitted.
The figure below shows a simplified CSI. The D-PHY transmits data by using one pair of source-synchronized differential clocks and one to four pairs of differential data lanes. Data is transmitted in Double Data Rate (DDR) mode, that is, data is transmitted on both the rising and falling edges of the clock. The figure below shows a simplified CSI. The D-PHY transmits data by using one pair of source-synchronized differential clocks and one to four pairs of differential data lanes. Data is transmitted in Double Data Rate (DDR) mode, that is, data is transmitted on both the rising and falling edges of the clock.
**Figure 1** CSI TX and RX interfaces<a name="fig1_MIPI_CSIDes"></a> **Figure 1** CSI TX and RX interfaces
![](figures/CSI_TX-RX_interface.png) ![](figures/CSI_TX-RX_interface.png)
### ComboDevAttr Structure<a name="section1.1_MIPI_CSIDes"></a> ### ComboDevAttr Structure
**Table 1** ComboDevAttr structure **Table 1** ComboDevAttr structure
...@@ -26,7 +27,7 @@ The figure below shows a simplified CSI. The D-PHY transmits data by using one p ...@@ -26,7 +27,7 @@ The figure below shows a simplified CSI. The D-PHY transmits data by using one p
| MIPIAttr | Attributes of the MIPI device. | | MIPIAttr | Attributes of the MIPI device. |
| lvdsAttr | Attributes of the LVDS, sub-LVDS, or HiSPi device. | | lvdsAttr | Attributes of the LVDS, sub-LVDS, or HiSPi device. |
### ExtDataType Structure<a name="section1.2_MIPI_CSIDes"></a> ### ExtDataType Structure
**Table 2** ExtDataType structure **Table 2** ExtDataType structure
...@@ -39,33 +40,34 @@ The figure below shows a simplified CSI. The D-PHY transmits data by using one p ...@@ -39,33 +40,34 @@ The figure below shows a simplified CSI. The D-PHY transmits data by using one p
| extDataBitWidth | Bit depth of an image. | | extDataBitWidth | Bit depth of an image. |
| extDataType | Pointer to the YUV, raw data format, and bit depth.| | extDataType | Pointer to the YUV, raw data format, and bit depth.|
### Available APIs<a name="section1.3_MIPI_CSIDes"></a> ### Available APIs
**Table 3** MIPI CSI APIs **Table 3** MIPI CSI APIs
<a name="table3_MIPI_CSIDes"></a> <a name="table3_MIPI_CSIDes"></a>
| Category| API| | Category| API|
| -------- | -------- | | -------- | -------- |
| Opening or closing the MIPI CSI controller operation handle| **MipiCsiOpen**: opens the MIPI CSI controller operation handle.<br>**MipiCsiClose**: closes the MIPI CSI controller operation handle.| | Opening or closing the MIPI CSI controller operation handle| **MipiCsiOpen**: opens the MIPI CSI controller operation handle.<br>**MipiCsiClose**: closes the MIPI CSI controller operation handle.|
| Setting MIPI CSI parameters| **MipiCsiSetComboDevAttr**: sets parameters of the MIPI, CMOS, or LVDS camera to the controller. The parameters include the working mode, image area, image depth, data rate, and physical channel.<br>**MipiCsiSetExtDataType** (optional): sets the YUV and RAW data formats and bit depths.<br>**MipiCsiSetHsMode**: sets the MIPI RX lane distribution. Set the mode based on the hardware connection.<br>**MipiCsiSetPhyCmvmode**: sets the common-mode voltage (CMV) mode.| | Setting MIPI CSI attributes | **MipiCsiSetComboDevAttr**: sets attributes of the MIPI, CMOS, or LVDS camera to the controller. The attributes include the working mode, image area, image depth, data rate, and physical channel.<br>**MipiCsiSetExtDataType** (optional): sets the YUV and RAW data formats and bit depths.<br>**MipiCsiSetHsMode**: sets the MIPI RX lane distribution. Set the mode based on the hardware connection.<br>**MipiCsiSetPhyCmvmode**: sets the common-mode voltage (CMV) mode. |
| Resetting a sensor or deasserting the reset of a sensor| **MipiCsiResetSensor**: resets a sensor.<br>**MipiCsiUnresetSensor**: deasserts the reset of a sensor.| | Resetting a sensor or deasserting the reset of a sensor| **MipiCsiResetSensor**: resets a sensor.<br>**MipiCsiUnresetSensor**: deasserts the reset of a sensor.|
| Resetting the MIPI RX or deasserting the reset of the MIPI RX| **MipiCsiResetRx**: resets the MIPI&amp;nbsp;RX. The value of **enSnsType** varies depending on the value of **s32WorkingViNum**.<br>**MipiCsiUnresetRx**: deasserts the reset on the MIPI&amp;nbsp;RX.| | Resetting the MIPI RX or deasserting the reset of the MIPI RX| **MipiCsiResetRx**: resets the MIPI&amp;nbsp;RX. The value of **enSnsType** varies depending on the value of **s32WorkingViNum**.<br>**MipiCsiUnresetRx**: deasserts the reset on the MIPI&amp;nbsp;RX.|
| Enabling or disabling the MIPI clock| **MipiCsiEnableClock**: enables the MIPI clock. The **enSnsType** passed by the upper-layer function during electrophoresis determines whether MIPI or LVDS is used.<br>**MipiCsiDisableClock**: disables the MIPI clock.| | Enabling or disabling the MIPI clock| **MipiCsiEnableClock**: enables the MIPI clock. The **enSnsType** passed by the upper-layer function during electrophoresis determines whether MIPI or LVDS is used.<br>**MipiCsiDisableClock**: disables the MIPI clock.|
| Enabling or disabling the MIPI sensor clock| **MipiCsiEnableSensorClock**: enables the MIPI sensor clock.<br>**MipiCsiDisableSensorClock**: disables the MIPI sensor clock.| | Enabling or disabling the MIPI sensor clock| **MipiCsiEnableSensorClock**: enables the MIPI sensor clock.<br>**MipiCsiDisableSensorClock**: disables the MIPI sensor clock.|
## Usage Guidelines<a name="section2_MIPI_CSIDes"></a> ## Usage Guidelines
### How to Use<a name="section2.1_MIPI_CSIDes"></a> ### How to Use
The figure below illustrates how to use the APIs. The figure below illustrates the general development process.
**Figure 2** Using MIPI CSI driver APIs **Figure 2** Using MIPI CSI driver APIs
![](figures/using-MIPI-CSI-process.png) ![](figures/using-MIPI-CSI-process.png)
### Opening the MIPI CSI Controller Operation Handle<a name="section2.2_MIPI_CSIDes"></a> ### Opening a MIPI CSI Controller Operation Handle
Before starting MIPI CSI communication, call **MipiCsiOpen** to open the MIPI CSI device handle. This function returns the MIPI CSI device handle with the specified lane ID. Before starting MIPI CSI communication, call **MipiCsiOpen** to open the MIPI CSI device handle. This function returns the MIPI CSI device handle with the specified lane ID.
...@@ -81,10 +83,10 @@ DevHandle MipiCsiOpen(uint8_t id); ...@@ -81,10 +83,10 @@ DevHandle MipiCsiOpen(uint8_t id);
| ---------- | ----------------------------------------------- | | ---------- | ----------------------------------------------- |
| id | MIPI CSI lane ID. | | id | MIPI CSI lane ID. |
| **Return Value**| **Description** | | **Return Value**| **Description** |
| NULL | The operation fails. | | NULL | The operation failed. |
| Device handle | MIPI CSI device handle with the specified lane ID. The data type is **DevHandle**.| | Device handle | The operation is successful. The MIPI CSI device handle with the specified lane ID is returned. The data type is **DevHandle**. |
For example, open the controller operation handle for MIPI CSI lane 0: For example, open the controller operation handle of MIPI CSI lane 0:
```c ```c
DevHandle mipiCsiHandle = NULL; /* Device handle */ DevHandle mipiCsiHandle = NULL; /* Device handle */
...@@ -98,9 +100,9 @@ if (MipiCsiHandle == NULL) { ...@@ -98,9 +100,9 @@ if (MipiCsiHandle == NULL) {
} }
``` ```
### Setting MIPI CSI Parameters<a name="section2.3_MIPI_CSIDes"></a> ### Setting MIPI CSI Attributes
- Set MIPI CSI parameters. - Set MIPI CSI attributes.
```c ```c
int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr *pAttr); int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr *pAttr);
...@@ -116,7 +118,7 @@ if (MipiCsiHandle == NULL) { ...@@ -116,7 +118,7 @@ if (MipiCsiHandle == NULL) {
| pAttr | Pointer to the MIPI CSI structure.| | pAttr | Pointer to the MIPI CSI structure.|
| **Return Value**| **Description** | | **Return Value**| **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -155,7 +157,7 @@ if (MipiCsiHandle == NULL) { ...@@ -155,7 +157,7 @@ if (MipiCsiHandle == NULL) {
| dataType | Pointer to the YUV, raw data format, and bit depth.| | dataType | Pointer to the YUV, raw data format, and bit depth.|
| **Return Value**| **Description** | | **Return Value**| **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -195,7 +197,7 @@ if (MipiCsiHandle == NULL) { ...@@ -195,7 +197,7 @@ if (MipiCsiHandle == NULL) {
| laneDivideMode | Lane mode. | | laneDivideMode | Lane mode. |
| **Return Value** | **Description**| | **Return Value** | **Description**|
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -228,7 +230,7 @@ if (MipiCsiHandle == NULL) { ...@@ -228,7 +230,7 @@ if (MipiCsiHandle == NULL) {
| devno | Device number. | | devno | Device number. |
| **Return Value**| **Description** | | **Return Value**| **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -247,7 +249,7 @@ if (MipiCsiHandle == NULL) { ...@@ -247,7 +249,7 @@ if (MipiCsiHandle == NULL) {
} }
``` ```
### Resetting a Sensor or Deasserting the Reset of a Sensor<a name="section2.4_MIPI_CSIDes"></a> ### Resetting a Sensor or Deasserting the Reset of a Sensor
- Reset a sensor. - Reset a sensor.
...@@ -262,10 +264,10 @@ if (MipiCsiHandle == NULL) { ...@@ -262,10 +264,10 @@ if (MipiCsiHandle == NULL) {
| Parameter | Description | | Parameter | Description |
| -------------- | ------------------------------------------------ | | -------------- | ------------------------------------------------ |
| handle | Controller operation handle. | | handle | Controller operation handle. |
| snsResetSource | Sensor's reset signal cable number, which is called reset source of the sensor in software.| | snsResetSource | Sensor's reset signal cable number, which is called "sensor reset source" in software. |
| **Return Value** | **Description** | | **Return Value** | **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -294,10 +296,10 @@ if (MipiCsiHandle == NULL) { ...@@ -294,10 +296,10 @@ if (MipiCsiHandle == NULL) {
| Parameter | Description | | Parameter | Description |
| -------------- | ------------------------------------------------ | | -------------- | ------------------------------------------------ |
| handle | Controller operation handle. | | handle | Controller operation handle. |
| snsResetSource | Sensor's reset signal cable number, which is called reset source of the sensor in software.| | snsResetSource | Sensor's reset signal cable number, which is called "sensor reset source" in software. |
| **Return Value** | **Description** | | **Return Value** | **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -313,7 +315,7 @@ if (MipiCsiHandle == NULL) { ...@@ -313,7 +315,7 @@ if (MipiCsiHandle == NULL) {
} }
``` ```
### Resetting the MIPI RX or Deasserting the Reset of the MIPI RX<a name="section2.5_MIPI_CSIDes"></a> ### Resetting the MIPI RX or Deasserting the Reset of the MIPI RX
- Reset the MIPI RX. - Reset the MIPI RX.
...@@ -331,7 +333,7 @@ if (MipiCsiHandle == NULL) { ...@@ -331,7 +333,7 @@ if (MipiCsiHandle == NULL) {
| comboDev | MIPI RX or LVDS channel number.| | comboDev | MIPI RX or LVDS channel number.|
| **Return Value**| **Description** | | **Return Value**| **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -363,7 +365,7 @@ if (MipiCsiHandle == NULL) { ...@@ -363,7 +365,7 @@ if (MipiCsiHandle == NULL) {
| comboDev | MIPI RX or LVDS channel number.| | comboDev | MIPI RX or LVDS channel number.|
| **Return Value**| **Description** | | **Return Value**| **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -379,7 +381,7 @@ if (MipiCsiHandle == NULL) { ...@@ -379,7 +381,7 @@ if (MipiCsiHandle == NULL) {
} }
``` ```
### Enabling or Disabling the MIPI Clock<a name="section2.6_MIPI_CSIDes"></a> ### Enabling or Disabling the MIPI Clock
- Enable the MIPI clock. - Enable the MIPI clock.
...@@ -397,7 +399,7 @@ if (MipiCsiHandle == NULL) { ...@@ -397,7 +399,7 @@ if (MipiCsiHandle == NULL) {
| comboDev | Channel number. | | comboDev | Channel number. |
| **Return Value**| **Description**| | **Return Value**| **Description**|
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -429,7 +431,7 @@ if (MipiCsiHandle == NULL) { ...@@ -429,7 +431,7 @@ if (MipiCsiHandle == NULL) {
| comboDev | Channel number. | | comboDev | Channel number. |
| **Return Value**| **Description**| | **Return Value**| **Description**|
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -445,7 +447,7 @@ if (MipiCsiHandle == NULL) { ...@@ -445,7 +447,7 @@ if (MipiCsiHandle == NULL) {
} }
``` ```
### Enabling or Disabling the MIPI Sensor Clock<a name="section2.7_MIPI_CSIDes"></a> ### Enabling or Disabling the MIPI Sensor Clock
- Enable the MIPI sensor clock. - Enable the MIPI sensor clock.
...@@ -463,7 +465,7 @@ if (MipiCsiHandle == NULL) { ...@@ -463,7 +465,7 @@ if (MipiCsiHandle == NULL) {
| snsClkSource | Sensor's clock signal cable number, which is called clock source of the sensor in software.| | snsClkSource | Sensor's clock signal cable number, which is called clock source of the sensor in software.|
| **Return Value** | **Description** | | **Return Value** | **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -495,7 +497,7 @@ if (MipiCsiHandle == NULL) { ...@@ -495,7 +497,7 @@ if (MipiCsiHandle == NULL) {
| snsClkSource | Sensor's clock signal cable number, which is called clock source of the sensor in software.| | snsClkSource | Sensor's clock signal cable number, which is called clock source of the sensor in software.|
| **Return Value** | **Description** | | **Return Value** | **Description** |
| 0 | The operation is successful. | | 0 | The operation is successful. |
| Negative value | The operation fails. | | Negative value | The operation failed. |
```c ```c
int32_t ret; int32_t ret;
...@@ -511,9 +513,9 @@ if (MipiCsiHandle == NULL) { ...@@ -511,9 +513,9 @@ if (MipiCsiHandle == NULL) {
} }
``` ```
### Closing a MIPI CSI Controller Operation Handle<a name="section2.8_MIPI_CSIDes"></a> ### Closing a MIPI CSI Controller Operation Handle
After the MIPI CSI communication, close the MIPI CSI controller handle by calling the following function: Call **MipiCsiClose()** to close the MIPI CSI controller handle after the MIPI CSI communication is complete.
```c ```c
void MipiCsiClose(DevHandle handle); void MipiCsiClose(DevHandle handle);
...@@ -533,7 +535,7 @@ This function releases the resources requested by **MipiCsiOpen**. ...@@ -533,7 +535,7 @@ This function releases the resources requested by **MipiCsiOpen**.
MipiCsiClose(MIPIHandle); /* Close the operation handle of the MIPI CSI controller. */ MipiCsiClose(MIPIHandle); /* Close the operation handle of the MIPI CSI controller. */
``` ```
## Development Example<a name="section3_MIPI_CSIDes"></a> ## Example
The sample code is as follows: The sample code is as follows:
......
# MIPI CSI<a name="EN-US_TOPIC_0000001198067744"></a> # MIPI CSI
## Overview<a name="section72226945170128"></a> ## Overview
Defined by the Mobile Industry Processor Interface \(MIPI\) Alliance, the Camera Serial Interface \(CSI\) is a specification that allows data to be transmitted from the camera to the host processor on mobile platforms. In the Hardware Driver Foundation \(HDF\), the MIPI CSI module uses the service-free mode for API 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. In the service-free mode, DevHandle \(a void pointer\) directly points to the kernel-mode address of the device object. The Camera Serial Interface (CSI), defined by the Mobile Industry Processor Interface (MIPI) Alliance, allows data to be transmitted from the camera to the host processor on mobile platforms. In the Hardware Driver Foundation (HDF), the MIPI CSI module uses the service-free mode for API adaptation. The service-free mode applies to the devices that do not provide user-mode APIs or the operating system (OS) that does not distinguish the user mode and the kernel mode. In the service-free mode, **DevHandle** (a void pointer) directly points to the kernel-mode address of the device object.
**Figure 1** Service-free mode<a name="fig260692723120"></a> **Figure 1** Service-free mode
![](figures/service-free-mode.png "Service-free mode") ![image1](figures/service-free-mode.png "service-free-mode")
## Available APIs<a name="section735525713405"></a> ## Available APIs
MipiCsiCntlrMethod: **MipiCsiCntlrMethod**:
``` ```c
struct MipiCsiCntlrMethod { struct MipiCsiCntlrMethod {
int32_t (*setComboDevAttr)(struct MipiCsiCntlr *cntlr, ComboDevAttr *pAttr); int32_t (*setComboDevAttr)(struct MipiCsiCntlr *cntlr, ComboDevAttr *pAttr);
int32_t (*setPhyCmvmode)(struct MipiCsiCntlr *cntlr, uint8_t devno, PhyCmvMode cmvMode); int32_t (*setPhyCmvmode)(struct MipiCsiCntlr *cntlr, uint8_t devno, PhyCmvMode cmvMode);
...@@ -28,466 +28,294 @@ struct MipiCsiCntlrMethod { ...@@ -28,466 +28,294 @@ struct MipiCsiCntlrMethod {
int32_t (*unresetSensor)(struct MipiCsiCntlr *cntlr, uint8_t snsResetSource); int32_t (*unresetSensor)(struct MipiCsiCntlr *cntlr, uint8_t snsResetSource);
}; };
``` ```
**Table 1** Description of the callback functions in the MipiCsiCntlrMethod structure
**Table 1** Callbacks for the members in the MipiCsiCntlrMethod structure | Function | Input Parameter | Output Parameter| Return Value | Description |
| ------------------ | ------------------------------------------------------------ | ---- | ------------------ | -------------------------- |
<a name="table1233500677170128"></a> | setComboDevAttr | **cntlr**: structure pointer to the MIPI CSI controller.<br>**pAttr**: structure pointer to the MIPI CSI configuration.| – | HDF_STATUS| Sets MIPI CSI attributes. |
<table><thead align="left"><tr id="row1000451054170128"><th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.1"><p id="entry1111988081170128p0"><a name="entry1111988081170128p0"></a><a name="entry1111988081170128p0"></a>Callback</p> | setPhyCmvmode | **cntlr**: structure pointer to the MIPI CSI controller.<br>**devno**: Device number, which is of the uint8_t type.<br>**cmvMode**: common-mode voltage (CMV) mode to set.| – | HDF_STATUS| Sets the CMV mode. |
</th> | setExtDataType | **cntlr**: structure pointer to the MIPI CSI controller.<br>**dataType**: structure pointer to the data that defines the YUV, original data formats, and bit depth.| – | HDF_STATUS| Sets the YUV, RAW data format, and bit depth.|
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.2"><p id="entry1314377643170128p0"><a name="entry1314377643170128p0"></a><a name="entry1314377643170128p0"></a>Input Parameter</p> | setHsMode | **cntlr**: structure pointer to the MIPI CSI controller.<br>**laneDivideMode**: lane mode.| – | HDF_STATUS| Sets the MIPI RX lane distribution. |
</th> | enableClock | **cntlr**: structure pointer to the MIPI CSI controller.<br>**comboDev**: channel number, which is of the uint8_t type.| – | HDF_STATUS| Enables the MIPI clock. |
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.3"><p id="entry102571833170128p0"><a name="entry102571833170128p0"></a><a name="entry102571833170128p0"></a>Output Parameter</p> | disableClock | **cntlr**: structure pointer to the MIPI CSI controller.<br>**comboDev**: channel number, which is of the uint8_t type.| – | HDF_STATUS| Disables the MIPI clock. |
</th> | resetRx | **cntlr**: structure pointer to the MIPI CSI controller.<br>**comboDev**: channel number, which is of the uint8_t type.| – | HDF_STATUS| Resets the MIPI RX. |
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.4"><p id="entry259883708170128p0"><a name="entry259883708170128p0"></a><a name="entry259883708170128p0"></a>Return Value</p> | unresetRx | **cntlr**: structure pointer to the MIPI CSI controller.<br>**comboDev**: channel number, which is of the uint8_t type.| – | HDF_STATUS| Deasserts the reset of the MIPI RX. |
</th> | enableSensorClock | **cntlr**: structure pointer to the MIPI CSI controller.<br>**snsClkSource**: number of the clock signal cable of the sensor, which is of the uint8_t type.| – | HDF_STATUS| Enables the MIPI sensor clock. |
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.5"><p id="entry1719007141170128p0"><a name="entry1719007141170128p0"></a><a name="entry1719007141170128p0"></a>Description</p> | disableSensorClock | **cntlr**: structure pointer to the MIPI CSI controller.<br>**snsClkSource**: number of the clock signal cable of the sensor, which is of the uint8_t type.| – | HDF_STATUS| Disables the MIPI sensor clock. |
</th> | resetSensor | **cntlr**: structure pointer to the MIPI CSI controller.<br>**snsClkSource**: number of the clock signal cable of the sensor, which is of the uint8_t type.| – | HDF_STATUS| Resets a sensor. |
</tr> | unresetSensor | **cntlr**: structure pointer to the MIPI CSI controller.<br>**snsClkSource**: number of the clock signal cable of the sensor, which is of the uint8_t type.| – | HDF_STATUS| Deasserts the reset of a sensor. |
</thead>
<tbody><tr id="row893348241170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry2092857420170128p0"><a name="entry2092857420170128p0"></a><a name="entry2092857420170128p0"></a>setComboDevAttr</p> ## How to Develop
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p155578927170128"><a name="p155578927170128"></a><a name="p155578927170128"></a><strong id="b2983104693117"><a name="b2983104693117"></a><a name="b2983104693117"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p534134719170128"><a name="p534134719170128"></a><a name="p534134719170128"></a><strong id="b717683263220"><a name="b717683263220"></a><a name="b717683263220"></a>pAttr</strong>: structure pointer to the configuration structure of the MIPI CSI.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry1300850044170128p0"><a name="entry1300850044170128p0"></a><a name="entry1300850044170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry1079550609170128p0"><a name="entry1079550609170128p0"></a><a name="entry1079550609170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry1104973652170128p0"><a name="entry1104973652170128p0"></a><a name="entry1104973652170128p0"></a>Sets the MIPI-CSI configuration.</p>
</td>
</tr>
<tr id="row1236584443170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry1263277119170128p0"><a name="entry1263277119170128p0"></a><a name="entry1263277119170128p0"></a>setPhyCmvmode</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p548503413170128"><a name="p548503413170128"></a><a name="p548503413170128"></a><strong id="b33316314348"><a name="b33316314348"></a><a name="b33316314348"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p1389106408170128"><a name="p1389106408170128"></a><a name="p1389106408170128"></a><strong id="b7288183093611"><a name="b7288183093611"></a><a name="b7288183093611"></a>devno</strong>: Device ID, which is of the uint8_t type.</p>
<p id="p118314402170128"><a name="p118314402170128"></a><a name="p118314402170128"></a><strong id="b1347113393714"><a name="b1347113393714"></a><a name="b1347113393714"></a>cmvMode</strong>: common-mode voltage (CMV) mode.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry886884421170128p0"><a name="entry886884421170128p0"></a><a name="entry886884421170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry1542733203170128p0"><a name="entry1542733203170128p0"></a><a name="entry1542733203170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry1506663070170128p0"><a name="entry1506663070170128p0"></a><a name="entry1506663070170128p0"></a>Sets the CMV mode.</p>
</td>
</tr>
<tr id="row1486148936170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry1589217404170128p0"><a name="entry1589217404170128p0"></a><a name="entry1589217404170128p0"></a>setExtDataType</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p114389566170128"><a name="p114389566170128"></a><a name="p114389566170128"></a><strong id="b34053117344"><a name="b34053117344"></a><a name="b34053117344"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p996608377170128"><a name="p996608377170128"></a><a name="p996608377170128"></a><strong id="b784685684412"><a name="b784685684412"></a><a name="b784685684412"></a>dataType</strong>: structure pointer to the data that defines the YUV, original data formats, and bit depth.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry378080489170128p0"><a name="entry378080489170128p0"></a><a name="entry378080489170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry851136224170128p0"><a name="entry851136224170128p0"></a><a name="entry851136224170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry1309676064170128p0"><a name="entry1309676064170128p0"></a><a name="entry1309676064170128p0"></a>Sets the YUV, RAW data format, and bit depth.</p>
</td>
</tr>
<tr id="row692364909170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry1017488702170128p0"><a name="entry1017488702170128p0"></a><a name="entry1017488702170128p0"></a>setHsMode</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p1054266120170128"><a name="p1054266120170128"></a><a name="p1054266120170128"></a><strong id="b144183117349"><a name="b144183117349"></a><a name="b144183117349"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p1574674418170128"><a name="p1574674418170128"></a><a name="p1574674418170128"></a><strong id="b18748194155516"><a name="b18748194155516"></a><a name="b18748194155516"></a>laneDivideMode</strong>: lane mode.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry1749069145170128p0"><a name="entry1749069145170128p0"></a><a name="entry1749069145170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry1237801346170128p0"><a name="entry1237801346170128p0"></a><a name="entry1237801346170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry1643965522170128p0"><a name="entry1643965522170128p0"></a><a name="entry1643965522170128p0"></a>Sets the MIPI RX lane distribution.</p>
</td>
</tr>
<tr id="row1437392211170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry80806261170128p0"><a name="entry80806261170128p0"></a><a name="entry80806261170128p0"></a>enableClock</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p867235167170128"><a name="p867235167170128"></a><a name="p867235167170128"></a><strong id="b94263116342"><a name="b94263116342"></a><a name="b94263116342"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p1770663973170128"><a name="p1770663973170128"></a><a name="p1770663973170128"></a><strong id="b1342116531004"><a name="b1342116531004"></a><a name="b1342116531004"></a>comboDev</strong>: channel ID, which is of the uint8_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry836736200170128p0"><a name="entry836736200170128p0"></a><a name="entry836736200170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry918324954170128p0"><a name="entry918324954170128p0"></a><a name="entry918324954170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry373275246170128p0"><a name="entry373275246170128p0"></a><a name="entry373275246170128p0"></a>Enables the MIPI clock.</p>
</td>
</tr>
<tr id="row1944617165170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry1879109927170128p0"><a name="entry1879109927170128p0"></a><a name="entry1879109927170128p0"></a>disableClock</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p252627163170128"><a name="p252627163170128"></a><a name="p252627163170128"></a><strong id="b343103114343"><a name="b343103114343"></a><a name="b343103114343"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p573650189170128"><a name="p573650189170128"></a><a name="p573650189170128"></a><strong id="b1747970172618"><a name="b1747970172618"></a><a name="b1747970172618"></a>comboDev</strong>: channel ID, which is of the uint8_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry8107921170128p0"><a name="entry8107921170128p0"></a><a name="entry8107921170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry349207958170128p0"><a name="entry349207958170128p0"></a><a name="entry349207958170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry693552037170128p0"><a name="entry693552037170128p0"></a><a name="entry693552037170128p0"></a>Disables the MIPI clock.</p>
</td>
</tr>
<tr id="row168452313170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry536818735170128p0"><a name="entry536818735170128p0"></a><a name="entry536818735170128p0"></a>resetRx</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p1214231503170128"><a name="p1214231503170128"></a><a name="p1214231503170128"></a><strong id="b1043031153417"><a name="b1043031153417"></a><a name="b1043031153417"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p104793304170128"><a name="p104793304170128"></a><a name="p104793304170128"></a><strong id="b597920533269"><a name="b597920533269"></a><a name="b597920533269"></a>comboDev</strong>: channel ID, which is of the uint8_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry349755171170128p0"><a name="entry349755171170128p0"></a><a name="entry349755171170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry608378681170128p0"><a name="entry608378681170128p0"></a><a name="entry608378681170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry1692819512170128p0"><a name="entry1692819512170128p0"></a><a name="entry1692819512170128p0"></a>Resets the MIPI RX.</p>
</td>
</tr>
<tr id="row812174477170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry677771062170128p0"><a name="entry677771062170128p0"></a><a name="entry677771062170128p0"></a>unresetRx</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p1883220887170128"><a name="p1883220887170128"></a><a name="p1883220887170128"></a><strong id="b1202156153016"><a name="b1202156153016"></a><a name="b1202156153016"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p114324757170128"><a name="p114324757170128"></a><a name="p114324757170128"></a><strong id="b105520153110"><a name="b105520153110"></a><a name="b105520153110"></a>comboDev</strong>: channel ID, which is of the uint8_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry2088687179170128p0"><a name="entry2088687179170128p0"></a><a name="entry2088687179170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry250678538170128p0"><a name="entry250678538170128p0"></a><a name="entry250678538170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry1714667992170128p0"><a name="entry1714667992170128p0"></a><a name="entry1714667992170128p0"></a>Deasserts the reset of the MIPI RX.</p>
</td>
</tr>
<tr id="row1282919412170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry204916079170128p0"><a name="entry204916079170128p0"></a><a name="entry204916079170128p0"></a>enableSensorClock</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p217879421170128"><a name="p217879421170128"></a><a name="p217879421170128"></a><strong id="b197181237203211"><a name="b197181237203211"></a><a name="b197181237203211"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p2098908158170128"><a name="p2098908158170128"></a><a name="p2098908158170128"></a><strong id="b12861154993218"><a name="b12861154993218"></a><a name="b12861154993218"></a>snsClkSource</strong>: number of the clock signal cable of the sensor, which is of the uint8_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry1290595383170128p0"><a name="entry1290595383170128p0"></a><a name="entry1290595383170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry1313850176170128p0"><a name="entry1313850176170128p0"></a><a name="entry1313850176170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry384362703170128p0"><a name="entry384362703170128p0"></a><a name="entry384362703170128p0"></a>Enables the MIPI sensor clock.</p>
</td>
</tr>
<tr id="row1992432516170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry980444503170128p0"><a name="entry980444503170128p0"></a><a name="entry980444503170128p0"></a>disableSensorClock</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p1996780281170128"><a name="p1996780281170128"></a><a name="p1996780281170128"></a><strong id="b4445316347"><a name="b4445316347"></a><a name="b4445316347"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p2021170726170128"><a name="p2021170726170128"></a><a name="p2021170726170128"></a><strong id="b17971423820"><a name="b17971423820"></a><a name="b17971423820"></a>snsClkSource</strong>: number of the clock signal cable of the sensor, which is of the uint8_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry1694413990170128p0"><a name="entry1694413990170128p0"></a><a name="entry1694413990170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry1647081928170128p0"><a name="entry1647081928170128p0"></a><a name="entry1647081928170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry2011696236170128p0"><a name="entry2011696236170128p0"></a><a name="entry2011696236170128p0"></a>Disables the MIPI sensor clock.</p>
</td>
</tr>
<tr id="row1739370133170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry386036597170128p0"><a name="entry386036597170128p0"></a><a name="entry386036597170128p0"></a>resetSensor</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p1065048089170128"><a name="p1065048089170128"></a><a name="p1065048089170128"></a><strong id="b19451631183417"><a name="b19451631183417"></a><a name="b19451631183417"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p998202090170128"><a name="p998202090170128"></a><a name="p998202090170128"></a><strong id="b10443111911384"><a name="b10443111911384"></a><a name="b10443111911384"></a>snsClkSource</strong>: number of the clock signal cable of the sensor, which is of the uint8_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry173182567170128p0"><a name="entry173182567170128p0"></a><a name="entry173182567170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry879245456170128p0"><a name="entry879245456170128p0"></a><a name="entry879245456170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry944835652170128p0"><a name="entry944835652170128p0"></a><a name="entry944835652170128p0"></a>Resets the sensor.</p>
</td>
</tr>
<tr id="row1197566339170128"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="entry363281016170128p0"><a name="entry363281016170128p0"></a><a name="entry363281016170128p0"></a>unresetSensor</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p416483731170128"><a name="p416483731170128"></a><a name="p416483731170128"></a><strong id="b178488417385"><a name="b178488417385"></a><a name="b178488417385"></a>cntlr</strong>: structure pointer to the MIPI CSI controller.</p>
<p id="p1988272362170128"><a name="p1988272362170128"></a><a name="p1988272362170128"></a><strong id="b6353246183818"><a name="b6353246183818"></a><a name="b6353246183818"></a>snsClkSource</strong>: number of the clock signal cable of the sensor, which is of the uint8_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="entry1658055665170128p0"><a name="entry1658055665170128p0"></a><a name="entry1658055665170128p0"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="entry2142771023170128p0"><a name="entry2142771023170128p0"></a><a name="entry2142771023170128p0"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="entry791107803170128p0"><a name="entry791107803170128p0"></a><a name="entry791107803170128p0"></a>Deasserts the reset of a sensor.</p>
</td>
</tr>
</tbody>
</table>
## How to Develop<a name="section378858277170128"></a>
The MIPI CSI module adaptation involves the following steps: The MIPI CSI module adaptation involves the following steps:
1. Instantiate the driver entry. 1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure. - Instantiate the **HdfDriverEntry** structure.
- Call **HDF\_INIT** to register the **HdfDriverEntry** instance with the HDF. - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files. 2. Configure attribute files.
- Add the **deviceNode** information to the **device\_info.hcs** file.
- \(Optional\) Add the **mipicsi\_config.hcs** file. - Add the **deviceNode** information to the **device_info.hcs** file.
- (Optional) Add the **mipicsi_config.hcs** file.
3. Instantiate the MIPI CSI controller object.
- Initialize **MipiCsiCntlr**. 3. Instantiate the MIPI CSI controller object.
- Instantiate **MipiCsiCntlrMethod** in the **MipiCsiCntlr** object. - Initialize **MipiCsiCntlr**.
- Instantiate **MipiCsiCntlrMethod** in the **MipiCsiCntlr** object.
For details, see [Available APIs](#available-apis). >![](../public_sys-resources/icon-note.gif) **NOTE**<br>
>For details about the functions in **MipiCsiCntlrMethod**, see [Available APIs](#available-apis).
4. \(Optional\) Debug the driver.
For new drivers, verify basic functions, for example, verify the information returned after the connect operation and whether data is successfully transmitted. 4. Debug the driver.
- (Optional) For new drivers, verify the basic functions, for example, the data transmission and the information returned after the **MipiCsiCntlrMethod** instance is attached.
## Development Example<a name="section2049027816170128"></a>
## Development Example
The following uses **mipi\_rx\_hi35xx.c** as an example to present the contents that need to be provided by the vendor to implement device functions.
The following uses **mipi_rx_hi35xx.c** as an example to present the information required for implementing device functions.
1. Generally, you need to configure the device attributes in **busxx\_config.hcs** and add the **deviceNode** information to the **device\_info.hcs** file. The device attribute values are closely related to the default values or value range of the **MipiCsiCntlr** members at the core layer. The **deviceNode** information is related to the driver entry registration.
>![](../public_sys-resources/icon-note.gif) **NOTE:** 1. Configure the device attributes in **busxx_config.hcs** and add the **deviceNode** information to the **device_info.hcs** file.
>In this example, the MIPI controller attributes are defined in the source file. If required, add the **deviceMatchAttr** information to **deviceNode** in the **device\_info** file and add the** mipicsi\_config.hcs** file.
The device attribute values are closely related to the default values or value range of the **MipiCsiCntlr** members at the core layer. The **deviceNode** information is related to the driver entry registration.
**device\_info.hcs** configuration reference:
In this example, the MIPI controller attributes are defined in the source file. If required, add the **deviceMatchAttr** information to **deviceNode** in the **device_info** file and add the **mipicsi_config.hcs** file.
```
root { - **device_info.hcs** configuration example
device_info {
match_attr = "hdf_manager"; ```c
platform :: host { root {
hostName = "platform_host"; device_info {
priority = 50; match_attr = "hdf_manager";
device_mipi_csi:: device { platform :: host {
device0 :: deviceNode { hostName = "platform_host";
policy = 0; priority = 50;
priority = 160; device_mipi_csi:: device {
permission = 0644; device0 :: deviceNode {
moduleName = "HDF_MIPI_RX"; // (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. policy = 0;
serviceName = "HDF_MIPI_RX";// (Mandatory) Unique name of the service published by the driver. priority = 160;
} permission = 0644;
} moduleName = "HDF_MIPI_RX"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
} serviceName = "HDF_MIPI_RX"; // (Mandatory) Unique name of the service published by the driver.
} }
} }
``` }
}
2. 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**. The function pointer members of the **HdfDriverEntry** structure are filled by the vendors' operation functions. 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.
2. 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**. The function pointer members in the **HdfDriverEntry** structure are filled by the vendors' operation functions. 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.
MIPI CSI driver entry reference:
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.
```
struct HdfDriverEntry g_mipiCsiDriverEntry = { - MIPI CSI driver entry example
.moduleVersion = 1,
.Init = Hi35xxMipiCsiInit, // See the Init function. ```c
.Release = Hi35xxMipiCsiRelease, //See the Release function. struct HdfDriverEntry g_mipiCsiDriverEntry = {
.moduleName = "HDF_MIPI_RX", // (Mandatory) The value must be the same as that in the device_info.hcs file. .moduleVersion = 1,
}; .Init = Hi35xxMipiCsiInit, // See the Init function.
HDF_INIT(g_mipiCsiDriverEntry); // Call HDF_INIT to register the driver entry with the HDF. .Release = Hi35xxMipiCsiRelease, //See the Release function.
``` .moduleName = "HDF_MIPI_RX", // (Mandatory) The value must be the same as that in the device_info.hcs file.
};
3. Initialize the **MipiCsiCntlr** object at the core layer, including initializing the vendor custom structure \(passing parameters and data\), instantiating **MipiCsiCntlrMethod** \(used to call underlying functions of the driver\) in **MipiCsiCntlr**, and implementing the **HdfDriverEntry** member functions \(**Bind**, **Init**, and **Release**\). HDF_INIT(g_mipiCsiDriverEntry); // Call HDF_INIT to register the driver entry with the HDF.
- Custom structure reference: ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** 3. Initialize the **MipiCsiCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) to instantiate **MipiCsiCntlrMethod** in **MipiCsiCntlr** (so that the underlying driver functions can be called).
>To the driver, the custom structure carries parameters and data. The values in the **config** file are used to initialize the structure members. In this example, the MIPI CSI attributes are defined in the source file. Therefore, the basic member structure is similar to that of **MipiCsiCntlr**.
- Defining a custom structure
```
typedef struct { To the driver, the custom structure hols parameters and data. The values in the **config** file are used to initialize the structure members. In this example, the MIPI CSI attributes are defined in the source file. Therefore, the basic member structure is similar to that of **MipiCsiCntlr**.
/** Data type: 8-bit, 10-bit, 12-bit, 14-bit, or 16-bit */
DataType inputDataType; ```c
/** MIPI WDM mode */ typedef struct {
MipiWdrMode wdrMode; /** The data type can be 8-, 10-, 12-, 14-, or 16-bit. */
/** laneId: -1 - disabled */ DataType inputDataType;
short laneId[MIPI_LANE_NUM]; /** MIPI WDM mode */
MipiWdrMode wdrMode;
union { /** laneId: -1 - disabled */
/** Used for HI_MIPI_WDR_MODE_DT */ short laneId[MIPI_LANE_NUM];
short dataType[WDR_VC_NUM];
}; union {
} MipiDevAttr; /** Used for HI_MIPI_WDR_MODE_DT */
short dataType[WDR_VC_NUM];
typedef struct { };
/** Device number. */ } MipiDevAttr;
uint8_t devno;
/** Input mode, which can be MIPI, LVDS, sub-LVDS, HiSPi, or DC. */ typedef struct {
InputMode inputMode; /** Device number */
MipiDataRate dataRate; uint8_t devno;
/** Crop area of the MIPI RX device (same as the size of the input image of the sensor). */ /** Input mode, which can be MIPI, LVDS, sub-LVDS, HiSPi, or DC. */
ImgRect imgRect; InputMode inputMode;
MipiDataRate dataRate;
union { /** Crop area of the MIPI RX device (same as the size of the sensor input image) */
MipiDevAttr mipiAttr; ImgRect imgRect;
LvdsDevAttr lvdsAttr;
}; union {
} ComboDevAttr; MipiDevAttr mipiAttr;
LvdsDevAttr lvdsAttr;
// MipiCsiCntlr is the core layer controller structure. Its members are assigned with values by using the Init function. };
struct MipiCsiCntlr { } ComboDevAttr;
/** Send the service provided by this controller when the driver is bound to the HDF. */
struct IDeviceIoService service; // MipiCsiCntlr is the core layer controller structure. The Init function assigns values to the members of MipiCsiCntlr.
/** Pass the pointer to the device when the driver is bound to the HDF. */ struct MipiCsiCntlr {
struct HdfDeviceObject *device; /** Send the service provided by this controller when the driver is bound to the HDF. */
/** Device number */ struct IDeviceIoService service;
unsigned int devNo; /** Pass the pointer to the device when the driver is bound to the HDF. */
/** All APIs provided by the controller */ struct HdfDeviceObject *device;
struct MipiCsiCntlrMethod *ops; /** Device number */
/** All APIs for controller debugging. Set it to null if the driver is not implemented. */ unsigned int devNo;
struct MipiCsiCntlrDebugMethod *debugs; /** All APIs provided by the controller */
/** Controller context variable. */ struct MipiCsiCntlrMethod *ops;
MipiDevCtx ctx; /** All APIs for controller debugging. Set it to null if the driver is not implemented. */
/** Spinlock used when the controller context variable is accessed. */ struct MipiCsiCntlrDebugMethod *debugs;
OsalSpinlock ctxLock; /** Controller context variable. */
/** Lock method when the controller is managed */ MipiDevCtx ctx;
struct OsalMutex lock; /** Spinlock used when the controller context variable is accessed. */
/** Pointer to anonymous data, which is used to store the CSI device structure */ OsalSpinlock ctxLock;
void *priv; /** Lock method when the controller is managed */
}; struct OsalMutex lock;
``` /** Pointer to the anonymous structure that holds the CSI device data */
void *priv;
- **\(Important\)** Instantiate the callback function structure **MipiCsiCntlrMethod** in **MipiCsiCntlr**. Other members are initialized by using the **Init** function. };
```
```
static struct MipiCsiCntlrMethod g_method = { - Instantiating **MipiCsiCntlrMethod** in **MipiCsiCntlr** (other members are initialized by **Init**)
.setComboDevAttr = Hi35xxSetComboDevAttr,
.setPhyCmvmode = Hi35xxSetPhyCmvmode, ```c
.setExtDataType = Hi35xxSetExtDataType, static struct MipiCsiCntlrMethod g_method = {
.setHsMode = Hi35xxSetHsMode, .setComboDevAttr = Hi35xxSetComboDevAttr,
.enableClock = Hi35xxEnableClock, .setPhyCmvmode = Hi35xxSetPhyCmvmode,
.disableClock = Hi35xxDisableClock, .setExtDataType = Hi35xxSetExtDataType,
.resetRx = Hi35xxResetRx, .setHsMode = Hi35xxSetHsMode,
.unresetRx = Hi35xxUnresetRx, .enableClock = Hi35xxEnableClock,
.enableSensorClock = Hi35xxEnableSensorClock, .disableClock = Hi35xxDisableClock,
.disableSensorClock = Hi35xxDisableSensorClock, .resetRx = Hi35xxResetRx,
.resetSensor = Hi35xxResetSensor, .unresetRx = Hi35xxUnresetRx,
.unresetSensor = Hi35xxUnresetSensor .enableSensorClock = Hi35xxEnableSensorClock,
}; .disableSensorClock = Hi35xxDisableSensorClock,
``` .resetSensor = Hi35xxResetSensor,
.unresetSensor = Hi35xxUnresetSensor
- Init function };
```
Input parameters:
- Init function
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
**Input parameter**:
Return values:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
HDF\_STATUS \(The following table lists some status. For details about other status, see **HDF\_STATUS** in the **/drivers/framework/include/utils/hdf\_base.h** file.\)
**Return value**:
<a name="table683892652170128"></a>
<table><thead align="left"><tr id="row466801181170128"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="entry433041536170128p0"><a name="entry433041536170128p0"></a><a name="entry433041536170128p0"></a>Status (Value)</p> 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.
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="entry1260647143170128p0"><a name="entry1260647143170128p0"></a><a name="entry1260647143170128p0"></a>Description</p>
</th> | Status | Description |
</tr> | :--------------------- | :----------: |
</thead> | HDF_ERR_INVALID_OBJECT | Invalid object. |
<tbody><tr id="row2053721693170128"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry772353853170128p0"><a name="entry772353853170128p0"></a><a name="entry772353853170128p0"></a>HDF_ERR_INVALID_OBJECT</p> | HDF_ERR_MALLOC_FAIL | Failed to allocate memory.|
</td> | HDF_ERR_INVALID_PARAM | Invalid parameter. |
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry891453569170128p0"><a name="entry891453569170128p0"></a><a name="entry891453569170128p0"></a>Invalid object</p> | HDF_ERR_IO | I/O error. |
</td> | HDF_SUCCESS | Operation successful. |
</tr> | HDF_FAILURE | Operation failed. |
<tr id="row1654561941170128"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1037876509170128p0"><a name="entry1037876509170128p0"></a><a name="entry1037876509170128p0"></a>HDF_ERR_MALLOC_FAIL</p>
</td> **Function description**:
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1354763041170128p0"><a name="entry1354763041170128p0"></a><a name="entry1354763041170128p0"></a>Failed to allocate memory</p>
</td> Attaches the **MipiCsiCntlrMethod** instance, calls **MipiCsiRegisterCntlr**, and initializes the custom structure.
</tr>
<tr id="row515913237170128"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1517991694170128p0"><a name="entry1517991694170128p0"></a><a name="entry1517991694170128p0"></a>HDF_ERR_INVALID_PARAM</p>
</td> ```c
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry784824354170128p0"><a name="entry784824354170128p0"></a><a name="entry784824354170128p0"></a>Invalid parameter</p> static int32_t Hi35xxMipiCsiInit(struct HdfDeviceObject *device)
</td> {
</tr> int32_t ret;
<tr id="row1055228061170128"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry771111180170128p0"><a name="entry771111180170128p0"></a><a name="entry771111180170128p0"></a>HDF_ERR_IO</p>
</td> HDF_LOGI("%s: enter!", __func__);
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1302592910170128p0"><a name="entry1302592910170128p0"></a><a name="entry1302592910170128p0"></a>I/O error</p> g_mipiCsi.priv = NULL; // g_mipiTx is a global variable defined.
</td> // static struct MipiCsiCntlr g_mipiCsi = {
</tr> // .devNo = 0
<tr id="row1131544928170128"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1360197988170128p0"><a name="entry1360197988170128p0"></a><a name="entry1360197988170128p0"></a>HDF_SUCCESS</p> //};
</td> g_mipiCsi.ops = &g_method; // Attach the MipiCsiCntlrMethod instance.
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1609403118170128p0"><a name="entry1609403118170128p0"></a><a name="entry1609403118170128p0"></a>Operation successful</p> #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
</td> g_mipiCsi.debugs = &g_debugMethod;
</tr> #endif
<tr id="row1247344727170128"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry816278864170128p0"><a name="entry816278864170128p0"></a><a name="entry816278864170128p0"></a>HDF_FAILURE</p> ret = MipiCsiRegisterCntlr(&g_mipiCsi, device); // (Mandatory) Call the function at the core layer and g_mipiTx to initialize global variables at the core layer.
</td> if (ret != HDF_SUCCESS) {
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry814861870170128p0"><a name="entry814861870170128p0"></a><a name="entry814861870170128p0"></a>Operation failed</p> HDF_LOGE("%s: [MipiCsiRegisterCntlr] failed!", __func__);
</td> return ret;
</tr> }
</tbody>
</table> ret = MipiRxDrvInit(); // (Mandatory) Device initialization customized by the vendor.
if (ret != HDF_SUCCESS) {
Function description: HDF_LOGE("%s: [MipiRxDrvInit] failed.", __func__);
return ret;
Connects to the **MipiCsiCntlrMethod** instance, calls **MipiCsiRegisterCntlr**, and performs other vendor-defined initialization operations. }
#ifdef MIPICSI_VFS_SUPPORT
``` ret = MipiCsiDevModuleInit(g_mipiCsi.devNo);
static int32_t Hi35xxMipiCsiInit(struct HdfDeviceObject *device) if (ret != HDF_SUCCESS) {
{ HDF_LOGE("%s: [MipiCsiDevModuleInit] failed!", __func__);
int32_t ret; return ret;
}
HDF_LOGI("%s: enter!", __func__); #endif
g_mipiCsi.priv = NULL; // g_mipiTx is a global variable defined.
// static struct MipiCsiCntlr g_mipiCsi = { OsalSpinInit(&g_mipiCsi.ctxLock);
// .devNo = 0 HDF_LOGI("%s: load mipi csi driver success!", __func__);
// };
g_mipiCsi.ops = &g_method; // Connect to the MipiCsiCntlrMethod instance. return ret;
#ifdef CONFIG_HI_PROC_SHOW_SUPPORT }
g_mipiCsi.debugs = &g_debugMethod;
#endif // mipi_csi_core.c file
ret = MipiCsiRegisterCntlr(&g_mipiCsi, device); // (Mandatory) Call the function at the core layer and g_mipiTx to initialize global variables at the core layer. int32_t MipiCsiRegisterCntlr(struct MipiCsiCntlr *cntlr, struct HdfDeviceObject *device)
if (ret != HDF_SUCCESS) { {
HDF_LOGE("%s: [MipiCsiRegisterCntlr] failed!", __func__); ...
return ret; // Global variable static struct MipiCsiHandle g_mipiCsihandle[MAX_CNTLR_CNT];
} if (g_mipiCsihandle[cntlr->devNo].cntlr == NULL) {
(void)OsalMutexInit(&g_mipiCsihandle[cntlr->devNo].lock);
ret = MipiRxDrvInit(); // (Mandatory) Device initialization customized by the vendor. (void)OsalMutexInit(&(cntlr->lock));
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: [MipiRxDrvInit] failed.", __func__); g_mipiCsihandle[cntlr->devNo].cntlr = cntlr; // Initialize MipiCsiHandle.
return ret; g_mipiCsihandle[cntlr->devNo].priv = NULL;
} cntlr->device = device; // Prerequisites for conversion between HdfDeviceObject and MipiCsiHandle
#ifdef MIPICSI_VFS_SUPPORT device->service = &(cntlr->service); // Prerequisites for conversion between HdfDeviceObject and MipiCsiHandle.
ret = MipiCsiDevModuleInit(g_mipiCsi.devNo); cntlr->priv = NULL;
if (ret != HDF_SUCCESS) { HDF_LOGI("%s: success.", __func__);
HDF_LOGE("%s: [MipiCsiDevModuleInit] failed!", __func__);
return ret; return HDF_SUCCESS;
} }
#endif
HDF_LOGE("%s: cntlr already exists.", __func__);
OsalSpinInit(&g_mipiCsi.ctxLock); return HDF_FAILURE;
HDF_LOGI("%s: load mipi csi driver success!", __func__); }
```
return ret;
} - Release function
// mipi_csi_core.c, core layer file. **Input parameter**:
int32_t MipiCsiRegisterCntlr(struct MipiCsiCntlr *cntlr, struct HdfDeviceObject *device)
{ **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
...
// Define the global variable static struct MipiCsiHandle g_mipiCsihandle[MAX_CNTLR_CNT]; **Return value**:
if (g_mipiCsihandle[cntlr->devNo].cntlr == NULL) {
(void)OsalMutexInit(&g_mipiCsihandle[cntlr->devNo].lock); No value is returned.
(void)OsalMutexInit(&(cntlr->lock));
**Function description**:
g_mipiCsihandle[cntlr->devNo].cntlr = cntlr; // Initialize MipiCsiHandle.
g_mipiCsihandle[cntlr->devNo].priv = NULL; Releases the memory and deletes the controller. This function assigns values to the **Release** API in the driver entry structure. When the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
cntlr->device = device; // Enable conversion between HdfDeviceObject and MipiCsiHandle.
device->service = &(cntlr->service); // Enable conversion between HdfDeviceObject and MipiCsiHandle. All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the value assignment operations.
cntlr->priv = NULL;
HDF_LOGI("%s: success.", __func__); ```c
static void Hi35xxMipiCsiRelease(struct HdfDeviceObject *device)
return HDF_SUCCESS; {
} struct MipiCsiCntlr *cntlr = NULL;
...
HDF_LOGE("%s: cntlr already exists.", __func__); cntlr = MipiCsiCntlrFromDevice(device); // A forced conversion from HdfDeviceObject to MipiCsiCntlr is involved.
return HDF_FAILURE; // return (device == NULL) ? NULL : (struct MipiCsiCntlr *)device->service;
} ...
```
OsalSpinDestroy(&cntlr->ctxLock);
- Release function #ifdef MIPICSI_VFS_SUPPORT
MipiCsiDevModuleExit(cntlr->devNo);
Input parameters: #endif
MipiRxDrvExit(); // (Mandatory) Release the resources occupied by vendor devices.
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information. MipiCsiUnregisterCntlr(&g_mipiCsi); // Null function
g_mipiCsi.priv = NULL;
Return values:
HDF_LOGI("%s: unload mipi csi driver success!", __func__);
}
```
Function description:
Releases the memory and deletes the controller. This function assigns a value to the **Release** API in the driver entry structure. When the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
```
static void Hi35xxMipiCsiRelease(struct HdfDeviceObject *device)
{
struct MipiCsiCntlr *cntlr = NULL;
...
cntlr = MipiCsiCntlrFromDevice(device); // A forced conversion from HdfDeviceObject to MipiCsiCntlr is involved.
// return (device == NULL) ? NULL : (struct MipiCsiCntlr *)device->service;
...
OsalSpinDestroy(&cntlr->ctxLock);
#ifdef MIPICSI_VFS_SUPPORT
MipiCsiDevModuleExit(cntlr->devNo);
#endif
MipiRxDrvExit(); // (Mandatory) Release the resources occupied by the vendor's devices.
MipiCsiUnregisterCntlr(&g_mipiCsi); // Null function
g_mipiCsi.priv = NULL;
HDF_LOGI("%s: unload mipi csi driver success!", __func__);
}
```
\ No newline at end of file
# MMC<a name="EN-US_TOPIC_0000001153669000"></a> # MMC
## Overview<a name="section1846388309162704"></a>
In the Hardware Driver Foundation \(HDF\) framework, the MultiMedia Card \(MMC\) uses the independent service mode for API adaptation. In this mode, each device independently publishes a device service to handle external access requests. After receiving an access request from an API, the device manager extracts the parameters in the request to call the internal method of the target device. In the independent service mode, the service management capabilities of the HDFDeviceManager can be directly used. However, you need to configure a device node for each device, which increases the memory usage. ## Overview
**Figure 1** Independent service mode<a name="fig19517114132810"></a> In the Hardware Driver Foundation (HDF), the MultiMedia Card (MMC) uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device to increase memory resources.
![](figures/independent-service-mode.png "independent-service-mode")
## Available APIs<a name="section752964871810"></a> **Figure 1** Independent service mode
![image](figures/independent-service-mode.png "MMC independent service mode")
## Available APIs
**MmcCntlrOps**:
MmcCntlrOps
``` ```
struct MmcCntlrOps { struct MmcCntlrOps {
...@@ -31,520 +35,356 @@ struct MmcCntlrOps { ...@@ -31,520 +35,356 @@ struct MmcCntlrOps {
}; };
``` ```
**Table 1** Callbacks for the members in the MmcCntlrOps structure **Table 1** Description of callback functions in MmcCntlrOps
<a name="table99129433019"></a> | Function| Input Parameter| Return Value| Description|
<table><thead align="left"><tr id="row1891214163012"><th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.1"><p id="p79129483017"><a name="p79129483017"></a><a name="p79129483017"></a>Callback</p> | -------- | -------- | -------- | -------- |
</th> | doRequest | **cntlr**: structure pointer to the MMC controller at the core layer.<br>**cmd**: structure pointer to the command to execute.| HDF_STATUS| Processes the request.|
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.2"><p id="p1591213403019"><a name="p1591213403019"></a><a name="p1591213403019"></a>Input Parameter</p> | setClock | **cntlr**: structure pointer to the MMC controller at the core layer.<br>**clock**: clock frequency to set.| HDF_STATUS| Sets the clock frequency.|
</th> | setPowerMode | **cntlr**: structure pointer to the MMC controller at the core layer.<br>**mode**: power consumption mode, which is an enumerated value.| HDF_STATUS| Sets the power consumption mode.|
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.3"><p id="p491312483012"><a name="p491312483012"></a><a name="p491312483012"></a>Return Value</p> | setBusWidth | **cntlr**: structure pointer to the MMC controller at the core layer.<br>**width**: bus width, which is an enumerated value.| HDF_STATUS| Sets the bus width.|
</th> | setBusTiming | **cntlr**: structure pointer to the MMC controller at the core layer.<br>**timing**: bus timing, which is an enumerated value.| HDF_STATUS| Sets the bus timing.|
<th class="cellrowborder" valign="top" width="25%" id="mcps1.2.5.1.4"><p id="p8913144203017"><a name="p8913144203017"></a><a name="p8913144203017"></a>Description</p> | setSdioIrq | **cntlr**: structure pointer to the MMC controller at the core layer.<br>**enable**: whether to enable Secure Digital Input Output (SDIO) interrupts.| HDF_STATUS| Enables or disables SDIO interrupts.|
</th> | hardwareReset | **cntlr**: structure pointer to the MMC controller at the core layer.| HDF_STATUS| Resets hardware.|
</tr> | systemInit | **cntlr**: structure pointer to the MMC controller at the core layer.| HDF_STATUS| Performs system initialization.|
</thead> | setEnhanceSrobe | **cntlr**: structure pointer to the MMC controller at the core layer.<br>**enable**: whether to enable the enhanced strobe feature.| HDF_STATUS| Sets the enhanced strobe feature.|
<tbody><tr id="row4913844307"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p17913149309"><a name="p17913149309"></a><a name="p17913149309"></a>doRequest</p> | switchVoltage | **cntlr**: structure pointer to the MMC controller at the core layer.<br>**volt**: voltage to set, which can be 3.3 V, 1.8 V, or 1.2 V.| HDF_STATUS| Sets the voltage.|
</td> | devReadOnly | **cntlr**: structure pointer to the MMC controller at the core layer.| Boolean value| Checks whether the device is read-only.|
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p359655512340"><a name="p359655512340"></a><a name="p359655512340"></a><strong id="b1596155533411"><a name="b1596155533411"></a><a name="b1596155533411"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p> | cardPluged | **cntlr**: structure pointer to the MMC controller at the core layer.| Boolean value| Checks whether the device is removed.|
<p id="p159131449308"><a name="p159131449308"></a><a name="p159131449308"></a><strong id="b71781053113715"><a name="b71781053113715"></a><a name="b71781053113715"></a>cmd</strong>: structure pointer to the input command.</p> | devBusy | **cntlr**: structure pointer to the MMC controller at the core layer.| Boolean value| Checks whether the device is being used.|
</td> | tune | **cntlr**: structure pointer to the MMC controller at the core layer.<br>**cmdCode**: command code of the uint32_t type.| HDF_STATUS| Tunes the oscillator circuit frequency. |
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1291519413308"><a name="p1291519413308"></a><a name="p1291519413308"></a>HDF_STATUS</p> | rescanSdioDev | **cntlr**: structure pointer to the MMC controller at the core layer.| HDF_STATUS| Scans and adds an SDIO device.|
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p3915048309"><a name="p3915048309"></a><a name="p3915048309"></a>Processes the request.</p>
</td> ## How to Develop
</tr>
<tr id="row17915124113014"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p69152416307"><a name="p69152416307"></a><a name="p69152416307"></a>setClock</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p12397758163416"><a name="p12397758163416"></a><a name="p12397758163416"></a><strong id="b2397155816345"><a name="b2397155816345"></a><a name="b2397155816345"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
<p id="p119153413013"><a name="p119153413013"></a><a name="p119153413013"></a><strong id="b13651101617393"><a name="b13651101617393"></a><a name="b13651101617393"></a>clock</strong>: input clock value.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p79153417302"><a name="p79153417302"></a><a name="p79153417302"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1291614183010"><a name="p1291614183010"></a><a name="p1291614183010"></a>Sets the clock frequency.</p>
</td>
</tr>
<tr id="row19168433011"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1391614416305"><a name="p1391614416305"></a><a name="p1391614416305"></a>setPowerMode</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p349710303139"><a name="p349710303139"></a><a name="p349710303139"></a><strong id="b749713013132"><a name="b749713013132"></a><a name="b749713013132"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
<p id="p99161341305"><a name="p99161341305"></a><a name="p99161341305"></a><strong id="b1355614134405"><a name="b1355614134405"></a><a name="b1355614134405"></a>mode</strong>: power consumption mode. It is an enumerated value (see MmcPowerMode).</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1091674183020"><a name="p1091674183020"></a><a name="p1091674183020"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1191617420307"><a name="p1191617420307"></a><a name="p1191617420307"></a>Sets the power consumption mode.</p>
</td>
</tr>
<tr id="row291620463018"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p291612453018"><a name="p291612453018"></a><a name="p291612453018"></a>setBusWidth</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p52591598350"><a name="p52591598350"></a><a name="p52591598350"></a><strong id="b225999203512"><a name="b225999203512"></a><a name="b225999203512"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
<p id="p11916245309"><a name="p11916245309"></a><a name="p11916245309"></a><strong id="b24742024134111"><a name="b24742024134111"></a><a name="b24742024134111"></a>width</strong>: bus width. It is an enumerated value (see MmcBusWidth).</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1491610415305"><a name="p1491610415305"></a><a name="p1491610415305"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p19916147304"><a name="p19916147304"></a><a name="p19916147304"></a>Sets the bus width.</p>
</td>
</tr>
<tr id="row1916742301"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p3916104143014"><a name="p3916104143014"></a><a name="p3916104143014"></a>setBusTiming</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p109861912123517"><a name="p109861912123517"></a><a name="p109861912123517"></a><strong id="b39864125357"><a name="b39864125357"></a><a name="b39864125357"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
<p id="p591710419302"><a name="p591710419302"></a><a name="p591710419302"></a><strong id="b1067164920426"><a name="b1067164920426"></a><a name="b1067164920426"></a>timing</strong>: bus timing. It is an enumerated value (see MmcBusTiming).</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p14917154123017"><a name="p14917154123017"></a><a name="p14917154123017"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1991814443016"><a name="p1991814443016"></a><a name="p1991814443016"></a>Sets the bus timing.</p>
</td>
</tr>
<tr id="row199186423012"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p991810414305"><a name="p991810414305"></a><a name="p991810414305"></a>setSdioIrq</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p207324169351"><a name="p207324169351"></a><a name="p207324169351"></a><strong id="b11731716183510"><a name="b11731716183510"></a><a name="b11731716183510"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
<p id="p16918844305"><a name="p16918844305"></a><a name="p16918844305"></a><strong id="b49304428454"><a name="b49304428454"></a><a name="b49304428454"></a>enable</strong>: specifies whether to enable interrupt.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p17918204193011"><a name="p17918204193011"></a><a name="p17918204193011"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1191813416305"><a name="p1191813416305"></a><a name="p1191813416305"></a>Enables or disables Secure Digital Input Output (SDIO) interrupt.</p>
</td>
</tr>
<tr id="row139181453012"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p491874193011"><a name="p491874193011"></a><a name="p491874193011"></a>hardwareReset</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p12918114163011"><a name="p12918114163011"></a><a name="p12918114163011"></a><strong id="b127774583476"><a name="b127774583476"></a><a name="b127774583476"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p4918244309"><a name="p4918244309"></a><a name="p4918244309"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p11919243306"><a name="p11919243306"></a><a name="p11919243306"></a>Resets hardware.</p>
</td>
</tr>
<tr id="row169195410309"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p89191746303"><a name="p89191746303"></a><a name="p89191746303"></a>systemInit</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p8919441302"><a name="p8919441302"></a><a name="p8919441302"></a><strong id="b296543474814"><a name="b296543474814"></a><a name="b296543474814"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p199191941307"><a name="p199191941307"></a><a name="p199191941307"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p391919473014"><a name="p391919473014"></a><a name="p391919473014"></a>Performs system initialization.</p>
</td>
</tr>
<tr id="row159191423012"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p189194417307"><a name="p189194417307"></a><a name="p189194417307"></a>setEnhanceSrobe</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p684922173510"><a name="p684922173510"></a><a name="p684922173510"></a><strong id="b1184122212354"><a name="b1184122212354"></a><a name="b1184122212354"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
<p id="p1191910419304"><a name="p1191910419304"></a><a name="p1191910419304"></a><strong id="b17674159184914"><a name="b17674159184914"></a><a name="b17674159184914"></a>enable</strong>: specifies whether to enable the enhanced strobe feature.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p69194473011"><a name="p69194473011"></a><a name="p69194473011"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p091904143019"><a name="p091904143019"></a><a name="p091904143019"></a>Sets the enhanced strobe feature.</p>
</td>
</tr>
<tr id="row109197416305"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p791917443010"><a name="p791917443010"></a><a name="p791917443010"></a>switchVoltage</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p180311317351"><a name="p180311317351"></a><a name="p180311317351"></a><strong id="b2803231173514"><a name="b2803231173514"></a><a name="b2803231173514"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
<p id="p1591912415304"><a name="p1591912415304"></a><a name="p1591912415304"></a><strong id="b5411538185218"><a name="b5411538185218"></a><a name="b5411538185218"></a>volt</strong>: voltage, which can be 3.3 V, 1.8 V, or 1.2 V. It is an enumerated value.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p59196416307"><a name="p59196416307"></a><a name="p59196416307"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p169207416301"><a name="p169207416301"></a><a name="p169207416301"></a>Sets the voltage.</p>
</td>
</tr>
<tr id="row1992015417301"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1892014463010"><a name="p1892014463010"></a><a name="p1892014463010"></a>devReadOnly</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p1392011411309"><a name="p1392011411309"></a><a name="p1392011411309"></a><strong id="b20848102414403"><a name="b20848102414403"></a><a name="b20848102414403"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p89207418304"><a name="p89207418304"></a><a name="p89207418304"></a>Boolean</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p7920847301"><a name="p7920847301"></a><a name="p7920847301"></a>Checks whether the device is read-only.</p>
</td>
</tr>
<tr id="row1092019483018"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1092034103011"><a name="p1092034103011"></a><a name="p1092034103011"></a>cardPluged</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p2920144123010"><a name="p2920144123010"></a><a name="p2920144123010"></a><strong id="b1685142434016"><a name="b1685142434016"></a><a name="b1685142434016"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p2092014411305"><a name="p2092014411305"></a><a name="p2092014411305"></a>Boolean</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1892094153017"><a name="p1892094153017"></a><a name="p1892094153017"></a>Checks whether the device is removed.</p>
</td>
</tr>
<tr id="row892018413013"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p39201146309"><a name="p39201146309"></a><a name="p39201146309"></a>devBusy</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p9920124193013"><a name="p9920124193013"></a><a name="p9920124193013"></a><strong id="b1885213240408"><a name="b1885213240408"></a><a name="b1885213240408"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p1992112419305"><a name="p1992112419305"></a><a name="p1992112419305"></a>Boolean</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p69211417302"><a name="p69211417302"></a><a name="p69211417302"></a>Checks whether the device is engaged.</p>
</td>
</tr>
<tr id="row71064053613"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1511114015361"><a name="p1511114015361"></a><a name="p1511114015361"></a>tune</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p4972240153511"><a name="p4972240153511"></a><a name="p4972240153511"></a><strong id="b1997244017354"><a name="b1997244017354"></a><a name="b1997244017354"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
<p id="p5116409364"><a name="p5116409364"></a><a name="p5116409364"></a><strong id="b2286168195617"><a name="b2286168195617"></a><a name="b2286168195617"></a>cmdCode</strong>: command code of the uint32_t type.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p711440123610"><a name="p711440123610"></a><a name="p711440123610"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p1411184011368"><a name="p1411184011368"></a><a name="p1411184011368"></a>Tunes</p>
</td>
</tr>
<tr id="row1559214410366"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1559364493618"><a name="p1559364493618"></a><a name="p1559364493618"></a>rescanSdioDev</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.2 "><p id="p165931944133618"><a name="p165931944133618"></a><a name="p165931944133618"></a><strong id="b0854424164010"><a name="b0854424164010"></a><a name="b0854424164010"></a>cntlr</strong>: structure pointer to the MMC controller at the core layer.</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.3 "><p id="p15593184493610"><a name="p15593184493610"></a><a name="p15593184493610"></a>HDF_STATUS</p>
</td>
<td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.4 "><p id="p359384473615"><a name="p359384473615"></a><a name="p359384473615"></a>Scans and adds an SDIO device.</p>
</td>
</tr>
</tbody>
</table>
## How to Develop<a name="section1617495117162704"></a>
The MMC module adaptation involves the following steps: The MMC module adaptation involves the following steps:
1. Instantiate the driver entry. 1. Instantiate the driver entry.
- Instantiate the **HdfDriverEntry** structure. - Instantiate the **HdfDriverEntry** structure.
- Call **HDF\_INIT** to register the **HdfDriverEntry** instance with the HDF framework. - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
2. Configure attribute files. 2. Configure attribute files.
- Add the **deviceNode** information to the **device\_info.hcs** file. - Add the **deviceNode** information to the **device_info.hcs** file.
- \(Optional\) Add the **mmc\_config.hcs** file. - (Optional) Add the **mmc_config.hcs** file.
3. Instantiate the MMC controller object. 3. Instantiate the MMC controller object.
- Initialize **MmcCntlr**. - Initialize **MmcCntlr**.
- Instantiate **MmcCntlrOps** in the **MmcCntlr** object. - Instantiate **MmcCntlrOps** in the **MmcCntlr** object.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
For details, see [Available APIs](#available-apis). > For details about the functions in **MmcCntlrOps**, see [Available APIs](#available-apis).
4. \(Optional\) Debug the driver. 4. Debug the driver.
For new drivers, verify basic functions, for example, verify the information returned after the mount operation and whether the device starts successfully.
(Optional) For new drivers, verify the basic functions, for example, verify the information returned after the **MmcCntlrOps** instance is attached and whether the device starts successfully.
## Development Example<a name="section1220893490162704"></a>
## Development Example
The following uses **himci.c** as an example to present the contents that need to be provided by the vendor to implement device functions.
The following uses **himci.c** as an example to present the information required for implementing device 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 framework, 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.<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.
Generally, HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, 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.
- MMC driver entry reference
MMC driver entry example:
```
struct HdfDriverEntry g_mmcDriverEntry = { ```
.moduleVersion = 1, struct HdfDriverEntry g_mmcDriverEntry = {
.Bind = HimciMmcBind, // See the Bind function. .moduleVersion = 1,
.Init = HimciMmcInit, // See the Init function. .Bind = HimciMmcBind, // See the Bind function.
.Release = HimciMmcRelease, //See the Release function. .Init = HimciMmcInit, // See the Init function.
.moduleName = "hi3516_mmc_driver",// (Mandatory) The value must be the same as that of moduleName in the .hcs file. .Release = HimciMmcRelease, // See the Release function.
}; .moduleName = "hi3516_mmc_driver",// (Mandatory) The value must be the same as that of moduleName in the .hcs file.
HDF_INIT(g_mmcDriverEntry); // Call HDF_INIT to register the driver entry with the HDF framework. };
``` HDF_INIT(g_mmcDriverEntry); // Call HDF_INIT to register the driver entry with the HDF.
```
2. Add the **deviceNode** information to the **device\_info.hcs** file and configure the device attributes in the **mmc\_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 **MmcCntlr** members at the core layer.
2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **mmc_config.hcs** file.
If there are multiple devices, you need to add the **deviceNode** information to the **device\_info** file and add the corresponding device attributes to the **mmc\_config** 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 **MmcCntlr** members at the core layer. If there are multiple devices, you need to add the **deviceNode** information to the **device_info** file and add the device attributes to the **mmc_config** file for each device.
- **device\_info.hcs** configuration reference
- **device_info.hcs** configuration example
```
root {
device_info { ```
match_attr = "hdf_manager"; root {
platform :: host { device_info {
hostName = "platform_host"; match_attr = "hdf_manager";
priority = 50; platform :: host {
device_mmc:: device { hostName = "platform_host";
device0 :: deviceNode { priority = 50;
policy = 2; device_mmc:: device {
priority = 10; device0 :: deviceNode {
permission = 0644; policy = 2;
moduleName = "hi3516_mmc_driver"; // (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. priority = 10;
serviceName = "HDF_PLATFORM_MMC_0"; // (Mandatory) Unique name of the service published by the driver permission = 0644;
deviceMatchAttr = "hi3516_mmc_emmc";// (Mandatory) Used to configure the private data of the controller. The value must be the same as the controller in mmc_config.hcs. moduleName = "hi3516_mmc_driver"; // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
} serviceName = "HDF_PLATFORM_MMC_0"; // (Mandatory) Unique name of the service published by the driver.
device1 :: deviceNode { deviceMatchAttr = "hi3516_mmc_emmc";// (Mandatory) Private data of the controller. The value must be the same as the controller information in mmc_config.hcs.
policy = 1; }
priority = 20; device1 :: deviceNode {
permission = 0644; policy = 1;
moduleName = "hi3516_mmc_driver"; priority = 20;
serviceName = "HDF_PLATFORM_MMC_1"; permission = 0644;
deviceMatchAttr = "hi3516_mmc_sd"; // Indicates an SD. moduleName = "hi3516_mmc_driver";
} serviceName = "HDF_PLATFORM_MMC_1";
device2 :: deviceNode { deviceMatchAttr = "hi3516_mmc_sd"; // The MMC is an SD card.
policy = 1; }
priority = 30; device2 :: deviceNode {
permission = 0644; policy = 1;
moduleName = "hi3516_mmc_driver"; priority = 30;
serviceName = "HDF_PLATFORM_MMC_2"; permission = 0644;
deviceMatchAttr = "hi3516_mmc_sdio";// Indicates an SDIO. moduleName = "hi3516_mmc_driver";
} serviceName = "HDF_PLATFORM_MMC_2";
} deviceMatchAttr = "hi3516_mmc_sdio";// The MMC is an SDIO card.
} }
} }
} }
``` }
}
- **mmc\_config.hcs** configuration reference ```
``` - **mmc_config.hcs** configuration example
root {
platform {
mmc_config { ```
template mmc_controller {// Template configuration. In the template, you can configure the common parameters shared by service nodes. root {
match_attr = ""; platform {
voltDef = 0; // 3.3V mmc_config {
freqMin = 50000; // (Mandatory) Minimum frequency template mmc_controller { // Template configuration. In the template, you can configure the common parameters shared by device nodes.
freqMax = 100000000; // (Mandatory) Maximum frequency match_attr = "";
freqDef = 400000; // (Mandatory) Default frequency voltDef = 0; // 3.3V
maxBlkNum = 2048; // (Mandatory) Maximum block number freqMin = 50000; // (Mandatory) Minimum frequency
maxBlkSize = 512; // (Mandatory) Maximum number of blocks freqMax = 100000000; // (Mandatory) Maximum frequency
ocrDef = 0x300000; // (Mandatory) Working voltage. freqDef = 400000; // (Mandatory) Default frequency
caps2 = 0; // (Mandatory) Attribute register. For details, see MmcCaps2 in mmc_caps.h. maxBlkNum = 2048; // (Mandatory) Maximum block number
regSize = 0x118; // (Mandatory) Register bit width maxBlkSize = 512; // (Mandatory) Maximum number of blocks
hostId = 0; // (Mandatory) Host ID ocrDef = 0x300000; // (Mandatory) Working voltage.
regBasePhy = 0x10020000;// (Mandatory) Physical base address of the register caps2 = 0; // (Mandatory) Attribute register. For details, see MmcCaps2 in mmc_caps.h.
irqNum = 63; // (Mandatory) Interrupt number regSize = 0x118; // (Mandatory) Register bit width
devType = 2; // (Mandatory) Device mode, which can be eMMC, SD, SDIO, or COMBO hostId = 0; // (Mandatory) Host ID
caps = 0x0001e045; // (Mandatory) Attribute register. For details, see MmcCaps in mmc_caps.h. regBasePhy = 0x10020000;// (Mandatory) Physical base address of the register
} irqNum = 63; // (Mandatory) Interrupt number
controller_0x10100000 :: mmc_controller { devType = 2; // (Mandatory) Device type, which can be eMMC, SD, SDIO, or COMBO
match_attr = "hi3516_mmc_emmc";// (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs. caps = 0x0001e045; // (Mandatory) Attribute register. For details, see MmcCaps in mmc_caps.h.
hostId = 0; }
regBasePhy = 0x10100000; controller_0x10100000 :: mmc_controller {
irqNum = 96; match_attr = "hi3516_mmc_emmc";// (Mandatory) The value must be the same as that of deviceMatchAttr in device_info.hcs.
devType = 0; // The value 0 indicates an eMMC. hostId = 0;
caps = 0xd001e045; regBasePhy = 0x10100000;
caps2 = 0x60; irqNum = 96;
} devType = 0; // The MMC is an eMMC card.
controller_0x100f0000 :: mmc_controller { caps = 0xd001e045;
match_attr = "hi3516_mmc_sd"; caps2 = 0x60;
hostId = 1; }
regBasePhy = 0x100f0000; controller_0x100f0000 :: mmc_controller {
irqNum = 62; match_attr = "hi3516_mmc_sd";
devType = 1; // The value 1 indicates an SD card. hostId = 1;
caps = 0xd001e005; regBasePhy = 0x100f0000;
irqNum = 62;
devType = 1; // The MMC is an SD card.
caps = 0xd001e005;
}
controller_0x10020000 :: mmc_controller {
match_attr = "hi3516_mmc_sdio";
hostId = 2;
regBasePhy = 0x10020000;
irqNum = 63;
devType = 2; // The MMC is an SDIO card.
caps = 0x0001e04d;
}
}
}
}
```
3. Initialize the **MmcCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) to instantiate **MmcCntlrOps** in **MmcCntlr** (so that the underlying driver functions can be called).
- Defining a custom structure
To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **mmc_config.hcs** file to initialize the members in the custom structure and pass important parameters to the **MmcCntlr** object at the core layer.
```
struct HimciHost {
struct MmcCntlr *mmc;// (Mandatory) Core layer structure
struct MmcCmd *cmd; // (Mandatory) Core layer structure used to pass commands. For details about related commands, see MmcCmdCode.
//(Optional) Set parameters based on actual requirements.
void *base;
enum HimciPowerStatus powerStatus;
uint8_t *alignedBuff;
uint32_t buffLen;
struct scatterlist dmaSg;
struct scatterlist *sg;
uint32_t dmaSgNum;
DMA_ADDR_T dmaPaddr;
uint32_t *dmaVaddr;
uint32_t irqNum;
bool isTuning;
uint32_t id;
struct OsalMutex mutex;
bool waitForEvent;
HIMCI_EVENT himciEvent;
};
// MmcCntlr is the core layer controller structure. The bind function assigns values to the members of MmcCntlr.
struct MmcCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *hdfDevObj;
struct PlatformDevice device;
struct OsalMutex mutex;
struct OsalSem released;
uint32_t devType;
struct MmcDevice *curDev;
struct MmcCntlrOps *ops;
struct PlatformQueue *msgQueue;
uint16_t index;
uint16_t voltDef;
uint32_t vddBit;
uint32_t freqMin;
uint32_t freqMax;
uint32_t freqDef;
union MmcOcr ocrDef;
union MmcCaps caps;
union MmcCaps2 caps2;
uint32_t maxBlkNum;
uint32_t maxBlkSize;
uint32_t maxReqSize;
bool devPluged;
bool detecting;
void *priv;
};
```
- Instantiating **MmcCntlrOps** in **MmcCntlr** (other members are initialized by **Bind**)
```
static struct MmcCntlrOps g_himciHostOps = {
.request = HimciDoRequest,
.setClock = HimciSetClock,
.setPowerMode = HimciSetPowerMode,
.setBusWidth = HimciSetBusWidth,
.setBusTiming = HimciSetBusTiming,
.setSdioIrq = HimciSetSdioIrq,
.hardwareReset = HimciHardwareReset,
.systemInit = HimciSystemInit,
.setEnhanceSrobe= HimciSetEnhanceSrobe,
.switchVoltage = HimciSwitchVoltage,
.devReadOnly = HimciDevReadOnly,
.devPluged = HimciCardPluged,
.devBusy = HimciDevBusy,
.tune = HimciTune,
.rescanSdioDev = HimciRescanSdioDev,
};
```
- **Bind** function
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**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.
| Status| 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 **HimciHost** object and **MmcCntlr**, and calls the **MmcCntlrAdd** function at the core layer. **MmcCntlr**, **HimciHost**, and **HdfDeviceObject** assign values with each other so that other functions can be converted successfully.
```
static int32_t HimciMmcBind(struct HdfDeviceObject *obj)
{
struct MmcCntlr *cntlr = NULL;
struct HimciHost *host = NULL;
int32_t ret;
cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));
host = (struct HimciHost *)OsalMemCalloc(sizeof(struct HimciHost));
host->mmc = cntlr; // (Mandatory) Prerequisites for conversion between HimciHost and MmcCntlr.
cntlr->priv = (void *)host; // (Mandatory) Prerequisites for conversion between HimciHost and MmcCntlr.
cntlr->ops = &g_himciHostOps; // (Mandatory) Attach the MmcCntlrOps instance.
cntlr->hdfDevObj = obj; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and MmcCntlr.
obj->service = &cntlr->service; // (Mandatory) Prerequisites for conversion between HdfDeviceObject and MmcCntlr.
ret = MmcCntlrParse(cntlr, obj); // (Mandatory) Initialize MmcCntlr. If the initialization fails, execute goto _ERR.
...
ret = HimciHostParse(host, obj); // (Mandatory) Initialize HimciHost. If the initialization fails, execute goto _ERR.
...
ret = HimciHostInit(host, cntlr);// Customized initialization. If the initialization fails, execute goto _ERR.
...
ret = MmcCntlrAdd(cntlr); // Call the functions at the core layer. If the operation fails, execute goto _ERR.
...
(void)MmcCntlrAddDetectMsgToQueue(cntlr);// Add the card detection message to the queue.
HDF_LOGD("HimciMmcBind: success.");
return HDF_SUCCESS;
_ERR:
HimciDeleteHost(host);
HDF_LOGD("HimciMmcBind: fail, err = %d.", ret);
return ret;
}
```
- **Init** function
**Input parameter**:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
**Return value**:
HDF_STATUS
**Function description**:
Implements **ProcMciInit**.
```
static int32_t HimciMmcInit(struct HdfDeviceObject *obj)
{
static bool procInit = false;
(void)obj;
if (procInit == false) {
if (ProcMciInit() == HDF_SUCCESS) {
procInit = true;
HDF_LOGD("HimciMmcInit: proc init success.");
} }
controller_0x10020000 :: mmc_controller {
match_attr = "hi3516_mmc_sdio";
hostId = 2;
regBasePhy = 0x10020000;
irqNum = 63;
devType = 2; // The value 2 indicates an SDIO device.
caps = 0x0001e04d;
}
}
} }
} HDF_LOGD("HimciMmcInit: success.");
``` return HDF_SUCCESS;
}
3. Initialize the **MmcCntlr** object at the core layer, including initializing the vendor custom structure \(transferring parameters and data\), instantiating **MmcCntlrOps** \(used to call underlying functions of the driver\) in **MmcCntlr**, and implementing the **HdfDriverEntry** member functions \(**Bind**, **Init**, and **Release**\). ```
- Custom structure reference - **Release** function
To the driver, the custom structure carries parameters and data. The values in the **mmc\_config.hcs** file are read by the HDF, and the structure members are initialized through **DeviceResourceIface**. Some important values are also transferred to the objects at the core layer. **Input parameter**:
``` **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
struct HimciHost {
struct MmcCntlr *mmc;// (Mandatory) Core layer structure **Return value**:
struct MmcCmd *cmd; // (Mandatory) Core layer structure used to transfer commands. For details about related commands, see MmcCmdCode.
//(Optional) Set parameters based on the vendor's requirements. No value is returned.
void *base;
enum HimciPowerStatus powerStatus; **Function description**:
uint8_t *alignedBuff;
uint32_t buffLen; 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.
struct scatterlist dmaSg;
struct scatterlist *sg;
uint32_t dmaSgNum; ```
DMA_ADDR_T dmaPaddr; static void HimciMmcRelease(struct HdfDeviceObject *obj)
uint32_t *dmaVaddr; {
uint32_t irqNum; struct MmcCntlr *cntlr = NULL;
bool isTuning; ...
uint32_t id; cntlr = (struct MmcCntlr *)obj->service;// Forcibly convert HdfDeviceObject to MmcCntlr by using service. For details about the value assignment, see the Bind function.
struct OsalMutex mutex; ...
bool waitForEvent; HimciDeleteHost((struct HimciHost *)cntlr->priv);// Customized memory release function. A forced conversion from MmcCntlr to HimciHost is involved in the process.
HIMCI_EVENT himciEvent; }
}; ```
// MmcCntlr is the core layer controller structure. Its members are assigned with values by using the bind function.
struct MmcCntlr {
struct IDeviceIoService service;
struct HdfDeviceObject *hdfDevObj;
struct PlatformDevice device;
struct OsalMutex mutex;
struct OsalSem released;
uint32_t devType;
struct MmcDevice *curDev;
struct MmcCntlrOps *ops;
struct PlatformQueue *msgQueue;
uint16_t index;
uint16_t voltDef;
uint32_t vddBit;
uint32_t freqMin;
uint32_t freqMax;
uint32_t freqDef;
union MmcOcr ocrDef;
union MmcCaps caps;
union MmcCaps2 caps2;
uint32_t maxBlkNum;
uint32_t maxBlkSize;
uint32_t maxReqSize;
bool devPluged;
bool detecting;
void *priv;
};
```
- Instantiate the callback function structure **MmcCntlrOps** in **MmcCntlr**. Other members are initialized by using the **Bind** function.
```
static struct MmcCntlrOps g_himciHostOps = {
.request = HimciDoRequest,
.setClock = HimciSetClock,
.setPowerMode = HimciSetPowerMode,
.setBusWidth = HimciSetBusWidth,
.setBusTiming = HimciSetBusTiming,
.setSdioIrq = HimciSetSdioIrq,
.hardwareReset = HimciHardwareReset,
.systemInit = HimciSystemInit,
.setEnhanceSrobe= HimciSetEnhanceSrobe,
.switchVoltage = HimciSwitchVoltage,
.devReadOnly = HimciDevReadOnly,
.devPluged = HimciCardPluged,
.devBusy = HimciDevBusy,
.tune = HimciTune,
.rescanSdioDev = HimciRescanSdioDev,
};
```
- Bind function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
Return values:
HDF\_STATUS \(The following table lists some status. For details about other status, see **HDF\_STATUS** in the **//drivers/framework/include/utils/hdf\_base.h** file.\)
<a name="table1428218958162704"></a>
<table><thead align="left"><tr id="row1723943104162704"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="entry136979408162704p0"><a name="entry136979408162704p0"></a><a name="entry136979408162704p0"></a>Status (Value)</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="entry1590766658162704p0"><a name="entry1590766658162704p0"></a><a name="entry1590766658162704p0"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row408410040162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1337150412162704p0"><a name="entry1337150412162704p0"></a><a name="entry1337150412162704p0"></a>HDF_ERR_INVALID_OBJECT</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry2061632106162704p0"><a name="entry2061632106162704p0"></a><a name="entry2061632106162704p0"></a>Invalid controller object</p>
</td>
</tr>
<tr id="row160841211162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1173668571162704p0"><a name="entry1173668571162704p0"></a><a name="entry1173668571162704p0"></a>HDF_ERR_MALLOC_FAIL</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry74350097162704p0"><a name="entry74350097162704p0"></a><a name="entry74350097162704p0"></a>Failed to allocate memory</p>
</td>
</tr>
<tr id="row1596857798162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry190784255162704p0"><a name="entry190784255162704p0"></a><a name="entry190784255162704p0"></a>HDF_ERR_INVALID_PARAM</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry1070501269162704p0"><a name="entry1070501269162704p0"></a><a name="entry1070501269162704p0"></a>Invalid parameter</p>
</td>
</tr>
<tr id="row1645995958162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry741922133162704p0"><a name="entry741922133162704p0"></a><a name="entry741922133162704p0"></a>HDF_ERR_IO</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry2094504256162704p0"><a name="entry2094504256162704p0"></a><a name="entry2094504256162704p0"></a>I/O error</p>
</td>
</tr>
<tr id="row733220922162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry1177794681162704p0"><a name="entry1177794681162704p0"></a><a name="entry1177794681162704p0"></a>HDF_SUCCESS</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry540896959162704p0"><a name="entry540896959162704p0"></a><a name="entry540896959162704p0"></a>Initialization successful</p>
</td>
</tr>
<tr id="row1890064939162704"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="entry118676812162704p0"><a name="entry118676812162704p0"></a><a name="entry118676812162704p0"></a>HDF_FAILURE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="entry2078272728162704p0"><a name="entry2078272728162704p0"></a><a name="entry2078272728162704p0"></a>Initialization failed</p>
</td>
</tr>
</tbody>
</table>
Function description:
Initializes the custom structure **HimciHost** object and **MmcCntlr**, and calls the **MmcCntlrAdd** function at the core layer. **MmcCntlr**, **HimciHost**, and **HdfDeviceObject** assign values with each other so that other functions can be converted successfully.
```
static int32_t HimciMmcBind(struct HdfDeviceObject *obj)
{
struct MmcCntlr *cntlr = NULL;
struct HimciHost *host = NULL;
int32_t ret;
cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));
host = (struct HimciHost *)OsalMemCalloc(sizeof(struct HimciHost));
host->mmc = cntlr; // (Mandatory) Enable conversion between HimciHost and MmcCntlr.
cntlr->priv = (void *)host; // (Mandatory) Enable conversion between HimciHost and MmcCntlr.
cntlr->ops = &g_himciHostOps; // (Mandatory) Connect to the MmcCntlrOps instance.
cntlr->hdfDevObj = obj; // (Mandatory) Enable conversion between HdfDeviceObject and MmcCntlr.
obj->service = &cntlr->service; // (Mandatory) Enable conversion between HdfDeviceObject and MmcCntlr.
ret = MmcCntlrParse(cntlr, obj); // (Mandatory) Initialize cntlr. If the initialization fails, execute goto _ERR.
...
ret = HimciHostParse(host, obj); // (Mandatory) Initialize the attributes of the host. If the initialization fails, execute goto _ERR.
...
ret = HimciHostInit(host, cntlr);// Initialization defined by the vendor. If the initialization fails, execute goto _ERR.
...
ret = MmcCntlrAdd(cntlr); // Call the function at the core layer. If the function fails to be called, execute goto _ERR.
...
(void)MmcCntlrAddDetectMsgToQueue(cntlr);// Add the card detection message to the queue.
HDF_LOGD("HimciMmcBind: success.");
return HDF_SUCCESS;
_ERR:
HimciDeleteHost(host);
HDF_LOGD("HimciMmcBind: fail, err = %d.", ret);
return ret;
}
```
- Init function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
Return values:
HDF\_STATUS
Function description:
Implements ProcMciInit.
```
static int32_t HimciMmcInit(struct HdfDeviceObject *obj)
{
static bool procInit = false;
(void)obj;
if (procInit == false) {
if (ProcMciInit() == HDF_SUCCESS) {
procInit = true;
HDF_LOGD("HimciMmcInit: proc init success.");
}
}
HDF_LOGD("HimciMmcInit: success.");
return HDF_SUCCESS;
}
```
- Release function
Input parameters:
**HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs configuration file information.
Return values:
Function description:
Releases the memory and deletes the controller. This function assigns a value to the **Release** API in the driver entry structure. When the HDF framework 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.
```
static void HimciMmcRelease(struct HdfDeviceObject *obj)
{
struct MmcCntlr *cntlr = NULL;
...
cntlr = (struct MmcCntlr *)obj->service;// Forcibly convert HdfDeviceObject to MmcCntlr by using service. For details about the value assignment, see the Bind function.
...
HimciDeleteHost((struct HimciHost *)cntlr->priv);// Memory release function customized by the vendor. A forced conversion from MmcCntlr to HimciHost is involved in the process.
}
```
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## Overview ## Overview
The real-time clock (RTC) is a real-time clock device in the operating system. In the HDF, the RTC uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device to increase memory resources. The real-time clock (RTC) is a real-time clock device in the operating system. In the Hardware Driver Foundation (HDF), the RTC uses the independent service mode for API adaptation. In this mode, each device independently publishes a service to process external access requests. When receiving an access request, the HDF DeviceManager extracts parameters from the request to call the internal APIs of the target device. In the independent service mode, the HDF DeviceManager provides service management capabilities. However, you need to configure a node for each device to increase memory resources.
**Figure 1** Independent service mode **Figure 1** Independent service mode
...@@ -14,7 +14,7 @@ The real-time clock (RTC) is a real-time clock device in the operating system. I ...@@ -14,7 +14,7 @@ The real-time clock (RTC) is a real-time clock device in the operating system. I
**RtcMethod**: **RtcMethod**:
``` ```
struct RtcMethod { struct RtcMethod {
int32_t (*ReadTime)(struct RtcHost *host, struct RtcTime *time); int32_t (*ReadTime)(struct RtcHost *host, struct RtcTime *time);
...@@ -64,7 +64,7 @@ The RTC module adaptation involves the following steps: ...@@ -64,7 +64,7 @@ The RTC module adaptation involves the following steps:
- Initialize **RtcHost**. - Initialize **RtcHost**.
- Instantiate **RtcMethod** in the **RtcHost** object. - Instantiate **RtcMethod** in the **RtcHost** object.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br>
> For details about the functions in **RtcMethod**, see [API APIs](#available-apis). > For details about the functions in **RtcMethod**, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
(Optional) For new drivers, verify the basic functions, such as the RTC status control and response to interrupts. (Optional) For new drivers, verify the basic functions, such as the RTC status control and response to interrupts.
...@@ -72,13 +72,13 @@ The RTC module adaptation involves the following steps: ...@@ -72,13 +72,13 @@ The RTC module adaptation involves the following steps:
## Development Example ## Development Example
The following uses **rtc_hi35xx.c** as an example to present the information to be provided by the vendor to implement device functions. The following uses **rtc_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 framework, 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.<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 framework, 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.
RTC driver entry example: RTC driver entry example:
``` ```
struct HdfDriverEntry g_rtcDriverEntry = { struct HdfDriverEntry g_rtcDriverEntry = {
.moduleVersion = 1, .moduleVersion = 1,
...@@ -91,11 +91,14 @@ The following uses **rtc_hi35xx.c** as an example to present the information to ...@@ -91,11 +91,14 @@ The following uses **rtc_hi35xx.c** as an example to present the information to
HDF_INIT(g_rtcDriverEntry); HDF_INIT(g_rtcDriverEntry);
``` ```
2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **rtc_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 **RtcHost** members at the core layer. 2. Add the **deviceNode** information to the **device_info.hcs** file and configure the device attributes in the **rtc_config.hcs** file.
In this example, there is only one RTC controller. If there are multiple RTC controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **rtc_config** file for each controller.
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 **RtcHost** members at the core layer.
In this example, there is only one RTC controller. If there are multiple RTC controllers, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **rtc_config** file for each controller.
- **device_info.hcs** configuration example - **device_info.hcs** configuration example
``` ```
root { root {
device_info { device_info {
...@@ -117,7 +120,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to ...@@ -117,7 +120,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to
- **rtc_config.hcs** configuration example - **rtc_config.hcs** configuration example
``` ```
root { root {
platform { platform {
...@@ -136,16 +139,16 @@ The following uses **rtc_hi35xx.c** as an example to present the information to ...@@ -136,16 +139,16 @@ The following uses **rtc_hi35xx.c** as an example to present the information to
lock3Addr = 0xff; lock3Addr = 0xff;
} }
} }
}
} }
} ```
```
3. Initialize the **RtcHost** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init** and **Release**) to instantiate **RtcMethod** in **RtcHost** (so that the underlying driver functions can be called). 3. Initialize the **RtcHost** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init** and **Release**) to instantiate **RtcMethod** in **RtcHost** (so that the underlying driver functions can be called).
- Defining a custom structure - Defining a custom structure
To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **rtc_config.hcs** file to initialize the members in the custom structure. To the driver, the custom structure holds parameters and data. The **DeviceResourceIface** method provided by the HDF reads the values in the **rtc_config.hcs** file to initialize the members in the custom structure.
``` ```
struct RtcConfigInfo { struct RtcConfigInfo {
uint32_t spiBaseAddr; // Used for address mapping. uint32_t spiBaseAddr; // Used for address mapping.
...@@ -171,7 +174,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to ...@@ -171,7 +174,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to
``` ```
- Instantiating **RtcMethod** in **RtcHost** (other members are initialized by **Init**) - Instantiating **RtcMethod** in **RtcHost** (other members are initialized by **Init**)
``` ```
// Example in rtc_hi35xx.c: instantiate the hook. // Example in rtc_hi35xx.c: instantiate the hook.
static struct RtcMethod g_method = { static struct RtcMethod g_method = {
...@@ -214,7 +217,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to ...@@ -214,7 +217,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to
Binds the **HdfDeviceObject** object and **RtcHost**. Binds the **HdfDeviceObject** object and **RtcHost**.
``` ```
static int32_t HiRtcBind(struct HdfDeviceObject *device) static int32_t HiRtcBind(struct HdfDeviceObject *device)
{ {
...@@ -242,7 +245,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to ...@@ -242,7 +245,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to
Initializes the custom structure object and **RtcHost**. Initializes the custom structure object and **RtcHost**.
``` ```
static int32_t HiRtcInit(struct HdfDeviceObject *device) static int32_t HiRtcInit(struct HdfDeviceObject *device)
{ {
...@@ -284,7 +287,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to ...@@ -284,7 +287,7 @@ The following uses **rtc_hi35xx.c** as an example to present the information to
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** or **Bind** function has the corresponding 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 the **Init** or **Bind** function has the corresponding value assignment operations.
``` ```
static void HiRtcRelease(struct HdfDeviceObject *device) static void HiRtcRelease(struct HdfDeviceObject *device)
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册