aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.c109
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);
32static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); 32static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
33static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); 33static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
34static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); 34static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
35static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
36static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
37static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
38static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
35 39
36const static struct ctrl ov7660_ctrls[] = { 40const 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
126static struct v4l2_pix_format ov7660_modes[] = { 159static 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
487static 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
497static 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
516static 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
527static 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
444static void ov7660_dump_registers(struct sd *sd) 549static void ov7660_dump_registers(struct sd *sd)
445{ 550{
446 int address; 551 int address;