The patch number 12704 was added via Brian Johnson <[email protected]>
to http://linuxtv.org/hg/v4l-dvb master development tree.
Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel
If anyone has any objections, please let us know by sending a message to:
Linux Media Mailing List <[email protected]>
------
From: Brian Johnson <[email protected]>
gspca - sn9c20x: Fix exposure on SOI968 sensors
Fixes broken exposure on SOI968 webcams that was causing
the camera to display a black screen
Priority: high
Signed-off-by: Brian Johnson <[email protected]>
---
linux/drivers/media/video/gspca/sn9c20x.c | 53 +++++++++++++++++-----
1 file changed, 42 insertions(+), 11 deletions(-)
diff -r 1bff8943b653 -r 52d053851896 linux/drivers/media/video/gspca/sn9c20x.c
--- a/linux/drivers/media/video/gspca/sn9c20x.c Wed Sep 02 00:12:13 2009 -0400
+++ b/linux/drivers/media/video/gspca/sn9c20x.c Wed Sep 02 11:39:41 2009 -0400
@@ -812,7 +812,7 @@
{0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
{0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
{0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
- {0x13, 0x8a}, {0x12, 0x40}, {0x17, 0x13},
+ {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
{0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
{0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
{0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
@@ -1260,7 +1260,7 @@
}
}
/* disable hflip and vflip */
- gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
+ gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 <<
EXPOSURE_IDX);
sd->hstart = 60;
sd->vstart = 11;
return 0;
@@ -1636,7 +1636,6 @@
switch (sd->sensor) {
case SENSOR_OV7660:
case SENSOR_OV7670:
- case SENSOR_SOI968:
case SENSOR_OV9655:
case SENSOR_OV9650:
exp[0] |= (3 << 4);
@@ -1661,6 +1660,8 @@
exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8;
exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff;
break;
+ default:
+ return 0;
}
i2c_w(gspca_dev, exp);
return 0;
@@ -1704,6 +1705,8 @@
gain[2] = 0x30;
gain[3] = hv7131r_gain[sd->gain];
break;
+ default:
+ return 0;
}
i2c_w(gspca_dev, gain);
return 0;
@@ -2227,15 +2230,10 @@
kfree(sd->jpeg_hdr);
}
-static void do_autoexposure(struct gspca_dev *gspca_dev)
+static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
{
struct sd *sd = (struct sd *) gspca_dev;
- int avg_lum, new_exp;
-
- if (!sd->auto_exposure)
- return;
-
- avg_lum = atomic_read(&sd->avg_lum);
+ s16 new_exp;
/*
* some hardcoded values are present
@@ -2282,6 +2280,39 @@
}
}
+static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (avg_lum < MIN_AVG_LUM) {
+ if (sd->gain + 1 <= 28) {
+ sd->gain++;
+ set_gain(gspca_dev);
+ }
+ }
+ if (avg_lum > MAX_AVG_LUM) {
+ if (sd->gain - 1 >= 0) {
+ sd->gain--;
+ set_gain(gspca_dev);
+ }
+ }
+}
+
+static void sd_dqcallback(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int avg_lum;
+
+ if (!sd->auto_exposure)
+ return;
+
+ avg_lum = atomic_read(&sd->avg_lum);
+ if (sd->sensor == SENSOR_SOI968)
+ do_autogain(gspca_dev, avg_lum);
+ else
+ do_autoexposure(gspca_dev, avg_lum);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
u8 *data, /* isoc packet */
@@ -2349,7 +2380,7 @@
.stopN = sd_stopN,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
- .dq_callback = do_autoexposure,
+ .dq_callback = sd_dqcallback,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.set_register = sd_dbg_s_register,
.get_register = sd_dbg_g_register,
---
Patch is available at:
http://linuxtv.org/hg/v4l-dvb/rev/52d05385189622a59d7c876495a3b8fb38a5a9f5
_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits