diff options
author | Erik Andrén <erik.andren@gmail.com> | 2009-05-03 14:45:48 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 17:20:53 -0400 |
commit | 1906d8d17e556510603a9281b4fa960f2d73cc37 (patch) | |
tree | 4621b48b80fddbfc08919e7a6a774a45d3d7082b /drivers/media/video/gspca/stv06xx | |
parent | 1b844b536794163eb676b71e6e4c033f6d4b6b33 (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.c | 69 | ||||
-rw-r--r-- | drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h | 4 |
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 | ||
90 | static int vv6410_probe(struct sd *sd) | 104 | static int vv6410_probe(struct sd *sd) |
91 | { | 105 | { |
@@ -121,6 +135,7 @@ static int vv6410_probe(struct sd *sd) | |||
121 | static int vv6410_init(struct sd *sd) | 135 | static 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 | |||
342 | static 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 | |||
354 | static 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 | |||
385 | out: | ||
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 | |||
176 | static int vv6410_probe(struct sd *sd); | 178 | static int vv6410_probe(struct sd *sd); |
177 | static int vv6410_start(struct sd *sd); | 179 | static int vv6410_start(struct sd *sd); |
178 | static int vv6410_init(struct sd *sd); | 180 | static int vv6410_init(struct sd *sd); |
@@ -187,6 +189,8 @@ static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | |||
187 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | 189 | static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val); |
188 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); | 190 | static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val); |
189 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); | 191 | static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val); |
192 | static int vv6410_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
193 | static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
190 | 194 | ||
191 | const struct stv06xx_sensor stv06xx_sensor_vv6410 = { | 195 | const struct stv06xx_sensor stv06xx_sensor_vv6410 = { |
192 | .name = "ST VV6410", | 196 | .name = "ST VV6410", |