aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/stv06xx
diff options
context:
space:
mode:
authorErik Andrén <erik.andren@gmail.com>2009-05-03 14:45:48 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 17:20:53 -0400
commit1906d8d17e556510603a9281b4fa960f2d73cc37 (patch)
tree4621b48b80fddbfc08919e7a6a774a45d3d7082b /drivers/media/video/gspca/stv06xx
parent1b844b536794163eb676b71e6e4c033f6d4b6b33 (diff)
V4L/DVB (11693): gspca - stv06xx-vv6410: Add exposure ctrl
Add the possibility to control the exposure on the vv6410 sensor 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/gspca/stv06xx')
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c69
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h4
2 files changed, 72 insertions, 1 deletions
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index 69c77c932fc0..f6603a9deab8 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -84,8 +84,22 @@ static const struct ctrl vv6410_ctrl[] = {
84 }, 84 },
85 .set = vv6410_set_analog_gain, 85 .set = vv6410_set_analog_gain,
86 .get = vv6410_get_analog_gain 86 .get = vv6410_get_analog_gain
87 },
88#define EXPOSURE_IDX 3
89 {
90 {
91 .id = V4L2_CID_EXPOSURE,
92 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "exposure",
94 .minimum = 0,
95 .maximum = 32768,
96 .step = 1,
97 .default_value = 20000
98 },
99 .set = vv6410_set_exposure,
100 .get = vv6410_get_exposure
87 } 101 }
88}; 102 };
89 103
90static int vv6410_probe(struct sd *sd) 104static int vv6410_probe(struct sd *sd)
91{ 105{
@@ -121,6 +135,7 @@ static int vv6410_probe(struct sd *sd)
121static int vv6410_init(struct sd *sd) 135static int vv6410_init(struct sd *sd)
122{ 136{
123 int err = 0, i; 137 int err = 0, i;
138 s32 *sensor_settings = sd->sensor_priv;
124 139
125 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) { 140 for (i = 0; i < ARRAY_SIZE(stv_bridge_init); i++) {
126 /* if NULL then len contains single value */ 141 /* if NULL then len contains single value */
@@ -142,6 +157,11 @@ static int vv6410_init(struct sd *sd)
142 157
143 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init, 158 err = stv06xx_write_sensor_bytes(sd, (u8 *) vv6410_sensor_init,
144 ARRAY_SIZE(vv6410_sensor_init)); 159 ARRAY_SIZE(vv6410_sensor_init));
160 if (err < 0)
161 return err;
162
163 err = vv6410_set_exposure(&sd->gspca_dev,
164 sensor_settings[EXPOSURE_IDX]);
145 165
146 return (err < 0) ? err : 0; 166 return (err < 0) ? err : 0;
147} 167}
@@ -318,3 +338,50 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
318 338
319 return (err < 0) ? err : 0; 339 return (err < 0) ? err : 0;
320} 340}
341
342static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
343{
344 struct sd *sd = (struct sd *) gspca_dev;
345 s32 *sensor_settings = sd->sensor_priv;
346
347 *val = sensor_settings[EXPOSURE_IDX];
348
349 PDEBUG(D_V4L2, "Read exposure %d", *val);
350
351 return 0;
352}
353
354static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
355{
356 int err;
357 struct sd *sd = (struct sd *) gspca_dev;
358 s32 *sensor_settings = sd->sensor_priv;
359 unsigned int fine, coarse;
360
361 sensor_settings[EXPOSURE_IDX] = val;
362
363 val = (val * val >> 14) + val / 4;
364
365 fine = val % VV6410_CIF_LINELENGTH;
366 coarse = min(512, val / VV6410_CIF_LINELENGTH);
367
368 PDEBUG(D_V4L2, "Set coarse exposure to %d, fine expsure to %d",
369 coarse, fine);
370
371 err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8);
372 if (err < 0)
373 goto out;
374
375 err = stv06xx_write_sensor(sd, VV6410_FINEL, fine & 0xff);
376 if (err < 0)
377 goto out;
378
379 err = stv06xx_write_sensor(sd, VV6410_COARSEH, coarse >> 8);
380 if (err < 0)
381 goto out;
382
383 err = stv06xx_write_sensor(sd, VV6410_COARSEL, coarse & 0xff);
384
385out:
386 return err;
387}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 95ac55891bd4..809f92264977 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -173,6 +173,8 @@
173#define VV6410_SUBSAMPLE 0x01 173#define VV6410_SUBSAMPLE 0x01
174#define VV6410_CROP_TO_QVGA 0x02 174#define VV6410_CROP_TO_QVGA 0x02
175 175
176#define VV6410_CIF_LINELENGTH 415
177
176static int vv6410_probe(struct sd *sd); 178static int vv6410_probe(struct sd *sd);
177static int vv6410_start(struct sd *sd); 179static int vv6410_start(struct sd *sd);
178static int vv6410_init(struct sd *sd); 180static int vv6410_init(struct sd *sd);
@@ -187,6 +189,8 @@ static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
187static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 189static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
188static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); 190static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val);
189static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); 191static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val);
192static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
193static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
190 194
191const struct stv06xx_sensor stv06xx_sensor_vv6410 = { 195const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
192 .name = "ST VV6410", 196 .name = "ST VV6410",