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);  // 创建设备节点

}

平台设备函数接口:

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
    }
}

probe函数注册i2c设别驱动:

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

i2c驱动接口结构体实现:

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,
};

i2c探测函数实现:

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();  // 注册字符设备
}

注册字符设别驱动,camera相关节点;

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;
}

cdev 字符设备操作函数集:


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 与hal 层交互接口:

============ 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函数
        breakcase 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;
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值