Skip to content

Commit

Permalink
V4L/DVB (13009): gspca - stv06xx-hdcs: Reduce exposure range
Browse files Browse the repository at this point in the history
Due to rounding and clipping, exposure and gain settings do not map to
unique register values.  Rather than read the registers and report gain
and exposure that may be different than the values that were set, just
cache the latest values that were set and report them.  Reduce exposure
range from 0-65535 to 0-255 so libv4l's autogain doesn't take forever.
Remove vestiges of driver signal processing that is now handled by
libv4l.

Signed-off-by: James Blanford <jhblanford@gmail.com>
Signed-off-by: Erik Andrén <erik.andren@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
James Blanford authored and Mauro Carvalho Chehab committed Sep 19, 2009
1 parent 4711ca8 commit 35ccf8f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 52 deletions.
72 changes: 21 additions & 51 deletions drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static const struct ctrl hdcs1x00_ctrl[] = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "exposure",
.minimum = 0x00,
.maximum = 0xffff,
.maximum = 0xff,
.step = 0x1,
.default_value = HDCS_DEFAULT_EXPOSURE,
.flags = V4L2_CTRL_FLAG_SLIDER
Expand Down Expand Up @@ -148,6 +148,7 @@ struct hdcs {
} exp;

int psmp;
u8 exp_cache, gain_cache;
};

static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
Expand Down Expand Up @@ -233,34 +234,8 @@ static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
struct sd *sd = (struct sd *) gspca_dev;
struct hdcs *hdcs = sd->sensor_priv;

/* Column time period */
int ct;
/* Column processing period */
int cp;
/* Row processing period */
int rp;
int cycles;
int err;
int rowexp;
u16 data[2];

err = stv06xx_read_sensor(sd, HDCS_ROWEXPL, &data[0]);
if (err < 0)
return err;

err = stv06xx_read_sensor(sd, HDCS_ROWEXPH, &data[1]);
if (err < 0)
return err;

rowexp = (data[1] << 8) | data[0];
*val = hdcs->exp_cache;

ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
cp = hdcs->exp.cto + (hdcs->w * ct / 2);
rp = hdcs->exp.rs + cp;

cycles = rp * rowexp;
*val = cycles / HDCS_CLK_FREQ_MHZ;
PDEBUG(D_V4L2, "Read exposure %d", *val);
return 0;
}

Expand All @@ -282,7 +257,10 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
int cycles, err;
u8 exp[14];

cycles = val * HDCS_CLK_FREQ_MHZ;
val &= 0xff;
hdcs->exp_cache = val;

cycles = val * HDCS_CLK_FREQ_MHZ * 257;

ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
cp = hdcs->exp.cto + (hdcs->w * ct / 2);
Expand Down Expand Up @@ -353,49 +331,42 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
return err;
}

static int hdcs_set_gains(struct sd *sd, u8 r, u8 g, u8 b)
static int hdcs_set_gains(struct sd *sd, u8 g)
{
struct hdcs *hdcs = sd->sensor_priv;
int err;
u8 gains[4];

hdcs->gain_cache = g;

/* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
if (r > 127)
r = 0x80 | (r / 2);
if (g > 127)
g = 0x80 | (g / 2);
if (b > 127)
b = 0x80 | (b / 2);

gains[0] = g;
gains[1] = r;
gains[2] = b;
gains[1] = g;
gains[2] = g;
gains[3] = g;

return hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
return err;
}

static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
int err;
u16 data;
struct hdcs *hdcs = sd->sensor_priv;

err = stv06xx_read_sensor(sd, HDCS_ERECPGA, &data);
*val = hdcs->gain_cache;

/* Bit 7 doubles the gain */
if (data & 0x80)
*val = (data & 0x7f) * 2;
else
*val = data;

PDEBUG(D_V4L2, "Read gain %d", *val);
return err;
return 0;
}

static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
{
PDEBUG(D_V4L2, "Writing gain %d", val);
return hdcs_set_gains((struct sd *) gspca_dev,
val & 0xff, val & 0xff, val & 0xff);
val & 0xff);
}

static int hdcs_set_size(struct sd *sd,
Expand Down Expand Up @@ -613,8 +584,7 @@ static int hdcs_init(struct sd *sd)
if (err < 0)
return err;

err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN, HDCS_DEFAULT_GAIN,
HDCS_DEFAULT_GAIN);
err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN);
if (err < 0)
return err;

Expand Down
2 changes: 1 addition & 1 deletion drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
#define HDCS_RUN_ENABLE (1 << 2)
#define HDCS_SLEEP_MODE (1 << 1)

#define HDCS_DEFAULT_EXPOSURE 5000
#define HDCS_DEFAULT_EXPOSURE 48
#define HDCS_DEFAULT_GAIN 128

static int hdcs_probe_1x00(struct sd *sd);
Expand Down

0 comments on commit 35ccf8f

Please sign in to comment.