From 6a41678346a4a73f1c99220a1b2c67269bb0938d Mon Sep 17 00:00:00 2001 From: GWater Date: Sun, 10 Aug 2008 19:01:23 +0200 Subject: [PATCH] Auto-exposure for ov96xx sensors. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch adds the auto-exposure setting/feature for all webcams with a sensor from the ov96xx series. These are currently: - 0c45:624e (SOI968 ≈ OV9628) - 0c45:624f (OV9650) - 0c45:6288 (OV9655) Signed-off-by: GWater --- microdia-dev.c | 1 + microdia-usb.c | 3 +++ microdia-v4l.c | 9 +++++---- ov965x.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ ov965x.h | 1 + 5 files changed, 57 insertions(+), 4 deletions(-) diff --git a/microdia-dev.c b/microdia-dev.c index b6f6b15..cd5f36c 100644 --- a/microdia-dev.c +++ b/microdia-dev.c @@ -9856,3 +9856,4 @@ int microdia_6260_flip_detect(struct usb_microdia *dev) return ret; } + diff --git a/microdia-usb.c b/microdia-usb.c index dacff5f..19df1bb 100644 --- a/microdia-usb.c +++ b/microdia-usb.c @@ -278,6 +278,7 @@ struct microdia_camera cameras[] = { .initialize = microdia_624e_initialize, .start_stream = microdia_624e_start_stream, .stop_stream = microdia_624e_stop_stream, + .set_auto_exposure = ov965x_set_autoexposure, }, { .model = CAMERA_MODEL(USB_0C45_VID, USB_624F_PID), @@ -290,6 +291,7 @@ struct microdia_camera cameras[] = { .start_stream = microdia_624f_start_stream, .stop_stream = microdia_624f_stop_stream, .flip_detect = microdia_624f_flip_detect, + .set_auto_exposure = ov965x_set_autoexposure, .set_exposure = ov965x_set_exposure, .set_hvflip = ov965x_set_hvflip, }, @@ -337,6 +339,7 @@ struct microdia_camera cameras[] = { .initialize = microdia_6288_initialize, .start_stream = microdia_6288_start_stream, .stop_stream = microdia_6288_stop_stream, + .set_auto_exposure = ov965x_set_autoexposure, }, { .model = CAMERA_MODEL(USB_0C45_VID, USB_62B3_PID), diff --git a/microdia-v4l.c b/microdia-v4l.c index e1961f0..dc1174e 100644 --- a/microdia-v4l.c +++ b/microdia-v4l.c @@ -40,7 +40,8 @@ /* USER DEFINED V4L2-CONTROLS: */ -#define V4L2_CID_SHARPNESS (V4L2_CID_PRIVATE_BASE) +#define V4L2_CID_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_AUTOEXPOSURE (V4L2_CID_PRIVATE_BASE + 1) static struct file_operations v4l_microdia_fops; @@ -258,7 +259,7 @@ static struct v4l2_queryctrl microdia_controls[] = { .default_value = 0x20, }, { - .id = V4L2_CID_AUTOGAIN, + .id = V4L2_CID_AUTOEXPOSURE, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Automatic exposure control", .minimum = 0, @@ -843,7 +844,7 @@ int microdia_vidioc_g_ctrl(struct file *file, void *priv, ctrl->value = dev->vsettings.rgb_gain[3]; break; - case V4L2_CID_AUTOGAIN: + case V4L2_CID_AUTOEXPOSURE: ctrl->value = dev->vsettings.auto_exposure; break; @@ -916,7 +917,7 @@ int microdia_vidioc_s_ctrl(struct file *file, void *priv, dev_microdia_camera_set_rgb_gain(dev); break; - case V4L2_CID_AUTOGAIN: + case V4L2_CID_AUTOEXPOSURE: dev->vsettings.auto_exposure = ctrl->value; dev_microdia_camera_set_auto_exposure(dev); break; diff --git a/ov965x.c b/ov965x.c index 9a5c1b9..308f3b7 100644 --- a/ov965x.c +++ b/ov965x.c @@ -188,3 +188,50 @@ int ov965x_set_exposure(struct usb_microdia *dev) return ret; } +/** + * @brief Set autoexposure for ov96xx sensors + * + * @param dev + * + * @returns 0 or negative error value + * + * @author GWater + * + * For all OV965x and SOI968 sensors. + */ +int ov965x_set_autoexposure(struct usb_microdia *dev) +{ + __u8 buf[1]; + int ret = 0; + + /* Read current value of the I2C-register + * controlling AutoExposureControl: + */ + ret = sn9c20x_read_i2c_data(dev, dev->sensor_slave_address, + 1, 0x13, dev->sensor_flags, buf); + if (ret < 0) { + UDIA_ERROR("Error: setting of auto exposure failed: " + "error while reading from I2C-register 0x13"); + return ret; + } + + /* Determine new value for register 0x13: */ + if (dev->vsettings.auto_exposure == 1) { + /* Enable automatic exposure: */ + buf[0] |= 0x01; + } else if (dev->vsettings.auto_exposure == 0) { + /* Disable automatic exposure: */ + buf[0] &= ~0x01; + } else + return -EINVAL; + + /* Write new value to I2C-register 0x13: */ + ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, + 1, 0x13, dev->sensor_flags, buf); + if (ret < 0) { + UDIA_ERROR("Error: setting of auto exposure failed: " + "error while writing to I2C-register 0x13"); + return ret; + } + return 0; +} diff --git a/ov965x.h b/ov965x.h index f47efe2..8e9bc67 100644 --- a/ov965x.h +++ b/ov965x.h @@ -233,4 +233,5 @@ int ov965x_initialize(struct usb_microdia *); int ov965x_set_hvflip(struct usb_microdia *); int ov965x_set_exposure(struct usb_microdia *); +int ov965x_set_autoexposure(struct usb_microdia *dev); #endif -- 2.11.4.GIT