日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MTK6577---camera驱动分析

發布時間:2023/12/16 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MTK6577---camera驱动分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?MTK6577---camera驅動分析?2013-11-21 15:34:31

分類:?Android平臺

一.camera驅動的初始化
1. 支持的攝像頭列表
在./mediatek/config/mobitek77_m01_ics2/ProjectConfig.mk中,
配置支持的攝像頭驅動
  • CUSTOM_HAL_IMGSENSOR=ov5640_yuv s5k4e1ga_raw ov5647_raw gc2035_yuv gc0329_yuv
  • CUSTOM_HAL_MAIN_IMGSENSOR=ov5640_yuv s5k4e1ga_raw ov5647_raw #gc2035_yuv
  • CUSTOM_HAL_SUB_IMGSENSOR=gc2035_yuv gc0329_yuv
  • CUSTOM_KERNEL_IMGSENSOR=ov5640_yuv s5k4e1ga_raw ov5647_raw gc2035_yuv gc0329_yuv
  • CUSTOM_KERNEL_SUB_IMGSENSOR=gc2035_yuv gc0329_yuv



  • 在 custom/common/kernel/imgsensor/src/kd_sensorlist.h或
    在source/external/mhal/src/custom/common/kernel/imgsensor/kd_sensorlist.h 中
  • ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT kdSensorList[]?=
  • {
  • #if?defined(GC2035_YUV)
  • ????????{GC2035_SENSOR_ID,?SENSOR_DRVNAME_GC2035_YUV,?GC2035_YUV_SensorInit},
  • #endif
  • #if?defined(OV5640_YUV)
  • ????{OV5640_SENSOR_ID,?SENSOR_DRVNAME_OV5640_YUV,?OV5640_YUV_SensorInit},
  • #endif
  • ????{0,{0},NULL},
  • };



  • 2. module_init
    在mediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.c中
    module_init(CAMERA_HW_i2C_init);
    //文件的開頭,先聲明I2C信息
    static struct i2c_board_info __initdata kd_camera_dev={ I2C_BOARD_INFO("kd_camera_hw", 0xfe>>1)};
  • static?int?__init CAMERA_HW_i2C_init(void)
  • {
  • ????//注冊i2c信息,下一步就可以調用i2c_add_driver
  • ????i2c_register_board_info(CAMERA_I2C_BUSNUM,?&kd_camera_dev,?1);???
  • ????//注冊platform_driver然后調用probe函數CAMERA_HW_probe
  • ????platform_driver_register(&g_stCAMERA_HW_Driver);
  • ??? //在proc目錄中創建/proc/driver/camsensor調試信息
  • ????prEntry?=?create_proc_entry("driver/camsensor",?0,?NULL);
  • ??? prEntry->read_proc?=?CAMERA_HW_DumpReg_To_Proc;
  • ??? prEntry->write_proc?=?CAMERA_HW_Reg_Debug;
  • ????
  • ??? //全局變量的初始化
  • ??? atomic_set(&g_CamHWOpend,?0);
  • ????atomic_set(&g_CamDrvOpenCnt,?0);
  • ????atomic_set(&g_CamHWOpening,?0);
  • }
  • 3. Camera_hw_p
    CAMERA_HW_i2C_init
    ??? --> platform_driver_register?
    ??????? -->?CAMERA_HW_probe
    ??????? --> i2c_add_driver
    在mediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.c中
  • static?int?CAMERA_HW_probe(struct platform_device?*pdev)
  • {
  • ????//創建一個等侍隊列
  • ????init_waitqueue_head(&kd_sensor_wait_queue);???????
  • ????//注冊一個i2c驅動,然后調用i2c驅動的probe函數CAMERA_HW_i2c_probe
  • ????return i2c_add_driver(&CAMERA_HW_i2c_driver);
  • }
  • 4. Camera_hw_i2c_probe
    CAMERA_HW_i2C_init
    ??? --> platform_driver_register?
    ??????? -->?CAMERA_HW_probe
    ??????? --> i2c_add_driver
    ??????????????? --> CAMERA_HW_i2c_probe
    在mediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.c中
    static DEFINE_SPINLOCK(kdsensor_drv_lock);?//spin_lock的初始化是在全局變量中初始化的
  • static?int?CAMERA_HW_i2c_probe(struct i2c_client?*client,?const?struct i2c_device_id?*id)
  • {
  • ????spin_lock(&kdsensor_drv_lock);???????????//加鎖
  • ????g_pstI2Cclient?=?client;????????//獲取client
  • ??? g_pstI2Cclient->timing?=?200;???//設置clock 200k
  • ????spin_unlock(&kdsensor_drv_lock);?????????//解鎖

  • ????i4RetValue?=?RegisterCAMERA_HWCharDrv();???//字符設備的初始化
  • }
  • 4.1 字符設備初始化
    #define CAMERA_HW_DRVNAME "kd_camera_hw"
    static dev_t g_CAMERA_HWdevno = MKDEV(250,0);
  • inline static?int?RegisterCAMERA_HWCharDrv(void)
  • {
  • ????struct device*?sensor_device?=?NULL;

  • #if?CAMERA_HW_DYNAMIC_ALLOCATE_DEVNO
  • ????alloc_chrdev_region(&g_CAMERA_HWdevno,?0,?1,CAMERA_HW_DRVNAME);?//動態分配dev_no
  • #else
  • ????register_chrdev_region(?g_CAMERA_HWdevno?,?1?,?CAMERA_HW_DRVNAME);????
  • #endif

  • ????g_pCAMERA_HW_CharDrv?=?cdev_alloc();???????????????????//分配設備內存
  • ????cdev_init(g_pCAMERA_HW_CharDrv,?&g_stCAMERA_HW_fops);??//初始化設備
  • ????g_pCAMERA_HW_CharDrv->owner?=?THIS_MODULE;
  • ????cdev_add(g_pCAMERA_HW_CharDrv,?g_CAMERA_HWdevno,?1))???//注冊設備
  • ????//這樣就創建了結點/dev/kd_camera_hw
  • ????sensor_class?=?class_create(THIS_MODULE,?"sensordrv");?????//與下一句一起創建設備結點
  • ????sensor_device?=?device_create(sensor_class,?NULL,?g_CAMERA_HWdevno,?NULL,?CAMERA_HW_DRVNAME);
  • ????
  • }

  • 字符設備的文件操作
  • static?const?struct file_operations g_stCAMERA_HW_fops?=
  • {
  • ????.owner?=?THIS_MODULE,
  • ????.open?=?CAMERA_HW_Open,
  • ????.release?=?CAMERA_HW_Release,
  • #ifdef HAL_CAMERA_COMPATIBLE
  • ????.read?=?device_read,
  • #endif
  • ????#ifdef USE_NEW_IOCTL
  • ????.unlocked_ioctl?=?CAMERA_HW_Ioctl
  • ????#else
  • ????.ioctl?=?CAMERA_HW_Ioctl
  • ????#endif
  • };

  • 5. 字符設備的open與relase
    open與relase函數啥也不作,只是把計數加1或減1
  • static?int?CAMERA_HW_Open(struct inode?*?a_pstInode,?struct file?*?a_pstFile)
  • {
  • ????dbmsg("open");
  • ????atomic_inc(&g_CamDrvOpenCnt);
  • ????return 0;
  • }
  • release:
  • static?int?CAMERA_HW_Release(struct inode?*?a_pstInode,?struct file?*?a_pstFile)
  • {
  • ????atomic_dec(&g_CamDrvOpenCnt);

  • ????return 0;
  • }
  • 5. 字符設備的read過程
    在./mediatek/config/mobitek77_m01_ics2/ProjectConfig.mk中
    CUSTOM_HAL_IMGSENSOR=ov5640_yuv s5k4e1ga_raw ov5647_raw? gc2035_yuv gc0329_yuv
    在mediatek\custom\common\hal\imgsensor\src\sensorlist.cpp中
  • MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[]?=
  • {?
  • ????#if?defined(OV5640_YUV)
  • ????????YUV_INFO(OV5640_SENSOR_ID,?SENSOR_DRVNAME_OV5640_YUV,?NULL),
  • ????#endif
  • ????#if?defined(S5K4E1GA_RAW)
  • ????????RAW_INFO(S5K4E1GA_SENSOR_ID,?SENSOR_DRVNAME_S5K4E1GA_RAW,?NULL),
  • ????#endif
  • ????#if?defined(OV5647_RAW)
  • ????????RAW_INFO(OV5647_SENSOR_ID,?SENSOR_DRVNAME_OV5647_RAW,?NULL),
  • ????#endif
  • ????#if?defined(GC2035_YUV)????????????????????????????
  • ????????YUV_INFO(GC2035_SENSOR_ID,?SENSOR_DRVNAME_GC2035_YUV,NULL),
  • ????#endif
  • ????#if?defined(GC0329_YUV)
  • ????????YUV_INFO(GC0329_SENSOR_ID,?SENSOR_DRVNAME_GC0329_YUV,?NULL),
  • ????#endif
  • ????{0,{0},NULL,?NULL,?NULL}//end?of list
  • };
  • 在mediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.c
  • static ssize_t device_read(struct file?*filp,?char?*buffer,?size_t length,?loff_t?*offset)
  • {
  • ????int?bytes_read?=?0;
  • ????char i,k,j,g,err;
  • ????char msg[2]={0};//"pangfei read test program";
  • ????
  • ????//查看sensorList中的支持的驅動數目
  • ????k?=?sizeof(kdSensorList)/sizeof(ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT)?-?1;
  • ????//尋找主攝像頭
  • ????for(i=0;i<k;i++)?
  • ????{
  • ??????? kdSearchCameraDriver(i,DUAL_CAMERA_MAIN_SENSOR);?//5.1檢查是否有這個驅動的硬件
  • ??????? msg[0]?=?i;
  • ????????MainCameraDrvIdx?=?i;????//如果有將全局變量MainCameraDrvIdx設為找到的值,這兒為0?
  • ????????break;???????????????????//這兒為0,即主攝像頭是在SensorList中的第0項:ov5640_yuv
  • ?????}????????
  • ????//尋找次攝像頭
  • ????for(j=k-1;j>msg[0];j--)?
  • ????{
  • ????????err=kdSearchCameraDriver(j,DUAL_CAMERA_SUB_SENSOR);??//檢查是否有這個驅動的硬件
  • ??????? msg[1]?=?j;
  • ??????? SubCameraDrvIdx?=?j;?????//如果有將全局變量SubCameraDrvIdx設為找到的值,這兒為3
    ????????break;???????????????????//這兒為0,即次攝像頭是在SensorList中的第3項:gc2035_yuv??
  • ????}
  • }
  • 5.1 尋找驅動
  • static?int?kdSearchCameraDriver(char drvIdx,char index)
  • {
  • ????ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT?*pSensorList?=?NULL;
  • ??? kdGetSensorInitFuncList(&pSensorList));?//5.1.1由pSensorList獲取首地址
  • ??? pSensorList[drvIdx].SensorInit(&g_pSensorFunc);???//調用具體硬件的SensorInit??????
  • ??? CAMERA_HW_CheckIsAlive(index);????????????????????//5.1.2讀取sensorID是否正歷來判斷是否有這個驅動的硬件連上
  • }
  • 5.1.1獲取sensorList的首地址
  • UINT32 kdGetSensorInitFuncList(ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT?**ppSensorList)
  • {
  • ????*ppSensorList?=?&kdSensorList[0];
  • ????return 0;
  • }
  • 5.1.2讀取器件的SensorID來判斷是否有硬件連上
  • static?int?CAMERA_HW_CheckIsAlive(char index)
  • {
  • ??? g_currDualSensorIdx?=?index;?//power?on?main?or?sub?sensor
  • ????kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM)?g_currDualSensorIdx,?g_currSensorName,true,?CAMERA_HW_DRVNAME);
  • ????mDELAY(10);
  • ????//讀取SensorID
  • ??? g_pSensorFunc->SensorFeatureControl(SENSOR_FEATURE_CHECK_SENSOR_ID,?(MUINT8*)&sensorID,?&retLen);
  • ????if?(sensorID?==?0)?{?//如果讀取失敗,還有可能是沒有實現這個接口,再用SensorOpen試試??????????
  • ??? ? ??err?=?g_pSensorFunc->SensorOpen();
  • ????}
  • ????else?if?(sensorID?==?0xFFFFFFFF)?{???????????
  • ???????err?=?ERROR_SENSOR_CONNECT_FAIL;
  • ????}
  • ????else?{
  • ???????????err?=?ERROR_NONE;
  • ????}????
  • ????kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM)?g_currDualSensorIdx,?NULL,?false,?CAMERA_HW_DRVNAME);
  • }





  • int?kdSetDriver(unsigned?int*?pDrvIndex)
  • {
  • ????ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT?*pSensorList?=?NULL;
  • ????unsigned?int?drvIdx?=?(*pDrvIndex?&?KDIMGSENSOR_DUAL_MASK_LSB);
  • ????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);
  • ??? kdGetSensorInitFuncList(&pSensorList);????
  • ????k?=?sizeof(kdSensorList)/sizeof(ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT)?-?1;
  • ????if?(drvIdx?==?0)
  • ????{
  • ????????drvIdx?=?MainCameraDrvIdx;
  • ????????pSensorList[drvIdx].SensorInit(&g_pSensorFunc);?????//調用init獲取具體驅動的函數指針
  • ????????memcpy((char*)g_currSensorName,(char*)pSensorList[drvIdx].drvname,sizeof(pSensorList[drvIdx].drvname));
  • ????????*pDrvIndex?=?(unsigned?int)pSensorList[drvIdx].SensorId;???????
  • ????}
  • ????else
  • ????{???????
  • ????????drvIdx?=?SubCameraDrvIdx;
  • ??????? pSensorList[drvIdx].SensorInit(&g_pSensorFunc);?????//調用init獲取具體驅動的函數指針
  • ????????memcpy((char*)g_currSensorName,(char*)pSensorList[drvIdx].drvname,sizeof(pSensorList[drvIdx].drvname));
  • ????????*pDrvIndex?=?(unsigned?int)pSensorList[drvIdx].SensorId;
  • ????}
  • }
  • 總結

    以上是生活随笔為你收集整理的MTK6577---camera驱动分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。