aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2010-01-07 03:18:16 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:10:35 -0500
commitc52af79916028f9d15638519b54a80ed1c10bce5 (patch)
treef4e49161d702ca4bbf2fdc1e465ea79125685739
parentde2d1549c2083e45ed84c779b64acf438ba5bf7f (diff)
V4L/DVB (13916): gspca - ov534/ov534_9: Split the ov534 subdriver.
The two sensors ov772x and ov965x have too much differences. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--Documentation/video4linux/gspca.txt3
-rw-r--r--drivers/media/video/gspca/Kconfig16
-rw-r--r--drivers/media/video/gspca/Makefile2
-rw-r--r--drivers/media/video/gspca/ov534.c1242
-rw-r--r--drivers/media/video/gspca/ov534_9.c1477
5 files changed, 1597 insertions, 1143 deletions
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 7b603439509d..c6364faa15af 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -190,8 +190,7 @@ spca500 06bd:0404 Agfa CL20
190spca500 06be:0800 Optimedia 190spca500 06be:0800 Optimedia
191sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom 191sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom
192spca506 06e1:a190 ADS Instant VCD 192spca506 06e1:a190 ADS Instant VCD
193ov534 06f8:3002 Hercules Blog Webcam 193ov534_9 06f8:3003 Hercules Dualpix HD Weblog
194ov534 06f8:3003 Hercules Dualpix HD Weblog
195sonixj 06f8:3004 Hercules Classic Silver 194sonixj 06f8:3004 Hercules Classic Silver
196sonixj 06f8:3008 Hercules Deluxe Optical Glass 195sonixj 06f8:3008 Hercules Deluxe Optical Glass
197pac7302 06f8:3009 Hercules Classic Link 196pac7302 06f8:3009 Hercules Classic Link
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 824e95a3d889..561bab0874ce 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -95,15 +95,25 @@ config USB_GSPCA_OV519
95 module will be called gspca_ov519. 95 module will be called gspca_ov519.
96 96
97config USB_GSPCA_OV534 97config USB_GSPCA_OV534
98 tristate "OV534 USB Camera Driver" 98 tristate "OV534 OV772x USB Camera Driver"
99 depends on VIDEO_V4L2 && USB_GSPCA 99 depends on VIDEO_V4L2 && USB_GSPCA
100 help 100 help
101 Say Y here if you want support for cameras based on the OV534 chip. 101 Say Y here if you want support for cameras based on the OV534 chip
102 (e.g. Sony Playstation EYE) 102 and sensor OV772x (e.g. Sony Playstation EYE)
103 103
104 To compile this driver as a module, choose M here: the 104 To compile this driver as a module, choose M here: the
105 module will be called gspca_ov534. 105 module will be called gspca_ov534.
106 106
107config USB_GSPCA_OV534_9
108 tristate "OV534 OV965x USB Camera Driver"
109 depends on VIDEO_V4L2 && USB_GSPCA
110 help
111 Say Y here if you want support for cameras based on the OV534 chip
112 and sensor OV965x (e.g. Hercules Dualpix)
113
114 To compile this driver as a module, choose M here: the
115 module will be called gspca_ov534_9.
116
107config USB_GSPCA_PAC207 117config USB_GSPCA_PAC207
108 tristate "Pixart PAC207 USB Camera Driver" 118 tristate "Pixart PAC207 USB Camera Driver"
109 depends on VIDEO_V4L2 && USB_GSPCA 119 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 82da9c3d204a..553753d5c5ea 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
8obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o 8obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
9obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 9obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
10obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o 10obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
11obj-$(CONFIG_USB_GSPCA_OV534_9) += gspca_ov534_9.o
11obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o 12obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
12obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o 13obj-$(CONFIG_USB_GSPCA_PAC7302) += gspca_pac7302.o
13obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o 14obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
@@ -40,6 +41,7 @@ gspca_mars-objs := mars.o
40gspca_mr97310a-objs := mr97310a.o 41gspca_mr97310a-objs := mr97310a.o
41gspca_ov519-objs := ov519.o 42gspca_ov519-objs := ov519.o
42gspca_ov534-objs := ov534.o 43gspca_ov534-objs := ov534.o
44gspca_ov534_9-objs := ov534_9.o
43gspca_pac207-objs := pac207.o 45gspca_pac207-objs := pac207.o
44gspca_pac7302-objs := pac7302.o 46gspca_pac7302-objs := pac7302.o
45gspca_pac7311-objs := pac7311.o 47gspca_pac7311-objs := pac7311.o
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index da55637d07e8..0878c09e2485 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ov534 gspca driver 2 * ov534-ov772x gspca driver
3 * 3 *
4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
5 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
@@ -68,12 +68,7 @@ struct sd {
68 s8 sharpness; 68 s8 sharpness;
69 u8 hflip; 69 u8 hflip;
70 u8 vflip; 70 u8 vflip;
71 u8 satur;
72 u8 lightfreq;
73 71
74 u8 sensor;
75#define SENSOR_OV772X 0
76#define SENSOR_OV965X 1
77}; 72};
78 73
79/* V4L2 controls supported by the driver */ 74/* V4L2 controls supported by the driver */
@@ -101,12 +96,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 96static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
102static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 97static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
103static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 98static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
104static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
105static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
106static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
107static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
108 99
109static const struct ctrl sd_ctrls_ov772x[] = { 100static const struct ctrl sd_ctrls[] = {
110 { /* 0 */ 101 { /* 0 */
111 { 102 {
112 .id = V4L2_CID_BRIGHTNESS, 103 .id = V4L2_CID_BRIGHTNESS,
@@ -115,8 +106,8 @@ static const struct ctrl sd_ctrls_ov772x[] = {
115 .minimum = 0, 106 .minimum = 0,
116 .maximum = 255, 107 .maximum = 255,
117 .step = 1, 108 .step = 1,
118#define BRIGHTNESS_77_DEF 20 109#define BRIGHTNESS_DEF 20
119 .default_value = BRIGHTNESS_77_DEF, 110 .default_value = BRIGHTNESS_DEF,
120 }, 111 },
121 .set = sd_setbrightness, 112 .set = sd_setbrightness,
122 .get = sd_getbrightness, 113 .get = sd_getbrightness,
@@ -129,8 +120,8 @@ static const struct ctrl sd_ctrls_ov772x[] = {
129 .minimum = 0, 120 .minimum = 0,
130 .maximum = 255, 121 .maximum = 255,
131 .step = 1, 122 .step = 1,
132#define CONTRAST_77_DEF 37 123#define CONTRAST_DEF 37
133 .default_value = CONTRAST_77_DEF, 124 .default_value = CONTRAST_DEF,
134 }, 125 },
135 .set = sd_setcontrast, 126 .set = sd_setcontrast,
136 .get = sd_getcontrast, 127 .get = sd_getcontrast,
@@ -157,8 +148,8 @@ static const struct ctrl sd_ctrls_ov772x[] = {
157 .minimum = 0, 148 .minimum = 0,
158 .maximum = 255, 149 .maximum = 255,
159 .step = 1, 150 .step = 1,
160#define EXPO_77_DEF 120 151#define EXPO_DEF 120
161 .default_value = EXPO_77_DEF, 152 .default_value = EXPO_DEF,
162 }, 153 },
163 .set = sd_setexposure, 154 .set = sd_setexposure,
164 .get = sd_getexposure, 155 .get = sd_getexposure,
@@ -213,13 +204,13 @@ static const struct ctrl sd_ctrls_ov772x[] = {
213 .minimum = 0, 204 .minimum = 0,
214 .maximum = 1, 205 .maximum = 1,
215 .step = 1, 206 .step = 1,
216#define AUTOGAIN_77_DEF 0 207#define AUTOGAIN_DEF 0
217 .default_value = AUTOGAIN_77_DEF, 208 .default_value = AUTOGAIN_DEF,
218 }, 209 },
219 .set = sd_setautogain, 210 .set = sd_setautogain,
220 .get = sd_getautogain, 211 .get = sd_getautogain,
221 }, 212 },
222#define AWB_77_IDX 8 213#define AWB_IDX 8
223 { /* 8 */ 214 { /* 8 */
224 { 215 {
225 .id = V4L2_CID_AUTO_WHITE_BALANCE, 216 .id = V4L2_CID_AUTO_WHITE_BALANCE,
@@ -242,8 +233,8 @@ static const struct ctrl sd_ctrls_ov772x[] = {
242 .minimum = 0, 233 .minimum = 0,
243 .maximum = 63, 234 .maximum = 63,
244 .step = 1, 235 .step = 1,
245#define SHARPNESS_77_DEF 0 236#define SHARPNESS_DEF 0
246 .default_value = SHARPNESS_77_DEF, 237 .default_value = SHARPNESS_DEF,
247 }, 238 },
248 .set = sd_setsharpness, 239 .set = sd_setsharpness,
249 .get = sd_getsharpness, 240 .get = sd_getsharpness,
@@ -277,107 +268,6 @@ static const struct ctrl sd_ctrls_ov772x[] = {
277 .get = sd_getvflip, 268 .get = sd_getvflip,
278 }, 269 },
279}; 270};
280static const struct ctrl sd_ctrls_ov965x[] = {
281 { /* 0 */
282 {
283 .id = V4L2_CID_BRIGHTNESS,
284 .type = V4L2_CTRL_TYPE_INTEGER,
285 .name = "Brightness",
286 .minimum = 0,
287 .maximum = 15,
288 .step = 1,
289#define BRIGHTNESS_96_DEF 7
290 .default_value = BRIGHTNESS_96_DEF,
291 },
292 .set = sd_setbrightness,
293 .get = sd_getbrightness,
294 },
295 { /* 1 */
296 {
297 .id = V4L2_CID_CONTRAST,
298 .type = V4L2_CTRL_TYPE_INTEGER,
299 .name = "Contrast",
300 .minimum = 0,
301 .maximum = 15,
302 .step = 1,
303#define CONTRAST_96_DEF 3
304 .default_value = CONTRAST_96_DEF,
305 },
306 .set = sd_setcontrast,
307 .get = sd_getcontrast,
308 },
309 { /* 2 */
310 {
311 .id = V4L2_CID_AUTOGAIN,
312 .type = V4L2_CTRL_TYPE_BOOLEAN,
313 .name = "Autogain",
314 .minimum = 0,
315 .maximum = 1,
316 .step = 1,
317#define AUTOGAIN_96_DEF 1
318 .default_value = AUTOGAIN_96_DEF,
319 },
320 .set = sd_setautogain,
321 .get = sd_getautogain,
322 },
323#define EXPO_96_IDX 3
324 { /* 3 */
325 {
326 .id = V4L2_CID_EXPOSURE,
327 .type = V4L2_CTRL_TYPE_INTEGER,
328 .name = "Exposure",
329 .minimum = 0,
330 .maximum = 3,
331 .step = 1,
332#define EXPO_96_DEF 0
333 .default_value = EXPO_96_DEF,
334 },
335 .set = sd_setexposure,
336 .get = sd_getexposure,
337 },
338 { /* 4 */
339 {
340 .id = V4L2_CID_SHARPNESS,
341 .type = V4L2_CTRL_TYPE_INTEGER,
342 .name = "Sharpness",
343 .minimum = -1, /* -1 = auto */
344 .maximum = 4,
345 .step = 1,
346#define SHARPNESS_96_DEF -1
347 .default_value = SHARPNESS_96_DEF,
348 },
349 .set = sd_setsharpness,
350 .get = sd_getsharpness,
351 },
352 { /* 5 */
353 {
354 .id = V4L2_CID_SATURATION,
355 .type = V4L2_CTRL_TYPE_INTEGER,
356 .name = "Saturation",
357 .minimum = 0,
358 .maximum = 4,
359 .step = 1,
360#define SATUR_DEF 2
361 .default_value = SATUR_DEF,
362 },
363 .set = sd_setsatur,
364 .get = sd_getsatur,
365 },
366 {
367 {
368 .id = V4L2_CID_POWER_LINE_FREQUENCY,
369 .type = V4L2_CTRL_TYPE_MENU,
370 .name = "Light frequency filter",
371 .minimum = 0,
372 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
373 .step = 1,
374#define FREQ_DEF 0
375 .default_value = FREQ_DEF,
376 },
377 .set = sd_setfreq,
378 .get = sd_getfreq,
379 },
380};
381 271
382static const struct v4l2_pix_format ov772x_mode[] = { 272static const struct v4l2_pix_format ov772x_mode[] = {
383 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 273 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
@@ -392,35 +282,7 @@ static const struct v4l2_pix_format ov772x_mode[] = {
392 .priv = 0}, 282 .priv = 0},
393}; 283};
394 284
395static const struct v4l2_pix_format ov965x_mode[] = { 285static const u8 bridge_init[][2] = {
396 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
397 .bytesperline = 320,
398 .sizeimage = 320 * 240 * 3 / 8 + 590,
399 .colorspace = V4L2_COLORSPACE_JPEG,
400 .priv = 4},
401 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
402 .bytesperline = 640,
403 .sizeimage = 640 * 480 * 3 / 8 + 590,
404 .colorspace = V4L2_COLORSPACE_JPEG,
405 .priv = 3},
406 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
407 .bytesperline = 800,
408 .sizeimage = 800 * 600 * 3 / 8 + 590,
409 .colorspace = V4L2_COLORSPACE_JPEG,
410 .priv = 2},
411 {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
412 .bytesperline = 1024,
413 .sizeimage = 1024 * 768 * 3 / 8 + 590,
414 .colorspace = V4L2_COLORSPACE_JPEG,
415 .priv = 1},
416 {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
417 .bytesperline = 1280,
418 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
419 .colorspace = V4L2_COLORSPACE_JPEG,
420 .priv = 0},
421};
422
423static const u8 bridge_init_ov772x[][2] = {
424 { 0xc2, 0x0c }, 286 { 0xc2, 0x0c },
425 { 0x88, 0xf8 }, 287 { 0x88, 0xf8 },
426 { 0xc3, 0x69 }, 288 { 0xc3, 0x69 },
@@ -478,7 +340,7 @@ static const u8 bridge_init_ov772x[][2] = {
478 { 0xc1, 0x3c }, 340 { 0xc1, 0x3c },
479 { 0xc2, 0x0c }, 341 { 0xc2, 0x0c },
480}; 342};
481static const u8 sensor_init_ov772x[][2] = { 343static const u8 sensor_init[][2] = {
482 { 0x12, 0x80 }, 344 { 0x12, 0x80 },
483 { 0x11, 0x01 }, 345 { 0x11, 0x01 },
484/*fixme: better have a delay?*/ 346/*fixme: better have a delay?*/
@@ -571,7 +433,7 @@ static const u8 sensor_init_ov772x[][2] = {
571 { 0x8e, 0x00 }, /* De-noise threshold */ 433 { 0x8e, 0x00 }, /* De-noise threshold */
572 { 0x0c, 0xd0 } 434 { 0x0c, 0xd0 }
573}; 435};
574static const u8 bridge_start_ov772x_vga[][2] = { 436static const u8 bridge_start_vga[][2] = {
575 {0x1c, 0x00}, 437 {0x1c, 0x00},
576 {0x1d, 0x40}, 438 {0x1d, 0x40},
577 {0x1d, 0x02}, 439 {0x1d, 0x02},
@@ -582,7 +444,7 @@ static const u8 bridge_start_ov772x_vga[][2] = {
582 {0xc0, 0x50}, 444 {0xc0, 0x50},
583 {0xc1, 0x3c}, 445 {0xc1, 0x3c},
584}; 446};
585static const u8 sensor_start_ov772x_vga[][2] = { 447static const u8 sensor_start_vga[][2] = {
586 {0x12, 0x00}, 448 {0x12, 0x00},
587 {0x17, 0x26}, 449 {0x17, 0x26},
588 {0x18, 0xa0}, 450 {0x18, 0xa0},
@@ -592,7 +454,7 @@ static const u8 sensor_start_ov772x_vga[][2] = {
592 {0x2c, 0xf0}, 454 {0x2c, 0xf0},
593 {0x65, 0x20}, 455 {0x65, 0x20},
594}; 456};
595static const u8 bridge_start_ov772x_qvga[][2] = { 457static const u8 bridge_start_qvga[][2] = {
596 {0x1c, 0x00}, 458 {0x1c, 0x00},
597 {0x1d, 0x40}, 459 {0x1d, 0x40},
598 {0x1d, 0x02}, 460 {0x1d, 0x02},
@@ -603,7 +465,7 @@ static const u8 bridge_start_ov772x_qvga[][2] = {
603 {0xc0, 0x28}, 465 {0xc0, 0x28},
604 {0xc1, 0x1e}, 466 {0xc1, 0x1e},
605}; 467};
606static const u8 sensor_start_ov772x_qvga[][2] = { 468static const u8 sensor_start_qvga[][2] = {
607 {0x12, 0x40}, 469 {0x12, 0x40},
608 {0x17, 0x3f}, 470 {0x17, 0x3f},
609 {0x18, 0x50}, 471 {0x18, 0x50},
@@ -614,571 +476,6 @@ static const u8 sensor_start_ov772x_qvga[][2] = {
614 {0x65, 0x2f}, 476 {0x65, 0x2f},
615}; 477};
616 478
617static const u8 bridge_init_ov965x[][2] = {
618 {0x88, 0xf8},
619 {0x89, 0xff},
620 {0x76, 0x03},
621 {0x92, 0x03},
622 {0x95, 0x10},
623 {0xe2, 0x00},
624 {0xe7, 0x3e},
625 {0x8d, 0x1c},
626 {0x8e, 0x00},
627 {0x8f, 0x00},
628 {0x1f, 0x00},
629 {0xc3, 0xf9},
630 {0x89, 0xff},
631 {0x88, 0xf8},
632 {0x76, 0x03},
633 {0x92, 0x01},
634 {0x93, 0x18},
635 {0x1c, 0x0a},
636 {0x1d, 0x48},
637 {0xc0, 0x50},
638 {0xc1, 0x3c},
639 {0x34, 0x05},
640 {0xc2, 0x0c},
641 {0xc3, 0xf9},
642 {0x34, 0x05},
643 {0xe7, 0x2e},
644 {0x31, 0xf9},
645 {0x35, 0x02},
646 {0xd9, 0x10},
647 {0x25, 0x42},
648 {0x94, 0x11},
649};
650
651static const u8 sensor_init_ov965x[][2] = {
652 {0x12, 0x80}, /* com7 - SSCB reset */
653 {0x00, 0x00}, /* gain */
654 {0x01, 0x80}, /* blue */
655 {0x02, 0x80}, /* red */
656 {0x03, 0x1b}, /* vref */
657 {0x04, 0x03}, /* com1 - exposure low bits */
658 {0x0b, 0x57}, /* ver */
659 {0x0e, 0x61}, /* com5 */
660 {0x0f, 0x42}, /* com6 */
661 {0x11, 0x00}, /* clkrc */
662 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
663 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
664 {0x14, 0x28}, /* com9 */
665 {0x16, 0x24}, /* reg16 */
666 {0x17, 0x1d}, /* hstart*/
667 {0x18, 0xbd}, /* hstop */
668 {0x19, 0x01}, /* vstrt */
669 {0x1a, 0x81}, /* vstop*/
670 {0x1e, 0x04}, /* mvfp */
671 {0x24, 0x3c}, /* aew */
672 {0x25, 0x36}, /* aeb */
673 {0x26, 0x71}, /* vpt */
674 {0x27, 0x08}, /* bbias */
675 {0x28, 0x08}, /* gbbias */
676 {0x29, 0x15}, /* gr com */
677 {0x2a, 0x00}, /* exhch */
678 {0x2b, 0x00}, /* exhcl */
679 {0x2c, 0x08}, /* rbias */
680 {0x32, 0xff}, /* href */
681 {0x33, 0x00}, /* chlf */
682 {0x34, 0x3f}, /* aref1 */
683 {0x35, 0x00}, /* aref2 */
684 {0x36, 0xf8}, /* aref3 */
685 {0x38, 0x72}, /* adc2 */
686 {0x39, 0x57}, /* aref4 */
687 {0x3a, 0x80}, /* tslb - yuyv */
688 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
689 {0x3d, 0x99}, /* com13 */
690 {0x3f, 0xc1}, /* edge */
691 {0x40, 0xc0}, /* com15 */
692 {0x41, 0x40}, /* com16 */
693 {0x42, 0xc0}, /* com17 */
694 {0x43, 0x0a}, /* rsvd */
695 {0x44, 0xf0},
696 {0x45, 0x46},
697 {0x46, 0x62},
698 {0x47, 0x2a},
699 {0x48, 0x3c},
700 {0x4a, 0xfc},
701 {0x4b, 0xfc},
702 {0x4c, 0x7f},
703 {0x4d, 0x7f},
704 {0x4e, 0x7f},
705 {0x4f, 0x98}, /* matrix */
706 {0x50, 0x98},
707 {0x51, 0x00},
708 {0x52, 0x28},
709 {0x53, 0x70},
710 {0x54, 0x98},
711 {0x58, 0x1a}, /* matrix coef sign */
712 {0x59, 0x85}, /* AWB control */
713 {0x5a, 0xa9},
714 {0x5b, 0x64},
715 {0x5c, 0x84},
716 {0x5d, 0x53},
717 {0x5e, 0x0e},
718 {0x5f, 0xf0}, /* AWB blue limit */
719 {0x60, 0xf0}, /* AWB red limit */
720 {0x61, 0xf0}, /* AWB green limit */
721 {0x62, 0x00}, /* lcc1 */
722 {0x63, 0x00}, /* lcc2 */
723 {0x64, 0x02}, /* lcc3 */
724 {0x65, 0x16}, /* lcc4 */
725 {0x66, 0x01}, /* lcc5 */
726 {0x69, 0x02}, /* hv */
727 {0x6b, 0x5a}, /* dbvl */
728 {0x6c, 0x04},
729 {0x6d, 0x55},
730 {0x6e, 0x00},
731 {0x6f, 0x9d},
732 {0x70, 0x21}, /* dnsth */
733 {0x71, 0x78},
734 {0x72, 0x00}, /* poidx */
735 {0x73, 0x01}, /* pckdv */
736 {0x74, 0x3a}, /* xindx */
737 {0x75, 0x35}, /* yindx */
738 {0x76, 0x01},
739 {0x77, 0x02},
740 {0x7a, 0x12}, /* gamma curve */
741 {0x7b, 0x08},
742 {0x7c, 0x16},
743 {0x7d, 0x30},
744 {0x7e, 0x5e},
745 {0x7f, 0x72},
746 {0x80, 0x82},
747 {0x81, 0x8e},
748 {0x82, 0x9a},
749 {0x83, 0xa4},
750 {0x84, 0xac},
751 {0x85, 0xb8},
752 {0x86, 0xc3},
753 {0x87, 0xd6},
754 {0x88, 0xe6},
755 {0x89, 0xf2},
756 {0x8a, 0x03},
757 {0x8c, 0x89}, /* com19 */
758 {0x14, 0x28}, /* com9 */
759 {0x90, 0x7d},
760 {0x91, 0x7b},
761 {0x9d, 0x03}, /* lcc6 */
762 {0x9e, 0x04}, /* lcc7 */
763 {0x9f, 0x7a},
764 {0xa0, 0x79},
765 {0xa1, 0x40}, /* aechm */
766 {0xa4, 0x50}, /* com21 */
767 {0xa5, 0x68}, /* com26 */
768 {0xa6, 0x4a}, /* AWB green */
769 {0xa8, 0xc1}, /* refa8 */
770 {0xa9, 0xef}, /* refa9 */
771 {0xaa, 0x92},
772 {0xab, 0x04},
773 {0xac, 0x80}, /* black level control */
774 {0xad, 0x80},
775 {0xae, 0x80},
776 {0xaf, 0x80},
777 {0xb2, 0xf2},
778 {0xb3, 0x20},
779 {0xb4, 0x20}, /* ctrlb4 */
780 {0xb5, 0x00},
781 {0xb6, 0xaf},
782 {0xbb, 0xae},
783 {0xbc, 0x7f}, /* ADC channel offsets */
784 {0xdb, 0x7f},
785 {0xbe, 0x7f},
786 {0xbf, 0x7f},
787 {0xc0, 0xe2},
788 {0xc1, 0xc0},
789 {0xc2, 0x01},
790 {0xc3, 0x4e},
791 {0xc6, 0x85},
792 {0xc7, 0x80}, /* com24 */
793 {0xc9, 0xe0},
794 {0xca, 0xe8},
795 {0xcb, 0xf0},
796 {0xcc, 0xd8},
797 {0xcd, 0xf1},
798 {0x4f, 0x98}, /* matrix */
799 {0x50, 0x98},
800 {0x51, 0x00},
801 {0x52, 0x28},
802 {0x53, 0x70},
803 {0x54, 0x98},
804 {0x58, 0x1a},
805 {0xff, 0x41}, /* read 41, write ff 00 */
806 {0x41, 0x40}, /* com16 */
807
808 {0xc5, 0x03}, /* 60 Hz banding filter */
809 {0x6a, 0x02}, /* 50 Hz banding filter */
810
811 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
812 {0x36, 0xfa}, /* aref3 */
813 {0x69, 0x0a}, /* hv */
814 {0x8c, 0x89}, /* com22 */
815 {0x14, 0x28}, /* com9 */
816 {0x3e, 0x0c},
817 {0x41, 0x40}, /* com16 */
818 {0x72, 0x00},
819 {0x73, 0x00},
820 {0x74, 0x3a},
821 {0x75, 0x35},
822 {0x76, 0x01},
823 {0xc7, 0x80},
824 {0x03, 0x12}, /* vref */
825 {0x17, 0x16}, /* hstart */
826 {0x18, 0x02}, /* hstop */
827 {0x19, 0x01}, /* vstrt */
828 {0x1a, 0x3d}, /* vstop */
829 {0x32, 0xff}, /* href */
830 {0xc0, 0xaa},
831};
832
833static const u8 bridge_init_ov965x_2[][2] = {
834 {0x94, 0xaa},
835 {0xf1, 0x60},
836 {0xe5, 0x04},
837 {0xc0, 0x50},
838 {0xc1, 0x3c},
839 {0x8c, 0x00},
840 {0x8d, 0x1c},
841 {0x34, 0x05},
842
843 {0xc2, 0x0c},
844 {0xc3, 0xf9},
845 {0xda, 0x01},
846 {0x50, 0x00},
847 {0x51, 0xa0},
848 {0x52, 0x3c},
849 {0x53, 0x00},
850 {0x54, 0x00},
851 {0x55, 0x00},
852 {0x57, 0x00},
853 {0x5c, 0x00},
854 {0x5a, 0xa0},
855 {0x5b, 0x78},
856 {0x35, 0x02},
857 {0xd9, 0x10},
858 {0x94, 0x11},
859};
860
861static const u8 sensor_init_ov965x_2[][2] = {
862 {0x3b, 0xc4},
863 {0x1e, 0x04}, /* mvfp */
864 {0x13, 0xe0}, /* com8 */
865 {0x00, 0x00}, /* gain */
866 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
867 {0x11, 0x03}, /* clkrc */
868 {0x6b, 0x5a}, /* dblv */
869 {0x6a, 0x05},
870 {0xc5, 0x07},
871 {0xa2, 0x4b},
872 {0xa3, 0x3e},
873 {0x2d, 0x00},
874 {0xff, 0x42}, /* read 42, write ff 00 */
875 {0x42, 0xc0}, /* com17 */
876 {0x2d, 0x00},
877 {0xff, 0x42}, /* read 42, write ff 00 */
878 {0x42, 0xc1}, /* com17 */
879/* sharpness */
880 {0x3f, 0x01},
881 {0xff, 0x42}, /* read 42, write ff 00 */
882 {0x42, 0xc1}, /* com17 */
883/* saturation */
884 {0x4f, 0x98}, /* matrix */
885 {0x50, 0x98},
886 {0x51, 0x00},
887 {0x52, 0x28},
888 {0x53, 0x70},
889 {0x54, 0x98},
890 {0x58, 0x1a},
891 {0xff, 0x41}, /* read 41, write ff 00 */
892 {0x41, 0x40}, /* com16 */
893/* contrast */
894 {0x56, 0x40},
895/* brightness */
896 {0x55, 0x8f},
897/* expo */
898 {0x10, 0x25}, /* aech - exposure high bits */
899 {0xff, 0x13}, /* read 13, write ff 00 */
900 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
901};
902
903static const u8 sensor_start_ov965x_1_vga[][2] = { /* same for qvga */
904 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
905 {0x36, 0xfa}, /* aref3 */
906 {0x69, 0x0a}, /* hv */
907 {0x8c, 0x89}, /* com22 */
908 {0x14, 0x28}, /* com9 */
909 {0x3e, 0x0c}, /* com14 */
910 {0x41, 0x40}, /* com16 */
911 {0x72, 0x00},
912 {0x73, 0x00},
913 {0x74, 0x3a},
914 {0x75, 0x35},
915 {0x76, 0x01},
916 {0xc7, 0x80}, /* com24 */
917 {0x03, 0x12}, /* vref */
918 {0x17, 0x16}, /* hstart */
919 {0x18, 0x02}, /* hstop */
920 {0x19, 0x01}, /* vstrt */
921 {0x1a, 0x3d}, /* vstop */
922 {0x32, 0xff}, /* href */
923 {0xc0, 0xaa},
924};
925
926static const u8 sensor_start_ov965x_1_svga[][2] = {
927 {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
928 {0x36, 0xf8}, /* aref3 */
929 {0x69, 0x02}, /* hv */
930 {0x8c, 0x0d}, /* com22 */
931 {0x3e, 0x0c}, /* com14 */
932 {0x41, 0x40}, /* com16 */
933 {0x72, 0x00},
934 {0x73, 0x01},
935 {0x74, 0x3a},
936 {0x75, 0x35},
937 {0x76, 0x01},
938 {0xc7, 0x80}, /* com24 */
939 {0x03, 0x1b}, /* vref */
940 {0x17, 0x1d}, /* hstart */
941 {0x18, 0xbd}, /* hstop */
942 {0x19, 0x01}, /* vstrt */
943 {0x1a, 0x81}, /* vstop */
944 {0x32, 0xff}, /* href */
945 {0xc0, 0xe2},
946};
947
948static const u8 sensor_start_ov965x_1_xga[][2] = {
949 {0x12, 0x02}, /* com7 */
950 {0x36, 0xf8}, /* aref3 */
951 {0x69, 0x02}, /* hv */
952 {0x8c, 0x89}, /* com22 */
953 {0x14, 0x28}, /* com9 */
954 {0x3e, 0x0c}, /* com14 */
955 {0x41, 0x40}, /* com16 */
956 {0x72, 0x00},
957 {0x73, 0x01},
958 {0x74, 0x3a},
959 {0x75, 0x35},
960 {0x76, 0x01},
961 {0xc7, 0x80}, /* com24 */
962 {0x03, 0x1b}, /* vref */
963 {0x17, 0x1d}, /* hstart */
964 {0x18, 0xbd}, /* hstop */
965 {0x19, 0x01}, /* vstrt */
966 {0x1a, 0x81}, /* vstop */
967 {0x32, 0xff}, /* href */
968 {0xc0, 0xe2},
969};
970
971static const u8 sensor_start_ov965x_1_sxga[][2] = {
972 {0x12, 0x02}, /* com7 */
973 {0x36, 0xf8}, /* aref3 */
974 {0x69, 0x02}, /* hv */
975 {0x8c, 0x89}, /* com22 */
976 {0x14, 0x28}, /* com9 */
977 {0x3e, 0x0c}, /* com14 */
978 {0x41, 0x40}, /* com16 */
979 {0x72, 0x00},
980 {0x73, 0x01},
981 {0x74, 0x3a},
982 {0x75, 0x35},
983 {0x76, 0x01},
984 {0xc7, 0x80}, /* com24 */
985 {0x03, 0x1b}, /* vref */
986 {0x17, 0x1d}, /* hstart */
987 {0x18, 0x02}, /* hstop */
988 {0x19, 0x01}, /* vstrt */
989 {0x1a, 0x81}, /* vstop */
990 {0x32, 0xff}, /* href */
991 {0xc0, 0xe2},
992};
993
994static const u8 bridge_start_ov965x_qvga[][2] = {
995 {0x94, 0xaa},
996 {0xf1, 0x60},
997 {0xe5, 0x04},
998 {0xc0, 0x50},
999 {0xc1, 0x3c},
1000 {0x8c, 0x00},
1001 {0x8d, 0x1c},
1002 {0x34, 0x05},
1003
1004 {0xc2, 0x4c},
1005 {0xc3, 0xf9},
1006 {0xda, 0x00},
1007 {0x50, 0x00},
1008 {0x51, 0xa0},
1009 {0x52, 0x78},
1010 {0x53, 0x00},
1011 {0x54, 0x00},
1012 {0x55, 0x00},
1013 {0x57, 0x00},
1014 {0x5c, 0x00},
1015 {0x5a, 0x50},
1016 {0x5b, 0x3c},
1017 {0x35, 0x02},
1018 {0xd9, 0x10},
1019 {0x94, 0x11},
1020};
1021
1022static const u8 bridge_start_ov965x_vga[][2] = {
1023 {0x94, 0xaa},
1024 {0xf1, 0x60},
1025 {0xe5, 0x04},
1026 {0xc0, 0x50},
1027 {0xc1, 0x3c},
1028 {0x8c, 0x00},
1029 {0x8d, 0x1c},
1030 {0x34, 0x05},
1031 {0xc2, 0x0c},
1032 {0xc3, 0xf9},
1033 {0xda, 0x01},
1034 {0x50, 0x00},
1035 {0x51, 0xa0},
1036 {0x52, 0x3c},
1037 {0x53, 0x00},
1038 {0x54, 0x00},
1039 {0x55, 0x00},
1040 {0x57, 0x00},
1041 {0x5c, 0x00},
1042 {0x5a, 0xa0},
1043 {0x5b, 0x78},
1044 {0x35, 0x02},
1045 {0xd9, 0x10},
1046 {0x94, 0x11},
1047};
1048
1049static const u8 bridge_start_ov965x_svga[][2] = {
1050 {0x94, 0xaa},
1051 {0xf1, 0x60},
1052 {0xe5, 0x04},
1053 {0xc0, 0xa0},
1054 {0xc1, 0x80},
1055 {0x8c, 0x00},
1056 {0x8d, 0x1c},
1057 {0x34, 0x05},
1058 {0xc2, 0x4c},
1059 {0xc3, 0xf9},
1060 {0x50, 0x00},
1061 {0x51, 0x40},
1062 {0x52, 0x00},
1063 {0x53, 0x00},
1064 {0x54, 0x00},
1065 {0x55, 0x88},
1066 {0x57, 0x00},
1067 {0x5c, 0x00},
1068 {0x5a, 0xc8},
1069 {0x5b, 0x96},
1070 {0x35, 0x02},
1071 {0xd9, 0x10},
1072 {0xda, 0x00},
1073 {0x94, 0x11},
1074};
1075
1076static const u8 bridge_start_ov965x_xga[][2] = {
1077 {0x94, 0xaa},
1078 {0xf1, 0x60},
1079 {0xe5, 0x04},
1080 {0xc0, 0xa0},
1081 {0xc1, 0x80},
1082 {0x8c, 0x00},
1083 {0x8d, 0x1c},
1084 {0x34, 0x05},
1085 {0xc2, 0x4c},
1086 {0xc3, 0xf9},
1087 {0x50, 0x00},
1088 {0x51, 0x40},
1089 {0x52, 0x00},
1090 {0x53, 0x00},
1091 {0x54, 0x00},
1092 {0x55, 0x88},
1093 {0x57, 0x00},
1094 {0x5c, 0x01},
1095 {0x5a, 0x00},
1096 {0x5b, 0xc0},
1097 {0x35, 0x02},
1098 {0xd9, 0x10},
1099 {0xda, 0x01},
1100 {0x94, 0x11},
1101};
1102
1103static const u8 bridge_start_ov965x_sxga[][2] = {
1104 {0x94, 0xaa},
1105 {0xf1, 0x60},
1106 {0xe5, 0x04},
1107 {0xc0, 0xa0},
1108 {0xc1, 0x80},
1109 {0x8c, 0x00},
1110 {0x8d, 0x1c},
1111 {0x34, 0x05},
1112 {0xc2, 0x0c},
1113 {0xc3, 0xf9},
1114 {0xda, 0x00},
1115 {0x35, 0x02},
1116 {0xd9, 0x10},
1117 {0x94, 0x11},
1118};
1119
1120static const u8 sensor_start_ov965x_2_qvga[][2] = {
1121 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
1122 {0x1e, 0x04}, /* mvfp */
1123 {0x13, 0xe0}, /* com8 */
1124 {0x00, 0x00},
1125 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1126 {0x11, 0x01}, /* clkrc */
1127 {0x6b, 0x5a}, /* dblv */
1128 {0x6a, 0x02}, /* 50 Hz banding filter */
1129 {0xc5, 0x03}, /* 60 Hz banding filter */
1130 {0xa2, 0x96}, /* bd50 */
1131 {0xa3, 0x7d}, /* bd60 */
1132
1133 {0xff, 0x13}, /* read 13, write ff 00 */
1134 {0x13, 0xe7},
1135 {0x3a, 0x80}, /* tslb - yuyv */
1136};
1137
1138static const u8 sensor_start_ov965x_2_vga[][2] = {
1139 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1140 {0x1e, 0x04}, /* mvfp */
1141 {0x13, 0xe0}, /* com8 */
1142 {0x00, 0x00},
1143 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1144 {0x11, 0x03}, /* clkrc */
1145 {0x6b, 0x5a}, /* dblv */
1146 {0x6a, 0x05}, /* 50 Hz banding filter */
1147 {0xc5, 0x07}, /* 60 Hz banding filter */
1148 {0xa2, 0x4b}, /* bd50 */
1149 {0xa3, 0x3e}, /* bd60 */
1150
1151 {0x2d, 0x00}, /* advfl */
1152};
1153
1154static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */
1155 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1156 {0x1e, 0x04}, /* mvfp */
1157 {0x13, 0xe0}, /* com8 */
1158 {0x00, 0x00},
1159 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1160 {0x11, 0x01}, /* clkrc */
1161 {0x6b, 0x5a}, /* dblv */
1162 {0x6a, 0x0c}, /* 50 Hz banding filter */
1163 {0xc5, 0x0f}, /* 60 Hz banding filter */
1164 {0xa2, 0x4e}, /* bd50 */
1165 {0xa3, 0x41}, /* bd60 */
1166};
1167
1168static const u8 sensor_start_ov965x_2_sxga[][2] = {
1169 {0x13, 0xe0}, /* com8 */
1170 {0x00, 0x00},
1171 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
1172 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
1173 {0x1e, 0x04}, /* mvfp */
1174 {0x11, 0x01}, /* clkrc */
1175 {0x6b, 0x5a}, /* dblv */
1176 {0x6a, 0x0c}, /* 50 Hz banding filter */
1177 {0xc5, 0x0f}, /* 60 Hz banding filter */
1178 {0xa2, 0x4e}, /* bd50 */
1179 {0xa3, 0x41}, /* bd60 */
1180};
1181
1182static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) 479static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
1183{ 480{
1184 struct usb_device *udev = gspca_dev->dev; 481 struct usb_device *udev = gspca_dev->dev;
@@ -1360,14 +657,14 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
1360 PDEBUG(D_PROBE, "frame_rate: %d", r->fps); 657 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
1361} 658}
1362 659
1363static void setbrightness_77(struct gspca_dev *gspca_dev) 660static void setbrightness(struct gspca_dev *gspca_dev)
1364{ 661{
1365 struct sd *sd = (struct sd *) gspca_dev; 662 struct sd *sd = (struct sd *) gspca_dev;
1366 663
1367 sccb_reg_write(gspca_dev, 0x9B, sd->brightness); 664 sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
1368} 665}
1369 666
1370static void setcontrast_77(struct gspca_dev *gspca_dev) 667static void setcontrast(struct gspca_dev *gspca_dev)
1371{ 668{
1372 struct sd *sd = (struct sd *) gspca_dev; 669 struct sd *sd = (struct sd *) gspca_dev;
1373 670
@@ -1401,7 +698,7 @@ static void setgain(struct gspca_dev *gspca_dev)
1401 sccb_reg_write(gspca_dev, 0x00, val); 698 sccb_reg_write(gspca_dev, 0x00, val);
1402} 699}
1403 700
1404static void setexposure_77(struct gspca_dev *gspca_dev) 701static void setexposure(struct gspca_dev *gspca_dev)
1405{ 702{
1406 struct sd *sd = (struct sd *) gspca_dev; 703 struct sd *sd = (struct sd *) gspca_dev;
1407 u8 val; 704 u8 val;
@@ -1432,7 +729,7 @@ static void sethue(struct gspca_dev *gspca_dev)
1432 sccb_reg_write(gspca_dev, 0x01, sd->hue); 729 sccb_reg_write(gspca_dev, 0x01, sd->hue);
1433} 730}
1434 731
1435static void setautogain_77(struct gspca_dev *gspca_dev) 732static void setautogain(struct gspca_dev *gspca_dev)
1436{ 733{
1437 struct sd *sd = (struct sd *) gspca_dev; 734 struct sd *sd = (struct sd *) gspca_dev;
1438 735
@@ -1457,7 +754,7 @@ static void setawb(struct gspca_dev *gspca_dev)
1457 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */ 754 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */
1458} 755}
1459 756
1460static void setsharpness_77(struct gspca_dev *gspca_dev) 757static void setsharpness(struct gspca_dev *gspca_dev)
1461{ 758{
1462 struct sd *sd = (struct sd *) gspca_dev; 759 struct sd *sd = (struct sd *) gspca_dev;
1463 u8 val; 760 u8 val;
@@ -1491,132 +788,6 @@ static void setvflip(struct gspca_dev *gspca_dev)
1491 sccb_reg_read(gspca_dev, 0x0c) & 0x7f); 788 sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
1492} 789}
1493 790
1494/* ov965x specific controls */
1495static void setbrightness_96(struct gspca_dev *gspca_dev)
1496{
1497 struct sd *sd = (struct sd *) gspca_dev;
1498 u8 val;
1499
1500 val = sd->brightness;
1501 if (val < 8)
1502 val = 15 - val; /* f .. 8 */
1503 else
1504 val = val - 8; /* 0 .. 7 */
1505 sccb_reg_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
1506 0x0f | (val << 4));
1507}
1508
1509static void setcontrast_96(struct gspca_dev *gspca_dev)
1510{
1511 struct sd *sd = (struct sd *) gspca_dev;
1512
1513 sccb_reg_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
1514 sd->contrast << 4);
1515}
1516
1517static void setexposure_96(struct gspca_dev *gspca_dev)
1518{
1519 struct sd *sd = (struct sd *) gspca_dev;
1520 u8 val;
1521 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
1522
1523 sccb_reg_write(gspca_dev, 0x10, /* aec[9:2] */
1524 expo[sd->exposure]);
1525 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1526 sccb_reg_write(gspca_dev, 0xff, 0x00);
1527 sccb_reg_write(gspca_dev, 0x13, val);
1528 val = sccb_reg_read(gspca_dev, 0xa1); /* aech */
1529 sccb_reg_write(gspca_dev, 0xff, 0x00);
1530 sccb_reg_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
1531}
1532
1533static void setsharpness_96(struct gspca_dev *gspca_dev)
1534{
1535 struct sd *sd = (struct sd *) gspca_dev;
1536 s8 val;
1537
1538 val = sd->sharpness;
1539 if (val < 0) { /* auto */
1540 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1541 sccb_reg_write(gspca_dev, 0xff, 0x00);
1542 sccb_reg_write(gspca_dev, 0x42, val | 0x40);
1543 /* Edge enhancement strength auto adjust */
1544 return;
1545 }
1546 if (val != 0)
1547 val = 1 << (val - 1);
1548 sccb_reg_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
1549 val);
1550 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1551 sccb_reg_write(gspca_dev, 0xff, 0x00);
1552 sccb_reg_write(gspca_dev, 0x42, val & 0xbf);
1553}
1554
1555static void setautogain_96(struct gspca_dev *gspca_dev)
1556{
1557 struct sd *sd = (struct sd *) gspca_dev;
1558 u8 val;
1559
1560/*fixme: should adjust agc/awb/aec by different controls */
1561 val = sd->autogain;
1562 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1563 sccb_reg_write(gspca_dev, 0xff, 0x00);
1564 if (sd->autogain)
1565 val |= 0x05; /* agc & aec */
1566 else
1567 val &= 0xfa;
1568 sccb_reg_write(gspca_dev, 0x13, val);
1569}
1570
1571static void setsatur(struct gspca_dev *gspca_dev)
1572{
1573 struct sd *sd = (struct sd *) gspca_dev;
1574 u8 val1, val2, val3;
1575 static const u8 matrix[5][2] = {
1576 {0x14, 0x38},
1577 {0x1e, 0x54},
1578 {0x28, 0x70},
1579 {0x32, 0x8c},
1580 {0x48, 0x90}
1581 };
1582
1583 val1 = matrix[sd->satur][0];
1584 val2 = matrix[sd->satur][1];
1585 val3 = val1 + val2;
1586 sccb_reg_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1587 sccb_reg_write(gspca_dev, 0x50, val3);
1588 sccb_reg_write(gspca_dev, 0x51, 0x00);
1589 sccb_reg_write(gspca_dev, 0x52, val1);
1590 sccb_reg_write(gspca_dev, 0x53, val2);
1591 sccb_reg_write(gspca_dev, 0x54, val3);
1592 sccb_reg_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
1593 val1 = sccb_reg_read(gspca_dev, 0x41); /* com16 */
1594 sccb_reg_write(gspca_dev, 0xff, 0x00);
1595 sccb_reg_write(gspca_dev, 0x41, val1);
1596}
1597
1598static void setfreq(struct gspca_dev *gspca_dev)
1599{
1600 struct sd *sd = (struct sd *) gspca_dev;
1601 u8 val;
1602
1603 val = sccb_reg_read(gspca_dev, 0x13); /* com8 */
1604 sccb_reg_write(gspca_dev, 0xff, 0x00);
1605 if (sd->lightfreq == 0) {
1606 sccb_reg_write(gspca_dev, 0x13, val & 0xdf);
1607 return;
1608 }
1609 sccb_reg_write(gspca_dev, 0x13, val | 0x20);
1610
1611 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
1612 sccb_reg_write(gspca_dev, 0xff, 0x00);
1613 if (sd->lightfreq == 1)
1614 val |= 0x01;
1615 else
1616 val &= 0xfe;
1617 sccb_reg_write(gspca_dev, 0x42, val);
1618}
1619
1620/* this function is called at probe time */ 791/* this function is called at probe time */
1621static int sd_config(struct gspca_dev *gspca_dev, 792static int sd_config(struct gspca_dev *gspca_dev,
1622 const struct usb_device_id *id) 793 const struct usb_device_id *id)
@@ -1624,77 +795,49 @@ static int sd_config(struct gspca_dev *gspca_dev,
1624 struct sd *sd = (struct sd *) gspca_dev; 795 struct sd *sd = (struct sd *) gspca_dev;
1625 struct cam *cam; 796 struct cam *cam;
1626 797
1627 sd->sensor = id->driver_info;
1628
1629 cam = &gspca_dev->cam; 798 cam = &gspca_dev->cam;
1630 799
1631 if (sd->sensor == SENSOR_OV772X) { 800 cam->cam_mode = ov772x_mode;
1632 cam->cam_mode = ov772x_mode; 801 cam->nmodes = ARRAY_SIZE(ov772x_mode);
1633 cam->nmodes = ARRAY_SIZE(ov772x_mode);
1634 802
1635 cam->bulk = 1; 803 cam->bulk = 1;
1636 cam->bulk_size = 16384; 804 cam->bulk_size = 16384;
1637 cam->bulk_nurbs = 2; 805 cam->bulk_nurbs = 2;
1638 } else { /* ov965x */
1639 cam->cam_mode = ov965x_mode;
1640 cam->nmodes = ARRAY_SIZE(ov965x_mode);
1641 }
1642 806
1643 sd->frame_rate = 30; 807 sd->frame_rate = 30;
1644 808
1645 if (sd->sensor == SENSOR_OV772X) { 809 sd->brightness = BRIGHTNESS_DEF;
1646 sd->brightness = BRIGHTNESS_77_DEF; 810 sd->contrast = CONTRAST_DEF;
1647 sd->contrast = CONTRAST_77_DEF; 811 sd->gain = GAIN_DEF;
1648 sd->gain = GAIN_DEF; 812 sd->exposure = EXPO_DEF;
1649 sd->exposure = EXPO_77_DEF; 813 sd->redblc = RED_BALANCE_DEF;
1650 sd->redblc = RED_BALANCE_DEF; 814 sd->blueblc = BLUE_BALANCE_DEF;
1651 sd->blueblc = BLUE_BALANCE_DEF; 815 sd->hue = HUE_DEF;
1652 sd->hue = HUE_DEF; 816#if AUTOGAIN_DEF != 0
1653#if AUTOGAIN_77_DEF != 0 817 sd->autogain = AUTOGAIN_DEF;
1654 sd->autogain = AUTOGAIN_77_DEF;
1655#else 818#else
1656 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); 819 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
1657#endif 820#endif
1658#if AWB_DEF != 0 821#if AWB_DEF != 0
1659 sd->awb = AWB_DEF 822 sd->awb = AWB_DEF
1660#endif 823#endif
1661#if SHARPNESS_77_DEF != 0 824#if SHARPNESS_DEF != 0
1662 sd->sharpness = SHARPNESS_77_DEF; 825 sd->sharpness = SHARPNESS_DEF;
1663#endif 826#endif
1664#if HFLIP_DEF != 0 827#if HFLIP_DEF != 0
1665 sd->hflip = HFLIP_DEF; 828 sd->hflip = HFLIP_DEF;
1666#endif 829#endif
1667#if VFLIP_DEF != 0 830#if VFLIP_DEF != 0
1668 sd->vflip = VFLIP_DEF; 831 sd->vflip = VFLIP_DEF;
1669#endif
1670 } else {
1671 sd->brightness = BRIGHTNESS_96_DEF;
1672 sd->contrast = CONTRAST_96_DEF;
1673#if AUTOGAIN_96_DEF != 0
1674 sd->autogain = AUTOGAIN_96_DEF;
1675 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
1676#endif
1677#if EXPO_96_DEF != 0
1678 sd->exposure = EXPO_96_DEF;
1679#endif 832#endif
1680#if SHARPNESS_96_DEF != 0 833
1681 sd->sharpness = SHARPNESS_96_DEF;
1682#endif
1683 sd->satur = SATUR_DEF;
1684 sd->lightfreq = FREQ_DEF;
1685 }
1686 return 0; 834 return 0;
1687} 835}
1688 836
1689/* this function is called at probe and resume time */ 837/* this function is called at probe and resume time */
1690static int sd_init(struct gspca_dev *gspca_dev) 838static int sd_init(struct gspca_dev *gspca_dev)
1691{ 839{
1692 struct sd *sd = (struct sd *) gspca_dev;
1693 u16 sensor_id; 840 u16 sensor_id;
1694 static const u8 sensor_addr[2] = {
1695 0x42, /* 0 SENSOR_OV772X */
1696 0x60, /* 1 SENSOR_OV965X */
1697 };
1698 841
1699 /* reset bridge */ 842 /* reset bridge */
1700 ov534_reg_write(gspca_dev, 0xe7, 0x3a); 843 ov534_reg_write(gspca_dev, 0xe7, 0x3a);
@@ -1702,8 +845,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1702 msleep(100); 845 msleep(100);
1703 846
1704 /* initialize the sensor address */ 847 /* initialize the sensor address */
1705 ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 848 ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 0x42);
1706 sensor_addr[sd->sensor]);
1707 849
1708 /* reset sensor */ 850 /* reset sensor */
1709 sccb_reg_write(gspca_dev, 0x12, 0x80); 851 sccb_reg_write(gspca_dev, 0x12, 0x80);
@@ -1717,64 +859,46 @@ static int sd_init(struct gspca_dev *gspca_dev)
1717 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id); 859 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1718 860
1719 /* initialize */ 861 /* initialize */
1720 switch (sd->sensor) { 862 reg_w_array(gspca_dev, bridge_init,
1721 case SENSOR_OV772X: 863 ARRAY_SIZE(bridge_init));
1722 reg_w_array(gspca_dev, bridge_init_ov772x, 864 ov534_set_led(gspca_dev, 1);
1723 ARRAY_SIZE(bridge_init_ov772x)); 865 sccb_w_array(gspca_dev, sensor_init,
1724 ov534_set_led(gspca_dev, 1); 866 ARRAY_SIZE(sensor_init));
1725 sccb_w_array(gspca_dev, sensor_init_ov772x, 867 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1726 ARRAY_SIZE(sensor_init_ov772x)); 868 ov534_set_led(gspca_dev, 0);
1727 ov534_reg_write(gspca_dev, 0xe0, 0x09); 869 set_frame_rate(gspca_dev);
1728 ov534_set_led(gspca_dev, 0);
1729 set_frame_rate(gspca_dev);
1730 break;
1731 default:
1732/* case SENSOR_OV965X: */
1733 reg_w_array(gspca_dev, bridge_init_ov965x,
1734 ARRAY_SIZE(bridge_init_ov965x));
1735 sccb_w_array(gspca_dev, sensor_init_ov965x,
1736 ARRAY_SIZE(sensor_init_ov965x));
1737 reg_w_array(gspca_dev, bridge_init_ov965x_2,
1738 ARRAY_SIZE(bridge_init_ov965x_2));
1739 sccb_w_array(gspca_dev, sensor_init_ov965x_2,
1740 ARRAY_SIZE(sensor_init_ov965x_2));
1741 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1742 ov534_reg_write(gspca_dev, 0xe0, 0x01);
1743 ov534_set_led(gspca_dev, 0);
1744 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1745 }
1746 870
1747 return 0; 871 return 0;
1748} 872}
1749 873
1750static int sd_start_ov772x(struct gspca_dev *gspca_dev) 874static int sd_start(struct gspca_dev *gspca_dev)
1751{ 875{
1752 int mode; 876 int mode;
1753 877
1754 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 878 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1755 if (mode != 0) { /* 320x240 */ 879 if (mode != 0) { /* 320x240 */
1756 reg_w_array(gspca_dev, bridge_start_ov772x_qvga, 880 reg_w_array(gspca_dev, bridge_start_qvga,
1757 ARRAY_SIZE(bridge_start_ov772x_qvga)); 881 ARRAY_SIZE(bridge_start_qvga));
1758 sccb_w_array(gspca_dev, sensor_start_ov772x_qvga, 882 sccb_w_array(gspca_dev, sensor_start_qvga,
1759 ARRAY_SIZE(sensor_start_ov772x_qvga)); 883 ARRAY_SIZE(sensor_start_qvga));
1760 } else { /* 640x480 */ 884 } else { /* 640x480 */
1761 reg_w_array(gspca_dev, bridge_start_ov772x_vga, 885 reg_w_array(gspca_dev, bridge_start_vga,
1762 ARRAY_SIZE(bridge_start_ov772x_vga)); 886 ARRAY_SIZE(bridge_start_vga));
1763 sccb_w_array(gspca_dev, sensor_start_ov772x_vga, 887 sccb_w_array(gspca_dev, sensor_start_vga,
1764 ARRAY_SIZE(sensor_start_ov772x_vga)); 888 ARRAY_SIZE(sensor_start_vga));
1765 } 889 }
1766 set_frame_rate(gspca_dev); 890 set_frame_rate(gspca_dev);
1767 891
1768 setautogain_77(gspca_dev); 892 setautogain(gspca_dev);
1769 setawb(gspca_dev); 893 setawb(gspca_dev);
1770 setgain(gspca_dev); 894 setgain(gspca_dev);
1771 setredblc(gspca_dev); 895 setredblc(gspca_dev);
1772 setblueblc(gspca_dev); 896 setblueblc(gspca_dev);
1773 sethue(gspca_dev); 897 sethue(gspca_dev);
1774 setexposure_77(gspca_dev); 898 setexposure(gspca_dev);
1775 setbrightness_77(gspca_dev); 899 setbrightness(gspca_dev);
1776 setcontrast_77(gspca_dev); 900 setcontrast(gspca_dev);
1777 setsharpness_77(gspca_dev); 901 setsharpness(gspca_dev);
1778 setvflip(gspca_dev); 902 setvflip(gspca_dev);
1779 sethflip(gspca_dev); 903 sethflip(gspca_dev);
1780 904
@@ -1783,81 +907,12 @@ static int sd_start_ov772x(struct gspca_dev *gspca_dev)
1783 return 0; 907 return 0;
1784} 908}
1785 909
1786static int sd_start_ov965x(struct gspca_dev *gspca_dev) 910static void sd_stopN(struct gspca_dev *gspca_dev)
1787{
1788 int mode;
1789
1790 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1791 switch (mode) {
1792 default:
1793/* case 4: * 320x240 */
1794 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
1795 ARRAY_SIZE(sensor_start_ov965x_1_vga));
1796 reg_w_array(gspca_dev, bridge_start_ov965x_qvga,
1797 ARRAY_SIZE(bridge_start_ov965x_qvga));
1798 sccb_w_array(gspca_dev, sensor_start_ov965x_2_qvga,
1799 ARRAY_SIZE(sensor_start_ov965x_2_qvga));
1800 break;
1801 case 3: /* 640x480 */
1802 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
1803 ARRAY_SIZE(sensor_start_ov965x_1_vga));
1804 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
1805 ARRAY_SIZE(bridge_start_ov965x_vga));
1806 sccb_w_array(gspca_dev, sensor_start_ov965x_2_vga,
1807 ARRAY_SIZE(sensor_start_ov965x_2_vga));
1808 break;
1809 case 2: /* 800x600 */
1810 sccb_w_array(gspca_dev, sensor_start_ov965x_1_svga,
1811 ARRAY_SIZE(sensor_start_ov965x_1_svga));
1812 reg_w_array(gspca_dev, bridge_start_ov965x_svga,
1813 ARRAY_SIZE(bridge_start_ov965x_svga));
1814 sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
1815 ARRAY_SIZE(sensor_start_ov965x_2_svga));
1816 break;
1817 case 1: /* 1024x768 */
1818 sccb_w_array(gspca_dev, sensor_start_ov965x_1_xga,
1819 ARRAY_SIZE(sensor_start_ov965x_1_xga));
1820 reg_w_array(gspca_dev, bridge_start_ov965x_xga,
1821 ARRAY_SIZE(bridge_start_ov965x_xga));
1822 sccb_w_array(gspca_dev, sensor_start_ov965x_2_svga,
1823 ARRAY_SIZE(sensor_start_ov965x_2_svga));
1824 break;
1825 case 0: /* 1280x1024 */
1826 sccb_w_array(gspca_dev, sensor_start_ov965x_1_sxga,
1827 ARRAY_SIZE(sensor_start_ov965x_1_sxga));
1828 reg_w_array(gspca_dev, bridge_start_ov965x_sxga,
1829 ARRAY_SIZE(bridge_start_ov965x_sxga));
1830 sccb_w_array(gspca_dev, sensor_start_ov965x_2_sxga,
1831 ARRAY_SIZE(sensor_start_ov965x_2_sxga));
1832 break;
1833 }
1834 setfreq(gspca_dev);
1835 setautogain_96(gspca_dev);
1836 setbrightness_96(gspca_dev);
1837 setcontrast_96(gspca_dev);
1838 setexposure_96(gspca_dev);
1839 setsharpness_96(gspca_dev);
1840 setsatur(gspca_dev);
1841
1842 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1843 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1844 ov534_set_led(gspca_dev, 1);
1845 return 0;
1846}
1847
1848static void sd_stopN_ov772x(struct gspca_dev *gspca_dev)
1849{ 911{
1850 ov534_reg_write(gspca_dev, 0xe0, 0x09); 912 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1851 ov534_set_led(gspca_dev, 0); 913 ov534_set_led(gspca_dev, 0);
1852} 914}
1853 915
1854static void sd_stopN_ov965x(struct gspca_dev *gspca_dev)
1855{
1856 ov534_reg_write(gspca_dev, 0xe0, 0x01);
1857 ov534_set_led(gspca_dev, 0);
1858 ov534_reg_write(gspca_dev, 0xe0, 0x00);
1859}
1860
1861/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 916/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1862#define UVC_STREAM_EOH (1 << 7) 917#define UVC_STREAM_EOH (1 << 7)
1863#define UVC_STREAM_ERR (1 << 6) 918#define UVC_STREAM_ERR (1 << 6)
@@ -1875,11 +930,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1875 __u32 this_pts; 930 __u32 this_pts;
1876 u16 this_fid; 931 u16 this_fid;
1877 int remaining_len = len; 932 int remaining_len = len;
1878 int payload_len;
1879 933
1880 payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
1881 do { 934 do {
1882 len = min(remaining_len, payload_len); 935 len = min(remaining_len, 2048);
1883 936
1884 /* Payloads are prefixed with a UVC-style header. We 937 /* Payloads are prefixed with a UVC-style header. We
1885 consider a frame to start when the FID toggles, or the PTS 938 consider a frame to start when the FID toggles, or the PTS
@@ -1918,7 +971,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1918 data + 12, len - 12); 971 data + 12, len - 12);
1919 /* If this packet is marked as EOF, end the frame */ 972 /* If this packet is marked as EOF, end the frame */
1920 } else if (data[1] & UVC_STREAM_EOF) { 973 } else if (data[1] & UVC_STREAM_EOF) {
974 struct gspca_frame *frame;
975
1921 sd->last_pts = 0; 976 sd->last_pts = 0;
977 frame = gspca_get_i_frame(gspca_dev);
978 if (frame == NULL)
979 goto discard;
980 if (frame->data_end - frame->data !=
981 gspca_dev->width * gspca_dev->height * 2) {
982 PDEBUG(D_PACK, "short frame");
983 goto discard;
984 }
1922 gspca_frame_add(gspca_dev, LAST_PACKET, 985 gspca_frame_add(gspca_dev, LAST_PACKET,
1923 data + 12, len - 12); 986 data + 12, len - 12);
1924 } else { 987 } else {
@@ -1965,12 +1028,8 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1965 struct sd *sd = (struct sd *) gspca_dev; 1028 struct sd *sd = (struct sd *) gspca_dev;
1966 1029
1967 sd->exposure = val; 1030 sd->exposure = val;
1968 if (gspca_dev->streaming) { 1031 if (gspca_dev->streaming)
1969 if (sd->sensor == SENSOR_OV772X) 1032 setexposure(gspca_dev);
1970 setexposure_77(gspca_dev);
1971 else
1972 setexposure_96(gspca_dev);
1973 }
1974 return 0; 1033 return 0;
1975} 1034}
1976 1035
@@ -1987,12 +1046,8 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1987 struct sd *sd = (struct sd *) gspca_dev; 1046 struct sd *sd = (struct sd *) gspca_dev;
1988 1047
1989 sd->brightness = val; 1048 sd->brightness = val;
1990 if (gspca_dev->streaming) { 1049 if (gspca_dev->streaming)
1991 if (sd->sensor == SENSOR_OV772X) 1050 setbrightness(gspca_dev);
1992 setbrightness_77(gspca_dev);
1993 else
1994 setbrightness_96(gspca_dev);
1995 }
1996 return 0; 1051 return 0;
1997} 1052}
1998 1053
@@ -2009,12 +1064,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2009 struct sd *sd = (struct sd *) gspca_dev; 1064 struct sd *sd = (struct sd *) gspca_dev;
2010 1065
2011 sd->contrast = val; 1066 sd->contrast = val;
2012 if (gspca_dev->streaming) { 1067 if (gspca_dev->streaming)
2013 if (sd->sensor == SENSOR_OV772X) 1068 setcontrast(gspca_dev);
2014 setcontrast_77(gspca_dev);
2015 else
2016 setcontrast_96(gspca_dev);
2017 }
2018 return 0; 1069 return 0;
2019} 1070}
2020 1071
@@ -2026,41 +1077,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2026 return 0; 1077 return 0;
2027} 1078}
2028 1079
2029static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
2030{
2031 struct sd *sd = (struct sd *) gspca_dev;
2032
2033 sd->satur = val;
2034 if (gspca_dev->streaming)
2035 setsatur(gspca_dev);
2036 return 0;
2037}
2038
2039static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
2040{
2041 struct sd *sd = (struct sd *) gspca_dev;
2042
2043 *val = sd->satur;
2044 return 0;
2045}
2046static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2047{
2048 struct sd *sd = (struct sd *) gspca_dev;
2049
2050 sd->lightfreq = val;
2051 if (gspca_dev->streaming)
2052 setfreq(gspca_dev);
2053 return 0;
2054}
2055
2056static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2057{
2058 struct sd *sd = (struct sd *) gspca_dev;
2059
2060 *val = sd->lightfreq;
2061 return 0;
2062}
2063
2064static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val) 1080static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val)
2065{ 1081{
2066 struct sd *sd = (struct sd *) gspca_dev; 1082 struct sd *sd = (struct sd *) gspca_dev;
@@ -2122,22 +1138,14 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2122 sd->autogain = val; 1138 sd->autogain = val;
2123 1139
2124 if (gspca_dev->streaming) { 1140 if (gspca_dev->streaming) {
2125 if (sd->sensor == SENSOR_OV772X) { 1141
2126 1142 /* the auto white balance control works only
2127 /* the auto white balance control works only 1143 * when auto gain is set */
2128 * when auto gain is set */ 1144 if (val)
2129 if (val) 1145 gspca_dev->ctrl_inac &= ~(1 << AWB_IDX);
2130 gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX); 1146 else
2131 else 1147 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
2132 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX); 1148 setautogain(gspca_dev);
2133 setautogain_77(gspca_dev);
2134 } else {
2135 if (val)
2136 gspca_dev->ctrl_inac |= (1 << EXPO_96_IDX);
2137 else
2138 gspca_dev->ctrl_inac &= ~(1 << EXPO_96_IDX);
2139 setautogain_96(gspca_dev);
2140 }
2141 } 1149 }
2142 return 0; 1150 return 0;
2143} 1151}
@@ -2173,12 +1181,8 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2173 struct sd *sd = (struct sd *) gspca_dev; 1181 struct sd *sd = (struct sd *) gspca_dev;
2174 1182
2175 sd->sharpness = val; 1183 sd->sharpness = val;
2176 if (gspca_dev->streaming) { 1184 if (gspca_dev->streaming)
2177 if (sd->sensor == SENSOR_OV772X) 1185 setsharpness(gspca_dev);
2178 setsharpness_77(gspca_dev);
2179 else
2180 setsharpness_96(gspca_dev);
2181 }
2182 return 0; 1186 return 0;
2183} 1187}
2184 1188
@@ -2257,7 +1261,7 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
2257 1261
2258 /* Set requested framerate */ 1262 /* Set requested framerate */
2259 sd->frame_rate = tpf->denominator / tpf->numerator; 1263 sd->frame_rate = tpf->denominator / tpf->numerator;
2260 if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X) 1264 if (gspca_dev->streaming)
2261 set_frame_rate(gspca_dev); 1265 set_frame_rate(gspca_dev);
2262 1266
2263 /* Return the actual framerate */ 1267 /* Return the actual framerate */
@@ -2267,57 +1271,23 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
2267 return 0; 1271 return 0;
2268} 1272}
2269 1273
2270static int sd_querymenu(struct gspca_dev *gspca_dev,
2271 struct v4l2_querymenu *menu)
2272{
2273 switch (menu->id) {
2274 case V4L2_CID_POWER_LINE_FREQUENCY:
2275 switch (menu->index) {
2276 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2277 strcpy((char *) menu->name, "NoFliker");
2278 return 0;
2279 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2280 strcpy((char *) menu->name, "50 Hz");
2281 return 0;
2282 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2283 strcpy((char *) menu->name, "60 Hz");
2284 return 0;
2285 }
2286 break;
2287 }
2288 return -EINVAL;
2289}
2290
2291/* sub-driver description */ 1274/* sub-driver description */
2292static const struct sd_desc sd_desc_ov772x = { 1275static const struct sd_desc sd_desc = {
2293 .name = MODULE_NAME, 1276 .name = MODULE_NAME,
2294 .ctrls = sd_ctrls_ov772x, 1277 .ctrls = sd_ctrls,
2295 .nctrls = ARRAY_SIZE(sd_ctrls_ov772x), 1278 .nctrls = ARRAY_SIZE(sd_ctrls),
2296 .config = sd_config, 1279 .config = sd_config,
2297 .init = sd_init, 1280 .init = sd_init,
2298 .start = sd_start_ov772x, 1281 .start = sd_start,
2299 .stopN = sd_stopN_ov772x, 1282 .stopN = sd_stopN,
2300 .pkt_scan = sd_pkt_scan, 1283 .pkt_scan = sd_pkt_scan,
2301 .get_streamparm = sd_get_streamparm, 1284 .get_streamparm = sd_get_streamparm,
2302 .set_streamparm = sd_set_streamparm, 1285 .set_streamparm = sd_set_streamparm,
2303}; 1286};
2304 1287
2305static const struct sd_desc sd_desc_ov965x = {
2306 .name = MODULE_NAME,
2307 .ctrls = sd_ctrls_ov965x,
2308 .nctrls = ARRAY_SIZE(sd_ctrls_ov965x),
2309 .config = sd_config,
2310 .init = sd_init,
2311 .start = sd_start_ov965x,
2312 .stopN = sd_stopN_ov965x,
2313 .pkt_scan = sd_pkt_scan,
2314 .querymenu = sd_querymenu,
2315};
2316
2317/* -- module initialisation -- */ 1288/* -- module initialisation -- */
2318static const __devinitdata struct usb_device_id device_table[] = { 1289static const __devinitdata struct usb_device_id device_table[] = {
2319 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X}, 1290 {USB_DEVICE(0x1415, 0x2000)},
2320 {USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
2321 {} 1291 {}
2322}; 1292};
2323 1293
@@ -2326,11 +1296,7 @@ MODULE_DEVICE_TABLE(usb, device_table);
2326/* -- device connect -- */ 1296/* -- device connect -- */
2327static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 1297static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
2328{ 1298{
2329 return gspca_dev_probe(intf, id, 1299 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2330 id->driver_info == SENSOR_OV772X
2331 ? &sd_desc_ov772x
2332 : &sd_desc_ov965x,
2333 sizeof(struct sd),
2334 THIS_MODULE); 1300 THIS_MODULE);
2335} 1301}
2336 1302
diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c
new file mode 100644
index 000000000000..464b7f50827d
--- /dev/null
+++ b/drivers/media/video/gspca/ov534_9.c
@@ -0,0 +1,1477 @@
1/*
2 * ov534-ov965x gspca driver
3 *
4 * Copyright (C) 2009-2010 Jean-Francois Moine http://moinejf.free.fr
5 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
6 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
7 *
8 * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#define MODULE_NAME "ov534_9"
28
29#include "gspca.h"
30
31#define OV534_REG_ADDRESS 0xf1 /* sensor address */
32#define OV534_REG_SUBADDR 0xf2
33#define OV534_REG_WRITE 0xf3
34#define OV534_REG_READ 0xf4
35#define OV534_REG_OPERATION 0xf5
36#define OV534_REG_STATUS 0xf6
37
38#define OV534_OP_WRITE_3 0x37
39#define OV534_OP_WRITE_2 0x33
40#define OV534_OP_READ_2 0xf9
41
42#define CTRL_TIMEOUT 500
43
44MODULE_AUTHOR("Jean-Francois Moine <moinejf@free.fr>");
45MODULE_DESCRIPTION("GSPCA/OV534_9 USB Camera Driver");
46MODULE_LICENSE("GPL");
47
48/* specific webcam descriptor */
49struct sd {
50 struct gspca_dev gspca_dev; /* !! must be the first item */
51 __u32 last_pts;
52 u8 last_fid;
53
54 u8 brightness;
55 u8 contrast;
56 u8 autogain;
57 u8 exposure;
58 s8 sharpness;
59 u8 satur;
60 u8 freq;
61};
62
63/* V4L2 controls supported by the driver */
64static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
65static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
66static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
72static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
78
79static const struct ctrl sd_ctrls[] = {
80 { /* 0 */
81 {
82 .id = V4L2_CID_BRIGHTNESS,
83 .type = V4L2_CTRL_TYPE_INTEGER,
84 .name = "Brightness",
85 .minimum = 0,
86 .maximum = 15,
87 .step = 1,
88#define BRIGHTNESS_DEF 7
89 .default_value = BRIGHTNESS_DEF,
90 },
91 .set = sd_setbrightness,
92 .get = sd_getbrightness,
93 },
94 { /* 1 */
95 {
96 .id = V4L2_CID_CONTRAST,
97 .type = V4L2_CTRL_TYPE_INTEGER,
98 .name = "Contrast",
99 .minimum = 0,
100 .maximum = 15,
101 .step = 1,
102#define CONTRAST_DEF 3
103 .default_value = CONTRAST_DEF,
104 },
105 .set = sd_setcontrast,
106 .get = sd_getcontrast,
107 },
108 { /* 2 */
109 {
110 .id = V4L2_CID_AUTOGAIN,
111 .type = V4L2_CTRL_TYPE_BOOLEAN,
112 .name = "Autogain",
113 .minimum = 0,
114 .maximum = 1,
115 .step = 1,
116#define AUTOGAIN_DEF 1
117 .default_value = AUTOGAIN_DEF,
118 },
119 .set = sd_setautogain,
120 .get = sd_getautogain,
121 },
122#define EXPO_IDX 3
123 { /* 3 */
124 {
125 .id = V4L2_CID_EXPOSURE,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "Exposure",
128 .minimum = 0,
129 .maximum = 3,
130 .step = 1,
131#define EXPO_DEF 0
132 .default_value = EXPO_DEF,
133 },
134 .set = sd_setexposure,
135 .get = sd_getexposure,
136 },
137 { /* 4 */
138 {
139 .id = V4L2_CID_SHARPNESS,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "Sharpness",
142 .minimum = -1, /* -1 = auto */
143 .maximum = 4,
144 .step = 1,
145#define SHARPNESS_DEF -1
146 .default_value = SHARPNESS_DEF,
147 },
148 .set = sd_setsharpness,
149 .get = sd_getsharpness,
150 },
151 { /* 5 */
152 {
153 .id = V4L2_CID_SATURATION,
154 .type = V4L2_CTRL_TYPE_INTEGER,
155 .name = "Saturation",
156 .minimum = 0,
157 .maximum = 4,
158 .step = 1,
159#define SATUR_DEF 2
160 .default_value = SATUR_DEF,
161 },
162 .set = sd_setsatur,
163 .get = sd_getsatur,
164 },
165 {
166 {
167 .id = V4L2_CID_POWER_LINE_FREQUENCY,
168 .type = V4L2_CTRL_TYPE_MENU,
169 .name = "Light frequency filter",
170 .minimum = 0,
171 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
172 .step = 1,
173#define FREQ_DEF 0
174 .default_value = FREQ_DEF,
175 },
176 .set = sd_setfreq,
177 .get = sd_getfreq,
178 },
179};
180
181static const struct v4l2_pix_format ov965x_mode[] = {
182#define QVGA_MODE 0
183 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
184 .bytesperline = 320,
185 .sizeimage = 320 * 240 * 3 / 8 + 590,
186 .colorspace = V4L2_COLORSPACE_JPEG},
187#define VGA_MODE 1
188 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
189 .bytesperline = 640,
190 .sizeimage = 640 * 480 * 3 / 8 + 590,
191 .colorspace = V4L2_COLORSPACE_JPEG},
192#define SVGA_MODE 2
193 {800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
194 .bytesperline = 800,
195 .sizeimage = 800 * 600 * 3 / 8 + 590,
196 .colorspace = V4L2_COLORSPACE_JPEG},
197#define XGA_MODE 3
198 {1024, 768, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
199 .bytesperline = 1024,
200 .sizeimage = 1024 * 768 * 3 / 8 + 590,
201 .colorspace = V4L2_COLORSPACE_JPEG},
202#define SXGA_MODE 4
203 {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
204 .bytesperline = 1280,
205 .sizeimage = 1280 * 1024 * 3 / 8 + 590,
206 .colorspace = V4L2_COLORSPACE_JPEG},
207};
208
209static const u8 bridge_init[][2] = {
210 {0x88, 0xf8},
211 {0x89, 0xff},
212 {0x76, 0x03},
213 {0x92, 0x03},
214 {0x95, 0x10},
215 {0xe2, 0x00},
216 {0xe7, 0x3e},
217 {0x8d, 0x1c},
218 {0x8e, 0x00},
219 {0x8f, 0x00},
220 {0x1f, 0x00},
221 {0xc3, 0xf9},
222 {0x89, 0xff},
223 {0x88, 0xf8},
224 {0x76, 0x03},
225 {0x92, 0x01},
226 {0x93, 0x18},
227 {0x1c, 0x0a},
228 {0x1d, 0x48},
229 {0xc0, 0x50},
230 {0xc1, 0x3c},
231 {0x34, 0x05},
232 {0xc2, 0x0c},
233 {0xc3, 0xf9},
234 {0x34, 0x05},
235 {0xe7, 0x2e},
236 {0x31, 0xf9},
237 {0x35, 0x02},
238 {0xd9, 0x10},
239 {0x25, 0x42},
240 {0x94, 0x11},
241};
242
243static const u8 sensor_init[][2] = {
244 {0x12, 0x80}, /* com7 - SSCB reset */
245 {0x00, 0x00}, /* gain */
246 {0x01, 0x80}, /* blue */
247 {0x02, 0x80}, /* red */
248 {0x03, 0x1b}, /* vref */
249 {0x04, 0x03}, /* com1 - exposure low bits */
250 {0x0b, 0x57}, /* ver */
251 {0x0e, 0x61}, /* com5 */
252 {0x0f, 0x42}, /* com6 */
253 {0x11, 0x00}, /* clkrc */
254 {0x12, 0x02}, /* com7 - 15fps VGA YUYV */
255 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
256 {0x14, 0x28}, /* com9 */
257 {0x16, 0x24}, /* reg16 */
258 {0x17, 0x1d}, /* hstart*/
259 {0x18, 0xbd}, /* hstop */
260 {0x19, 0x01}, /* vstrt */
261 {0x1a, 0x81}, /* vstop*/
262 {0x1e, 0x04}, /* mvfp */
263 {0x24, 0x3c}, /* aew */
264 {0x25, 0x36}, /* aeb */
265 {0x26, 0x71}, /* vpt */
266 {0x27, 0x08}, /* bbias */
267 {0x28, 0x08}, /* gbbias */
268 {0x29, 0x15}, /* gr com */
269 {0x2a, 0x00}, /* exhch */
270 {0x2b, 0x00}, /* exhcl */
271 {0x2c, 0x08}, /* rbias */
272 {0x32, 0xff}, /* href */
273 {0x33, 0x00}, /* chlf */
274 {0x34, 0x3f}, /* aref1 */
275 {0x35, 0x00}, /* aref2 */
276 {0x36, 0xf8}, /* aref3 */
277 {0x38, 0x72}, /* adc2 */
278 {0x39, 0x57}, /* aref4 */
279 {0x3a, 0x80}, /* tslb - yuyv */
280 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
281 {0x3d, 0x99}, /* com13 */
282 {0x3f, 0xc1}, /* edge */
283 {0x40, 0xc0}, /* com15 */
284 {0x41, 0x40}, /* com16 */
285 {0x42, 0xc0}, /* com17 */
286 {0x43, 0x0a}, /* rsvd */
287 {0x44, 0xf0},
288 {0x45, 0x46},
289 {0x46, 0x62},
290 {0x47, 0x2a},
291 {0x48, 0x3c},
292 {0x4a, 0xfc},
293 {0x4b, 0xfc},
294 {0x4c, 0x7f},
295 {0x4d, 0x7f},
296 {0x4e, 0x7f},
297 {0x4f, 0x98}, /* matrix */
298 {0x50, 0x98},
299 {0x51, 0x00},
300 {0x52, 0x28},
301 {0x53, 0x70},
302 {0x54, 0x98},
303 {0x58, 0x1a}, /* matrix coef sign */
304 {0x59, 0x85}, /* AWB control */
305 {0x5a, 0xa9},
306 {0x5b, 0x64},
307 {0x5c, 0x84},
308 {0x5d, 0x53},
309 {0x5e, 0x0e},
310 {0x5f, 0xf0}, /* AWB blue limit */
311 {0x60, 0xf0}, /* AWB red limit */
312 {0x61, 0xf0}, /* AWB green limit */
313 {0x62, 0x00}, /* lcc1 */
314 {0x63, 0x00}, /* lcc2 */
315 {0x64, 0x02}, /* lcc3 */
316 {0x65, 0x16}, /* lcc4 */
317 {0x66, 0x01}, /* lcc5 */
318 {0x69, 0x02}, /* hv */
319 {0x6b, 0x5a}, /* dbvl */
320 {0x6c, 0x04},
321 {0x6d, 0x55},
322 {0x6e, 0x00},
323 {0x6f, 0x9d},
324 {0x70, 0x21}, /* dnsth */
325 {0x71, 0x78},
326 {0x72, 0x00}, /* poidx */
327 {0x73, 0x01}, /* pckdv */
328 {0x74, 0x3a}, /* xindx */
329 {0x75, 0x35}, /* yindx */
330 {0x76, 0x01},
331 {0x77, 0x02},
332 {0x7a, 0x12}, /* gamma curve */
333 {0x7b, 0x08},
334 {0x7c, 0x16},
335 {0x7d, 0x30},
336 {0x7e, 0x5e},
337 {0x7f, 0x72},
338 {0x80, 0x82},
339 {0x81, 0x8e},
340 {0x82, 0x9a},
341 {0x83, 0xa4},
342 {0x84, 0xac},
343 {0x85, 0xb8},
344 {0x86, 0xc3},
345 {0x87, 0xd6},
346 {0x88, 0xe6},
347 {0x89, 0xf2},
348 {0x8a, 0x03},
349 {0x8c, 0x89}, /* com19 */
350 {0x14, 0x28}, /* com9 */
351 {0x90, 0x7d},
352 {0x91, 0x7b},
353 {0x9d, 0x03}, /* lcc6 */
354 {0x9e, 0x04}, /* lcc7 */
355 {0x9f, 0x7a},
356 {0xa0, 0x79},
357 {0xa1, 0x40}, /* aechm */
358 {0xa4, 0x50}, /* com21 */
359 {0xa5, 0x68}, /* com26 */
360 {0xa6, 0x4a}, /* AWB green */
361 {0xa8, 0xc1}, /* refa8 */
362 {0xa9, 0xef}, /* refa9 */
363 {0xaa, 0x92},
364 {0xab, 0x04},
365 {0xac, 0x80}, /* black level control */
366 {0xad, 0x80},
367 {0xae, 0x80},
368 {0xaf, 0x80},
369 {0xb2, 0xf2},
370 {0xb3, 0x20},
371 {0xb4, 0x20}, /* ctrlb4 */
372 {0xb5, 0x00},
373 {0xb6, 0xaf},
374 {0xbb, 0xae},
375 {0xbc, 0x7f}, /* ADC channel offsets */
376 {0xdb, 0x7f},
377 {0xbe, 0x7f},
378 {0xbf, 0x7f},
379 {0xc0, 0xe2},
380 {0xc1, 0xc0},
381 {0xc2, 0x01},
382 {0xc3, 0x4e},
383 {0xc6, 0x85},
384 {0xc7, 0x80}, /* com24 */
385 {0xc9, 0xe0},
386 {0xca, 0xe8},
387 {0xcb, 0xf0},
388 {0xcc, 0xd8},
389 {0xcd, 0xf1},
390 {0x4f, 0x98}, /* matrix */
391 {0x50, 0x98},
392 {0x51, 0x00},
393 {0x52, 0x28},
394 {0x53, 0x70},
395 {0x54, 0x98},
396 {0x58, 0x1a},
397 {0xff, 0x41}, /* read 41, write ff 00 */
398 {0x41, 0x40}, /* com16 */
399
400 {0xc5, 0x03}, /* 60 Hz banding filter */
401 {0x6a, 0x02}, /* 50 Hz banding filter */
402
403 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
404 {0x36, 0xfa}, /* aref3 */
405 {0x69, 0x0a}, /* hv */
406 {0x8c, 0x89}, /* com22 */
407 {0x14, 0x28}, /* com9 */
408 {0x3e, 0x0c},
409 {0x41, 0x40}, /* com16 */
410 {0x72, 0x00},
411 {0x73, 0x00},
412 {0x74, 0x3a},
413 {0x75, 0x35},
414 {0x76, 0x01},
415 {0xc7, 0x80},
416 {0x03, 0x12}, /* vref */
417 {0x17, 0x16}, /* hstart */
418 {0x18, 0x02}, /* hstop */
419 {0x19, 0x01}, /* vstrt */
420 {0x1a, 0x3d}, /* vstop */
421 {0x32, 0xff}, /* href */
422 {0xc0, 0xaa},
423};
424
425static const u8 bridge_init_2[][2] = {
426 {0x94, 0xaa},
427 {0xf1, 0x60},
428 {0xe5, 0x04},
429 {0xc0, 0x50},
430 {0xc1, 0x3c},
431 {0x8c, 0x00},
432 {0x8d, 0x1c},
433 {0x34, 0x05},
434
435 {0xc2, 0x0c},
436 {0xc3, 0xf9},
437 {0xda, 0x01},
438 {0x50, 0x00},
439 {0x51, 0xa0},
440 {0x52, 0x3c},
441 {0x53, 0x00},
442 {0x54, 0x00},
443 {0x55, 0x00},
444 {0x57, 0x00},
445 {0x5c, 0x00},
446 {0x5a, 0xa0},
447 {0x5b, 0x78},
448 {0x35, 0x02},
449 {0xd9, 0x10},
450 {0x94, 0x11},
451};
452
453static const u8 sensor_init_2[][2] = {
454 {0x3b, 0xc4},
455 {0x1e, 0x04}, /* mvfp */
456 {0x13, 0xe0}, /* com8 */
457 {0x00, 0x00}, /* gain */
458 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
459 {0x11, 0x03}, /* clkrc */
460 {0x6b, 0x5a}, /* dblv */
461 {0x6a, 0x05},
462 {0xc5, 0x07},
463 {0xa2, 0x4b},
464 {0xa3, 0x3e},
465 {0x2d, 0x00},
466 {0xff, 0x42}, /* read 42, write ff 00 */
467 {0x42, 0xc0}, /* com17 */
468 {0x2d, 0x00},
469 {0xff, 0x42}, /* read 42, write ff 00 */
470 {0x42, 0xc1}, /* com17 */
471/* sharpness */
472 {0x3f, 0x01},
473 {0xff, 0x42}, /* read 42, write ff 00 */
474 {0x42, 0xc1}, /* com17 */
475/* saturation */
476 {0x4f, 0x98}, /* matrix */
477 {0x50, 0x98},
478 {0x51, 0x00},
479 {0x52, 0x28},
480 {0x53, 0x70},
481 {0x54, 0x98},
482 {0x58, 0x1a},
483 {0xff, 0x41}, /* read 41, write ff 00 */
484 {0x41, 0x40}, /* com16 */
485/* contrast */
486 {0x56, 0x40},
487/* brightness */
488 {0x55, 0x8f},
489/* expo */
490 {0x10, 0x25}, /* aech - exposure high bits */
491 {0xff, 0x13}, /* read 13, write ff 00 */
492 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
493};
494
495static const u8 sensor_start_1_vga[][2] = { /* same for qvga */
496 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
497 {0x36, 0xfa}, /* aref3 */
498 {0x69, 0x0a}, /* hv */
499 {0x8c, 0x89}, /* com22 */
500 {0x14, 0x28}, /* com9 */
501 {0x3e, 0x0c}, /* com14 */
502 {0x41, 0x40}, /* com16 */
503 {0x72, 0x00},
504 {0x73, 0x00},
505 {0x74, 0x3a},
506 {0x75, 0x35},
507 {0x76, 0x01},
508 {0xc7, 0x80}, /* com24 */
509 {0x03, 0x12}, /* vref */
510 {0x17, 0x16}, /* hstart */
511 {0x18, 0x02}, /* hstop */
512 {0x19, 0x01}, /* vstrt */
513 {0x1a, 0x3d}, /* vstop */
514 {0x32, 0xff}, /* href */
515 {0xc0, 0xaa},
516};
517
518static const u8 sensor_start_1_svga[][2] = {
519 {0x12, 0x02}, /* com7 - YUYV - VGA 15 full resolution */
520 {0x36, 0xf8}, /* aref3 */
521 {0x69, 0x02}, /* hv */
522 {0x8c, 0x0d}, /* com22 */
523 {0x3e, 0x0c}, /* com14 */
524 {0x41, 0x40}, /* com16 */
525 {0x72, 0x00},
526 {0x73, 0x01},
527 {0x74, 0x3a},
528 {0x75, 0x35},
529 {0x76, 0x01},
530 {0xc7, 0x80}, /* com24 */
531 {0x03, 0x1b}, /* vref */
532 {0x17, 0x1d}, /* hstart */
533 {0x18, 0xbd}, /* hstop */
534 {0x19, 0x01}, /* vstrt */
535 {0x1a, 0x81}, /* vstop */
536 {0x32, 0xff}, /* href */
537 {0xc0, 0xe2},
538};
539
540static const u8 sensor_start_1_xga[][2] = {
541 {0x12, 0x02}, /* com7 */
542 {0x36, 0xf8}, /* aref3 */
543 {0x69, 0x02}, /* hv */
544 {0x8c, 0x89}, /* com22 */
545 {0x14, 0x28}, /* com9 */
546 {0x3e, 0x0c}, /* com14 */
547 {0x41, 0x40}, /* com16 */
548 {0x72, 0x00},
549 {0x73, 0x01},
550 {0x74, 0x3a},
551 {0x75, 0x35},
552 {0x76, 0x01},
553 {0xc7, 0x80}, /* com24 */
554 {0x03, 0x1b}, /* vref */
555 {0x17, 0x1d}, /* hstart */
556 {0x18, 0xbd}, /* hstop */
557 {0x19, 0x01}, /* vstrt */
558 {0x1a, 0x81}, /* vstop */
559 {0x32, 0xff}, /* href */
560 {0xc0, 0xe2},
561};
562
563static const u8 sensor_start_1_sxga[][2] = {
564 {0x12, 0x02}, /* com7 */
565 {0x36, 0xf8}, /* aref3 */
566 {0x69, 0x02}, /* hv */
567 {0x8c, 0x89}, /* com22 */
568 {0x14, 0x28}, /* com9 */
569 {0x3e, 0x0c}, /* com14 */
570 {0x41, 0x40}, /* com16 */
571 {0x72, 0x00},
572 {0x73, 0x01},
573 {0x74, 0x3a},
574 {0x75, 0x35},
575 {0x76, 0x01},
576 {0xc7, 0x80}, /* com24 */
577 {0x03, 0x1b}, /* vref */
578 {0x17, 0x1d}, /* hstart */
579 {0x18, 0x02}, /* hstop */
580 {0x19, 0x01}, /* vstrt */
581 {0x1a, 0x81}, /* vstop */
582 {0x32, 0xff}, /* href */
583 {0xc0, 0xe2},
584};
585
586static const u8 bridge_start_qvga[][2] = {
587 {0x94, 0xaa},
588 {0xf1, 0x60},
589 {0xe5, 0x04},
590 {0xc0, 0x50},
591 {0xc1, 0x3c},
592 {0x8c, 0x00},
593 {0x8d, 0x1c},
594 {0x34, 0x05},
595
596 {0xc2, 0x4c},
597 {0xc3, 0xf9},
598 {0xda, 0x00},
599 {0x50, 0x00},
600 {0x51, 0xa0},
601 {0x52, 0x78},
602 {0x53, 0x00},
603 {0x54, 0x00},
604 {0x55, 0x00},
605 {0x57, 0x00},
606 {0x5c, 0x00},
607 {0x5a, 0x50},
608 {0x5b, 0x3c},
609 {0x35, 0x02},
610 {0xd9, 0x10},
611 {0x94, 0x11},
612};
613
614static const u8 bridge_start_vga[][2] = {
615 {0x94, 0xaa},
616 {0xf1, 0x60},
617 {0xe5, 0x04},
618 {0xc0, 0x50},
619 {0xc1, 0x3c},
620 {0x8c, 0x00},
621 {0x8d, 0x1c},
622 {0x34, 0x05},
623 {0xc2, 0x0c},
624 {0xc3, 0xf9},
625 {0xda, 0x01},
626 {0x50, 0x00},
627 {0x51, 0xa0},
628 {0x52, 0x3c},
629 {0x53, 0x00},
630 {0x54, 0x00},
631 {0x55, 0x00},
632 {0x57, 0x00},
633 {0x5c, 0x00},
634 {0x5a, 0xa0},
635 {0x5b, 0x78},
636 {0x35, 0x02},
637 {0xd9, 0x10},
638 {0x94, 0x11},
639};
640
641static const u8 bridge_start_svga[][2] = {
642 {0x94, 0xaa},
643 {0xf1, 0x60},
644 {0xe5, 0x04},
645 {0xc0, 0xa0},
646 {0xc1, 0x80},
647 {0x8c, 0x00},
648 {0x8d, 0x1c},
649 {0x34, 0x05},
650 {0xc2, 0x4c},
651 {0xc3, 0xf9},
652 {0x50, 0x00},
653 {0x51, 0x40},
654 {0x52, 0x00},
655 {0x53, 0x00},
656 {0x54, 0x00},
657 {0x55, 0x88},
658 {0x57, 0x00},
659 {0x5c, 0x00},
660 {0x5a, 0xc8},
661 {0x5b, 0x96},
662 {0x35, 0x02},
663 {0xd9, 0x10},
664 {0xda, 0x00},
665 {0x94, 0x11},
666};
667
668static const u8 bridge_start_xga[][2] = {
669 {0x94, 0xaa},
670 {0xf1, 0x60},
671 {0xe5, 0x04},
672 {0xc0, 0xa0},
673 {0xc1, 0x80},
674 {0x8c, 0x00},
675 {0x8d, 0x1c},
676 {0x34, 0x05},
677 {0xc2, 0x4c},
678 {0xc3, 0xf9},
679 {0x50, 0x00},
680 {0x51, 0x40},
681 {0x52, 0x00},
682 {0x53, 0x00},
683 {0x54, 0x00},
684 {0x55, 0x88},
685 {0x57, 0x00},
686 {0x5c, 0x01},
687 {0x5a, 0x00},
688 {0x5b, 0xc0},
689 {0x35, 0x02},
690 {0xd9, 0x10},
691 {0xda, 0x01},
692 {0x94, 0x11},
693};
694
695static const u8 bridge_start_sxga[][2] = {
696 {0x94, 0xaa},
697 {0xf1, 0x60},
698 {0xe5, 0x04},
699 {0xc0, 0xa0},
700 {0xc1, 0x80},
701 {0x8c, 0x00},
702 {0x8d, 0x1c},
703 {0x34, 0x05},
704 {0xc2, 0x0c},
705 {0xc3, 0xf9},
706 {0xda, 0x00},
707 {0x35, 0x02},
708 {0xd9, 0x10},
709 {0x94, 0x11},
710};
711
712static const u8 sensor_start_2_qvga[][2] = {
713 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */
714 {0x1e, 0x04}, /* mvfp */
715 {0x13, 0xe0}, /* com8 */
716 {0x00, 0x00},
717 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
718 {0x11, 0x01}, /* clkrc */
719 {0x6b, 0x5a}, /* dblv */
720 {0x6a, 0x02}, /* 50 Hz banding filter */
721 {0xc5, 0x03}, /* 60 Hz banding filter */
722 {0xa2, 0x96}, /* bd50 */
723 {0xa3, 0x7d}, /* bd60 */
724
725 {0xff, 0x13}, /* read 13, write ff 00 */
726 {0x13, 0xe7},
727 {0x3a, 0x80}, /* tslb - yuyv */
728};
729
730static const u8 sensor_start_2_vga[][2] = {
731 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
732 {0x1e, 0x04}, /* mvfp */
733 {0x13, 0xe0}, /* com8 */
734 {0x00, 0x00},
735 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
736 {0x11, 0x03}, /* clkrc */
737 {0x6b, 0x5a}, /* dblv */
738 {0x6a, 0x05}, /* 50 Hz banding filter */
739 {0xc5, 0x07}, /* 60 Hz banding filter */
740 {0xa2, 0x4b}, /* bd50 */
741 {0xa3, 0x3e}, /* bd60 */
742
743 {0x2d, 0x00}, /* advfl */
744};
745
746static const u8 sensor_start_2_svga[][2] = { /* same for xga */
747 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
748 {0x1e, 0x04}, /* mvfp */
749 {0x13, 0xe0}, /* com8 */
750 {0x00, 0x00},
751 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
752 {0x11, 0x01}, /* clkrc */
753 {0x6b, 0x5a}, /* dblv */
754 {0x6a, 0x0c}, /* 50 Hz banding filter */
755 {0xc5, 0x0f}, /* 60 Hz banding filter */
756 {0xa2, 0x4e}, /* bd50 */
757 {0xa3, 0x41}, /* bd60 */
758};
759
760static const u8 sensor_start_2_sxga[][2] = {
761 {0x13, 0xe0}, /* com8 */
762 {0x00, 0x00},
763 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
764 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
765 {0x1e, 0x04}, /* mvfp */
766 {0x11, 0x01}, /* clkrc */
767 {0x6b, 0x5a}, /* dblv */
768 {0x6a, 0x0c}, /* 50 Hz banding filter */
769 {0xc5, 0x0f}, /* 60 Hz banding filter */
770 {0xa2, 0x4e}, /* bd50 */
771 {0xa3, 0x41}, /* bd60 */
772};
773
774static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val)
775{
776 struct usb_device *udev = gspca_dev->dev;
777 int ret;
778
779 if (gspca_dev->usb_err < 0)
780 return;
781 gspca_dev->usb_buf[0] = val;
782 ret = usb_control_msg(udev,
783 usb_sndctrlpipe(udev, 0),
784 0x01,
785 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
786 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
787 if (ret < 0) {
788 PDEBUG(D_ERR, "reg_w failed %d", ret);
789 gspca_dev->usb_err = ret;
790 }
791}
792
793static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val)
794{
795 PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val);
796 reg_w_i(gspca_dev, reg, val);
797}
798
799static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
800{
801 struct usb_device *udev = gspca_dev->dev;
802 int ret;
803
804 if (gspca_dev->usb_err < 0)
805 return 0;
806 ret = usb_control_msg(udev,
807 usb_rcvctrlpipe(udev, 0),
808 0x01,
809 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
810 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
811 PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]);
812 if (ret < 0) {
813 PDEBUG(D_ERR, "reg_r err %d", ret);
814 gspca_dev->usb_err = ret;
815 }
816 return gspca_dev->usb_buf[0];
817}
818
819static int sccb_check_status(struct gspca_dev *gspca_dev)
820{
821 u8 data;
822 int i;
823
824 for (i = 0; i < 5; i++) {
825 data = reg_r(gspca_dev, OV534_REG_STATUS);
826
827 switch (data) {
828 case 0x00:
829 return 1;
830 case 0x04:
831 return 0;
832 case 0x03:
833 break;
834 default:
835 PDEBUG(D_USBI|D_USBO,
836 "sccb status 0x%02x, attempt %d/5",
837 data, i + 1);
838 }
839 }
840 return 0;
841}
842
843static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
844{
845 PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val);
846 reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg);
847 reg_w_i(gspca_dev, OV534_REG_WRITE, val);
848 reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
849
850 if (!sccb_check_status(gspca_dev))
851 PDEBUG(D_ERR, "sccb_write failed");
852}
853
854static u8 sccb_read(struct gspca_dev *gspca_dev, u16 reg)
855{
856 reg_w(gspca_dev, OV534_REG_SUBADDR, reg);
857 reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
858 if (!sccb_check_status(gspca_dev))
859 PDEBUG(D_ERR, "sccb_read failed 1");
860
861 reg_w(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
862 if (!sccb_check_status(gspca_dev))
863 PDEBUG(D_ERR, "sccb_read failed 2");
864
865 return reg_r(gspca_dev, OV534_REG_READ);
866}
867
868/* output a bridge sequence (reg - val) */
869static void reg_w_array(struct gspca_dev *gspca_dev,
870 const u8 (*data)[2], int len)
871{
872 while (--len >= 0) {
873 reg_w(gspca_dev, (*data)[0], (*data)[1]);
874 data++;
875 }
876}
877
878/* output a sensor sequence (reg - val) */
879static void sccb_w_array(struct gspca_dev *gspca_dev,
880 const u8 (*data)[2], int len)
881{
882 while (--len >= 0) {
883 if ((*data)[0] != 0xff) {
884 sccb_write(gspca_dev, (*data)[0], (*data)[1]);
885 } else {
886 sccb_read(gspca_dev, (*data)[1]);
887 sccb_write(gspca_dev, 0xff, 0x00);
888 }
889 data++;
890 }
891}
892
893/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
894 * (direction and output)? */
895static void set_led(struct gspca_dev *gspca_dev, int status)
896{
897 u8 data;
898
899 PDEBUG(D_CONF, "led status: %d", status);
900
901 data = reg_r(gspca_dev, 0x21);
902 data |= 0x80;
903 reg_w(gspca_dev, 0x21, data);
904
905 data = reg_r(gspca_dev, 0x23);
906 if (status)
907 data |= 0x80;
908 else
909 data &= ~0x80;
910
911 reg_w(gspca_dev, 0x23, data);
912
913 if (!status) {
914 data = reg_r(gspca_dev, 0x21);
915 data &= ~0x80;
916 reg_w(gspca_dev, 0x21, data);
917 }
918}
919
920static void setbrightness(struct gspca_dev *gspca_dev)
921{
922 struct sd *sd = (struct sd *) gspca_dev;
923 u8 val;
924
925 val = sd->brightness;
926 if (val < 8)
927 val = 15 - val; /* f .. 8 */
928 else
929 val = val - 8; /* 0 .. 7 */
930 sccb_write(gspca_dev, 0x55, /* brtn - brightness adjustment */
931 0x0f | (val << 4));
932}
933
934static void setcontrast(struct gspca_dev *gspca_dev)
935{
936 struct sd *sd = (struct sd *) gspca_dev;
937
938 sccb_write(gspca_dev, 0x56, /* cnst1 - contrast 1 ctrl coeff */
939 sd->contrast << 4);
940}
941
942static void setautogain(struct gspca_dev *gspca_dev)
943{
944 struct sd *sd = (struct sd *) gspca_dev;
945 u8 val;
946
947/*fixme: should adjust agc/awb/aec by different controls */
948 val = sd->autogain;
949 val = sccb_read(gspca_dev, 0x13); /* com8 */
950 sccb_write(gspca_dev, 0xff, 0x00);
951 if (sd->autogain)
952 val |= 0x05; /* agc & aec */
953 else
954 val &= 0xfa;
955 sccb_write(gspca_dev, 0x13, val);
956}
957
958static void setexposure(struct gspca_dev *gspca_dev)
959{
960 struct sd *sd = (struct sd *) gspca_dev;
961 u8 val;
962 static const u8 expo[4] = {0x00, 0x25, 0x38, 0x5e};
963
964 sccb_write(gspca_dev, 0x10, /* aec[9:2] */
965 expo[sd->exposure]);
966
967 val = sccb_read(gspca_dev, 0x13); /* com8 */
968 sccb_write(gspca_dev, 0xff, 0x00);
969 sccb_write(gspca_dev, 0x13, val);
970
971 val = sccb_read(gspca_dev, 0xa1); /* aech */
972 sccb_write(gspca_dev, 0xff, 0x00);
973 sccb_write(gspca_dev, 0xa1, val & 0xe0); /* aec[15:10] = 0 */
974}
975
976static void setsharpness(struct gspca_dev *gspca_dev)
977{
978 struct sd *sd = (struct sd *) gspca_dev;
979 s8 val;
980
981 val = sd->sharpness;
982 if (val < 0) { /* auto */
983 val = sccb_read(gspca_dev, 0x42); /* com17 */
984 sccb_write(gspca_dev, 0xff, 0x00);
985 sccb_write(gspca_dev, 0x42, val | 0x40);
986 /* Edge enhancement strength auto adjust */
987 return;
988 }
989 if (val != 0)
990 val = 1 << (val - 1);
991 sccb_write(gspca_dev, 0x3f, /* edge - edge enhance. factor */
992 val);
993 val = sccb_read(gspca_dev, 0x42); /* com17 */
994 sccb_write(gspca_dev, 0xff, 0x00);
995 sccb_write(gspca_dev, 0x42, val & 0xbf);
996}
997
998static void setsatur(struct gspca_dev *gspca_dev)
999{
1000 struct sd *sd = (struct sd *) gspca_dev;
1001 u8 val1, val2, val3;
1002 static const u8 matrix[5][2] = {
1003 {0x14, 0x38},
1004 {0x1e, 0x54},
1005 {0x28, 0x70},
1006 {0x32, 0x8c},
1007 {0x48, 0x90}
1008 };
1009
1010 val1 = matrix[sd->satur][0];
1011 val2 = matrix[sd->satur][1];
1012 val3 = val1 + val2;
1013 sccb_write(gspca_dev, 0x4f, val3); /* matrix coeff */
1014 sccb_write(gspca_dev, 0x50, val3);
1015 sccb_write(gspca_dev, 0x51, 0x00);
1016 sccb_write(gspca_dev, 0x52, val1);
1017 sccb_write(gspca_dev, 0x53, val2);
1018 sccb_write(gspca_dev, 0x54, val3);
1019 sccb_write(gspca_dev, 0x58, 0x1a); /* mtxs - coeff signs */
1020
1021 val1 = sccb_read(gspca_dev, 0x41); /* com16 */
1022 sccb_write(gspca_dev, 0xff, 0x00);
1023 sccb_write(gspca_dev, 0x41, val1);
1024}
1025
1026static void setfreq(struct gspca_dev *gspca_dev)
1027{
1028 struct sd *sd = (struct sd *) gspca_dev;
1029 u8 val;
1030
1031 val = sccb_read(gspca_dev, 0x13); /* com8 */
1032 sccb_write(gspca_dev, 0xff, 0x00);
1033 if (sd->freq == 0) {
1034 sccb_write(gspca_dev, 0x13, val & 0xdf);
1035 return;
1036 }
1037 sccb_write(gspca_dev, 0x13, val | 0x20);
1038
1039 val = sccb_read(gspca_dev, 0x42); /* com17 */
1040 sccb_write(gspca_dev, 0xff, 0x00);
1041 if (sd->freq == 1)
1042 val |= 0x01;
1043 else
1044 val &= 0xfe;
1045 sccb_write(gspca_dev, 0x42, val);
1046}
1047
1048/* this function is called at probe time */
1049static int sd_config(struct gspca_dev *gspca_dev,
1050 const struct usb_device_id *id)
1051{
1052 struct sd *sd = (struct sd *) gspca_dev;
1053 struct cam *cam;
1054
1055 cam = &gspca_dev->cam;
1056
1057 cam->cam_mode = ov965x_mode;
1058 cam->nmodes = ARRAY_SIZE(ov965x_mode);
1059
1060 sd->brightness = BRIGHTNESS_DEF;
1061 sd->contrast = CONTRAST_DEF;
1062#if AUTOGAIN_DEF != 0
1063 sd->autogain = AUTOGAIN_DEF;
1064 gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
1065#endif
1066#if EXPO_DEF != 0
1067 sd->exposure = EXPO_DEF;
1068#endif
1069#if SHARPNESS_DEF != 0
1070 sd->sharpness = SHARPNESS_DEF;
1071#endif
1072 sd->satur = SATUR_DEF;
1073 sd->freq = FREQ_DEF;
1074
1075 return 0;
1076}
1077
1078/* this function is called at probe and resume time */
1079static int sd_init(struct gspca_dev *gspca_dev)
1080{
1081 u16 sensor_id;
1082
1083 /* reset bridge */
1084 reg_w(gspca_dev, 0xe7, 0x3a);
1085 reg_w(gspca_dev, 0xe0, 0x08);
1086 msleep(100);
1087
1088 /* initialize the sensor address */
1089 reg_w(gspca_dev, OV534_REG_ADDRESS, 0x60);
1090
1091 /* reset sensor */
1092 sccb_write(gspca_dev, 0x12, 0x80);
1093 msleep(10);
1094
1095 /* probe the sensor */
1096 sccb_read(gspca_dev, 0x0a);
1097 sensor_id = sccb_read(gspca_dev, 0x0a) << 8;
1098 sccb_read(gspca_dev, 0x0b);
1099 sensor_id |= sccb_read(gspca_dev, 0x0b);
1100 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1101
1102 /* initialize */
1103 reg_w_array(gspca_dev, bridge_init,
1104 ARRAY_SIZE(bridge_init));
1105 sccb_w_array(gspca_dev, sensor_init,
1106 ARRAY_SIZE(sensor_init));
1107 reg_w_array(gspca_dev, bridge_init_2,
1108 ARRAY_SIZE(bridge_init_2));
1109 sccb_w_array(gspca_dev, sensor_init_2,
1110 ARRAY_SIZE(sensor_init_2));
1111 reg_w(gspca_dev, 0xe0, 0x00);
1112 reg_w(gspca_dev, 0xe0, 0x01);
1113 set_led(gspca_dev, 0);
1114 reg_w(gspca_dev, 0xe0, 0x00);
1115
1116 return 0;
1117}
1118
1119static int sd_start(struct gspca_dev *gspca_dev)
1120{
1121 switch (gspca_dev->curr_mode) {
1122 case QVGA_MODE: /* 320x240 */
1123 sccb_w_array(gspca_dev, sensor_start_1_vga,
1124 ARRAY_SIZE(sensor_start_1_vga));
1125 reg_w_array(gspca_dev, bridge_start_qvga,
1126 ARRAY_SIZE(bridge_start_qvga));
1127 sccb_w_array(gspca_dev, sensor_start_2_qvga,
1128 ARRAY_SIZE(sensor_start_2_qvga));
1129 break;
1130 case VGA_MODE: /* 640x480 */
1131 sccb_w_array(gspca_dev, sensor_start_1_vga,
1132 ARRAY_SIZE(sensor_start_1_vga));
1133 reg_w_array(gspca_dev, bridge_start_vga,
1134 ARRAY_SIZE(bridge_start_vga));
1135 sccb_w_array(gspca_dev, sensor_start_2_vga,
1136 ARRAY_SIZE(sensor_start_2_vga));
1137 break;
1138 case SVGA_MODE: /* 800x600 */
1139 sccb_w_array(gspca_dev, sensor_start_1_svga,
1140 ARRAY_SIZE(sensor_start_1_svga));
1141 reg_w_array(gspca_dev, bridge_start_svga,
1142 ARRAY_SIZE(bridge_start_svga));
1143 sccb_w_array(gspca_dev, sensor_start_2_svga,
1144 ARRAY_SIZE(sensor_start_2_svga));
1145 break;
1146 case XGA_MODE: /* 1024x768 */
1147 sccb_w_array(gspca_dev, sensor_start_1_xga,
1148 ARRAY_SIZE(sensor_start_1_xga));
1149 reg_w_array(gspca_dev, bridge_start_xga,
1150 ARRAY_SIZE(bridge_start_xga));
1151 sccb_w_array(gspca_dev, sensor_start_2_svga,
1152 ARRAY_SIZE(sensor_start_2_svga));
1153 break;
1154 default:
1155/* case SXGA_MODE: * 1280x1024 */
1156 sccb_w_array(gspca_dev, sensor_start_1_sxga,
1157 ARRAY_SIZE(sensor_start_1_sxga));
1158 reg_w_array(gspca_dev, bridge_start_sxga,
1159 ARRAY_SIZE(bridge_start_sxga));
1160 sccb_w_array(gspca_dev, sensor_start_2_sxga,
1161 ARRAY_SIZE(sensor_start_2_sxga));
1162 break;
1163 }
1164 setfreq(gspca_dev);
1165 setautogain(gspca_dev);
1166 setbrightness(gspca_dev);
1167 setcontrast(gspca_dev);
1168 setexposure(gspca_dev);
1169 setsharpness(gspca_dev);
1170 setsatur(gspca_dev);
1171
1172 reg_w(gspca_dev, 0xe0, 0x00);
1173 reg_w(gspca_dev, 0xe0, 0x00);
1174 set_led(gspca_dev, 1);
1175 return 0;
1176}
1177
1178static void sd_stopN(struct gspca_dev *gspca_dev)
1179{
1180 reg_w(gspca_dev, 0xe0, 0x01);
1181 set_led(gspca_dev, 0);
1182 reg_w(gspca_dev, 0xe0, 0x00);
1183}
1184
1185/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1186#define UVC_STREAM_EOH (1 << 7)
1187#define UVC_STREAM_ERR (1 << 6)
1188#define UVC_STREAM_STI (1 << 5)
1189#define UVC_STREAM_RES (1 << 4)
1190#define UVC_STREAM_SCR (1 << 3)
1191#define UVC_STREAM_PTS (1 << 2)
1192#define UVC_STREAM_EOF (1 << 1)
1193#define UVC_STREAM_FID (1 << 0)
1194
1195static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1196 u8 *data, int len)
1197{
1198 struct sd *sd = (struct sd *) gspca_dev;
1199 __u32 this_pts;
1200 u8 this_fid;
1201 int remaining_len = len;
1202
1203 do {
1204 len = min(remaining_len, 2040);
1205
1206 /* Payloads are prefixed with a UVC-style header. We
1207 consider a frame to start when the FID toggles, or the PTS
1208 changes. A frame ends when EOF is set, and we've received
1209 the correct number of bytes. */
1210
1211 /* Verify UVC header. Header length is always 12 */
1212 if (data[0] != 12 || len < 12) {
1213 PDEBUG(D_PACK, "bad header");
1214 goto discard;
1215 }
1216
1217 /* Check errors */
1218 if (data[1] & UVC_STREAM_ERR) {
1219 PDEBUG(D_PACK, "payload error");
1220 goto discard;
1221 }
1222
1223 /* Extract PTS and FID */
1224 if (!(data[1] & UVC_STREAM_PTS)) {
1225 PDEBUG(D_PACK, "PTS not present");
1226 goto discard;
1227 }
1228 this_pts = (data[5] << 24) | (data[4] << 16)
1229 | (data[3] << 8) | data[2];
1230 this_fid = data[1] & UVC_STREAM_FID;
1231
1232 /* If PTS or FID has changed, start a new frame. */
1233 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
1234 if (gspca_dev->last_packet_type == INTER_PACKET)
1235 gspca_frame_add(gspca_dev, LAST_PACKET,
1236 NULL, 0);
1237 sd->last_pts = this_pts;
1238 sd->last_fid = this_fid;
1239 gspca_frame_add(gspca_dev, FIRST_PACKET,
1240 data + 12, len - 12);
1241 /* If this packet is marked as EOF, end the frame */
1242 } else if (data[1] & UVC_STREAM_EOF) {
1243 sd->last_pts = 0;
1244 gspca_frame_add(gspca_dev, LAST_PACKET,
1245 data + 12, len - 12);
1246 } else {
1247
1248 /* Add the data from this payload */
1249 gspca_frame_add(gspca_dev, INTER_PACKET,
1250 data + 12, len - 12);
1251 }
1252
1253 /* Done this payload */
1254 goto scan_next;
1255
1256discard:
1257 /* Discard data until a new frame starts. */
1258 gspca_dev->last_packet_type = DISCARD_PACKET;
1259
1260scan_next:
1261 remaining_len -= len;
1262 data += len;
1263 } while (remaining_len > 0);
1264}
1265
1266/* controls */
1267static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1268{
1269 struct sd *sd = (struct sd *) gspca_dev;
1270
1271 sd->brightness = val;
1272 if (gspca_dev->streaming)
1273 setbrightness(gspca_dev);
1274 return 0;
1275}
1276
1277static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1278{
1279 struct sd *sd = (struct sd *) gspca_dev;
1280
1281 *val = sd->brightness;
1282 return 0;
1283}
1284
1285static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1286{
1287 struct sd *sd = (struct sd *) gspca_dev;
1288
1289 sd->contrast = val;
1290 if (gspca_dev->streaming)
1291 setcontrast(gspca_dev);
1292 return 0;
1293}
1294
1295static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1296{
1297 struct sd *sd = (struct sd *) gspca_dev;
1298
1299 *val = sd->contrast;
1300 return 0;
1301}
1302
1303static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1304{
1305 struct sd *sd = (struct sd *) gspca_dev;
1306
1307 sd->autogain = val;
1308
1309 if (gspca_dev->streaming) {
1310 if (val)
1311 gspca_dev->ctrl_inac |= (1 << EXPO_IDX);
1312 else
1313 gspca_dev->ctrl_inac &= ~(1 << EXPO_IDX);
1314 setautogain(gspca_dev);
1315 }
1316 return 0;
1317}
1318
1319static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1320{
1321 struct sd *sd = (struct sd *) gspca_dev;
1322
1323 *val = sd->autogain;
1324 return 0;
1325}
1326
1327static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1328{
1329 struct sd *sd = (struct sd *) gspca_dev;
1330
1331 sd->exposure = val;
1332 if (gspca_dev->streaming)
1333 setexposure(gspca_dev);
1334 return 0;
1335}
1336
1337static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1338{
1339 struct sd *sd = (struct sd *) gspca_dev;
1340
1341 *val = sd->exposure;
1342 return 0;
1343}
1344
1345static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1346{
1347 struct sd *sd = (struct sd *) gspca_dev;
1348
1349 sd->sharpness = val;
1350 if (gspca_dev->streaming)
1351 setsharpness(gspca_dev);
1352 return 0;
1353}
1354
1355static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1356{
1357 struct sd *sd = (struct sd *) gspca_dev;
1358
1359 *val = sd->sharpness;
1360 return 0;
1361}
1362
1363static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val)
1364{
1365 struct sd *sd = (struct sd *) gspca_dev;
1366
1367 sd->satur = val;
1368 if (gspca_dev->streaming)
1369 setsatur(gspca_dev);
1370 return 0;
1371}
1372
1373static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val)
1374{
1375 struct sd *sd = (struct sd *) gspca_dev;
1376
1377 *val = sd->satur;
1378 return 0;
1379}
1380static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1381{
1382 struct sd *sd = (struct sd *) gspca_dev;
1383
1384 sd->freq = val;
1385 if (gspca_dev->streaming)
1386 setfreq(gspca_dev);
1387 return 0;
1388}
1389
1390static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1391{
1392 struct sd *sd = (struct sd *) gspca_dev;
1393
1394 *val = sd->freq;
1395 return 0;
1396}
1397
1398static int sd_querymenu(struct gspca_dev *gspca_dev,
1399 struct v4l2_querymenu *menu)
1400{
1401 switch (menu->id) {
1402 case V4L2_CID_POWER_LINE_FREQUENCY:
1403 switch (menu->index) {
1404 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1405 strcpy((char *) menu->name, "NoFliker");
1406 return 0;
1407 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1408 strcpy((char *) menu->name, "50 Hz");
1409 return 0;
1410 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1411 strcpy((char *) menu->name, "60 Hz");
1412 return 0;
1413 }
1414 break;
1415 }
1416 return -EINVAL;
1417}
1418
1419/* sub-driver description */
1420static const struct sd_desc sd_desc = {
1421 .name = MODULE_NAME,
1422 .ctrls = sd_ctrls,
1423 .nctrls = ARRAY_SIZE(sd_ctrls),
1424 .config = sd_config,
1425 .init = sd_init,
1426 .start = sd_start,
1427 .stopN = sd_stopN,
1428 .pkt_scan = sd_pkt_scan,
1429 .querymenu = sd_querymenu,
1430};
1431
1432/* -- module initialisation -- */
1433static const __devinitdata struct usb_device_id device_table[] = {
1434 {USB_DEVICE(0x06f8, 0x3003)},
1435 {}
1436};
1437
1438MODULE_DEVICE_TABLE(usb, device_table);
1439
1440/* -- device connect -- */
1441static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1442{
1443 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1444 THIS_MODULE);
1445}
1446
1447static struct usb_driver sd_driver = {
1448 .name = MODULE_NAME,
1449 .id_table = device_table,
1450 .probe = sd_probe,
1451 .disconnect = gspca_disconnect,
1452#ifdef CONFIG_PM
1453 .suspend = gspca_suspend,
1454 .resume = gspca_resume,
1455#endif
1456};
1457
1458/* -- module insert / remove -- */
1459static int __init sd_mod_init(void)
1460{
1461 int ret;
1462
1463 ret = usb_register(&sd_driver);
1464 if (ret < 0)
1465 return ret;
1466 PDEBUG(D_PROBE, "registered");
1467 return 0;
1468}
1469
1470static void __exit sd_mod_exit(void)
1471{
1472 usb_deregister(&sd_driver);
1473 PDEBUG(D_PROBE, "deregistered");
1474}
1475
1476module_init(sd_mod_init);
1477module_exit(sd_mod_exit);