Skip to content

Commit

Permalink
V4L/DVB (8357): gspca: Perfect exposure for sn9c10x, sensor ov6650.
Browse files Browse the repository at this point in the history
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@infradead.org>
  • Loading branch information
Hans de Goede authored and Mauro Carvalho Chehab committed Jul 20, 2008
1 parent 3647fea commit f4d5202
Showing 1 changed file with 43 additions and 11 deletions.
54 changes: 43 additions & 11 deletions drivers/media/video/gspca/sonixb.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ static struct ctrl sd_ctrls[] = {
.id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Exposure",
#define EXPOSURE_DEF 0
#define EXPOSURE_KNEE 176 /* 10 fps */
#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
.minimum = 0,
.maximum = 255,
.step = 1,
Expand Down Expand Up @@ -611,8 +611,6 @@ static void setgain(struct gspca_dev *gspca_dev)
static void setexposure(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
/* translate 0 - 255 to a number of fps in a 30 - 1 scale */
int fps = 30 - sd->exposure * 29 / 255;

switch (sd->sensor) {
case SENSOR_TAS5110: {
Expand All @@ -621,19 +619,53 @@ static void setexposure(struct gspca_dev *gspca_dev)
/* register 19's high nibble contains the sn9c10x clock divider
The high nibble configures the no fps according to the
formula: 60 / high_nibble. With a maximum of 30 fps */
reg = 60 / fps;
if (reg > 15)
reg = 120 * sd->exposure / 1000;
if (reg < 2)
reg = 2;
else if (reg > 15)
reg = 15;
reg = (reg << 4) | 0x0b;
reg_w(gspca_dev, 0x19, &reg, 1);
break;
}
case SENSOR_OV6650: {
__u8 i2c[] = {0xa0, 0x60, 0x11, 0xc0, 0x00, 0x00, 0x00, 0x10};
i2c[3] = 30 / fps - 1;
if (i2c[3] > 15)
i2c[3] = 15;
i2c[3] |= 0xc0;
/* The ov6650 has 2 registers which both influence exposure,
first there is register 11, whose low nibble sets the no fps
according to: fps = 30 / (low_nibble + 1)
The fps configures the maximum exposure setting, but it is
possible to use less exposure then what the fps maximum
allows by setting register 10. register 10 configures the
actual exposure as quotient of the full exposure, with 0
being no exposure at all (not very usefull) and reg10_max
being max exposure possible at that framerate.
The code maps our 0 - 510 ms exposure ctrl to these 2
registers, trying to keep fps as high as possible.
*/
__u8 i2c[] = {0xb0, 0x60, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
int reg10, reg11;
/* No clear idea why, but setting reg10 above this value
results in no change */
const int reg10_max = 0x4d;

reg11 = (60 * sd->exposure + 999) / 1000;
if (reg11 < 1)
reg11 = 1;
else if (reg11 > 16)
reg11 = 16;

/* frame exposure time in ms = 1000 * reg11 / 30 ->
reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
if (reg10 < 1) /* 0 is a valid value, but is very _black_ */
reg10 = 1;
else if (reg10 > reg10_max)
reg10 = reg10_max;

/* Write reg 10 and reg11 low nibble */
i2c[3] = reg10;
i2c[4] |= reg11 - 1;
if (i2c_w(gspca_dev, i2c) < 0)
PDEBUG(D_ERR, "i2c error exposure");
break;
Expand Down

0 comments on commit f4d5202

Please sign in to comment.