MIPI DSI
Overview
The 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) framework, 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 OS system that does not distinguish the user mode and the kernel mode. In the service-free mode, DevHandle (a void pointer) directly points to the kernel-mode address of the device object.
Available APIs
MipiDsiCntlrMethod
struct MipiDsiCntlrMethod {// Member functions of the core layer structure
int32_t (*setCntlrCfg)(struct MipiDsiCntlr *cntlr);
int32_t (*setCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd);
int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
void (*toHs)(struct MipiDsiCntlr *cntlr);
void (*toLp)(struct MipiDsiCntlr *cntlr);
void (*enterUlps)(struct MipiDsiCntlr *cntlr);//(Optional) Enter the ultra-low power consumption mode.
void (*exitUlps)(struct MipiDsiCntlr *cntlr); // (Optional) Exit the ultra-low power consumption mode.
int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);// (Optional) Enable or disable power control.
int32_t (*attach)(struct MipiDsiCntlr *cntlr);// (Optional) Connect a DSI device to the host.
};
Table 1 Callbacks for the members in the MipiDsiCntlrMethod structure
How to Develop
The MIPI DSI module adaptation involves the following steps:
-
Instantiate the driver entry.
- Instantiate the HdfDriverEntry structure.
- Call HDF_INIT to register the HdfDriverEntry instance with the HDF framework.
-
Configure attribute files.
- Add the deviceNode information to the device_info.hcs file.
- (Optional) Add the mipidsi_config.hcs file.
-
Instantiate the MIPI DSI controller object.
-
Initialize MipiDsiCntlr.
-
Instantiate MipiDsiCntlrMethod in the MipiDsiCntlr object.
NOTE
For details, see Available APIs.
-
-
Debug the driver.
- (Optional) For new drivers, verify basic functions, for example, verify the information returned after the connect operation and whether data is successfully transmitted.
Development Example
The 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.
-
Generally, you need to configure the device attributes in xx_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 MipiDsiCntlr members at the core layer. The deviceNode information is related to the driver entry registration.
In this example, no additional attribute needs to be configured for the MIPI DSI controller. If required, you need to add the deviceMatchAttr information to deviceNode in the device_info file and add the mipidsi_config file.
-
device_info.hcs configuration reference
root { device_info { match_attr = "hdf_manager"; platform :: host { hostName = "platform_host"; priority = 50; device_mipi_dsi:: device { device0 :: deviceNode { policy = 0; priority = 150; permission = 0644; moduleName = "HDF_MIPI_TX"; // (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. serviceName = "HDF_MIPI_TX";// (Mandatory) Unique name of the service published by the driver } } } } }
-
-
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 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, 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 exits.
-
MIPI DSI driver entry reference
struct HdfDriverEntry g_mipiTxDriverEntry = { .moduleVersion = 1, .Init = Hi35xxMipiTxInit, // See the Init function. .Release = Hi35xxMipiTxRelease, //See the Release function. .moduleName = "HDF_MIPI_TX", // (Mandatory) The value must be the same as that in the device_info.hcs file. }; HDF_INIT(g_mipiTxDriverEntry); // Call HDF_INIT to register the driver entry with the HDF framework.
-
-
Initialize the MipiDsiCntlr object at the core layer, including initializing the vendor custom structure (transferring parameters and data), instantiating MipiDsiCntlrMethod (used to call underlying functions of the driver) in MipiDsiCntlr, and implementing the HdfDriverEntry member functions (Bind, Init, and Release).
-
Custom structure reference
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 DSI has no device attribute file. Therefore, the basic member structure is similar to that of MipiDsiCntlr.
typedef struct { unsigned int devno; // Device number short laneId[LANE_MAX_NUM]; // Lane ID OutPutModeTag outputMode; // Output mode, which can be CSI mode, DSI Video mode, or DSI Command mode. VideoModeTag videoMode; // Synchronization mode of the display device OutputFormatTag outputFormat; // Format of the output DSI image, which can be RGB or YUV. SyncInfoTag syncInfo; // Settings related to timing unsigned int phyDataRate; // mbps unsigned int pixelClk; // KHz } ComboDevCfgTag; // MipiDsiCntlr is the controller structure at the core layer. Its members are assigned with values by using the Init function. struct MipiDsiCntlr { struct IDeviceIoService service; struct HdfDeviceObject *device; unsigned int devNo; // Device number struct MipiCfg cfg; struct MipiDsiCntlrMethod *ops; struct OsalMutex lock; void *priv; };
-
Instantiate the callback function structure MipiDsiCntlrMethod in MipiDsiCntlr. Other members are initialized by using the Init function.
static struct MipiDsiCntlrMethod g_method = { .setCntlrCfg = Hi35xxSetCntlrCfg, .setCmd = Hi35xxSetCmd, .getCmd = Hi35xxGetCmd, .toHs = Hi35xxToHs, .toLp = Hi35xxToLp, };
-
Init 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.)
Function description:
Connects to the MipiDsiCntlrMethod instance, calls MipiDsiRegisterCntlr, and performs other vendor-defined initialization operations.
static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device) { int32_t ret; g_mipiTx.priv = NULL; // g_mipiTx is a global variable. //static struct MipiDsiCntlr g_mipiTx { // .devNo=0 //}; g_mipiTx.ops = &g_method;// Connect to the MipiDsiCntlrMethod instance. ret = MipiDsiRegisterCntlr(&g_mipiTx, device);// (Mandatory) Call the function at the core layer and g_mipiTx to initialize global variables at the core layer. ... return MipiTxDrvInit(0); // (Mandatory) Device initialization customized by the vendor. } // mipi_dsi_core.c, core layer file. int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device) { ... // Define the global variable static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT]. if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) { (void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock); (void)OsalMutexInit(&(cntlr->lock)); g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;// Initialize MipiDsiHandle. g_mipiDsihandle[cntlr->devNo].priv = NULL; cntlr->device = device; // Enable conversion between HdfDeviceObject and MipiDsiHandle. device->service = &(cntlr->service); // Enable conversion between HdfDeviceObject and MipiDsiHandle. cntlr->priv = NULL; ... return HDF_SUCCESS; } ... return HDF_FAILURE; }
-
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 Hi35xxMipiTxRelease(struct HdfDeviceObject *device) { struct MipiDsiCntlr *cntlr = NULL; ... cntlr = MipiDsiCntlrFromDevice(device);// A forced conversion from HdfDeviceObject to MipiDsiCntlr is involved. //return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service; ... MipiTxDrvExit(); // (Mandatory) Release the resources occupied by the vendor's devices. MipiDsiUnregisterCntlr(&g_mipiTx); // Empty function g_mipiTx.priv = NULL; HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__); }
-