aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorJames Blanford <jhblanford@gmail.com>2009-09-18 13:56:04 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:52:46 -0400
commit35ccf8f8eaa97637ccadbc4b4c6345eb3753d9a9 (patch)
tree8f14b4af4f5fa35227ca7cf97a2c73b1983c7351 /drivers/media/video
parent4711ca823bed12be879f22a930aa9deded9736df (diff)
V4L/DVB (13009): gspca - stv06xx-hdcs: Reduce exposure range
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>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c72
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h2
2 files changed, 22 insertions, 52 deletions
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index 1655dcd1a5dc..706e08dc5254 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -37,7 +37,7 @@ static const struct ctrl hdcs1x00_ctrl[] = {
37 .type = V4L2_CTRL_TYPE_INTEGER, 37 .type = V4L2_CTRL_TYPE_INTEGER,
38 .name = "exposure", 38 .name = "exposure",
39 .minimum = 0x00, 39 .minimum = 0x00,
40 .maximum = 0xffff, 40 .maximum = 0xff,
41 .step = 0x1, 41 .step = 0x1,
42 .default_value = HDCS_DEFAULT_EXPOSURE, 42 .default_value = HDCS_DEFAULT_EXPOSURE,
43 .flags = V4L2_CTRL_FLAG_SLIDER 43 .flags = V4L2_CTRL_FLAG_SLIDER
@@ -148,6 +148,7 @@ struct hdcs {
148 } exp; 148 } exp;
149 149
150 int psmp; 150 int psmp;
151 u8 exp_cache, gain_cache;
151}; 152};
152 153
153static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) 154static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
@@ -233,34 +234,8 @@ static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
233 struct sd *sd = (struct sd *) gspca_dev; 234 struct sd *sd = (struct sd *) gspca_dev;
234 struct hdcs *hdcs = sd->sensor_priv; 235 struct hdcs *hdcs = sd->sensor_priv;
235 236
236 /* Column time period */ 237 *val = hdcs->exp_cache;
237 int ct;
238 /* Column processing period */
239 int cp;
240 /* Row processing period */
241 int rp;
242 int cycles;
243 int err;
244 int rowexp;
245 u16 data[2];
246
247 err = stv06xx_read_sensor(sd, HDCS_ROWEXPL, &data[0]);
248 if (err < 0)
249 return err;
250
251 err = stv06xx_read_sensor(sd, HDCS_ROWEXPH, &data[1]);
252 if (err < 0)
253 return err;
254
255 rowexp = (data[1] << 8) | data[0];
256 238
257 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
258 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
259 rp = hdcs->exp.rs + cp;
260
261 cycles = rp * rowexp;
262 *val = cycles / HDCS_CLK_FREQ_MHZ;
263 PDEBUG(D_V4L2, "Read exposure %d", *val);
264 return 0; 239 return 0;
265} 240}
266 241
@@ -282,7 +257,10 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
282 int cycles, err; 257 int cycles, err;
283 u8 exp[14]; 258 u8 exp[14];
284 259
285 cycles = val * HDCS_CLK_FREQ_MHZ; 260 val &= 0xff;
261 hdcs->exp_cache = val;
262
263 cycles = val * HDCS_CLK_FREQ_MHZ * 257;
286 264
287 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2); 265 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
288 cp = hdcs->exp.cto + (hdcs->w * ct / 2); 266 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
@@ -353,49 +331,42 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
353 return err; 331 return err;
354} 332}
355 333
356static int hdcs_set_gains(struct sd *sd, u8 r, u8 g, u8 b) 334static int hdcs_set_gains(struct sd *sd, u8 g)
357{ 335{
336 struct hdcs *hdcs = sd->sensor_priv;
337 int err;
358 u8 gains[4]; 338 u8 gains[4];
359 339
340 hdcs->gain_cache = g;
341
360 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */ 342 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
361 if (r > 127)
362 r = 0x80 | (r / 2);
363 if (g > 127) 343 if (g > 127)
364 g = 0x80 | (g / 2); 344 g = 0x80 | (g / 2);
365 if (b > 127)
366 b = 0x80 | (b / 2);
367 345
368 gains[0] = g; 346 gains[0] = g;
369 gains[1] = r; 347 gains[1] = g;
370 gains[2] = b; 348 gains[2] = g;
371 gains[3] = g; 349 gains[3] = g;
372 350
373 return hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4); 351 err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
352 return err;
374} 353}
375 354
376static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 355static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
377{ 356{
378 struct sd *sd = (struct sd *) gspca_dev; 357 struct sd *sd = (struct sd *) gspca_dev;
379 int err; 358 struct hdcs *hdcs = sd->sensor_priv;
380 u16 data;
381 359
382 err = stv06xx_read_sensor(sd, HDCS_ERECPGA, &data); 360 *val = hdcs->gain_cache;
383 361
384 /* Bit 7 doubles the gain */ 362 return 0;
385 if (data & 0x80)
386 *val = (data & 0x7f) * 2;
387 else
388 *val = data;
389
390 PDEBUG(D_V4L2, "Read gain %d", *val);
391 return err;
392} 363}
393 364
394static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val) 365static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
395{ 366{
396 PDEBUG(D_V4L2, "Writing gain %d", val); 367 PDEBUG(D_V4L2, "Writing gain %d", val);
397 return hdcs_set_gains((struct sd *) gspca_dev, 368 return hdcs_set_gains((struct sd *) gspca_dev,
398 val & 0xff, val & 0xff, val & 0xff); 369 val & 0xff);
399} 370}
400 371
401static int hdcs_set_size(struct sd *sd, 372static int hdcs_set_size(struct sd *sd,
@@ -613,8 +584,7 @@ static int hdcs_init(struct sd *sd)
613 if (err < 0) 584 if (err < 0)
614 return err; 585 return err;
615 586
616 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN, HDCS_DEFAULT_GAIN, 587 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN);
617 HDCS_DEFAULT_GAIN);
618 if (err < 0) 588 if (err < 0)
619 return err; 589 return err;
620 590
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index 412f06cf3d5c..37b31c99d956 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -124,7 +124,7 @@
124#define HDCS_RUN_ENABLE (1 << 2) 124#define HDCS_RUN_ENABLE (1 << 2)
125#define HDCS_SLEEP_MODE (1 << 1) 125#define HDCS_SLEEP_MODE (1 << 1)
126 126
127#define HDCS_DEFAULT_EXPOSURE 5000 127#define HDCS_DEFAULT_EXPOSURE 48
128#define HDCS_DEFAULT_GAIN 128 128#define HDCS_DEFAULT_GAIN 128
129 129
130static int hdcs_probe_1x00(struct sd *sd); 130static int hdcs_probe_1x00(struct sd *sd);