diff options
author | Erik Andr?n <erik.andren@gmail.com> | 2009-01-13 01:57:57 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 17:20:31 -0400 |
commit | 9ae165779720209d4c566c8102dce415a3c7f055 (patch) | |
tree | 5973dc9ebb8aef8fbe81c3b340a052120455bc7d /drivers/media/video/gspca/m5602 | |
parent | e8a574052e3f05a86d7363065f6734626e34f389 (diff) |
V4L/DVB (11521): gspca - m5602-ov9650: Add auto exposure ctrl
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/m5602')
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov9650.c | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c index 8d830afcedb..89fb01c9bc8 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov9650.c +++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c | |||
@@ -36,6 +36,8 @@ static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, | |||
36 | __s32 val); | 36 | __s32 val); |
37 | static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); | 37 | static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); |
38 | static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); | 38 | static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); |
39 | static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); | ||
40 | static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); | ||
39 | 41 | ||
40 | /* Vertically and horizontally flips the image if matched, needed for machines | 42 | /* Vertically and horizontally flips the image if matched, needed for machines |
41 | where the sensor is mounted upside down */ | 43 | where the sensor is mounted upside down */ |
@@ -201,7 +203,22 @@ const static struct ctrl ov9650_ctrls[] = { | |||
201 | }, | 203 | }, |
202 | .set = ov9650_set_auto_gain, | 204 | .set = ov9650_set_auto_gain, |
203 | .get = ov9650_get_auto_gain | 205 | .get = ov9650_get_auto_gain |
206 | }, | ||
207 | #define AUTO_EXPOSURE_IDX 8 | ||
208 | { | ||
209 | { | ||
210 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
211 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
212 | .name = "auto exposure", | ||
213 | .minimum = 0, | ||
214 | .maximum = 1, | ||
215 | .step = 1, | ||
216 | .default_value = 1 | ||
217 | }, | ||
218 | .set = ov9650_set_auto_exposure, | ||
219 | .get = ov9650_get_auto_exposure | ||
204 | } | 220 | } |
221 | |||
205 | }; | 222 | }; |
206 | 223 | ||
207 | static struct v4l2_pix_format ov9650_modes[] = { | 224 | static struct v4l2_pix_format ov9650_modes[] = { |
@@ -356,13 +373,18 @@ int ov9650_init(struct sd *sd) | |||
356 | if (err < 0) | 373 | if (err < 0) |
357 | return err; | 374 | return err; |
358 | 375 | ||
376 | err = ov9650_set_auto_exposure(&sd->gspca_dev, | ||
377 | sensor_settings[AUTO_EXPOSURE_IDX]); | ||
378 | if (err < 0) | ||
379 | return err; | ||
380 | |||
359 | err = ov9650_set_auto_white_balance(&sd->gspca_dev, | 381 | err = ov9650_set_auto_white_balance(&sd->gspca_dev, |
360 | sensor_settings[AUTO_WHITE_BALANCE_IDX]); | 382 | sensor_settings[AUTO_WHITE_BALANCE_IDX]); |
361 | if (err < 0) | 383 | if (err < 0) |
362 | return err; | 384 | return err; |
363 | 385 | ||
364 | err = ov9650_set_auto_gain(&sd->gspca_dev, | 386 | err = ov9650_set_auto_gain(&sd->gspca_dev, |
365 | sensor_settings[AUTO_GAIN_CTRL_IDX]); | 387 | sensor_settings[AUTO_GAIN_CTRL_IDX]); |
366 | return err; | 388 | return err; |
367 | } | 389 | } |
368 | 390 | ||
@@ -699,6 +721,36 @@ static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | |||
699 | return err; | 721 | return err; |
700 | } | 722 | } |
701 | 723 | ||
724 | static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) | ||
725 | { | ||
726 | struct sd *sd = (struct sd *) gspca_dev; | ||
727 | s32 *sensor_settings = sd->sensor_priv; | ||
728 | |||
729 | *val = sensor_settings[AUTO_EXPOSURE_IDX]; | ||
730 | PDEBUG(D_V4L2, "Read auto exposure control %d", *val); | ||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, | ||
735 | __s32 val) | ||
736 | { | ||
737 | int err; | ||
738 | u8 i2c_data; | ||
739 | struct sd *sd = (struct sd *) gspca_dev; | ||
740 | s32 *sensor_settings = sd->sensor_priv; | ||
741 | |||
742 | PDEBUG(D_V4L2, "Set auto exposure control to %d", val); | ||
743 | |||
744 | sensor_settings[AUTO_EXPOSURE_IDX] = val; | ||
745 | err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); | ||
746 | if (err < 0) | ||
747 | return err; | ||
748 | |||
749 | i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); | ||
750 | |||
751 | return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); | ||
752 | } | ||
753 | |||
702 | static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, | 754 | static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, |
703 | __s32 *val) | 755 | __s32 *val) |
704 | { | 756 | { |
@@ -755,9 +807,8 @@ static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) | |||
755 | return err; | 807 | return err; |
756 | 808 | ||
757 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); | 809 | i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); |
758 | err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); | ||
759 | 810 | ||
760 | return err; | 811 | return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); |
761 | } | 812 | } |
762 | 813 | ||
763 | static void ov9650_dump_registers(struct sd *sd) | 814 | static void ov9650_dump_registers(struct sd *sd) |