我是靠谱客的博主 霸气画板,最近开发中收集的这篇文章主要介绍Camera4 MTK camera驱动结构介绍,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、概述:

  MTK  camera主要的内容在hal层,现在有hal1/hal3,当下主流的使用的是hal3,驱动主要负责sensor

电源的控制以及sensor相关寄存器的操作,MTK采用设备和驱动分离的思想,抽象出imgsensor.c来控制

sensor的上下电以及sensor具体的操作,结构图如下:

    

二、sensorDriver介绍:

  Sensordriver的对上响应需求,对下控制sensor硬件行为,处理器通过I2C 接口来控制sensor的

大部分行为,sensor输出的数据传输到TG、ISP等模块处理后,ISP将数据保存到内存中之后,才可以

dump出sensor的数据,才能看到sensor的第一帧画面。这节主要介绍sensordriver的代码。

1、sensorDriver函数结构体:

(1)imgsensor_mode_struct不同模式特征的结构体:

  这个结构体描叙了各个模式下的pclk/linelength/framelength 等:

struct imgsensor_mode_struct {
	kal_uint32 pclk;
	kal_uint32 linelength;
	kal_uint32 framelength;

	kal_uint8 startx;
	kal_uint8 starty;

	kal_uint16 grabwindow_width;
	kal_uint16 grabwindow_height;

	/* MIPIDataLowPwr2HighSpeedSettleDelayCount by different scenario */
	kal_uint8 mipi_data_lp2hs_settle_dc;

	/*	 following for GetDefaultFramerateByScenario()	*/
	kal_uint16 max_framerate;
	kal_uint32 mipi_pixel_rate;
};

  对应的描叙信息如下:pclk ≈ linelength * frame_length * framerate:

static kal_uint32 set_max_framerate_by_scenario(enum MSDK_SCENARIO_ID_ENUM scenario_id, MUINT32 framerate)
{
	kal_uint32 frame_length;

	switch (scenario_id) {
	case MSDK_SCENARIO_ID_CAMERA_PREVIEW:
		frame_length = imgsensor_info.pre.pclk / framerate * 10 / imgsensor_info.pre.linelength;//计算frame_length
		spin_lock(&imgsensor_drv_lock);
		imgsensor.dummy_line = (frame_length > imgsensor_info.pre.framelength) ?
			(frame_length - imgsensor_info.pre.framelength) : 0;
		imgsensor.frame_length = imgsensor_info.pre.framelength + imgsensor.dummy_line;
		imgsensor.min_frame_length = imgsensor.frame_length;
		spin_unlock(&imgsensor_drv_lock);
		set_dummy(); //更新新的frame_length
		break;
}

sensor的linelength是固定的,每个模式的pclk也是不可调的,所以要调整帧率framerate,只能调整frame_length。

set_dummy使得当前帧率立刻变化为设置的帧率,如果pclk或者linelength与对应sensor setting的实际值不一致,

设置的帧率和响应的帧率会有一个偏差,画面可能出现水波纹:

 

(2)struct imgsensor_info_struct描叙sensor info常量的结构体:

struct imgsensor_info_struct {
	kal_uint32 sensor_id;                      /*record sensor id defined in Kd_imgsensor.h*/
	kal_uint32 checksum_value;                 /*checksum value for Camera Auto Test*/
//不同mode 的信息
	struct imgsensor_mode_struct pre;          /*preview scenario relative information*/
	struct imgsensor_mode_struct cap;          /*capture scenario relative information*/
	struct imgsensor_mode_struct cap1;
	struct imgsensor_mode_struct cap2;
	struct imgsensor_mode_struct normal_video; /*normal video  scenario relative information*/
	struct imgsensor_mode_struct hs_video;     /*high speed video scenario relative information*/
	struct imgsensor_mode_struct slim_video;   /*slim video for VT scenario relative information*/
//支持的功能
	kal_uint8  ae_shut_delay_frame;            /*shutter delay frame for AE cycle*/
	kal_uint8  ae_sensor_gain_delay_frame;     /*sensor gain delay frame for AE cycle*/
	kal_uint8  ae_ispGain_delay_frame;         /*isp gain delay frame for AE cycle*/
	kal_uint8  ihdr_support;                   /*1, support; 0,not support*/
	kal_uint8  ihdr_le_firstline;              /*1,le first ; 0, se first*/
	kal_uint8  sensor_mode_num;                /*support sensor mode num*/
//丢帧处理(丢掉不稳定帧的数据)
	kal_uint8  cap_delay_frame;                /*enter capture delay frame num*/
	kal_uint8  pre_delay_frame;                /*enter preview delay frame num*/
	kal_uint8  video_delay_frame;              /*enter video delay frame num*/
	kal_uint8  hs_video_delay_frame;           /*enter high speed video  delay frame num*/
	kal_uint8  slim_video_delay_frame;         /*enter slim video delay frame num*/
	kal_uint8  margin;                         /*sensor framelength & shutter margin*/
	kal_uint32 min_shutter;                    /*min shutter*/
	kal_uint32 max_frame_length;               /*max framelength by sensor register's limitation*/
//isp驱动电流,电流过大可能会射频干扰
	kal_uint8  isp_driving_current;            /*mclk driving current*/
	kal_uint8  sensor_interface_type;          /*sensor_interface_type*/
	kal_uint8  mipi_sensor_type;
	/*0,MIPI_OPHY_NCSI2; 1,MIPI_OPHY_CSI2, default is NCSI2, don't modify this para*/
	/*don't modify this para*/
	kal_uint8  mipi_settle_delay_mode;
	/*0, high speed signal auto detect; 1, use settle delay,unit is ns, */
	kal_uint8  sensor_output_dataformat;       /*sensor output first pixel color*/
	kal_uint8  mclk;                           /*mclk value, suggest 24 or 26 for 24Mhz or 26Mhz*/
	kal_uint8  mipi_lane_num;                  /*mipi lane num*/
	kal_uint8  i2c_addr_table[5];
	/*record sensor support all write id addr, only supprt 4must end with 0xff*/
};

(3)struct imgsensor_struct记录sensor info变量的结构体,用于动态的保存sensor的关键信息:

struct imgsensor_struct {
//记录当前是normal, or H mirror, or V flip,or both H& V
	kal_uint8  mirror;                        /*mirrorflip information*/
//记录当前处于哪种mode(init/preview/capture/video)
	kal_uint8  sensor_mode;                   /*record IMGSENSOR_MODE enum value*/
//记录当前的shutter值
	kal_uint32 shutter;                       /*current shutter*/
//记录当前的sensor gain值
	kal_uint16 gain;                          /*current gain*/
	kal_uint32 pclk;                          /*current pclk*/
	kal_uint32 frame_length;                  /*current framelength*/
	kal_uint32 line_length;                   /*current linelength*/
	kal_uint32 min_frame_length;              /*current min  framelength to max framerate*/
//记录当前的dummy pixel, dummy line的值
	kal_uint16 dummy_pixel;                   /*current dummypixel*/
	kal_uint16 dummy_line;                    /*current dummline*/
	kal_uint16 current_fps;                   /*current max fps*/
	kal_bool   autoflicker_en;                /*record autoflicker enable or disable*/
	kal_bool   test_pattern;                  /*record test pattern mode or not*/
//记录当前处于哪个scenario( preview/capture/video)
	enum MSDK_SCENARIO_ID_ENUM current_scenario_id;/*current scenario id*/
	kal_bool   ihdr_en;                       /*ihdr enable or disable*/
//记录当前i2c使用的address
	kal_uint8  i2c_write_id;                  /*record current sensor's i2c write id*/
};

 

2、驱动入口xxxx_MIPI_RAW_SensorInit:

  可以看到SensorInit以函数指针的形式传入到kdSensorList结构体中:

//kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.c
struct IMGSENSOR_INIT_FUNC_LIST kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] = {
    #if defined(XXXXX_MIPI_RAW)
            {XXXXX_SENSOR_ID,
            SENSOR_DRVNAME_XXXXX_MIPI_RAW,
            XXXXX_MIPI_RAW_SensorInit},
    #endif
    ......
}

UINT32 XXXXX_MIPI_RAW_SensorInit(struct SENSOR_FUNCTION_STRUCT **pfFunc)
{
	/* Check Sensor status here */
	if (pfFunc != NULL)
		*pfFunc = &sensor_func;
	return ERROR_NONE;
}

  SENSOR_FUNCTION_STRUCT这个结构体包含了所有sensorDriver的操作接口:

struct SENSOR_FUNCTION_STRUCT {
	MUINT32 (*SensorOpen)(void);
	MUINT32 (*SensorGetInfo)(enum MSDK_SCENARIO_ID_ENUM ScenarioId,
	    MSDK_SENSOR_INFO_STRUCT *pSensorInfo,
	    MSDK_SENSOR_CONFIG_STRUCT *pSensorConfigData);

	MUINT32 (*SensorGetResolution)(
	    MSDK_SENSOR_RESOLUTION_INFO_STRUCT * pSensorResolution);

	MUINT32 (*SensorFeatureControl)(MSDK_SENSOR_FEATURE_ENUM FeatureId,
	    MUINT8 *pFeaturePara,
	    MUINT32 *pFeatureParaLen);

	MUINT32 (*SensorControl)(enum MSDK_SCENARIO_ID_ENUM ScenarioId,
	    MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *pImageWindow,
	    MSDK_SENSOR_CONFIG_STRUCT *pSensorConfigData);

	MUINT32 (*SensorClose)(void);

	MUINT8  arch;
	void   *psensor_inst; /* IMGSENSOR_SENSOR_INST */
};

  对应驱动中填充的信息如下:

static struct SENSOR_FUNCTION_STRUCT sensor_func = {
	open,//打开camera时调用
	get_info,// 获取sensor的动态信息
	get_resolution,//获取sensor特定模式下的尺寸
	feature_control,
	control,
	close
};

 

3、open 函数介绍及其所完成的任务:

  (1)此函每次打开camera都会调用;

  (2)读取sensorid,确保I2C通讯正常;

  (3)调用sensor_init初始化sensor芯片;

  (4)初始化imgsensor结构体中的变量;

  (5)读取otp中信息;

static kal_uint32 open(void)
{
    //获取sensor的ID确认i2c是否正常
  sensor_id = return_sensor_id();
    //设置I2C 的速率
    kdSetI2CSpeed(400);
    //sensor初始化参数设置
    sensor_init();
    //初始化imgsensor结构体
	imgsensor.autoflicker_en = KAL_FALSE;
	imgsensor.sensor_mode = IMGSENSOR_MODE_INIT;
	imgsensor.pclk = imgsensor_info.pre.pclk;
	imgsensor.frame_length = imgsensor_info.pre.framelength;
	imgsensor.line_length = imgsensor_info.pre.linelength;
	imgsensor.min_frame_length = imgsensor_info.pre.framelength;
	imgsensor.dummy_pixel = 0;
	imgsensor.dummy_line = 0;
	imgsensor.ihdr_en = 0;
	imgsensor.test_pattern = KAL_FALSE;
	imgsensor.current_fps = imgsensor_info.pre.max_framerate;
}

4、feature_control接口:

(1)获取linelength和pclk:

	case SENSOR_FEATURE_GET_PERIOD:
		*feature_return_para_16++ = imgsensor.line_length;
		*feature_return_para_16 = imgsensor.frame_length;
		*feature_para_len = 4;
		break;
	case SENSOR_FEATURE_GET_PIXEL_CLOCK_FREQ:
		*feature_return_para_32 = imgsensor.pclk;
		*feature_para_len = 4;
		break;

获取各个mode的sensor pclk(pixel/s),PCLK指pixel采样的时钟,

linelength, 结合pclk来计算linetime, 用来换算ae plinetable的exposure time对应的shutter (unit: line,条数)。

(2)set_shutter设置曝光行:

	case SENSOR_FEATURE_SET_ESHUTTER:
		set_shutter(*feature_data);
		break;

设置曝光行,曝光行物理上小于frame_length,所以曝光行大于当前frame_length时,frame_length会自动撑长,

帧率降低所以亮度较低时,帧率会下降,因为这时候shutter比较大。每个AE周期会根据AE算法找到的对应pline

table中相应index的exp转换为shutter下给driver。

(3)streaming_control控制sensor输出数据:

	case SENSOR_FEATURE_SET_STREAMING_SUSPEND:
		pr_info("SENSOR_FEATURE_SET_STREAMING_SUSPENDn");
		streaming_control(KAL_FALSE);
		break;
	case SENSOR_FEATURE_SET_STREAMING_RESUME:
		pr_info("SENSOR_FEATURE_SET_STREAMING_RESUME, shutter:%llun",
				*feature_data);
		if (*feature_data != 0)
			set_shutter(*feature_data);
		streaming_control(KAL_TRUE);
		break;

  在打开sensor输出数据前,需要先设置shutter。

5、control 模式切换函数:

static kal_uint32 control(enum MSDK_SCENARIO_ID_ENUM scenario_id, MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window,
	MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data)
{
	spin_lock(&imgsensor_drv_lock);
	imgsensor.current_scenario_id = scenario_id;
	spin_unlock(&imgsensor_drv_lock);
	switch (scenario_id) {
	case MSDK_SCENARIO_ID_CAMERA_PREVIEW:
		preview(image_window, sensor_config_data);
		break;
	case MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG:
		capture(image_window, sensor_config_data);
		break;
	case MSDK_SCENARIO_ID_VIDEO_PREVIEW:
		normal_video(image_window, sensor_config_data);
		break;
	case MSDK_SCENARIO_ID_HIGH_SPEED_VIDEO:
		hs_video(image_window, sensor_config_data);
		break;
	case MSDK_SCENARIO_ID_SLIM_VIDEO:
		slim_video(image_window, sensor_config_data);
		break;
	}
	return ERROR_NONE;
}

以preview为例说明流程:

static kal_uint32 preview(MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window,
	MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data)
{
//更新imgsensor结构体信息
	spin_lock(&imgsensor_drv_lock);
	imgsensor.sensor_mode = IMGSENSOR_MODE_PREVIEW;
	imgsensor.pclk = imgsensor_info.pre.pclk;
	/* imgsensor.video_mode = KAL_FALSE; */
	imgsensor.line_length = imgsensor_info.pre.linelength;
	imgsensor.frame_length = imgsensor_info.pre.framelength;
	imgsensor.min_frame_length = imgsensor_info.pre.framelength;
	imgsensor.autoflicker_en = KAL_TRUE;
	spin_unlock(&imgsensor_drv_lock);
//更新寄存器
	preview_setting();
	return ERROR_NONE;
}

 

作者:frank_zyp
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文无所谓版权,欢迎转载。

最后

以上就是霸气画板为你收集整理的Camera4 MTK camera驱动结构介绍的全部内容,希望文章能够帮你解决Camera4 MTK camera驱动结构介绍所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)

评论列表共有 0 条评论

立即
投稿
返回
顶部