MTK6582平台gc_0328+2035Camera驱动笔记

一、Camera驱动的初始化

1. 支持的摄像头列表

在-->ProjectConfig.mk 配置文件中 可查看所支持的摄像头驱动:

CUSTOM_HAL_IMGSENSOR =sp2518_yuv sp0a19_yuv gc2155_yuvgc0328_yuv gc03091_yuv gc0309_yuvgc2035_yuv
CUSTOM_HAL_MAIN_IMGSENSOR =sp2518_yuv gc2155_yuv   gc03091_yuvgc2035_yuv
CUSTOM_HAL_SUB_IMGSENSOR = sp0a19_yuv gc0328_yuv  gc0309_yuv
CUSTOM_KERNEL_IMGSENSOR =sp2518_yuv sp0a19_yuv gc2155_yuvgc0328_yuv gc03091_yuv gc0309_yuvgc2035_yuv
CUSTOM_KERNEL_MAIN_IMGSENSOR = sp2518_yuv gc2155_yuv  gc03091_yuvgc2035_yuv
CUSTOM_KERNEL_SUB_IMGSENSOR = sp0a19_yuv gc0328_yuv gc0309_yuv

在-->kd_sensorlist.h 文件中添加的Sensor会在开机启动时扫描

ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR+1] =
{
#if defined(GC2035_YUV)                                                           //jiang add
    {GC2035_SENSOR_ID, SENSOR_DRVNAME_GC2035_YUV,GC2035_YUV_SensorInit},-->此参数为驱动的操作函数接口初始化
#endif
#if defined(GC0328_YUV)
    {GC0328_SENSOR_ID, SENSOR_DRVNAME_GC0328_YUV,GC0328_YUV_SensorInit}, 
#endif

...

  {0,{0},NULL},   //end of list

}

我们添加Sensor时一般添加在数组的开头, 这样不会出现kenel 层与 hal 层数组Sensor顺序不一致的情况

2. 插入模块

在-->  kd_sensorlist.c

由这两函数来实现模块的插拔,驱动流程的分析也从此函数开始

module_init(CAMERA_HW_i2C_init); -->模块插入

module_exit(CAMERA_HW_i2C_exit);             -->模块拔出

1)、CAMERA_HW_i2C_init

static int __init CAMERA_HW_i2C_init(void)
{

    i2c_register_board_info(SUPPORT_I2C_BUS_NUM1, &i2c_devs1, 1);      -->注册一个i2c_device

    platform_driver_register(&g_stCAMERA_HW_Driver); -->注册一个platform_driver --> 调用probe函数
}

2)、CAMERA_HW_probe

static int CAMERA_HW_probe(struct platform_device *pdev)
{
    return i2c_add_driver(&CAMERA_HW_i2c_driver);-->注册一个i2c驱动 --> 调用i2c驱动的probe函数

}

3)、CAMERA_HW_i2c_probe

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)、字符设备初始化

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_DRVNAME1) ;  -->动态分配 dev_no
#else
         register_chrdev_region(  g_CAMERA_HWdevno , 1 , CAMERA_HW_DRVNAME1) ;
#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);-->注册设备

 sensor_class = class_create(THIS_MODULE, "sensordrv");-->创建设备节点          

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

}

static const struct file_operations g_stCAMERA_HW_fops=            -->字符设备的文件操作
{
    .owner = THIS_MODULE,
    .open = CAMERA_HW_Open
--> 只是把计数加1
    .release = CAMERA_HW_Release,
    .unlocked_ioctl = CAMERA_HW_Ioctl
};
   

5)、给上层提供硬件操作的接口

static long CAMERA_HW_Ioctl( struct file * a_pstFile,unsigned int a_u4Command, unsigned long a_u4Param)
{
        pBuff = kmalloc(_IOC_SIZE(a_u4Command),GFP_KERNEL);  -->给指针分配空间
        copy_from_user(pBuff , (void *) a_u4Param, _IOC_SIZE(a_u4Command)
        pIdx = (u32*)pBuff;
    switch(a_u4Command) {
        case KDIMGSENSORIOC_X_SET_DRIVER:
            i4RetValue = kdSetDriver((unsigned int*)pBuff);  -->通过name和ID匹配具体的sensor型号的驱动,区分主摄、次摄并初始化, 参数pDrvIndex是一个数组,他有两个成员,数组的前16位为后摄,前摄的下标(目前1、2)后16位为sensor的索引
            break;                                                                     
        case KDIMGSENSORIOC_T_OPEN:
            i4RetValue = adopt_CAMERA_HW_Open();
            break; 
        case KDIMGSENSORIOC_X_FEATURECONCTROL:
            i4RetValue = adopt_CAMERA_HW_FeatureControl(pBuff);  -->在pBuff中调用具体的sensor的GetsensorID函数,存在就记录
            break;         
        case KDIMGSENSORIOC_T_CHECK_IS_ALIVE:
            i4RetValue = adopt_CAMERA_HW_CheckIsAlive();  -->读取器件的sensor ID来判断是否有硬件连上,给camera上电
            break;

         ...
}

int kdSetDriver(unsigned int* pDrvIndex)

{

ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT *pSensorList = NULL;

        u32 drvIdx[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {0,0};

g_invokeSocketIdx[i] = (CAMERA_DUAL_CAMERA_SENSOR_ENUM)((pDrvIndex[i]& KDIMGSENSOR_DUAL_MASK_MSB)>>KDIMGSENSOR_DUAL_SHIFT); 

  drvIdx[i] = (pDrvIndex[i] & KDIMGSENSOR_DUAL_MASK_LSB);  --> 位操作获取sensor的ID

pSensorList[drvIdx[i]].SensorInit(&g_pInvokeSensorFunc[i]);  -->调用init获取具体驱动的函数指针

}

你可能感兴趣的:(MTK6582平台gc_0328+2035Camera驱动笔记)