一,Camera架构及流程简析
整个框架分为三个部分:hal部分逻辑调用,kernel层的通用驱动 sensorlist.c 和 具体IC的驱动 xxxx_mipi_raw.c。kernel 起来后不会直接去访问硬件sensor,而是会注册相关的驱动,之后Android系统起来后会启动相关的服务如 :camera_service,在camera服务中会直接去访问hal,kernel驱动,进而操作camera。
-Kernel部分主要有两块:一块是imagesensor驱动,负责具体型号的sensor的id检测,上电,以及在preview,capture,初始化,3A等等功能设定时的寄存器配置。另一块是ispdriver,通过DMA将sensor数据流上传。
-HAL层这边主要分3块:一块是imageio,主要是数据buffer上传的pipe。一块是drv,包含imgsensor和isp的hal层控制。最后是featureio,包含各种3A等性能配置。
流程图:
主要发生在两个时间点:开机过程中camera的动作以及打开应用时camera的动作。
-开机时:camera完成了sensor框架的初始化,id检测,以及上下电操作。
-打开应用时:camera会有上电,完成寄存器的初始配置,向上层传送基本参数及配置信息,以及preview和capture模式循环。
二,配置相关文件
(下面的文件如不知道路径,请在代码中查找)
1,系统配置文件---ProjectConfig.mk
2,Sensor ID 和一些枚举类型的定义---kd_imgsensor.h,kd_imgsensor_define.h
定义sensor id和sensor name
此处填写正确的sensor ID
#define OV5648MIPI_SENSOR_ID 0x5648
此处填写的字符串包含 sensor的 part no 、格式(YUV or RAW)
#define SENSOR_DRVNAME_OV5648_MIPI_RAW "ov5648_mipi_raw"
3,kd_sensorlist.h,sensorlist.cpp
声明初始化函数
UINT32 OV5648MIPI_RAW_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc);
kdSensorList[] :
#if defined(OV5648_MIPI_RAW) //与xxxxxSensor.c中的函数名对应,即驱动文件夹名大写
{OV5648MIPI_SENSOR_ID, SENSOR_DRVNAME_OV5648_MIPI_RAW, OV5648MIPI_RAW_SensorInit},
#endif
SensorList[] :
#if defined(OV5648_MIPI_RAW)
YUV_INFO(OV5648MIPI_SENSOR_ID,SENSOR_DRVNAME_OV5648_MIPI_RAW, NULL),
#endif
sensor 在kdSensorList[] 中的顺序必须和SensorList[]中的顺序保持一致 ,通常按照resolution从大到小的顺序依次排列下来。
4,hal层--camera_info_ov5648mipiraw.h
#define SENSOR_ID OV5648MIPI_SENSOR_ID
#define SENSOR_DRVNAME SENSOR_DRVNAME_OV5648_MIPI_RAW //为kd_imgsensor.h中定义的宏
5,AF定义---lenslist.cpp
MSDK_LENS_INIT_FUNCTION_STRUCT LensList_main[MAX_NUM_OF_SUPPORT_LENS] =
{
#if defined(AD5820AF)
{OV5648MIPI_SENSOR_ID, AD5820AF_LENS_ID, "AD5820AF", pAD5820AF_getDefaultData},
#endif
}
{ YOUR SENSOR ID(在kd_imgsensor.h里面定义的一致),LENS ID(不用改变),“lens名称”(不需要改),Lens Para(不需要改)}
三,驱动代码分析
(有点长,是按照代码的调用逻辑排版的,所以会有点乱,边看边阅读代码会比较好理解)
1,kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt6580\kd_sensorlist.c
在驱动装载函数 CAMERA_HW_i2C_init 中注册了 platform driver
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", //驱动名称
.owner = THIS_MODULE,
#ifdef CONFIG_OF //与设备树的形式进行匹配
.of_match_table = CAMERA_HW_of_ids,
#endif
}
};
if (platform_driver_register(&g_stCAMERA_HW_Driver)) { // 注册platform总线的driver
PK_ERR("failed to register CAMERA_HW driver\n");
return -ENODEV;
}
与设备树里的 platform device 匹配成功后调用 CAMERA_HW_probe 方法注册 i2c driver
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_probe(struct platform_device *pdev)
{
#if !defined(CONFIG_MTK_LEGACY)
mtkcam_gpio_init(pdev);
mtkcam_pin_mux_init(pdev);
#endif
return i2c_add_driver(&CAMERA_HW_i2c_driver); //注册 i2c driver
}
I2c匹配成功之后调用 CAMERA_HW_i2c_probe 方法
static int CAMERA_HW_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int i4RetValue = 0;
PK_DBG("[CAMERA_HW] Attach I2C\n");
/* get sensor i2c client */
spin_lock(&kdsensor_drv_lock);
g_pstI2Cclient = client; //这里是获得我们的clientdevice,并且以platform方式进行注册
/* 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