[OMAPZOOM][PATCH 4/7] MT9P012: Changes to support QVGA at 120 fps

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 82420673286f5b4ef2917ae87ba1656f3b53faad Mon Sep 17 00:00:00 2001
From: Sergio Aguirre <saaguirre@xxxxxx>
Date: Tue, 6 Jan 2009 14:17:34 -0600
Subject: [PATCH] MT9P012: Changes to support QVGA at 120 fps

This enables MT9P012 sensor to stream video at 120 fps in
QVGA size only.

Signed-off-by: Sergio Aguirre <saaguirre@xxxxxx>
---
 drivers/media/video/mt9p012.c |  147 ++++++++++++++++++++++++++++++++++++++---
 drivers/media/video/mt9p012.h |    3 +-
 2 files changed, 140 insertions(+), 10 deletions(-)
 mode change 100644 => 100755 drivers/media/video/mt9p012.c
 mode change 100644 => 100755 drivers/media/video/mt9p012.h

diff --git a/drivers/media/video/mt9p012.c b/drivers/media/video/mt9p012.c
old mode 100644
new mode 100755
index ee45881..7633086
--- a/drivers/media/video/mt9p012.c
+++ b/drivers/media/video/mt9p012.c
@@ -46,6 +46,7 @@
 
 #define I2C_ENTER_VIDEO_216_30FPS_LIST_SIZE 22
 #define I2C_ENTER_VIDEO_648_30FPS_LIST_SIZE 21
+#define I2C_ENTER_VIDEO_648_120FPS_LIST_SIZE 31
 #define I2C_ENTER_VIDEO_1296_30FPS_LIST_SIZE 21
 
 unsigned char initial_list_buf[][6] = {
@@ -776,6 +777,110 @@ struct i2c_msg enter_video_648_30fps[] = {
 					&enter_video_648_30fps_buf[20][0]},
 };
 
+unsigned char enter_video_648_120fps_buf[][6] = {
+	/* hold */
+	{I2C_REG_GROUPED_PAR_HOLD, 0x00, 0x01, 0x00, 0x00},
+	{I2C_REG_VT_PIX_CLK_DIV, 0x00, 0x06, 0x00, 0x00},
+	{I2C_REG_VT_SYS_CLK_DIV, 0x00, 0x01, 0x00, 0x00},
+	{I2C_REG_PRE_PLL_CLK_DIV, 0x00, 0x02, 0x00, 0x00},
+	{I2C_REG_PLL_MULTIPLIER, 0x00, 0xc0, 0x00, 0x00},
+	{I2C_REG_OP_PIX_CLK_DIV, 0x00, 0x0a, 0x00, 0x00},
+	{I2C_REG_OP_SYS_CLK_DIV, 0x00, 0x01, 0x00, 0x00},
+	{I2C_REG_RESERVED_MFR_3064, 0x08, 0x05, 0x00, 0x00},
+	{I2C_REG_X_OUTPUT_SIZE, I2C_VIDEO_WIDTH_4X_BINN},
+	{I2C_REG_Y_OUTPUT_SIZE, I2C_VIDEO_HEIGHT_4X_BINN},
+	{I2C_REG_X_ADDR_START, 0x00, 0x08, 0x00, 0x00},
+	{I2C_REG_Y_ADDR_START, 0x00, 0x08, 0x00, 0x00},
+	{I2C_REG_X_ADDR_END, 0x0a, 0x01, 0x00, 0x00},
+	{I2C_REG_Y_ADDR_END, 0x07, 0x81, 0x00, 0x00},
+	{I2C_REG_READ_MODE, 0x00, 0xFC, 0x00, 0x00},
+	{I2C_REG_FINE_INT_TIME, 0x03, 0xf8, 0x00, 0x00},
+	{I2C_REG_LINE_LEN_PCK, 0x07, 0x24, 0x00, 0x00},
+	{I2C_REG_FRAME_LEN_LINES, 0x02, 0x3b, 0x00, 0x00},
+	{I2C_REG_SCALING_MODE, 0x00, 0x00, 0x00, 0x00},
+	{I2C_REG_SCALE_M, 0x00, 0x20, 0x00, 0x00},
+	{I2C_REG_COARSE_INT_TIME, 0x02, 0x38, 0x00, 0x00},
+	{I2C_REG_ANALOG_GAIN_GLOBAL, 0x00, 0x7D, 0x00, 0x00},
+	/* values for QVGA@120fps */
+	{0x30, 0x88, 0x6F, 0xF6, 0x00, 0x00},
+	{0x31, 0x62, 0x04, 0xCE, 0x00, 0x00},
+	{0x30, 0x8a, 0x64, 0x24, 0x00, 0x00},
+	{0x30, 0x92, 0x0a, 0x53, 0x00, 0x00},
+	{0x30, 0x94, 0x46, 0x56, 0x00, 0x00},
+	{0x30, 0x96, 0x56, 0x52, 0x00, 0x00},
+	{0x31, 0x54, 0x02, 0x82, 0x00, 0x00},
+	{0x31, 0x56, 0x03, 0x81, 0x00, 0x00},
+	/* update */
+	{I2C_REG_GROUPED_PAR_HOLD, 0x00, 0x00, 0x00, 0x00},
+};
+
+struct i2c_msg enter_video_648_120fps[] = {
+	/* hold */
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_8BIT,
+					&enter_video_648_120fps_buf[0][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[1][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[2][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[3][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[4][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[5][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[6][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[7][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[8][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[9][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[10][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[11][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[12][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[13][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[14][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[15][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[16][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[17][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[18][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[19][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[20][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[21][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[22][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[23][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[24][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[25][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[26][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[27][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[28][0]},
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_16BIT,
+					&enter_video_648_120fps_buf[29][0]},
+	/* update */
+	{MT9P012_I2C_ADDR, 0x00, I2C_MT9P012_8BIT,
+					&enter_video_648_120fps_buf[30][0]},
+};
+
 unsigned char enter_video_1296_30fps_buf[][6] = {
 	/* hold */
 	{I2C_REG_GROUPED_PAR_HOLD, 0x00, 0x01, 0x00, 0x00},
@@ -1073,6 +1178,10 @@ static struct mt9p012_pll_settings all_pll_settings[] = {
 	/* PLL_216_30FPS */
 	{.vt_pix_clk_div = 5, .vt_sys_clk_div = 2, .pre_pll_div = 3,
 	.fine_int_tm = 1794,  .frame_lines = 1374, .line_len = 3712,
+	.min_pll = 96, .max_pll = 192},
+	/* PLL_648_120FPS */
+	{.vt_pix_clk_div = 6, .vt_sys_clk_div = 1, .pre_pll_div = 2,
+	.fine_int_tm = 1016, .frame_lines = 571, .line_len = 1828,
 	.min_pll = 96, .max_pll = 192}
 };
 
@@ -1400,9 +1509,12 @@ mt9p012_calc_pll(enum image_size isize,
 			current_pll_video = PLL_1296_15FPS;
 	} else if (isize > BIN4XSCALE) {
 		sensor->scaler = 1;
-		if (sensor->fps > 15)
-			current_pll_video = PLL_648_30FPS;
-		else
+		if (sensor->fps > 15) {
+			if (sensor->fps == 120)
+				current_pll_video = PLL_648_120FPS;
+			else
+				current_pll_video = PLL_648_30FPS;
+		} else
 			current_pll_video = PLL_648_15FPS;
 	} else {
 		sensor->scaler = 2;
@@ -1569,6 +1681,7 @@ static unsigned long mt9p012sensor_calc_xclk(struct i2c_client *c)
 	struct mt9p012_sensor *sensor = i2c_get_clientdata(c);
 	struct v4l2_fract *timeperframe = &sensor->timeperframe;
 	struct v4l2_pix_format *pix = &sensor->pix;
+	int qvga_120 = 0;
 
 	if ((timeperframe->numerator == 0)
 	|| (timeperframe->denominator == 0)) {
@@ -1578,15 +1691,18 @@ static unsigned long mt9p012sensor_calc_xclk(struct i2c_client *c)
 	}
 
 	sensor->fps = timeperframe->denominator/timeperframe->numerator;
+	if ((sensor->fps == 120) && (pix->width <= VIDEO_WIDTH_4X_BINN) &&
+				(pix->width > VIDEO_WIDTH_4X_BINN_SCALED))
+		qvga_120 = 1;
 	if (sensor->fps < MT9P012_MIN_FPS)
 		sensor->fps = MT9P012_MIN_FPS;
-	else if (sensor->fps > MT9P012_MAX_FPS)
+	else if ((sensor->fps > MT9P012_MAX_FPS) && (!qvga_120))
 		sensor->fps = MT9P012_MAX_FPS;
 
 	timeperframe->numerator = 1;
 	timeperframe->denominator = sensor->fps;
-
-	if ((pix->width <= VIDEO_WIDTH_4X_BINN) && (sensor->fps > 15))
+	if ((pix->width <= VIDEO_WIDTH_4X_BINN) && (sensor->fps > 15) &&
+							(!qvga_120))
 		xclk_current = MT9P012_XCLK_NOM_2;
 	else
 		xclk_current = MT9P012_XCLK_NOM_1;
@@ -1629,9 +1745,15 @@ static int mt9p012_configure(struct v4l2_int_device *s)
 
 	/* configure image size and pixel format */
 	if (pix->pixelformat == V4L2_PIX_FMT_SGRBG10) {
-		err = mt9p012_write_regs(client,
-			mt9p012_reg_init[fps_index][isize].reg_list,
-			mt9p012_reg_init[fps_index][isize].list_size);
+		if (sensor->fps == 120) {
+			err = mt9p012_write_regs(client,
+				enter_video_648_120fps,
+				I2C_ENTER_VIDEO_648_120FPS_LIST_SIZE);
+		} else {
+			err = mt9p012_write_regs(client,
+				mt9p012_reg_init[fps_index][isize].reg_list,
+				mt9p012_reg_init[fps_index][isize].list_size);
+		}
 	} else if (pix->pixelformat == V4L2_PIX_FMT_PATT) {
 		err = mt9p012_write_regs(client,
 			mt9p012_pattern_reg_init[0][0].reg_list,
@@ -2123,6 +2245,7 @@ const struct v4l2_fract mt9p012_frameintervals[] = {
 	{  .numerator = 1, .denominator = 20 },
 	{  .numerator = 1, .denominator = 25 },
 	{  .numerator = 1, .denominator = 30 },
+	{  .numerator = 1, .denominator = 120 },
 };
 
 static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
@@ -2149,6 +2272,12 @@ static int ioctl_enum_frameintervals(struct v4l2_int_device *s,
 		 */
 		if (frmi->index != 0)
 			return -EINVAL;
+	} else if ((frmi->width == mt9p012_sizes[1].width) &&
+				(frmi->height == mt9p012_sizes[1].height)) {
+		/* QVGA base size supports all framerates, including 120 fps!
+		 */
+		if (frmi->index >= 6)
+			return -EINVAL;
 	} else {
 		if (frmi->index >= 5)
 			return -EINVAL;
diff --git a/drivers/media/video/mt9p012.h b/drivers/media/video/mt9p012.h
old mode 100644
new mode 100755
index 4c74512..bf0c038
--- a/drivers/media/video/mt9p012.h
+++ b/drivers/media/video/mt9p012.h
@@ -289,7 +289,8 @@ enum mt9p012_pll_type {
   PLL_648_15FPS,
   PLL_648_30FPS,
   PLL_216_15FPS,
-  PLL_216_30FPS
+  PLL_216_30FPS,
+  PLL_648_120FPS
 };
 
 /* Used registers */
-- 
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux