summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/gspca/pac207.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/gspca/pac207.c')
-rw-r--r--linux/drivers/media/video/gspca/pac207.c87
1 files changed, 14 insertions, 73 deletions
diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c
index 4f197c1f4..fa7abc411 100644
--- a/linux/drivers/media/video/gspca/pac207.c
+++ b/linux/drivers/media/video/gspca/pac207.c
@@ -27,8 +27,8 @@
#include "gspca.h"
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5)
-static const char version[] = "2.1.5";
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
MODULE_DESCRIPTION("Pixart PAC207");
@@ -187,18 +187,18 @@ static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
static const unsigned char pac207_sof_marker[5] =
{ 0xff, 0xff, 0x00, 0xff, 0x96 };
-int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
+static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
const u8 *buffer, u16 length)
{
struct usb_device *udev = gspca_dev->dev;
int err;
- u8 kbuf[8];
- memcpy(kbuf, buffer, length);
+ memcpy(gspca_dev->usb_buf, buffer, length);
err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0x00, index, kbuf, length, PAC207_CTRL_TIMEOUT);
+ 0x00, index,
+ gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT);
if (err < 0)
PDEBUG(D_ERR,
"Failed to write registers to index 0x%04X, error %d)",
@@ -227,12 +227,12 @@ int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
{
struct usb_device *udev = gspca_dev->dev;
- u8 buff;
int res;
res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- 0x00, index, &buff, 1, PAC207_CTRL_TIMEOUT);
+ 0x00, index,
+ gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT);
if (res < 0) {
PDEBUG(D_ERR,
"Failed to read a register (index 0x%04X, error %d)",
@@ -240,10 +240,9 @@ int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
return res;
}
- return buff;
+ return gspca_dev->usb_buf[0];
}
-
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
@@ -357,70 +356,20 @@ static void sd_close(struct gspca_dev *gspca_dev)
{
}
-/* auto gain and exposure algorithm based on the knee algorithm described here:
- * <http://ytse.tricolour.net/docs/LowLightOptimization.html> */
static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int i, steps, desired_avg_lum;
- int orig_gain = sd->gain;
- int orig_exposure = sd->exposure;
int avg_lum = atomic_read(&sd->avg_lum);
- if (!sd->autogain || avg_lum == -1)
+ if (avg_lum == -1)
return;
- if (sd->autogain_ignore_frames > 0) {
+ if (sd->autogain_ignore_frames > 0)
sd->autogain_ignore_frames--;
- return;
- }
-
- /* correct desired lumination for the configured brightness */
- desired_avg_lum = 100 + sd->brightness / 2;
-
- /* If we are of a multiple of deadzone, do multiple step to reach the
- desired lumination fast (with the risc of a slight overshoot) */
- steps = abs(desired_avg_lum - avg_lum) / PAC207_AUTOGAIN_DEADZONE;
-
- for (i = 0; i < steps; i++) {
- if (avg_lum > desired_avg_lum) {
- if (sd->gain > PAC207_GAIN_KNEE)
- sd->gain--;
- else if (sd->exposure > PAC207_EXPOSURE_KNEE)
- sd->exposure--;
- else if (sd->gain > PAC207_GAIN_DEFAULT)
- sd->gain--;
- else if (sd->exposure > PAC207_EXPOSURE_MIN)
- sd->exposure--;
- else if (sd->gain > PAC207_GAIN_MIN)
- sd->gain--;
- else
- break;
- } else {
- if (sd->gain < PAC207_GAIN_DEFAULT)
- sd->gain++;
- else if (sd->exposure < PAC207_EXPOSURE_KNEE)
- sd->exposure++;
- else if (sd->gain < PAC207_GAIN_KNEE)
- sd->gain++;
- else if (sd->exposure < PAC207_EXPOSURE_MAX)
- sd->exposure++;
- else if (sd->gain < PAC207_GAIN_MAX)
- sd->gain++;
- else
- break;
- }
- }
-
- if (sd->exposure != orig_exposure || sd->gain != orig_gain) {
- if (sd->exposure != orig_exposure)
- pac207_write_reg(gspca_dev, 0x0002, sd->exposure);
- if (sd->gain != orig_gain)
- pac207_write_reg(gspca_dev, 0x000e, sd->gain);
- pac207_write_reg(gspca_dev, 0x13, 0x01); /* load reg to sen */
- pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
+ else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
+ 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
+ PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES;
- }
}
static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev,
@@ -546,10 +495,6 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
- /* don't allow mucking with exposure when using autogain */
- if (sd->autogain)
- return -EINVAL;
-
sd->exposure = val;
if (gspca_dev->streaming)
setexposure(gspca_dev);
@@ -568,10 +513,6 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
- /* don't allow mucking with gain when using autogain */
- if (sd->autogain)
- return -EINVAL;
-
sd->gain = val;
if (gspca_dev->streaming)
setgain(gspca_dev);