forked from Minki/linux
V4L/DVB (8873): gspca: Bad image offset with rev012a of spca561 and adjust exposure.
-Make raw bayer header size change from 20 to 16 affect rev072a only, my 2 rev012a cams both have a header size of 20 -While testing this I also tested the new exposure setting (good work on finding the register JF), and after quite a bit of testing have found out the exact meaning of the register, this patch modifies setexposure to control the exposure over a much wider range. Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl> Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
b77c0046a6
commit
0fc23d2069
@ -38,9 +38,9 @@ struct sd {
|
||||
#define CONTRAST_MAX 0x3fff
|
||||
|
||||
__u16 exposure; /* rev12a only */
|
||||
#define EXPOSURE_MIN 0
|
||||
#define EXPOSURE_MIN 1
|
||||
#define EXPOSURE_DEF 200
|
||||
#define EXPOSURE_MAX 762
|
||||
#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
|
||||
|
||||
__u8 brightness; /* rev72a only */
|
||||
#define BRIGHTNESS_MIN 0
|
||||
@ -648,9 +648,31 @@ static void setexposure(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int expo;
|
||||
int clock_divider;
|
||||
__u8 data[2];
|
||||
|
||||
expo = sd->exposure + 0x20a8; /* from test */
|
||||
/* Register 0x8309 controls exposure for the spca561,
|
||||
the basic exposure setting goes from 1-2047, where 1 is completely
|
||||
dark and 2047 is very bright. It not only influences exposure but
|
||||
also the framerate (to allow for longer exposure) from 1 - 300 it
|
||||
only raises the exposure time then from 300 - 600 it halves the
|
||||
framerate to be able to further raise the exposure time and for every
|
||||
300 more it halves the framerate again. This allows for a maximum
|
||||
exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
|
||||
Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
|
||||
configure a divider for the base framerate which us used at the
|
||||
exposure setting of 1-300. These bits configure the base framerate
|
||||
according to the following formula: fps = 60 / (value + 2) */
|
||||
if (sd->exposure < 2048) {
|
||||
expo = sd->exposure;
|
||||
clock_divider = 0;
|
||||
} else {
|
||||
/* Add 900 to make the 0 setting of the second part of the
|
||||
exposure equal to the 2047 setting of the first part. */
|
||||
expo = (sd->exposure - 2048) + 900;
|
||||
clock_divider = 3;
|
||||
}
|
||||
expo |= clock_divider << 11;
|
||||
data[0] = expo;
|
||||
data[1] = expo >> 8;
|
||||
reg_w_buf(gspca_dev, 0x8309, data, 2);
|
||||
@ -680,23 +702,11 @@ static void setautogain(struct gspca_dev *gspca_dev)
|
||||
static void sd_start_12a(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct usb_device *dev = gspca_dev->dev;
|
||||
int Clck;
|
||||
int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */
|
||||
__u8 Reg8307[] = { 0xaa, 0x00 };
|
||||
int mode;
|
||||
|
||||
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
|
||||
switch (mode) {
|
||||
case 0:
|
||||
case 1:
|
||||
Clck = 0x8a;
|
||||
break;
|
||||
case 2:
|
||||
Clck = 0x85;
|
||||
break;
|
||||
default:
|
||||
Clck = 0x83;
|
||||
break;
|
||||
}
|
||||
if (mode <= 1) {
|
||||
/* Use compression on 320x240 and above */
|
||||
reg_w_val(dev, 0x8500, 0x10 | mode);
|
||||
@ -714,6 +724,7 @@ static void sd_start_12a(struct gspca_dev *gspca_dev)
|
||||
setcontrast(gspca_dev);
|
||||
setwhite(gspca_dev);
|
||||
setautogain(gspca_dev);
|
||||
setexposure(gspca_dev);
|
||||
}
|
||||
static void sd_start_72a(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
@ -849,6 +860,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
__u8 *data, /* isoc packet */
|
||||
int len) /* iso packet length */
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
switch (data[0]) {
|
||||
case 0: /* start of frame */
|
||||
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
|
||||
@ -861,9 +874,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
frame, data, len);
|
||||
} else {
|
||||
/* raw bayer (with a header, which we skip) */
|
||||
/*fixme: is this specific to the rev012a? */
|
||||
data += 16;
|
||||
len -= 16;
|
||||
if (sd->chip_revision == Rev012A) {
|
||||
data += 20;
|
||||
len -= 20;
|
||||
} else {
|
||||
data += 16;
|
||||
len -= 16;
|
||||
}
|
||||
gspca_frame_add(gspca_dev, FIRST_PACKET,
|
||||
frame, data, len);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user