mt6737 camera 驱动代码分析

1.摄像头代码分析:

驱动函数入口: module_init(CAMERA_HW_i2C_init);
驱动函数出口: module_exit(CAMERA_HW_i2C_exit);

static int __init CAMERA_HW_i2C_init(void) {
i2c_register_board_info(SUPPORT_I2C_BUS_NUM1, &i2c_devs1, 1);
i2c_register_board_info(SUPPORT_I2C_BUS_NUM2, &i2c_devs2, 1); // 注册IIC平台信息,IIC组,设备类型和IIC地址

ret = platform_device_register(&camerahw_platform_device);
ret = platform_device_register(&camerahw2_platform_device);  // 注册摄像头平台设备

if (platform_driver_register(&g_stCAMERA_HW_Driver)) {  // 注册驱动
PK_ERR("failed to register CAMERA_HW driver\n");
return -ENODEV;
}
if (platform_driver_register(&g_stCAMERA_HW_Driver2)) {  // 注册驱动
PK_ERR("failed to register CAMERA_HW driver\n");
return -ENODEV;
}

proc_create("driver/camsensor", 0777, NULL, &fcamera_proc_fops);
proc_create("driver/camsensor2", 0777, NULL, &fcamera_proc_fops2);
proc_create("driver/camsensor3", 0777, NULL, &fcamera_proc_fops3);  // 创建设备节点

}

2.驱动函数接口
static struct platform_driver g_stCAMERA_HW_Driver = {
.probe = CAMERA_HW_probe,
.remove = CAMERA_HW_remove,
.suspend = CAMERA_HW_suspend,
.resume = CAMERA_HW_resume,
.driver = {
.name = “image_sensor”, // platform_device 在匹配时需要名字一样。
.owner = THIS_MODULE,

ifdef CONFIG_OF

.of_match_table = CAMERA_HW_of_ids,

endif

}

}

static int CAMERA_HW_probe(struct platform_device *pdev)
{
return i2c_add_driver(&CAMERA_HW_i2c_driver); // 注册IIC
}

struct i2c_driver CAMERA_HW_i2c_driver = {
.probe = CAMERA_HW_i2c_probe,
.remove = CAMERA_HW_i2c_remove,
.driver = {
.name = CAMERA_HW_DRVNAME1,
.owner = THIS_MODULE,

ifdef CONFIG_OF

.of_match_table = CAMERA_HW_i2c_of_ids,

endif

},
.id_table = CAMERA_HW_i2c_id,

};

static int CAMERA_HW_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
/* get sensor i2c client */
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient = client;
/* set I2C clock rate */
g_pstI2Cclient->timing = 100;/* 100k */
g_pstI2Cclient->ext_flag &= ~I2C_POLLING_FLAG; /* No I2C polling busy waiting */

spin_unlock(&kdsensor_drv_lock);

/* Register char driver */
i4RetValue = RegisterCAMERA_HWCharDrv();  // 注册字符设备

}

inline static int RegisterCAMERA_HWCharDrv(void)
{
if (alloc_chrdev_region(&g_CAMERA_HWdevno, 0, 1, CAMERA_HW_DRVNAME1)) //设置主次设备号
{
PK_DBG(“[CAMERA SENSOR] Allocate device no failed\n”);

return -EAGAIN;
}
/* Allocate driver */
g_pCAMERA_HW_CharDrv = cdev_alloc();  // 申请cdev 设备 

if (NULL == g_pCAMERA_HW_CharDrv)
{
unregister_chrdev_region(g_CAMERA_HWdevno, 1);

PK_DBG("[CAMERA SENSOR] Allocate mem for kobject failed\n");

return -ENOMEM;
}
/* Attatch file operation. */
cdev_init(g_pCAMERA_HW_CharDrv, &g_stCAMERA_HW_fops);  // 注册初始化字符设备;一般驱动中注册字符设备,多是利用字符设备的fops与上层交互,特别是ioctl .

g_pCAMERA_HW_CharDrv->owner = THIS_MODULE;

/* Add to system */
if (cdev_add(g_pCAMERA_HW_CharDrv, g_CAMERA_HWdevno, 1))
{
PK_DBG("[mt6516_IDP] Attatch file operation failed\n");

unregister_chrdev_region(g_CAMERA_HWdevno, 1);

return -EAGAIN;
}

sensor_class = class_create(THIS_MODULE, "sensordrv");
if (IS_ERR(sensor_class)) {
int ret = PTR_ERR(sensor_class);
PK_DBG("Unable to create class, err = %d\n", ret);
return ret;
}
sensor_device = device_create(sensor_class, NULL, g_CAMERA_HWdevno, NULL, CAMERA_HW_DRVNAME1);

return 0;

}

static const struct file_operations g_stCAMERA_HW_fops = // cdev 字符设备操作函数集
{
.owner = THIS_MODULE,
.open = CAMERA_HW_Open, //只用来计数目前打开的camera 的数量。
.release = CAMERA_HW_Release,
.unlocked_ioctl = CAMERA_HW_Ioctl, // 摄像头控制部分代码。

ifdef CONFIG_COMPAT

.compat_ioctl = CAMERA_HW_Ioctl_Compat,

endif

};

============ camera control core ================= // 为上下层提供交互的接口,
static long CAMERA_HW_Ioctl( struct file *a_pstFile, unsigned int a_u4Command, unsigned long a_u4Param )
{
int i4RetValue = 0;
void *pBuff = NULL;
u32 *pIdx = NULL;

mutex_lock(&kdCam_Mutex);

if (_IOC_NONE == _IOC_DIR(a_u4Command)) {
}
else {
pBuff = kmalloc(_IOC_SIZE(a_u4Command), GFP_KERNEL);

if (NULL == pBuff) {
    PK_DBG("[CAMERA SENSOR] ioctl allocate mem failed\n");
    i4RetValue = -ENOMEM;
    goto CAMERA_HW_Ioctl_EXIT;
}

if (_IOC_WRITE & _IOC_DIR(a_u4Command)) {
    if (copy_from_user(pBuff , (void *) a_u4Param, _IOC_SIZE(a_u4Command))) {
    kfree(pBuff);
    PK_DBG("[CAMERA SENSOR] ioctl copy from user failed\n");
    i4RetValue =  -EFAULT;
    goto CAMERA_HW_Ioctl_EXIT;
    }
}
}

pIdx = (u32 *)pBuff;
switch (a_u4Command) {  // ioctrl 命令解析 

if 0

case KDIMGSENSORIOC_X_POWER_ON:           /*imgesensor 上电工作*/
    i4RetValue = kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx, true, CAMERA_HW_DRVNAME);
    break;
case KDIMGSENSORIOC_X_POWER_OFF:  /* imgesensor 下电工作 */
    i4RetValue = kdModulePowerOn((CAMERA_DUAL_CAMERA_SENSOR_ENUM) *pIdx, false, CAMERA_HW_DRVNAME);
    break;

endif

case KDIMGSENSORIOC_X_SET_DRIVER:
    i4RetValue = kdSetDriver((unsigned int *)pBuff);   /* 调用kdSetDriver函数获得摄像头配置列表   */
    break;
case KDIMGSENSORIOC_T_OPEN:
    i4RetValue = adopt_CAMERA_HW_Open();  // 主要是摄像头上电以及完成初始化工作,对应摄像头驱动的open函数。
    break;
case KDIMGSENSORIOC_X_GETINFO:
    i4RetValue = adopt_CAMERA_HW_GetInfo(pBuff);   // 获得sensor信息对应摄像头驱动的get_info函数
    break;
    case KDIMGSENSORIOC_X_GETRESOLUTION2:
    i4RetValue = adopt_CAMERA_HW_GetResolution(pBuff);  // 获取摄像头在拍照 预览 录像的模式下的窗口大小
    break;
case KDIMGSENSORIOC_X_GETINFO2:
    i4RetValue = adopt_CAMERA_HW_GetInfo2(pBuff);  //获取摄像头信息,上报给应用层使用
    break;
case KDIMGSENSORIOC_X_FEATURECONCTROL:
    i4RetValue = adopt_CAMERA_HW_FeatureControl(pBuff);  // 设置摄像头各种功能模式,返回对应模式的值 对应摄像头feature_control函数
    break;
case KDIMGSENSORIOC_X_CONTROL:
    i4RetValue = adopt_CAMERA_HW_Control(pBuff);  // 初始化各种拍照模式,比如 预览 拍照 录像 高速拍照模式等参数
    break;
case KDIMGSENSORIOC_T_CLOSE:
    i4RetValue = adopt_CAMERA_HW_Close();  // 关闭摄像头,下电 对应回调摄像头close
    break;
    case KDIMGSENSORIOC_T_CHECK_IS_ALIVE:
    i4RetValue = adopt_CAMERA_HW_CheckIsAlive();  // 判断是否有前后摄存在,若存在获取摄像头名
    break;
case KDIMGSENSORIOC_X_GET_SOCKET_POS:
    i4RetValue = kdGetSocketPostion((unsigned int *)pBuff);  // 判断是否存在双摄像头(双后摄或者双前摄)
    break;
case KDIMGSENSORIOC_X_SET_I2CBUS:
    /* i4RetValue = kdSetI2CBusNum(*pIdx); */
    break;
case KDIMGSENSORIOC_X_RELEASE_I2C_TRIGGER_LOCK:
    /* i4RetValue = kdReleaseI2CTriggerLock(); */
    break;

case KDIMGSENSORIOC_X_SET_SHUTTER_GAIN_WAIT_DONE:
    i4RetValue = kdSensorSetExpGainWaitDone((int *)pBuff);  // 设置曝光等待时间
    break;

case KDIMGSENSORIOC_X_SET_CURRENT_SENSOR:
    i4RetValue = kdSetCurrentSensorIdx(*pIdx);  // 设置摄像头是前摄还是后摄
    break;

case KDIMGSENSORIOC_X_SET_MCLK_PLL:   
    i4RetValue = kdSetSensorMclk(pBuff); // 重新设置pclk值  48MHZ/52MHZ
    break;

case KDIMGSENSORIOC_X_SET_GPIO:
    i4RetValue = kdSetSensorGpio(pBuff);  //设置mipi连接方式
    break;

case KDIMGSENSORIOC_X_GET_ISP_CLK:
    //PK_DBG("get_isp_clk=%d\n",get_isp_clk());
    //*(unsigned int*)pBuff = get_isp_clk();
    break;

default:
    PK_DBG("No such command\n");
    i4RetValue = -EPERM;
    break;

}

if (_IOC_READ & _IOC_DIR(a_u4Command)) {
if (copy_to_user((void __user *) a_u4Param , pBuff , _IOC_SIZE(a_u4Command))) {   // 回传数据到应用层
    kfree(pBuff);
    PK_DBG("[CAMERA SENSOR] ioctl copy to user failed\n");
    i4RetValue =  -EFAULT;
    goto CAMERA_HW_Ioctl_EXIT;
}
}

kfree(pBuff);

CAMERA_HW_Ioctl_EXIT:
mutex_unlock(&kdCam_Mutex);
return i4RetValue;
}
/**
** 获取新的摄像头列表和前后摄的ID
**/
int kdSetDriver(unsigned int *pDrvIndex)
{
ACDK_KD_SENSOR_INIT_FUNCTION_STRUCT *pSensorList = NULL;
u32 drvIdx[KDIMGSENSOR_MAX_INVOKE_DRIVERS] = {0, 0};
u32 i;

/* set driver for MAIN or SUB sensor */
PK_INF("pDrvIndex:0x%08x/0x%08x\n", pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_0], pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_1]);
/* Camera information */
gDrvIndex = pDrvIndex[KDIMGSENSOR_INVOKE_DRIVER_0];

if (0 != kdGetSensorInitFuncList(&pSensorList))  //获得 sensorlist   
{
PK_ERR("ERROR:kdGetSensorInitFuncList()\n");
return -EIO;
}

for (i = KDIMGSENSOR_INVOKE_DRIVER_0; i < KDIMGSENSOR_MAX_INVOKE_DRIVERS; i++) {
    /*  */
    spin_lock(&kdsensor_drv_lock);
    g_bEnableDriver[i] = FALSE;
    g_invokeSocketIdx[i] = (CAMERA_DUAL_CAMERA_SENSOR_ENUM)((pDrvIndex[i] & KDIMGSENSOR_DUAL_MASK_MSB)>>KDIMGSENSOR_DUAL_SHIFT);   // 高16位 ===> 前摄ID
    spin_unlock(&kdsensor_drv_lock);
    drvIdx[i] = (pDrvIndex[i] & KDIMGSENSOR_DUAL_MASK_LSB); // 低16位  ==> 后摄ID
    /*  */
    if (DUAL_CAMERA_NONE_SENSOR == g_invokeSocketIdx[i]) { continue; }  // 判断ID 位时过滤掉。
#if 0
            if (DUAL_CAMERA_MAIN_SENSOR == g_invokeSocketIdx[i] || DUAL_CAMERA_SUB_SENSOR == g_invokeSocketIdx[i] || DUAL_CAMERA_MAIN_2_SENSOR == g_invokeSocketIdx[i]) {
            spin_lock(&kdsensor_drv_lock);
            gI2CBusNum = SENSOR_I2C_BUS_NUM[g_invokeSocketIdx[i]];
            spin_unlock(&kdsensor_drv_lock);
            PK_XLOG_INFO("kd_MultiSensorOpen: switch I2C BUS%d\n", gI2CBusNum);
            }
#else

    if (DUAL_CAMERA_SUB_SENSOR == g_invokeSocketIdx[i]) {  // ID 为前摄时 设置I2C
        spin_lock(&kdsensor_drv_lock);
        gI2CBusNum = SUPPORT_I2C_BUS_NUM2;
        spin_unlock(&kdsensor_drv_lock);
         /* PK_XLOG_INFO("kdSetDriver: switch I2C BUS2\n"); */
    }
    else {  // id 不为前摄时设置I2C。
        spin_lock(&kdsensor_drv_lock);
        gI2CBusNum = SUPPORT_I2C_BUS_NUM1;
        spin_unlock(&kdsensor_drv_lock);
         /* PK_XLOG_INFO("kdSetDriver: switch I2C BUS1\n"); */
    }
#endif
        PK_INF("g_invokeSocketIdx[%d]=%d,drvIdx[%d]=%d\n", i, g_invokeSocketIdx[i], i, drvIdx[i]);
    //PK_INF("[kdSetDriver]drvIdx[%d] = %d\n", i, drvIdx[i]);
    /*  */
    if (MAX_NUM_OF_SUPPORT_SENSOR > drvIdx[i]) {   // 最大同时支持imgesensor 数为16个。
        if (NULL == pSensorList[drvIdx[i]].SensorInit) {
        PK_ERR("ERROR:kdSetDriver()\n");
        return -EIO;
        }

        pSensorList[drvIdx[i]].SensorInit(&g_pInvokeSensorFunc[i]);  // 调用我们所取得snsor的SensorInit函数
        if (NULL == g_pInvokeSensorFunc[i]) {
        PK_ERR("ERROR:NULL g_pSensorFunc[%d]\n", i);
        return -EIO;
        }
        /*  */
        spin_lock(&kdsensor_drv_lock);
        g_bEnableDriver[i] = TRUE;    // 设置是能imgesensor ,
        spin_unlock(&kdsensor_drv_lock);
        /* get sensor name */
                    memcpy((char *)g_invokeSensorNameStr[i], (char *)pSensorList[drvIdx[i]].drvname, sizeof(pSensorList[drvIdx[i]].drvname));  // 获得imgesensor ID的名称。
        /* return sensor ID */
        /* pDrvIndex[0] = (unsigned int)pSensorList[drvIdx].SensorId; */
        PK_INF("[%d][%d][%d][%s][%d]\n", i, g_bEnableDriver[i], g_invokeSocketIdx[i], g_invokeSensorNameStr[i], sizeof(pSensorList[drvIdx[i]].drvname));
    }
}
return 0;

}

你可能感兴趣的:(驱动代码分析)