Merge branch 'for-rmk/samsung3' of git://git.fluff.org/bjdooks/linux into devel-stable
[deliverable/linux.git] / drivers / media / video / gspca / ov534.c
1 /*
2 * ov534 gspca driver
3 *
4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
6 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
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 * 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 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 */
30
31 #define MODULE_NAME "ov534"
32
33 #include "gspca.h"
34
35 #define OV534_REG_ADDRESS 0xf1 /* sensor address */
36 #define OV534_REG_SUBADDR 0xf2
37 #define OV534_REG_WRITE 0xf3
38 #define OV534_REG_READ 0xf4
39 #define OV534_REG_OPERATION 0xf5
40 #define OV534_REG_STATUS 0xf6
41
42 #define OV534_OP_WRITE_3 0x37
43 #define OV534_OP_WRITE_2 0x33
44 #define OV534_OP_READ_2 0xf9
45
46 #define CTRL_TIMEOUT 500
47
48 MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
49 MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
50 MODULE_LICENSE("GPL");
51
52 /* specific webcam descriptor */
53 struct sd {
54 struct gspca_dev gspca_dev; /* !! must be the first item */
55 __u32 last_pts;
56 u16 last_fid;
57 u8 frame_rate;
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
74 u8 sensor;
75 #define SENSOR_OV772X 0
76 #define SENSOR_OV965X 1
77 };
78
79 /* V4L2 controls supported by the driver */
80 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
81 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
82 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
83 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
84 static int sd_setredblc(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getredblc(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setblueblc(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getblueblc(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
90 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
91 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
92 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
93 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
94 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
95 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
96 static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
97 static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
98 static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
99 static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
100 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
101 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
102 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
103 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
104 static int sd_setsatur(struct gspca_dev *gspca_dev, __s32 val);
105 static int sd_getsatur(struct gspca_dev *gspca_dev, __s32 *val);
106 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
107 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
108
109 static 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 };
280 static 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
382 static 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},
388 {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
389 .bytesperline = 640 * 2,
390 .sizeimage = 640 * 480 * 2,
391 .colorspace = V4L2_COLORSPACE_SRGB,
392 .priv = 0},
393 };
394
395 static const struct v4l2_pix_format ov965x_mode[] = {
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
423 static const u8 bridge_init_ov772x[][2] = {
424 { 0xc2, 0x0c },
425 { 0x88, 0xf8 },
426 { 0xc3, 0x69 },
427 { 0x89, 0xff },
428 { 0x76, 0x03 },
429 { 0x92, 0x01 },
430 { 0x93, 0x18 },
431 { 0x94, 0x10 },
432 { 0x95, 0x10 },
433 { 0xe2, 0x00 },
434 { 0xe7, 0x3e },
435
436 { 0x96, 0x00 },
437
438 { 0x97, 0x20 },
439 { 0x97, 0x20 },
440 { 0x97, 0x20 },
441 { 0x97, 0x0a },
442 { 0x97, 0x3f },
443 { 0x97, 0x4a },
444 { 0x97, 0x20 },
445 { 0x97, 0x15 },
446 { 0x97, 0x0b },
447
448 { 0x8e, 0x40 },
449 { 0x1f, 0x81 },
450 { 0x34, 0x05 },
451 { 0xe3, 0x04 },
452 { 0x88, 0x00 },
453 { 0x89, 0x00 },
454 { 0x76, 0x00 },
455 { 0xe7, 0x2e },
456 { 0x31, 0xf9 },
457 { 0x25, 0x42 },
458 { 0x21, 0xf0 },
459
460 { 0x1c, 0x00 },
461 { 0x1d, 0x40 },
462 { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
463 { 0x1d, 0x00 }, /* payload size */
464
465 { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
466 { 0x1d, 0x58 }, /* frame size */
467 { 0x1d, 0x00 }, /* frame size */
468
469 { 0x1c, 0x0a },
470 { 0x1d, 0x08 }, /* turn on UVC header */
471 { 0x1d, 0x0e }, /* .. */
472
473 { 0x8d, 0x1c },
474 { 0x8e, 0x80 },
475 { 0xe5, 0x04 },
476
477 { 0xc0, 0x50 },
478 { 0xc1, 0x3c },
479 { 0xc2, 0x0c },
480 };
481 static const u8 sensor_init_ov772x[][2] = {
482 { 0x12, 0x80 },
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 },
495
496 { 0x3d, 0x03 },
497 { 0x17, 0x26 },
498 { 0x18, 0xa0 },
499 { 0x19, 0x07 },
500 { 0x1a, 0xf0 },
501 { 0x32, 0x00 },
502 { 0x29, 0xa0 },
503 { 0x2c, 0xf0 },
504 { 0x65, 0x20 },
505 { 0x11, 0x01 },
506 { 0x42, 0x7f },
507 { 0x63, 0xaa }, /* AWB - was e0 */
508 { 0x64, 0xff },
509 { 0x66, 0x00 },
510 { 0x13, 0xf0 }, /* com8 */
511 { 0x0d, 0x41 },
512 { 0x0f, 0xc5 },
513 { 0x14, 0x11 },
514
515 { 0x22, 0x7f },
516 { 0x23, 0x03 },
517 { 0x24, 0x40 },
518 { 0x25, 0x30 },
519 { 0x26, 0xa1 },
520 { 0x2a, 0x00 },
521 { 0x2b, 0x00 },
522 { 0x6b, 0xaa },
523 { 0x13, 0xff }, /* AWB */
524
525 { 0x90, 0x05 },
526 { 0x91, 0x01 },
527 { 0x92, 0x03 },
528 { 0x93, 0x00 },
529 { 0x94, 0x60 },
530 { 0x95, 0x3c },
531 { 0x96, 0x24 },
532 { 0x97, 0x1e },
533 { 0x98, 0x62 },
534 { 0x99, 0x80 },
535 { 0x9a, 0x1e },
536 { 0x9b, 0x08 },
537 { 0x9c, 0x20 },
538 { 0x9e, 0x81 },
539
540 { 0xa6, 0x04 },
541 { 0x7e, 0x0c },
542 { 0x7f, 0x16 },
543 { 0x80, 0x2a },
544 { 0x81, 0x4e },
545 { 0x82, 0x61 },
546 { 0x83, 0x6f },
547 { 0x84, 0x7b },
548 { 0x85, 0x86 },
549 { 0x86, 0x8e },
550 { 0x87, 0x97 },
551 { 0x88, 0xa4 },
552 { 0x89, 0xaf },
553 { 0x8a, 0xc5 },
554 { 0x8b, 0xd7 },
555 { 0x8c, 0xe8 },
556 { 0x8d, 0x20 },
557
558 { 0x0c, 0x90 },
559
560 { 0x2b, 0x00 },
561 { 0x22, 0x7f },
562 { 0x23, 0x03 },
563 { 0x11, 0x01 },
564 { 0x0c, 0xd0 },
565 { 0x64, 0xff },
566 { 0x0d, 0x41 },
567
568 { 0x14, 0x41 },
569 { 0x0e, 0xcd },
570 { 0xac, 0xbf },
571 { 0x8e, 0x00 }, /* De-noise threshold */
572 { 0x0c, 0xd0 }
573 };
574 static 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 };
585 static 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 };
595 static 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 };
606 static 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 };
616
617 static 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
651 static 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
833 static 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
861 static 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
903 static 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
926 static 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
948 static 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
971 static 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
994 static 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
1022 static 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
1049 static 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
1076 static 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
1103 static 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
1120 static 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
1138 static 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
1154 static 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
1168 static 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
1182 static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
1183 {
1184 struct usb_device *udev = gspca_dev->dev;
1185 int ret;
1186
1187 PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
1188 gspca_dev->usb_buf[0] = val;
1189 ret = usb_control_msg(udev,
1190 usb_sndctrlpipe(udev, 0),
1191 0x01,
1192 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1193 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
1194 if (ret < 0)
1195 PDEBUG(D_ERR, "write failed");
1196 }
1197
1198 static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
1199 {
1200 struct usb_device *udev = gspca_dev->dev;
1201 int ret;
1202
1203 ret = usb_control_msg(udev,
1204 usb_rcvctrlpipe(udev, 0),
1205 0x01,
1206 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1207 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
1208 PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
1209 if (ret < 0)
1210 PDEBUG(D_ERR, "read failed");
1211 return gspca_dev->usb_buf[0];
1212 }
1213
1214 /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
1215 * (direction and output)? */
1216 static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
1217 {
1218 u8 data;
1219
1220 PDEBUG(D_CONF, "led status: %d", status);
1221
1222 data = ov534_reg_read(gspca_dev, 0x21);
1223 data |= 0x80;
1224 ov534_reg_write(gspca_dev, 0x21, data);
1225
1226 data = ov534_reg_read(gspca_dev, 0x23);
1227 if (status)
1228 data |= 0x80;
1229 else
1230 data &= ~0x80;
1231
1232 ov534_reg_write(gspca_dev, 0x23, data);
1233
1234 if (!status) {
1235 data = ov534_reg_read(gspca_dev, 0x21);
1236 data &= ~0x80;
1237 ov534_reg_write(gspca_dev, 0x21, data);
1238 }
1239 }
1240
1241 static int sccb_check_status(struct gspca_dev *gspca_dev)
1242 {
1243 u8 data;
1244 int i;
1245
1246 for (i = 0; i < 5; i++) {
1247 data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
1248
1249 switch (data) {
1250 case 0x00:
1251 return 1;
1252 case 0x04:
1253 return 0;
1254 case 0x03:
1255 break;
1256 default:
1257 PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
1258 data, i + 1);
1259 }
1260 }
1261 return 0;
1262 }
1263
1264 static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1265 {
1266 PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val);
1267 ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
1268 ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
1269 ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
1270
1271 if (!sccb_check_status(gspca_dev))
1272 PDEBUG(D_ERR, "sccb_reg_write failed");
1273 }
1274
1275 static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
1276 {
1277 ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
1278 ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
1279 if (!sccb_check_status(gspca_dev))
1280 PDEBUG(D_ERR, "sccb_reg_read failed 1");
1281
1282 ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
1283 if (!sccb_check_status(gspca_dev))
1284 PDEBUG(D_ERR, "sccb_reg_read failed 2");
1285
1286 return ov534_reg_read(gspca_dev, OV534_REG_READ);
1287 }
1288
1289 /* output a bridge sequence (reg - val) */
1290 static void reg_w_array(struct gspca_dev *gspca_dev,
1291 const u8 (*data)[2], int len)
1292 {
1293 while (--len >= 0) {
1294 ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]);
1295 data++;
1296 }
1297 }
1298
1299 /* output a sensor sequence (reg - val) */
1300 static void sccb_w_array(struct gspca_dev *gspca_dev,
1301 const u8 (*data)[2], int len)
1302 {
1303 while (--len >= 0) {
1304 if ((*data)[0] != 0xff) {
1305 sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]);
1306 } else {
1307 sccb_reg_read(gspca_dev, (*data)[1]);
1308 sccb_reg_write(gspca_dev, 0xff, 0x00);
1309 }
1310 data++;
1311 }
1312 }
1313
1314 /* ov772x specific controls */
1315 static 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
1363 static 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
1370 static void setcontrast_77(struct gspca_dev *gspca_dev)
1371 {
1372 struct sd *sd = (struct sd *) gspca_dev;
1373
1374 sccb_reg_write(gspca_dev, 0x9C, sd->contrast);
1375 }
1376
1377 static void setgain(struct gspca_dev *gspca_dev)
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;
1386 break;
1387 case 0x10:
1388 val &= 0x0f;
1389 val |= 0x30;
1390 break;
1391 case 0x20:
1392 val &= 0x0f;
1393 val |= 0x70;
1394 break;
1395 default:
1396 /* case 0x30: */
1397 val &= 0x0f;
1398 val |= 0xf0;
1399 break;
1400 }
1401 sccb_reg_write(gspca_dev, 0x00, val);
1402 }
1403
1404 static 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
1414 static 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
1421 static 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
1428 static 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
1435 static 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
1450 static 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
1460 static 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
1470 static 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
1482 static 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 */
1495 static 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
1509 static 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
1517 static 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
1533 static 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
1555 static 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
1571 static 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
1598 static 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 */
1621 static int sd_config(struct gspca_dev *gspca_dev,
1622 const struct usb_device_id *id)
1623 {
1624 struct sd *sd = (struct sd *) gspca_dev;
1625 struct cam *cam;
1626
1627 sd->sensor = id->driver_info;
1628
1629 cam = &gspca_dev->cam;
1630
1631 if (sd->sensor == SENSOR_OV772X) {
1632 cam->cam_mode = ov772x_mode;
1633 cam->nmodes = ARRAY_SIZE(ov772x_mode);
1634
1635 cam->bulk = 1;
1636 cam->bulk_size = 16384;
1637 cam->bulk_nurbs = 2;
1638 } else { /* ov965x */
1639 cam->cam_mode = ov965x_mode;
1640 cam->nmodes = ARRAY_SIZE(ov965x_mode);
1641 }
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 }
1686 return 0;
1687 }
1688
1689 /* this function is called at probe and resume time */
1690 static int sd_init(struct gspca_dev *gspca_dev)
1691 {
1692 struct sd *sd = (struct sd *) gspca_dev;
1693 u16 sensor_id;
1694 static const u8 sensor_addr[2] = {
1695 0x42, /* 0 SENSOR_OV772X */
1696 0x60, /* 1 SENSOR_OV965X */
1697 };
1698
1699 /* reset bridge */
1700 ov534_reg_write(gspca_dev, 0xe7, 0x3a);
1701 ov534_reg_write(gspca_dev, 0xe0, 0x08);
1702 msleep(100);
1703
1704 /* initialize the sensor address */
1705 ov534_reg_write(gspca_dev, OV534_REG_ADDRESS,
1706 sensor_addr[sd->sensor]);
1707
1708 /* reset sensor */
1709 sccb_reg_write(gspca_dev, 0x12, 0x80);
1710 msleep(10);
1711
1712 /* probe the sensor */
1713 sccb_reg_read(gspca_dev, 0x0a);
1714 sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
1715 sccb_reg_read(gspca_dev, 0x0b);
1716 sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
1717 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1718
1719 /* initialize */
1720 switch (sd->sensor) {
1721 case SENSOR_OV772X:
1722 reg_w_array(gspca_dev, bridge_init_ov772x,
1723 ARRAY_SIZE(bridge_init_ov772x));
1724 ov534_set_led(gspca_dev, 1);
1725 sccb_w_array(gspca_dev, sensor_init_ov772x,
1726 ARRAY_SIZE(sensor_init_ov772x));
1727 ov534_reg_write(gspca_dev, 0xe0, 0x09);
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
1747 return 0;
1748 }
1749
1750 static int sd_start_ov772x(struct gspca_dev *gspca_dev)
1751 {
1752 int mode;
1753
1754 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1755 if (mode != 0) { /* 320x240 */
1756 reg_w_array(gspca_dev, bridge_start_ov772x_qvga,
1757 ARRAY_SIZE(bridge_start_ov772x_qvga));
1758 sccb_w_array(gspca_dev, sensor_start_ov772x_qvga,
1759 ARRAY_SIZE(sensor_start_ov772x_qvga));
1760 } else { /* 640x480 */
1761 reg_w_array(gspca_dev, bridge_start_ov772x_vga,
1762 ARRAY_SIZE(bridge_start_ov772x_vga));
1763 sccb_w_array(gspca_dev, sensor_start_ov772x_vga,
1764 ARRAY_SIZE(sensor_start_ov772x_vga));
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);
1783 return 0;
1784 }
1785
1786 static int sd_start_ov965x(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
1848 static 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
1854 static 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) */
1862 #define UVC_STREAM_EOH (1 << 7)
1863 #define UVC_STREAM_ERR (1 << 6)
1864 #define UVC_STREAM_STI (1 << 5)
1865 #define UVC_STREAM_RES (1 << 4)
1866 #define UVC_STREAM_SCR (1 << 3)
1867 #define UVC_STREAM_PTS (1 << 2)
1868 #define UVC_STREAM_EOF (1 << 1)
1869 #define UVC_STREAM_FID (1 << 0)
1870
1871 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1872 u8 *data, int len)
1873 {
1874 struct sd *sd = (struct sd *) gspca_dev;
1875 __u32 this_pts;
1876 u16 this_fid;
1877 int remaining_len = len;
1878 int payload_len;
1879
1880 payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
1881 do {
1882 len = min(remaining_len, payload_len);
1883
1884 /* Payloads are prefixed with a UVC-style header. We
1885 consider a frame to start when the FID toggles, or the PTS
1886 changes. A frame ends when EOF is set, and we've received
1887 the correct number of bytes. */
1888
1889 /* Verify UVC header. Header length is always 12 */
1890 if (data[0] != 12 || len < 12) {
1891 PDEBUG(D_PACK, "bad header");
1892 goto discard;
1893 }
1894
1895 /* Check errors */
1896 if (data[1] & UVC_STREAM_ERR) {
1897 PDEBUG(D_PACK, "payload error");
1898 goto discard;
1899 }
1900
1901 /* Extract PTS and FID */
1902 if (!(data[1] & UVC_STREAM_PTS)) {
1903 PDEBUG(D_PACK, "PTS not present");
1904 goto discard;
1905 }
1906 this_pts = (data[5] << 24) | (data[4] << 16)
1907 | (data[3] << 8) | data[2];
1908 this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
1909
1910 /* If PTS or FID has changed, start a new frame. */
1911 if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
1912 if (gspca_dev->last_packet_type == INTER_PACKET)
1913 gspca_frame_add(gspca_dev, LAST_PACKET,
1914 NULL, 0);
1915 sd->last_pts = this_pts;
1916 sd->last_fid = this_fid;
1917 gspca_frame_add(gspca_dev, FIRST_PACKET,
1918 data + 12, len - 12);
1919 /* If this packet is marked as EOF, end the frame */
1920 } else if (data[1] & UVC_STREAM_EOF) {
1921 sd->last_pts = 0;
1922 gspca_frame_add(gspca_dev, LAST_PACKET,
1923 data + 12, len - 12);
1924 } else {
1925
1926 /* Add the data from this payload */
1927 gspca_frame_add(gspca_dev, INTER_PACKET,
1928 data + 12, len - 12);
1929 }
1930
1931 /* Done this payload */
1932 goto scan_next;
1933
1934 discard:
1935 /* Discard data until a new frame starts. */
1936 gspca_dev->last_packet_type = DISCARD_PACKET;
1937
1938 scan_next:
1939 remaining_len -= len;
1940 data += len;
1941 } while (remaining_len > 0);
1942 }
1943
1944 /* controls */
1945 static 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
1955 static 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
1963 static 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
1977 static 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
1985 static 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
1999 static 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
2007 static 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
2021 static 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
2029 static 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
2039 static 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 }
2046 static 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
2056 static 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
2064 static 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
2074 static 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
2082 static 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
2092 static 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
2100 static 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
2110 static 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
2118 static 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
2145 static 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
2153 static 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
2163 static 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
2171 static 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
2185 static 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
2193 static 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
2203 static 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
2211 static 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
2221 static 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
2229 /* get stream parameters (framerate) */
2230 static int sd_get_streamparm(struct gspca_dev *gspca_dev,
2231 struct v4l2_streamparm *parm)
2232 {
2233 struct v4l2_captureparm *cp = &parm->parm.capture;
2234 struct v4l2_fract *tpf = &cp->timeperframe;
2235 struct sd *sd = (struct sd *) gspca_dev;
2236
2237 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2238 return -EINVAL;
2239
2240 cp->capability |= V4L2_CAP_TIMEPERFRAME;
2241 tpf->numerator = 1;
2242 tpf->denominator = sd->frame_rate;
2243
2244 return 0;
2245 }
2246
2247 /* set stream parameters (framerate) */
2248 static int sd_set_streamparm(struct gspca_dev *gspca_dev,
2249 struct v4l2_streamparm *parm)
2250 {
2251 struct v4l2_captureparm *cp = &parm->parm.capture;
2252 struct v4l2_fract *tpf = &cp->timeperframe;
2253 struct sd *sd = (struct sd *) gspca_dev;
2254
2255 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2256 return -EINVAL;
2257
2258 /* Set requested framerate */
2259 sd->frame_rate = tpf->denominator / tpf->numerator;
2260 if (gspca_dev->streaming && sd->sensor == SENSOR_OV772X)
2261 set_frame_rate(gspca_dev);
2262
2263 /* Return the actual framerate */
2264 tpf->numerator = 1;
2265 tpf->denominator = sd->frame_rate;
2266
2267 return 0;
2268 }
2269
2270 static 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 */
2292 static const struct sd_desc sd_desc_ov772x = {
2293 .name = MODULE_NAME,
2294 .ctrls = sd_ctrls_ov772x,
2295 .nctrls = ARRAY_SIZE(sd_ctrls_ov772x),
2296 .config = sd_config,
2297 .init = sd_init,
2298 .start = sd_start_ov772x,
2299 .stopN = sd_stopN_ov772x,
2300 .pkt_scan = sd_pkt_scan,
2301 .get_streamparm = sd_get_streamparm,
2302 .set_streamparm = sd_set_streamparm,
2303 };
2304
2305 static 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 -- */
2318 static const __devinitdata struct usb_device_id device_table[] = {
2319 {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
2320 {USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
2321 {}
2322 };
2323
2324 MODULE_DEVICE_TABLE(usb, device_table);
2325
2326 /* -- device connect -- */
2327 static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
2328 {
2329 return gspca_dev_probe(intf, id,
2330 id->driver_info == SENSOR_OV772X
2331 ? &sd_desc_ov772x
2332 : &sd_desc_ov965x,
2333 sizeof(struct sd),
2334 THIS_MODULE);
2335 }
2336
2337 static struct usb_driver sd_driver = {
2338 .name = MODULE_NAME,
2339 .id_table = device_table,
2340 .probe = sd_probe,
2341 .disconnect = gspca_disconnect,
2342 #ifdef CONFIG_PM
2343 .suspend = gspca_suspend,
2344 .resume = gspca_resume,
2345 #endif
2346 };
2347
2348 /* -- module insert / remove -- */
2349 static int __init sd_mod_init(void)
2350 {
2351 int ret;
2352
2353 ret = usb_register(&sd_driver);
2354 if (ret < 0)
2355 return ret;
2356 PDEBUG(D_PROBE, "registered");
2357 return 0;
2358 }
2359
2360 static void __exit sd_mod_exit(void)
2361 {
2362 usb_deregister(&sd_driver);
2363 PDEBUG(D_PROBE, "deregistered");
2364 }
2365
2366 module_init(sd_mod_init);
2367 module_exit(sd_mod_exit);
This page took 0.126918 seconds and 5 git commands to generate.