Web lists-archives.com

Re: [Spca50x-devs] PATCH: gspca-mercurial OV7630 light frequency filter




Andoni,

I've been working on adding hue, saturation and contrast controls for the ovXXXX chips, unfortunately they don't work as advertised in the datasheet on my ov6650, maybe they do work on your ov7630? Attached is my patch, please give it a try.

Regards,

Hans


diff -r e7aa8d7a1cfd linux/drivers/media/video/gspca/sonixb.c
--- a/linux/drivers/media/video/gspca/sonixb.c	Thu Jul 17 07:41:50 2008 +0200
+++ b/linux/drivers/media/video/gspca/sonixb.c	Thu Jul 17 11:43:14 2008 +0200
@@ -45,6 +45,9 @@
 	unsigned char autogain;
 	unsigned char autogain_ignore_frames;
 	unsigned char freq;		/* light freq filter setting */
+	unsigned char saturation;
+	unsigned char hue;
+	unsigned char contrast;
 
 	unsigned char fr_h_sz;		/* size of frame header */
 	char sensor;			/* Type of image sensor chip */
@@ -89,6 +92,12 @@
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
 	{
@@ -164,6 +173,48 @@
 		},
 		.set = sd_setfreq,
 		.get = sd_getfreq,
+	},
+	{
+		{
+			.id      = V4L2_CID_SATURATION,
+			.type    = V4L2_CTRL_TYPE_INTEGER,
+			.name    = "Saturation",
+			.minimum = 0,
+			.maximum = 255,
+			.step    = 1,
+#define SATURATION_DEF 127
+			.default_value = SATURATION_DEF,
+		},
+		.set = sd_setsaturation,
+		.get = sd_getsaturation,
+	},
+	{
+		{
+			.id      = V4L2_CID_HUE,
+			.type    = V4L2_CTRL_TYPE_INTEGER,
+			.name    = "Hue",
+			.minimum = 0,
+			.maximum = 255,
+			.step    = 1,
+#define HUE_DEF 127
+			.default_value = HUE_DEF,
+		},
+		.set = sd_sethue,
+		.get = sd_gethue,
+	},
+	{
+		{
+			.id      = V4L2_CID_CONTRAST,
+			.type    = V4L2_CTRL_TYPE_INTEGER,
+			.name    = "Contrast",
+			.minimum = 0,
+			.maximum = 255,
+			.step    = 1,
+#define CONTRAST_DEF 127
+			.default_value = CONTRAST_DEF,
+		},
+		.set = sd_setcontrast,
+		.get = sd_getcontrast,
 	},
 };
 
@@ -752,6 +810,68 @@
 	}
 }
 
+static void setsaturation(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	switch (sd->sensor) {
+/*	case SENSOR_OV6650: */
+	case SENSOR_OV7630_3:
+	case SENSOR_OV7630: {
+		__u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10};
+		i2c[1] = sd->sensor_addr;
+		i2c[3] = sd->saturation & 0xf0;
+		if (i2c_w(gspca_dev, i2c) < 0)
+			PDEBUG(D_ERR, "i2c error setsaturation");
+		else
+			PDEBUG(D_CONF, "saturation set to: %d",
+				(int)sd->saturation);
+		break;
+	    }
+	}
+}
+
+static void sethue(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	switch (sd->sensor) {
+/*	case SENSOR_OV6650: */
+	case SENSOR_OV7630_3:
+	case SENSOR_OV7630: {
+		__u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10};
+		i2c[1] = sd->sensor_addr;
+		i2c[3] = 0x20 | (sd->hue >> 3);
+		if (i2c_w(gspca_dev, i2c) < 0)
+			PDEBUG(D_ERR, "i2c error setsaturation");
+		else
+			PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue);
+		break;
+	    }
+	}
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	switch (sd->sensor) {
+/*	case SENSOR_OV6650: */
+	case SENSOR_OV7630_3:
+	case SENSOR_OV7630: {
+		__u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10};
+		i2c[1] = sd->sensor_addr;
+		i2c[3] = 0x20 | (sd->contrast >> 3);
+		if (i2c_w(gspca_dev, i2c) < 0)
+			PDEBUG(D_ERR, "i2c error setcontrast");
+		else
+			PDEBUG(D_CONF, "contrast set to: %d",
+				(int)sd->contrast);
+		break;
+	    }
+	}
+}
+
 
 static void do_autogain(struct gspca_dev *gspca_dev)
 {
@@ -788,7 +908,6 @@
 	sd->fr_h_sz = 12;		/* default size of the frame header */
 	sd->sd_desc.nctrls = 2;		/* default nb of ctrls */
 	sd->autogain = AUTOGAIN_DEF;    /* default is autogain active */
-	sd->freq = FREQ_DEF;
 
 	product = id->idProduct;
 /*	switch (id->idVendor) { */
@@ -828,7 +947,7 @@
 			sd->sensor_addr = 0x21;
 			sd->fr_h_sz = 18;	/* size of frame header */
 			sd->sensor_has_gain = 1;
-			sd->sd_desc.nctrls = 5;
+			sd->sd_desc.nctrls = 8;
 			sd->sd_desc.dq_callback = do_autogain;
 			sd->autogain = 0;
 			break;
@@ -868,6 +987,10 @@
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->gain = GAIN_DEF;
 	sd->exposure = EXPOSURE_DEF;
+	sd->freq = FREQ_DEF;
+	sd->contrast = CONTRAST_DEF;
+	sd->saturation = SATURATION_DEF;
+	sd->hue = HUE_DEF;
 	if (sd->sensor == SENSOR_OV7630_3)	/* jfm: from win trace */
 		reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
 	return 0;
@@ -1050,6 +1173,9 @@
 	setbrightness(gspca_dev);
 	setexposure(gspca_dev);
 	setfreq(gspca_dev);
+	setsaturation(gspca_dev);
+	sethue(gspca_dev);
+	setcontrast(gspca_dev);
 
 	sd->autogain_ignore_frames = 0;
 	atomic_set(&sd->avg_lum, -1);
@@ -1225,6 +1351,60 @@
 	return 0;
 }
 
+static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->saturation = val;
+	if (gspca_dev->streaming)
+		setsaturation(gspca_dev);
+	return 0;
+}
+
+static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->saturation;
+	return 0;
+}
+
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->hue = val;
+	if (gspca_dev->streaming)
+		sethue(gspca_dev);
+	return 0;
+}
+
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->hue;
+	return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->contrast = val;
+	if (gspca_dev->streaming)
+		setcontrast(gspca_dev);
+	return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->contrast;
+	return 0;
+}
+
 static int sd_querymenu(struct gspca_dev *gspca_dev,
 			struct v4l2_querymenu *menu)
 {
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Spca50x-devs mailing list
Spca50x-devs@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/spca50x-devs