MTK6577---camera驱动分析
生活随笔
收集整理的這篇文章主要介紹了
MTK6577---camera驱动分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?MTK6577---camera驅動分析?2013-11-21 15:34:31
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; ????} }
分類:?Android平臺
一.camera驅動的初始化
1. 支持的攝像頭列表
在./mediatek/config/mobitek77_m01_ics2/ProjectConfig.mk中,
配置支持的攝像頭驅動
在 custom/common/kernel/imgsensor/src/kd_sensorlist.h或
在source/external/mhal/src/custom/common/kernel/imgsensor/kd_sensorlist.h 中
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)};
CAMERA_HW_i2C_init
??? --> platform_driver_register?
??????? -->?CAMERA_HW_probe
??????? --> i2c_add_driver
在mediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.c中
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的初始化是在全局變量中初始化的
#define CAMERA_HW_DRVNAME "kd_camera_hw"
static dev_t g_CAMERA_HWdevno = MKDEV(250,0);
字符設備的文件操作
5. 字符設備的open與relase
open與relase函數啥也不作,只是把計數加1或減1
在./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中
????????break;???????????????????//這兒為0,即次攝像頭是在SensorList中的第3項:gc2035_yuv??
總結
以上是生活随笔為你收集整理的MTK6577---camera驱动分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端开发概述
- 下一篇: 直流稳压电源设计—7805