diff options
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_ov7660.c | 109 |
1 files changed, 107 insertions, 2 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c index f7c050f2552a..9b5e10532796 100644 --- a/drivers/media/video/gspca/m5602/m5602_ov7660.c +++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c | |||
@@ -32,6 +32,10 @@ static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); | |||
32 | static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); | 32 | static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); |
33 | static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); | 33 | static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); |
34 | static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); | 34 | static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); |
35 | static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
36 | static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val); | ||
37 | static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); | ||
38 | static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val); | ||
35 | 39 | ||
36 | const static struct ctrl ov7660_ctrls[] = { | 40 | const static struct ctrl ov7660_ctrls[] = { |
37 | #define GAIN_IDX 1 | 41 | #define GAIN_IDX 1 |
@@ -120,7 +124,36 @@ const static struct ctrl ov7660_ctrls[] = { | |||
120 | }, | 124 | }, |
121 | .set = ov7660_set_auto_exposure, | 125 | .set = ov7660_set_auto_exposure, |
122 | .get = ov7660_get_auto_exposure | 126 | .get = ov7660_get_auto_exposure |
123 | } | 127 | }, |
128 | #define HFLIP_IDX 7 | ||
129 | { | ||
130 | { | ||
131 | .id = V4L2_CID_HFLIP, | ||
132 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
133 | .name = "horizontal flip", | ||
134 | .minimum = 0, | ||
135 | .maximum = 1, | ||
136 | .step = 1, | ||
137 | .default_value = 0 | ||
138 | }, | ||
139 | .set = ov7660_set_hflip, | ||
140 | .get = ov7660_get_hflip | ||
141 | }, | ||
142 | #define VFLIP_IDX 8 | ||
143 | { | ||
144 | { | ||
145 | .id = V4L2_CID_VFLIP, | ||
146 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
147 | .name = "vertical flip", | ||
148 | .minimum = 0, | ||
149 | .maximum = 1, | ||
150 | .step = 1, | ||
151 | .default_value = 0 | ||
152 | }, | ||
153 | .set = ov7660_set_vflip, | ||
154 | .get = ov7660_get_vflip | ||
155 | }, | ||
156 | |||
124 | }; | 157 | }; |
125 | 158 | ||
126 | static struct v4l2_pix_format ov7660_modes[] = { | 159 | static struct v4l2_pix_format ov7660_modes[] = { |
@@ -221,7 +254,7 @@ int ov7660_init(struct sd *sd) | |||
221 | } else { | 254 | } else { |
222 | data[0] = init2_ov7660[i][2]; | 255 | data[0] = init2_ov7660[i][2]; |
223 | err = m5602_write_sensor(sd, | 256 | err = m5602_write_sensor(sd, |
224 | init2_ov7660[i][1], data, 1); | 257 | init2_ov7660[i][1], data, 1); |
225 | } | 258 | } |
226 | } | 259 | } |
227 | 260 | ||
@@ -254,6 +287,16 @@ int ov7660_init(struct sd *sd) | |||
254 | 287 | ||
255 | err = ov7660_set_red_gain(&sd->gspca_dev, | 288 | err = ov7660_set_red_gain(&sd->gspca_dev, |
256 | sensor_settings[RED_BALANCE_IDX]); | 289 | sensor_settings[RED_BALANCE_IDX]); |
290 | if (err < 0) | ||
291 | return err; | ||
292 | |||
293 | err = ov7660_set_hflip(&sd->gspca_dev, | ||
294 | sensor_settings[HFLIP_IDX]); | ||
295 | if (err < 0) | ||
296 | return err; | ||
297 | |||
298 | err = ov7660_set_vflip(&sd->gspca_dev, | ||
299 | sensor_settings[VFLIP_IDX]); | ||
257 | 300 | ||
258 | return err; | 301 | return err; |
259 | } | 302 | } |
@@ -441,6 +484,68 @@ static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, | |||
441 | return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); | 484 | return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); |
442 | } | 485 | } |
443 | 486 | ||
487 | static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
488 | { | ||
489 | struct sd *sd = (struct sd *) gspca_dev; | ||
490 | s32 *sensor_settings = sd->sensor_priv; | ||
491 | |||
492 | *val = sensor_settings[HFLIP_IDX]; | ||
493 | PDEBUG(D_V4L2, "Read horizontal flip %d", *val); | ||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val) | ||
498 | { | ||
499 | int err; | ||
500 | u8 i2c_data; | ||
501 | struct sd *sd = (struct sd *) gspca_dev; | ||
502 | s32 *sensor_settings = sd->sensor_priv; | ||
503 | |||
504 | PDEBUG(D_V4L2, "Set horizontal flip to %d", val); | ||
505 | |||
506 | sensor_settings[HFLIP_IDX] = val; | ||
507 | |||
508 | i2c_data = ((val & 0x01) << 5) | | ||
509 | (sensor_settings[VFLIP_IDX] << 4); | ||
510 | |||
511 | err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1); | ||
512 | |||
513 | return err; | ||
514 | } | ||
515 | |||
516 | static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) | ||
517 | { | ||
518 | struct sd *sd = (struct sd *) gspca_dev; | ||
519 | s32 *sensor_settings = sd->sensor_priv; | ||
520 | |||
521 | *val = sensor_settings[VFLIP_IDX]; | ||
522 | PDEBUG(D_V4L2, "Read vertical flip %d", *val); | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val) | ||
528 | { | ||
529 | int err; | ||
530 | u8 i2c_data; | ||
531 | struct sd *sd = (struct sd *) gspca_dev; | ||
532 | s32 *sensor_settings = sd->sensor_priv; | ||
533 | |||
534 | PDEBUG(D_V4L2, "Set vertical flip to %d", val); | ||
535 | sensor_settings[VFLIP_IDX] = val; | ||
536 | |||
537 | i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); | ||
538 | err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1); | ||
539 | if (err < 0) | ||
540 | return err; | ||
541 | |||
542 | /* When vflip is toggled we need to readjust the bridge hsync/vsync */ | ||
543 | if (gspca_dev->streaming) | ||
544 | err = ov7660_start(sd); | ||
545 | |||
546 | return err; | ||
547 | } | ||
548 | |||
444 | static void ov7660_dump_registers(struct sd *sd) | 549 | static void ov7660_dump_registers(struct sd *sd) |
445 | { | 550 | { |
446 | int address; | 551 | int address; |