GWater schrieb:
GWater schrieb:I already told you that I asked scott bertin to help me with our auto-exposure problem. (Currently auto-exposure doesn't show up in v4l2ucp because it has an id which isn't queried.)Scott Bertin answered me with a nice patch (v4l2ucp-extcontrols.patch) which led me to conlude that our code contains the problem. I found it and fixed it in the attached patch 0006. However I still face some difficulties with V4L2_CTRL_FLAG_NEXT_CTRL.V4L2_CTRL_FLAG_NEXT_CTRL can be used by an app to automagically get the next available CID. That works fine as long as all CIDs are in a nice order like:1,2,3,4 However in our code they are a bit mixed: 1,3,2,4This leads to CID number 2 being missed because my algorithm can't process the fact that before CID 3 CID 2 should be sent. However CID 1 should not be sent twice.Help me, Obi-Wan. GWaterPS:The other patches are just there to provide a nice line from origin to patch 0006. But please free to discuss them, too.Patch 0005 doesn't fix anything. I'll do that again. GWater
Patches 0005 and 0006 are fixed now.Please check whether my dynamic memory allocation in 0005 is correct. I never did that stuff before and just figured the lack of kernel-oopses meant it works correctly.
In 0006 an incorrect if-statement was used in the last version. Nothing serious but may have caused non-V4L2-compliant behaviour.
GWater
From 4615a3c7a36111be87f9d33525d746a89ea14f73 Mon Sep 17 00:00:00 2001 From: GWater <[email protected]> Date: Wed, 17 Dec 2008 23:07:56 +0100 Subject: [PATCH] Add support for hv7131r sensors devices 627c and 62bc should now work Signed-off-by: GWater <[email protected]> --- Makefile | 2 +- hv7131r.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ microdia-dev.c | 14 ++++++ microdia.h | 7 +++ sn9c20x.c | 14 +----- 5 files changed, 152 insertions(+), 13 deletions(-) create mode 100644 hv7131r.c diff --git a/Makefile b/Makefile index 379ae58..59d10ba 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ include $(src)/.config microdia-objs := microdia-usb.o microdia-v4l.o microdia-sysfs.o microdia-objs += microdia-dev.o microdia-queue.o -microdia-objs += sn9c20x.o omnivision.o micron.o +microdia-objs += sn9c20x.o omnivision.o micron.o hv7131r.o ifeq ($(CONFIG_MICRODIA_DEBUGFS),y) microdia-objs += microdia-debugfs.o diff --git a/hv7131r.c b/hv7131r.c new file mode 100644 index 0000000..ea44300 --- /dev/null +++ b/hv7131r.c @@ -0,0 +1,128 @@ +/** + * @file hv7131r.c + * @author GWater + * @date 2008-12-17 + * + * @brief Common control functions the HV7131R Image Sensor + * + * @note Copyright (C) GWater + * + * @par Licences + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "microdia.h" +#include "sn9c20x.h" + +static __u8 hv7131r_init[][2] = { + {0x02, 0x08}, + {0x02, 0x00}, + {0x01, 0x08}, + {0x02, 0x00}, + {0x20, 0x00}, + {0x21, 0xd0}, + {0x22, 0x00}, + {0x23, 0x09}, + {0x01, 0x08}, + {0x01, 0x08}, + {0x01, 0x08}, + {0x25, 0x07}, + {0x26, 0xc3}, + {0x27, 0x50}, + {0x30, 0x62}, + {0x31, 0x10}, + {0x32, 0x06}, + {0x33, 0x10}, + {0x20, 0x00}, + {0x21, 0xd0}, + {0x22, 0x00}, + {0x23, 0x09}, + {0x01, 0x08}, +}; + +int hv7131r_initialize(struct usb_microdia *dev) +{ + int i; + int ret = 0; + + dev->camera.i2c_flags |= SN9C20X_I2C_400KHZ; + + for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) { + ret = sn9c20x_write_i2c_data(dev, 1, hv7131r_init[i][0], + &hv7131r_init[i][1]); + if (ret < 0) + goto err; + } + + return ret; + +err: + UDIA_ERROR("Sensor Init failed (%d)! - line %d\n", ret, i); + return ret; +} + +int hv7131r_set_exposure(struct usb_microdia *dev) +{ + __u8 buf[3]; + int ret; + __u32 val; + + val = (dev->vsettings.exposure * 0xffffff) / 0xffff; + + buf[0] = (val >> 16) & 0xff; + buf[1] = (val >> 8) & 0xff; + buf[2] = val & 0xff; + + ret = sn9c20x_write_i2c_data_ext(dev, 3, 0x25, buf, 0x1e); + + return ret; +} + +/* int hv7131r_set_gain(struct usb_microdia *dev) +{ + __u8 buf; + int ret; + + buf = (dev->vsettings.gain >> 8) & 0xff; + + ret = sn9c20x_write_i2c_data_ext(dev, 1, 0x30, &buf, 0x1d); + + return ret; +} */ + +int hv7131r_set_hvflip(struct usb_microdia *dev) +{ + __u8 buf; + int ret; + + ret = sn9c20x_read_i2c_data(dev, 1, 0x01, &buf); + if (ret < 0) + return ret; + + if (dev->vsettings.hflip) + buf |= 0x02; + else + buf &= ~0x02; + + if (dev->vsettings.vflip) + buf |= 0x01; + else + buf &= ~0x01; + + ret = sn9c20x_write_i2c_data(dev, 1, 0x01, &buf); + + return ret; +} diff --git a/microdia-dev.c b/microdia-dev.c index 2f684ce..d16481b 100644 --- a/microdia-dev.c +++ b/microdia-dev.c @@ -139,6 +139,18 @@ static struct sensor_info sensors[] = { .hstart = 2, .vstart = 2, }, + { + .id = HV7131R_SENSOR, + .name = "HV7131R", + .address = 0x11, + .initialize = hv7131r_initialize, + /* not yet available via V4L2: + .set_gain = hv7131r_set_gain, */ + .set_exposure = hv7131r_set_exposure, + .set_hvflip = hv7131r_set_hvflip, + .hstart = 0, + .vstart = 1, + }, }; static __u16 known_cams[][2] = { @@ -151,6 +163,7 @@ static __u16 known_cams[][2] = { {0x6253, OV9650_SENSOR}, {0x6260, OV7670_SENSOR}, {0x627b, OV7660_SENSOR}, + {0x627c, HV7131R_SENSOR}, {0x627f, OV9650_SENSOR}, {0x6280, MT9M001_SENSOR}, {0x6282, MT9M111_SENSOR}, @@ -160,6 +173,7 @@ static __u16 known_cams[][2] = { {0x62a0, OV7670_SENSOR}, {0x62b3, OV9655_SENSOR}, {0x62bb, OV7660_SENSOR}, + {0x62bc, HV7131R_SENSOR}, /* The following PIDs have VIDs different from 0x0c45. */ {0x00f4, OV9650_SENSOR}, {0x013d, OV7660_SENSOR}, diff --git a/microdia.h b/microdia.h index 1134542..3f5dd7c 100644 --- a/microdia.h +++ b/microdia.h @@ -324,6 +324,7 @@ enum microdia_sensors { MT9V111_SENSOR = 7, MT9V011_SENSOR = 8, MT9M001_SENSOR = 9, + HV7131R_SENSOR = 10, }; @@ -522,4 +523,10 @@ static inline int microdia_queue_streaming(struct microdia_video_queue *queue) return queue->flags & MICRODIA_QUEUE_STREAMING; } +/* sensor hv7131r has no header-file of its own: */ +int hv7131r_initialize(struct usb_microdia *dev); +int hv7131r_set_exposure(struct usb_microdia *dev); +/* int hv7131r_set_gain(struct usb_microdia *dev); */ +int hv7131r_set_hvflip(struct usb_microdia *dev); + #endif diff --git a/sn9c20x.c b/sn9c20x.c index 328dad2..b66c1e1 100644 --- a/sn9c20x.c +++ b/sn9c20x.c @@ -227,17 +227,12 @@ int sn9c20x_set_LEDs(struct usb_microdia *dev, int enable) if (enable) { switch (sensor) { case MT9M001_SENSOR: - led[0] = 0x80; - led[1] = 0xa0; - break; + case HV7131R_SENSOR: case SOI968_SENSOR: led[0] = 0x80; led[1] = 0xa0; break; case MT9V011_SENSOR: - led[0] = 0x40; - led[1] = 0x60; - break; case OV7660_SENSOR: led[0] = 0x40; led[1] = 0x60; @@ -252,18 +247,13 @@ int sn9c20x_set_LEDs(struct usb_microdia *dev, int enable) } } else { switch (sensor) { + case HV7131R_SENSOR: case MT9M001_SENSOR: - led[0] = 0xa0; - led[1] = 0xa0; - break; case MT9V011_SENSOR: led[0] = 0xa0; led[1] = 0xa0; break; case MT9M111_SENSOR: - led[0] = 0x20; - led[1] = 0x60; - break; case OV7660_SENSOR: led[0] = 0x20; led[1] = 0x60; -- 1.6.0.6
From 55a1cbdac19e13b67d9761cff48fd667c1bf378b Mon Sep 17 00:00:00 2001 From: GWater <[email protected]> Date: Fri, 19 Dec 2008 20:45:34 +0100 Subject: [PATCH] Add module parameter gain/V4L2_CID_GAIN Signed-off-by: GWater <[email protected]> --- hv7131r.c | 4 ++-- microdia-dev.c | 19 +++++++++++++++++-- microdia-usb.c | 8 ++++++++ microdia-v4l.c | 18 ++++++++++++++++++ microdia.h | 5 ++++- 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/hv7131r.c b/hv7131r.c index ea44300..291fbec 100644 --- a/hv7131r.c +++ b/hv7131r.c @@ -91,7 +91,7 @@ int hv7131r_set_exposure(struct usb_microdia *dev) return ret; } -/* int hv7131r_set_gain(struct usb_microdia *dev) +int hv7131r_set_gain(struct usb_microdia *dev) { __u8 buf; int ret; @@ -101,7 +101,7 @@ int hv7131r_set_exposure(struct usb_microdia *dev) ret = sn9c20x_write_i2c_data_ext(dev, 1, 0x30, &buf, 0x1d); return ret; -} */ +} int hv7131r_set_hvflip(struct usb_microdia *dev) { diff --git a/microdia-dev.c b/microdia-dev.c index d16481b..a6070f5 100644 --- a/microdia-dev.c +++ b/microdia-dev.c @@ -144,8 +144,7 @@ static struct sensor_info sensors[] = { .name = "HV7131R", .address = 0x11, .initialize = hv7131r_initialize, - /* not yet available via V4L2: - .set_gain = hv7131r_set_gain, */ + .set_gain = hv7131r_set_gain, .set_exposure = hv7131r_set_exposure, .set_hvflip = hv7131r_set_hvflip, .hstart = 0, @@ -441,6 +440,22 @@ int dev_microdia_camera_set_exposure(struct usb_microdia *dev) } /** + * @brief Wrapper function for device-specific gain functions + * + * @param dev Pointer to device structure + * + * @returns 0 or negative error value + * + */ +int dev_microdia_camera_set_gain(struct usb_microdia *dev) +{ + if (dev && dev->camera.sensor->set_gain != NULL) + return dev->camera.sensor->set_gain(dev); + + return 0; +} + +/** * @brief Wrapper function for device-specific hvflip functions * * @param dev Pointer to device structure diff --git a/microdia-usb.c b/microdia-usb.c index e9b405b..a06bdeb 100644 --- a/microdia-usb.c +++ b/microdia-usb.c @@ -96,6 +96,12 @@ static int contrast = MICRODIA_PERCENT(50, 0xFFFF); static int exposure = MICRODIA_PERCENT(20, 0xFFFF); /** + * @var gain + * Module parameter to set the gain + */ +static int gain = MICRODIA_PERCENT(20, 0xFFFF); + +/** * @var sharpness * Module parameter to set the sharpness */ @@ -705,6 +711,7 @@ static int usb_microdia_default_settings(struct usb_microdia *dev) dev->vsettings.contrast = contrast & 0xffff; dev->vsettings.whiteness = whiteness & 0xffff; dev->vsettings.exposure = exposure & 0xffff; + dev->vsettings.gain = gain & 0xffff; dev->vsettings.sharpness = sharpness & 0x3f; dev->vsettings.rgb_gain[0] = (rgb_gain >> 16) & 0x7f; dev->vsettings.rgb_gain[1] = (rgb_gain >> 8) & 0x7f; @@ -1023,6 +1030,7 @@ MODULE_PARM_DESC(auto_whitebalance, "Automatic whitebalance"); /**< @brief Descr MODULE_PARM_DESC(brightness, "Brightness setting"); /**< @brief Description of 'brightness' parameter */ MODULE_PARM_DESC(whiteness, "Whiteness setting"); /**< @brief Description of 'whiteness' parameter */ MODULE_PARM_DESC(exposure, "Exposure setting"); /**< @brief Description of 'exposure' parameter */ +MODULE_PARM_DESC(gain, "Gain setting"); /**< @brief Description of 'gain' parameter */ MODULE_PARM_DESC(contrast, "Contrast setting"); /**< @brief Description of 'contrast' parameter */ MODULE_PARM_DESC(sharpness, "Sharpness setting"); /**< @brief Description of 'sharpness' parameter */ MODULE_PARM_DESC(rgb_gain, "Red/Green/Blue Gain setting"); /**< @brief Description of 'RGB Gain' parameter */ diff --git a/microdia-v4l.c b/microdia-v4l.c index 4f6f11d..7be3909 100644 --- a/microdia-v4l.c +++ b/microdia-v4l.c @@ -96,6 +96,15 @@ static struct v4l2_queryctrl microdia_controls[] = { .default_value = 0x1000, }, { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, + .maximum = 0xff00, + .step = 1, + .default_value = 0x1000, + }, + { .id = V4L2_CID_HFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Horizontal flip", @@ -777,6 +786,10 @@ int microdia_vidioc_g_ctrl(struct file *file, void *priv, ctrl->value = dev->vsettings.exposure; break; + case V4L2_CID_GAIN: + ctrl->value = dev->vsettings.gain; + break; + case V4L2_CID_WHITENESS: ctrl->value = dev->vsettings.whiteness; break; @@ -857,6 +870,11 @@ int microdia_vidioc_s_ctrl(struct file *file, void *priv, dev_microdia_camera_set_exposure(dev); break; + case V4L2_CID_GAIN: + dev->vsettings.gain = (0xff00 & ctrl->value); + dev_microdia_camera_set_gain(dev); + break; + case V4L2_CID_WHITENESS: dev->vsettings.whiteness = (0xff00 & ctrl->value); dev_microdia_camera_set_gamma(dev); diff --git a/microdia.h b/microdia.h index 3f5dd7c..5a474b6 100644 --- a/microdia.h +++ b/microdia.h @@ -282,6 +282,7 @@ struct microdia_video { int hflip; /**< Horizontal flip */ int vflip; /**< Vertical flip */ int exposure; /**< Exposure */ + int gain; /**< Gain */ int sharpness; /**< Sharpness */ __u8 rgb_gain[4]; /**< RGB Gain (RGGB) */ int auto_exposure; /**< Automatic exposure */ @@ -362,6 +363,7 @@ struct sensor_info { /* sensor specific functions */ int (*initialize) (struct usb_microdia *dev); int (*set_exposure) (struct usb_microdia *dev); + int (*set_gain) (struct usb_microdia *dev); int (*set_auto_exposure) (struct usb_microdia *dev); int (*set_auto_gain) (struct usb_microdia *dev); int (*set_auto_whitebalance) (struct usb_microdia *dev); @@ -467,6 +469,7 @@ int dev_microdia_camera_set_contrast(struct usb_microdia *); int dev_microdia_camera_set_brightness(struct usb_microdia *); int dev_microdia_camera_set_gamma(struct usb_microdia *); int dev_microdia_camera_set_exposure(struct usb_microdia *); +int dev_microdia_camera_set_gain(struct usb_microdia *); int dev_microdia_camera_set_hvflip(struct usb_microdia *); int dev_microdia_camera_set_sharpness(struct usb_microdia *dev); int dev_microdia_camera_set_rgb_gain(struct usb_microdia *dev); @@ -526,7 +529,7 @@ static inline int microdia_queue_streaming(struct microdia_video_queue *queue) /* sensor hv7131r has no header-file of its own: */ int hv7131r_initialize(struct usb_microdia *dev); int hv7131r_set_exposure(struct usb_microdia *dev); -/* int hv7131r_set_gain(struct usb_microdia *dev); */ +int hv7131r_set_gain(struct usb_microdia *dev); int hv7131r_set_hvflip(struct usb_microdia *dev); #endif -- 1.6.0.6
From 2d2a26580ca0a4e08ba0094aeb373349374fcbdc Mon Sep 17 00:00:00 2001 From: GWater <[email protected]> Date: Fri, 19 Dec 2008 21:14:18 +0100 Subject: [PATCH] Add gain control for omnivision sensors Signed-off-by: GWater <[email protected]> --- microdia-dev.c | 5 +++++ omnivision.c | 32 ++++++++++++++++++++++++++++++++ omnivision.h | 1 + 3 files changed, 38 insertions(+), 0 deletions(-) diff --git a/microdia-dev.c b/microdia-dev.c index a6070f5..c0b7cb3 100644 --- a/microdia-dev.c +++ b/microdia-dev.c @@ -44,6 +44,7 @@ static struct sensor_info sensors[] = { .set_hvflip = ov965x_set_hvflip, .set_exposure = ov965x_set_exposure, .set_auto_gain = ov_set_autogain, + .set_gain = ov_set_gain, .flip_detect = ov965x_flip_detect, .get_yavg = ov965x_get_yavg, .min_yavg = 30, @@ -58,6 +59,7 @@ static struct sensor_info sensors[] = { .initialize = ov_initialize, .set_auto_exposure = ov_set_autoexposure, .set_auto_gain = ov_set_autogain, + .set_gain = ov_set_gain, .hstart = 0, .vstart = 7, }, @@ -69,6 +71,7 @@ static struct sensor_info sensors[] = { .set_exposure = soi968_set_exposure, .set_auto_exposure = ov_set_autoexposure, .set_auto_gain = ov_set_autogain, + .set_gain = ov_set_gain, .button_detect = soi968_button_detect, .hstart = 60, .vstart = 11, @@ -80,6 +83,7 @@ static struct sensor_info sensors[] = { .initialize = ov_initialize, .set_exposure = ov7660_set_exposure, .set_auto_gain = ov_set_autogain, + .set_gain = ov_set_gain, .hstart = 1, .vstart = 1, .get_yavg = ov965x_get_yavg, @@ -96,6 +100,7 @@ static struct sensor_info sensors[] = { .set_auto_exposure = ov_set_autoexposure, .set_exposure = ov7660_set_exposure, .set_auto_gain = ov_set_autogain, + .set_gain = ov_set_gain, .flip_detect = ov7670_flip_detect, .hstart = 0, .vstart = 1, diff --git a/omnivision.c b/omnivision.c index 7cfc230..b67742f 100644 --- a/omnivision.c +++ b/omnivision.c @@ -892,6 +892,38 @@ int soi968_set_exposure(struct usb_microdia *dev) return 0; } +int ov_set_gain(struct usb_microdia *dev) +{ + __u8 buf, buf2; + int ret; + __u16 val = dev->vsettings.gain; + + switch (dev->camera.sensor->id) { + case SOI968_SENSOR: + buf = (val >> 10) & 0x3f; + break; + case OV7660_SENSOR: + buf = (val >> 9) & 0x7f; + break; + case OV7670_SENSOR: + buf = (val >> 6) & 0xff; + ret = sn9c20x_read_i2c_data(dev, 1, 0x03, &buf2); + if (ret < 0) + return ret; + buf2 |= ((val >> 8) & 0xc0); + ret = sn9c20x_write_i2c_data(dev, 1, 0x03, &buf2); + if (ret < 0) + return ret; + break; + default: + buf = (val >> 8) & 0xff; + } + + ret = sn9c20x_write_i2c_data(dev, 1, 0x00, &buf); + + return ret; +} + /** * @brief Detect whether the image for 6260 has to be flipped * diff --git a/omnivision.h b/omnivision.h index 391fbf1..5840fb7 100644 --- a/omnivision.h +++ b/omnivision.h @@ -550,4 +550,5 @@ int ov965x_get_yavg(struct usb_microdia *dev); int ov_initialize(struct usb_microdia *dev); int ov_set_autogain(struct usb_microdia *dev); int ov_set_autoexposure(struct usb_microdia *dev); +int ov_set_gain(struct usb_microdia *dev); #endif -- 1.6.0.6
From dabf7fb879f9ade8f1c5d7838c6d303d353fae5a Mon Sep 17 00:00:00 2001 From: GWater <[email protected]> Date: Fri, 19 Dec 2008 21:58:36 +0100 Subject: [PATCH] YUV422 omnivision sensors This patch is based on an older version by Brian Johnson <[email protected]> . Signed-off-by: GWater <[email protected]> --- microdia-dev.c | 2 ++ microdia-v4l.c | 9 +++++++-- omnivision.c | 23 +++++++++++++++++++++-- omnivision.h | 3 +++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/microdia-dev.c b/microdia-dev.c index c0b7cb3..b17e921 100644 --- a/microdia-dev.c +++ b/microdia-dev.c @@ -51,6 +51,8 @@ static struct sensor_info sensors[] = { .max_yavg = 60, .min_stable_yavg = 32, .max_stable_yavg = 58, + .set_yuv422 = ov965x_set_yuv422, + .set_bayer = ov965x_set_bayer, }, { .id = OV9655_SENSOR, diff --git a/microdia-v4l.c b/microdia-v4l.c index 7be3909..1985fa3 100644 --- a/microdia-v4l.c +++ b/microdia-v4l.c @@ -374,9 +374,13 @@ int v4l2_enable_video(struct usb_microdia *dev, int mode) dev_microdia_enable_video(dev, 1); dev_microdia_camera_settings(dev); - dev->queue.flags &= ~MICRODIA_QUEUE_DROP_INCOMPLETE; dev->mode = mode; + if(dev->vsettings.format.pixelformat == V4L2_PIX_FMT_JPEG) + dev->queue.flags &= ~MICRODIA_QUEUE_DROP_INCOMPLETE; + else + dev->queue.flags |= MICRODIA_QUEUE_DROP_INCOMPLETE; + return 0; } @@ -1061,9 +1065,10 @@ int microdia_vidioc_s_fmt_cap(struct file *file, void *priv, if (ret) return -EINVAL; + memcpy(&(dev->vsettings.format), &(fmt->fmt.pix), sizeof(fmt->fmt.pix)); + sn9c20x_set_resolution(dev, fmt->fmt.pix.width, fmt->fmt.pix.height); dev->camera.fmts[fmt->fmt.pix.priv].set_format(dev); - memcpy(&(dev->vsettings.format), &(fmt->fmt.pix), sizeof(fmt->fmt.pix)); return 0; } diff --git a/omnivision.c b/omnivision.c index b67742f..eb6bd5c 100644 --- a/omnivision.c +++ b/omnivision.c @@ -352,8 +352,7 @@ static __u8 ov9650_init[][2] = { {OV965X_CTL_ADC, 0x00}, /* reserved */ {OV965X_CTL_ACOM, 0x93}, /* reserved */ {OV965X_CTL_OFON, 0x50}, - {OV965X_CTL_TSLB, OV965X_TSLB_OUTPUT_SEQ_UYVY | - OV965X_TSLB_DIGITAL_BLC_ENABLE}, + {OV965X_CTL_TSLB, OV965X_TSLB_DIGITAL_BLC_ENABLE}, {OV965X_CTL_COM11, OV965X_COM11_MANUAL_BANDING_FILTER}, {OV965X_CTL_COM12, 0x73}, {OV965X_CTL_COM13, OV965X_COM13_ENABLE_COLOR_MATRIX | @@ -810,6 +809,26 @@ int ov_set_autoexposure(struct usb_microdia *dev) return ret; } +int ov965x_set_yuv422(struct usb_microdia *dev) +{ + __u8 buf = OV965X_COM7_OUTPUT_VGA; + sn9c20x_write_i2c_data(dev, 1, 0x12, &buf); + + sn9c20x_set_raw(dev); + + return 0; +} + +int ov965x_set_bayer(struct usb_microdia *dev) +{ + __u8 buf = OV965X_COM7_OUTPUT_RAW_RGB; + sn9c20x_write_i2c_data(dev, 1, 0x12, &buf); + + sn9c20x_set_raw(dev); + + return 0; +} + /** * @brief Set autogain for omnivision sensors * diff --git a/omnivision.h b/omnivision.h index 5840fb7..5246275 100644 --- a/omnivision.h +++ b/omnivision.h @@ -546,6 +546,9 @@ int ov965x_set_hvflip(struct usb_microdia *); int ov965x_set_exposure(struct usb_microdia *); int ov965x_flip_detect(struct usb_microdia *dev); int ov965x_get_yavg(struct usb_microdia *dev); +int ov965x_set_yuv422(struct usb_microdia *dev); +int ov965x_set_bayer(struct usb_microdia *dev); + int ov_initialize(struct usb_microdia *dev); int ov_set_autogain(struct usb_microdia *dev); -- 1.6.0.6
From 777b0d6b4f470514be40659f2a9a0dd1cba4d6c7 Mon Sep 17 00:00:00 2001 From: GWater <[email protected]> Date: Fri, 19 Dec 2008 22:21:59 +0100 Subject: [PATCH] Copy default_fmts for every microdia device to avoid problems with multiple webcams on one host Signed-off-by: GWater <[email protected]> --- microdia-dev.c | 9 ++++++++- microdia-usb.c | 2 ++ 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/microdia-dev.c b/microdia-dev.c index b17e921..4675210 100644 --- a/microdia-dev.c +++ b/microdia-dev.c @@ -283,7 +283,14 @@ int dev_microdia_assign_fmts(struct usb_microdia *dev) { int i, j; - dev->camera.fmts = default_fmts; + struct microdia_video_format *sensor_fmts = + kcalloc(ARRAY_SIZE(default_fmts), + sizeof(struct microdia_video_format), GFP_KERNEL); + + for (i = 0; i < ARRAY_SIZE(default_fmts); i++) + sensor_fmts[i] = default_fmts[i]; + + dev->camera.fmts = sensor_fmts; dev->camera.nfmts = ARRAY_SIZE(default_fmts); for (i = 0; i < ARRAY_SIZE(default_fmts); i++) { diff --git a/microdia-usb.c b/microdia-usb.c index a06bdeb..cd5e1bd 100644 --- a/microdia-usb.c +++ b/microdia-usb.c @@ -844,6 +844,8 @@ void usb_microdia_delete(struct kref *kref) microdia_remove_debugfs_files(dev); v4l_microdia_unregister_video_device(dev); } + if (dev->camera.fmts != NULL) + kfree(dev->camera.fmts); kfree(dev); } -- 1.6.0.6
From 006d906eeeb34289e946abe79b41453595abd6bd Mon Sep 17 00:00:00 2001 From: GWater <[email protected]> Date: Sat, 20 Dec 2008 00:36:32 +0100 Subject: [PATCH] Implement V4L2_CTRL_FLAG_NEXT_CTRL This fixes the problem with V4L2_CID_EXPOSURE_AUTO Signed-off-by: GWater <[email protected]> --- microdia-v4l.c | 50 +++++++++++++++++++++++++++++++++++++------------- 1 files changed, 37 insertions(+), 13 deletions(-) diff --git a/microdia-v4l.c b/microdia-v4l.c index 1985fa3..ec70454 100644 --- a/microdia-v4l.c +++ b/microdia-v4l.c @@ -743,18 +743,42 @@ int microdia_vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *ctrl) { int i; - int nbr; - - UDIA_DEBUG("VIDIOC_QUERYCTRL id = %d\n", ctrl->id); - - nbr = sizeof(microdia_controls)/sizeof(struct v4l2_queryctrl); - - for (i = 0; i < nbr; i++) { - if (microdia_controls[i].id == ctrl->id) { + int nbr = ARRAY_SIZE(microdia_controls); +#ifdef V4L2_CTRL_FLAG_NEXT_CTRL + int min; + __u32 idnew, idlast; +#endif + UDIA_DEBUG("VIDIOC_QUERYCTRL id = 0x%x\n", ctrl->id); + +#ifdef V4L2_CTRL_FLAG_NEXT_CTRL + if (ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL) { + min = 0; + idnew = V4L2_CTRL_FLAG_NEXT_CTRL; + idlast = ctrl->id & ~V4L2_CTRL_FLAG_NEXT_CTRL; + for (i = 0; i < nbr; i++) { + if ((microdia_controls[i].id < idnew) && + (microdia_controls[i].id > idlast)) { + idnew = microdia_controls[i].id; + min = i; + } + } + if (idnew != V4L2_CTRL_FLAG_NEXT_CTRL) { UDIA_DEBUG("VIDIOC_QUERYCTRL found\n"); - memcpy(ctrl, µdia_controls[i], - sizeof(struct v4l2_queryctrl)); - break; + memcpy(ctrl, µdia_controls[min], + sizeof(struct v4l2_queryctrl)); + return 0; + } else + return -EINVAL; + } else +#endif + { + for (i = 0; i < nbr; i++) { + if (microdia_controls[i].id == ctrl->id) { + UDIA_DEBUG("VIDIOC_QUERYCTRL found\n"); + memcpy(ctrl, µdia_controls[i], + sizeof(struct v4l2_queryctrl)); + break; + } } } @@ -779,7 +803,7 @@ int microdia_vidioc_g_ctrl(struct file *file, void *priv, dev = video_get_drvdata(priv); - UDIA_DEBUG("GET CTRL id=%d\n", ctrl->id); + UDIA_DEBUG("GET CTRL id=0x%x\n", ctrl->id); switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: @@ -861,7 +885,7 @@ int microdia_vidioc_s_ctrl(struct file *file, void *priv, dev = video_get_drvdata(priv); - UDIA_DEBUG("SET CTRL id=%d value=%d\n", ctrl->id, ctrl->value); + UDIA_DEBUG("SET CTRL id=0x%x value=%d\n", ctrl->id, ctrl->value); switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: -- 1.6.0.6
signature.asc
Description: OpenPGP digital signature
