aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Lorin <o.lorin@laposte.net>2009-10-15 03:20:54 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:40:50 -0500
commitfdd1dd1d246e14dacd8fb0bf842828b03bed2481 (patch)
tree23c63e895e965d869300dde37c3269d8d8b4ed58
parentbe9904bdde05137085af1df98de98a49ddce9ad8 (diff)
V4L/DVB (13196): gspca - gl860: add flip/mirror for OV2640
- add flip/mirror support for OV2640 - fix for backlight value range - fix for red-blue inversion hue mode with V4L1 applications Signed-off-by: Olivier Lorin <o.lorin@laposte.net> Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov2640.c99
1 files changed, 41 insertions, 58 deletions
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c
index e0837432d394..768cac5cd72b 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov2640.c
+++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c
@@ -20,8 +20,12 @@
20#include "gl860.h" 20#include "gl860.h"
21 21
22static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01"; 22static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01";
23static u8 dat_init2[] = {0x61}; /* expected */ 23
24static u8 dat_init3[] = {0x51}; /* expected */ 24static u8 c61[] = {0x61}; /* expected */
25static u8 c51[] = {0x51}; /* expected */
26static u8 c50[] = {0x50}; /* expected */
27static u8 c28[] = {0x28}; /* expected */
28static u8 ca8[] = {0xa8}; /* expected */
25 29
26static u8 dat_post[] = 30static u8 dat_post[] =
27 "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01"; 31 "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01";
@@ -31,10 +35,6 @@ static u8 dat_800[] = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21";
31static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01"; 35static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01";
32static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41"; 36static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41";
33 37
34static u8 c50[] = {0x50}; /* expected */
35static u8 c28[] = {0x28}; /* expected */
36static u8 ca8[] = {0xa8}; /* expected */
37
38static struct validx tbl_init_at_startup[] = { 38static struct validx tbl_init_at_startup[] = {
39 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1}, 39 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
40 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d}, 40 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
@@ -107,36 +107,6 @@ static struct validx tbl_sensor_settings_common2[] = {
107 {0x6001, 0x00ff}, {0x6038, 0x000c}, 107 {0x6001, 0x00ff}, {0x6038, 0x000c},
108 {10, 0xffff}, 108 {10, 0xffff},
109 {0x6000, 0x0011}, 109 {0x6000, 0x0011},
110 /* backlight=31/64 */
111 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
112 /* bright=0/256 */
113 {0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d},
114 /* wbal=64/128 */
115 {0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d},
116 /* cntr=0/256 */
117 {0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d},
118 /* sat=128/256 */
119 {0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d},
120 /* sharpness=0/32 */
121 {0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093},
122 /* hue=0/256 */
123 {0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d},
124 /* gam=32/64 */
125 {0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d},
126 /* image right up */
127 {0xffff, 0xffff},
128 {15, 0xffff},
129 {0x6001, 0x00ff}, {0x6000, 0x8004},
130 {0xffff, 0xffff},
131 {0x60a8, 0x0004},
132 {15, 0xffff},
133 {0x6001, 0x00ff}, {0x6000, 0x8004},
134 {0xffff, 0xffff},
135 {0x60f8, 0x0004},
136 /* image right up */
137 {0xffff, 0xffff},
138 /* backlight=31/64 */
139 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
140}; 110};
141 111
142static struct validx tbl_640[] = { 112static struct validx tbl_640[] = {
@@ -222,17 +192,19 @@ void ov2640_init_settings(struct gspca_dev *gspca_dev)
222 sd->vcur.hue = 0; 192 sd->vcur.hue = 0;
223 sd->vcur.saturation = 128; 193 sd->vcur.saturation = 128;
224 sd->vcur.whitebal = 64; 194 sd->vcur.whitebal = 64;
195 sd->vcur.mirror = 0;
196 sd->vcur.flip = 0;
225 197
226 sd->vmax.backlight = 64; 198 sd->vmax.backlight = 64;
227 sd->vmax.brightness = 255; 199 sd->vmax.brightness = 255;
228 sd->vmax.sharpness = 31; 200 sd->vmax.sharpness = 31;
229 sd->vmax.contrast = 255; 201 sd->vmax.contrast = 255;
230 sd->vmax.gamma = 64; 202 sd->vmax.gamma = 64;
231 sd->vmax.hue = 255 + 1; 203 sd->vmax.hue = 254 + 2;
232 sd->vmax.saturation = 255; 204 sd->vmax.saturation = 255;
233 sd->vmax.whitebal = 128; 205 sd->vmax.whitebal = 128;
234 sd->vmax.mirror = 0; 206 sd->vmax.mirror = 1;
235 sd->vmax.flip = 0; 207 sd->vmax.flip = 1;
236 sd->vmax.AC50Hz = 0; 208 sd->vmax.AC50Hz = 0;
237 209
238 sd->dev_camera_settings = ov2640_camera_settings; 210 sd->dev_camera_settings = ov2640_camera_settings;
@@ -258,11 +230,11 @@ static int ov2640_init_at_startup(struct gspca_dev *gspca_dev)
258 230
259 common(gspca_dev); 231 common(gspca_dev);
260 232
261 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2); 233 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, c61);
262 234
263 ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL); 235 ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL);
264 236
265 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3); 237 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c51);
266 238
267 ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL); 239 ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL);
268/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ 240/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
@@ -284,6 +256,8 @@ static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
284 sd->vold.gamma = -1; 256 sd->vold.gamma = -1;
285 sd->vold.hue = -1; 257 sd->vold.hue = -1;
286 sd->vold.whitebal = -1; 258 sd->vold.whitebal = -1;
259 sd->vold.mirror = -1;
260 sd->vold.flip = -1;
287 261
288 ov2640_init_post_alt(gspca_dev); 262 ov2640_init_post_alt(gspca_dev);
289 263
@@ -346,18 +320,6 @@ static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
346 320
347 n = fetch_validx(gspca_dev, tbl_sensor_settings_common2, 321 n = fetch_validx(gspca_dev, tbl_sensor_settings_common2,
348 ARRAY_SIZE(tbl_sensor_settings_common2)); 322 ARRAY_SIZE(tbl_sensor_settings_common2));
349 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
350 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2,
351 ARRAY_SIZE(tbl_sensor_settings_common2), n);
352 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
353 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2,
354 ARRAY_SIZE(tbl_sensor_settings_common2), n);
355 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
356 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2,
357 ARRAY_SIZE(tbl_sensor_settings_common2), n);
358 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
359 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common2,
360 ARRAY_SIZE(tbl_sensor_settings_common2), n);
361 323
362 ov2640_camera_settings(gspca_dev); 324 ov2640_camera_settings(gspca_dev);
363 325
@@ -394,6 +356,8 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
394 s32 sat = sd->vcur.saturation; 356 s32 sat = sd->vcur.saturation;
395 s32 hue = sd->vcur.hue; 357 s32 hue = sd->vcur.hue;
396 s32 wbal = sd->vcur.whitebal; 358 s32 wbal = sd->vcur.whitebal;
359 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) == 0);
360 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) == 0);
397 361
398 if (backlight != sd->vold.backlight) { 362 if (backlight != sd->vold.backlight) {
399 /* No sd->vold.backlight=backlight; (to be done again later) */ 363 /* No sd->vold.backlight=backlight; (to be done again later) */
@@ -402,9 +366,9 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
402 366
403 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, 367 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
404 0, NULL); 368 0, NULL);
405 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, 369 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024,
406 0, NULL); 370 0, NULL);
407 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, 371 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
408 0, NULL); 372 0, NULL);
409 } 373 }
410 374
@@ -467,7 +431,7 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
467 ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL); 431 ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL);
468 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d, 432 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d,
469 0, NULL); 433 0, NULL);
470 if (hue >= sd->vmax.hue) 434 if (hue >= 255)
471 sd->swapRB = 1; 435 sd->swapRB = 1;
472 else 436 else
473 sd->swapRB = 0; 437 sd->swapRB = 0;
@@ -483,14 +447,33 @@ static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
483 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL); 447 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL);
484 } 448 }
485 449
450 if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
451 sd->vold.mirror = mirror;
452 sd->vold.flip = flip;
453
454 mirror = 0x80 * mirror;
455 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
456 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
457 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
458 ctrl_out(gspca_dev, 0x40, 1, 0x6028 + mirror, 0x0004, 0, NULL);
459
460 flip = 0x50 * flip + mirror;
461 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
462 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x8004, 0, NULL);
463 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
464 ctrl_out(gspca_dev, 0x40, 1, 0x6028 + flip, 0x0004, 0, NULL);
465
466 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
467 }
468
486 if (backlight != sd->vold.backlight) { 469 if (backlight != sd->vold.backlight) {
487 sd->vold.backlight = backlight; 470 sd->vold.backlight = backlight;
488 471
489 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff, 472 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
490 0, NULL); 473 0, NULL);
491 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024, 474 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight , 0x0024,
492 0, NULL); 475 0, NULL);
493 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025, 476 ctrl_out(gspca_dev, 0x40, 1, 0x601e + backlight - 10, 0x0025,
494 0, NULL); 477 0, NULL);
495 } 478 }
496 479