Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3125064
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: Android平台

2014-09-20 14:55:51

原文地址:http://blog.chinaunix.net/uid-26009923-id-3999723.html

一.camera驱动的初始化
1. 支持的摄像头列表
在./mediatek/config/mobitek77_m01_ics2/ProjectConfig.mk中,
配置支持的摄像头驱动
  1. CUSTOM_HAL_IMGSENSOR=ov5640_yuv s5k4e1ga_raw ov5647_raw gc2035_yuv gc0329_yuv
  2. CUSTOM_HAL_MAIN_IMGSENSOR=ov5640_yuv s5k4e1ga_raw ov5647_raw #gc2035_yuv
  3. CUSTOM_HAL_SUB_IMGSENSOR=gc2035_yuv gc0329_yuv
  4. CUSTOM_KERNEL_IMGSENSOR=ov5640_yuv s5k4e1ga_raw ov5647_raw gc2035_yuv gc0329_yuv
  5. 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 中
  1. ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT kdSensorList[] =
  2. {
  3. #if defined(GC2035_YUV)
  4.         {GC2035_SENSOR_ID, SENSOR_DRVNAME_GC2035_YUV, GC2035_YUV_SensorInit},
  5. #endif
  6. #if defined(OV5640_YUV)
  7.     {OV5640_SENSOR_ID, SENSOR_DRVNAME_OV5640_YUV, OV5640_YUV_SensorInit},
  8. #endif
  9.     {0,{0},NULL},
  10. };



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)};
  1. static int __init CAMERA_HW_i2C_init(void)
  2. {
  3.     //注册i2c信息,下一步就可以调用i2c_add_driver
  4.     i2c_register_board_info(CAMERA_I2C_BUSNUM, &kd_camera_dev, 1);   
  5.     //注册platform_driver然后调用probe函数CAMERA_HW_probe
  6.     platform_driver_register(&g_stCAMERA_HW_Driver);
  7.     //在proc目录中创建/proc/driver/camsensor调试信息
  8.     prEntry = create_proc_entry("driver/camsensor", 0, NULL);
  9.     prEntry->read_proc = CAMERA_HW_DumpReg_To_Proc;
  10.     prEntry->write_proc = CAMERA_HW_Reg_Debug;
  11.     
  12.     //全局变量的初始化
  13.     atomic_set(&g_CamHWOpend, 0);
  14.     atomic_set(&g_CamDrvOpenCnt, 0);
  15.     atomic_set(&g_CamHWOpening, 0);
  16. }
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中
  1. static int CAMERA_HW_probe(struct platform_device *pdev)
  2. {
  3.     //创建一个等侍队列
  4.     init_waitqueue_head(&kd_sensor_wait_queue);       
  5.     //注册一个i2c驱动,然后调用i2c驱动的probe函数CAMERA_HW_i2c_probe
  6.     return i2c_add_driver(&CAMERA_HW_i2c_driver);
  7. }
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的初始化是在全局变量中初始化的
  1. static int CAMERA_HW_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
  2. {
  3.     spin_lock(&kdsensor_drv_lock);           //加锁
  4.     g_pstI2Cclient = client;        //获取client
  5.     g_pstI2Cclient->timing = 200;   //设置clock 200k
  6.     spin_unlock(&kdsensor_drv_lock);         //解锁

  7.     i4RetValue = RegisterCAMERA_HWCharDrv();   //字符设备的初始化
  8. }
4.1 字符设备初始化
#define CAMERA_HW_DRVNAME "kd_camera_hw"
static dev_t g_CAMERA_HWdevno = MKDEV(250,0);
  1. inline static int RegisterCAMERA_HWCharDrv(void)
  2. {
  3.     struct device* sensor_device = NULL;

  4. #if CAMERA_HW_DYNAMIC_ALLOCATE_DEVNO
  5.     alloc_chrdev_region(&g_CAMERA_HWdevno, 0, 1,CAMERA_HW_DRVNAME); //动态分配dev_no
  6. #else
  7.     register_chrdev_region( g_CAMERA_HWdevno , 1 , CAMERA_HW_DRVNAME);    
  8. #endif

  9.     g_pCAMERA_HW_CharDrv = cdev_alloc();                   //分配设备内存
  10.     cdev_init(g_pCAMERA_HW_CharDrv, &g_stCAMERA_HW_fops);  //初始化设备
  11.     g_pCAMERA_HW_CharDrv->owner = THIS_MODULE;
  12.     cdev_add(g_pCAMERA_HW_CharDrv, g_CAMERA_HWdevno, 1))   //注册设备
  13.     //这样就创建了结点/dev/kd_camera_hw
  14.     sensor_class = class_create(THIS_MODULE, "sensordrv");     //与下一句一起创建设备结点
  15.     sensor_device = device_create(sensor_class, NULL, g_CAMERA_HWdevno, NULL, CAMERA_HW_DRVNAME);
  16.     
  17. }

字符设备的文件操作
  1. static const struct file_operations g_stCAMERA_HW_fops =
  2. {
  3.     .owner = THIS_MODULE,
  4.     .open = CAMERA_HW_Open,
  5.     .release = CAMERA_HW_Release,
  6. #ifdef HAL_CAMERA_COMPATIBLE
  7.     .read = device_read,
  8. #endif
  9.     #ifdef USE_NEW_IOCTL
  10.     .unlocked_ioctl = CAMERA_HW_Ioctl
  11.     #else
  12.     .ioctl = CAMERA_HW_Ioctl
  13.     #endif
  14. };

5. 字符设备的open与relase
open与relase函数啥也不作,只是把计数加1或减1
  1. static int CAMERA_HW_Open(struct inode * a_pstInode, struct file * a_pstFile)
  2. {
  3.     dbmsg("open");
  4.     atomic_inc(&g_CamDrvOpenCnt);
  5.     return 0;
  6. }
release:
  1. static int CAMERA_HW_Release(struct inode * a_pstInode, struct file * a_pstFile)
  2. {
  3.     atomic_dec(&g_CamDrvOpenCnt);

  4.     return 0;
  5. }
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中
  1. MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[] =
  2. { 
  3.     #if defined(OV5640_YUV)
  4.         YUV_INFO(OV5640_SENSOR_ID, SENSOR_DRVNAME_OV5640_YUV, NULL),
  5.     #endif
  6.     #if defined(S5K4E1GA_RAW)
  7.         RAW_INFO(S5K4E1GA_SENSOR_ID, SENSOR_DRVNAME_S5K4E1GA_RAW, NULL),
  8.     #endif
  9.     #if defined(OV5647_RAW)
  10.         RAW_INFO(OV5647_SENSOR_ID, SENSOR_DRVNAME_OV5647_RAW, NULL),
  11.     #endif
  12.     #if defined(GC2035_YUV)                            
  13.         YUV_INFO(GC2035_SENSOR_ID, SENSOR_DRVNAME_GC2035_YUV,NULL),
  14.     #endif
  15.     #if defined(GC0329_YUV)
  16.         YUV_INFO(GC0329_SENSOR_ID, SENSOR_DRVNAME_GC0329_YUV, NULL),
  17.     #endif
  18.     {0,{0},NULL, NULL, NULL}//end of list
  19. };
在mediatek\custom\common\kernel\imgsensor\src\kd_sensorlist.c
  1. static ssize_t device_read(struct file *filpchar *buffer, size_t length, loff_t *offset)
  2. {
  3.     int bytes_read = 0;
  4.     char i,k,j,g,err;
  5.     char msg[2]={0};//"pangfei read test program";
  6.     
  7.     //查看sensorList中的支持的驱动数目
  8.     k = sizeof(kdSensorList)/sizeof(ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT) - 1;
  9.     //寻找主摄像头
  10.     for(i=0;i<k;i++
  11.     {
  12.         kdSearchCameraDriver(i,DUAL_CAMERA_MAIN_SENSOR); //5.1检查是否有这个驱动的硬件
  13.         msg[0] = i;
  14.         MainCameraDrvIdx = i;    //如果有将全局变量MainCameraDrvIdx设为找到的值,这儿为0 
  15.         break;                   //这儿为0,即主摄像头是在SensorList中的第0项:ov5640_yuv
  16.      }        
  17.     //寻找次摄像头
  18.     for(j=k-1;j>msg[0];j--
  19.     {
  20.         err=kdSearchCameraDriver(j,DUAL_CAMERA_SUB_SENSOR);  //检查是否有这个驱动的硬件
  21.         msg[1] = j;
  22.         SubCameraDrvIdx = j;     //如果有将全局变量SubCameraDrvIdx设为找到的值,这儿为3
            break;                   //这儿为0,即次摄像头是在SensorList中的第3项:gc2035_yuv  
  23.     }
  24. }
5.1 寻找驱动
  1. static int kdSearchCameraDriver(char drvIdx,char index)
  2. {
  3.     ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT *pSensorList = NULL;
  4.     kdGetSensorInitFuncList(&pSensorList))//5.1.1由pSensorList获取首地址
  5.     pSensorList[drvIdx].SensorInit(&g_pSensorFunc);   //调用具体硬件的SensorInit      
  6.     CAMERA_HW_CheckIsAlive(index);                    //5.1.2读取sensorID是否正历来判断是否有这个驱动的硬件连上
  7. }
5.1.1获取sensorList的首地址
  1. UINT32 kdGetSensorInitFuncList(ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)
  2. {
  3.     *ppSensorList = &kdSensorList[0];
  4.     return 0;
  5. }
5.1.2读取器件的SensorID来判断是否有硬件连上
  1. static int CAMERA_HW_CheckIsAlive(char index)
  2. {
  3.     g_currDualSensorIdx = index//power on main or sub sensor
  4.     kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) g_currDualSensorIdx, g_currSensorName,true, CAMERA_HW_DRVNAME);
  5.     mDELAY(10);
  6.     //读取SensorID
  7.     g_pSensorFunc->SensorFeatureControl(SENSOR_FEATURE_CHECK_SENSOR_ID, (MUINT8*)&sensorID, &retLen);
  8.     if (sensorID == 0) { //如果读取失败,还有可能是没有实现这个接口,再用SensorOpen试试          
  9.         err = g_pSensorFunc->SensorOpen();
  10.     }
  11.     else if (sensorID == 0xFFFFFFFF) {           
  12.        err = ERROR_SENSOR_CONNECT_FAIL;
  13.     }
  14.     else {
  15.            err = ERROR_NONE;
  16.     }    
  17.     kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) g_currDualSensorIdx, NULL, false, CAMERA_HW_DRVNAME);
  18. }





  1. int kdSetDriver(unsigned int* pDrvIndex)
  2. {
  3.     ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT *pSensorList = NULL;
  4.     unsigned int drvIdx = (*pDrvIndex & KDIMGSENSOR_DUAL_MASK_LSB);
  5.     spin_lock(&kdsensor_drv_lock);
  6.     g_currDualSensorIdx = (CAMERA_DUAL_CAMERA_SENSOR_ENUM)((*pDrvIndex & KDIMGSENSOR_DUAL_MASK_MSB)>>KDIMGSENSOR_DUAL_SHIFT);
  7.     spin_unlock(&kdsensor_drv_lock);
  8.     kdGetSensorInitFuncList(&pSensorList);    
  9.     k = sizeof(kdSensorList)/sizeof(ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT) - 1;
  10.     if (drvIdx == 0)
  11.     {
  12.         drvIdx = MainCameraDrvIdx;
  13.         pSensorList[drvIdx].SensorInit(&g_pSensorFunc);     //调用init获取具体驱动的函数指针
  14.         memcpy((char*)g_currSensorName,(char*)pSensorList[drvIdx].drvname,sizeof(pSensorList[drvIdx].drvname));
  15.         *pDrvIndex = (unsigned int)pSensorList[drvIdx].SensorId;       
  16.     }
  17.     else
  18.     {       
  19.         drvIdx = SubCameraDrvIdx;
  20.         pSensorList[drvIdx].SensorInit(&g_pSensorFunc);     //调用init获取具体驱动的函数指针
  21.         memcpy((char*)g_currSensorName,(char*)pSensorList[drvIdx].drvname,sizeof(pSensorList[drvIdx].drvname));
  22.         *pDrvIndex = (unsigned int)pSensorList[drvIdx].SensorId;
  23.     }
  24. }

阅读(1402) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~