aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/m5602
diff options
context:
space:
mode:
authorErik Andr?n <erik.andren@gmail.com>2009-01-13 01:57:57 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 17:20:31 -0400
commit9ae165779720209d4c566c8102dce415a3c7f055 (patch)
tree5973dc9ebb8aef8fbe81c3b340a052120455bc7d /drivers/media/video/gspca/m5602
parente8a574052e3f05a86d7363065f6734626e34f389 (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.c57
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);
37static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); 37static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
38static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); 38static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
39static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
40static 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
207static struct v4l2_pix_format ov9650_modes[] = { 224static 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
724static 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
734static 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
702static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, 754static 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
763static void ov9650_dump_registers(struct sd *sd) 814static void ov9650_dump_registers(struct sd *sd)