MTK6577---camera驱动分析
2013-11-21 15:34:31
分类: 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)};
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中
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的初始化是在全局变量中初始化的
4.1 字符设备初始化
#define CAMERA_HW_DRVNAME "kd_camera_hw"
static dev_t g_CAMERA_HWdevno = MKDEV(250,0);
字符设备的文件操作
5. 字符设备的open与relase
open与relase函数啥也不作,只是把计数加1或减1
release:
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中
在mediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.c
5.1 寻找驱动
5.1.1获取sensorList的首地址
5.1.2读取器件的SensorID来判断是否有硬件连上
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);
- }
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);
- }
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(); //字符设备的初始化
- }
#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;
- }
- static int CAMERA_HW_Release(struct inode * a_pstInode, struct file * a_pstFile)
- {
- atomic_dec(&g_CamDrvOpenCnt);
-
- return 0;
- }
在./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
- };
- 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
- }
- }
- 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是否正历来判断是否有这个驱动的硬件连上
- }
- UINT32 kdGetSensorInitFuncList(ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)
- {
- *ppSensorList = &kdSensorList[0];
- return 0;
- }
- 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;
- }
- }