aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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);