未验证 提交 a69078e6 编写于 作者: O openharmony_ci 提交者: Gitee

!3940 【OpenHarmony开源贡献者计划2022】MMC,MIPICSI,MIPIDSI相关格式及表达问题

Merge pull request !3940 from king_he/mipicsi-1
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
## 概述<a name="section1_MIPI_CSIDes"></a> ## 概述<a name="section1_MIPI_CSIDes"></a>
- CSI(Camera Serial Interface)是由MIPI联盟下Camera工作组指定的接口标准。CSI-2是MIPI CSI第二版,主要由应用层、协议层、物理层组成,最大支持4通道数据传输、单线传输速度高达1Gb/s。 CSI(Camera Serial Interface)是由MIPI联盟下Camera工作组指定的接口标准。CSI-2是MIPI CSI第二版,主要由应用层、协议层、物理层组成,最大支持4通道数据传输、单线传输速度高达1Gb/s。
- 物理层支持HS(High Speed)和LP(Low Power)两种工作模式。HS模式下采用低压差分信号,功耗较大,但数据传输速率可以很高(数据速率为80M~1Gbps);LP模式下采用单端信号,数据速率很低(<10Mbps),但是相应的功耗也很低。两种模式的结合保证了MIPI总线在需要传输大量数据(如图像)时可以高速传输,而在不需要传输大数据量时又能够减少功耗。 物理层支持HS(High Speed)和LP(Low Speed)两种工作模式。HS模式下采用低压差分信号,功耗较大,但数据传输速率可以很高(数据速率为80M~1Gbps);LP模式下采用单端信号,数据速率很低(<10Mbps),但是相应的功耗也很低。两种模式的结合保证了MIPI总线在需要传输大量数据(如图像)时可以高速传输,而在不需要传输大数据量时又能够减少功耗。
- 图1显示了简化的CSI接口。D-PHY采用1对源同步的差分时钟和1~4对差分数据线来进行数据传输。数据传输采用DDR方式,即在时钟的上下边沿都有数据传输。 图1显示了简化的CSI接口。D-PHY采用1对源同步的差分时钟和1~4对差分数据线来进行数据传输。数据传输采用DDR方式,即在时钟的上下边沿都有数据传输。
**图 1** CSI发送、接收接口<a name="fig1_MIPI_CSIDes"></a> **图 1** CSI发送、接收接口<a name="fig1_MIPI_CSIDes"></a>
![](figures/CSI发送-接收接口.png) ![](figures/CSI发送-接收接口.png)
...@@ -567,7 +567,7 @@ void PalMipiCsiTestSample(void) ...@@ -567,7 +567,7 @@ void PalMipiCsiTestSample(void)
/* lane模式参数为0 */ /* lane模式参数为0 */
mode = LANE_DIVIDE_MODE_0; mode = LANE_DIVIDE_MODE_0;
/* 设置MIPI RX的 Lane分布 */ /* 设置MIPI RX的Lane分布 */
ret = MipiCsiSetHsMode(MipiCsiHandle, mode); ret = MipiCsiSetHsMode(MipiCsiHandle, mode);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret); HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
## 概述 <a name="section1_MIPI_CSIDevelop"></a> ## 概述 <a name="section1_MIPI_CSIDevelop"></a>
CSI(Camera Serial Interface)是由MIPI(Mobile Industry Processor Interface )联盟下Camera工作组指定的接口标准。在HDF框架中,MIPI CSI的接口适配模式采用无服务模式,用于不需要在用户态提供API的设备类型,或者没有用户态和内核区分的OS系统,MIPI CSI的接口关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。 CSI(Camera Serial Interface)是由MIPI(Mobile Industry Processor Interface)联盟下Camera工作组指定的接口标准。在HDF框架中,MIPI CSI的接口适配模式采用无服务模式,用于不需要在用户态提供API的设备类型,或者没有用户态和内核区分的OS系统,MIPI CSI的接口关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。
图 1 无服务模式结构图 图 1 无服务模式结构图
...@@ -10,7 +10,7 @@ CSI(Camera Serial Interface)是由MIPI(Mobile Industry Processor Interface ...@@ -10,7 +10,7 @@ CSI(Camera Serial Interface)是由MIPI(Mobile Industry Processor Interface
## 接口说明 <a name="section2_MIPI_CSIDevelop"></a> ## 接口说明 <a name="section2_MIPI_CSIDevelop"></a>
MipiCsiCntlrMethod定义 MipiCsiCntlrMethod定义
```c ```c
struct MipiCsiCntlrMethod { struct MipiCsiCntlrMethod {
...@@ -35,12 +35,12 @@ struct MipiCsiCntlrMethod { ...@@ -35,12 +35,12 @@ struct MipiCsiCntlrMethod {
| setPhyCmvmode | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**devno**:uint8_t,设备编号;<br>**cmvMode**:枚举类型,共模电压模式参数 | 无 | HDF_STATUS相关状态 | 设置共模电压模式 | | setPhyCmvmode | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**devno**:uint8_t,设备编号;<br>**cmvMode**:枚举类型,共模电压模式参数 | 无 | HDF_STATUS相关状态 | 设置共模电压模式 |
| setExtDataType | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**dataType**:结构体指针,定义YUV和原始数据格式以及位深度 | 无 | HDF_STATUS相关状态 | 设置YUV和RAW数据格式和位深 | | setExtDataType | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**dataType**:结构体指针,定义YUV和原始数据格式以及位深度 | 无 | HDF_STATUS相关状态 | 设置YUV和RAW数据格式和位深 |
| setHsMode | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**laneDivideMode**:枚举类型,lane模式参数 | 无 | HDF_STATUS相关状态 | 设置MIPI RX的Lane分布 | | setHsMode | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**laneDivideMode**:枚举类型,lane模式参数 | 无 | HDF_STATUS相关状态 | 设置MIPI RX的Lane分布 |
| enableClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 使能mipi的时钟 | | enableClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 使能MIPI的时钟 |
| disableClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 关闭mipi的时钟 | | disableClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 关闭MIPI的时钟 |
| resetRx | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 复位MIPI RX | | resetRx | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 复位MIPI RX |
| unresetRx | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 撤销复位MIPI RX | | unresetRx | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**comboDev**:uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 撤销复位MIPI RX |
| enableSensorClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 使能mipi上的Sensor时钟 | | enableSensorClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 使能MIPI上的Sensor时钟 |
| disableSensorClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 关闭mipi上的Sensor时钟 | | disableSensorClock | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 关闭MIPI上的Sensor时钟 |
| resetSensor | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 复位Sensor | | resetSensor | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 复位Sensor |
| unresetSensor | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 撤销复位Sensor | | unresetSensor | **cntlr**:结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**:uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 撤销复位Sensor |
...@@ -60,7 +60,7 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、 ...@@ -60,7 +60,7 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
3. **实例化MIPICSI控制器对象:** 3. **实例化MIPICSI控制器对象:**
- 初始化MipiCsiCntlr成员。 - 初始化MipiCsiCntlr成员。
- 实例化MipiCsiCntlr成员MipiCsiCntlrMethod。 - 实例化MipiCsiCntlr成员MipiCsiCntlrMethod。
>![](../public_sys-resources/icon-note.gif) **说明:** >![](../public_sys-resources/icon-note.gif) **说明:**<br>
>实例化MipiCsiCntlr成员MipiCsiCntlrMethod,其定义和成员说明见[接口说明](#section2_MIPI_CSIDevelop)。 >实例化MipiCsiCntlr成员MipiCsiCntlrMethod,其定义和成员说明见[接口说明](#section2_MIPI_CSIDevelop)。
4. **驱动调试:** 4. **驱动调试:**
...@@ -90,8 +90,8 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、 ...@@ -90,8 +90,8 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
policy = 0; policy = 0;
priority = 160; priority = 160;
permission = 0644; permission = 0644;
moduleName = "HDF_MIPI_RX"; //【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致; moduleName = "HDF_MIPI_RX"; // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致;
serviceName = "HDF_MIPI_RX"; //【必要且唯一】驱动对外发布服务的名称 serviceName = "HDF_MIPI_RX"; // 【必要且唯一】驱动对外发布服务的名称
} }
} }
} }
...@@ -108,11 +108,11 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、 ...@@ -108,11 +108,11 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
```c ```c
struct HdfDriverEntry g_mipiCsiDriverEntry = { struct HdfDriverEntry g_mipiCsiDriverEntry = {
.moduleVersion = 1, .moduleVersion = 1,
.Init = Hi35xxMipiCsiInit, //见Init参考 .Init = Hi35xxMipiCsiInit, // 见Init参考
.Release = Hi35xxMipiCsiRelease, //见Release参考 .Release = Hi35xxMipiCsiRelease, // 见Release参考
.moduleName = "HDF_MIPI_RX", //【必要】需要与device_info.hcs 中保持一致。 .moduleName = "HDF_MIPI_RX", // 【必要】需要与device_info.hcs 中保持一致。
}; };
HDF_INIT(g_mipiCsiDriverEntry); //调用HDF_INIT将驱动入口注册到HDF框架中 HDF_INIT(g_mipiCsiDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中
``` ```
3. 完成驱动入口注册之后,最后一步就是以核心层MipiCsiCntlr对象的初始化为核心,实现HdfDriverEntry成员函数(Bind,Init,Release)。MipiCsiCntlr对象的初始化包括厂商自定义结构体(用于传递参数和数据)和实例化MipiCsiCntlr成员MipiCsiCntlrMethod(让用户可以通过接口来调用驱动底层函数)。 3. 完成驱动入口注册之后,最后一步就是以核心层MipiCsiCntlr对象的初始化为核心,实现HdfDriverEntry成员函数(Bind,Init,Release)。MipiCsiCntlr对象的初始化包括厂商自定义结构体(用于传递参数和数据)和实例化MipiCsiCntlr成员MipiCsiCntlrMethod(让用户可以通过接口来调用驱动底层函数)。
...@@ -151,7 +151,7 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、 ...@@ -151,7 +151,7 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
}; };
} ComboDevAttr; } ComboDevAttr;
//MipiCsiCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值 // MipiCsiCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值
struct MipiCsiCntlr { struct MipiCsiCntlr {
/** 当驱动程序绑定到HDF框架时,将发送此控制器提供的服务 */ /** 当驱动程序绑定到HDF框架时,将发送此控制器提供的服务 */
struct IDeviceIoService service; struct IDeviceIoService service;
...@@ -196,10 +196,10 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、 ...@@ -196,10 +196,10 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
- **Init函数参考** - **Init函数参考**
**入参:** **入参:**
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息 HdfDeviceObject 是整个驱动对外暴露的接口参数,具备hcs配置文件的信息
**返回值:** **返回值:**
HDF_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义) HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)
| 状态(值) | 问题描述 | | 状态(值) | 问题描述 |
...@@ -221,21 +221,21 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、 ...@@ -221,21 +221,21 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
int32_t ret; int32_t ret;
HDF_LOGI("%s: enter!", __func__); HDF_LOGI("%s: enter!", __func__);
g_mipiCsi.priv = NULL; //g_mipiTx是定义的全局变量 g_mipiCsi.priv = NULL; // g_mipiTx是定义的全局变量
//static struct MipiCsiCntlr g_mipiCsi = { // static struct MipiCsiCntlr g_mipiCsi = {
//.devNo = 0 // .devNo = 0
//}; //};
g_mipiCsi.ops = &g_method; //MipiCsiCntlrMethod的实例化对象的挂载 g_mipiCsi.ops = &g_method; //MipiCsiCntlrMethod的实例化对象的挂载
#ifdef CONFIG_HI_PROC_SHOW_SUPPORT #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
g_mipiCsi.debugs = &g_debugMethod; g_mipiCsi.debugs = &g_debugMethod;
#endif #endif
ret = MipiCsiRegisterCntlr(&g_mipiCsi, device); //【必要】调用核心层函数和g_mipiTx初始化核心层全局变量 ret = MipiCsiRegisterCntlr(&g_mipiCsi, device); // 【必要】调用核心层函数和g_mipiTx初始化核心层全局变量
if (ret != HDF_SUCCESS) { if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: [MipiCsiRegisterCntlr] failed!", __func__); HDF_LOGE("%s: [MipiCsiRegisterCntlr] failed!", __func__);
return ret; return ret;
} }
ret = MipiRxDrvInit(); //【必要】厂商对设备的初始化,形式不限 ret = MipiRxDrvInit(); // 【必要】厂商对设备的初始化,形式不限
if (ret != HDF_SUCCESS) { if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: [MipiRxDrvInit] failed.", __func__); HDF_LOGE("%s: [MipiRxDrvInit] failed.", __func__);
return ret; return ret;
...@@ -254,19 +254,19 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、 ...@@ -254,19 +254,19 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
return ret; return ret;
} }
//mipi_dsi_core.c核心层 // mipi_dsi_core.c核心层
int32_t MipiCsiRegisterCntlr(struct MipiCsiCntlr *cntlr, struct HdfDeviceObject *device) int32_t MipiCsiRegisterCntlr(struct MipiCsiCntlr *cntlr, struct HdfDeviceObject *device)
{ {
... ...
//定义的全局变量:static struct MipiCsiHandle g_mipiCsihandle[MAX_CNTLR_CNT]; // 定义的全局变量:static struct MipiCsiHandle g_mipiCsihandle[MAX_CNTLR_CNT];
if (g_mipiCsihandle[cntlr->devNo].cntlr == NULL) { if (g_mipiCsihandle[cntlr->devNo].cntlr == NULL) {
(void)OsalMutexInit(&g_mipiCsihandle[cntlr->devNo].lock); (void)OsalMutexInit(&g_mipiCsihandle[cntlr->devNo].lock);
(void)OsalMutexInit(&(cntlr->lock)); (void)OsalMutexInit(&(cntlr->lock));
g_mipiCsihandle[cntlr->devNo].cntlr = cntlr; //初始化MipiCsiHandle成员 g_mipiCsihandle[cntlr->devNo].cntlr = cntlr; // 初始化MipiCsiHandle成员
g_mipiCsihandle[cntlr->devNo].priv = NULL; g_mipiCsihandle[cntlr->devNo].priv = NULL;
cntlr->device = device; //使HdfDeviceObject与MipiCsiHandle可以相互转化的前提 cntlr->device = device; // 使HdfDeviceObject与MipiCsiHandle可以相互转化的前提
device->service = &(cntlr->service); //使HdfDeviceObject与MipiCsiHandle可以相互转化的前提 device->service = &(cntlr->service); // 使HdfDeviceObject与MipiCsiHandle可以相互转化的前提
cntlr->priv = NULL; cntlr->priv = NULL;
HDF_LOGI("%s: success.", __func__); HDF_LOGI("%s: success.", __func__);
...@@ -294,16 +294,16 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、 ...@@ -294,16 +294,16 @@ MIPI CSI模块适配的三个环节是配置属性文件、实例化驱动入、
{ {
struct MipiCsiCntlr *cntlr = NULL; struct MipiCsiCntlr *cntlr = NULL;
... ...
cntlr = MipiCsiCntlrFromDevice(device); //这里有HdfDeviceObject到MipiCsiCntlr的强制转化 cntlr = MipiCsiCntlrFromDevice(device); // 这里有HdfDeviceObject到MipiCsiCntlr的强制转化
//return (device == NULL) ? NULL : (struct MipiCsiCntlr *)device->service; // return (device == NULL) ? NULL : (struct MipiCsiCntlr *)device->service;
... ...
OsalSpinDestroy(&cntlr->ctxLock); OsalSpinDestroy(&cntlr->ctxLock);
#ifdef MIPICSI_VFS_SUPPORT #ifdef MIPICSI_VFS_SUPPORT
MipiCsiDevModuleExit(cntlr->devNo); MipiCsiDevModuleExit(cntlr->devNo);
#endif #endif
MipiRxDrvExit(); //【必要】对厂商设备所占资源的释放 MipiRxDrvExit(); // 【必要】对厂商设备所占资源的释放
MipiCsiUnregisterCntlr(&g_mipiCsi); //空函数 MipiCsiUnregisterCntlr(&g_mipiCsi); // 空函数
g_mipiCsi.priv = NULL; g_mipiCsi.priv = NULL;
HDF_LOGI("%s: unload mipi csi driver success!", __func__); HDF_LOGI("%s: unload mipi csi driver success!", __func__);
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
## 概述 ## 概述
- DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface (MIPI) Alliance)制定的规范,旨在降低移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设(通常是LCD或者类似的显示设备),或从外设中读取状态信息或像素信息;它定义了主机、图像数据源和目标设备之间的串行总线和通信协议。 DSI(Display Serial Interface)是由移动行业处理器接口联盟(Mobile Industry Processor Interface (MIPI) Alliance)制定的规范,旨在降低移动设备中显示控制器的成本。它以串行的方式发送像素数据或指令给外设(通常是LCD或者类似的显示设备),或从外设中读取状态信息或像素信息;它定义了主机、图像数据源和目标设备之间的串行总线和通信协议。
- MIPI DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,从属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。 MIPI DSI具备高速模式和低速模式两种工作模式,全部数据通道都可以用于单向的高速传输,但只有第一个数据通道才可用于低速双向传输,从属端的状态信息、像素等是通过该数据通道返回。时钟通道专用于在高速传输数据的过程中传输同步时钟信号。
- 图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。主要区别在于,DSI对所有像素数据、命令和事件进行序列化,而在传统接口中,这些像素数据、命令和事件通常需要附加控制信号才能在并行数据总线上传输。 图1显示了简化的DSI接口。从概念上看,符合DSI的接口与基于DBI-2和DPI-2标准的接口具有相同的功能。它向外围设备传输像素或命令数据,并且可以从外围设备读取状态或像素信息。主要区别在于,DSI对所有像素数据、命令和事件进行序列化,而在传统接口中,这些像素数据、命令和事件通常需要附加控制信号才能在并行数据总线上传输。
**图1** DSI发送、接收接口 **图1** DSI发送、接收接口
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
| 设置MIPI&nbsp;DSI进入Low&nbsp;power模式/High&nbsp;speed模式 | -&nbsp;MipiDsiSetLpMode:设置MIPI&nbsp;DSI进入Low&nbsp;power模式<br/>-&nbsp;MipiDsiSetHsMode:设置MIPI&nbsp;DSI进入High&nbsp;speed模式 | | 设置MIPI&nbsp;DSI进入Low&nbsp;power模式/High&nbsp;speed模式 | -&nbsp;MipiDsiSetLpMode:设置MIPI&nbsp;DSI进入Low&nbsp;power模式<br/>-&nbsp;MipiDsiSetHsMode:设置MIPI&nbsp;DSI进入High&nbsp;speed模式 |
| MIPI&nbsp;DSI发送/回读指令 | -&nbsp;MipiDsiTx:MIPI&nbsp;DSI发送相应指令的接口<br/>-&nbsp;MipiDsiRx:MIPI&nbsp;DSI按期望长度回读的接口 | | MIPI&nbsp;DSI发送/回读指令 | -&nbsp;MipiDsiTx:MIPI&nbsp;DSI发送相应指令的接口<br/>-&nbsp;MipiDsiRx:MIPI&nbsp;DSI按期望长度回读的接口 |
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>
> 本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 > 本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。
......
...@@ -22,10 +22,10 @@ struct MipiDsiCntlrMethod { // 核心层结构体的成员函数 ...@@ -22,10 +22,10 @@ struct MipiDsiCntlrMethod { // 核心层结构体的成员函数
int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out); int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
void (*toHs)(struct MipiDsiCntlr *cntlr); void (*toHs)(struct MipiDsiCntlr *cntlr);
void (*toLp)(struct MipiDsiCntlr *cntlr); void (*toLp)(struct MipiDsiCntlr *cntlr);
void (*enterUlps)(struct MipiDsiCntlr *cntlr);//【可选】进入超低功耗模式 void (*enterUlps)(struct MipiDsiCntlr *cntlr);// 【可选】进入超低功耗模式
void (*exitUlps)(struct MipiDsiCntlr *cntlr); //【可选】退出超低功耗模式 void (*exitUlps)(struct MipiDsiCntlr *cntlr); // 【可选】退出超低功耗模式
int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);//【可选】使能/去使能功耗控制 int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);//【可选】使能/去使能功耗控制
int32_t (*attach)(struct MipiDsiCntlr *cntlr);//【可选】将一个DSI设备连接上host int32_t (*attach)(struct MipiDsiCntlr *cntlr);// 【可选】将一个DSI设备连接上host
}; };
``` ```
...@@ -33,11 +33,11 @@ struct MipiDsiCntlrMethod { // 核心层结构体的成员函数 ...@@ -33,11 +33,11 @@ struct MipiDsiCntlrMethod { // 核心层结构体的成员函数
| 成员函数 | 入参 | 出参 | 返回状态 | 功能 | | 成员函数 | 入参 | 出参 | 返回状态 | 功能 |
| -------- | -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- | -------- |
| setCntlrCfg | cntlr:结构体指针,MipiDsi控制器&nbsp; | 无 | HDF_STATUS相关状态 | 设置控制器参数 | | setCntlrCfg | cntlr:结构体指针,MipiDsi控制器 | 无 | HDF_STATUS相关状态 | 设置控制器参数 |
| setCmd | cntlr:结构体指针,MipiDsi控制器<br>cmd:结构体指针,指令传入值; | 无 | HDF_STATUS相关状态 | 向显示设备发送指令 | | setCmd | cntlr:结构体指针,MipiDsi控制器<br>cmd:结构体指针,指令传入值 | 无 | HDF_STATUS相关状态 | 向显示设备发送指令 |
| getCmd | cntlr:结构体指针,MipiDsi控制器<br>cmd:传入的命令描述结构体指针;<br>readLen:读取的数据大小; | out:结构体指针,用于存储读取的数据。 | HDF_STATUS相关状态 | 通过发送指令读取数据 | | getCmd | cntlr:结构体指针,MipiDsi控制器<br>cmd:传入的命令描述结构体指针<br>readLen:读取的数据大小 | out:结构体指针,用于存储读取的数据 | HDF_STATUS相关状态 | 通过发送指令读取数据 |
| toHs | cntlr:&nbsp;结构体指针,MipiDsi控制器&nbsp;; | 无 | HDF_STATUS相关状态 | 设置为高速模式 | | toHs | cntlr:结构体指针,MipiDsi控制器 | 无 | HDF_STATUS相关状态 | 设置为高速模式 |
| toLp | cntlr:&nbsp;结构体指针,MipiDsi控制器&nbsp;; | 无 | HDF_STATUS相关状态 | 设置为低电模式 | | toLp | cntlr:结构体指针,MipiDsi控制器 | 无 | HDF_STATUS相关状态 | 设置为低电模式 |
## 开发步骤 ## 开发步骤
...@@ -55,7 +55,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -55,7 +55,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
3. **实例化MIPIDSI控制器对象:** 3. **实例化MIPIDSI控制器对象:**
- 初始化MipiDsiCntlr成员。 - 初始化MipiDsiCntlr成员。
- 实例化MipiDsiCntlr成员MipiDsiCntlrMethod。 - 实例化MipiDsiCntlr成员MipiDsiCntlrMethod。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>
> 实例化MipiDsiCntlr成员MipiDsiCntlrMethod,其定义和成员说明见[接口说明](#接口说明)。 > 实例化MipiDsiCntlr成员MipiDsiCntlrMethod,其定义和成员说明见[接口说明](#接口说明)。
4. **驱动调试:** 4. **驱动调试:**
...@@ -66,7 +66,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -66,7 +66,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
下方将以mipi_tx_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。 下方将以mipi_tx_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。
1. 一般来说,驱动开发首先需要在 xx_config.hcs 中配置器件属性,并在device_info.hcs文件中添加deviceNode描述。器件属性值与核心层MipiDsiCntlr 成员的默认值或限制范围有密切关系,deviceNode信息与驱动入口注册相关。 1. 一般来说,驱动开发首先需要在xx_config.hcs中配置器件属性,并在device_info.hcs文件中添加deviceNode描述。器件属性值与核心层MipiDsiCntlr成员的默认值或限制范围有密切关系,deviceNode信息与驱动入口注册相关。
但本例中MIPI控制器无需配置额外属性,如有厂商需要,则需要在device_info文件的deviceNode增加deviceMatchAttr信息,以及增加mipidsi_config文件。 但本例中MIPI控制器无需配置额外属性,如有厂商需要,则需要在device_info文件的deviceNode增加deviceMatchAttr信息,以及增加mipidsi_config文件。
...@@ -84,7 +84,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -84,7 +84,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
policy = 0; policy = 0;
priority = 150; priority = 150;
permission = 0644; permission = 0644;
moduleName = "HDF_MIPI_TX"; //【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致; moduleName = "HDF_MIPI_TX"; // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致
serviceName = "HDF_MIPI_TX"; // 【必要且唯一】驱动对外发布服务的名称 serviceName = "HDF_MIPI_TX"; // 【必要且唯一】驱动对外发布服务的名称
} }
} }
...@@ -96,20 +96,20 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -96,20 +96,20 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
2. 完成器件属性文件的配置之后,下一步请实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf_device_desc.h 中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HdfDriverEntry结构体的函数指针成员会被厂商操作函数填充,HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组,方便调用。 2. 完成器件属性文件的配置之后,下一步请实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf_device_desc.h 中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HdfDriverEntry结构体的函数指针成员会被厂商操作函数填充,HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组,方便调用。
一般在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 一般在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
- MIPI DSI驱动入口参考 - MIPI DSI驱动入口参考
``` ```
struct HdfDriverEntry g_mipiTxDriverEntry = { struct HdfDriverEntry g_mipiTxDriverEntry = {
.moduleVersion = 1, .moduleVersion = 1,
.Init = Hi35xxMipiTxInit, //见Init参考 .Init = Hi35xxMipiTxInit, // 见Init参考
.Release = Hi35xxMipiTxRelease,//见Release参考 .Release = Hi35xxMipiTxRelease,// 见Release参考
.moduleName = "HDF_MIPI_TX", //【必要】需要与device_info.hcs 中保持一致。 .moduleName = "HDF_MIPI_TX", // 【必要】需要与device_info.hcs 中保持一致。
}; };
HDF_INIT(g_mipiTxDriverEntry); //调用HDF_INIT将驱动入口注册到HDF框架中 HDF_INIT(g_mipiTxDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中
``` ```
3. 完成驱动入口注册之后,最后一步就是以核心层MipiDsiCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化MipiDsiCntlr成员MipiDsiCntlrMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。 3. 完成驱动入口注册之后,最后一步就是以核心层MipiDsiCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化MipiDsiCntlr成员MipiDsiCntlrMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。
- 自定义结构体参考 - 自定义结构体参考
从驱动的角度看,自定义结构体是参数和数据的载体,一般来说,config文件中的数值也会用来初始化结构体成员,但本例的mipidsi无器件属性文件,故基本成员结构与MipiDsiCntlr无太大差异。 从驱动的角度看,自定义结构体是参数和数据的载体,一般来说,config文件中的数值也会用来初始化结构体成员,但本例的mipidsi无器件属性文件,故基本成员结构与MipiDsiCntlr无太大差异。
...@@ -120,10 +120,10 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -120,10 +120,10 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
short laneId[LANE_MAX_NUM]; // lane号 short laneId[LANE_MAX_NUM]; // lane号
OutPutModeTag outputMode; // 输出模式选择:刷新模式,命令行模式和视频流模式 OutPutModeTag outputMode; // 输出模式选择:刷新模式,命令行模式和视频流模式
VideoModeTag videoMode; // 显示设备的同步模式 VideoModeTag videoMode; // 显示设备的同步模式
OutputFormatTag outputFormat; // 输出DSI图像数据格式:RGB or YUV OutputFormatTag outputFormat; // 输出DSI图像数据格式:RGB或YUV
SyncInfoTag syncInfo; // 时序相关的设置 SyncInfoTag syncInfo; // 时序相关的设置
unsigned int phyDataRate; // mbps unsigned int phyDataRate; // 数率:mbps
unsigned int pixelClk; // KHz unsigned int pixelClk; // 时钟:KHz
} ComboDevCfgTag; } ComboDevCfgTag;
// MipiDsiCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值 // MipiDsiCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值
...@@ -153,7 +153,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -153,7 +153,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
入参: 入参:
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 HdfDeviceObject是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值: 返回值:
...@@ -178,29 +178,29 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -178,29 +178,29 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device) static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device)
{ {
int32_t ret; int32_t ret;
g_mipiTx.priv = NULL; //g_mipiTx是定义的全局变量 g_mipiTx.priv = NULL; // g_mipiTx是定义的全局变量
//static struct MipiDsiCntlr g_mipiTx { // static struct MipiDsiCntlr g_mipiTx {
// .devNo=0 // .devNo=0
//}; //};
g_mipiTx.ops = &g_method;//MipiDsiCntlrMethod的实例化对象的挂载 g_mipiTx.ops = &g_method;// MipiDsiCntlrMethod的实例化对象的挂载
ret = MipiDsiRegisterCntlr(&g_mipiTx, device);//【必要】调用核心层函数和g_mipiTx初始化核心层全局变量 ret = MipiDsiRegisterCntlr(&g_mipiTx, device);// 【必要】调用核心层函数和g_mipiTx初始化核心层全局变量
... ...
return MipiTxDrvInit(0); //【必要】厂商对设备的初始化,形式不限 return MipiTxDrvInit(0); // 【必要】厂商对设备的初始化,形式不限
} }
//mipi_dsi_core.c核心层 // mipi_dsi_core.c核心层
int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device) int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device)
{ {
... ...
//定义的全局变量:static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT]; // 定义的全局变量:static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT];
if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) { if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) {
(void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock); (void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock);
(void)OsalMutexInit(&(cntlr->lock)); (void)OsalMutexInit(&(cntlr->lock));
g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;//初始化MipiDsiHandle成员 g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;// 初始化MipiDsiHandle成员
g_mipiDsihandle[cntlr->devNo].priv = NULL; g_mipiDsihandle[cntlr->devNo].priv = NULL;
cntlr->device = device; //使HdfDeviceObject与MipiDsiHandle可以相互转化的前提 cntlr->device = device; // 使HdfDeviceObject与MipiDsiHandle可以相互转化的前提
device->service = &(cntlr->service); //使HdfDeviceObject与MipiDsiHandle可以相互转化的前提 device->service = &(cntlr->service); // 使HdfDeviceObject与MipiDsiHandle可以相互转化的前提
cntlr->priv = NULL; cntlr->priv = NULL;
... ...
return HDF_SUCCESS; return HDF_SUCCESS;
...@@ -213,7 +213,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -213,7 +213,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
入参: 入参:
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 HdfDeviceObject是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值: 返回值:
...@@ -221,7 +221,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -221,7 +221,7 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
函数说明: 函数说明:
该函数需要在驱动入口结构体中赋值给 Release 接口, 当 HDF 框架调用 Init 函数初始化驱动失败时,可以调用 Release 释放驱动资源, 该函数中需包含释放内存和删除控制器等操作。所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。 该函数需要在驱动入口结构体中赋值给Release接口,当DF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源,该函数中需包含释放内存和删除控制器等操作。所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。
``` ```
...@@ -229,11 +229,11 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口 ...@@ -229,11 +229,11 @@ MIPI DSI模块适配的三个环节是配置属性文件,实例化驱动入口
{ {
struct MipiDsiCntlr *cntlr = NULL; struct MipiDsiCntlr *cntlr = NULL;
... ...
cntlr = MipiDsiCntlrFromDevice(device);//这里有HdfDeviceObject到MipiDsiCntlr的强制转化 cntlr = MipiDsiCntlrFromDevice(device);// 这里有HdfDeviceObject到MipiDsiCntlr的强制转化
//return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service; // return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service;
... ...
MipiTxDrvExit(); //【必要】对厂商设备所占资源的释放 MipiTxDrvExit(); // 【必要】对厂商设备所占资源的释放
MipiDsiUnregisterCntlr(&g_mipiTx); //空函数 MipiDsiUnregisterCntlr(&g_mipiTx); // 空函数
g_mipiTx.priv = NULL; g_mipiTx.priv = NULL;
HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__); HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__);
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## 概述 ## 概述
MMC(MultiMedia Card),即多媒体卡,在HDF框架中,MMC的接口适配模式采用独立服务模式,在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 MMC(MultiMedia Card)即多媒体卡。在HDF框架中,MMC的接口适配模式采用独立服务模式。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。
**图1** MMC独立服务模式结构图 **图1** MMC独立服务模式结构图
...@@ -39,21 +39,21 @@ struct MmcCntlrOps { ...@@ -39,21 +39,21 @@ struct MmcCntlrOps {
| 成员函数 | 入参 | 返回值 | 功能 | | 成员函数 | 入参 | 返回值 | 功能 |
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| doRequest | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;cmd:&nbsp;结构体指针,传入命令值 | HDF_STATUS相关状态 | request相应处理 | | doRequest | cntlr:核心层结构体指针,MMC控制器<br>cmd:结构体指针,传入命令值 | HDF_STATUS相关状态 | request相应处理 |
| setClock | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;clock:&nbsp;时钟传入值 | HDF_STATUS相关状态 | 设置时钟频率 | | setClock | cntlr:核心层结构体指针,MMC控制器<br>clock:时钟传入值 | HDF_STATUS相关状态 | 设置时钟频率 |
| setPowerMode | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;mode:&nbsp;枚举值(见MmcPowerMode定义),功耗模式 | HDF_STATUS相关状态 | 设置功耗模式 | | setPowerMode | cntlr:核心层结构体指针,MMC控制器<br>mode:枚举值(见MmcPowerMode定义),功耗模式 | HDF_STATUS相关状态 | 设置功耗模式 |
| setBusWidth | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;width:&nbsp;枚举值(见MmcBusWidth定义),总线带宽 | HDF_STATUS相关状态 | 设置总线带宽 | | setBusWidth | cntlr:核心层结构体指针,MMC控制器<br>width:枚举值(见MmcBusWidth定义),总线带宽 | HDF_STATUS相关状态 | 设置总线带宽 |
| setBusTiming | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;timing:&nbsp;枚举值(见MmcBusTiming定义),总线时序 | HDF_STATUS相关状态 | 设置总线时序 | | setBusTiming | cntlr:核心层结构体指针,MMC控制器<br>timing:枚举值(见MmcBusTiming定义),总线时序 | HDF_STATUS相关状态 | 设置总线时序 |
| setSdioIrq | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;enable:&nbsp;布尔值,控制中断 | HDF_STATUS相关状态 | 使能/去使能SDIO中断 | | setSdioIrq | cntlr:核心层结构体指针,MMC控制器<br>enable:布尔值,控制中断 | HDF_STATUS相关状态 | 使能/去使能SDIO中断 |
| hardwareReset | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | HDF_STATUS相关状态 | 复位硬件 | | hardwareReset | cntlr:核心层结构体指针,MMC控制器 | HDF_STATUS相关状态 | 复位硬件 |
| systemInit | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | HDF_STATUS相关状态 | 系统初始化 | | systemInit | cntlr:核心层结构体指针,MMC控制器 | HDF_STATUS相关状态 | 系统初始化 |
| setEnhanceSrobe | cntlr:&nbsp;核心层结构体指针,mmc控制器&nbsp;;enable:&nbsp;布尔值,设置功能 | HDF_STATUS相关状态 | 设置增强选通 | | setEnhanceSrobe | cntlr:核心层结构体指针,MMC控制器<br>enable:布尔值,设置功能 | HDF_STATUS相关状态 | 设置增强选通 |
| switchVoltage | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;volt:&nbsp;枚举值,电压值(3.3,1.8,1.2V); | HDF_STATUS相关状态 | 设置电压值 | | switchVoltage | cntlr:核心层结构体指针,MMC控制器<br>volt:枚举值,电压值(3.3,1.8,1.2V) | HDF_STATUS相关状态 | 设置电压值 |
| devReadOnly | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | 布尔值 | 检验设备是否只读 | | devReadOnly | cntlr:核心层结构体指针,MMC控制器 | 布尔值 | 检验设备是否只读 |
| cardPluged | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | 布尔值 | 检验设备是否拔出 | | cardPluged | cntlr:核心层结构体指针,MMC控制器 | 布尔值 | 检验设备是否拔出 |
| devBusy | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | 布尔值 | 检验设备是否忙碌 | | devBusy | cntlr:核心层结构体指针,MMC控制器 | 布尔值 | 检验设备是否忙碌 |
| tune | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;;cmdCode:&nbsp;uint32_t,命令代码; | HDF_STATUS相关状态 | 调谐 | | tune | cntlr:核心层结构体指针,MMC控制器<br>cmdCode:uint32_t,命令代码 | HDF_STATUS相关状态 | 调谐 |
| rescanSdioDev | cntlr:&nbsp;核心层结构体指针;mmc控制器&nbsp;; | HDF_STATUS相关状态 | 扫描并添加SDIO设备 | | rescanSdioDev | cntlr:核心层结构体指针,MMC控制器 | HDF_STATUS相关状态 | 扫描并添加SDIO设备 |
## 开发步骤 ## 开发步骤
...@@ -71,7 +71,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -71,7 +71,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
3. **实例化MMC控制器对象:** 3. **实例化MMC控制器对象:**
- 初始化MmcCntlr成员。 - 初始化MmcCntlr成员。
- 实例化MmcCntlr成员MmcCntlrOps。 - 实例化MmcCntlr成员MmcCntlrOps。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**<br>
> 实例化MmcCntlr成员MmcCntlrOps,其定义和成员说明见[接口说明](#接口说明)。 > 实例化MmcCntlr成员MmcCntlrOps,其定义和成员说明见[接口说明](#接口说明)。
4. **驱动调试:** 4. **驱动调试:**
...@@ -91,17 +91,17 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -91,17 +91,17 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
``` ```
struct HdfDriverEntry g_mmcDriverEntry = { struct HdfDriverEntry g_mmcDriverEntry = {
.moduleVersion = 1, .moduleVersion = 1,
.Bind = HimciMmcBind, //见Bind参考 .Bind = HimciMmcBind, // 见Bind参考
.Init = HimciMmcInit, //见Init参考 .Init = HimciMmcInit, // 见Init参考
.Release = HimciMmcRelease, //见Release参考 .Release = HimciMmcRelease, // 见Release参考
.moduleName = "hi3516_mmc_driver",//【必要且与HCS文件中里面的moduleName匹配】 .moduleName = "hi3516_mmc_driver",// 【必要且与HCS文件中里面的moduleName匹配】
}; };
HDF_INIT(g_mmcDriverEntry); //调用HDF_INIT将驱动入口注册到HDF框架中 HDF_INIT(g_mmcDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中
``` ```
2. 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在mmc_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值与核心层MmcCntlr成员的默认值或限制范围有密切关系。 2. 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在mmc_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值与核心层MmcCntlr成员的默认值或限制范围有密切关系。
如有多个器件信息,则需要在device_info文件增加deviceNode信息,以及在mmc_config文件中增加对应的器件属性**。** 如有多个器件信息,则需要在device_info文件增加deviceNode信息,以及在mmc_config文件中增加对应的器件属性**。**
- device_info.hcs 配置参考 - device_info.hcs 配置参考
``` ```
...@@ -116,9 +116,9 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -116,9 +116,9 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
policy = 2; policy = 2;
priority = 10; priority = 10;
permission = 0644; permission = 0644;
moduleName = "hi3516_mmc_driver"; //【必要】用于指定驱动名称,需要与驱动Entry中的moduleName一致; moduleName = "hi3516_mmc_driver"; // 【必要】用于指定驱动名称,需要与驱动Entry中的moduleName一致;
serviceName = "HDF_PLATFORM_MMC_0"; //【必要】驱动对外发布服务的名称,必须唯一 serviceName = "HDF_PLATFORM_MMC_0"; // 【必要】驱动对外发布服务的名称,必须唯一
deviceMatchAttr = "hi3516_mmc_emmc";//【必要】用于配置控制器私有数据,要与 mmc_config.hcs 中对应控制器保持一致 deviceMatchAttr = "hi3516_mmc_emmc";// 【必要】用于配置控制器私有数据,要与 mmc_config.hcs 中对应控制器保持一致
} }
device1 :: deviceNode { device1 :: deviceNode {
policy = 1; policy = 1;
...@@ -126,7 +126,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -126,7 +126,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
permission = 0644; permission = 0644;
moduleName = "hi3516_mmc_driver"; moduleName = "hi3516_mmc_driver";
serviceName = "HDF_PLATFORM_MMC_1"; serviceName = "HDF_PLATFORM_MMC_1";
deviceMatchAttr = "hi3516_mmc_sd"; //SD类型 deviceMatchAttr = "hi3516_mmc_sd"; // SD类型
} }
device2 :: deviceNode { device2 :: deviceNode {
policy = 1; policy = 1;
...@@ -134,7 +134,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -134,7 +134,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
permission = 0644; permission = 0644;
moduleName = "hi3516_mmc_driver"; moduleName = "hi3516_mmc_driver";
serviceName = "HDF_PLATFORM_MMC_2"; serviceName = "HDF_PLATFORM_MMC_2";
deviceMatchAttr = "hi3516_mmc_sdio";//SDIO类型 deviceMatchAttr = "hi3516_mmc_sdio";// SDIO类型
} }
} }
} }
...@@ -142,32 +142,32 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -142,32 +142,32 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
} }
``` ```
- mmc_config.hcs 配置参考。 - mmc_config.hcs配置参考
``` ```
root { root {
platform { platform {
mmc_config { mmc_config {
template mmc_controller {//模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省 template mmc_controller {// 模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省
match_attr = ""; match_attr = "";
voltDef = 0; // 3.3V voltDef = 0; // 3.3V
freqMin = 50000; //【必要】最小频率值 freqMin = 50000; // 【必要】最小频率值
freqMax = 100000000; //【必要】最大频率值 freqMax = 100000000; // 【必要】最大频率值
freqDef = 400000; //【必要】默认频率值 freqDef = 400000; // 【必要】默认频率值
maxBlkNum = 2048; //【必要】最大的block号 maxBlkNum = 2048; // 【必要】最大的block号
maxBlkSize = 512; //【必要】最大的block个数 maxBlkSize = 512; // 【必要】最大的block个数
ocrDef = 0x300000; //【必要】工作电压设置相关 ocrDef = 0x300000; // 【必要】工作电压设置相关
caps2 = 0; //【必要】属性寄存器相关,见mmc_caps.h 中 MmcCaps2 定义 caps2 = 0; // 【必要】属性寄存器相关,见mmc_caps.h中MmcCaps2定义
regSize = 0x118; //【必要】寄存器位宽 regSize = 0x118; // 【必要】寄存器位宽
hostId = 0; //【必要】主机号 hostId = 0; // 【必要】主机号
regBasePhy = 0x10020000;//【必要】寄存器物理基地址 regBasePhy = 0x10020000;// 【必要】寄存器物理基地址
irqNum = 63; //【必要】中断号 irqNum = 63; // 【必要】中断号
devType = 2; //【必要】模式选择:emmc, SD, SDIO ,COMBO devType = 2; // 【必要】模式选择:emmc, SD, SDIO ,COMBO
caps = 0x0001e045; //【必要】属性寄存器相关,见mmc_caps.h 中 MmcCaps 定义 caps = 0x0001e045; // 【必要】属性寄存器相关,见mmc_caps.h 中 MmcCaps 定义
} }
controller_0x10100000 :: mmc_controller { controller_0x10100000 :: mmc_controller {
match_attr = "hi3516_mmc_emmc";//【必要】需要和device_info.hcs中的deviceMatchAttr值一致 match_attr = "hi3516_mmc_emmc";// 【必要】需要和device_info.hcs中的deviceMatchAttr值一致
hostId = 0; hostId = 0;
regBasePhy = 0x10100000; regBasePhy = 0x10100000;
irqNum = 96; irqNum = 96;
...@@ -180,7 +180,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -180,7 +180,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
hostId = 1; hostId = 1;
regBasePhy = 0x100f0000; regBasePhy = 0x100f0000;
irqNum = 62; irqNum = 62;
devType = 1; // sd类型 devType = 1; // SD类型
caps = 0xd001e005; caps = 0xd001e005;
} }
controller_0x10020000 :: mmc_controller { controller_0x10020000 :: mmc_controller {
...@@ -188,7 +188,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -188,7 +188,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
hostId = 2; hostId = 2;
regBasePhy = 0x10020000; regBasePhy = 0x10020000;
irqNum = 63; irqNum = 63;
devType = 2; // sdio类型 devType = 2; // SDIO类型
caps = 0x0001e04d; caps = 0x0001e04d;
} }
} }
...@@ -197,16 +197,16 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -197,16 +197,16 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
``` ```
3. 完成驱动入口注册之后,最后一步就是以核心层MmcCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化MmcCntlr成员MmcCntlrOps(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。 3. 完成驱动入口注册之后,最后一步就是以核心层MmcCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化MmcCntlr成员MmcCntlrOps(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。
- 自定义结构体参考 - 自定义结构体参考
从驱动的角度看,自定义结构体是参数和数据的载体,而且mmc_config.hcs文件中的数值会被HDF读入通过DeviceResourceIface来初始化结构体成员 ,一些重要数值也会传递给核心层对象。 从驱动的角度看,自定义结构体是参数和数据的载体,而且mmc_config.hcs文件中的数值会被HDF读入通过DeviceResourceIface来初始化结构体成员 ,一些重要数值也会传递给核心层对象。
``` ```
struct HimciHost { struct HimciHost {
struct MmcCntlr *mmc;//【必要】核心层结构体 struct MmcCntlr *mmc;// 【必要】核心层结构体
struct MmcCmd *cmd; //【必要】核心层结构体,传递命令的,相关命令见枚举量 MmcCmdCode struct MmcCmd *cmd; // 【必要】核心层结构体,传递命令的,相关命令见枚举量 MmcCmdCode
//【可选】根据厂商驱动需要添加 // 【可选】根据厂商驱动需要添加
void *base; void *base;
enum HimciPowerStatus powerStatus; enum HimciPowerStatus powerStatus;
uint8_t *alignedBuff; uint8_t *alignedBuff;
...@@ -223,7 +223,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -223,7 +223,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
bool waitForEvent; bool waitForEvent;
HIMCI_EVENT himciEvent; HIMCI_EVENT himciEvent;
}; };
//MmcCntlr是核心层控制器结构体,其中的成员在bind函数中会被赋值 // MmcCntlr是核心层控制器结构体,其中的成员在bind函数中会被赋值
struct MmcCntlr { struct MmcCntlr {
struct IDeviceIoService service; struct IDeviceIoService service;
struct HdfDeviceObject *hdfDevObj; struct HdfDeviceObject *hdfDevObj;
...@@ -278,11 +278,11 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -278,11 +278,11 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
入参**:** 入参**:**
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 HdfDeviceObject是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值: 返回值:
HDF_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)。 HDF_STATUS相关状态(下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)。
| 状态(值) | 问题描述 | | 状态(值) | 问题描述 |
| -------- | -------- | | -------- | -------- |
...@@ -307,20 +307,20 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -307,20 +307,20 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr)); cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));
host = (struct HimciHost *)OsalMemCalloc(sizeof(struct HimciHost)); host = (struct HimciHost *)OsalMemCalloc(sizeof(struct HimciHost));
host->mmc = cntlr; //【必要】使HimciHost与MmcCntlr可以相互转化的前提 host->mmc = cntlr; // 【必要】使HimciHost与MmcCntlr可以相互转化的前提
cntlr->priv = (void *)host; //【必要】使HimciHost与MmcCntlr可以相互转化的前提 cntlr->priv = (void *)host; // 【必要】使HimciHost与MmcCntlr可以相互转化的前提
cntlr->ops = &g_himciHostOps; //【必要】MmcCntlrOps的实例化对象的挂载 cntlr->ops = &g_himciHostOps; // 【必要】MmcCntlrOps的实例化对象的挂载
cntlr->hdfDevObj = obj; //【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提 cntlr->hdfDevObj = obj; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提
obj->service = &cntlr->service; //【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提 obj->service = &cntlr->service; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提
ret = MmcCntlrParse(cntlr, obj); //【必要】 初始化 cntlr. 失败就 goto _ERR; ret = MmcCntlrParse(cntlr, obj); // 【必要】 初始化 cntlr,失败就goto _ERR;
... ...
ret = HimciHostParse(host, obj); //【必要】 初始化 host对象的相关属性,失败就 goto _ERR; ret = HimciHostParse(host, obj); // 【必要】 初始化host对象的相关属性,失败就goto _ERR;
... ...
ret = HimciHostInit(host, cntlr);//厂商自定义的初始化,失败就 goto _ERR; ret = HimciHostInit(host, cntlr);// 厂商自定义的初始化,失败就 goto _ERR;
... ...
ret = MmcCntlrAdd(cntlr); //调用核心层函数 失败就 goto _ERR; ret = MmcCntlrAdd(cntlr); // 调用核心层函数 失败就goto _ERR;
... ...
(void)MmcCntlrAddDetectMsgToQueue(cntlr);//将卡检测消息添加到队列中。 (void)MmcCntlrAddDetectMsgToQueue(cntlr);// 将卡检测消息添加到队列中。
HDF_LOGD("HimciMmcBind: success."); HDF_LOGD("HimciMmcBind: success.");
return HDF_SUCCESS; return HDF_SUCCESS;
_ERR: _ERR:
...@@ -334,7 +334,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -334,7 +334,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
入参: 入参:
HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。 HdfDeviceObject是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值: 返回值:
...@@ -364,7 +364,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -364,7 +364,7 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
入参: 入参:
HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。 HdfDeviceObject 是整个驱动对外暴露的接口参数,具备hcs配置文件的信息。
返回值: 返回值:
...@@ -380,8 +380,8 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口, ...@@ -380,8 +380,8 @@ MMC模块适配的三个环节是配置属性文件,实例化驱动入口,
{ {
struct MmcCntlr *cntlr = NULL; struct MmcCntlr *cntlr = NULL;
... ...
cntlr = (struct MmcCntlr *)obj->service;//这里有HdfDeviceObject到MmcCntlr的强制转化,通过service成员,赋值见Bind函数 cntlr = (struct MmcCntlr *)obj->service;// 这里有HdfDeviceObject到MmcCntlr的强制转化,通过service成员,赋值见Bind函数
... ...
HimciDeleteHost((struct HimciHost *)cntlr->priv);//厂商自定义的内存释放函数,这里有MmcCntlr到HimciHost的强制转化 HimciDeleteHost((struct HimciHost *)cntlr->priv);// 厂商自定义的内存释放函数,这里有MmcCntlr到HimciHost的强制转化
} }
``` ```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册