1e41f4b71Sopenharmony_ci# MIPI DSI
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ci## Overview
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ciThe Display Serial Interface (DSI) is a specification developed by the Mobile Industry Processor Interface (MIPI) Alliance to reduce the cost of display controllers in mobile devices. In the Hardware Driver Foundation (HDF), the MIPI DSI 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.
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci  **Figure 1** Service-free mode
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci  ![](figures/service-free-mode.png "service-free-mode")
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci## Available APIs
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci**MipiDsiCntlrMethod**:
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci```
19e41f4b71Sopenharmony_cistruct MipiDsiCntlrMethod { // Member functions of the core layer structure
20e41f4b71Sopenharmony_ci    int32_t (*setCntlrCfg)(struct MipiDsiCntlr *cntlr);
21e41f4b71Sopenharmony_ci    int32_t (*setCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd);
22e41f4b71Sopenharmony_ci    int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
23e41f4b71Sopenharmony_ci    void (*toHs)(struct MipiDsiCntlr *cntlr);
24e41f4b71Sopenharmony_ci    void (*toLp)(struct MipiDsiCntlr *cntlr);
25e41f4b71Sopenharmony_ci    void (*enterUlps)(struct MipiDsiCntlr *cntlr);                      // (Optional) Enter the Ultra-Low Power State (ULPS).
26e41f4b71Sopenharmony_ci    void (*exitUlps)(struct MipiDsiCntlr *cntlr);                       // (Optional) Exit the ULPS.
27e41f4b71Sopenharmony_ci    int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);// (Optional) Enable or disable power control.
28e41f4b71Sopenharmony_ci    int32_t (*attach)(struct MipiDsiCntlr *cntlr);                      // (Optional) Attach a DSI device to the host.
29e41f4b71Sopenharmony_ci};
30e41f4b71Sopenharmony_ci```
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci  **Table 1** Description of the callback functions in MipiDsiCntlrMethod
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci| Function| Input Parameter| Output Parameter| Return Value| Description|
35e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- | -------- |
36e41f4b71Sopenharmony_ci| setCntlrCfg | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets controller parameters.|
37e41f4b71Sopenharmony_ci| setCmd | **cntlr**: structure pointer to the MIPI DSI controller.<br>**cmd**: structure pointer to the commands to send. | –| HDF_STATUS| Sends commands to a display device.|
38e41f4b71Sopenharmony_ci| getCmd | **cntlr**: structure pointer to the MIPI DSI controller.<br>**cmd**: pointer to the command description structure.<br>**readLen**: length of the data to read.| **out**: structure pointer to the data obtained.| HDF_STATUS| Reads data by sending commands.|
39e41f4b71Sopenharmony_ci| toHs | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets the high speed (HS) mode.|
40e41f4b71Sopenharmony_ci| toLp | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets the low power (LP) mode.|
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci## How to Develop
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ciThe MIPI DSI module adaptation involves the following steps:
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci1. Configure attribute files.
48e41f4b71Sopenharmony_ci   - Add the **deviceNode** description to the **device_info.hcs** file.
49e41f4b71Sopenharmony_ci   - (Optional) Add the **mipidsi_config.hcs** file.
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci2. Instantiate the driver entry.
52e41f4b71Sopenharmony_ci   - Instantiate the **HdfDriverEntry** structure.
53e41f4b71Sopenharmony_ci   - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci3. Instantiate the MIPI DSI controller object.
56e41f4b71Sopenharmony_ci   - Initialize **MipiDsiCntlr**.
57e41f4b71Sopenharmony_ci   - Instantiate **MipiDsiCntlrMethod** in the **MipiDsiCntlr** object.
58e41f4b71Sopenharmony_ci      > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>
59e41f4b71Sopenharmony_ci      > For details about the functions in **MipiDsiCntlrMethod**, see [Available APIs](#available-apis).
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci4. Debug the driver.
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci   (Optional) For new drivers, verify basic functions, for example, check the information returned after the driver is attached and whether data is successfully transmitted.
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci## Development Example
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ciThe following uses **mipi_tx_hi35xx.c** as an example to present the contents that need to be provided by the vendor to implement device functions.
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci1. Configure the device attributes in **xx_config.hcs** and add the **deviceNode** information to the **device_info.hcs** file.
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ci   The device attribute values are closely related to the default values or value range of the **MipiDsiCntlr** members at the core layer. The **deviceNode** information is related to the driver entry registration.
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci   In this example, no additional attribute needs to be configured for the MIPI DSI controller. If required, add the **deviceMatchAttr** information to **deviceNode** in the **device_info** file and add the **mipidsi_config** file.
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci     **device_info.hcs** configuration example:
77e41f4b71Sopenharmony_ci   
78e41f4b71Sopenharmony_ci   ```
79e41f4b71Sopenharmony_ci   root {
80e41f4b71Sopenharmony_ci   device_info {
81e41f4b71Sopenharmony_ci       match_attr = "hdf_manager";
82e41f4b71Sopenharmony_ci       platform :: host {
83e41f4b71Sopenharmony_ci       hostName = "platform_host";
84e41f4b71Sopenharmony_ci       priority = 50;
85e41f4b71Sopenharmony_ci       device_mipi_dsi:: device {
86e41f4b71Sopenharmony_ci           device0 :: deviceNode {
87e41f4b71Sopenharmony_ci           policy = 0;
88e41f4b71Sopenharmony_ci           priority = 150;
89e41f4b71Sopenharmony_ci           permission = 0644;
90e41f4b71Sopenharmony_ci           moduleName = "HDF_MIPI_TX";    // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
91e41f4b71Sopenharmony_ci           serviceName = "HDF_MIPI_TX";   // (Mandatory) Unique name of the service published by the driver.
92e41f4b71Sopenharmony_ci           }
93e41f4b71Sopenharmony_ci       }
94e41f4b71Sopenharmony_ci       }
95e41f4b71Sopenharmony_ci   }
96e41f4b71Sopenharmony_ci   }
97e41f4b71Sopenharmony_ci   ```
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci2. Instantiate the driver entry.
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci   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.
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci   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.
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci   MIPI DSI driver entry example:
106e41f4b71Sopenharmony_ci        
107e41f4b71Sopenharmony_ci      ```
108e41f4b71Sopenharmony_ci      struct HdfDriverEntry g_mipiTxDriverEntry = {
109e41f4b71Sopenharmony_ci          .moduleVersion = 1,             
110e41f4b71Sopenharmony_ci          .Init = Hi35xxMipiTxInit,       // See the Init function.
111e41f4b71Sopenharmony_ci          .Release = Hi35xxMipiTxRelease, // See the Release function.
112e41f4b71Sopenharmony_ci          .moduleName = "HDF_MIPI_TX",    // (Mandatory) The value must be the same as that in the device_info.hcs file.
113e41f4b71Sopenharmony_ci      };
114e41f4b71Sopenharmony_ci      HDF_INIT(g_mipiTxDriverEntry);      // Call HDF_INIT to register the driver entry with the HDF.
115e41f4b71Sopenharmony_ci      ```
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ci3. Initialize the **MipiDsiCntlr** 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 **MipiDsiCntlrMethod** in **MipiDsiCntlr** (so that the underlying driver functions can be called).
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci   - Defining a custom structure
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ci     To the driver, the custom structure holds parameters and data. Generally, the values in the **config** file are used to initialize the structure members. However, in this example, the MIPI DSI has no device attribute file. Therefore, the basic member structure is similar to that of **MipiDsiCntlr**.
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci     ```
124e41f4b71Sopenharmony_ci     typedef struct {
125e41f4b71Sopenharmony_ci       unsigned int devno;                   // Device number
126e41f4b71Sopenharmony_ci       short           laneId[LANE_MAX_NUM]; // Lane ID
127e41f4b71Sopenharmony_ci       OutPutModeTag   outputMode;           // Output mode, which can be CSI mode, DSI Video mode, or DSI Command mode.
128e41f4b71Sopenharmony_ci       VideoModeTag    videoMode;            // Synchronization mode of the display device
129e41f4b71Sopenharmony_ci       OutputFormatTag outputFormat;         // Format of the output DSI image, which can be RGB or YUV.
130e41f4b71Sopenharmony_ci       SyncInfoTag syncInfo;                 // Settings related to timing
131e41f4b71Sopenharmony_ci       unsigned int phyDataRate;             // Data rate, in Mbit/s
132e41f4b71Sopenharmony_ci       unsigned int    pixelClk;             // Clock, in kHz
133e41f4b71Sopenharmony_ci     } ComboDevCfgTag;
134e41f4b71Sopenharmony_ci     
135e41f4b71Sopenharmony_ci     // MipiDsiCntlr is the controller structure at the core layer. The Init function assigns values to the members of MipiDsiCntlr.
136e41f4b71Sopenharmony_ci     struct MipiDsiCntlr {
137e41f4b71Sopenharmony_ci       struct IDeviceIoService service;
138e41f4b71Sopenharmony_ci       struct HdfDeviceObject *device;
139e41f4b71Sopenharmony_ci       unsigned int devNo;         // Device number
140e41f4b71Sopenharmony_ci       struct MipiCfg cfg;
141e41f4b71Sopenharmony_ci       struct MipiDsiCntlrMethod *ops;
142e41f4b71Sopenharmony_ci       struct OsalMutex  lock;
143e41f4b71Sopenharmony_ci       void *priv;
144e41f4b71Sopenharmony_ci     };
145e41f4b71Sopenharmony_ci     ```
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci   - Instantiating **MipiDsiCntlrMethod** in **MipiDsiCntlr** (other members are initialized by **Init**)
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci     ```
150e41f4b71Sopenharmony_ci     static struct MipiDsiCntlrMethod g_method = {
151e41f4b71Sopenharmony_ci         .setCntlrCfg = Hi35xxSetCntlrCfg,
152e41f4b71Sopenharmony_ci         .setCmd = Hi35xxSetCmd,
153e41f4b71Sopenharmony_ci         .getCmd = Hi35xxGetCmd,
154e41f4b71Sopenharmony_ci         .toHs = Hi35xxToHs,
155e41f4b71Sopenharmony_ci         .toLp = Hi35xxToLp,
156e41f4b71Sopenharmony_ci     };
157e41f4b71Sopenharmony_ci     ```
158e41f4b71Sopenharmony_ci
159e41f4b71Sopenharmony_ci   - **Init** function
160e41f4b71Sopenharmony_ci
161e41f4b71Sopenharmony_ci     **Input parameter**:
162e41f4b71Sopenharmony_ci
163e41f4b71Sopenharmony_ci     **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
164e41f4b71Sopenharmony_ci
165e41f4b71Sopenharmony_ci     **Return value**:
166e41f4b71Sopenharmony_ci
167e41f4b71Sopenharmony_ci     **HDF_STATUS**
168e41f4b71Sopenharmony_ci
169e41f4b71Sopenharmony_ci     The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
170e41f4b71Sopenharmony_ci
171e41f4b71Sopenharmony_ci     | Status                 | Description                |
172e41f4b71Sopenharmony_ci     | ---------------------- | -------------------------- |
173e41f4b71Sopenharmony_ci     | HDF_ERR_INVALID_OBJECT | Invalid object.            |
174e41f4b71Sopenharmony_ci     | HDF_ERR_MALLOC_FAIL    | Failed to allocate memory. |
175e41f4b71Sopenharmony_ci     | HDF_ERR_INVALID_PARAM  | Invalid parameter.         |
176e41f4b71Sopenharmony_ci     | HDF_ERR_IO             | I/O error.                 |
177e41f4b71Sopenharmony_ci     | HDF_SUCCESS            | Operation successful.      |
178e41f4b71Sopenharmony_ci     | HDF_FAILURE            | Operation failed.          |
179e41f4b71Sopenharmony_ci
180e41f4b71Sopenharmony_ci     **Function description**:
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ci     Attaches the **MipiDsiCntlrMethod** instance, calls **MipiDsiRegisterCntlr**, and performs other vendor-defined initialization operations.
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci     ```
185e41f4b71Sopenharmony_ci      static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device)
186e41f4b71Sopenharmony_ci      {
187e41f4b71Sopenharmony_ci      int32_t ret;
188e41f4b71Sopenharmony_ci      g_mipiTx.priv = NULL;                         // g_mipiTx is a global variable defined.
189e41f4b71Sopenharmony_ci                                                     // static struct MipiDsiCntlr g_mipiTx { 
190e41f4b71Sopenharmony_ci                                                     //     .devNo=0
191e41f4b71Sopenharmony_ci                                                     //};
192e41f4b71Sopenharmony_ci      g_mipiTx.ops = &g_method;                     // Attach the MipiDsiCntlrMethod instance.
193e41f4b71Sopenharmony_ci      ret = MipiDsiRegisterCntlr(&g_mipiTx, device);// (Mandatory) Call the function at the core layer and g_mipiTx to initialize global variables at the core layer.
194e41f4b71Sopenharmony_ci      ...
195e41f4b71Sopenharmony_ci      return MipiTxDrvInit(0);                      // (Mandatory) Device initialization customized by the vendor.
196e41f4b71Sopenharmony_ci      }
197e41f4b71Sopenharmony_ci       
198e41f4b71Sopenharmony_ci      // mipi_dsi_core.c file
199e41f4b71Sopenharmony_ci      int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device)
200e41f4b71Sopenharmony_ci      {
201e41f4b71Sopenharmony_ci      ...
202e41f4b71Sopenharmony_ci      // Define the global variable static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT].
203e41f4b71Sopenharmony_ci      if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) {
204e41f4b71Sopenharmony_ci          (void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock);
205e41f4b71Sopenharmony_ci          (void)OsalMutexInit(&(cntlr->lock));
206e41f4b71Sopenharmony_ci       
207e41f4b71Sopenharmony_ci          g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;// Initialize MipiDsiHandle.
208e41f4b71Sopenharmony_ci          g_mipiDsihandle[cntlr->devNo].priv = NULL;  
209e41f4b71Sopenharmony_ci          cntlr->device = device;                     // Prerequisites for conversion between HdfDeviceObject and MipiDsiHandle.
210e41f4b71Sopenharmony_ci          device->service = &(cntlr->service);       // Prerequisites for conversion between HdfDeviceObject and MipiDsiHandle.
211e41f4b71Sopenharmony_ci          cntlr->priv = NULL;    
212e41f4b71Sopenharmony_ci          ...
213e41f4b71Sopenharmony_ci          return HDF_SUCCESS;
214e41f4b71Sopenharmony_ci      }
215e41f4b71Sopenharmony_ci      ...
216e41f4b71Sopenharmony_ci      return HDF_FAILURE;
217e41f4b71Sopenharmony_ci      }
218e41f4b71Sopenharmony_ci     ```
219e41f4b71Sopenharmony_ci
220e41f4b71Sopenharmony_ci   - **Release** function
221e41f4b71Sopenharmony_ci
222e41f4b71Sopenharmony_ci     **Input parameter**:
223e41f4b71Sopenharmony_ci
224e41f4b71Sopenharmony_ci     **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
225e41f4b71Sopenharmony_ci
226e41f4b71Sopenharmony_ci     **Return value**:
227e41f4b71Sopenharmony_ci
228e41f4b71Sopenharmony_ci     No value is returned.
229e41f4b71Sopenharmony_ci
230e41f4b71Sopenharmony_ci     **Function description**:
231e41f4b71Sopenharmony_ci
232e41f4b71Sopenharmony_ci     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.
233e41f4b71Sopenharmony_ci
234e41f4b71Sopenharmony_ci        > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
235e41f4b71Sopenharmony_ci		> 
236e41f4b71Sopenharmony_ci        > All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
237e41f4b71Sopenharmony_ci
238e41f4b71Sopenharmony_ci     ```
239e41f4b71Sopenharmony_ci      static void Hi35xxMipiTxRelease(struct HdfDeviceObject *device)
240e41f4b71Sopenharmony_ci      {
241e41f4b71Sopenharmony_ci      struct MipiDsiCntlr *cntlr = NULL;
242e41f4b71Sopenharmony_ci      ...
243e41f4b71Sopenharmony_ci      cntlr = MipiDsiCntlrFromDevice(device);// A forced conversion from HdfDeviceObject to MipiDsiCntlr is involved.
244e41f4b71Sopenharmony_ci                                               // return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service;
245e41f4b71Sopenharmony_ci      ...
246e41f4b71Sopenharmony_ci      MipiTxDrvExit(;                        // (Mandatory) Release the resources occupied by the vendor's devices.
247e41f4b71Sopenharmony_ci      MipiDsiUnregisterCntlr(&g_mipiTx);     // Empty function
248e41f4b71Sopenharmony_ci      g_mipiTx.priv = NULL;
249e41f4b71Sopenharmony_ci      HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__);
250e41f4b71Sopenharmony_ci      } 
251e41f4b71Sopenharmony_ci     ```
252