aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/ov534.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/ov534.c')
-rw-r--r--drivers/media/video/gspca/ov534.c1537
1 files changed, 1393 insertions, 144 deletions
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 4b528b372911..4dbb882c83dc 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * ov534 gspca driver 2 * ov534 gspca driver
3 *
3 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
4 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
5 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr 6 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
@@ -8,6 +9,10 @@
8 * USB protocol reverse engineered by Jim Paris <jim@jtan.com> 9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
9 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ 10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
10 * 11 *
12 * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
13 * PS3 Eye camera, brightness, contrast, hue, AWB control added
14 * by Max Thrun <bear24rw@gmail.com>
15 *
11 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 18 * the Free Software Foundation; either version 2 of the License, or
@@ -51,16 +56,335 @@ struct sd {
51 u16 last_fid; 56 u16 last_fid;
52 u8 frame_rate; 57 u8 frame_rate;
53 58
59 u8 brightness;
60 u8 contrast;
61 u8 gain;
62 u8 exposure;
63 u8 redblc;
64 u8 blueblc;
65 u8 hue;
66 u8 autogain;
67 u8 awb;
68 s8 sharpness;
69 u8 hflip;
70 u8 vflip;
71 u8 satur;
72 u8 lightfreq;
73
54 u8 sensor; 74 u8 sensor;
55#define SENSOR_OV772X 0 75#define SENSOR_OV772X 0
56#define SENSOR_OV965X 1 76#define SENSOR_OV965X 1
57}; 77};
58 78
59/* V4L2 controls supported by the driver */ 79/* V4L2 controls supported by the driver */
60static struct ctrl sd_ctrls[] = { 80static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
84static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val);
86static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
90static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
94static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
96static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
98static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
100static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
102static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
103static 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
109static struct ctrl sd_ctrls_ov772x[] = {
110 { /* 0 */
111 {
112 .id = V4L2_CID_BRIGHTNESS,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "Brightness",
115 .minimum = 0,
116 .maximum = 255,
117 .step = 1,
118#define BRIGHTNESS_77_DEF 20
119 .default_value = BRIGHTNESS_77_DEF,
120 },
121 .set = sd_setbrightness,
122 .get = sd_getbrightness,
123 },
124 { /* 1 */
125 {
126 .id = V4L2_CID_CONTRAST,
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Contrast",
129 .minimum = 0,
130 .maximum = 255,
131 .step = 1,
132#define CONTRAST_77_DEF 37
133 .default_value = CONTRAST_77_DEF,
134 },
135 .set = sd_setcontrast,
136 .get = sd_getcontrast,
137 },
138 { /* 2 */
139 {
140 .id = V4L2_CID_GAIN,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Main Gain",
143 .minimum = 0,
144 .maximum = 63,
145 .step = 1,
146#define GAIN_DEF 20
147 .default_value = GAIN_DEF,
148 },
149 .set = sd_setgain,
150 .get = sd_getgain,
151 },
152 { /* 3 */
153 {
154 .id = V4L2_CID_EXPOSURE,
155 .type = V4L2_CTRL_TYPE_INTEGER,
156 .name = "Exposure",
157 .minimum = 0,
158 .maximum = 255,
159 .step = 1,
160#define EXPO_77_DEF 120
161 .default_value = EXPO_77_DEF,
162 },
163 .set = sd_setexposure,
164 .get = sd_getexposure,
165 },
166 { /* 4 */
167 {
168 .id = V4L2_CID_RED_BALANCE,
169 .type = V4L2_CTRL_TYPE_INTEGER,
170 .name = "Red Balance",
171 .minimum = 0,
172 .maximum = 255,
173 .step = 1,
174#define RED_BALANCE_DEF 128
175 .default_value = RED_BALANCE_DEF,
176 },
177 .set = sd_setredblc,
178 .get = sd_getredblc,
179 },
180 { /* 5 */
181 {
182 .id = V4L2_CID_BLUE_BALANCE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "Blue Balance",
185 .minimum = 0,
186 .maximum = 255,
187 .step = 1,
188#define BLUE_BALANCE_DEF 128
189 .default_value = BLUE_BALANCE_DEF,
190 },
191 .set = sd_setblueblc,
192 .get = sd_getblueblc,
193 },
194 { /* 6 */
195 {
196 .id = V4L2_CID_HUE,
197 .type = V4L2_CTRL_TYPE_INTEGER,
198 .name = "Hue",
199 .minimum = 0,
200 .maximum = 255,
201 .step = 1,
202#define HUE_DEF 143
203 .default_value = HUE_DEF,
204 },
205 .set = sd_sethue,
206 .get = sd_gethue,
207 },
208 { /* 7 */
209 {
210 .id = V4L2_CID_AUTOGAIN,
211 .type = V4L2_CTRL_TYPE_BOOLEAN,
212 .name = "Autogain",
213 .minimum = 0,
214 .maximum = 1,
215 .step = 1,
216#define AUTOGAIN_77_DEF 0
217 .default_value = AUTOGAIN_77_DEF,
218 },
219 .set = sd_setautogain,
220 .get = sd_getautogain,
221 },
222#define AWB_77_IDX 8
223 { /* 8 */
224 {
225 .id = V4L2_CID_AUTO_WHITE_BALANCE,
226 .type = V4L2_CTRL_TYPE_BOOLEAN,
227 .name = "Auto White Balance",
228 .minimum = 0,
229 .maximum = 1,
230 .step = 1,
231#define AWB_DEF 0
232 .default_value = AWB_DEF,
233 },
234 .set = sd_setawb,
235 .get = sd_getawb,
236 },
237 { /* 9 */
238 {
239 .id = V4L2_CID_SHARPNESS,
240 .type = V4L2_CTRL_TYPE_INTEGER,
241 .name = "Sharpness",
242 .minimum = 0,
243 .maximum = 63,
244 .step = 1,
245#define SHARPNESS_77_DEF 0
246 .default_value = SHARPNESS_77_DEF,
247 },
248 .set = sd_setsharpness,
249 .get = sd_getsharpness,
250 },
251 { /* 10 */
252 {
253 .id = V4L2_CID_HFLIP,
254 .type = V4L2_CTRL_TYPE_BOOLEAN,
255 .name = "HFlip",
256 .minimum = 0,
257 .maximum = 1,
258 .step = 1,
259#define HFLIP_DEF 0
260 .default_value = HFLIP_DEF,
261 },
262 .set = sd_sethflip,
263 .get = sd_gethflip,
264 },
265 { /* 11 */
266 {
267 .id = V4L2_CID_VFLIP,
268 .type = V4L2_CTRL_TYPE_BOOLEAN,
269 .name = "VFlip",
270 .minimum = 0,
271 .maximum = 1,
272 .step = 1,
273#define VFLIP_DEF 0
274 .default_value = VFLIP_DEF,
275 },
276 .set = sd_setvflip,
277 .get = sd_getvflip,
278 },
279};
280static 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 },
61}; 380};
62 381
63static const struct v4l2_pix_format vga_yuyv_mode[] = { 382static const struct v4l2_pix_format ov772x_mode[] = {
383 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
384 .bytesperline = 320 * 2,
385 .sizeimage = 320 * 240 * 2,
386 .colorspace = V4L2_COLORSPACE_SRGB,
387 .priv = 1},
64 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 388 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
65 .bytesperline = 640 * 2, 389 .bytesperline = 640 * 2,
66 .sizeimage = 640 * 480 * 2, 390 .sizeimage = 640 * 480 * 2,
@@ -68,20 +392,35 @@ static const struct v4l2_pix_format vga_yuyv_mode[] = {
68 .priv = 0}, 392 .priv = 0},
69}; 393};
70 394
71static const struct v4l2_pix_format vga_jpeg_mode[] = { 395static const struct v4l2_pix_format ov965x_mode[] = {
72 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 396 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
73 .bytesperline = 320, 397 .bytesperline = 320,
74 .sizeimage = 320 * 240 * 3 / 8 + 590, 398 .sizeimage = 320 * 240 * 3 / 8 + 590,
75 .colorspace = V4L2_COLORSPACE_JPEG, 399 .colorspace = V4L2_COLORSPACE_JPEG,
76 .priv = 1}, 400 .priv = 4},
77 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 401 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
78 .bytesperline = 640, 402 .bytesperline = 640,
79 .sizeimage = 640 * 480 * 3 / 8 + 590, 403 .sizeimage = 640 * 480 * 3 / 8 + 590,
80 .colorspace = V4L2_COLORSPACE_JPEG, 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,
81 .priv = 0}, 420 .priv = 0},
82}; 421};
83 422
84static const u8 bridge_init_ov722x[][2] = { 423static const u8 bridge_init_ov772x[][2] = {
85 { 0xc2, 0x0c }, 424 { 0xc2, 0x0c },
86 { 0x88, 0xf8 }, 425 { 0x88, 0xf8 },
87 { 0xc3, 0x69 }, 426 { 0xc3, 0x69 },
@@ -122,6 +461,7 @@ static const u8 bridge_init_ov722x[][2] = {
122 { 0x1d, 0x40 }, 461 { 0x1d, 0x40 },
123 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ 462 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
124 { 0x1d, 0x00 }, /* payload size */ 463 { 0x1d, 0x00 }, /* payload size */
464
125 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ 465 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
126 { 0x1d, 0x58 }, /* frame size */ 466 { 0x1d, 0x58 }, /* frame size */
127 { 0x1d, 0x00 }, /* frame size */ 467 { 0x1d, 0x00 }, /* frame size */
@@ -138,10 +478,20 @@ static const u8 bridge_init_ov722x[][2] = {
138 { 0xc1, 0x3c }, 478 { 0xc1, 0x3c },
139 { 0xc2, 0x0c }, 479 { 0xc2, 0x0c },
140}; 480};
141 481static const u8 sensor_init_ov772x[][2] = {
142static const u8 sensor_init_ov722x[][2] = {
143 { 0x12, 0x80 }, 482 { 0x12, 0x80 },
144 { 0x11, 0x01 }, 483 { 0x11, 0x01 },
484/*fixme: better have a delay?*/
485 { 0x11, 0x01 },
486 { 0x11, 0x01 },
487 { 0x11, 0x01 },
488 { 0x11, 0x01 },
489 { 0x11, 0x01 },
490 { 0x11, 0x01 },
491 { 0x11, 0x01 },
492 { 0x11, 0x01 },
493 { 0x11, 0x01 },
494 { 0x11, 0x01 },
145 495
146 { 0x3d, 0x03 }, 496 { 0x3d, 0x03 },
147 { 0x17, 0x26 }, 497 { 0x17, 0x26 },
@@ -154,10 +504,10 @@ static const u8 sensor_init_ov722x[][2] = {
154 { 0x65, 0x20 }, 504 { 0x65, 0x20 },
155 { 0x11, 0x01 }, 505 { 0x11, 0x01 },
156 { 0x42, 0x7f }, 506 { 0x42, 0x7f },
157 { 0x63, 0xe0 }, 507 { 0x63, 0xaa }, /* AWB - was e0 */
158 { 0x64, 0xff }, 508 { 0x64, 0xff },
159 { 0x66, 0x00 }, 509 { 0x66, 0x00 },
160 { 0x13, 0xf0 }, 510 { 0x13, 0xf0 }, /* com8 */
161 { 0x0d, 0x41 }, 511 { 0x0d, 0x41 },
162 { 0x0f, 0xc5 }, 512 { 0x0f, 0xc5 },
163 { 0x14, 0x11 }, 513 { 0x14, 0x11 },
@@ -170,7 +520,7 @@ static const u8 sensor_init_ov722x[][2] = {
170 { 0x2a, 0x00 }, 520 { 0x2a, 0x00 },
171 { 0x2b, 0x00 }, 521 { 0x2b, 0x00 },
172 { 0x6b, 0xaa }, 522 { 0x6b, 0xaa },
173 { 0x13, 0xff }, 523 { 0x13, 0xff }, /* AWB */
174 524
175 { 0x90, 0x05 }, 525 { 0x90, 0x05 },
176 { 0x91, 0x01 }, 526 { 0x91, 0x01 },
@@ -218,9 +568,51 @@ static const u8 sensor_init_ov722x[][2] = {
218 { 0x14, 0x41 }, 568 { 0x14, 0x41 },
219 { 0x0e, 0xcd }, 569 { 0x0e, 0xcd },
220 { 0xac, 0xbf }, 570 { 0xac, 0xbf },
221 { 0x8e, 0x00 }, 571 { 0x8e, 0x00 }, /* De-noise threshold */
222 { 0x0c, 0xd0 } 572 { 0x0c, 0xd0 }
223}; 573};
574static const u8 bridge_start_ov772x_vga[][2] = {
575 {0x1c, 0x00},
576 {0x1d, 0x40},
577 {0x1d, 0x02},
578 {0x1d, 0x00},
579 {0x1d, 0x02},
580 {0x1d, 0x58},
581 {0x1d, 0x00},
582 {0xc0, 0x50},
583 {0xc1, 0x3c},
584};
585static const u8 sensor_start_ov772x_vga[][2] = {
586 {0x12, 0x00},
587 {0x17, 0x26},
588 {0x18, 0xa0},
589 {0x19, 0x07},
590 {0x1a, 0xf0},
591 {0x29, 0xa0},
592 {0x2c, 0xf0},
593 {0x65, 0x20},
594};
595static const u8 bridge_start_ov772x_qvga[][2] = {
596 {0x1c, 0x00},
597 {0x1d, 0x40},
598 {0x1d, 0x02},
599 {0x1d, 0x00},
600 {0x1d, 0x01},
601 {0x1d, 0x4b},
602 {0x1d, 0x00},
603 {0xc0, 0x28},
604 {0xc1, 0x1e},
605};
606static const u8 sensor_start_ov772x_qvga[][2] = {
607 {0x12, 0x40},
608 {0x17, 0x3f},
609 {0x18, 0x50},
610 {0x19, 0x03},
611 {0x1a, 0x78},
612 {0x29, 0x50},
613 {0x2c, 0x78},
614 {0x65, 0x2f},
615};
224 616
225static const u8 bridge_init_ov965x[][2] = { 617static const u8 bridge_init_ov965x[][2] = {
226 {0x88, 0xf8}, 618 {0x88, 0xf8},
@@ -403,7 +795,7 @@ static const u8 sensor_init_ov965x[][2] = {
403 {0xcb, 0xf0}, 795 {0xcb, 0xf0},
404 {0xcc, 0xd8}, 796 {0xcc, 0xd8},
405 {0xcd, 0xf1}, 797 {0xcd, 0xf1},
406 {0x4f, 0x98}, 798 {0x4f, 0x98}, /* matrix */
407 {0x50, 0x98}, 799 {0x50, 0x98},
408 {0x51, 0x00}, 800 {0x51, 0x00},
409 {0x52, 0x28}, 801 {0x52, 0x28},
@@ -412,6 +804,7 @@ static const u8 sensor_init_ov965x[][2] = {
412 {0x58, 0x1a}, 804 {0x58, 0x1a},
413 {0xff, 0x41}, /* read 41, write ff 00 */ 805 {0xff, 0x41}, /* read 41, write ff 00 */
414 {0x41, 0x40}, /* com16 */ 806 {0x41, 0x40}, /* com16 */
807
415 {0xc5, 0x03}, /* 60 Hz banding filter */ 808 {0xc5, 0x03}, /* 60 Hz banding filter */
416 {0x6a, 0x02}, /* 50 Hz banding filter */ 809 {0x6a, 0x02}, /* 50 Hz banding filter */
417 810
@@ -455,8 +848,8 @@ static const u8 bridge_init_ov965x_2[][2] = {
455 {0x52, 0x3c}, 848 {0x52, 0x3c},
456 {0x53, 0x00}, 849 {0x53, 0x00},
457 {0x54, 0x00}, 850 {0x54, 0x00},
458 {0x55, 0x00}, /* brightness */ 851 {0x55, 0x00},
459 {0x57, 0x00}, /* contrast 2 */ 852 {0x57, 0x00},
460 {0x5c, 0x00}, 853 {0x5c, 0x00},
461 {0x5a, 0xa0}, 854 {0x5a, 0xa0},
462 {0x5b, 0x78}, 855 {0x5b, 0x78},
@@ -479,14 +872,16 @@ static const u8 sensor_init_ov965x_2[][2] = {
479 {0xa3, 0x3e}, 872 {0xa3, 0x3e},
480 {0x2d, 0x00}, 873 {0x2d, 0x00},
481 {0xff, 0x42}, /* read 42, write ff 00 */ 874 {0xff, 0x42}, /* read 42, write ff 00 */
482 {0x42, 0xc0}, 875 {0x42, 0xc0}, /* com17 */
483 {0x2d, 0x00}, 876 {0x2d, 0x00},
484 {0xff, 0x42}, /* read 42, write ff 00 */ 877 {0xff, 0x42}, /* read 42, write ff 00 */
485 {0x42, 0xc1}, 878 {0x42, 0xc1}, /* com17 */
879/* sharpness */
486 {0x3f, 0x01}, 880 {0x3f, 0x01},
487 {0xff, 0x42}, /* read 42, write ff 00 */ 881 {0xff, 0x42}, /* read 42, write ff 00 */
488 {0x42, 0xc1}, 882 {0x42, 0xc1}, /* com17 */
489 {0x4f, 0x98}, 883/* saturation */
884 {0x4f, 0x98}, /* matrix */
490 {0x50, 0x98}, 885 {0x50, 0x98},
491 {0x51, 0x00}, 886 {0x51, 0x00},
492 {0x52, 0x28}, 887 {0x52, 0x28},
@@ -495,14 +890,17 @@ static const u8 sensor_init_ov965x_2[][2] = {
495 {0x58, 0x1a}, 890 {0x58, 0x1a},
496 {0xff, 0x41}, /* read 41, write ff 00 */ 891 {0xff, 0x41}, /* read 41, write ff 00 */
497 {0x41, 0x40}, /* com16 */ 892 {0x41, 0x40}, /* com16 */
893/* contrast */
498 {0x56, 0x40}, 894 {0x56, 0x40},
895/* brightness */
499 {0x55, 0x8f}, 896 {0x55, 0x8f},
897/* expo */
500 {0x10, 0x25}, /* aech - exposure high bits */ 898 {0x10, 0x25}, /* aech - exposure high bits */
501 {0xff, 0x13}, /* read 13, write ff 00 */ 899 {0xff, 0x13}, /* read 13, write ff 00 */
502 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 900 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
503}; 901};
504 902
505static const u8 sensor_start_ov965x[][2] = { 903static const u8 sensor_start_ov965x_1_vga[][2] = { /* same for qvga */
506 {0x12, 0x62}, /* com7 - 30fps VGA YUV */ 904 {0x12, 0x62}, /* com7 - 30fps VGA YUV */
507 {0x36, 0xfa}, /* aref3 */ 905 {0x36, 0xfa}, /* aref3 */
508 {0x69, 0x0a}, /* hv */ 906 {0x69, 0x0a}, /* hv */
@@ -523,10 +921,77 @@ static const u8 sensor_start_ov965x[][2] = {
523 {0x1a, 0x3d}, /* vstop */ 921 {0x1a, 0x3d}, /* vstop */
524 {0x32, 0xff}, /* href */ 922 {0x32, 0xff}, /* href */
525 {0xc0, 0xaa}, 923 {0xc0, 0xaa},
526 {}
527}; 924};
528 925
529static const u8 bridge_start_ov965x[][2] = { 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] = {
530 {0x94, 0xaa}, 995 {0x94, 0xaa},
531 {0xf1, 0x60}, 996 {0xf1, 0x60},
532 {0xe5, 0x04}, 997 {0xe5, 0x04},
@@ -535,10 +1000,34 @@ static const u8 bridge_start_ov965x[][2] = {
535 {0x8c, 0x00}, 1000 {0x8c, 0x00},
536 {0x8d, 0x1c}, 1001 {0x8d, 0x1c},
537 {0x34, 0x05}, 1002 {0x34, 0x05},
538 {} 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},
539}; 1020};
540 1021
541static const u8 bridge_start_ov965x_vga[][2] = { 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},
542 {0xc2, 0x0c}, 1031 {0xc2, 0x0c},
543 {0xc3, 0xf9}, 1032 {0xc3, 0xf9},
544 {0xda, 0x01}, 1033 {0xda, 0x01},
@@ -555,30 +1044,98 @@ static const u8 bridge_start_ov965x_vga[][2] = {
555 {0x35, 0x02}, 1044 {0x35, 0x02},
556 {0xd9, 0x10}, 1045 {0xd9, 0x10},
557 {0x94, 0x11}, 1046 {0x94, 0x11},
558 {}
559}; 1047};
560 1048
561static const u8 bridge_start_ov965x_cif[][2] = { 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},
562 {0xc2, 0x4c}, 1058 {0xc2, 0x4c},
563 {0xc3, 0xf9}, 1059 {0xc3, 0xf9},
564 {0xda, 0x00},
565 {0x50, 0x00}, 1060 {0x50, 0x00},
566 {0x51, 0xa0}, 1061 {0x51, 0x40},
567 {0x52, 0x78}, 1062 {0x52, 0x00},
568 {0x53, 0x00}, 1063 {0x53, 0x00},
569 {0x54, 0x00}, 1064 {0x54, 0x00},
570 {0x55, 0x00}, 1065 {0x55, 0x88},
571 {0x57, 0x00}, 1066 {0x57, 0x00},
572 {0x5c, 0x00}, 1067 {0x5c, 0x00},
573 {0x5a, 0x50}, 1068 {0x5a, 0xc8},
574 {0x5b, 0x3c}, 1069 {0x5b, 0x96},
575 {0x35, 0x02}, 1070 {0x35, 0x02},
576 {0xd9, 0x10}, 1071 {0xd9, 0x10},
1072 {0xda, 0x00},
577 {0x94, 0x11}, 1073 {0x94, 0x11},
578 {}
579}; 1074};
580 1075
581static const u8 sensor_start_ov965x_vga[][2] = { 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] = {
582 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */ 1139 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
583 {0x1e, 0x04}, /* mvfp */ 1140 {0x1e, 0x04}, /* mvfp */
584 {0x13, 0xe0}, /* com8 */ 1141 {0x13, 0xe0}, /* com8 */
@@ -592,35 +1149,36 @@ static const u8 sensor_start_ov965x_vga[][2] = {
592 {0xa3, 0x3e}, /* bd60 */ 1149 {0xa3, 0x3e}, /* bd60 */
593 1150
594 {0x2d, 0x00}, /* advfl */ 1151 {0x2d, 0x00}, /* advfl */
595 {}
596}; 1152};
597 1153
598static const u8 sensor_start_ov965x_cif[][2] = { 1154static const u8 sensor_start_ov965x_2_svga[][2] = { /* same for xga */
599 {0x3b, 0xe4}, /* com11 - night mode 1/4 frame rate */ 1155 {0x3b, 0xc4}, /* com11 - night mode 1/4 frame rate */
600 {0x1e, 0x04}, /* mvfp */ 1156 {0x1e, 0x04}, /* mvfp */
601 {0x13, 0xe0}, /* com8 */ 1157 {0x13, 0xe0}, /* com8 */
602 {0x00, 0x00}, 1158 {0x00, 0x00},
603 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */ 1159 {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
604 {0x11, 0x01}, /* clkrc */ 1160 {0x11, 0x01}, /* clkrc */
605 {0x6b, 0x5a}, /* dblv */ 1161 {0x6b, 0x5a}, /* dblv */
606 {0x6a, 0x02}, /* 50 Hz banding filter */ 1162 {0x6a, 0x0c}, /* 50 Hz banding filter */
607 {0xc5, 0x03}, /* 60 Hz banding filter */ 1163 {0xc5, 0x0f}, /* 60 Hz banding filter */
608 {0xa2, 0x96}, /* bd50 */ 1164 {0xa2, 0x4e}, /* bd50 */
609 {0xa3, 0x7d}, /* bd60 */ 1165 {0xa3, 0x41}, /* bd60 */
610
611 {0xff, 0x13}, /* read 13, write ff 00 */
612 {0x13, 0xe7},
613 {0x3a, 0x80}, /* tslb - yuyv */
614 {}
615}; 1166};
616 1167
617static const u8 sensor_start_ov965x_2[][2] = { 1168static const u8 sensor_start_ov965x_2_sxga[][2] = {
618 {0xff, 0x42}, /* read 42, write ff 00 */ 1169 {0x13, 0xe0}, /* com8 */
619 {0x42, 0xc1}, /* com17 - 50 Hz filter */ 1170 {0x00, 0x00},
620 {} 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 */
621}; 1180};
622 1181
623
624static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) 1182static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
625{ 1183{
626 struct usb_device *udev = gspca_dev->dev; 1184 struct usb_device *udev = gspca_dev->dev;
@@ -753,39 +1311,310 @@ static void sccb_w_array(struct gspca_dev *gspca_dev,
753 } 1311 }
754} 1312}
755 1313
756/* set framerate */ 1314/* ov772x specific controls */
757static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) 1315static void set_frame_rate(struct gspca_dev *gspca_dev)
1316{
1317 struct sd *sd = (struct sd *) gspca_dev;
1318 int i;
1319 struct rate_s {
1320 u8 fps;
1321 u8 r11;
1322 u8 r0d;
1323 u8 re5;
1324 };
1325 const struct rate_s *r;
1326 static const struct rate_s rate_0[] = { /* 640x480 */
1327 {60, 0x01, 0xc1, 0x04},
1328 {50, 0x01, 0x41, 0x02},
1329 {40, 0x02, 0xc1, 0x04},
1330 {30, 0x04, 0x81, 0x02},
1331 {15, 0x03, 0x41, 0x04},
1332 };
1333 static const struct rate_s rate_1[] = { /* 320x240 */
1334 {125, 0x02, 0x81, 0x02},
1335 {100, 0x02, 0xc1, 0x04},
1336 {75, 0x03, 0xc1, 0x04},
1337 {60, 0x04, 0xc1, 0x04},
1338 {50, 0x02, 0x41, 0x04},
1339 {40, 0x03, 0x41, 0x04},
1340 {30, 0x04, 0x41, 0x04},
1341 };
1342
1343 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
1344 r = rate_0;
1345 i = ARRAY_SIZE(rate_0);
1346 } else {
1347 r = rate_1;
1348 i = ARRAY_SIZE(rate_1);
1349 }
1350 while (--i > 0) {
1351 if (sd->frame_rate >= r->fps)
1352 break;
1353 r++;
1354 }
1355
1356 sccb_reg_write(gspca_dev, 0x11, r->r11);
1357 sccb_reg_write(gspca_dev, 0x0d, r->r0d);
1358 ov534_reg_write(gspca_dev, 0xe5, r->re5);
1359
1360 PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
1361}
1362
1363static void setbrightness_77(struct gspca_dev *gspca_dev)
1364{
1365 struct sd *sd = (struct sd *) gspca_dev;
1366
1367 sccb_reg_write(gspca_dev, 0x9B, sd->brightness);
1368}
1369
1370static void setcontrast_77(struct gspca_dev *gspca_dev)
758{ 1371{
759 struct sd *sd = (struct sd *) gspca_dev; 1372 struct sd *sd = (struct sd *) gspca_dev;
760 int fr = sd->frame_rate;
761 1373
762 switch (fr) { 1374 sccb_reg_write(gspca_dev, 0x9C, sd->contrast);
763 case 50: 1375}
764 sccb_reg_write(gspca_dev, 0x11, 0x01); 1376
765 sccb_reg_write(gspca_dev, 0x0d, 0x41); 1377static void setgain(struct gspca_dev *gspca_dev)
766 ov534_reg_write(gspca_dev, 0xe5, 0x02); 1378{
1379 struct sd *sd = (struct sd *) gspca_dev;
1380 u8 val;
1381
1382 val = sd->gain;
1383 switch (val & 0x30) {
1384 case 0x00:
1385 val &= 0x0f;
767 break; 1386 break;
768 case 40: 1387 case 0x10:
769 sccb_reg_write(gspca_dev, 0x11, 0x02); 1388 val &= 0x0f;
770 sccb_reg_write(gspca_dev, 0x0d, 0xc1); 1389 val |= 0x30;
771 ov534_reg_write(gspca_dev, 0xe5, 0x04);
772 break; 1390 break;
773/* case 30: */ 1391 case 0x20:
774 default: 1392 val &= 0x0f;
775 fr = 30; 1393 val |= 0x70;
776 sccb_reg_write(gspca_dev, 0x11, 0x04);
777 sccb_reg_write(gspca_dev, 0x0d, 0x81);
778 ov534_reg_write(gspca_dev, 0xe5, 0x02);
779 break; 1394 break;
780 case 15: 1395 default:
781 sccb_reg_write(gspca_dev, 0x11, 0x03); 1396/* case 0x30: */
782 sccb_reg_write(gspca_dev, 0x0d, 0x41); 1397 val &= 0x0f;
783 ov534_reg_write(gspca_dev, 0xe5, 0x04); 1398 val |= 0xf0;
784 break; 1399 break;
785 } 1400 }
1401 sccb_reg_write(gspca_dev, 0x00, val);
1402}
1403
1404static void setexposure_77(struct gspca_dev *gspca_dev)
1405{
1406 struct sd *sd = (struct sd *) gspca_dev;
1407 u8 val;
1408
1409 val = sd->exposure;
1410 sccb_reg_write(gspca_dev, 0x08, val >> 7);
1411 sccb_reg_write(gspca_dev, 0x10, val << 1);
1412}
1413
1414static void setredblc(struct gspca_dev *gspca_dev)
1415{
1416 struct sd *sd = (struct sd *) gspca_dev;
1417
1418 sccb_reg_write(gspca_dev, 0x43, sd->redblc);
1419}
1420
1421static void setblueblc(struct gspca_dev *gspca_dev)
1422{
1423 struct sd *sd = (struct sd *) gspca_dev;
1424
1425 sccb_reg_write(gspca_dev, 0x42, sd->blueblc);
1426}
1427
1428static void sethue(struct gspca_dev *gspca_dev)
1429{
1430 struct sd *sd = (struct sd *) gspca_dev;
1431
1432 sccb_reg_write(gspca_dev, 0x01, sd->hue);
1433}
1434
1435static void setautogain_77(struct gspca_dev *gspca_dev)
1436{
1437 struct sd *sd = (struct sd *) gspca_dev;
1438
1439 if (sd->autogain) {
1440 sccb_reg_write(gspca_dev, 0x13, 0xf7); /* AGC,AEC,AWB ON */
1441 sccb_reg_write(gspca_dev, 0x64,
1442 sccb_reg_read(gspca_dev, 0x64) | 0x03);
1443 } else {
1444 sccb_reg_write(gspca_dev, 0x13, 0xf0); /* AGC,AEC,AWB OFF */
1445 sccb_reg_write(gspca_dev, 0x64,
1446 sccb_reg_read(gspca_dev, 0x64) & 0xfc);
1447 }
1448}
1449
1450static void setawb(struct gspca_dev *gspca_dev)
1451{
1452 struct sd *sd = (struct sd *) gspca_dev;
1453
1454 if (sd->awb)
1455 sccb_reg_write(gspca_dev, 0x63, 0xe0); /* AWB on */
1456 else
1457 sccb_reg_write(gspca_dev, 0x63, 0xaa); /* AWB off */
1458}
1459
1460static void setsharpness_77(struct gspca_dev *gspca_dev)
1461{
1462 struct sd *sd = (struct sd *) gspca_dev;
1463 u8 val;
1464
1465 val = sd->sharpness;
1466 sccb_reg_write(gspca_dev, 0x91, val); /* vga noise */
1467 sccb_reg_write(gspca_dev, 0x8e, val); /* qvga noise */
1468}
1469
1470static void sethflip(struct gspca_dev *gspca_dev)
1471{
1472 struct sd *sd = (struct sd *) gspca_dev;
1473
1474 if (sd->hflip == 0)
1475 sccb_reg_write(gspca_dev, 0x0c,
1476 sccb_reg_read(gspca_dev, 0x0c) | 0x40);
1477 else
1478 sccb_reg_write(gspca_dev, 0x0c,
1479 sccb_reg_read(gspca_dev, 0x0c) & 0xbf);
1480}
1481
1482static void setvflip(struct gspca_dev *gspca_dev)
1483{
1484 struct sd *sd = (struct sd *) gspca_dev;
1485
1486 if (sd->vflip == 0)
1487 sccb_reg_write(gspca_dev, 0x0c,
1488 sccb_reg_read(gspca_dev, 0x0c) | 0x80);
1489 else
1490 sccb_reg_write(gspca_dev, 0x0c,
1491 sccb_reg_read(gspca_dev, 0x0c) & 0x7f);
1492}
1493
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 u8 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);
786 1610
787 sd->frame_rate = fr; 1611 val = sccb_reg_read(gspca_dev, 0x42); /* com17 */
788 PDEBUG(D_PROBE, "frame_rate: %d", fr); 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);
789} 1618}
790 1619
791/* this function is called at probe time */ 1620/* this function is called at probe time */
@@ -800,17 +1629,60 @@ static int sd_config(struct gspca_dev *gspca_dev,
800 cam = &gspca_dev->cam; 1629 cam = &gspca_dev->cam;
801 1630
802 if (sd->sensor == SENSOR_OV772X) { 1631 if (sd->sensor == SENSOR_OV772X) {
803 cam->cam_mode = vga_yuyv_mode; 1632 cam->cam_mode = ov772x_mode;
804 cam->nmodes = ARRAY_SIZE(vga_yuyv_mode); 1633 cam->nmodes = ARRAY_SIZE(ov772x_mode);
805 1634
806 cam->bulk = 1; 1635 cam->bulk = 1;
807 cam->bulk_size = 16384; 1636 cam->bulk_size = 16384;
808 cam->bulk_nurbs = 2; 1637 cam->bulk_nurbs = 2;
809 } else { /* ov965x */ 1638 } else { /* ov965x */
810 cam->cam_mode = vga_jpeg_mode; 1639 cam->cam_mode = ov965x_mode;
811 cam->nmodes = ARRAY_SIZE(vga_jpeg_mode); 1640 cam->nmodes = ARRAY_SIZE(ov965x_mode);
812 } 1641 }
813 1642
1643 sd->frame_rate = 30;
1644
1645 if (sd->sensor == SENSOR_OV772X) {
1646 sd->brightness = BRIGHTNESS_77_DEF;
1647 sd->contrast = CONTRAST_77_DEF;
1648 sd->gain = GAIN_DEF;
1649 sd->exposure = EXPO_77_DEF;
1650 sd->redblc = RED_BALANCE_DEF;
1651 sd->blueblc = BLUE_BALANCE_DEF;
1652 sd->hue = HUE_DEF;
1653#if AUTOGAIN_77_DEF != 0
1654 sd->autogain = AUTOGAIN_77_DEF;
1655#else
1656 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
1657#endif
1658#if AWB_DEF != 0
1659 sd->awb = AWB_DEF
1660#endif
1661#if SHARPNESS_77_DEF != 0
1662 sd->sharpness = SHARPNESS_77_DEF;
1663#endif
1664#if HFLIP_DEF != 0
1665 sd->hflip = HFLIP_DEF;
1666#endif
1667#if VFLIP_DEF != 0
1668 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
1680#if SHARPNESS_96_DEF != 0
1681 sd->sharpness = SHARPNESS_96_DEF;
1682#endif
1683 sd->satur = SATUR_DEF;
1684 sd->lightfreq = FREQ_DEF;
1685 }
814 return 0; 1686 return 0;
815} 1687}
816 1688
@@ -847,14 +1719,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
847 /* initialize */ 1719 /* initialize */
848 switch (sd->sensor) { 1720 switch (sd->sensor) {
849 case SENSOR_OV772X: 1721 case SENSOR_OV772X:
850 reg_w_array(gspca_dev, bridge_init_ov722x, 1722 reg_w_array(gspca_dev, bridge_init_ov772x,
851 ARRAY_SIZE(bridge_init_ov722x)); 1723 ARRAY_SIZE(bridge_init_ov772x));
852 ov534_set_led(gspca_dev, 1); 1724 ov534_set_led(gspca_dev, 1);
853 sccb_w_array(gspca_dev, sensor_init_ov722x, 1725 sccb_w_array(gspca_dev, sensor_init_ov772x,
854 ARRAY_SIZE(sensor_init_ov722x)); 1726 ARRAY_SIZE(sensor_init_ov772x));
855 ov534_reg_write(gspca_dev, 0xe0, 0x09); 1727 ov534_reg_write(gspca_dev, 0xe0, 0x09);
856 ov534_set_led(gspca_dev, 0); 1728 ov534_set_led(gspca_dev, 0);
857 ov534_set_frame_rate(gspca_dev); 1729 set_frame_rate(gspca_dev);
858 break; 1730 break;
859 default: 1731 default:
860/* case SENSOR_OV965X: */ 1732/* case SENSOR_OV965X: */
@@ -875,60 +1747,115 @@ static int sd_init(struct gspca_dev *gspca_dev)
875 return 0; 1747 return 0;
876} 1748}
877 1749
878static int sd_start(struct gspca_dev *gspca_dev) 1750static int sd_start_ov772x(struct gspca_dev *gspca_dev)
879{ 1751{
880 struct sd *sd = (struct sd *) gspca_dev;
881 int mode; 1752 int mode;
882 1753
883 switch (sd->sensor) { 1754 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
884 case SENSOR_OV772X: 1755 if (mode != 0) { /* 320x240 */
885 ov534_set_led(gspca_dev, 1); 1756 reg_w_array(gspca_dev, bridge_start_ov772x_qvga,
886 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1757 ARRAY_SIZE(bridge_start_ov772x_qvga));
887 break; 1758 sccb_w_array(gspca_dev, sensor_start_ov772x_qvga,
888 default: 1759 ARRAY_SIZE(sensor_start_ov772x_qvga));
889/* case SENSOR_OV965X: */ 1760 } else { /* 640x480 */
890 1761 reg_w_array(gspca_dev, bridge_start_ov772x_vga,
891 sccb_w_array(gspca_dev, sensor_start_ov965x, 1762 ARRAY_SIZE(bridge_start_ov772x_vga));
892 ARRAY_SIZE(sensor_start_ov965x)); 1763 sccb_w_array(gspca_dev, sensor_start_ov772x_vga,
893 reg_w_array(gspca_dev, bridge_start_ov965x, 1764 ARRAY_SIZE(sensor_start_ov772x_vga));
894 ARRAY_SIZE(bridge_start_ov965x));
895 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
896 if (mode != 0) { /* 320x240 */
897 reg_w_array(gspca_dev, bridge_start_ov965x_cif,
898 ARRAY_SIZE(bridge_start_ov965x_cif));
899 sccb_w_array(gspca_dev, sensor_start_ov965x_cif,
900 ARRAY_SIZE(sensor_start_ov965x_cif));
901 } else { /* 640x480 */
902 reg_w_array(gspca_dev, bridge_start_ov965x_vga,
903 ARRAY_SIZE(bridge_start_ov965x_vga));
904 sccb_w_array(gspca_dev, sensor_start_ov965x_vga,
905 ARRAY_SIZE(sensor_start_ov965x_vga));
906 }
907 sccb_w_array(gspca_dev, sensor_start_ov965x_2,
908 ARRAY_SIZE(sensor_start_ov965x_2));
909 ov534_reg_write(gspca_dev, 0xe0, 0x00);
910 ov534_reg_write(gspca_dev, 0xe0, 0x00);
911 ov534_set_led(gspca_dev, 1);
912 } 1765 }
1766 set_frame_rate(gspca_dev);
1767
1768 setautogain_77(gspca_dev);
1769 setawb(gspca_dev);
1770 setgain(gspca_dev);
1771 setredblc(gspca_dev);
1772 setblueblc(gspca_dev);
1773 sethue(gspca_dev);
1774 setexposure_77(gspca_dev);
1775 setbrightness_77(gspca_dev);
1776 setcontrast_77(gspca_dev);
1777 setsharpness_77(gspca_dev);
1778 setvflip(gspca_dev);
1779 sethflip(gspca_dev);
1780
1781 ov534_set_led(gspca_dev, 1);
1782 ov534_reg_write(gspca_dev, 0xe0, 0x00);
913 return 0; 1783 return 0;
914} 1784}
915 1785
916static void sd_stopN(struct gspca_dev *gspca_dev) 1786static int sd_start_ov965x(struct gspca_dev *gspca_dev)
917{ 1787{
918 struct sd *sd = (struct sd *) gspca_dev; 1788 int mode;
919 1789
920 switch (sd->sensor) { 1790 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
921 case SENSOR_OV772X: 1791 switch (mode) {
922 ov534_reg_write(gspca_dev, 0xe0, 0x09);
923 ov534_set_led(gspca_dev, 0);
924 break;
925 default: 1792 default:
926/* case SENSOR_OV965X: */ 1793/* case 4: * 320x240 */
927 ov534_reg_write(gspca_dev, 0xe0, 0x01); 1794 sccb_w_array(gspca_dev, sensor_start_ov965x_1_vga,
928 ov534_set_led(gspca_dev, 0); 1795 ARRAY_SIZE(sensor_start_ov965x_1_vga));
929 ov534_reg_write(gspca_dev, 0xe0, 0x00); 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));
930 break; 1832 break;
931 } 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{
1850 ov534_reg_write(gspca_dev, 0xe0, 0x09);
1851 ov534_set_led(gspca_dev, 0);
1852}
1853
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);
932} 1859}
933 1860
934/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 1861/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -941,8 +1868,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
941#define UVC_STREAM_EOF (1 << 1) 1868#define UVC_STREAM_EOF (1 << 1)
942#define UVC_STREAM_FID (1 << 0) 1869#define UVC_STREAM_FID (1 << 0)
943 1870
944static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, 1871static void sd_pkt_scan(struct gspca_dev *gspca_dev,
945 __u8 *data, int len) 1872 u8 *data, int len)
946{ 1873{
947 struct sd *sd = (struct sd *) gspca_dev; 1874 struct sd *sd = (struct sd *) gspca_dev;
948 __u32 this_pts; 1875 __u32 this_pts;
@@ -983,32 +1910,30 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
983 /* If PTS or FID has changed, start a new frame. */ 1910 /* If PTS or FID has changed, start a new frame. */
984 if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 1911 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
985 if (gspca_dev->last_packet_type == INTER_PACKET) 1912 if (gspca_dev->last_packet_type == INTER_PACKET)
986 frame = gspca_frame_add(gspca_dev, 1913 gspca_frame_add(gspca_dev, LAST_PACKET,
987 LAST_PACKET, frame, 1914 NULL, 0);
988 NULL, 0);
989 sd->last_pts = this_pts; 1915 sd->last_pts = this_pts;
990 sd->last_fid = this_fid; 1916 sd->last_fid = this_fid;
991 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1917 gspca_frame_add(gspca_dev, FIRST_PACKET,
992 data + 12, len - 12); 1918 data + 12, len - 12);
993 /* If this packet is marked as EOF, end the frame */ 1919 /* If this packet is marked as EOF, end the frame */
994 } else if (data[1] & UVC_STREAM_EOF) { 1920 } else if (data[1] & UVC_STREAM_EOF) {
995 sd->last_pts = 0; 1921 sd->last_pts = 0;
996 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 1922 gspca_frame_add(gspca_dev, LAST_PACKET,
997 data + 12, len - 12); 1923 data + 12, len - 12);
998 } else { 1924 } else {
999 1925
1000 /* Add the data from this payload */ 1926 /* Add the data from this payload */
1001 gspca_frame_add(gspca_dev, INTER_PACKET, frame, 1927 gspca_frame_add(gspca_dev, INTER_PACKET,
1002 data + 12, len - 12); 1928 data + 12, len - 12);
1003 } 1929 }
1004 1930
1005
1006 /* Done this payload */ 1931 /* Done this payload */
1007 goto scan_next; 1932 goto scan_next;
1008 1933
1009discard: 1934discard:
1010 /* Discard data until a new frame starts. */ 1935 /* Discard data until a new frame starts. */
1011 gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); 1936 gspca_dev->last_packet_type = DISCARD_PACKET;
1012 1937
1013scan_next: 1938scan_next:
1014 remaining_len -= len; 1939 remaining_len -= len;
@@ -1016,6 +1941,291 @@ scan_next:
1016 } while (remaining_len > 0); 1941 } while (remaining_len > 0);
1017} 1942}
1018 1943
1944/* controls */
1945static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1946{
1947 struct sd *sd = (struct sd *) gspca_dev;
1948
1949 sd->gain = val;
1950 if (gspca_dev->streaming)
1951 setgain(gspca_dev);
1952 return 0;
1953}
1954
1955static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1956{
1957 struct sd *sd = (struct sd *) gspca_dev;
1958
1959 *val = sd->gain;
1960 return 0;
1961}
1962
1963static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1964{
1965 struct sd *sd = (struct sd *) gspca_dev;
1966
1967 sd->exposure = val;
1968 if (gspca_dev->streaming) {
1969 if (sd->sensor == SENSOR_OV772X)
1970 setexposure_77(gspca_dev);
1971 else
1972 setexposure_96(gspca_dev);
1973 }
1974 return 0;
1975}
1976
1977static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1978{
1979 struct sd *sd = (struct sd *) gspca_dev;
1980
1981 *val = sd->exposure;
1982 return 0;
1983}
1984
1985static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1986{
1987 struct sd *sd = (struct sd *) gspca_dev;
1988
1989 sd->brightness = val;
1990 if (gspca_dev->streaming) {
1991 if (sd->sensor == SENSOR_OV772X)
1992 setbrightness_77(gspca_dev);
1993 else
1994 setbrightness_96(gspca_dev);
1995 }
1996 return 0;
1997}
1998
1999static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
2000{
2001 struct sd *sd = (struct sd *) gspca_dev;
2002
2003 *val = sd->brightness;
2004 return 0;
2005}
2006
2007static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2008{
2009 struct sd *sd = (struct sd *) gspca_dev;
2010
2011 sd->contrast = val;
2012 if (gspca_dev->streaming) {
2013 if (sd->sensor == SENSOR_OV772X)
2014 setcontrast_77(gspca_dev);
2015 else
2016 setcontrast_96(gspca_dev);
2017 }
2018 return 0;
2019}
2020
2021static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2022{
2023 struct sd *sd = (struct sd *) gspca_dev;
2024
2025 *val = sd->contrast;
2026 return 0;
2027}
2028
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)
2065{
2066 struct sd *sd = (struct sd *) gspca_dev;
2067
2068 sd->redblc = val;
2069 if (gspca_dev->streaming)
2070 setredblc(gspca_dev);
2071 return 0;
2072}
2073
2074static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val)
2075{
2076 struct sd *sd = (struct sd *) gspca_dev;
2077
2078 *val = sd->redblc;
2079 return 0;
2080}
2081
2082static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val)
2083{
2084 struct sd *sd = (struct sd *) gspca_dev;
2085
2086 sd->blueblc = val;
2087 if (gspca_dev->streaming)
2088 setblueblc(gspca_dev);
2089 return 0;
2090}
2091
2092static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val)
2093{
2094 struct sd *sd = (struct sd *) gspca_dev;
2095
2096 *val = sd->blueblc;
2097 return 0;
2098}
2099
2100static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
2101{
2102 struct sd *sd = (struct sd *) gspca_dev;
2103
2104 sd->hue = val;
2105 if (gspca_dev->streaming)
2106 sethue(gspca_dev);
2107 return 0;
2108}
2109
2110static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
2111{
2112 struct sd *sd = (struct sd *) gspca_dev;
2113
2114 *val = sd->hue;
2115 return 0;
2116}
2117
2118static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2119{
2120 struct sd *sd = (struct sd *) gspca_dev;
2121
2122 sd->autogain = val;
2123
2124 if (gspca_dev->streaming) {
2125 if (sd->sensor == SENSOR_OV772X) {
2126
2127 /* the auto white balance control works only
2128 * when auto gain is set */
2129 if (val)
2130 gspca_dev->ctrl_inac &= ~(1 << AWB_77_IDX);
2131 else
2132 gspca_dev->ctrl_inac |= (1 << AWB_77_IDX);
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 }
2142 return 0;
2143}
2144
2145static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2146{
2147 struct sd *sd = (struct sd *) gspca_dev;
2148
2149 *val = sd->autogain;
2150 return 0;
2151}
2152
2153static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
2154{
2155 struct sd *sd = (struct sd *) gspca_dev;
2156
2157 sd->awb = val;
2158 if (gspca_dev->streaming)
2159 setawb(gspca_dev);
2160 return 0;
2161}
2162
2163static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
2164{
2165 struct sd *sd = (struct sd *) gspca_dev;
2166
2167 *val = sd->awb;
2168 return 0;
2169}
2170
2171static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2172{
2173 struct sd *sd = (struct sd *) gspca_dev;
2174
2175 sd->sharpness = val;
2176 if (gspca_dev->streaming) {
2177 if (sd->sensor == SENSOR_OV772X)
2178 setsharpness_77(gspca_dev);
2179 else
2180 setsharpness_96(gspca_dev);
2181 }
2182 return 0;
2183}
2184
2185static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2186{
2187 struct sd *sd = (struct sd *) gspca_dev;
2188
2189 *val = sd->sharpness;
2190 return 0;
2191}
2192
2193static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2194{
2195 struct sd *sd = (struct sd *) gspca_dev;
2196
2197 sd->hflip = val;
2198 if (gspca_dev->streaming)
2199 sethflip(gspca_dev);
2200 return 0;
2201}
2202
2203static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
2204{
2205 struct sd *sd = (struct sd *) gspca_dev;
2206
2207 *val = sd->hflip;
2208 return 0;
2209}
2210
2211static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2212{
2213 struct sd *sd = (struct sd *) gspca_dev;
2214
2215 sd->vflip = val;
2216 if (gspca_dev->streaming)
2217 setvflip(gspca_dev);
2218 return 0;
2219}
2220
2221static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2222{
2223 struct sd *sd = (struct sd *) gspca_dev;
2224
2225 *val = sd->vflip;
2226 return 0;
2227}
2228
1019/* get stream parameters (framerate) */ 2229/* get stream parameters (framerate) */
1020static int sd_get_streamparm(struct gspca_dev *gspca_dev, 2230static int sd_get_streamparm(struct gspca_dev *gspca_dev,
1021 struct v4l2_streamparm *parm) 2231 struct v4l2_streamparm *parm)
@@ -1047,7 +2257,8 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1047 2257
1048 /* Set requested framerate */ 2258 /* Set requested framerate */
1049 sd->frame_rate = tpf->denominator / tpf->numerator; 2259 sd->frame_rate = tpf->denominator / tpf->numerator;
1050 ov534_set_frame_rate(gspca_dev); 2260 if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X)
2261 set_frame_rate(gspca_dev);
1051 2262
1052 /* Return the actual framerate */ 2263 /* Return the actual framerate */
1053 tpf->numerator = 1; 2264 tpf->numerator = 1;
@@ -1056,20 +2267,53 @@ static int sd_set_streamparm(struct gspca_dev *gspca_dev,
1056 return 0; 2267 return 0;
1057} 2268}
1058 2269
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
1059/* sub-driver description */ 2291/* sub-driver description */
1060static const struct sd_desc sd_desc = { 2292static const struct sd_desc sd_desc_ov772x = {
1061 .name = MODULE_NAME, 2293 .name = MODULE_NAME,
1062 .ctrls = sd_ctrls, 2294 .ctrls = sd_ctrls_ov772x,
1063 .nctrls = ARRAY_SIZE(sd_ctrls), 2295 .nctrls = ARRAY_SIZE(sd_ctrls_ov772x),
1064 .config = sd_config, 2296 .config = sd_config,
1065 .init = sd_init, 2297 .init = sd_init,
1066 .start = sd_start, 2298 .start = sd_start_ov772x,
1067 .stopN = sd_stopN, 2299 .stopN = sd_stopN_ov772x,
1068 .pkt_scan = sd_pkt_scan, 2300 .pkt_scan = sd_pkt_scan,
1069 .get_streamparm = sd_get_streamparm, 2301 .get_streamparm = sd_get_streamparm,
1070 .set_streamparm = sd_set_streamparm, 2302 .set_streamparm = sd_set_streamparm,
1071}; 2303};
1072 2304
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
1073/* -- module initialisation -- */ 2317/* -- module initialisation -- */
1074static const __devinitdata struct usb_device_id device_table[] = { 2318static const __devinitdata struct usb_device_id device_table[] = {
1075 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X}, 2319 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
@@ -1082,8 +2326,12 @@ MODULE_DEVICE_TABLE(usb, device_table);
1082/* -- device connect -- */ 2326/* -- device connect -- */
1083static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 2327static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1084{ 2328{
1085 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 2329 return gspca_dev_probe(intf, id,
1086 THIS_MODULE); 2330 id->driver_info == SENSOR_OV772X
2331 ? &sd_desc_ov772x
2332 : &sd_desc_ov965x,
2333 sizeof(struct sd),
2334 THIS_MODULE);
1087} 2335}
1088 2336
1089static struct usb_driver sd_driver = { 2337static struct usb_driver sd_driver = {
@@ -1101,6 +2349,7 @@ static struct usb_driver sd_driver = {
1101static int __init sd_mod_init(void) 2349static int __init sd_mod_init(void)
1102{ 2350{
1103 int ret; 2351 int ret;
2352
1104 ret = usb_register(&sd_driver); 2353 ret = usb_register(&sd_driver);
1105 if (ret < 0) 2354 if (ret < 0)
1106 return ret; 2355 return ret;