Third patch adds custom i420 format to be used with libv4l.
libv4l patch will be attached to the next post.

Regards
Vasily
From 5077fe668336dd71ee7a1ec5bb917e4bffd59fd3 Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <[email protected]>
Date: Wed, 7 Jan 2009 17:57:21 +0200
Subject: [PATCH] Added old_yavg field to the camera struct, removed static variable old_yavg. Soft AE should work now with multiple cams


Signed-off-by: Vasily Khoruzhick <[email protected]>
---
 sn9c20x-dev.c |   16 ++++++++--------
 sn9c20x.h     |    2 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/sn9c20x-dev.c b/sn9c20x-dev.c
index 5b9fd8e..e0d4e13 100644
--- a/sn9c20x-dev.c
+++ b/sn9c20x-dev.c
@@ -114,6 +114,7 @@ int sn9c20x_initialize_sensor(struct usb_sn9c20x *dev)
 	dev->camera.max_yavg = 150;
 	dev->camera.min_stable_yavg = 70;
 	dev->camera.max_stable_yavg = 140;
+	dev->camera.old_yavg = -1;
 
 	/* Probe sensor first if sensor set to probe*/
 	if (dev->camera.sensor == PROBE_SENSOR) {
@@ -290,7 +291,6 @@ int dev_sn9c20x_button_detection(struct usb_sn9c20x *dev)
 int dev_sn9c20x_perform_soft_ae(struct usb_sn9c20x *dev)
 {
 	int yavg;
-	static int old_yavg = -1;
 	int koef = 100, new_exp, i;
 	yavg = -1;
 	i = 10;
@@ -299,7 +299,7 @@ int dev_sn9c20x_perform_soft_ae(struct usb_sn9c20x *dev)
 		return -1;
 	yavg = atomic_read(&dev->camera.yavg);
 
-	UDIA_INFO("Sensor YAVG: %d\n", yavg);
+	UDIA_DEBUG("Sensor YAVG: %d\n", yavg);
 	if (yavg < 0) {
 		/* Can't get YAVG - we have nothing to do */
 		return -1;
@@ -310,13 +310,13 @@ int dev_sn9c20x_perform_soft_ae(struct usb_sn9c20x *dev)
 		/* yavg can't be 0 - in that way new_exp == infinity */
 		if (yavg == 0)
 			yavg = 1;
-		if (old_yavg != -1) {
+		if (dev->camera.old_yavg != -1) {
 			/* Previous correction was made to make image darker,
 			 * but we made it too dark. Calculating our error
 			 * and taking it into account.
 			 * Usually error is 0.7 - 2, so we multiply it by 100
 			 */
-			if (old_yavg > dev->camera.max_yavg)
+			if (dev->camera.old_yavg > dev->camera.max_yavg)
 				koef = 100 * dev->camera.
 					min_stable_yavg / yavg;
 			else
@@ -335,7 +335,7 @@ int dev_sn9c20x_perform_soft_ae(struct usb_sn9c20x *dev)
 		if (new_exp < 0x1)
 			new_exp = 1;
 
-		old_yavg = yavg;
+		dev->camera.old_yavg = yavg;
 
 		/* Applying new exposure */
 		dev->vsettings.exposure = new_exp;
@@ -347,14 +347,14 @@ int dev_sn9c20x_perform_soft_ae(struct usb_sn9c20x *dev)
 			/* yavg can't be 0 - in that way new_exp == infinity */
 		if (yavg == 0)
 			yavg = 1;
-		if (old_yavg != -1) {
+		if (dev->camera.old_yavg != -1) {
 
 			/* Previous correction was made to make image brighter,
 			 * but we made it too bright. Calculating our error
 			 * and taking it into account.
 			 * Usually error is 0.7 - 2, so we multiply it by 100
 			 */
-			if (old_yavg < dev->camera.min_yavg)
+			if (dev->camera.old_yavg < dev->camera.min_yavg)
 				koef = 100 * yavg / dev->camera.
 					max_stable_yavg;
 			else
@@ -373,7 +373,7 @@ int dev_sn9c20x_perform_soft_ae(struct usb_sn9c20x *dev)
 		if (new_exp < 0x1)
 			new_exp = 1;
 
-		old_yavg = yavg;
+		dev->camera.old_yavg = yavg;
 
 		/* Applying new exposure */
 		dev->vsettings.exposure = new_exp;
diff --git a/sn9c20x.h b/sn9c20x.h
index 061a4e9..b463624 100644
--- a/sn9c20x.h
+++ b/sn9c20x.h
@@ -370,7 +370,7 @@ struct sn9c20x_camera {
 	__u8 i2c_flags;
 	__u8 address;
 
-	int min_yavg, max_yavg, min_stable_yavg, max_stable_yavg;
+	int min_yavg, max_yavg, min_stable_yavg, max_stable_yavg, old_yavg;
 
 	atomic_t yavg;
 
-- 
1.6.0.6

From 5280ad318549ecf1585cbb5e0c38ba471a126ed1 Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <[email protected]>
Date: Wed, 7 Jan 2009 18:09:26 +0200
Subject: [PATCH] Added OV9650 gain control


Signed-off-by: Vasily Khoruzhick <[email protected]>
---
 omnivision.c  |   39 +++++++++++++++++++++++++++++++++++++++
 omnivision.h  |    1 +
 sn9c20x-dev.c |    1 +
 3 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/omnivision.c b/omnivision.c
index f14df4c..cbd5a59 100644
--- a/omnivision.c
+++ b/omnivision.c
@@ -721,6 +721,45 @@ int soi968_set_gain(struct usb_sn9c20x *dev)
 	return ret;
 }
 
+/*
+ * @brief Set gain for ov9650 sensor
+ *
+ * @param dev
+ *
+ * @returns 0 or negative error value
+ *
+ * @author Vasily Khoruzhick
+ *
+ */
+int ov9650_set_gain(struct usb_sn9c20x *dev)
+{
+	__u8 buf[1];
+	int ret = 0;
+
+	buf[0] = (dev->vsettings.gain >> 1) & 0x0F;
+	switch (dev->vsettings.gain >> 1 & 0xF0) {
+	case 0x00:
+		break;
+	case 0x10:
+		buf[0] |= 0x10;
+		break;
+	case 0x20:
+		buf[0] |= 0x30;
+		break;
+	case 0x30:
+		buf[0] |= 0x70;
+		break;
+	case 0x40:
+		buf[0] |= 0xF0;
+		break;
+	default:
+		buf[0] |= 0xFF;
+		break;
+	}
+	ret |= sn9c20x_write_i2c_data(dev, 1, OV965X_CTL_GAIN, buf);
+
+	return ret;
+}
 
 /**
  * @brief Detect whether the image for 6260 has to be flipped
diff --git a/omnivision.h b/omnivision.h
index ebf2a01..c67c237 100644
--- a/omnivision.h
+++ b/omnivision.h
@@ -541,6 +541,7 @@ int soi968_set_autoexposure(struct usb_sn9c20x *dev);
 
 int ov965x_set_hvflip(struct usb_sn9c20x *);
 int ov965x_flip_detect(struct usb_sn9c20x *dev);
+int ov9650_set_gain(struct usb_sn9c20x *dev);
 
 int ov_set_exposure(struct usb_sn9c20x *);
 int ov_set_autogain(struct usb_sn9c20x *dev);
diff --git a/sn9c20x-dev.c b/sn9c20x-dev.c
index e0d4e13..ce6dc48 100644
--- a/sn9c20x-dev.c
+++ b/sn9c20x-dev.c
@@ -145,6 +145,7 @@ int sn9c20x_initialize_sensor(struct usb_sn9c20x *dev)
 		dev->camera.set_hvflip = ov965x_set_hvflip;
 		dev->camera.set_exposure = ov_set_exposure;
 		dev->camera.set_auto_gain = ov_set_autogain;
+		dev->camera.set_gain = ov9650_set_gain;
 		dev->camera.flip_detect = ov965x_flip_detect;
 		UDIA_INFO("Detected OV9650 Sensor.\n");
 		break;
-- 
1.6.0.6

From e6817deb0ec8ba212a32868b7390ee535775f446 Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <[email protected]>
Date: Wed, 7 Jan 2009 22:13:39 +0200
Subject: [PATCH] Added custom sn9c20x i420 output format


Signed-off-by: Vasily Khoruzhick <[email protected]>
---
 sn9c20x-bridge.c |    4 ++++
 sn9c20x-dev.c    |   14 ++++++++------
 sn9c20x-sysfs.c  |    4 ++--
 sn9c20x.h        |    4 ++++
 4 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/sn9c20x-bridge.c b/sn9c20x-bridge.c
index b2a2d1b..2b1b491 100644
--- a/sn9c20x-bridge.c
+++ b/sn9c20x-bridge.c
@@ -757,6 +757,7 @@ void sn9c20x_set_raw(struct usb_sn9c20x *dev)
 	__u8 value;
 	value = 0x2d;
 	usb_sn9c20x_control_write(dev, 0x10e0, &value, 1);
+	UDIA_INFO("Using raw output format\n");
 }
 
 void sn9c20x_set_jpeg(struct usb_sn9c20x *dev)
@@ -764,6 +765,7 @@ void sn9c20x_set_jpeg(struct usb_sn9c20x *dev)
 	__u8 value;
 	value = 0x2c;
 	usb_sn9c20x_control_write(dev, 0x10e0, &value, 1);
+	UDIA_INFO("Using jpeg output format\n");
 }
 
 void sn9c20x_set_yuv420(struct usb_sn9c20x *dev)
@@ -771,6 +773,7 @@ void sn9c20x_set_yuv420(struct usb_sn9c20x *dev)
 	__u8 value;
 	value = 0x2f;
 	usb_sn9c20x_control_write(dev, 0x10e0, &value, 1);
+	UDIA_INFO("Using yuv420 output format\n");
 }
 
 void sn9c20x_set_yuv422(struct usb_sn9c20x *dev)
@@ -778,6 +781,7 @@ void sn9c20x_set_yuv422(struct usb_sn9c20x *dev)
 	__u8 value;
 	value = 0x2e;
 	usb_sn9c20x_control_write(dev, 0x10e0, &value, 1);
+	UDIA_INFO("Using yuv422 output format\n");
 }
 
 /**
diff --git a/sn9c20x-dev.c b/sn9c20x-dev.c
index ce6dc48..659ac6f 100644
--- a/sn9c20x-dev.c
+++ b/sn9c20x-dev.c
@@ -80,23 +80,25 @@ struct sn9c20x_video_mode sn9c20x_modes[SN9C20X_N_MODES] = {
 
 struct sn9c20x_video_format sn9c20x_fmts[SN9C20X_N_FMTS] = {
 	{
+		.pix_fmt = V4L2_PIX_FMT_SN9C20X_I420,
+		.desc = "SN9C20X I420 (YUV 4:2:0)",
+		.depth = 12,
+		.set_format = sn9c20x_set_yuv420,
+	},
+	{
 		.pix_fmt = V4L2_PIX_FMT_SBGGR8,
 		.desc = "Bayer 8bit (BGGR)",
 		.depth = 8,
 		.set_format = sn9c20x_set_raw,
 	},
-	{
-		.pix_fmt = V4L2_PIX_FMT_YUV420,
-		.desc = "I420 (YUV 4:2:0)",
-		.depth = 12,
-		.set_format = sn9c20x_set_yuv420,
-	},
+/*
 	{
 		.pix_fmt = V4L2_PIX_FMT_YUYV,
 		.desc = "YUYV (YUV 4:2:0)",
 		.depth = 16,
 		.set_format = sn9c20x_set_yuv422,
 	},
+*/
 	{
 		.pix_fmt = V4L2_PIX_FMT_JPEG,
 		.desc = "JPEG (YUV 4:2:2)",
diff --git a/sn9c20x-sysfs.c b/sn9c20x-sysfs.c
index e2bd2b1..05ff950 100644
--- a/sn9c20x-sysfs.c
+++ b/sn9c20x-sysfs.c
@@ -113,7 +113,7 @@ static ssize_t show_informations(struct device *class, struct device_attribute *
 	char *palette_bgr24 = "BGR24 - BGR-8-8-8 - 24 bits";
 	char *palette_rgb24 = "RGB24 - RGB-8-8-8 - 24 bits";
 	char *palette_yuyv = "YUYV - YUV 4:2:2 - 16 bits";
-	char *palette_i420 = "I420 - YUV 4:2:0 - 12 bits";
+	char *palette_i420 = "SN9C20X_I420 - YUV 4:2:0 - 12 bits";
 
 
 	switch (dev->vsettings.format.pixelformat) {
@@ -129,7 +129,7 @@ static ssize_t show_informations(struct device *class, struct device_attribute *
 		pixelfmt = palette_yuyv;
 		break;
 
-	case V4L2_PIX_FMT_YUV420:
+	case V4L2_PIX_FMT_SN9C20X_I420:
 		pixelfmt = palette_i420;
 		break;
 	}
diff --git a/sn9c20x.h b/sn9c20x.h
index b463624..16c487b 100644
--- a/sn9c20x.h
+++ b/sn9c20x.h
@@ -110,6 +110,10 @@ enum  v4l2_exposure_auto_type {
 };
 #endif
 
+#ifndef V4L2_PIX_FMT_SN9C20X_I420
+#define V4L2_PIX_FMT_SN9C20X_I420  v4l2_fourcc('S', '9', '2', '0')
+#endif
+
 /**
  * @def MAX_URBS
  *   Number maximal of URBS
-- 
1.6.0.6

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to