我是靠谱客的博主 刻苦季节,最近开发中收集的这篇文章主要介绍Mtk Camera Hal到驱动的流程(3),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

(1)Camera成像原理

(A)成像原理

  • 物体通过镜头(lens)生成的光学图像投射到图像传感器上(CMOS/CCD集成电路),把光信号转换为电信号;
  • 然后经过A/D(模数转换)转换后变为数字图像信号(图像处理器ISP处理);
  • 在送到数字信号处理器中处理(DSP)转换成标准的GRB、YUV等格式图像信号;

在这里插入图片描述
(B)相机包含四大件

镜头(lens)、图像传感器(sensor)、图像处理器(ISP)、数字信号处理器(DSP)

  • 镜头(lens)是相机的灵魂,镜头(lens)对成像的效果有很重要的作用,是利用透镜的折射原理,景物光线通过镜头,在聚焦平面上形成清晰的影像,通过感光材料CMOS或CCD感光器记录景物的影像;
  • 图像传感器(sensor)是一种半导体芯片,其表面包含几十万到几百万的光电二极管,二极管受到光照时就会产生电荷。目前主要有两种CCD,一种是广泛使用的CCD(电荷藕合)元件,另一种是CMOS(互补金属氧化物导体)器件;
  • ISP的性能是决定是否流畅的关键;
  • 数字信号处理器(DSP)是将感光芯片获得的数据及时快速地传递到中央处理器并刷新感光芯片,因此DSP芯片的好坏,直接影响画面品质(比如色彩饱和度,清晰度等);

(C)图像输出格式

常见的输出格式:YUV格式、RGB格式、Rawdata格式

  • YUV格式:"Y"表示明亮度 ,"U"和 "V"则是色度、浓度,一般情况下sensor支持YUV422格式,即数据格式是按Y-U-Y-V次序输出的;
  • RGB格式:传统的红绿蓝格式,比如RGB565/RGB8888,采用这种编码方法,每种颜色都可用三个变量来表示红色、绿色以及蓝色的强度。每一个像素有三原色R红色、G绿色、B蓝色组成;
  • 图像感应器将捕捉到的光源信号转化为数字信号的原始数据。RAW文件是一种记录了数码相机传感器的原始信息,同时记录了由相机拍摄所产生的一些原数据( Metadata,如ISO的设置、快门速度、光圈值、白平衡等)的文件;

(2)Sensor Drv结构

在这里插入图片描述
首先看一下Sensor Drv的头文件相关。

/* SENSOR MIRROR FLIP INFO */
#define GC08A3_MIRROR_NORMAL    0
#define GC08A3_MIRROR_H         0
#define GC08A3_MIRROR_V         0
#define GC08A3_MIRROR_HV        1

#if GC08A3_MIRROR_NORMAL
#define GC08A3_MIRROR	        0x00
#elif GC08A3_MIRROR_H
#define GC08A3_MIRROR	        0x01
#elif GC08A3_MIRROR_V
#define GC08A3_MIRROR	        0x02
#elif GC08A3_MIRROR_HV
#define GC08A3_MIRROR	        0x03
#else
#define GC08A3_MIRROR	        0x00
#endif

#define SENSOR_BASE_GAIN           0x40
#define SENSOR_MAX_GAIN            (16 * SENSOR_BASE_GAIN)

enum{
	IMGSENSOR_MODE_INIT,
	IMGSENSOR_MODE_PREVIEW,
	IMGSENSOR_MODE_CAPTURE,
	IMGSENSOR_MODE_VIDEO,
	IMGSENSOR_MODE_HIGH_SPEED_VIDEO,
	IMGSENSOR_MODE_SLIM_VIDEO,
};

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;
	kal_uint32 mipi_pixel_rate;
	kal_uint8  mipi_data_lp2hs_settle_dc;
	kal_uint16 max_framerate;
};

/* SENSOR PRIVATE STRUCT FOR VARIABLES */
struct imgsensor_struct {
	kal_uint8 mirror;
	kal_uint8 sensor_mode;
	kal_uint32 shutter;
	kal_uint16 gain;
	kal_uint32 pclk;
	kal_uint32 frame_length;
	kal_uint32 line_length;
	kal_uint32 min_frame_length;
	kal_uint16 dummy_pixel;
	kal_uint16 dummy_line;
	kal_uint16 current_fps;
	kal_bool   autoflicker_en;
	kal_bool   test_pattern;
	enum MSDK_SCENARIO_ID_ENUM current_scenario_id; /* current scenario id */
	kal_uint8  ihdr_en;
	kal_uint8 i2c_write_id;
};

/* SENSOR PRIVATE STRUCT FOR CONSTANT */
struct imgsensor_info_struct {
	kal_uint32 sensor_id;
	kal_uint32 checksum_value;
	struct imgsensor_mode_struct pre;
	struct imgsensor_mode_struct cap;
	struct imgsensor_mode_struct cap1;
	struct imgsensor_mode_struct normal_video;
	struct imgsensor_mode_struct hs_video;
	struct imgsensor_mode_struct slim_video;
	kal_uint8  ae_shut_delay_frame;
	kal_uint8  ae_sensor_gain_delay_frame;
	kal_uint8  ae_ispGain_delay_frame;
	kal_uint8  ihdr_support;
	kal_uint8  ihdr_le_firstline;
	kal_uint8  sensor_mode_num;
	kal_uint8  cap_delay_frame;
	kal_uint8  pre_delay_frame;
	kal_uint8  video_delay_frame;
	kal_uint8  hs_video_delay_frame;
	kal_uint8  slim_video_delay_frame;
	kal_uint8  margin;
	kal_uint32 min_shutter;
	kal_uint32 max_frame_length;
	kal_uint8  isp_driving_current;
	kal_uint8  sensor_interface_type;
	kal_uint8  mipi_sensor_type;
	kal_uint8  mipi_settle_delay_mode;
	kal_uint8  sensor_output_dataformat;
	kal_uint8  mclk;
	kal_uint8  mipi_lane_num;
	kal_uint8  i2c_addr_table[5];
	kal_uint32 i2c_speed;
	
	kal_uint8 min_gain;
	kal_uint32 max_gain;
	kal_uint8 min_gain_iso;
	kal_uint8 gain_step;
	kal_uint8 gain_type;
};

extern int iReadRegI2C(u8 *a_pSendData, u16 a_sizeSendData, u8 *a_pRecvData, u16 a_sizeRecvData, u16 i2cId);
extern int iWriteRegI2C(u8 *a_pSendData, u16 a_sizeSendData, u16 i2cId);
extern int iWriteRegI2CTiming(u8 *a_pSendData, u16 a_sizeSendData, u16 i2cId, u16 timing);
extern int iBurstWriteReg_multi(u8 *pData, u32 bytes, u16 i2cId, u16 transfer_length, u16 timing);

#endif

(A)控制Flip + Mirror效果

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.h

#define GC08A3_MIRROR_NORMAL    0
#define GC08A3_MIRROR_H         0
#define GC08A3_MIRROR_V         0
#define GC08A3_MIRROR_HV        1

#if GC08A3_MIRROR_NORMAL
#define GC08A3_MIRROR	        0x00
#elif GC08A3_MIRROR_H
#define GC08A3_MIRROR	        0x01
#elif GC08A3_MIRROR_V
#define GC08A3_MIRROR	        0x02
#elif GC08A3_MIRROR_HV
#define GC08A3_MIRROR	        0x03
#else
#define GC08A3_MIRROR	        0x00
#endif

(B)struct imgsensor_mode_struct不同模式特征的结构体:这个结构体描叙了各个模式下的pclk/linelength/framelength 等。

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.h

enum{
	IMGSENSOR_MODE_INIT,
	IMGSENSOR_MODE_PREVIEW,
	IMGSENSOR_MODE_CAPTURE,
	IMGSENSOR_MODE_VIDEO,
	IMGSENSOR_MODE_HIGH_SPEED_VIDEO,
	IMGSENSOR_MODE_SLIM_VIDEO,
};

struct imgsensor_mode_struct {
	kal_uint32 pclk;                    /*record different mode's pclk*/
	kal_uint32 linelength;              /*record different mode's linelength*/
	kal_uint32 framelength;             /*record different mode's framelength*/
	kal_uint8  startx;                  /*record different mode's startx of grabwindow*/
	kal_uint8  starty;                  /*record different mode's startx of grabwindow*/
	kal_uint16 grabwindow_width;        /*record different mode's width of grabwindow*/
	kal_uint16 grabwindow_height;       /*record different mode's height of grabwindow*/
	/* following for MIPIDataLowPwr2HighSpeedSettleDelayCount by different scenario */
	kal_uint8  mipi_data_lp2hs_settle_dc;
	/* following for GetDefaultFramerateByScenario() */
	kal_uint32 mipi_pixel_rate;
	kal_uint16 max_framerate;
};

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c
static struct imgsensor_info_struct imgsensor_info = {
	.sensor_id = GC8034_SENSOR_ID,       /*record sensor id defined in Kd_imgsensor.h*/
	.checksum_value = 0x1b375588,		//0xa11f4e23,            /*checksum value for Camera Auto Test*/

	.pre = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,                /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85, /*unit, ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},

	.cap = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85, /*unit, ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	//...
};

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

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

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

	LOG_INF("scenario_id = %d, framerate = %dn", scenario_id, framerate);

	switch (scenario_id) {
	case MSDK_SCENARIO_ID_CAMERA_PREVIEW:
		frame_length = imgsensor_info.pre.pclk / framerate * 10 / imgsensor_info.pre.linelength;
		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);
    	if(imgsensor.frame_length > imgsensor.shutter)
		{
			set_dummy();
		}
		break;
	case MSDK_SCENARIO_ID_VIDEO_PREVIEW:
		if (framerate == 0)
			return ERROR_NONE;
		frame_length = imgsensor_info.normal_video.pclk / framerate * 10 /
			imgsensor_info.normal_video.linelength;
		spin_lock(&imgsensor_drv_lock);
		imgsensor.dummy_line = (frame_length > imgsensor_info.normal_video.framelength) ?
			(frame_length - imgsensor_info.normal_video.framelength) : 0;
		imgsensor.frame_length = imgsensor_info.normal_video.framelength + imgsensor.dummy_line;
		imgsensor.min_frame_length = imgsensor.frame_length;
		spin_unlock(&imgsensor_drv_lock);
    	if(imgsensor.frame_length > imgsensor.shutter)
		{
			set_dummy();
		}
		break;
		//...
}

static void set_dummy(void)
{
	write_cmos_sensor(0x0340, imgsensor.frame_length);
	LOG_INF("frame length = %dn", imgsensor.frame_length);
}

sensor的linelength是固定的,每个模式的pclk也是不可调的,所以要调整帧率framerate,只能调整frame_length。set_dummy使得当前帧率立刻变化为设置的帧率。

(C)struct imgsensor_info_struct描叙sensor info常量的结构体。

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.h

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*/
};
//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

static struct imgsensor_info_struct imgsensor_info = {
	.sensor_id = GC8034_SENSOR_ID,       /*record sensor id defined in Kd_imgsensor.h*/
	.checksum_value = 0x1b375588,		//0xa11f4e23,            /*checksum value for Camera Auto Test*/

	.pre = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,                /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85, /*unit, ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},

	.cap = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85, /*unit, ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	.cap1 = {
		/* capture for PIP 24fps relative information */
		/* capture1 mode must use same framelength */
		/* linelength with Capture mode for shutter calculate */
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85,/*unit , ns*/
		/* less than 13M(include 13M),cap1 max framerate is 24fps */
		/* 16M max framerate is 20fps, 20M max framerate is 15fps */
		.mipi_pixel_rate = 215040000,	//672000000,
		.max_framerate = 240,
	},
	.normal_video = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 3264,
		.grabwindow_height = 2448,
		.mipi_data_lp2hs_settle_dc = 85,/*unit , ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	.hs_video = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 1632,
		.grabwindow_height = 1224,
		.mipi_data_lp2hs_settle_dc = 85,/*unit , ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	.slim_video = {
		.pclk = 320000000,                /*record different mode's pclk*/
		.linelength = 4272,               /*record different mode's linelength*/
		.framelength = 2500,
		.startx = 0,
		.starty = 0,
		.grabwindow_width = 1280,
		.grabwindow_height = 720,
		.mipi_data_lp2hs_settle_dc = 85,/*unit , ns*/
		.mipi_pixel_rate = 268800000,	//672000000,
		.max_framerate = 300,
	},
	.margin = 4,                          /* sensor framelength & shutter margin */
	.min_shutter = 4,                     /* min shutter */
	.max_frame_length =0x7fff,           /* 0xffff 0x29b3max framelength by sensor register's limitation */
	.ae_shut_delay_frame = 0,
	/* shutter delay frame for AE cycle, 2 frame with ispGain_delay-shut_delay=2-0=2 */
	.ae_sensor_gain_delay_frame = 0,
	/* sensor gain delay frame for AE cycle, */
	/* 2 frame with ispGain_delay-sensor_gain_delay=2-0=2 */
	.ae_ispGain_delay_frame = 2,          /* isp gain delay frame for AE cycle */
	.frame_time_delay_frame = 2,
	.ihdr_support = 0,                    /* 1, support; 0,not support */
	.ihdr_le_firstline = 0,               /* 1,le first ; 0, se first */
	.sensor_mode_num = 5,                 /* support sensor mode num */
	.cap_delay_frame = 2,                 /* enter capture delay frame num */
	.pre_delay_frame = 2,                 /* enter preview delay frame num */
	.video_delay_frame = 2,               /* enter video delay frame num */
	.hs_video_delay_frame = 2,            /* enter high speed video  delay frame num */
	.slim_video_delay_frame = 2,          /* enter slim video delay frame num */

	.isp_driving_current = ISP_DRIVING_8MA,                 /* mclk driving current */
	.sensor_interface_type = SENSOR_INTERFACE_TYPE_MIPI,    /* sensor_interface_type */
	.mipi_sensor_type = MIPI_OPHY_NCSI2,                    /* 0,MIPI_OPHY_NCSI2;  1,MIPI_OPHY_CSI2 */
	.mipi_settle_delay_mode = MIPI_SETTLEDELAY_AUTO,
	/* 0,MIPI_SETTLEDELAY_AUTO; 1,MIPI_SETTLEDELAY_MANNUAL */
#if defined(GC8034_MIRROR_NORMAL)
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_R, /*sensor output first pixel color*/
#elif defined(GC8034_MIRROR_H)
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_Gr,/*sensor output first pixel color*/
#elif defined(GC8034_MIRROR_V)
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_Gb,/*sensor output first pixel color*/
#elif defined(GC8034_MIRROR_HV)
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_B, /*sensor output first pixel color*/
#else
	.sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_R, /*sensor output first pixel color*/
#endif
	.mclk = 24,                                             /* mclk value, suggest 24 or 26 for 24Mhz or 26Mhz */
	.mipi_lane_num = SENSOR_MIPI_4_LANE,                    /* mipi lane num */
	.i2c_addr_table = { 0x6e, 0xff },
	/* record sensor support all write id addr, only supprt 4must end with 0xff */
};

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

struct imgsensor_struct {
//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.h

    //记录当前是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*/
};

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

static struct imgsensor_struct imgsensor = {
	.mirror = IMAGE_HV_MIRROR,            /* IMAGE_NORMAL, mirrorflip information */
	.sensor_mode = IMGSENSOR_MODE_INIT,
	/* IMGSENSOR_MODE enum value,record current sensor mode */
	/* such as: INIT, Preview, Capture, Video,High Speed Video, Slim Video */
	.shutter = 0x3ED,                     /* current shutter */
	.gain = 0x40,                         /* current gain */
	.dummy_pixel = 0,                     /* current dummypixel */
	.dummy_line = 0,                      /* current dummyline */
	.current_fps = 300,                   /* full size current fps : 24fps for PIP, 30fps for Normal or ZSD */
	.autoflicker_en = KAL_FALSE,
	/* auto flicker enable: KAL_FALSE for disable auto flicker, KAL_TRUE for enable auto flicker */
	.test_pattern = KAL_FALSE,
	/* test pattern mode or not. KAL_FALSE for in test pattern mode, KAL_TRUE for normal output */
	.current_scenario_id = MSDK_SCENARIO_ID_CAMERA_PREVIEW,	/* current scenario id */
	.ihdr_en = 0,                         /* sensor need support LE, SE with HDR feature */
	.i2c_write_id = 0x6e,                 /* record current sensor's i2c write id */
};

(E)Sensor output window information

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

static struct SENSOR_WINSIZE_INFO_STRUCT imgsensor_winsize_info[5] = {
	{ 3264, 2448,   0,   0, 3264, 2448, 3264, 2448, 0, 0, 3264, 2448, 0, 0, 3264, 2448}, /* Preview */
	{ 3264, 2448,   0,   0, 3264, 2448, 3264, 2448, 0, 0, 3264, 2448, 0, 0, 3264, 2448}, /* capture */
	{ 3264, 2448,   0,   0, 3264, 2448, 3264, 2448, 0, 0, 3264, 2448, 0, 0, 3264, 2448}, /* video */
	{ 3264, 2448,   0,   0, 3264, 2448, 3264, 2448, 0, 0, 1632, 1224, 0, 0, 1632, 1224}, /* hight speed video */
	{ 3264, 2448, 252, 504, 2560, 1440, 1280,  720, 0, 0, 1280,  720, 0, 0, 1280,  720}  /* slim video */
};

(3)驱动入口函数xxxx_MIPI_RAW_SensorInit

(A)驱动入口函数GC8034_MIPI_RAW_SensorInit

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.c

struct IMGSENSOR_INIT_FUNC_LIST kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] = {

	#if defined(GC8034_MIPI_RAW)
	{GC8034_SENSOR_ID,
	SENSOR_DRVNAME_GC8034_MIPI_RAW,
	GC8034_MIPI_RAW_SensorInit},
#endif

//...
{0, {0}, NULL}
};

//kernel-4.19/drivers/misc/mediatek/imgsensor/src/mt6779/gc8034_mipi_raw/gc8034mipi_Sensor.c

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

(B)SENSOR_FUNCTION_STRUCT这个结构体包含了所有sensor driver的操作接口

//kernel-4.19/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor_define.h

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

(C)open 函数

//gc8034mipi_Sensor.c

//此函每次打开camera都会调用
static kal_uint32 open(void)
{
	  //sensor初始化参数设置
	sensor_init();

	gc8034_gcore_identify_otp();
	spin_lock(&imgsensor_drv_lock);
	
	  //初始化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;
	spin_unlock(&imgsensor_drv_lock);
}

(D)feature_control函数

//获取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;

//set_shutter设置曝光行
    case SENSOR_FEATURE_SET_ESHUTTER:
    	set_shutter(*feature_data);
    	break;

//set_gain增益
	case SENSOR_FEATURE_SET_GAIN:
		set_gain((UINT16)*feature_data);
		break;

//streaming_control控制sensor输出数据
   case SENSOR_FEATURE_SET_STREAMING_SUSPEND:
    	pr_info("SENSOR_FEATURE_SET_STREAMING_SUSPENDn");
    	streaming_control(KAL_FALSE);
    	break;


static kal_uint16 set_gain(kal_uint16 gain)
{
	kal_uint32 reg_gain = 0;
	reg_gain = gain2reg(gain);
	LOG_INF("gain = %d, reg_gain = %dn", gain, reg_gain);
	write_cmos_sensor(0x0204, reg_gain & 0xffff);

	return gain;
}

static kal_uint16 gain2reg(kal_uint16 gain)
{
	kal_uint16 reg_gain = gain << 4;
	reg_gain = (reg_gain < SENSOR_BASE_GAIN) ? SENSOR_BASE_GAIN : reg_gain;
	reg_gain = (reg_gain > SENSOR_MAX_GAIN) ? SENSOR_MAX_GAIN : reg_gain;

	return reg_gain;
}

设置曝光行,曝光行物理上小于frame_length,所以曝光行大于当前frame_length时,frame_length会自动撑长,
帧率降低,所以亮度较低时,帧率会下降,因为这时候shutter比较大。每个AE周期会根据AE算法找到的对应pline table中相应index的exposure转换为shutter下给driver。

(E)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)
{
	LOG_INF("Enter control!n");
	LOG_INF("scenario_id = %dn", scenario_id);
	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;
	default:
		LOG_INF("Error ScenarioId setting");
		preview(image_window, sensor_config_data);
		return ERROR_INVALID_SCENARIO_ID;
	}
	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;
}

最后

以上就是刻苦季节为你收集整理的Mtk Camera Hal到驱动的流程(3)的全部内容,希望文章能够帮你解决Mtk Camera Hal到驱动的流程(3)所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部