MTK camera image sensor driver

  • Post author:
  • Post category:其他





camera_sensor_driver





image_sensr




首先要进行板极设备的初始化的工作:代码路径是在:




/mediatek/platform/mt6577/kernel/core/mt6577_devs.c




里面





#if1 ///defined(CONFIG_VIDEO_CAPTURE_DRIVERS)





retval =platform_device_register(&sensor_dev);





if (retval != 0){






return retval;





}





sensor_dev




的实现如下:





staticstruct platform_device sensor_dev = {






.name = “image_sensor”,





.id = -1,





};





上面是以




platformbus




方式进行注册设备的,




platformbus









match




的规则是名字相同,所以我们要找到




imagesensor









driver




就要找到以




Platform




方式进行注册,名字是”




image_sensor”




的驱动。





我们下




grepcmd ,




找到了




driver




的路径:




/mediatek/custom/common/kernel/imgsensor/src/kd_sensorlist.c




文件中:





staticstruct platform_driver g_stCAMERA_HW_Driver = {






.probe = CAMERA_HW_probe,





.remove =CAMERA_HW_remove,





.suspend = CAMERA_HW_suspend,





.resume =CAMERA_HW_resume,





.driver = {






.name = “image_sensor”,





.owner = THIS_MODULE,





}





};





发现没有,上面的




name









image_sensor,




看下




driver




在哪里进行注册的?





/*=======================================================================





* CAMERA_HW_i2C_init()





*=======================================================================*/





staticint __init CAMERA_HW_i2C_init(void)





{






struct proc_dir_entry*prEntry;





i2c_register_board_info(CAMERA_I2C_BUSNUM,&kd_camera_dev, 1);//




这里是注册一个




i2c




设备





if(platform_driver_register(&g_stCAMERA_HW_Driver)){//




这里就是我们以




platform




方式注册的驱动函数





PK_ERR(“failed toregister CAMERA_HW driver\n”);





return -ENODEV;





}





//Register proc file forsensor register debug





prEntry =create_proc_entry(“driver/camsensor”, 0,NULL);//




这里是注册




Image_sensor









proc




口,主要用于调试。





if (prEntry) {






prEntry->read_proc =CAMERA_HW_DumpReg_To_Proc;





prEntry->write_proc =CAMERA_HW_Reg_Debug;





}





else {






PK_ERR(“add/proc/driver/camsensor entry fail \n”);





}





atomic_set(&g_CamHWOpend,0);





atomic_set(&g_CamDrvOpenCnt,0);





atomic_set(&g_CamHWOpening,0);





return 0;





}





当我们




platformbus









deivice









drivermatch




成功后,就会调用




drver









probe




函数。





.probe =CAMERA_HW_probe,





staticint CAMERA_HW_probe(struct platform_device *pdev)





{






init_waitqueue_head(&kd_sensor_wait_queue);





returni2c_add_driver(&CAMERA_HW_i2c_driver);//




这里是以




i2c




的方式进行注册




cameradriver




整好和上上面的




i2c




方式注册设备一样。





}





其实




image_sensor









platform




方式注册,只是一个虚拟的方式进行注册的,主要好是以




i2c




方式进行注册的,下面就进入我们的主角,我们的




i2c




方式注册的




driver










platformbus




一样,




i2c




同样有自己的一套匹配方式,他的匹配方式就是匹配




id_table




里面的名字和以




i2c_register_board_info(CAMERA_I2C_BUSNUM,&kd_camera_dev, 1);




方式进行注册到




i2c




上面的设备的名字进行匹配,匹配成功后,同样也会调用对应的




probe




函数:





*I2C Driver structure





********************************************************************************/





structi2c_driver CAMERA_HW_i2c_driver = {





.probe = CAMERA_HW_i2c_probe,





.remove =CAMERA_HW_i2c_remove,





.driver.name =CAMERA_HW_DRVNAME,





.id_table = CAMERA_HW_i2c_id,





};





看下这个




Probe




函数的实现:





staticint CAMERA_HW_i2c_probe(struct i2c_client *client, const structi2c_device_id *id)





{





int i4RetValue = 0;





PK_DBG(“[CAMERA_HW]Attach I2C \n”);







//get sensor i2c client





spin_lock(&kdsensor_drv_lock);





g_pstI2Cclient =client;//




这里是获得我们的




clientdevice




,并且以




platform




方式进行注册





//set I2C clock rate





g_pstI2Cclient->timing =200;//200k





spin_unlock(&kdsensor_drv_lock);





//Register char driver





i4RetValue =RegisterCAMERA_HWCharDrv();





if(i4RetValue){






PK_ERR(“[CAMERA_HW]register char device failed!\n”);//




调用这个函数进行注册




char




类型的设备,下面




trace




下这个函数是如何实现的





return i4RetValue;





}





//spin_lock_init(&g_CamHWLock);





PK_DBG(“[CAMERA_HW]Attached!! \n”);





return 0;





}





trace









registerCAMERA_HWCharDrv




函数的实现:





*RegisterCAMERA_HWCharDrv





********************************************************************************/





inlinestatic int RegisterCAMERA_HWCharDrv(void)





{






struct device* sensor_device =NULL;





#ifCAMERA_HW_DYNAMIC_ALLOCATE_DEVNO





if(alloc_chrdev_region(&g_CAMERA_HWdevno, 0, 1,CAMERA_HW_DRVNAME))//




分配一个字符设备





{






PK_DBG(“[CAMERASENSOR] Allocate device no failed\n”);





return -EAGAIN;





}





#else





if( register_chrdev_region( g_CAMERA_HWdevno , 1 , CAMERA_HW_DRVNAME) )//




注册一个字符设备





{






PK_DBG(“[CAMERASENSOR] Register device no failed\n”);





return -EAGAIN;





}





#endif





//Allocate driver





g_pCAMERA_HW_CharDrv =cdev_alloc();





if(NULL ==g_pCAMERA_HW_CharDrv)





{






unregister_chrdev_region(g_CAMERA_HWdevno,1);





PK_DBG(“[CAMERASENSOR] Allocate mem for kobject failed\n”);





return -ENOMEM;





}





//Attatch file operation.





cdev_init(g_pCAMERA_HW_CharDrv,&g_stCAMERA_HW_fops);//




关联到




file_operation




进入字符设备





g_pCAMERA_HW_CharDrv->owner= THIS_MODULE;





//Add to system





if(cdev_add(g_pCAMERA_HW_CharDrv,g_CAMERA_HWdevno, 1))//




将我们分配的字符设备,




attach









file_operation




添加到




system





{






PK_DBG(“[mt6516_IDP]Attatch file operation failed\n”);





unregister_chrdev_region(g_CAMERA_HWdevno,1);





return -EAGAIN;





}





sensor_class =class_create(THIS_MODULE, “sensordrv”);//




创建一个




sensordrv










if (IS_ERR(sensor_class)) {






int ret =PTR_ERR(sensor_class);





PK_DBG(“Unable tocreate class, err = %d\n”, ret);





return ret;





}





sensor_device =device_create(sensor_class, NULL, g_CAMERA_HWdevno, NULL,CAMERA_HW_DRVNAME);









sensordrv




类里面创建一个




CAMERA_HW_DRVNAME




设备文件。





return 0;





}





上面只是一个虚拟的注册过程,我们还没有真正的到到我们的




image_sensor




设备。





看这个




image_sensor









file_operation




是如何实现的:





staticconst struct file_operations g_stCAMERA_HW_fops =





{






.owner = THIS_MODULE,





.open = CAMERA_HW_Open,





.release = CAMERA_HW_Release,





#ifdef USE_NEW_IOCTL





.unlocked_ioctl =CAMERA_HW_Ioctl





#else





.ioctl = CAMERA_HW_Ioctl





#endif





};





其实我最关注的就是我们手机上面有很多很多的




driver




,代码中是在哪里判断我们使用的是什么




IC




厂商的




imagesensor




。我找了很多代码,在




mediatek




的代码中我并没找到。





上层在操作设备的时候都是先




open




设备,获得文件指针以后就可以进行接下来的事情。





我们先分析




open




函数:





1









.open= CAMERA_HW_Open,






********************************************************************************/








staticint CAMERA_HW_Open

(

struct

inode * a_pstInode,

struct

file * a_pstFile)







{








//











atomic_inc(&g_CamDrvOpenCnt);












return

0;











}






//




open










函数里面没有进行任何的操作,就只是一个锁,防止多个






既然我们的




open




函数里面没有进行别的操作,而我们的




file_operation




里面就只有




open









ioctl




成员函数,所以说我们的任何操作




imagesensor




的操作函数都是通过




ioctl




进行操作设备的。





2









.unlocked_ioctl= CAMERA_HW_Ioctl





看下




unlocked_ioctl










上面的两种




ioctl




的函数都是




CAMERA_HW_Ioctl





看下




CAMERA_HW_Ioctl




函数的实现:





staticint CAMERA_HW_Ioctl(struct inode * a_pstInode,





structfile * a_pstFile,





unsignedint a_u4Command,





unsignedlong a_u4Param)





#endif





{






int i4RetValue = 0;





void * pBuff = NULL;





u32 *pIdx = NULL;





//PK_DBG(“%x, %x\n”,a_u4Command,a_u4Param);





mutex_lock(&kdCam_Mutex);





if(_IOC_NONE ==_IOC_DIR(a_u4Command))





{






}





else





{






pBuff =kmalloc(_IOC_SIZE(a_u4Command),GFP_KERNEL);//




分配一个




buffer,





if(NULL == pBuff)





{






PK_DBG(“[CAMERASENSOR] ioctl allocate mem failed\n”);





i4RetValue = -ENOMEM;





gotoCAMERA_HW_Ioctl_EXIT;





}





if(_IOC_WRITE &_IOC_DIR(a_u4Command))




//判断是否可写?





{






if(copy_from_user(pBuff, (void *) a_u4Param,_IOC_SIZE(a_u4Command)))//




将用户传递过来的命令参数复制到内核空间,接下来我们会根据这个数据进行选择





{






kfree(pBuff);





PK_DBG(“[CAMERASENSOR] ioctl copy from user failed\n”);





i4RetValue = -EFAULT;





gotoCAMERA_HW_Ioctl_EXIT;





}





}





}





pIdx = (u32*)pBuff;





switch(a_u4Command)





{






#if0





caseKDIMGSENSORIOC_X_POWER_ON:





i4RetValue =kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx, true,CAMERA_HW_DRVNAME);//




进行




imagesensor




上电的工作,具体如何上电,我们会在下面进行讲解。





break;





caseKDIMGSENSORIOC_X_POWER_OFF:





i4RetValue =kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx, false,CAMERA_HW_DRVNAME)









//




进行




imagesensor power off




的动作





break;





#endif





caseKDIMGSENSORIOC_X_SET_DRIVER:





i4RetValue =kdSetDriver((unsigned int*)pBuff);//




执行到这个




cmd




,将会调用




kdSetDriver





//




其实这个函数很重要,就是为我们对应的




imagesensor




设置




driver




,就是设置提供给上层操作底层的




interface







………………..






………………….





default :





PK_DBG(“No such command\n”);





i4RetValue = -EPERM;





break;










}





上层就是通过下




ioctl









cmd




进行操作底层的,我们就选几个




cmd




进行讲解下。







case


KDIMGSENSORIOC_T_OPEN:





i4RetValue= adopt_CAMERA_HW_Open();//




当执行上面的




cmd




的时候,我们就会执行这个函数







inline




static




int



adopt_CAMERA_HW_Open

(


void


)





{








UINT32


err = 0;






#ifdef



CONFIG_ARCH_MT6577








int



ret = 0;







//DDR2DRAM clock bug work around








if



(2 == get_ddr_type()) {



//DDR2





ret =set_dram_clk_gating(1);//




设置




dram




寄存器








if



(-1== ret) {






PK_ERR(


“ERROR: DRAM CLOCK GATING ERROR\n”


);





}





}






#endif








KD_IMGSENSOR_PROFILE_INIT();//




返回当前的时间







//poweron sensor








if



(atomic_read(&g_CamHWOpend) == 0) {








//turn on power





atomic_set(&g_CamHWOpening,1);





kdModulePowerOn((


CAMERA_DUAL_CAMERA_SENSOR_ENUM


)g_currDualSensorIdx, g_currSensorName,



true



,CAMERA_HW_DRVNAME);//













sensor






上电,这个上电函数我们在下面进行讲解







//waitfor power stable





mDELAY(10);





KD_IMGSENSOR_PROFILE(


“kdModulePowerOn”


);








//








if



(g_pSensorFunc) {//






判断我们






imagesensor






操作函数指针是否为






NULL






,如果为






NULL






,报错,因为我们就是靠这个操作函数集合去操作






imagesensor






的,





//






如果上层先下这个






cmd






的话,那么肯定是不行的,因为我们的






g_pSensorFunc













NULL






,并没有赋值,通过查询代码,发现是







case



KDIMGSENSORIOC_X_SET_DRIVER:






这个






case;






里面在做,所以上层肯定是先下这个






cmd






,然后才能执行我们现在讲解的






cmd.






这个






cmd






我们下面会进行讲解。





err =g_pSensorFunc->


SensorOpen


();//






调用使用的






imagesensor













open






函数






,






我们会对一个






imagesensor






的接口函数进行举例讲解。








if



(



ERROR_NONE



!= err) {









PK_DBG(




“ERROR:SensorOpen(), turn off power \n”




);








kdModulePowerOn((


CAMERA_DUAL_CAMERA_SENSOR_ENUM


)g_currDualSensorIdx, NULL,



false



,CAMERA_HW_DRVNAME);





}







//kaka_12_0112_2 add








else





// Add for sensor provider HW infomodule





{









if



(



DUAL_CAMERA_MAIN_SENSOR



== g_currDualSensorIdx){






memcpy(mainCameraName,g_currSensorName,CAM_NAME_LEN);





g_main_camera =mainCameraName;





}








else






if



(



DUAL_CAMERA_SUB_SENSOR



== g_currDualSensorIdx) {






memcpy(subCameraName,g_currSensorName,CAM_NAME_LEN);





g_sub_camera =subCameraName;





}





}







//kaka_12_0112_2end





}








else



{









PK_DBG(




“ERROR:NULL g_pSensorFunc\n”




);






}





KD_IMGSENSOR_PROFILE(


“SensorOpen”


);





}








if



(err == 0 ) {






atomic_set(&g_CamHWOpend,1);





}








return



err?-EIO:err;





}


/*adopt_CAMERA_HW_Open() */











2.1

















kdModulePowerOn((




CAMERA_DUAL_CAMERA_SENSOR_ENUM




)g_currDualSensorIdx, g_currSensorName,





true





,CAMERA_HW_DRVNAME);







—-










-----






>



kdCISModulePowerOn(SensorIdx,currSensorName,On,mode_name)//








这个就是








camera








的上电函数,函数定义在








/mediatek/custom/common/kernel/camera/camera/kd_camera_hw.c








里面。这个文件里面就是








camera








的上电函数,在








mediatek








平台下都共用这个函数。








3













Case: KDIMGSENSORIOC_X_SET_DRIVER






kdSetDriver




函数的实现如下:







int



kdSetDriver

(


unsigned




int


*pDrvIndex)





{








ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT


*pSensorList = NULL;








unsigned






int



drvIdx = (*pDrvIndex &KDIMGSENSOR_DUAL_MASK_LSB);//






这里根据我们用户传递进来的参数转化为






drvIdx






,就是






driverindex






的选择







//setdriver for MAIN or SUB sensor





spin_lock(&kdsensor_drv_lock);





g_currDualSensorIdx =(


CAMERA_DUAL_CAMERA_SENSOR_ENUM


)((*pDrvIndex& KDIMGSENSOR_DUAL_MASK_MSB)>>KDIMGSENSOR_DUAL_SHIFT);





spin_unlock(&kdsensor_drv_lock);








if



(0 != kdGetSensorInitFuncList(&pSensorList))//






调用这个函数,取得所有添加的






sensor






的结构的首地址。下面看下他的实现:





{






PK_ERR(


“ERROR:kdGetSensorInitFuncList()\n”


);








return



-EIO;





}








if



(drvIdx < MAX_NUM_OF_SUPPORT_SENSOR)





{









if



(NULL == pSensorList[drvIdx].


SensorInit


)





{






PK_ERR(


“ERROR:kdSetDriver()\n”


);








return



-EIO;





}





pSensorList[drvIdx].


SensorInit


(&g_pSensorFunc);//






调用我们所取得






snsor













SensorInit






函数,下面会进行看看这个






Init






函数的执行过程








if



(NULL == g_pSensorFunc)





{






PK_ERR(


“ERROR:NULLg_pSensorFunc\n”


);








return



-EIO;





}







//getsensor name





memcpy((



char



*)g_currSensorName,(



char



*)pSensorList[drvIdx].


drvname


,



sizeof



(pSensorList[drvIdx].


drvname


));







//returnsensor ID





*pDrvIndex = (



unsigned






int



)pSensorList[drvIdx].


SensorId


;





PK_DBG(


“[kdSetDriver]:%d,%d,%s,%d\n”


,g_currDualSensorIdx,drvIdx,g_currSensorName,



sizeof



(pSensorList[drvIdx].drvname));





}








return



0;





}






kdGetSensorInitFuncList














UINT32


kdGetSensorInitFuncList

(

ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT

**ppSensorList)





{









if



(



NULL



== ppSensorList)





{






printk(


“[kdGetSensorInitFuncList]ERROR:NULL ppSensorList\n”


);








return



1;





}





*ppSensorList =&kdSensorList[0];//




这里取出




kdSensorList




数组的第一个参数,这个




KdSensorList




很重要,当我们要添加一个新的




sensor




的时候,我们就会在这个数组里面进行填写。,这个添加的路径是在




/mediatek/custom/common/kernel/imagesensor/src/kd_sensor_list.h




这个头文件中








return



0;





}


// kdGetSensorInitFuncList()





上面我们是取得了整个数组的首地址:





下面会调用我们上层所应该调用的




imagesensor





pSensorList[drvIdx].

SensorInit:






调用




SensorInit




函数:





我们有很多的




imagesensor




,我这里我只选取其中一个进行讲解:





看下这个




init




函数在干嘛?代码的路径是在




/mediatek/custom/common/kernel/imagesensor/hi253_yuv_Sensor.c




里面





4












UINT32


HI253_YUV_SensorInit

(

PSENSOR_FUNCTION_STRUCT

*pfFunc)





{









static





SENSOR_FUNCTION_STRUCT


SensorFuncHI253=





{







HI253Open,











HI253GetInfo,











HI253GetResolution,











HI253FeatureControl,











HI253Control,











HI253Close











};












/*To Do : Check Sensor status here */








if



(pfFunc!=NULL)





*pfFunc=&SensorFuncHI253;








return






ERROR_NONE



;





}


/* SensorInit() */





上面我加红的函数就是




driver




里面提供的接口






4.1













HI253Open














UINT32


HI253Open

(


void


)





{








kal_uint16


SensorId = 0;







//1software reset sensor and wait (to sensor)





HI253SetPage(0x00);





HI253WriteCmosSensor(0x01,0xf1);





HI253WriteCmosSensor(0x01,0xf3);





HI253WriteCmosSensor(0x01,0xf1);





SensorId =HI253ReadCmosSensor(0x04);





Sleep(3);





SENSORDB(


“[HI253]HI253Open:Sensor ID %x\n”


,SensorId);









if



(SensorId!= HI253_SENSOR_ID)





{









return






ERROR_SENSOR_CONNECT_FAIL



;





}





HI253InitSetting();





HI253InitPara();








return






ERROR_NONE



;





}




通过函数实现就可以看出来,这里是在通过




i2c




控制




imagesensor









register




,读取




deivceid ,




看是否链接上对应的




imagesensor






4.2:HI253GetInfo






UINT32





HI253GetInfo



(MSDK_SCENARIO_ID_ENUMScenarioId,





MSDK_SENSOR_INFO_STRUCT*pSensorInfo,





MSDK_SENSOR_CONFIG_STRUCT*pSensorConfigData)





{






pSensorInfo->


SensorPreviewResolutionX


=HI253_PV_WIDTH;





pSensorInfo->


SensorPreviewResolutionY


=HI253_PV_HEIGHT;





pSensorInfo->


SensorFullResolutionX


=HI253_FULL_WIDTH;





pSensorInfo->


SensorFullResolutionY


=HI253_FULL_HEIGHT;






…………….






………………







switch


(ScenarioId)





{









case



MSDK_SCENARIO_ID_CAMERA_PREVIEW:








case



MSDK_SCENARIO_ID_VIDEO_PREVIEW:








case



MSDK_SCENARIO_ID_VIDEO_CAPTURE_MPEG4:








case



MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG:








case



MSDK_SCENARIO_ID_CAMERA_CAPTURE_MEM:








default



:





pSensorInfo->


SensorClockFreq


=26;





pSensorInfo->


SensorClockDividCount


=3;





pSensorInfo->


SensorClockRisingCount


=0;





pSensorInfo->


SensorClockFallingCount


=2;





pSensorInfo->


SensorPixelClockCount


=3;





pSensorInfo->


SensorDataLatchCount


=2;





pSensorInfo->


SensorGrabStartX


= HI253_GRAB_START_X;





pSensorInfo->


SensorGrabStartY


= HI253_GRAB_START_Y;








break



;





}








return






ERROR_NONE



;





}





上面的函数一共传递进来了






3






个变量,第一个变量:是控制






camera






的工作模式,






(






拍照、摄像等等






)














2






个参数:主要设置






imagesensor






的频率的






(






时钟频率、预览频率、以及同步频率






)






;第






3






个参数同样也是






camera






的设置,其实要看到底是在干嘛,只要看看这个参数是如何定义的就可以了。








4.3
















HI253GetResolution







UINT32


HI253GetResolution

(MSDK_SENSOR_RESOLUTION_INFO_STRUCT*pSensorResolution)





{






pSensorResolution->


SensorFullWidth


= HI253_FULL_WIDTH;





pSensorResolution->


SensorFullHeight


= HI253_FULL_HEIGHT;





pSensorResolution->


SensorPreviewWidth


= HI253_PV_WIDTH;





pSensorResolution->


SensorPreviewHeight


= HI253_PV_HEIGHT;








return






ERROR_NONE



;





}


/* HI253GetResolution() */






设置






camera






在预览模式下的高度、宽度等







4.4













HI253FeatureControl







UINT32


HI253FeatureControl

(MSDK_SENSOR_FEATURE_ENUM FeatureId,







UINT8


*pFeaturePara,


UINT32


*pFeatureParaLen)





{








UINT16


*pFeatureReturnPara16=(


UINT16


*) pFeaturePara;







UINT16


*pFeatureData16=(


UINT16


*) pFeaturePara;







UINT32


*pFeatureReturnPara32=(


UINT32


*) pFeaturePara;







UINT32


*pFeatureData32=(


UINT32


*) pFeaturePara;





MSDK_SENSOR_CONFIG_STRUCT*pSensorConfigData=(MSDK_SENSOR_CONFIG_STRUCT *) pFeaturePara;





MSDK_SENSOR_REG_INFO_STRUCT*pSensorRegData=(MSDK_SENSOR_REG_INFO_STRUCT *) pFeaturePara;








switch



(FeatureId)





{









case






SENSOR_FEATURE_GET_RESOLUTION



:





*pFeatureReturnPara16++=HI253_FULL_WIDTH;





*pFeatureReturnPara16=HI253_FULL_HEIGHT;





*pFeatureParaLen=4;








break



;













..





}





这个是上层会提供






featureid






,底层通过这个






id






进行不同






case






的执行为






para













paralen






赋值。






4.5

















HI253Control






UINT32





HI253Control



(MSDK_SCENARIO_ID_ENUMScenarioId, MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *pImageWindow,





MSDK_SENSOR_CONFIG_STRUCT*pSensorConfigData)





{









switch



(ScenarioId)





{









case



MSDK_SCENARIO_ID_CAMERA_PREVIEW:








case



MSDK_SCENARIO_ID_VIDEO_PREVIEW:








case



MSDK_SCENARIO_ID_VIDEO_CAPTURE_MPEG4:





HI253Preview(pImageWindow,pSensorConfigData);








break



;








case



MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG:








case



MSDK_SCENARIO_ID_CAMERA_CAPTURE_MEM:





HI253Capture(pImageWindow,pSensorConfigData);








break



;








default



:








break



;





}








return






TRUE



;





}


/* HI253Control() */





这个函数和上面一样,也是提供控制的一个






Interface






4.6













HI253Close






UINT32





HI253Close



(



void



)





{









return






ERROR_NONE



;





}


/* HI253Close() */





这里的






close






没有执行任何工作,当然你也可以自己实现






通过








mtk








代码的分析,








mtk








的代码只是提供一个








Interface,








只是提供一个机制,至于策略是上层在控制。





版权声明:本文为sunweizhong1024原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。