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,
.of_match_table = CAMERA_HW_of_ids,
}
}
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,
.of_match_table = CAMERA_HW_i2c_of_ids,
},
.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, // 摄像头控制部分代码。
.compat_ioctl = CAMERA_HW_Ioctl_Compat,
};
============ 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 命令解析
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;
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;
}