1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
37
38#define MODULE_NAME "ov519"
39
40#include <linux/input.h>
41#include "gspca.h"
42
43
44
45#define CONEX_CAM
46#include "jpeg.h"
47
48MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
49MODULE_DESCRIPTION("OV519 USB Camera Driver");
50MODULE_LICENSE("GPL");
51
52
53static int frame_rate;
54
55
56
57static int i2c_detect_tries = 10;
58
59
60struct sd {
61 struct gspca_dev gspca_dev;
62
63 struct v4l2_ctrl *jpegqual;
64 struct v4l2_ctrl *freq;
65 struct {
66 struct v4l2_ctrl *hflip;
67 struct v4l2_ctrl *vflip;
68 };
69 struct {
70 struct v4l2_ctrl *autobright;
71 struct v4l2_ctrl *brightness;
72 };
73
74 u8 revision;
75
76 u8 packet_nr;
77
78 char bridge;
79#define BRIDGE_OV511 0
80#define BRIDGE_OV511PLUS 1
81#define BRIDGE_OV518 2
82#define BRIDGE_OV518PLUS 3
83#define BRIDGE_OV519 4
84#define BRIDGE_OVFX2 5
85#define BRIDGE_W9968CF 6
86#define BRIDGE_MASK 7
87
88 char invert_led;
89#define BRIDGE_INVERT_LED 8
90
91 char snapshot_pressed;
92 char snapshot_needs_reset;
93
94
95 u8 sif;
96
97#define QUALITY_MIN 50
98#define QUALITY_MAX 70
99#define QUALITY_DEF 50
100
101 u8 stopped;
102 u8 first_frame;
103
104 u8 frame_rate;
105 u8 clockdiv;
106
107 s8 sensor;
108
109 u8 sensor_addr;
110 u16 sensor_width;
111 u16 sensor_height;
112 s16 sensor_reg_cache[256];
113
114 u8 jpeg_hdr[JPEG_HDR_SZ];
115};
116enum sensors {
117 SEN_OV2610,
118 SEN_OV2610AE,
119 SEN_OV3610,
120 SEN_OV6620,
121 SEN_OV6630,
122 SEN_OV66308AF,
123 SEN_OV7610,
124 SEN_OV7620,
125 SEN_OV7620AE,
126 SEN_OV7640,
127 SEN_OV7648,
128 SEN_OV7660,
129 SEN_OV7670,
130 SEN_OV76BE,
131 SEN_OV8610,
132 SEN_OV9600,
133};
134
135
136
137
138#include "w996Xcf.c"
139
140
141struct ctrl_valid {
142 unsigned int has_brightness:1;
143 unsigned int has_contrast:1;
144 unsigned int has_exposure:1;
145 unsigned int has_autogain:1;
146 unsigned int has_sat:1;
147 unsigned int has_hvflip:1;
148 unsigned int has_autobright:1;
149 unsigned int has_freq:1;
150};
151
152static const struct ctrl_valid valid_controls[] = {
153 [SEN_OV2610] = {
154 .has_exposure = 1,
155 .has_autogain = 1,
156 },
157 [SEN_OV2610AE] = {
158 .has_exposure = 1,
159 .has_autogain = 1,
160 },
161 [SEN_OV3610] = {
162
163 },
164 [SEN_OV6620] = {
165 .has_brightness = 1,
166 .has_contrast = 1,
167 .has_sat = 1,
168 .has_autobright = 1,
169 .has_freq = 1,
170 },
171 [SEN_OV6630] = {
172 .has_brightness = 1,
173 .has_contrast = 1,
174 .has_sat = 1,
175 .has_autobright = 1,
176 .has_freq = 1,
177 },
178 [SEN_OV66308AF] = {
179 .has_brightness = 1,
180 .has_contrast = 1,
181 .has_sat = 1,
182 .has_autobright = 1,
183 .has_freq = 1,
184 },
185 [SEN_OV7610] = {
186 .has_brightness = 1,
187 .has_contrast = 1,
188 .has_sat = 1,
189 .has_autobright = 1,
190 .has_freq = 1,
191 },
192 [SEN_OV7620] = {
193 .has_brightness = 1,
194 .has_contrast = 1,
195 .has_sat = 1,
196 .has_autobright = 1,
197 .has_freq = 1,
198 },
199 [SEN_OV7620AE] = {
200 .has_brightness = 1,
201 .has_contrast = 1,
202 .has_sat = 1,
203 .has_autobright = 1,
204 .has_freq = 1,
205 },
206 [SEN_OV7640] = {
207 .has_brightness = 1,
208 .has_sat = 1,
209 .has_freq = 1,
210 },
211 [SEN_OV7648] = {
212 .has_brightness = 1,
213 .has_sat = 1,
214 .has_freq = 1,
215 },
216 [SEN_OV7660] = {
217 .has_brightness = 1,
218 .has_contrast = 1,
219 .has_sat = 1,
220 .has_hvflip = 1,
221 .has_freq = 1,
222 },
223 [SEN_OV7670] = {
224 .has_brightness = 1,
225 .has_contrast = 1,
226 .has_hvflip = 1,
227 .has_freq = 1,
228 },
229 [SEN_OV76BE] = {
230 .has_brightness = 1,
231 .has_contrast = 1,
232 .has_sat = 1,
233 .has_autobright = 1,
234 .has_freq = 1,
235 },
236 [SEN_OV8610] = {
237 .has_brightness = 1,
238 .has_contrast = 1,
239 .has_sat = 1,
240 .has_autobright = 1,
241 },
242 [SEN_OV9600] = {
243 .has_exposure = 1,
244 .has_autogain = 1,
245 },
246};
247
248static const struct v4l2_pix_format ov519_vga_mode[] = {
249 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
250 .bytesperline = 320,
251 .sizeimage = 320 * 240 * 3 / 8 + 590,
252 .colorspace = V4L2_COLORSPACE_JPEG,
253 .priv = 1},
254 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
255 .bytesperline = 640,
256 .sizeimage = 640 * 480 * 3 / 8 + 590,
257 .colorspace = V4L2_COLORSPACE_JPEG,
258 .priv = 0},
259};
260static const struct v4l2_pix_format ov519_sif_mode[] = {
261 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
262 .bytesperline = 160,
263 .sizeimage = 160 * 120 * 3 / 8 + 590,
264 .colorspace = V4L2_COLORSPACE_JPEG,
265 .priv = 3},
266 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
267 .bytesperline = 176,
268 .sizeimage = 176 * 144 * 3 / 8 + 590,
269 .colorspace = V4L2_COLORSPACE_JPEG,
270 .priv = 1},
271 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
272 .bytesperline = 320,
273 .sizeimage = 320 * 240 * 3 / 8 + 590,
274 .colorspace = V4L2_COLORSPACE_JPEG,
275 .priv = 2},
276 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
277 .bytesperline = 352,
278 .sizeimage = 352 * 288 * 3 / 8 + 590,
279 .colorspace = V4L2_COLORSPACE_JPEG,
280 .priv = 0},
281};
282
283
284
285
286
287
288
289static const struct v4l2_pix_format ov518_vga_mode[] = {
290 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
291 .bytesperline = 320,
292 .sizeimage = 320 * 240 * 3,
293 .colorspace = V4L2_COLORSPACE_JPEG,
294 .priv = 1},
295 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
296 .bytesperline = 640,
297 .sizeimage = 640 * 480 * 2,
298 .colorspace = V4L2_COLORSPACE_JPEG,
299 .priv = 0},
300};
301static const struct v4l2_pix_format ov518_sif_mode[] = {
302 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
303 .bytesperline = 160,
304 .sizeimage = 70000,
305 .colorspace = V4L2_COLORSPACE_JPEG,
306 .priv = 3},
307 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
308 .bytesperline = 176,
309 .sizeimage = 70000,
310 .colorspace = V4L2_COLORSPACE_JPEG,
311 .priv = 1},
312 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
313 .bytesperline = 320,
314 .sizeimage = 320 * 240 * 3,
315 .colorspace = V4L2_COLORSPACE_JPEG,
316 .priv = 2},
317 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
318 .bytesperline = 352,
319 .sizeimage = 352 * 288 * 3,
320 .colorspace = V4L2_COLORSPACE_JPEG,
321 .priv = 0},
322};
323
324static const struct v4l2_pix_format ov511_vga_mode[] = {
325 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
326 .bytesperline = 320,
327 .sizeimage = 320 * 240 * 3,
328 .colorspace = V4L2_COLORSPACE_JPEG,
329 .priv = 1},
330 {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
331 .bytesperline = 640,
332 .sizeimage = 640 * 480 * 2,
333 .colorspace = V4L2_COLORSPACE_JPEG,
334 .priv = 0},
335};
336static const struct v4l2_pix_format ov511_sif_mode[] = {
337 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
338 .bytesperline = 160,
339 .sizeimage = 70000,
340 .colorspace = V4L2_COLORSPACE_JPEG,
341 .priv = 3},
342 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
343 .bytesperline = 176,
344 .sizeimage = 70000,
345 .colorspace = V4L2_COLORSPACE_JPEG,
346 .priv = 1},
347 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
348 .bytesperline = 320,
349 .sizeimage = 320 * 240 * 3,
350 .colorspace = V4L2_COLORSPACE_JPEG,
351 .priv = 2},
352 {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
353 .bytesperline = 352,
354 .sizeimage = 352 * 288 * 3,
355 .colorspace = V4L2_COLORSPACE_JPEG,
356 .priv = 0},
357};
358
359static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
360 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
361 .bytesperline = 800,
362 .sizeimage = 800 * 600,
363 .colorspace = V4L2_COLORSPACE_SRGB,
364 .priv = 1},
365 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
366 .bytesperline = 1600,
367 .sizeimage = 1600 * 1200,
368 .colorspace = V4L2_COLORSPACE_SRGB},
369};
370static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
371 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
372 .bytesperline = 640,
373 .sizeimage = 640 * 480,
374 .colorspace = V4L2_COLORSPACE_SRGB,
375 .priv = 1},
376 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
377 .bytesperline = 800,
378 .sizeimage = 800 * 600,
379 .colorspace = V4L2_COLORSPACE_SRGB,
380 .priv = 1},
381 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
382 .bytesperline = 1024,
383 .sizeimage = 1024 * 768,
384 .colorspace = V4L2_COLORSPACE_SRGB,
385 .priv = 1},
386 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
387 .bytesperline = 1600,
388 .sizeimage = 1600 * 1200,
389 .colorspace = V4L2_COLORSPACE_SRGB,
390 .priv = 0},
391 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
392 .bytesperline = 2048,
393 .sizeimage = 2048 * 1536,
394 .colorspace = V4L2_COLORSPACE_SRGB,
395 .priv = 0},
396};
397static const struct v4l2_pix_format ovfx2_ov9600_mode[] = {
398 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
399 .bytesperline = 640,
400 .sizeimage = 640 * 480,
401 .colorspace = V4L2_COLORSPACE_SRGB,
402 .priv = 1},
403 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
404 .bytesperline = 1280,
405 .sizeimage = 1280 * 1024,
406 .colorspace = V4L2_COLORSPACE_SRGB},
407};
408
409
410#define R51x_FIFO_PSIZE 0x30
411#define R51x_SYS_RESET 0x50
412
413 #define OV511_RESET_OMNICE 0x08
414#define R51x_SYS_INIT 0x53
415#define R51x_SYS_SNAP 0x52
416#define R51x_SYS_CUST_ID 0x5f
417#define R51x_COMP_LUT_BEGIN 0x80
418
419
420#define R511_CAM_DELAY 0x10
421#define R511_CAM_EDGE 0x11
422#define R511_CAM_PXCNT 0x12
423#define R511_CAM_LNCNT 0x13
424#define R511_CAM_PXDIV 0x14
425#define R511_CAM_LNDIV 0x15
426#define R511_CAM_UV_EN 0x16
427#define R511_CAM_LINE_MODE 0x17
428#define R511_CAM_OPTS 0x18
429
430#define R511_SNAP_FRAME 0x19
431#define R511_SNAP_PXCNT 0x1a
432#define R511_SNAP_LNCNT 0x1b
433#define R511_SNAP_PXDIV 0x1c
434#define R511_SNAP_LNDIV 0x1d
435#define R511_SNAP_UV_EN 0x1e
436#define R511_SNAP_OPTS 0x1f
437
438#define R511_DRAM_FLOW_CTL 0x20
439#define R511_FIFO_OPTS 0x31
440#define R511_I2C_CTL 0x40
441#define R511_SYS_LED_CTL 0x55
442#define R511_COMP_EN 0x78
443#define R511_COMP_LUT_EN 0x79
444
445
446#define R518_GPIO_OUT 0x56
447#define R518_GPIO_CTL 0x57
448
449
450#define OV519_R10_H_SIZE 0x10
451#define OV519_R11_V_SIZE 0x11
452#define OV519_R12_X_OFFSETL 0x12
453#define OV519_R13_X_OFFSETH 0x13
454#define OV519_R14_Y_OFFSETL 0x14
455#define OV519_R15_Y_OFFSETH 0x15
456#define OV519_R16_DIVIDER 0x16
457#define OV519_R20_DFR 0x20
458#define OV519_R25_FORMAT 0x25
459
460
461#define OV519_R51_RESET1 0x51
462#define OV519_R54_EN_CLK1 0x54
463#define OV519_R57_SNAPSHOT 0x57
464
465#define OV519_GPIO_DATA_OUT0 0x71
466#define OV519_GPIO_IO_CTRL0 0x72
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493#define OVFX2_BULK_SIZE (13 * 4096)
494
495
496#define R51x_I2C_W_SID 0x41
497#define R51x_I2C_SADDR_3 0x42
498#define R51x_I2C_SADDR_2 0x43
499#define R51x_I2C_R_SID 0x44
500#define R51x_I2C_DATA 0x45
501#define R518_I2C_CTL 0x47
502#define OVFX2_I2C_ADDR 0x00
503
504
505#define OV7xx0_SID 0x42
506#define OV_HIRES_SID 0x60
507#define OV8xx0_SID 0xa0
508#define OV6xx0_SID 0xc0
509
510
511#define OV7610_REG_GAIN 0x00
512#define OV7610_REG_BLUE 0x01
513#define OV7610_REG_RED 0x02
514#define OV7610_REG_SAT 0x03
515#define OV8610_REG_HUE 0x04
516#define OV7610_REG_CNT 0x05
517#define OV7610_REG_BRT 0x06
518#define OV7610_REG_COM_C 0x14
519#define OV7610_REG_ID_HIGH 0x1c
520#define OV7610_REG_ID_LOW 0x1d
521#define OV7610_REG_COM_I 0x29
522
523
524#define OV7670_R00_GAIN 0x00
525#define OV7670_R01_BLUE 0x01
526#define OV7670_R02_RED 0x02
527#define OV7670_R03_VREF 0x03
528#define OV7670_R04_COM1 0x04
529
530#define OV7670_R0C_COM3 0x0c
531#define OV7670_R0D_COM4 0x0d
532#define OV7670_R0E_COM5 0x0e
533#define OV7670_R0F_COM6 0x0f
534#define OV7670_R10_AECH 0x10
535#define OV7670_R11_CLKRC 0x11
536#define OV7670_R12_COM7 0x12
537#define OV7670_COM7_FMT_VGA 0x00
538
539#define OV7670_COM7_FMT_QVGA 0x10
540#define OV7670_COM7_FMT_MASK 0x38
541#define OV7670_COM7_RESET 0x80
542#define OV7670_R13_COM8 0x13
543#define OV7670_COM8_AEC 0x01
544#define OV7670_COM8_AWB 0x02
545#define OV7670_COM8_AGC 0x04
546#define OV7670_COM8_BFILT 0x20
547#define OV7670_COM8_AECSTEP 0x40
548#define OV7670_COM8_FASTAEC 0x80
549#define OV7670_R14_COM9 0x14
550#define OV7670_R15_COM10 0x15
551#define OV7670_R17_HSTART 0x17
552#define OV7670_R18_HSTOP 0x18
553#define OV7670_R19_VSTART 0x19
554#define OV7670_R1A_VSTOP 0x1a
555#define OV7670_R1E_MVFP 0x1e
556#define OV7670_MVFP_VFLIP 0x10
557#define OV7670_MVFP_MIRROR 0x20
558#define OV7670_R24_AEW 0x24
559#define OV7670_R25_AEB 0x25
560#define OV7670_R26_VPT 0x26
561#define OV7670_R32_HREF 0x32
562#define OV7670_R3A_TSLB 0x3a
563#define OV7670_R3B_COM11 0x3b
564#define OV7670_COM11_EXP 0x02
565#define OV7670_COM11_HZAUTO 0x10
566#define OV7670_R3C_COM12 0x3c
567#define OV7670_R3D_COM13 0x3d
568#define OV7670_COM13_GAMMA 0x80
569#define OV7670_COM13_UVSAT 0x40
570#define OV7670_R3E_COM14 0x3e
571#define OV7670_R3F_EDGE 0x3f
572#define OV7670_R40_COM15 0x40
573
574#define OV7670_R41_COM16 0x41
575#define OV7670_COM16_AWBGAIN 0x08
576
577#define OV7670_R55_BRIGHT 0x55
578#define OV7670_R56_CONTRAS 0x56
579#define OV7670_R69_GFIX 0x69
580
581#define OV7670_R9F_HAECC1 0x9f
582#define OV7670_RA0_HAECC2 0xa0
583#define OV7670_RA5_BD50MAX 0xa5
584#define OV7670_RA6_HAECC3 0xa6
585#define OV7670_RA7_HAECC4 0xa7
586#define OV7670_RA8_HAECC5 0xa8
587#define OV7670_RA9_HAECC6 0xa9
588#define OV7670_RAA_HAECC7 0xaa
589#define OV7670_RAB_BD60MAX 0xab
590
591struct ov_regvals {
592 u8 reg;
593 u8 val;
594};
595struct ov_i2c_regvals {
596 u8 reg;
597 u8 val;
598};
599
600
601static const struct ov_i2c_regvals norm_2610[] = {
602 { 0x12, 0x80 },
603};
604
605static const struct ov_i2c_regvals norm_2610ae[] = {
606 {0x12, 0x80},
607 {0x13, 0xcd},
608 {0x09, 0x01},
609 {0x0d, 0x00},
610 {0x11, 0x80},
611 {0x12, 0x20},
612 {0x33, 0x0c},
613 {0x35, 0x90},
614 {0x36, 0x37},
615
616 {0x11, 0x83},
617 {0x2d, 0x00},
618 {0x24, 0xb0},
619 {0x25, 0x90},
620 {0x10, 0x43},
621};
622
623static const struct ov_i2c_regvals norm_3620b[] = {
624
625
626
627
628
629
630
631
632
633 { 0x12, 0x80 },
634 { 0x12, 0x00 },
635
636
637
638
639
640
641
642 { 0x11, 0x80 },
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665 { 0x13, 0xc0 },
666
667
668
669
670
671
672
673
674
675
676
677
678
679 { 0x09, 0x08 },
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700 { 0x0c, 0x08 },
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721 { 0x0d, 0xa1 },
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736 { 0x0e, 0x70 },
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759 { 0x0f, 0x42 },
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785 { 0x14, 0xc6 },
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807 { 0x15, 0x02 },
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827 { 0x33, 0x09 },
828
829
830
831
832
833
834
835
836
837
838
839 { 0x34, 0x50 },
840
841
842
843
844
845
846
847
848
849
850
851 { 0x36, 0x00 },
852
853
854
855
856
857
858
859
860
861
862
863 { 0x37, 0x04 },
864
865
866
867
868
869
870
871
872
873
874
875 { 0x38, 0x52 },
876
877
878
879
880
881
882
883 { 0x3a, 0x00 },
884
885
886
887
888
889
890
891 { 0x3c, 0x1f },
892
893
894
895
896
897
898 { 0x44, 0x00 },
899
900
901
902
903
904
905 { 0x40, 0x00 },
906
907
908
909
910
911
912 { 0x41, 0x00 },
913
914
915
916
917
918
919 { 0x42, 0x00 },
920
921
922
923
924
925
926 { 0x43, 0x00 },
927
928
929
930
931
932
933 { 0x45, 0x80 },
934
935
936
937
938
939
940 { 0x48, 0xc0 },
941
942
943
944
945
946
947 { 0x49, 0x19 },
948
949
950
951
952
953
954 { 0x4b, 0x80 },
955
956
957
958
959
960
961 { 0x4d, 0xc4 },
962
963
964
965
966
967
968
969
970
971
972
973 { 0x35, 0x4c },
974
975
976
977
978
979
980 { 0x3d, 0x00 },
981
982
983
984
985
986
987 { 0x3e, 0x00 },
988
989
990
991
992
993
994
995 { 0x3b, 0x18 },
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015 { 0x33, 0x19 },
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027 { 0x34, 0x5a },
1028
1029
1030
1031
1032
1033
1034
1035 { 0x3b, 0x00 },
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055 { 0x33, 0x09 },
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 { 0x34, 0x50 },
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 { 0x12, 0x40 },
1086
1087
1088
1089
1090
1091
1092
1093 { 0x17, 0x1f },
1094
1095
1096
1097
1098
1099
1100
1101 { 0x18, 0x5f },
1102
1103
1104
1105
1106
1107
1108
1109 { 0x19, 0x00 },
1110
1111
1112
1113
1114
1115
1116
1117 { 0x1a, 0x60 },
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129 { 0x32, 0x12 },
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141 { 0x03, 0x4a },
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154 { 0x11, 0x80 },
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172 { 0x12, 0x00 },
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190 { 0x12, 0x40 },
1191
1192
1193
1194
1195
1196
1197
1198 { 0x17, 0x1f },
1199
1200
1201
1202
1203
1204
1205
1206 { 0x18, 0x5f },
1207
1208
1209
1210
1211
1212
1213
1214 { 0x19, 0x00 },
1215
1216
1217
1218
1219
1220
1221
1222 { 0x1a, 0x60 },
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234 { 0x32, 0x12 },
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246 { 0x03, 0x4a },
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256 { 0x02, 0xaf },
1257
1258
1259
1260
1261
1262
1263
1264 { 0x2d, 0xd2 },
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 { 0x00, 0x18 },
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287 { 0x01, 0xf0 },
1288
1289
1290
1291
1292
1293
1294
1295 { 0x10, 0x0a },
1296
1297 { 0xe1, 0x67 },
1298 { 0xe3, 0x03 },
1299 { 0xe4, 0x26 },
1300 { 0xe5, 0x3e },
1301 { 0xf8, 0x01 },
1302 { 0xff, 0x01 },
1303};
1304
1305static const struct ov_i2c_regvals norm_6x20[] = {
1306 { 0x12, 0x80 },
1307 { 0x11, 0x01 },
1308 { 0x03, 0x60 },
1309 { 0x05, 0x7f },
1310 { 0x07, 0xa8 },
1311
1312 { 0x0c, 0x24 },
1313 { 0x0d, 0x24 },
1314 { 0x0f, 0x15 },
1315 { 0x10, 0x75 },
1316 { 0x12, 0x24 },
1317 { 0x14, 0x04 },
1318
1319 { 0x16, 0x06 },
1320
1321 { 0x26, 0xb2 },
1322
1323 { 0x28, 0x05 },
1324 { 0x2a, 0x04 },
1325
1326 { 0x2d, 0x85 },
1327 { 0x33, 0xa0 },
1328 { 0x34, 0xd2 },
1329 { 0x38, 0x8b },
1330 { 0x39, 0x40 },
1331
1332 { 0x3c, 0x39 },
1333 { 0x3c, 0x3c },
1334 { 0x3c, 0x24 },
1335
1336 { 0x3d, 0x80 },
1337
1338
1339 { 0x4a, 0x80 },
1340 { 0x4b, 0x80 },
1341 { 0x4d, 0xd2 },
1342 { 0x4e, 0xc1 },
1343 { 0x4f, 0x04 },
1344
1345
1346};
1347
1348static const struct ov_i2c_regvals norm_6x30[] = {
1349 { 0x12, 0x80 },
1350 { 0x00, 0x1f },
1351 { 0x01, 0x99 },
1352 { 0x02, 0x7c },
1353 { 0x03, 0xc0 },
1354 { 0x05, 0x0a },
1355 { 0x06, 0x95 },
1356 { 0x07, 0x2d },
1357 { 0x0c, 0x20 },
1358 { 0x0d, 0x20 },
1359 { 0x0e, 0xa0 },
1360 { 0x0f, 0x05 },
1361 { 0x10, 0x9a },
1362 { 0x11, 0x00 },
1363 { 0x12, 0x24 },
1364 { 0x13, 0x21 },
1365 { 0x14, 0x80 },
1366 { 0x15, 0x01 },
1367 { 0x16, 0x03 },
1368 { 0x17, 0x38 },
1369 { 0x18, 0xea },
1370 { 0x19, 0x04 },
1371 { 0x1a, 0x93 },
1372 { 0x1b, 0x00 },
1373 { 0x1e, 0xc4 },
1374 { 0x1f, 0x04 },
1375 { 0x20, 0x20 },
1376 { 0x21, 0x10 },
1377 { 0x22, 0x88 },
1378 { 0x23, 0xc0 },
1379 { 0x25, 0x9a },
1380 { 0x26, 0xb2 },
1381 { 0x27, 0xa2 },
1382 { 0x28, 0x00 },
1383 { 0x29, 0x00 },
1384 { 0x2a, 0x84 },
1385 { 0x2b, 0xa8 },
1386 { 0x2c, 0xa0 },
1387 { 0x2d, 0x95 },
1388 { 0x2e, 0x88 },
1389 { 0x33, 0x26 },
1390 { 0x34, 0x03 },
1391 { 0x36, 0x8f },
1392 { 0x37, 0x80 },
1393 { 0x38, 0x83 },
1394 { 0x39, 0x80 },
1395 { 0x3a, 0x0f },
1396 { 0x3b, 0x3c },
1397 { 0x3c, 0x1a },
1398 { 0x3d, 0x80 },
1399 { 0x3e, 0x80 },
1400 { 0x3f, 0x0e },
1401 { 0x40, 0x00 },
1402 { 0x41, 0x00 },
1403 { 0x42, 0x80 },
1404 { 0x43, 0x3f },
1405 { 0x44, 0x80 },
1406 { 0x45, 0x20 },
1407 { 0x46, 0x20 },
1408 { 0x47, 0x80 },
1409 { 0x48, 0x7f },
1410 { 0x49, 0x00 },
1411 { 0x4a, 0x00 },
1412 { 0x4b, 0x80 },
1413 { 0x4c, 0xd0 },
1414 { 0x4d, 0x10 },
1415 { 0x4e, 0x40 },
1416 { 0x4f, 0x07 },
1417 { 0x50, 0xff },
1418 { 0x54, 0x23 },
1419 { 0x55, 0xff },
1420 { 0x56, 0x12 },
1421 { 0x57, 0x81 },
1422 { 0x58, 0x75 },
1423 { 0x59, 0x01 },
1424 { 0x5a, 0x2c },
1425 { 0x5b, 0x0f },
1426 { 0x5c, 0x10 },
1427 { 0x3d, 0x80 },
1428 { 0x27, 0xa6 },
1429 { 0x12, 0x20 },
1430 { 0x12, 0x24 },
1431};
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444static const struct ov_i2c_regvals norm_7610[] = {
1445 { 0x10, 0xff },
1446 { 0x16, 0x06 },
1447 { 0x28, 0x24 },
1448 { 0x2b, 0xac },
1449 { 0x12, 0x00 },
1450 { 0x38, 0x81 },
1451 { 0x28, 0x24 },
1452 { 0x0f, 0x85 },
1453 { 0x15, 0x01 },
1454 { 0x20, 0x1c },
1455 { 0x23, 0x2a },
1456 { 0x24, 0x10 },
1457 { 0x25, 0x8a },
1458 { 0x26, 0xa2 },
1459 { 0x27, 0xc2 },
1460 { 0x2a, 0x04 },
1461 { 0x2c, 0xfe },
1462 { 0x2d, 0x93 },
1463 { 0x30, 0x71 },
1464 { 0x31, 0x60 },
1465 { 0x32, 0x26 },
1466 { 0x33, 0x20 },
1467 { 0x34, 0x48 },
1468 { 0x12, 0x24 },
1469 { 0x11, 0x01 },
1470 { 0x0c, 0x24 },
1471 { 0x0d, 0x24 },
1472};
1473
1474static const struct ov_i2c_regvals norm_7620[] = {
1475 { 0x12, 0x80 },
1476 { 0x00, 0x00 },
1477 { 0x01, 0x80 },
1478 { 0x02, 0x80 },
1479 { 0x03, 0xc0 },
1480 { 0x06, 0x60 },
1481 { 0x07, 0x00 },
1482 { 0x0c, 0x24 },
1483 { 0x0c, 0x24 },
1484 { 0x0d, 0x24 },
1485 { 0x11, 0x01 },
1486 { 0x12, 0x24 },
1487 { 0x13, 0x01 },
1488 { 0x14, 0x84 },
1489 { 0x15, 0x01 },
1490 { 0x16, 0x03 },
1491 { 0x17, 0x2f },
1492 { 0x18, 0xcf },
1493 { 0x19, 0x06 },
1494 { 0x1a, 0xf5 },
1495 { 0x1b, 0x00 },
1496 { 0x20, 0x18 },
1497 { 0x21, 0x80 },
1498 { 0x22, 0x80 },
1499 { 0x23, 0x00 },
1500 { 0x26, 0xa2 },
1501 { 0x27, 0xea },
1502 { 0x28, 0x22 },
1503 { 0x29, 0x00 },
1504 { 0x2a, 0x10 },
1505 { 0x2b, 0x00 },
1506 { 0x2c, 0x88 },
1507 { 0x2d, 0x91 },
1508 { 0x2e, 0x80 },
1509 { 0x2f, 0x44 },
1510 { 0x60, 0x27 },
1511 { 0x61, 0x02 },
1512 { 0x62, 0x5f },
1513 { 0x63, 0xd5 },
1514 { 0x64, 0x57 },
1515 { 0x65, 0x83 },
1516 { 0x66, 0x55 },
1517 { 0x67, 0x92 },
1518 { 0x68, 0xcf },
1519 { 0x69, 0x76 },
1520 { 0x6a, 0x22 },
1521 { 0x6b, 0x00 },
1522 { 0x6c, 0x02 },
1523 { 0x6d, 0x44 },
1524 { 0x6e, 0x80 },
1525 { 0x6f, 0x1d },
1526 { 0x70, 0x8b },
1527 { 0x71, 0x00 },
1528 { 0x72, 0x14 },
1529 { 0x73, 0x54 },
1530 { 0x74, 0x00 },
1531 { 0x75, 0x8e },
1532 { 0x76, 0x00 },
1533 { 0x77, 0xff },
1534 { 0x78, 0x80 },
1535 { 0x79, 0x80 },
1536 { 0x7a, 0x80 },
1537 { 0x7b, 0xe2 },
1538 { 0x7c, 0x00 },
1539};
1540
1541
1542static const struct ov_i2c_regvals norm_7640[] = {
1543 { 0x12, 0x80 },
1544 { 0x12, 0x14 },
1545};
1546
1547static const struct ov_regvals init_519_ov7660[] = {
1548 { 0x5d, 0x03 },
1549 { 0x53, 0x9b },
1550 { 0x54, 0x0f },
1551 { 0xa2, 0x20 },
1552 { 0xa3, 0x18 },
1553 { 0xa4, 0x04 },
1554 { 0xa5, 0x28 },
1555 { 0x37, 0x00 },
1556 { 0x55, 0x02 },
1557
1558 { 0x20, 0x0c },
1559 { 0x21, 0x38 },
1560 { 0x22, 0x1d },
1561 { 0x17, 0x50 },
1562 { 0x37, 0x00 },
1563 { 0x40, 0xff },
1564 { 0x46, 0x00 },
1565};
1566static const struct ov_i2c_regvals norm_7660[] = {
1567 {OV7670_R12_COM7, OV7670_COM7_RESET},
1568 {OV7670_R11_CLKRC, 0x81},
1569 {0x92, 0x00},
1570 {0x93, 0x00},
1571 {0x9d, 0x4c},
1572 {0x9e, 0x3f},
1573 {OV7670_R3B_COM11, 0x02},
1574 {OV7670_R13_COM8, 0xf5},
1575 {OV7670_R10_AECH, 0x00},
1576 {OV7670_R00_GAIN, 0x00},
1577 {OV7670_R01_BLUE, 0x7c},
1578 {OV7670_R02_RED, 0x9d},
1579 {OV7670_R12_COM7, 0x00},
1580 {OV7670_R04_COM1, 00},
1581 {OV7670_R18_HSTOP, 0x01},
1582 {OV7670_R17_HSTART, 0x13},
1583 {OV7670_R32_HREF, 0x92},
1584 {OV7670_R19_VSTART, 0x02},
1585 {OV7670_R1A_VSTOP, 0x7a},
1586 {OV7670_R03_VREF, 0x00},
1587 {OV7670_R0E_COM5, 0x04},
1588 {OV7670_R0F_COM6, 0x62},
1589 {OV7670_R15_COM10, 0x00},
1590 {0x16, 0x02},
1591 {0x1b, 0x00},
1592 {OV7670_R1E_MVFP, 0x01},
1593 {0x29, 0x3c},
1594 {0x33, 0x00},
1595 {0x34, 0x07},
1596 {0x35, 0x84},
1597 {0x36, 0x00},
1598 {0x37, 0x04},
1599 {0x39, 0x43},
1600 {OV7670_R3A_TSLB, 0x00},
1601 {OV7670_R3C_COM12, 0x6c},
1602 {OV7670_R3D_COM13, 0x98},
1603 {OV7670_R3F_EDGE, 0x23},
1604 {OV7670_R40_COM15, 0xc1},
1605 {OV7670_R41_COM16, 0x22},
1606 {0x6b, 0x0a},
1607 {0xa1, 0x08},
1608 {0x69, 0x80},
1609 {0x43, 0xf0},
1610 {0x44, 0x10},
1611 {0x45, 0x78},
1612 {0x46, 0xa8},
1613 {0x47, 0x60},
1614 {0x48, 0x80},
1615 {0x59, 0xba},
1616 {0x5a, 0x9a},
1617 {0x5b, 0x22},
1618 {0x5c, 0xb9},
1619 {0x5d, 0x9b},
1620 {0x5e, 0x10},
1621 {0x5f, 0xe0},
1622 {0x60, 0x85},
1623 {0x61, 0x60},
1624 {0x9f, 0x9d},
1625 {0xa0, 0xa0},
1626 {0x4f, 0x60},
1627 {0x50, 0x64},
1628 {0x51, 0x04},
1629 {0x52, 0x18},
1630 {0x53, 0x3c},
1631 {0x54, 0x54},
1632 {0x55, 0x40},
1633 {0x56, 0x40},
1634 {0x57, 0x40},
1635 {0x58, 0x0d},
1636 {0x8b, 0xcc},
1637 {0x8c, 0xcc},
1638 {0x8d, 0xcf},
1639 {0x6c, 0x40},
1640 {0x6d, 0xe0},
1641 {0x6e, 0xa0},
1642 {0x6f, 0x80},
1643 {0x70, 0x70},
1644 {0x71, 0x80},
1645 {0x72, 0x60},
1646 {0x73, 0x60},
1647 {0x74, 0x50},
1648 {0x75, 0x40},
1649 {0x76, 0x38},
1650 {0x77, 0x3c},
1651 {0x78, 0x32},
1652 {0x79, 0x1a},
1653 {0x7a, 0x28},
1654 {0x7b, 0x24},
1655 {0x7c, 0x04},
1656 {0x7d, 0x12},
1657 {0x7e, 0x26},
1658 {0x7f, 0x46},
1659 {0x80, 0x54},
1660 {0x81, 0x64},
1661 {0x82, 0x70},
1662 {0x83, 0x7c},
1663 {0x84, 0x86},
1664 {0x85, 0x8e},
1665 {0x86, 0x9c},
1666 {0x87, 0xab},
1667 {0x88, 0xc4},
1668 {0x89, 0xd1},
1669 {0x8a, 0xe5},
1670 {OV7670_R14_COM9, 0x1e},
1671 {OV7670_R24_AEW, 0x80},
1672 {OV7670_R25_AEB, 0x72},
1673 {OV7670_R26_VPT, 0xb3},
1674 {0x62, 0x80},
1675 {0x63, 0x80},
1676 {0x64, 0x06},
1677 {0x65, 0x00},
1678 {0x66, 0x01},
1679 {0x94, 0x0e},
1680 {0x95, 0x14},
1681 {OV7670_R13_COM8, OV7670_COM8_FASTAEC
1682 | OV7670_COM8_AECSTEP
1683 | OV7670_COM8_BFILT
1684 | 0x10
1685 | OV7670_COM8_AGC
1686 | OV7670_COM8_AWB
1687 | OV7670_COM8_AEC},
1688 {0xa1, 0xc8}
1689};
1690static const struct ov_i2c_regvals norm_9600[] = {
1691 {0x12, 0x80},
1692 {0x0c, 0x28},
1693 {0x11, 0x80},
1694 {0x13, 0xb5},
1695 {0x14, 0x3e},
1696 {0x1b, 0x04},
1697 {0x24, 0xb0},
1698 {0x25, 0x90},
1699 {0x26, 0x94},
1700 {0x35, 0x90},
1701 {0x37, 0x07},
1702 {0x38, 0x08},
1703 {0x01, 0x8e},
1704 {0x02, 0x85}
1705};
1706
1707
1708
1709static const struct ov_i2c_regvals norm_7670[] = {
1710 { OV7670_R12_COM7, OV7670_COM7_RESET },
1711 { OV7670_R3A_TSLB, 0x04 },
1712 { OV7670_R12_COM7, OV7670_COM7_FMT_VGA },
1713 { OV7670_R11_CLKRC, 0x01 },
1714
1715
1716
1717
1718 { OV7670_R17_HSTART, 0x13 },
1719 { OV7670_R18_HSTOP, 0x01 },
1720 { OV7670_R32_HREF, 0xb6 },
1721 { OV7670_R19_VSTART, 0x02 },
1722 { OV7670_R1A_VSTOP, 0x7a },
1723 { OV7670_R03_VREF, 0x0a },
1724
1725 { OV7670_R0C_COM3, 0x00 },
1726 { OV7670_R3E_COM14, 0x00 },
1727
1728 { 0x70, 0x3a },
1729 { 0x71, 0x35 },
1730 { 0x72, 0x11 },
1731 { 0x73, 0xf0 },
1732 { 0xa2, 0x02 },
1733
1734
1735
1736 { 0x7a, 0x20 },
1737 { 0x7b, 0x10 },
1738 { 0x7c, 0x1e },
1739 { 0x7d, 0x35 },
1740 { 0x7e, 0x5a },
1741 { 0x7f, 0x69 },
1742 { 0x80, 0x76 },
1743 { 0x81, 0x80 },
1744 { 0x82, 0x88 },
1745 { 0x83, 0x8f },
1746 { 0x84, 0x96 },
1747 { 0x85, 0xa3 },
1748 { 0x86, 0xaf },
1749 { 0x87, 0xc4 },
1750 { 0x88, 0xd7 },
1751 { 0x89, 0xe8 },
1752
1753
1754
1755 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
1756 | OV7670_COM8_AECSTEP
1757 | OV7670_COM8_BFILT },
1758 { OV7670_R00_GAIN, 0x00 },
1759 { OV7670_R10_AECH, 0x00 },
1760 { OV7670_R0D_COM4, 0x40 },
1761 { OV7670_R14_COM9, 0x18 },
1762 { OV7670_RA5_BD50MAX, 0x05 },
1763 { OV7670_RAB_BD60MAX, 0x07 },
1764 { OV7670_R24_AEW, 0x95 },
1765 { OV7670_R25_AEB, 0x33 },
1766 { OV7670_R26_VPT, 0xe3 },
1767 { OV7670_R9F_HAECC1, 0x78 },
1768 { OV7670_RA0_HAECC2, 0x68 },
1769 { 0xa1, 0x03 },
1770 { OV7670_RA6_HAECC3, 0xd8 },
1771 { OV7670_RA7_HAECC4, 0xd8 },
1772 { OV7670_RA8_HAECC5, 0xf0 },
1773 { OV7670_RA9_HAECC6, 0x90 },
1774 { OV7670_RAA_HAECC7, 0x94 },
1775 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
1776 | OV7670_COM8_AECSTEP
1777 | OV7670_COM8_BFILT
1778 | OV7670_COM8_AGC
1779 | OV7670_COM8_AEC },
1780
1781
1782 { OV7670_R0E_COM5, 0x61 },
1783 { OV7670_R0F_COM6, 0x4b },
1784 { 0x16, 0x02 },
1785 { OV7670_R1E_MVFP, 0x07 },
1786 { 0x21, 0x02 },
1787 { 0x22, 0x91 },
1788 { 0x29, 0x07 },
1789 { 0x33, 0x0b },
1790 { 0x35, 0x0b },
1791 { 0x37, 0x1d },
1792 { 0x38, 0x71 },
1793 { 0x39, 0x2a },
1794 { OV7670_R3C_COM12, 0x78 },
1795 { 0x4d, 0x40 },
1796 { 0x4e, 0x20 },
1797 { OV7670_R69_GFIX, 0x00 },
1798 { 0x6b, 0x4a },
1799 { 0x74, 0x10 },
1800 { 0x8d, 0x4f },
1801 { 0x8e, 0x00 },
1802 { 0x8f, 0x00 },
1803 { 0x90, 0x00 },
1804 { 0x91, 0x00 },
1805 { 0x96, 0x00 },
1806 { 0x9a, 0x00 },
1807 { 0xb0, 0x84 },
1808 { 0xb1, 0x0c },
1809 { 0xb2, 0x0e },
1810 { 0xb3, 0x82 },
1811 { 0xb8, 0x0a },
1812
1813
1814 { 0x43, 0x0a },
1815 { 0x44, 0xf0 },
1816 { 0x45, 0x34 },
1817 { 0x46, 0x58 },
1818 { 0x47, 0x28 },
1819 { 0x48, 0x3a },
1820 { 0x59, 0x88 },
1821 { 0x5a, 0x88 },
1822 { 0x5b, 0x44 },
1823 { 0x5c, 0x67 },
1824 { 0x5d, 0x49 },
1825 { 0x5e, 0x0e },
1826 { 0x6c, 0x0a },
1827 { 0x6d, 0x55 },
1828 { 0x6e, 0x11 },
1829 { 0x6f, 0x9f },
1830 { 0x6a, 0x40 },
1831 { OV7670_R01_BLUE, 0x40 },
1832 { OV7670_R02_RED, 0x60 },
1833 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
1834 | OV7670_COM8_AECSTEP
1835 | OV7670_COM8_BFILT
1836 | OV7670_COM8_AGC
1837 | OV7670_COM8_AEC
1838 | OV7670_COM8_AWB },
1839
1840
1841 { 0x4f, 0x80 },
1842 { 0x50, 0x80 },
1843 { 0x51, 0x00 },
1844 { 0x52, 0x22 },
1845 { 0x53, 0x5e },
1846 { 0x54, 0x80 },
1847 { 0x58, 0x9e },
1848
1849 { OV7670_R41_COM16, OV7670_COM16_AWBGAIN },
1850 { OV7670_R3F_EDGE, 0x00 },
1851 { 0x75, 0x05 },
1852 { 0x76, 0xe1 },
1853 { 0x4c, 0x00 },
1854 { 0x77, 0x01 },
1855 { OV7670_R3D_COM13, OV7670_COM13_GAMMA
1856 | OV7670_COM13_UVSAT
1857 | 2},
1858 { 0x4b, 0x09 },
1859 { 0xc9, 0x60 },
1860 { OV7670_R41_COM16, 0x38 },
1861 { 0x56, 0x40 },
1862
1863 { 0x34, 0x11 },
1864 { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
1865 { 0xa4, 0x88 },
1866 { 0x96, 0x00 },
1867 { 0x97, 0x30 },
1868 { 0x98, 0x20 },
1869 { 0x99, 0x30 },
1870 { 0x9a, 0x84 },
1871 { 0x9b, 0x29 },
1872 { 0x9c, 0x03 },
1873 { 0x9d, 0x4c },
1874 { 0x9e, 0x3f },
1875 { 0x78, 0x04 },
1876
1877
1878 { 0x79, 0x01 },
1879 { 0xc8, 0xf0 },
1880 { 0x79, 0x0f },
1881 { 0xc8, 0x00 },
1882 { 0x79, 0x10 },
1883 { 0xc8, 0x7e },
1884 { 0x79, 0x0a },
1885 { 0xc8, 0x80 },
1886 { 0x79, 0x0b },
1887 { 0xc8, 0x01 },
1888 { 0x79, 0x0c },
1889 { 0xc8, 0x0f },
1890 { 0x79, 0x0d },
1891 { 0xc8, 0x20 },
1892 { 0x79, 0x09 },
1893 { 0xc8, 0x80 },
1894 { 0x79, 0x02 },
1895 { 0xc8, 0xc0 },
1896 { 0x79, 0x03 },
1897 { 0xc8, 0x40 },
1898 { 0x79, 0x05 },
1899 { 0xc8, 0x30 },
1900 { 0x79, 0x26 },
1901};
1902
1903static const struct ov_i2c_regvals norm_8610[] = {
1904 { 0x12, 0x80 },
1905 { 0x00, 0x00 },
1906 { 0x01, 0x80 },
1907 { 0x02, 0x80 },
1908 { 0x03, 0xc0 },
1909 { 0x04, 0x30 },
1910 { 0x05, 0x30 },
1911 { 0x06, 0x70 },
1912 { 0x0a, 0x86 },
1913 { 0x0b, 0xb0 },
1914 { 0x0c, 0x20 },
1915 { 0x0d, 0x20 },
1916 { 0x11, 0x01 },
1917 { 0x12, 0x25 },
1918 { 0x13, 0x01 },
1919 { 0x14, 0x04 },
1920 { 0x15, 0x01 },
1921 { 0x16, 0x03 },
1922 { 0x17, 0x38 },
1923 { 0x18, 0xea },
1924 { 0x19, 0x02 },
1925 { 0x1a, 0xf5 },
1926 { 0x1b, 0x00 },
1927 { 0x20, 0xd0 },
1928 { 0x23, 0xc0 },
1929 { 0x24, 0x30 },
1930 { 0x25, 0x50 },
1931 { 0x26, 0xa2 },
1932 { 0x27, 0xea },
1933 { 0x28, 0x00 },
1934 { 0x29, 0x00 },
1935 { 0x2a, 0x80 },
1936 { 0x2b, 0xc8 },
1937 { 0x2c, 0xac },
1938 { 0x2d, 0x45 },
1939 { 0x2e, 0x80 },
1940 { 0x2f, 0x14 },
1941 { 0x4c, 0x00 },
1942 { 0x4d, 0x30 },
1943 { 0x60, 0x02 },
1944 { 0x61, 0x00 },
1945 { 0x62, 0x5f },
1946 { 0x63, 0xff },
1947 { 0x64, 0x53 },
1948
1949 { 0x65, 0x00 },
1950 { 0x66, 0x55 },
1951 { 0x67, 0xb0 },
1952 { 0x68, 0xc0 },
1953 { 0x69, 0x02 },
1954 { 0x6a, 0x22 },
1955 { 0x6b, 0x00 },
1956 { 0x6c, 0x99 },
1957
1958 { 0x6d, 0x11 },
1959 { 0x6e, 0x11 },
1960 { 0x6f, 0x01 },
1961 { 0x70, 0x8b },
1962 { 0x71, 0x00 },
1963 { 0x72, 0x14 },
1964 { 0x73, 0x54 },
1965 { 0x74, 0x00 },
1966 { 0x75, 0x0e },
1967 { 0x76, 0x02 },
1968 { 0x77, 0xff },
1969 { 0x78, 0x80 },
1970 { 0x79, 0x80 },
1971 { 0x7a, 0x80 },
1972 { 0x7b, 0x10 },
1973 { 0x7c, 0x00 },
1974 { 0x7d, 0x08 },
1975 { 0x7e, 0x08 },
1976 { 0x7f, 0xfb },
1977 { 0x80, 0x28 },
1978 { 0x81, 0x00 },
1979 { 0x82, 0x23 },
1980 { 0x83, 0x0b },
1981 { 0x84, 0x00 },
1982 { 0x85, 0x62 },
1983 { 0x86, 0xc9 },
1984 { 0x87, 0x00 },
1985 { 0x88, 0x00 },
1986 { 0x89, 0x01 },
1987 { 0x12, 0x20 },
1988 { 0x12, 0x25 },
1989};
1990
1991static unsigned char ov7670_abs_to_sm(unsigned char v)
1992{
1993 if (v > 127)
1994 return v & 0x7f;
1995 return (128 - v) | 0x80;
1996}
1997
1998
1999static void reg_w(struct sd *sd, u16 index, u16 value)
2000{
2001 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2002 int ret, req = 0;
2003
2004 if (sd->gspca_dev.usb_err < 0)
2005 return;
2006
2007
2008 udelay(150);
2009
2010 switch (sd->bridge) {
2011 case BRIDGE_OV511:
2012 case BRIDGE_OV511PLUS:
2013 req = 2;
2014 break;
2015 case BRIDGE_OVFX2:
2016 req = 0x0a;
2017
2018 case BRIDGE_W9968CF:
2019 PDEBUG(D_USBO, "SET %02x %04x %04x",
2020 req, value, index);
2021 ret = usb_control_msg(sd->gspca_dev.dev,
2022 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2023 req,
2024 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2025 value, index, NULL, 0, 500);
2026 goto leave;
2027 default:
2028 req = 1;
2029 }
2030
2031 PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
2032 req, index, value);
2033 sd->gspca_dev.usb_buf[0] = value;
2034 ret = usb_control_msg(sd->gspca_dev.dev,
2035 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2036 req,
2037 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2038 0, index,
2039 sd->gspca_dev.usb_buf, 1, 500);
2040leave:
2041 if (ret < 0) {
2042 PERR("reg_w %02x failed %d\n", index, ret);
2043 sd->gspca_dev.usb_err = ret;
2044 return;
2045 }
2046}
2047
2048
2049
2050static int reg_r(struct sd *sd, u16 index)
2051{
2052 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2053 int ret;
2054 int req;
2055
2056 if (sd->gspca_dev.usb_err < 0)
2057 return -1;
2058
2059 switch (sd->bridge) {
2060 case BRIDGE_OV511:
2061 case BRIDGE_OV511PLUS:
2062 req = 3;
2063 break;
2064 case BRIDGE_OVFX2:
2065 req = 0x0b;
2066 break;
2067 default:
2068 req = 1;
2069 }
2070
2071
2072 udelay(150);
2073 ret = usb_control_msg(sd->gspca_dev.dev,
2074 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2075 req,
2076 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2077 0, index, sd->gspca_dev.usb_buf, 1, 500);
2078
2079 if (ret >= 0) {
2080 ret = sd->gspca_dev.usb_buf[0];
2081 PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
2082 req, index, ret);
2083 } else {
2084 PERR("reg_r %02x failed %d\n", index, ret);
2085 sd->gspca_dev.usb_err = ret;
2086 }
2087
2088 return ret;
2089}
2090
2091
2092static int reg_r8(struct sd *sd,
2093 u16 index)
2094{
2095 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2096 int ret;
2097
2098 if (sd->gspca_dev.usb_err < 0)
2099 return -1;
2100
2101
2102 udelay(150);
2103 ret = usb_control_msg(sd->gspca_dev.dev,
2104 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2105 1,
2106 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2107 0, index, sd->gspca_dev.usb_buf, 8, 500);
2108
2109 if (ret >= 0) {
2110 ret = sd->gspca_dev.usb_buf[0];
2111 } else {
2112 PERR("reg_r8 %02x failed %d\n", index, ret);
2113 sd->gspca_dev.usb_err = ret;
2114 }
2115
2116 return ret;
2117}
2118
2119
2120
2121
2122
2123
2124
2125static void reg_w_mask(struct sd *sd,
2126 u16 index,
2127 u8 value,
2128 u8 mask)
2129{
2130 int ret;
2131 u8 oldval;
2132
2133 if (mask != 0xff) {
2134 value &= mask;
2135 ret = reg_r(sd, index);
2136 if (ret < 0)
2137 return;
2138
2139 oldval = ret & ~mask;
2140 value |= oldval;
2141 }
2142 reg_w(sd, index, value);
2143}
2144
2145
2146
2147
2148
2149static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
2150{
2151 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2152 int ret;
2153
2154 if (sd->gspca_dev.usb_err < 0)
2155 return;
2156
2157 *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
2158
2159
2160 udelay(150);
2161 ret = usb_control_msg(sd->gspca_dev.dev,
2162 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2163 1 ,
2164 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2165 0, index,
2166 sd->gspca_dev.usb_buf, n, 500);
2167 if (ret < 0) {
2168 PERR("reg_w32 %02x failed %d\n", index, ret);
2169 sd->gspca_dev.usb_err = ret;
2170 }
2171}
2172
2173static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
2174{
2175 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2176 int rc, retries;
2177
2178 PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
2179
2180
2181 for (retries = 6; ; ) {
2182
2183 reg_w(sd, R51x_I2C_SADDR_3, reg);
2184
2185
2186 reg_w(sd, R51x_I2C_DATA, value);
2187
2188
2189 reg_w(sd, R511_I2C_CTL, 0x01);
2190
2191 do {
2192 rc = reg_r(sd, R511_I2C_CTL);
2193 } while (rc > 0 && ((rc & 1) == 0));
2194
2195 if (rc < 0)
2196 return;
2197
2198 if ((rc & 2) == 0)
2199 break;
2200 if (--retries < 0) {
2201 PDEBUG(D_USBO, "i2c write retries exhausted");
2202 return;
2203 }
2204 }
2205}
2206
2207static int ov511_i2c_r(struct sd *sd, u8 reg)
2208{
2209 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2210 int rc, value, retries;
2211
2212
2213 for (retries = 6; ; ) {
2214
2215 reg_w(sd, R51x_I2C_SADDR_2, reg);
2216
2217
2218 reg_w(sd, R511_I2C_CTL, 0x03);
2219
2220 do {
2221 rc = reg_r(sd, R511_I2C_CTL);
2222 } while (rc > 0 && ((rc & 1) == 0));
2223
2224 if (rc < 0)
2225 return rc;
2226
2227 if ((rc & 2) == 0)
2228 break;
2229
2230
2231 reg_w(sd, R511_I2C_CTL, 0x10);
2232
2233 if (--retries < 0) {
2234 PDEBUG(D_USBI, "i2c write retries exhausted");
2235 return -1;
2236 }
2237 }
2238
2239
2240 for (retries = 6; ; ) {
2241
2242 reg_w(sd, R511_I2C_CTL, 0x05);
2243
2244 do {
2245 rc = reg_r(sd, R511_I2C_CTL);
2246 } while (rc > 0 && ((rc & 1) == 0));
2247
2248 if (rc < 0)
2249 return rc;
2250
2251 if ((rc & 2) == 0)
2252 break;
2253
2254
2255 reg_w(sd, R511_I2C_CTL, 0x10);
2256
2257 if (--retries < 0) {
2258 PDEBUG(D_USBI, "i2c read retries exhausted");
2259 return -1;
2260 }
2261 }
2262
2263 value = reg_r(sd, R51x_I2C_DATA);
2264
2265 PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
2266
2267
2268 reg_w(sd, R511_I2C_CTL, 0x05);
2269
2270 return value;
2271}
2272
2273
2274
2275
2276
2277
2278static void ov518_i2c_w(struct sd *sd,
2279 u8 reg,
2280 u8 value)
2281{
2282 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2283
2284 PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
2285
2286
2287 reg_w(sd, R51x_I2C_SADDR_3, reg);
2288
2289
2290 reg_w(sd, R51x_I2C_DATA, value);
2291
2292
2293 reg_w(sd, R518_I2C_CTL, 0x01);
2294
2295
2296 msleep(4);
2297 reg_r8(sd, R518_I2C_CTL);
2298}
2299
2300
2301
2302
2303
2304
2305
2306
2307static int ov518_i2c_r(struct sd *sd, u8 reg)
2308{
2309 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2310 int value;
2311
2312
2313 reg_w(sd, R51x_I2C_SADDR_2, reg);
2314
2315
2316 reg_w(sd, R518_I2C_CTL, 0x03);
2317 reg_r8(sd, R518_I2C_CTL);
2318
2319
2320 reg_w(sd, R518_I2C_CTL, 0x05);
2321 reg_r8(sd, R518_I2C_CTL);
2322
2323 value = reg_r(sd, R51x_I2C_DATA);
2324 PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
2325 return value;
2326}
2327
2328static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
2329{
2330 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2331 int ret;
2332
2333 if (sd->gspca_dev.usb_err < 0)
2334 return;
2335
2336 ret = usb_control_msg(sd->gspca_dev.dev,
2337 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2338 0x02,
2339 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2340 (u16) value, (u16) reg, NULL, 0, 500);
2341
2342 if (ret < 0) {
2343 PERR("ovfx2_i2c_w %02x failed %d\n", reg, ret);
2344 sd->gspca_dev.usb_err = ret;
2345 }
2346
2347 PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
2348}
2349
2350static int ovfx2_i2c_r(struct sd *sd, u8 reg)
2351{
2352 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2353 int ret;
2354
2355 if (sd->gspca_dev.usb_err < 0)
2356 return -1;
2357
2358 ret = usb_control_msg(sd->gspca_dev.dev,
2359 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2360 0x03,
2361 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2362 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500);
2363
2364 if (ret >= 0) {
2365 ret = sd->gspca_dev.usb_buf[0];
2366 PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
2367 } else {
2368 PERR("ovfx2_i2c_r %02x failed %d\n", reg, ret);
2369 sd->gspca_dev.usb_err = ret;
2370 }
2371
2372 return ret;
2373}
2374
2375static void i2c_w(struct sd *sd, u8 reg, u8 value)
2376{
2377 if (sd->sensor_reg_cache[reg] == value)
2378 return;
2379
2380 switch (sd->bridge) {
2381 case BRIDGE_OV511:
2382 case BRIDGE_OV511PLUS:
2383 ov511_i2c_w(sd, reg, value);
2384 break;
2385 case BRIDGE_OV518:
2386 case BRIDGE_OV518PLUS:
2387 case BRIDGE_OV519:
2388 ov518_i2c_w(sd, reg, value);
2389 break;
2390 case BRIDGE_OVFX2:
2391 ovfx2_i2c_w(sd, reg, value);
2392 break;
2393 case BRIDGE_W9968CF:
2394 w9968cf_i2c_w(sd, reg, value);
2395 break;
2396 }
2397
2398 if (sd->gspca_dev.usb_err >= 0) {
2399
2400 if (reg == 0x12 && (value & 0x80))
2401 memset(sd->sensor_reg_cache, -1,
2402 sizeof(sd->sensor_reg_cache));
2403 else
2404 sd->sensor_reg_cache[reg] = value;
2405 }
2406}
2407
2408static int i2c_r(struct sd *sd, u8 reg)
2409{
2410 int ret = -1;
2411
2412 if (sd->sensor_reg_cache[reg] != -1)
2413 return sd->sensor_reg_cache[reg];
2414
2415 switch (sd->bridge) {
2416 case BRIDGE_OV511:
2417 case BRIDGE_OV511PLUS:
2418 ret = ov511_i2c_r(sd, reg);
2419 break;
2420 case BRIDGE_OV518:
2421 case BRIDGE_OV518PLUS:
2422 case BRIDGE_OV519:
2423 ret = ov518_i2c_r(sd, reg);
2424 break;
2425 case BRIDGE_OVFX2:
2426 ret = ovfx2_i2c_r(sd, reg);
2427 break;
2428 case BRIDGE_W9968CF:
2429 ret = w9968cf_i2c_r(sd, reg);
2430 break;
2431 }
2432
2433 if (ret >= 0)
2434 sd->sensor_reg_cache[reg] = ret;
2435
2436 return ret;
2437}
2438
2439
2440
2441
2442
2443
2444static void i2c_w_mask(struct sd *sd,
2445 u8 reg,
2446 u8 value,
2447 u8 mask)
2448{
2449 int rc;
2450 u8 oldval;
2451
2452 value &= mask;
2453 rc = i2c_r(sd, reg);
2454 if (rc < 0)
2455 return;
2456 oldval = rc & ~mask;
2457 value |= oldval;
2458 i2c_w(sd, reg, value);
2459}
2460
2461
2462
2463static inline void ov51x_stop(struct sd *sd)
2464{
2465 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2466
2467 PDEBUG(D_STREAM, "stopping");
2468 sd->stopped = 1;
2469 switch (sd->bridge) {
2470 case BRIDGE_OV511:
2471 case BRIDGE_OV511PLUS:
2472 reg_w(sd, R51x_SYS_RESET, 0x3d);
2473 break;
2474 case BRIDGE_OV518:
2475 case BRIDGE_OV518PLUS:
2476 reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
2477 break;
2478 case BRIDGE_OV519:
2479 reg_w(sd, OV519_R51_RESET1, 0x0f);
2480 reg_w(sd, OV519_R51_RESET1, 0x00);
2481 reg_w(sd, 0x22, 0x00);
2482 break;
2483 case BRIDGE_OVFX2:
2484 reg_w_mask(sd, 0x0f, 0x00, 0x02);
2485 break;
2486 case BRIDGE_W9968CF:
2487 reg_w(sd, 0x3c, 0x0a05);
2488 break;
2489 }
2490}
2491
2492
2493
2494static inline void ov51x_restart(struct sd *sd)
2495{
2496 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2497
2498 PDEBUG(D_STREAM, "restarting");
2499 if (!sd->stopped)
2500 return;
2501 sd->stopped = 0;
2502
2503
2504 switch (sd->bridge) {
2505 case BRIDGE_OV511:
2506 case BRIDGE_OV511PLUS:
2507 reg_w(sd, R51x_SYS_RESET, 0x00);
2508 break;
2509 case BRIDGE_OV518:
2510 case BRIDGE_OV518PLUS:
2511 reg_w(sd, 0x2f, 0x80);
2512 reg_w(sd, R51x_SYS_RESET, 0x00);
2513 break;
2514 case BRIDGE_OV519:
2515 reg_w(sd, OV519_R51_RESET1, 0x0f);
2516 reg_w(sd, OV519_R51_RESET1, 0x00);
2517 reg_w(sd, 0x22, 0x1d);
2518 break;
2519 case BRIDGE_OVFX2:
2520 reg_w_mask(sd, 0x0f, 0x02, 0x02);
2521 break;
2522 case BRIDGE_W9968CF:
2523 reg_w(sd, 0x3c, 0x8a05);
2524 break;
2525 }
2526}
2527
2528static void ov51x_set_slave_ids(struct sd *sd, u8 slave);
2529
2530
2531
2532
2533static int init_ov_sensor(struct sd *sd, u8 slave)
2534{
2535 int i;
2536 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2537
2538 ov51x_set_slave_ids(sd, slave);
2539
2540
2541 i2c_w(sd, 0x12, 0x80);
2542
2543
2544 msleep(150);
2545
2546 for (i = 0; i < i2c_detect_tries; i++) {
2547 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
2548 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
2549 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
2550 return 0;
2551 }
2552
2553
2554 i2c_w(sd, 0x12, 0x80);
2555
2556
2557 msleep(150);
2558
2559
2560 if (i2c_r(sd, 0x00) < 0)
2561 return -1;
2562 }
2563 return -1;
2564}
2565
2566
2567
2568
2569
2570
2571static void ov51x_set_slave_ids(struct sd *sd,
2572 u8 slave)
2573{
2574 switch (sd->bridge) {
2575 case BRIDGE_OVFX2:
2576 reg_w(sd, OVFX2_I2C_ADDR, slave);
2577 return;
2578 case BRIDGE_W9968CF:
2579 sd->sensor_addr = slave;
2580 return;
2581 }
2582
2583 reg_w(sd, R51x_I2C_W_SID, slave);
2584 reg_w(sd, R51x_I2C_R_SID, slave + 1);
2585}
2586
2587static void write_regvals(struct sd *sd,
2588 const struct ov_regvals *regvals,
2589 int n)
2590{
2591 while (--n >= 0) {
2592 reg_w(sd, regvals->reg, regvals->val);
2593 regvals++;
2594 }
2595}
2596
2597static void write_i2c_regvals(struct sd *sd,
2598 const struct ov_i2c_regvals *regvals,
2599 int n)
2600{
2601 while (--n >= 0) {
2602 i2c_w(sd, regvals->reg, regvals->val);
2603 regvals++;
2604 }
2605}
2606
2607
2608
2609
2610
2611
2612
2613
2614static void ov_hires_configure(struct sd *sd)
2615{
2616 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2617 int high, low;
2618
2619 if (sd->bridge != BRIDGE_OVFX2) {
2620 PERR("error hires sensors only supported with ovfx2\n");
2621 return;
2622 }
2623
2624 PDEBUG(D_PROBE, "starting ov hires configuration");
2625
2626
2627 high = i2c_r(sd, 0x0a);
2628 low = i2c_r(sd, 0x0b);
2629
2630 switch (high) {
2631 case 0x96:
2632 switch (low) {
2633 case 0x40:
2634 PDEBUG(D_PROBE, "Sensor is a OV2610");
2635 sd->sensor = SEN_OV2610;
2636 return;
2637 case 0x41:
2638 PDEBUG(D_PROBE, "Sensor is a OV2610AE");
2639 sd->sensor = SEN_OV2610AE;
2640 return;
2641 case 0xb1:
2642 PDEBUG(D_PROBE, "Sensor is a OV9600");
2643 sd->sensor = SEN_OV9600;
2644 return;
2645 }
2646 break;
2647 case 0x36:
2648 if ((low & 0x0f) == 0x00) {
2649 PDEBUG(D_PROBE, "Sensor is a OV3610");
2650 sd->sensor = SEN_OV3610;
2651 return;
2652 }
2653 break;
2654 }
2655 PERR("Error unknown sensor type: %02x%02x\n", high, low);
2656}
2657
2658
2659
2660
2661static void ov8xx0_configure(struct sd *sd)
2662{
2663 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2664 int rc;
2665
2666 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
2667
2668
2669 rc = i2c_r(sd, OV7610_REG_COM_I);
2670 if (rc < 0) {
2671 PERR("Error detecting sensor type");
2672 return;
2673 }
2674 if ((rc & 3) == 1)
2675 sd->sensor = SEN_OV8610;
2676 else
2677 PERR("Unknown image sensor version: %d\n", rc & 3);
2678}
2679
2680
2681
2682
2683static void ov7xx0_configure(struct sd *sd)
2684{
2685 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2686 int rc, high, low;
2687
2688 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
2689
2690
2691 rc = i2c_r(sd, OV7610_REG_COM_I);
2692
2693
2694
2695 if (rc < 0) {
2696 PERR("Error detecting sensor type\n");
2697 return;
2698 }
2699 if ((rc & 3) == 3) {
2700
2701 high = i2c_r(sd, 0x0a);
2702 low = i2c_r(sd, 0x0b);
2703
2704 if (high == 0x76 && (low & 0xf0) == 0x70) {
2705 PDEBUG(D_PROBE, "Sensor is an OV76%02x", low);
2706 sd->sensor = SEN_OV7670;
2707 } else {
2708 PDEBUG(D_PROBE, "Sensor is an OV7610");
2709 sd->sensor = SEN_OV7610;
2710 }
2711 } else if ((rc & 3) == 1) {
2712
2713 if (i2c_r(sd, 0x15) & 1) {
2714 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
2715 sd->sensor = SEN_OV7620AE;
2716 } else {
2717 PDEBUG(D_PROBE, "Sensor is an OV76BE");
2718 sd->sensor = SEN_OV76BE;
2719 }
2720 } else if ((rc & 3) == 0) {
2721
2722 high = i2c_r(sd, 0x0a);
2723 if (high < 0) {
2724 PERR("Error detecting camera chip PID\n");
2725 return;
2726 }
2727 low = i2c_r(sd, 0x0b);
2728 if (low < 0) {
2729 PERR("Error detecting camera chip VER\n");
2730 return;
2731 }
2732 if (high == 0x76) {
2733 switch (low) {
2734 case 0x30:
2735 PERR("Sensor is an OV7630/OV7635\n");
2736 PERR("7630 is not supported by this driver\n");
2737 return;
2738 case 0x40:
2739 PDEBUG(D_PROBE, "Sensor is an OV7645");
2740 sd->sensor = SEN_OV7640;
2741 break;
2742 case 0x45:
2743 PDEBUG(D_PROBE, "Sensor is an OV7645B");
2744 sd->sensor = SEN_OV7640;
2745 break;
2746 case 0x48:
2747 PDEBUG(D_PROBE, "Sensor is an OV7648");
2748 sd->sensor = SEN_OV7648;
2749 break;
2750 case 0x60:
2751 PDEBUG(D_PROBE, "Sensor is a OV7660");
2752 sd->sensor = SEN_OV7660;
2753 break;
2754 default:
2755 PERR("Unknown sensor: 0x76%02x\n", low);
2756 return;
2757 }
2758 } else {
2759 PDEBUG(D_PROBE, "Sensor is an OV7620");
2760 sd->sensor = SEN_OV7620;
2761 }
2762 } else {
2763 PERR("Unknown image sensor version: %d\n", rc & 3);
2764 }
2765}
2766
2767
2768static void ov6xx0_configure(struct sd *sd)
2769{
2770 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2771 int rc;
2772
2773 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
2774
2775
2776 rc = i2c_r(sd, OV7610_REG_COM_I);
2777 if (rc < 0) {
2778 PERR("Error detecting sensor type\n");
2779 return;
2780 }
2781
2782
2783
2784
2785 switch (rc) {
2786 case 0x00:
2787 sd->sensor = SEN_OV6630;
2788 pr_warn("WARNING: Sensor is an OV66308. Your camera may have been misdetected in previous driver versions.\n");
2789 break;
2790 case 0x01:
2791 sd->sensor = SEN_OV6620;
2792 PDEBUG(D_PROBE, "Sensor is an OV6620");
2793 break;
2794 case 0x02:
2795 sd->sensor = SEN_OV6630;
2796 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
2797 break;
2798 case 0x03:
2799 sd->sensor = SEN_OV66308AF;
2800 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
2801 break;
2802 case 0x90:
2803 sd->sensor = SEN_OV6630;
2804 pr_warn("WARNING: Sensor is an OV66307. Your camera may have been misdetected in previous driver versions.\n");
2805 break;
2806 default:
2807 PERR("FATAL: Unknown sensor version: 0x%02x\n", rc);
2808 return;
2809 }
2810
2811
2812 sd->sif = 1;
2813}
2814
2815
2816static void ov51x_led_control(struct sd *sd, int on)
2817{
2818 if (sd->invert_led)
2819 on = !on;
2820
2821 switch (sd->bridge) {
2822
2823 case BRIDGE_OV511PLUS:
2824 reg_w(sd, R511_SYS_LED_CTL, on);
2825 break;
2826 case BRIDGE_OV518:
2827 case BRIDGE_OV518PLUS:
2828 reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02);
2829 break;
2830 case BRIDGE_OV519:
2831 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1);
2832 break;
2833 }
2834}
2835
2836static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
2837{
2838 struct sd *sd = (struct sd *) gspca_dev;
2839
2840 if (!sd->snapshot_needs_reset)
2841 return;
2842
2843
2844
2845
2846 sd->snapshot_needs_reset = 0;
2847
2848 switch (sd->bridge) {
2849 case BRIDGE_OV511:
2850 case BRIDGE_OV511PLUS:
2851 reg_w(sd, R51x_SYS_SNAP, 0x02);
2852 reg_w(sd, R51x_SYS_SNAP, 0x00);
2853 break;
2854 case BRIDGE_OV518:
2855 case BRIDGE_OV518PLUS:
2856 reg_w(sd, R51x_SYS_SNAP, 0x02);
2857 reg_w(sd, R51x_SYS_SNAP, 0x01);
2858 break;
2859 case BRIDGE_OV519:
2860 reg_w(sd, R51x_SYS_RESET, 0x40);
2861 reg_w(sd, R51x_SYS_RESET, 0x00);
2862 break;
2863 }
2864}
2865
2866static void ov51x_upload_quan_tables(struct sd *sd)
2867{
2868 const unsigned char yQuanTable511[] = {
2869 0, 1, 1, 2, 2, 3, 3, 4,
2870 1, 1, 1, 2, 2, 3, 4, 4,
2871 1, 1, 2, 2, 3, 4, 4, 4,
2872 2, 2, 2, 3, 4, 4, 4, 4,
2873 2, 2, 3, 4, 4, 5, 5, 5,
2874 3, 3, 4, 4, 5, 5, 5, 5,
2875 3, 4, 4, 4, 5, 5, 5, 5,
2876 4, 4, 4, 4, 5, 5, 5, 5
2877 };
2878
2879 const unsigned char uvQuanTable511[] = {
2880 0, 2, 2, 3, 4, 4, 4, 4,
2881 2, 2, 2, 4, 4, 4, 4, 4,
2882 2, 2, 3, 4, 4, 4, 4, 4,
2883 3, 4, 4, 4, 4, 4, 4, 4,
2884 4, 4, 4, 4, 4, 4, 4, 4,
2885 4, 4, 4, 4, 4, 4, 4, 4,
2886 4, 4, 4, 4, 4, 4, 4, 4,
2887 4, 4, 4, 4, 4, 4, 4, 4
2888 };
2889
2890
2891 const unsigned char yQuanTable518[] = {
2892 5, 4, 5, 6, 6, 7, 7, 7,
2893 5, 5, 5, 5, 6, 7, 7, 7,
2894 6, 6, 6, 6, 7, 7, 7, 8,
2895 7, 7, 6, 7, 7, 7, 8, 8
2896 };
2897 const unsigned char uvQuanTable518[] = {
2898 6, 6, 6, 7, 7, 7, 7, 7,
2899 6, 6, 6, 7, 7, 7, 7, 7,
2900 6, 6, 6, 7, 7, 7, 7, 8,
2901 7, 7, 7, 7, 7, 7, 8, 8
2902 };
2903
2904 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2905 const unsigned char *pYTable, *pUVTable;
2906 unsigned char val0, val1;
2907 int i, size, reg = R51x_COMP_LUT_BEGIN;
2908
2909 PDEBUG(D_PROBE, "Uploading quantization tables");
2910
2911 if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
2912 pYTable = yQuanTable511;
2913 pUVTable = uvQuanTable511;
2914 size = 32;
2915 } else {
2916 pYTable = yQuanTable518;
2917 pUVTable = uvQuanTable518;
2918 size = 16;
2919 }
2920
2921 for (i = 0; i < size; i++) {
2922 val0 = *pYTable++;
2923 val1 = *pYTable++;
2924 val0 &= 0x0f;
2925 val1 &= 0x0f;
2926 val0 |= val1 << 4;
2927 reg_w(sd, reg, val0);
2928
2929 val0 = *pUVTable++;
2930 val1 = *pUVTable++;
2931 val0 &= 0x0f;
2932 val1 &= 0x0f;
2933 val0 |= val1 << 4;
2934 reg_w(sd, reg + size, val0);
2935
2936 reg++;
2937 }
2938}
2939
2940
2941static void ov511_configure(struct gspca_dev *gspca_dev)
2942{
2943 struct sd *sd = (struct sd *) gspca_dev;
2944
2945
2946 const struct ov_regvals init_511[] = {
2947 { R51x_SYS_RESET, 0x7f },
2948 { R51x_SYS_INIT, 0x01 },
2949 { R51x_SYS_RESET, 0x7f },
2950 { R51x_SYS_INIT, 0x01 },
2951 { R51x_SYS_RESET, 0x3f },
2952 { R51x_SYS_INIT, 0x01 },
2953 { R51x_SYS_RESET, 0x3d },
2954 };
2955
2956 const struct ov_regvals norm_511[] = {
2957 { R511_DRAM_FLOW_CTL, 0x01 },
2958 { R51x_SYS_SNAP, 0x00 },
2959 { R51x_SYS_SNAP, 0x02 },
2960 { R51x_SYS_SNAP, 0x00 },
2961 { R511_FIFO_OPTS, 0x1f },
2962 { R511_COMP_EN, 0x00 },
2963 { R511_COMP_LUT_EN, 0x03 },
2964 };
2965
2966 const struct ov_regvals norm_511_p[] = {
2967 { R511_DRAM_FLOW_CTL, 0xff },
2968 { R51x_SYS_SNAP, 0x00 },
2969 { R51x_SYS_SNAP, 0x02 },
2970 { R51x_SYS_SNAP, 0x00 },
2971 { R511_FIFO_OPTS, 0xff },
2972 { R511_COMP_EN, 0x00 },
2973 { R511_COMP_LUT_EN, 0x03 },
2974 };
2975
2976 const struct ov_regvals compress_511[] = {
2977 { 0x70, 0x1f },
2978 { 0x71, 0x05 },
2979 { 0x72, 0x06 },
2980 { 0x73, 0x06 },
2981 { 0x74, 0x14 },
2982 { 0x75, 0x03 },
2983 { 0x76, 0x04 },
2984 { 0x77, 0x04 },
2985 };
2986
2987 PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
2988
2989 write_regvals(sd, init_511, ARRAY_SIZE(init_511));
2990
2991 switch (sd->bridge) {
2992 case BRIDGE_OV511:
2993 write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
2994 break;
2995 case BRIDGE_OV511PLUS:
2996 write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
2997 break;
2998 }
2999
3000
3001 write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
3002
3003 ov51x_upload_quan_tables(sd);
3004}
3005
3006
3007static void ov518_configure(struct gspca_dev *gspca_dev)
3008{
3009 struct sd *sd = (struct sd *) gspca_dev;
3010
3011
3012 const struct ov_regvals init_518[] = {
3013 { R51x_SYS_RESET, 0x40 },
3014 { R51x_SYS_INIT, 0xe1 },
3015 { R51x_SYS_RESET, 0x3e },
3016 { R51x_SYS_INIT, 0xe1 },
3017 { R51x_SYS_RESET, 0x00 },
3018 { R51x_SYS_INIT, 0xe1 },
3019 { 0x46, 0x00 },
3020 { 0x5d, 0x03 },
3021 };
3022
3023 const struct ov_regvals norm_518[] = {
3024 { R51x_SYS_SNAP, 0x02 },
3025 { R51x_SYS_SNAP, 0x01 },
3026 { 0x31, 0x0f },
3027 { 0x5d, 0x03 },
3028 { 0x24, 0x9f },
3029 { 0x25, 0x90 },
3030 { 0x20, 0x00 },
3031 { 0x51, 0x04 },
3032 { 0x71, 0x19 },
3033 { 0x2f, 0x80 },
3034 };
3035
3036 const struct ov_regvals norm_518_p[] = {
3037 { R51x_SYS_SNAP, 0x02 },
3038 { R51x_SYS_SNAP, 0x01 },
3039 { 0x31, 0x0f },
3040 { 0x5d, 0x03 },
3041 { 0x24, 0x9f },
3042 { 0x25, 0x90 },
3043 { 0x20, 0x60 },
3044 { 0x51, 0x02 },
3045 { 0x71, 0x19 },
3046 { 0x40, 0xff },
3047 { 0x41, 0x42 },
3048 { 0x46, 0x00 },
3049 { 0x33, 0x04 },
3050 { 0x21, 0x19 },
3051 { 0x3f, 0x10 },
3052 { 0x2f, 0x80 },
3053 };
3054
3055
3056 sd->revision = reg_r(sd, R51x_SYS_CUST_ID) & 0x1f;
3057 PDEBUG(D_PROBE, "Device revision %d", sd->revision);
3058
3059 write_regvals(sd, init_518, ARRAY_SIZE(init_518));
3060
3061
3062 reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
3063
3064 switch (sd->bridge) {
3065 case BRIDGE_OV518:
3066 write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
3067 break;
3068 case BRIDGE_OV518PLUS:
3069 write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
3070 break;
3071 }
3072
3073 ov51x_upload_quan_tables(sd);
3074
3075 reg_w(sd, 0x2f, 0x80);
3076}
3077
3078static void ov519_configure(struct sd *sd)
3079{
3080 static const struct ov_regvals init_519[] = {
3081 { 0x5a, 0x6d },
3082 { 0x53, 0x9b },
3083 { OV519_R54_EN_CLK1, 0xff },
3084 { 0x5d, 0x03 },
3085 { 0x49, 0x01 },
3086 { 0x48, 0x00 },
3087
3088
3089 { OV519_GPIO_IO_CTRL0, 0xee },
3090 { OV519_R51_RESET1, 0x0f },
3091 { OV519_R51_RESET1, 0x00 },
3092 { 0x22, 0x00 },
3093
3094 };
3095
3096 write_regvals(sd, init_519, ARRAY_SIZE(init_519));
3097}
3098
3099static void ovfx2_configure(struct sd *sd)
3100{
3101 static const struct ov_regvals init_fx2[] = {
3102 { 0x00, 0x60 },
3103 { 0x02, 0x01 },
3104 { 0x0f, 0x1d },
3105 { 0xe9, 0x82 },
3106 { 0xea, 0xc7 },
3107 { 0xeb, 0x10 },
3108 { 0xec, 0xf6 },
3109 };
3110
3111 sd->stopped = 1;
3112
3113 write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
3114}
3115
3116
3117
3118static void ov519_set_mode(struct sd *sd)
3119{
3120 static const struct ov_regvals bridge_ov7660[2][10] = {
3121 {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
3122 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3123 {0x25, 0x01}, {0x26, 0x00}},
3124 {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
3125 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3126 {0x25, 0x03}, {0x26, 0x00}}
3127 };
3128 static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
3129 {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
3130 {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
3131 };
3132 static const struct ov_i2c_regvals sensor_ov7660_2[] = {
3133 {OV7670_R17_HSTART, 0x13},
3134 {OV7670_R18_HSTOP, 0x01},
3135 {OV7670_R32_HREF, 0x92},
3136 {OV7670_R19_VSTART, 0x02},
3137 {OV7670_R1A_VSTOP, 0x7a},
3138 {OV7670_R03_VREF, 0x00},
3139
3140
3141
3142
3143 };
3144
3145 write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
3146 ARRAY_SIZE(bridge_ov7660[0]));
3147 write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
3148 ARRAY_SIZE(sensor_ov7660[0]));
3149 write_i2c_regvals(sd, sensor_ov7660_2,
3150 ARRAY_SIZE(sensor_ov7660_2));
3151}
3152
3153
3154
3155static void ov519_set_fr(struct sd *sd)
3156{
3157 int fr;
3158 u8 clock;
3159
3160
3161
3162
3163
3164 static const u8 fr_tb[2][6][3] = {
3165 {{0x04, 0xff, 0x00},
3166 {0x04, 0x1f, 0x00},
3167 {0x04, 0x1b, 0x00},
3168 {0x04, 0x15, 0x00},
3169 {0x04, 0x09, 0x00},
3170 {0x04, 0x01, 0x00}},
3171 {{0x0c, 0xff, 0x00},
3172 {0x0c, 0x1f, 0x00},
3173 {0x0c, 0x1b, 0x00},
3174 {0x04, 0xff, 0x01},
3175 {0x04, 0x1f, 0x01},
3176 {0x04, 0x1b, 0x01}},
3177 };
3178
3179 if (frame_rate > 0)
3180 sd->frame_rate = frame_rate;
3181 if (sd->frame_rate >= 30)
3182 fr = 0;
3183 else if (sd->frame_rate >= 25)
3184 fr = 1;
3185 else if (sd->frame_rate >= 20)
3186 fr = 2;
3187 else if (sd->frame_rate >= 15)
3188 fr = 3;
3189 else if (sd->frame_rate >= 10)
3190 fr = 4;
3191 else
3192 fr = 5;
3193 reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
3194 reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
3195 clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
3196 if (sd->sensor == SEN_OV7660)
3197 clock |= 0x80;
3198 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
3199}
3200
3201static void setautogain(struct gspca_dev *gspca_dev, s32 val)
3202{
3203 struct sd *sd = (struct sd *) gspca_dev;
3204
3205 i2c_w_mask(sd, 0x13, val ? 0x05 : 0x00, 0x05);
3206}
3207
3208
3209static int sd_config(struct gspca_dev *gspca_dev,
3210 const struct usb_device_id *id)
3211{
3212 struct sd *sd = (struct sd *) gspca_dev;
3213 struct cam *cam = &gspca_dev->cam;
3214
3215 sd->bridge = id->driver_info & BRIDGE_MASK;
3216 sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0;
3217
3218 switch (sd->bridge) {
3219 case BRIDGE_OV511:
3220 case BRIDGE_OV511PLUS:
3221 cam->cam_mode = ov511_vga_mode;
3222 cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
3223 break;
3224 case BRIDGE_OV518:
3225 case BRIDGE_OV518PLUS:
3226 cam->cam_mode = ov518_vga_mode;
3227 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
3228 break;
3229 case BRIDGE_OV519:
3230 cam->cam_mode = ov519_vga_mode;
3231 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3232 break;
3233 case BRIDGE_OVFX2:
3234 cam->cam_mode = ov519_vga_mode;
3235 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3236 cam->bulk_size = OVFX2_BULK_SIZE;
3237 cam->bulk_nurbs = MAX_NURBS;
3238 cam->bulk = 1;
3239 break;
3240 case BRIDGE_W9968CF:
3241 cam->cam_mode = w9968cf_vga_mode;
3242 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
3243 break;
3244 }
3245
3246 sd->frame_rate = 15;
3247
3248 return 0;
3249}
3250
3251
3252static int sd_init(struct gspca_dev *gspca_dev)
3253{
3254 struct sd *sd = (struct sd *) gspca_dev;
3255 struct cam *cam = &gspca_dev->cam;
3256
3257 switch (sd->bridge) {
3258 case BRIDGE_OV511:
3259 case BRIDGE_OV511PLUS:
3260 ov511_configure(gspca_dev);
3261 break;
3262 case BRIDGE_OV518:
3263 case BRIDGE_OV518PLUS:
3264 ov518_configure(gspca_dev);
3265 break;
3266 case BRIDGE_OV519:
3267 ov519_configure(sd);
3268 break;
3269 case BRIDGE_OVFX2:
3270 ovfx2_configure(sd);
3271 break;
3272 case BRIDGE_W9968CF:
3273 w9968cf_configure(sd);
3274 break;
3275 }
3276
3277
3278
3279
3280 sd->sensor = -1;
3281
3282
3283 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
3284 ov7xx0_configure(sd);
3285
3286
3287 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
3288 ov6xx0_configure(sd);
3289
3290
3291 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
3292 ov8xx0_configure(sd);
3293
3294
3295 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
3296 ov_hires_configure(sd);
3297 } else {
3298 PERR("Can't determine sensor slave IDs\n");
3299 goto error;
3300 }
3301
3302 if (sd->sensor < 0)
3303 goto error;
3304
3305 ov51x_led_control(sd, 0);
3306
3307 switch (sd->bridge) {
3308 case BRIDGE_OV511:
3309 case BRIDGE_OV511PLUS:
3310 if (sd->sif) {
3311 cam->cam_mode = ov511_sif_mode;
3312 cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
3313 }
3314 break;
3315 case BRIDGE_OV518:
3316 case BRIDGE_OV518PLUS:
3317 if (sd->sif) {
3318 cam->cam_mode = ov518_sif_mode;
3319 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
3320 }
3321 break;
3322 case BRIDGE_OV519:
3323 if (sd->sif) {
3324 cam->cam_mode = ov519_sif_mode;
3325 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3326 }
3327 break;
3328 case BRIDGE_OVFX2:
3329 switch (sd->sensor) {
3330 case SEN_OV2610:
3331 case SEN_OV2610AE:
3332 cam->cam_mode = ovfx2_ov2610_mode;
3333 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3334 break;
3335 case SEN_OV3610:
3336 cam->cam_mode = ovfx2_ov3610_mode;
3337 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3338 break;
3339 case SEN_OV9600:
3340 cam->cam_mode = ovfx2_ov9600_mode;
3341 cam->nmodes = ARRAY_SIZE(ovfx2_ov9600_mode);
3342 break;
3343 default:
3344 if (sd->sif) {
3345 cam->cam_mode = ov519_sif_mode;
3346 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3347 }
3348 break;
3349 }
3350 break;
3351 case BRIDGE_W9968CF:
3352 if (sd->sif)
3353 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1;
3354
3355
3356 w9968cf_init(sd);
3357 break;
3358 }
3359
3360
3361 switch (sd->sensor) {
3362 case SEN_OV2610:
3363 write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610));
3364
3365
3366 i2c_w_mask(sd, 0x13, 0x27, 0x27);
3367 break;
3368 case SEN_OV2610AE:
3369 write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae));
3370
3371
3372 i2c_w_mask(sd, 0x13, 0x05, 0x05);
3373 break;
3374 case SEN_OV3610:
3375 write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
3376
3377
3378 i2c_w_mask(sd, 0x13, 0x27, 0x27);
3379 break;
3380 case SEN_OV6620:
3381 write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20));
3382 break;
3383 case SEN_OV6630:
3384 case SEN_OV66308AF:
3385 write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30));
3386 break;
3387 default:
3388
3389
3390 write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610));
3391 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
3392 break;
3393 case SEN_OV7620:
3394 case SEN_OV7620AE:
3395 write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620));
3396 break;
3397 case SEN_OV7640:
3398 case SEN_OV7648:
3399 write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
3400 break;
3401 case SEN_OV7660:
3402 i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
3403 msleep(14);
3404 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
3405 write_regvals(sd, init_519_ov7660,
3406 ARRAY_SIZE(init_519_ov7660));
3407 write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
3408 sd->gspca_dev.curr_mode = 1;
3409 ov519_set_mode(sd);
3410 ov519_set_fr(sd);
3411 sd_reset_snapshot(gspca_dev);
3412 ov51x_restart(sd);
3413 ov51x_stop(sd);
3414 ov51x_led_control(sd, 0);
3415 break;
3416 case SEN_OV7670:
3417 write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670));
3418 break;
3419 case SEN_OV8610:
3420 write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610));
3421 break;
3422 case SEN_OV9600:
3423 write_i2c_regvals(sd, norm_9600, ARRAY_SIZE(norm_9600));
3424
3425
3426
3427 break;
3428 }
3429 return gspca_dev->usb_err;
3430error:
3431 PERR("OV519 Config failed");
3432 return -EINVAL;
3433}
3434
3435
3436static int sd_isoc_init(struct gspca_dev *gspca_dev)
3437{
3438 struct sd *sd = (struct sd *) gspca_dev;
3439
3440 switch (sd->bridge) {
3441 case BRIDGE_OVFX2:
3442 if (gspca_dev->pixfmt.width != 800)
3443 gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
3444 else
3445 gspca_dev->cam.bulk_size = 7 * 4096;
3446 break;
3447 }
3448 return 0;
3449}
3450
3451
3452
3453
3454
3455static void ov511_mode_init_regs(struct sd *sd)
3456{
3457 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
3458 int hsegs, vsegs, packet_size, fps, needed;
3459 int interlaced = 0;
3460 struct usb_host_interface *alt;
3461 struct usb_interface *intf;
3462
3463 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3464 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3465 if (!alt) {
3466 PERR("Couldn't get altsetting\n");
3467 sd->gspca_dev.usb_err = -EIO;
3468 return;
3469 }
3470
3471 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3472 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3473
3474 reg_w(sd, R511_CAM_UV_EN, 0x01);
3475 reg_w(sd, R511_SNAP_UV_EN, 0x01);
3476 reg_w(sd, R511_SNAP_OPTS, 0x03);
3477
3478
3479
3480
3481 hsegs = (sd->gspca_dev.pixfmt.width >> 3) - 1;
3482 vsegs = (sd->gspca_dev.pixfmt.height >> 3) - 1;
3483
3484 reg_w(sd, R511_CAM_PXCNT, hsegs);
3485 reg_w(sd, R511_CAM_LNCNT, vsegs);
3486 reg_w(sd, R511_CAM_PXDIV, 0x00);
3487 reg_w(sd, R511_CAM_LNDIV, 0x00);
3488
3489
3490 reg_w(sd, R511_CAM_OPTS, 0x03);
3491
3492
3493 reg_w(sd, R511_SNAP_PXCNT, hsegs);
3494 reg_w(sd, R511_SNAP_LNCNT, vsegs);
3495 reg_w(sd, R511_SNAP_PXDIV, 0x00);
3496 reg_w(sd, R511_SNAP_LNDIV, 0x00);
3497
3498
3499 if (frame_rate > 0)
3500 sd->frame_rate = frame_rate;
3501
3502 switch (sd->sensor) {
3503 case SEN_OV6620:
3504
3505 sd->clockdiv = 3;
3506 break;
3507
3508
3509
3510 case SEN_OV7620:
3511 case SEN_OV7620AE:
3512 case SEN_OV7640:
3513 case SEN_OV7648:
3514 case SEN_OV76BE:
3515 if (sd->gspca_dev.pixfmt.width == 320)
3516 interlaced = 1;
3517
3518 case SEN_OV6630:
3519 case SEN_OV7610:
3520 case SEN_OV7670:
3521 switch (sd->frame_rate) {
3522 case 30:
3523 case 25:
3524
3525 if (sd->gspca_dev.pixfmt.width != 640) {
3526 sd->clockdiv = 0;
3527 break;
3528 }
3529
3530
3531 default:
3532
3533
3534 sd->clockdiv = 1;
3535 break;
3536 case 10:
3537 sd->clockdiv = 2;
3538 break;
3539 case 5:
3540 sd->clockdiv = 5;
3541 break;
3542 }
3543 if (interlaced) {
3544 sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
3545
3546 if (sd->clockdiv > 10)
3547 sd->clockdiv = 10;
3548 }
3549 break;
3550
3551 case SEN_OV8610:
3552
3553 sd->clockdiv = 0;
3554 break;
3555 }
3556
3557
3558 fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
3559 needed = fps * sd->gspca_dev.pixfmt.width *
3560 sd->gspca_dev.pixfmt.height * 3 / 2;
3561
3562 if (needed > 1000 * packet_size) {
3563
3564 reg_w(sd, R511_COMP_EN, 0x07);
3565 reg_w(sd, R511_COMP_LUT_EN, 0x03);
3566 } else {
3567 reg_w(sd, R511_COMP_EN, 0x06);
3568 reg_w(sd, R511_COMP_LUT_EN, 0x00);
3569 }
3570
3571 reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
3572 reg_w(sd, R51x_SYS_RESET, 0);
3573}
3574
3575
3576
3577
3578
3579
3580
3581
3582static void ov518_mode_init_regs(struct sd *sd)
3583{
3584 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
3585 int hsegs, vsegs, packet_size;
3586 struct usb_host_interface *alt;
3587 struct usb_interface *intf;
3588
3589 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3590 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3591 if (!alt) {
3592 PERR("Couldn't get altsetting\n");
3593 sd->gspca_dev.usb_err = -EIO;
3594 return;
3595 }
3596
3597 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3598 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
3599
3600
3601 reg_w(sd, 0x2b, 0);
3602 reg_w(sd, 0x2c, 0);
3603 reg_w(sd, 0x2d, 0);
3604 reg_w(sd, 0x2e, 0);
3605 reg_w(sd, 0x3b, 0);
3606 reg_w(sd, 0x3c, 0);
3607 reg_w(sd, 0x3d, 0);
3608 reg_w(sd, 0x3e, 0);
3609
3610 if (sd->bridge == BRIDGE_OV518) {
3611
3612 reg_w_mask(sd, 0x20, 0x08, 0x08);
3613
3614
3615 reg_w_mask(sd, 0x28, 0x80, 0xf0);
3616 reg_w_mask(sd, 0x38, 0x80, 0xf0);
3617 } else {
3618 reg_w(sd, 0x28, 0x80);
3619 reg_w(sd, 0x38, 0x80);
3620 }
3621
3622 hsegs = sd->gspca_dev.pixfmt.width / 16;
3623 vsegs = sd->gspca_dev.pixfmt.height / 4;
3624
3625 reg_w(sd, 0x29, hsegs);
3626 reg_w(sd, 0x2a, vsegs);
3627
3628 reg_w(sd, 0x39, hsegs);
3629 reg_w(sd, 0x3a, vsegs);
3630
3631
3632 reg_w(sd, 0x2f, 0x80);
3633
3634
3635 if (sd->bridge == BRIDGE_OV518PLUS && sd->revision == 0 &&
3636 sd->sensor == SEN_OV7620AE)
3637 sd->clockdiv = 0;
3638 else
3639 sd->clockdiv = 1;
3640
3641
3642
3643 reg_w(sd, 0x51, 0x04);
3644 reg_w(sd, 0x22, 0x18);
3645 reg_w(sd, 0x23, 0xff);
3646
3647 if (sd->bridge == BRIDGE_OV518PLUS) {
3648 switch (sd->sensor) {
3649 case SEN_OV7620AE:
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662 if (sd->revision > 0 &&
3663 sd->gspca_dev.pixfmt.width == 640) {
3664 reg_w(sd, 0x20, 0x60);
3665 reg_w(sd, 0x21, 0x1f);
3666 } else {
3667 reg_w(sd, 0x20, 0x00);
3668 reg_w(sd, 0x21, 0x19);
3669 }
3670 break;
3671 case SEN_OV7620:
3672 reg_w(sd, 0x20, 0x00);
3673 reg_w(sd, 0x21, 0x19);
3674 break;
3675 default:
3676 reg_w(sd, 0x21, 0x19);
3677 }
3678 } else
3679 reg_w(sd, 0x71, 0x17);
3680
3681
3682
3683 i2c_w(sd, 0x54, 0x23);
3684
3685 reg_w(sd, 0x2f, 0x80);
3686
3687 if (sd->bridge == BRIDGE_OV518PLUS) {
3688 reg_w(sd, 0x24, 0x94);
3689 reg_w(sd, 0x25, 0x90);
3690 ov518_reg_w32(sd, 0xc4, 400, 2);
3691 ov518_reg_w32(sd, 0xc6, 540, 2);
3692 ov518_reg_w32(sd, 0xc7, 540, 2);
3693 ov518_reg_w32(sd, 0xc8, 108, 2);
3694 ov518_reg_w32(sd, 0xca, 131098, 3);
3695 ov518_reg_w32(sd, 0xcb, 532, 2);
3696 ov518_reg_w32(sd, 0xcc, 2400, 2);
3697 ov518_reg_w32(sd, 0xcd, 32, 2);
3698 ov518_reg_w32(sd, 0xce, 608, 2);
3699 } else {
3700 reg_w(sd, 0x24, 0x9f);
3701 reg_w(sd, 0x25, 0x90);
3702 ov518_reg_w32(sd, 0xc4, 400, 2);
3703 ov518_reg_w32(sd, 0xc6, 381, 2);
3704 ov518_reg_w32(sd, 0xc7, 381, 2);
3705 ov518_reg_w32(sd, 0xc8, 128, 2);
3706 ov518_reg_w32(sd, 0xca, 183331, 3);
3707 ov518_reg_w32(sd, 0xcb, 746, 2);
3708 ov518_reg_w32(sd, 0xcc, 1750, 2);
3709 ov518_reg_w32(sd, 0xcd, 45, 2);
3710 ov518_reg_w32(sd, 0xce, 851, 2);
3711 }
3712
3713 reg_w(sd, 0x2f, 0x80);
3714}
3715
3716
3717
3718
3719
3720
3721
3722
3723static void ov519_mode_init_regs(struct sd *sd)
3724{
3725 static const struct ov_regvals mode_init_519_ov7670[] = {
3726 { 0x5d, 0x03 },
3727 { 0x53, 0x9f },
3728 { OV519_R54_EN_CLK1, 0x0f },
3729 { 0xa2, 0x20 },
3730 { 0xa3, 0x18 },
3731 { 0xa4, 0x04 },
3732 { 0xa5, 0x28 },
3733 { 0x37, 0x00 },
3734 { 0x55, 0x02 },
3735
3736 { 0x20, 0x0c },
3737 { 0x21, 0x38 },
3738 { 0x22, 0x1d },
3739 { 0x17, 0x50 },
3740 { 0x37, 0x00 },
3741 { 0x40, 0xff },
3742 { 0x46, 0x00 },
3743 { 0x59, 0x04 },
3744 { 0xff, 0x00 },
3745
3746 };
3747
3748 static const struct ov_regvals mode_init_519[] = {
3749 { 0x5d, 0x03 },
3750 { 0x53, 0x9f },
3751 { OV519_R54_EN_CLK1, 0x0f },
3752 { 0xa2, 0x20 },
3753 { 0xa3, 0x18 },
3754 { 0xa4, 0x04 },
3755 { 0xa5, 0x28 },
3756 { 0x37, 0x00 },
3757 { 0x55, 0x02 },
3758
3759 { 0x22, 0x1d },
3760 { 0x17, 0x50 },
3761 { 0x37, 0x00 },
3762 { 0x40, 0xff },
3763 { 0x46, 0x00 },
3764 { 0x59, 0x04 },
3765 { 0xff, 0x00 },
3766
3767 };
3768
3769 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
3770
3771
3772 switch (sd->sensor) {
3773 default:
3774 write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
3775 if (sd->sensor == SEN_OV7640 ||
3776 sd->sensor == SEN_OV7648) {
3777
3778 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
3779 }
3780 break;
3781 case SEN_OV7660:
3782 return;
3783 case SEN_OV7670:
3784 write_regvals(sd, mode_init_519_ov7670,
3785 ARRAY_SIZE(mode_init_519_ov7670));
3786 break;
3787 }
3788
3789 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.pixfmt.width >> 4);
3790 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.pixfmt.height >> 3);
3791 if (sd->sensor == SEN_OV7670 &&
3792 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3793 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
3794 else if (sd->sensor == SEN_OV7648 &&
3795 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3796 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
3797 else
3798 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
3799 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
3800 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
3801 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
3802 reg_w(sd, OV519_R16_DIVIDER, 0x00);
3803 reg_w(sd, OV519_R25_FORMAT, 0x03);
3804 reg_w(sd, 0x26, 0x00);
3805
3806
3807 if (frame_rate > 0)
3808 sd->frame_rate = frame_rate;
3809
3810
3811 sd->clockdiv = 0;
3812 switch (sd->sensor) {
3813 case SEN_OV7640:
3814 case SEN_OV7648:
3815 switch (sd->frame_rate) {
3816 default:
3817
3818 reg_w(sd, 0xa4, 0x0c);
3819 reg_w(sd, 0x23, 0xff);
3820 break;
3821 case 25:
3822 reg_w(sd, 0xa4, 0x0c);
3823 reg_w(sd, 0x23, 0x1f);
3824 break;
3825 case 20:
3826 reg_w(sd, 0xa4, 0x0c);
3827 reg_w(sd, 0x23, 0x1b);
3828 break;
3829 case 15:
3830 reg_w(sd, 0xa4, 0x04);
3831 reg_w(sd, 0x23, 0xff);
3832 sd->clockdiv = 1;
3833 break;
3834 case 10:
3835 reg_w(sd, 0xa4, 0x04);
3836 reg_w(sd, 0x23, 0x1f);
3837 sd->clockdiv = 1;
3838 break;
3839 case 5:
3840 reg_w(sd, 0xa4, 0x04);
3841 reg_w(sd, 0x23, 0x1b);
3842 sd->clockdiv = 1;
3843 break;
3844 }
3845 break;
3846 case SEN_OV8610:
3847 switch (sd->frame_rate) {
3848 default:
3849
3850 reg_w(sd, 0xa4, 0x06);
3851 reg_w(sd, 0x23, 0xff);
3852 break;
3853 case 10:
3854 reg_w(sd, 0xa4, 0x06);
3855 reg_w(sd, 0x23, 0x1f);
3856 break;
3857 case 5:
3858 reg_w(sd, 0xa4, 0x06);
3859 reg_w(sd, 0x23, 0x1b);
3860 break;
3861 }
3862 break;
3863 case SEN_OV7670:
3864 PDEBUG(D_STREAM, "Setting framerate to %d fps",
3865 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
3866 reg_w(sd, 0xa4, 0x10);
3867 switch (sd->frame_rate) {
3868 case 30:
3869 reg_w(sd, 0x23, 0xff);
3870 break;
3871 case 20:
3872 reg_w(sd, 0x23, 0x1b);
3873 break;
3874 default:
3875
3876 reg_w(sd, 0x23, 0xff);
3877 sd->clockdiv = 1;
3878 break;
3879 }
3880 break;
3881 }
3882}
3883
3884static void mode_init_ov_sensor_regs(struct sd *sd)
3885{
3886 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
3887 int qvga, xstart, xend, ystart, yend;
3888 u8 v;
3889
3890 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
3891
3892
3893 switch (sd->sensor) {
3894 case SEN_OV2610:
3895 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3896 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3897 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3898 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3899 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3900 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3901 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3902 return;
3903 case SEN_OV2610AE: {
3904 u8 v;
3905
3906
3907
3908
3909
3910 v = 80;
3911 if (qvga) {
3912 if (sd->frame_rate < 25)
3913 v = 0x81;
3914 } else {
3915 if (sd->frame_rate < 10)
3916 v = 0x81;
3917 }
3918 i2c_w(sd, 0x11, v);
3919 i2c_w(sd, 0x12, qvga ? 0x60 : 0x20);
3920 return;
3921 }
3922 case SEN_OV3610:
3923 if (qvga) {
3924 xstart = (1040 - gspca_dev->pixfmt.width) / 2 +
3925 (0x1f << 4);
3926 ystart = (776 - gspca_dev->pixfmt.height) / 2;
3927 } else {
3928 xstart = (2076 - gspca_dev->pixfmt.width) / 2 +
3929 (0x10 << 4);
3930 ystart = (1544 - gspca_dev->pixfmt.height) / 2;
3931 }
3932 xend = xstart + gspca_dev->pixfmt.width;
3933 yend = ystart + gspca_dev->pixfmt.height;
3934
3935
3936 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3937 i2c_w_mask(sd, 0x32,
3938 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3939 0x3f);
3940 i2c_w_mask(sd, 0x03,
3941 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3942 0x0f);
3943 i2c_w(sd, 0x17, xstart >> 4);
3944 i2c_w(sd, 0x18, xend >> 4);
3945 i2c_w(sd, 0x19, ystart >> 3);
3946 i2c_w(sd, 0x1a, yend >> 3);
3947 return;
3948 case SEN_OV8610:
3949
3950 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
3951 i2c_w_mask(sd, 0x13, 0x00, 0x20);
3952 i2c_w_mask(sd, 0x12, 0x04, 0x06);
3953 i2c_w_mask(sd, 0x2d, 0x00, 0x40);
3954 i2c_w_mask(sd, 0x28, 0x20, 0x20);
3955 break;
3956 case SEN_OV7610:
3957 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3958 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
3959 i2c_w_mask(sd, 0x13, 0x00, 0x20);
3960 i2c_w_mask(sd, 0x12, 0x04, 0x06);
3961 break;
3962 case SEN_OV7620:
3963 case SEN_OV7620AE:
3964 case SEN_OV76BE:
3965 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3966 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3967 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3968 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3969 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3970 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
3971 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3972 i2c_w_mask(sd, 0x13, 0x00, 0x20);
3973 i2c_w_mask(sd, 0x12, 0x04, 0x06);
3974 if (sd->sensor == SEN_OV76BE)
3975 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
3976 break;
3977 case SEN_OV7640:
3978 case SEN_OV7648:
3979 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3980 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3981
3982
3983 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3984
3985 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3986
3987 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3988 i2c_w_mask(sd, 0x12, 0x04, 0x04);
3989 break;
3990 case SEN_OV7670:
3991
3992
3993
3994 i2c_w_mask(sd, OV7670_R12_COM7,
3995 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
3996 OV7670_COM7_FMT_MASK);
3997 i2c_w_mask(sd, 0x13, 0x00, 0x20);
3998 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
3999 OV7670_COM8_AWB);
4000 if (qvga) {
4001
4002 xstart = 164;
4003 xend = 28;
4004 ystart = 14;
4005 yend = 494;
4006 } else {
4007 xstart = 158;
4008 xend = 14;
4009 ystart = 10;
4010 yend = 490;
4011 }
4012
4013
4014 i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
4015 i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
4016 v = i2c_r(sd, OV7670_R32_HREF);
4017 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
4018 msleep(10);
4019
4020 i2c_w(sd, OV7670_R32_HREF, v);
4021
4022 i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
4023 i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
4024 v = i2c_r(sd, OV7670_R03_VREF);
4025 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
4026 msleep(10);
4027
4028 i2c_w(sd, OV7670_R03_VREF, v);
4029 break;
4030 case SEN_OV6620:
4031 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4032 i2c_w_mask(sd, 0x13, 0x00, 0x20);
4033 i2c_w_mask(sd, 0x12, 0x04, 0x06);
4034 break;
4035 case SEN_OV6630:
4036 case SEN_OV66308AF:
4037 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4038 i2c_w_mask(sd, 0x12, 0x04, 0x06);
4039 break;
4040 case SEN_OV9600: {
4041 const struct ov_i2c_regvals *vals;
4042 static const struct ov_i2c_regvals sxga_15[] = {
4043 {0x11, 0x80}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75}
4044 };
4045 static const struct ov_i2c_regvals sxga_7_5[] = {
4046 {0x11, 0x81}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75}
4047 };
4048 static const struct ov_i2c_regvals vga_30[] = {
4049 {0x11, 0x81}, {0x14, 0x7e}, {0x24, 0x70}, {0x25, 0x60}
4050 };
4051 static const struct ov_i2c_regvals vga_15[] = {
4052 {0x11, 0x83}, {0x14, 0x3e}, {0x24, 0x80}, {0x25, 0x70}
4053 };
4054
4055
4056
4057
4058
4059 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0x40);
4060 if (qvga)
4061 vals = sd->frame_rate < 30 ? vga_15 : vga_30;
4062 else
4063 vals = sd->frame_rate < 15 ? sxga_7_5 : sxga_15;
4064 write_i2c_regvals(sd, vals, ARRAY_SIZE(sxga_15));
4065 return;
4066 }
4067 default:
4068 return;
4069 }
4070
4071
4072 i2c_w(sd, 0x11, sd->clockdiv);
4073}
4074
4075
4076static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
4077{
4078 struct sd *sd = (struct sd *) gspca_dev;
4079
4080 if (sd->gspca_dev.streaming)
4081 reg_w(sd, OV519_R51_RESET1, 0x0f);
4082 i2c_w_mask(sd, OV7670_R1E_MVFP,
4083 OV7670_MVFP_MIRROR * hflip | OV7670_MVFP_VFLIP * vflip,
4084 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
4085 if (sd->gspca_dev.streaming)
4086 reg_w(sd, OV519_R51_RESET1, 0x00);
4087}
4088
4089static void set_ov_sensor_window(struct sd *sd)
4090{
4091 struct gspca_dev *gspca_dev;
4092 int qvga, crop;
4093 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
4094
4095
4096 switch (sd->sensor) {
4097 case SEN_OV2610:
4098 case SEN_OV2610AE:
4099 case SEN_OV3610:
4100 case SEN_OV7670:
4101 case SEN_OV9600:
4102 mode_init_ov_sensor_regs(sd);
4103 return;
4104 case SEN_OV7660:
4105 ov519_set_mode(sd);
4106 ov519_set_fr(sd);
4107 return;
4108 }
4109
4110 gspca_dev = &sd->gspca_dev;
4111 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
4112 crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
4113
4114
4115
4116 switch (sd->sensor) {
4117 case SEN_OV8610:
4118 hwsbase = 0x1e;
4119 hwebase = 0x1e;
4120 vwsbase = 0x02;
4121 vwebase = 0x02;
4122 break;
4123 case SEN_OV7610:
4124 case SEN_OV76BE:
4125 hwsbase = 0x38;
4126 hwebase = 0x3a;
4127 vwsbase = vwebase = 0x05;
4128 break;
4129 case SEN_OV6620:
4130 case SEN_OV6630:
4131 case SEN_OV66308AF:
4132 hwsbase = 0x38;
4133 hwebase = 0x3a;
4134 vwsbase = 0x05;
4135 vwebase = 0x06;
4136 if (sd->sensor == SEN_OV66308AF && qvga)
4137
4138 hwsbase++;
4139 if (crop) {
4140 hwsbase += 8;
4141 hwebase += 8;
4142 vwsbase += 11;
4143 vwebase += 11;
4144 }
4145 break;
4146 case SEN_OV7620:
4147 case SEN_OV7620AE:
4148 hwsbase = 0x2f;
4149 hwebase = 0x2f;
4150 vwsbase = vwebase = 0x05;
4151 break;
4152 case SEN_OV7640:
4153 case SEN_OV7648:
4154 hwsbase = 0x1a;
4155 hwebase = 0x1a;
4156 vwsbase = vwebase = 0x03;
4157 break;
4158 default:
4159 return;
4160 }
4161
4162 switch (sd->sensor) {
4163 case SEN_OV6620:
4164 case SEN_OV6630:
4165 case SEN_OV66308AF:
4166 if (qvga) {
4167 hwscale = 0;
4168 vwscale = 0;
4169 } else {
4170 hwscale = 1;
4171 vwscale = 1;
4172
4173 }
4174 break;
4175 case SEN_OV8610:
4176 if (qvga) {
4177 hwscale = 1;
4178 vwscale = 1;
4179 } else {
4180 hwscale = 2;
4181 vwscale = 2;
4182 }
4183 break;
4184 default:
4185 if (qvga) {
4186 hwscale = 1;
4187 vwscale = 0;
4188 } else {
4189 hwscale = 2;
4190 vwscale = 1;
4191 }
4192 }
4193
4194 mode_init_ov_sensor_regs(sd);
4195
4196 i2c_w(sd, 0x17, hwsbase);
4197 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
4198 i2c_w(sd, 0x19, vwsbase);
4199 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
4200}
4201
4202
4203static int sd_start(struct gspca_dev *gspca_dev)
4204{
4205 struct sd *sd = (struct sd *) gspca_dev;
4206
4207
4208 sd->sensor_width = sd->gspca_dev.pixfmt.width;
4209 sd->sensor_height = sd->gspca_dev.pixfmt.height;
4210
4211 switch (sd->bridge) {
4212 case BRIDGE_OV511:
4213 case BRIDGE_OV511PLUS:
4214 ov511_mode_init_regs(sd);
4215 break;
4216 case BRIDGE_OV518:
4217 case BRIDGE_OV518PLUS:
4218 ov518_mode_init_regs(sd);
4219 break;
4220 case BRIDGE_OV519:
4221 ov519_mode_init_regs(sd);
4222 break;
4223
4224 case BRIDGE_W9968CF:
4225 w9968cf_mode_init_regs(sd);
4226 break;
4227 }
4228
4229 set_ov_sensor_window(sd);
4230
4231
4232
4233 sd->snapshot_needs_reset = 1;
4234 sd_reset_snapshot(gspca_dev);
4235
4236 sd->first_frame = 3;
4237
4238 ov51x_restart(sd);
4239 ov51x_led_control(sd, 1);
4240 return gspca_dev->usb_err;
4241}
4242
4243static void sd_stopN(struct gspca_dev *gspca_dev)
4244{
4245 struct sd *sd = (struct sd *) gspca_dev;
4246
4247 ov51x_stop(sd);
4248 ov51x_led_control(sd, 0);
4249}
4250
4251static void sd_stop0(struct gspca_dev *gspca_dev)
4252{
4253 struct sd *sd = (struct sd *) gspca_dev;
4254
4255 if (!sd->gspca_dev.present)
4256 return;
4257 if (sd->bridge == BRIDGE_W9968CF)
4258 w9968cf_stop0(sd);
4259
4260#if IS_ENABLED(CONFIG_INPUT)
4261
4262 if (sd->snapshot_pressed) {
4263 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
4264 input_sync(gspca_dev->input_dev);
4265 sd->snapshot_pressed = 0;
4266 }
4267#endif
4268 if (sd->bridge == BRIDGE_OV519)
4269 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
4270}
4271
4272static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
4273{
4274 struct sd *sd = (struct sd *) gspca_dev;
4275
4276 if (sd->snapshot_pressed != state) {
4277#if IS_ENABLED(CONFIG_INPUT)
4278 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
4279 input_sync(gspca_dev->input_dev);
4280#endif
4281 if (state)
4282 sd->snapshot_needs_reset = 1;
4283
4284 sd->snapshot_pressed = state;
4285 } else {
4286
4287
4288
4289 switch (sd->bridge) {
4290 case BRIDGE_OV511:
4291 case BRIDGE_OV511PLUS:
4292 case BRIDGE_OV519:
4293 if (state)
4294 sd->snapshot_needs_reset = 1;
4295 break;
4296 }
4297 }
4298}
4299
4300static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
4301 u8 *in,
4302 int len)
4303{
4304 struct sd *sd = (struct sd *) gspca_dev;
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
4320 (in[8] & 0x08)) {
4321 ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
4322 if (in[8] & 0x80) {
4323
4324 if ((in[9] + 1) * 8 != gspca_dev->pixfmt.width ||
4325 (in[10] + 1) * 8 != gspca_dev->pixfmt.height) {
4326 PERR("Invalid frame size, got: %dx%d, requested: %dx%d\n",
4327 (in[9] + 1) * 8, (in[10] + 1) * 8,
4328 gspca_dev->pixfmt.width,
4329 gspca_dev->pixfmt.height);
4330 gspca_dev->last_packet_type = DISCARD_PACKET;
4331 return;
4332 }
4333
4334 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
4335 return;
4336 } else {
4337
4338 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
4339 sd->packet_nr = 0;
4340 }
4341 }
4342
4343
4344 len--;
4345
4346
4347 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
4348}
4349
4350static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
4351 u8 *data,
4352 int len)
4353{
4354 struct sd *sd = (struct sd *) gspca_dev;
4355
4356
4357
4358 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
4359 ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
4360 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4361 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
4362 sd->packet_nr = 0;
4363 }
4364
4365 if (gspca_dev->last_packet_type == DISCARD_PACKET)
4366 return;
4367
4368
4369 if (len & 7) {
4370 len--;
4371 if (sd->packet_nr == data[len])
4372 sd->packet_nr++;
4373
4374
4375
4376 else if (sd->packet_nr == 0 || data[len]) {
4377 PERR("Invalid packet nr: %d (expect: %d)",
4378 (int)data[len], (int)sd->packet_nr);
4379 gspca_dev->last_packet_type = DISCARD_PACKET;
4380 return;
4381 }
4382 }
4383
4384
4385 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4386}
4387
4388static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
4389 u8 *data,
4390 int len)
4391{
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4405 switch (data[3]) {
4406 case 0x50:
4407
4408
4409
4410#define HDRSZ 16
4411 data += HDRSZ;
4412 len -= HDRSZ;
4413#undef HDRSZ
4414 if (data[0] == 0xff || data[1] == 0xd8)
4415 gspca_frame_add(gspca_dev, FIRST_PACKET,
4416 data, len);
4417 else
4418 gspca_dev->last_packet_type = DISCARD_PACKET;
4419 return;
4420 case 0x51:
4421 ov51x_handle_button(gspca_dev, data[11] & 1);
4422 if (data[9] != 0)
4423 gspca_dev->last_packet_type = DISCARD_PACKET;
4424 gspca_frame_add(gspca_dev, LAST_PACKET,
4425 NULL, 0);
4426 return;
4427 }
4428 }
4429
4430
4431 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4432}
4433
4434static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
4435 u8 *data,
4436 int len)
4437{
4438 struct sd *sd = (struct sd *) gspca_dev;
4439
4440 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4441
4442
4443 if (len < gspca_dev->cam.bulk_size) {
4444
4445
4446 if (sd->first_frame) {
4447 sd->first_frame--;
4448 if (gspca_dev->image_len <
4449 sd->gspca_dev.pixfmt.width *
4450 sd->gspca_dev.pixfmt.height)
4451 gspca_dev->last_packet_type = DISCARD_PACKET;
4452 }
4453 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4454 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
4455 }
4456}
4457
4458static void sd_pkt_scan(struct gspca_dev *gspca_dev,
4459 u8 *data,
4460 int len)
4461{
4462 struct sd *sd = (struct sd *) gspca_dev;
4463
4464 switch (sd->bridge) {
4465 case BRIDGE_OV511:
4466 case BRIDGE_OV511PLUS:
4467 ov511_pkt_scan(gspca_dev, data, len);
4468 break;
4469 case BRIDGE_OV518:
4470 case BRIDGE_OV518PLUS:
4471 ov518_pkt_scan(gspca_dev, data, len);
4472 break;
4473 case BRIDGE_OV519:
4474 ov519_pkt_scan(gspca_dev, data, len);
4475 break;
4476 case BRIDGE_OVFX2:
4477 ovfx2_pkt_scan(gspca_dev, data, len);
4478 break;
4479 case BRIDGE_W9968CF:
4480 w9968cf_pkt_scan(gspca_dev, data, len);
4481 break;
4482 }
4483}
4484
4485
4486
4487static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
4488{
4489 struct sd *sd = (struct sd *) gspca_dev;
4490 static const struct ov_i2c_regvals brit_7660[][7] = {
4491 {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
4492 {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
4493 {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
4494 {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
4495 {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
4496 {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
4497 {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
4498 {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
4499 {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
4500 {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
4501 {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
4502 {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
4503 {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
4504 {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
4505 };
4506
4507 switch (sd->sensor) {
4508 case SEN_OV8610:
4509 case SEN_OV7610:
4510 case SEN_OV76BE:
4511 case SEN_OV6620:
4512 case SEN_OV6630:
4513 case SEN_OV66308AF:
4514 case SEN_OV7640:
4515 case SEN_OV7648:
4516 i2c_w(sd, OV7610_REG_BRT, val);
4517 break;
4518 case SEN_OV7620:
4519 case SEN_OV7620AE:
4520 i2c_w(sd, OV7610_REG_BRT, val);
4521 break;
4522 case SEN_OV7660:
4523 write_i2c_regvals(sd, brit_7660[val],
4524 ARRAY_SIZE(brit_7660[0]));
4525 break;
4526 case SEN_OV7670:
4527
4528
4529 i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
4530 break;
4531 }
4532}
4533
4534static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
4535{
4536 struct sd *sd = (struct sd *) gspca_dev;
4537 static const struct ov_i2c_regvals contrast_7660[][31] = {
4538 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
4539 {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
4540 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
4541 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
4542 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
4543 {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
4544 {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
4545 {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
4546 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
4547 {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
4548 {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
4549 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
4550 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
4551 {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
4552 {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
4553 {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
4554 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
4555 {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
4556 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
4557 {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
4558 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
4559 {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
4560 {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
4561 {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
4562 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
4563 {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
4564 {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
4565 {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
4566 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
4567 {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
4568 {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
4569 {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
4570 {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
4571 {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
4572 {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
4573 {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
4574 {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
4575 {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
4576 {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
4577 {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
4578 {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
4579 {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
4580 {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
4581 {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
4582 {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
4583 {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
4584 {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
4585 {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
4586 {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
4587 {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
4588 {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
4589 {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
4590 {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
4591 {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
4592 {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
4593 {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
4594 };
4595
4596 switch (sd->sensor) {
4597 case SEN_OV7610:
4598 case SEN_OV6620:
4599 i2c_w(sd, OV7610_REG_CNT, val);
4600 break;
4601 case SEN_OV6630:
4602 case SEN_OV66308AF:
4603 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
4604 break;
4605 case SEN_OV8610: {
4606 static const u8 ctab[] = {
4607 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
4608 };
4609
4610
4611 i2c_w(sd, 0x64, ctab[val >> 5]);
4612 break;
4613 }
4614 case SEN_OV7620:
4615 case SEN_OV7620AE: {
4616 static const u8 ctab[] = {
4617 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4618 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
4619 };
4620
4621
4622 i2c_w(sd, 0x64, ctab[val >> 4]);
4623 break;
4624 }
4625 case SEN_OV7660:
4626 write_i2c_regvals(sd, contrast_7660[val],
4627 ARRAY_SIZE(contrast_7660[0]));
4628 break;
4629 case SEN_OV7670:
4630
4631 i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
4632 break;
4633 }
4634}
4635
4636static void setexposure(struct gspca_dev *gspca_dev, s32 val)
4637{
4638 struct sd *sd = (struct sd *) gspca_dev;
4639
4640 i2c_w(sd, 0x10, val);
4641}
4642
4643static void setcolors(struct gspca_dev *gspca_dev, s32 val)
4644{
4645 struct sd *sd = (struct sd *) gspca_dev;
4646 static const struct ov_i2c_regvals colors_7660[][6] = {
4647 {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
4648 {0x53, 0x19}, {0x54, 0x23}},
4649 {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
4650 {0x53, 0x2c}, {0x54, 0x3e}},
4651 {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
4652 {0x53, 0x40}, {0x54, 0x59}},
4653 {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
4654 {0x53, 0x53}, {0x54, 0x73}},
4655 {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
4656 {0x53, 0x66}, {0x54, 0x8e}},
4657 };
4658
4659 switch (sd->sensor) {
4660 case SEN_OV8610:
4661 case SEN_OV7610:
4662 case SEN_OV76BE:
4663 case SEN_OV6620:
4664 case SEN_OV6630:
4665 case SEN_OV66308AF:
4666 i2c_w(sd, OV7610_REG_SAT, val);
4667 break;
4668 case SEN_OV7620:
4669 case SEN_OV7620AE:
4670
4671
4672
4673
4674 i2c_w(sd, OV7610_REG_SAT, val);
4675 break;
4676 case SEN_OV7640:
4677 case SEN_OV7648:
4678 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4679 break;
4680 case SEN_OV7660:
4681 write_i2c_regvals(sd, colors_7660[val],
4682 ARRAY_SIZE(colors_7660[0]));
4683 break;
4684 case SEN_OV7670:
4685
4686
4687
4688 break;
4689 }
4690}
4691
4692static void setautobright(struct gspca_dev *gspca_dev, s32 val)
4693{
4694 struct sd *sd = (struct sd *) gspca_dev;
4695
4696 i2c_w_mask(sd, 0x2d, val ? 0x10 : 0x00, 0x10);
4697}
4698
4699static void setfreq_i(struct sd *sd, s32 val)
4700{
4701 if (sd->sensor == SEN_OV7660
4702 || sd->sensor == SEN_OV7670) {
4703 switch (val) {
4704 case 0:
4705 i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
4706 break;
4707 case 1:
4708 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
4709 OV7670_COM8_BFILT);
4710 i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
4711 break;
4712 case 2:
4713 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
4714 OV7670_COM8_BFILT);
4715 i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
4716 break;
4717 case 3:
4718 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
4719 OV7670_COM8_BFILT);
4720 i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
4721 0x18);
4722 break;
4723 }
4724 } else {
4725 switch (val) {
4726 case 0:
4727 i2c_w_mask(sd, 0x2d, 0x00, 0x04);
4728 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4729 break;
4730 case 1:
4731 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4732 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4733
4734 if (sd->sensor == SEN_OV6620 ||
4735 sd->sensor == SEN_OV6630 ||
4736 sd->sensor == SEN_OV66308AF)
4737 i2c_w(sd, 0x2b, 0x5e);
4738 else
4739 i2c_w(sd, 0x2b, 0xac);
4740 break;
4741 case 2:
4742 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4743 if (sd->sensor == SEN_OV6620 ||
4744 sd->sensor == SEN_OV6630 ||
4745 sd->sensor == SEN_OV66308AF) {
4746
4747 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4748 i2c_w(sd, 0x2b, 0xa8);
4749 } else {
4750
4751 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4752 }
4753 break;
4754 }
4755 }
4756}
4757
4758static void setfreq(struct gspca_dev *gspca_dev, s32 val)
4759{
4760 struct sd *sd = (struct sd *) gspca_dev;
4761
4762 setfreq_i(sd, val);
4763
4764
4765 if (sd->bridge == BRIDGE_W9968CF)
4766 w9968cf_set_crop_window(sd);
4767}
4768
4769static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4770 struct v4l2_jpegcompression *jcomp)
4771{
4772 struct sd *sd = (struct sd *) gspca_dev;
4773
4774 if (sd->bridge != BRIDGE_W9968CF)
4775 return -ENOTTY;
4776
4777 memset(jcomp, 0, sizeof *jcomp);
4778 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
4779 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4780 V4L2_JPEG_MARKER_DRI;
4781 return 0;
4782}
4783
4784static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4785 const struct v4l2_jpegcompression *jcomp)
4786{
4787 struct sd *sd = (struct sd *) gspca_dev;
4788
4789 if (sd->bridge != BRIDGE_W9968CF)
4790 return -ENOTTY;
4791
4792 v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
4793 return 0;
4794}
4795
4796static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
4797{
4798 struct gspca_dev *gspca_dev =
4799 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
4800 struct sd *sd = (struct sd *)gspca_dev;
4801
4802 gspca_dev->usb_err = 0;
4803
4804 switch (ctrl->id) {
4805 case V4L2_CID_AUTOGAIN:
4806 gspca_dev->exposure->val = i2c_r(sd, 0x10);
4807 break;
4808 }
4809 return 0;
4810}
4811
4812static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
4813{
4814 struct gspca_dev *gspca_dev =
4815 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
4816 struct sd *sd = (struct sd *)gspca_dev;
4817
4818 gspca_dev->usb_err = 0;
4819
4820 if (!gspca_dev->streaming)
4821 return 0;
4822
4823 switch (ctrl->id) {
4824 case V4L2_CID_BRIGHTNESS:
4825 setbrightness(gspca_dev, ctrl->val);
4826 break;
4827 case V4L2_CID_CONTRAST:
4828 setcontrast(gspca_dev, ctrl->val);
4829 break;
4830 case V4L2_CID_POWER_LINE_FREQUENCY:
4831 setfreq(gspca_dev, ctrl->val);
4832 break;
4833 case V4L2_CID_AUTOBRIGHTNESS:
4834 if (ctrl->is_new)
4835 setautobright(gspca_dev, ctrl->val);
4836 if (!ctrl->val && sd->brightness->is_new)
4837 setbrightness(gspca_dev, sd->brightness->val);
4838 break;
4839 case V4L2_CID_SATURATION:
4840 setcolors(gspca_dev, ctrl->val);
4841 break;
4842 case V4L2_CID_HFLIP:
4843 sethvflip(gspca_dev, ctrl->val, sd->vflip->val);
4844 break;
4845 case V4L2_CID_AUTOGAIN:
4846 if (ctrl->is_new)
4847 setautogain(gspca_dev, ctrl->val);
4848 if (!ctrl->val && gspca_dev->exposure->is_new)
4849 setexposure(gspca_dev, gspca_dev->exposure->val);
4850 break;
4851 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
4852 return -EBUSY;
4853 }
4854 return gspca_dev->usb_err;
4855}
4856
4857static const struct v4l2_ctrl_ops sd_ctrl_ops = {
4858 .g_volatile_ctrl = sd_g_volatile_ctrl,
4859 .s_ctrl = sd_s_ctrl,
4860};
4861
4862static int sd_init_controls(struct gspca_dev *gspca_dev)
4863{
4864 struct sd *sd = (struct sd *)gspca_dev;
4865 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
4866
4867 gspca_dev->vdev.ctrl_handler = hdl;
4868 v4l2_ctrl_handler_init(hdl, 10);
4869 if (valid_controls[sd->sensor].has_brightness)
4870 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4871 V4L2_CID_BRIGHTNESS, 0,
4872 sd->sensor == SEN_OV7660 ? 6 : 255, 1,
4873 sd->sensor == SEN_OV7660 ? 3 : 127);
4874 if (valid_controls[sd->sensor].has_contrast) {
4875 if (sd->sensor == SEN_OV7660)
4876 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4877 V4L2_CID_CONTRAST, 0, 6, 1, 3);
4878 else
4879 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4880 V4L2_CID_CONTRAST, 0, 255, 1,
4881 (sd->sensor == SEN_OV6630 ||
4882 sd->sensor == SEN_OV66308AF) ? 200 : 127);
4883 }
4884 if (valid_controls[sd->sensor].has_sat)
4885 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4886 V4L2_CID_SATURATION, 0,
4887 sd->sensor == SEN_OV7660 ? 4 : 255, 1,
4888 sd->sensor == SEN_OV7660 ? 2 : 127);
4889 if (valid_controls[sd->sensor].has_exposure)
4890 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4891 V4L2_CID_EXPOSURE, 0, 255, 1, 127);
4892 if (valid_controls[sd->sensor].has_hvflip) {
4893 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4894 V4L2_CID_HFLIP, 0, 1, 1, 0);
4895 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4896 V4L2_CID_VFLIP, 0, 1, 1, 0);
4897 }
4898 if (valid_controls[sd->sensor].has_autobright)
4899 sd->autobright = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4900 V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, 1);
4901 if (valid_controls[sd->sensor].has_autogain)
4902 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4903 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
4904 if (valid_controls[sd->sensor].has_freq) {
4905 if (sd->sensor == SEN_OV7670)
4906 sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
4907 V4L2_CID_POWER_LINE_FREQUENCY,
4908 V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
4909 V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
4910 else
4911 sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
4912 V4L2_CID_POWER_LINE_FREQUENCY,
4913 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0);
4914 }
4915 if (sd->bridge == BRIDGE_W9968CF)
4916 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4917 V4L2_CID_JPEG_COMPRESSION_QUALITY,
4918 QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
4919
4920 if (hdl->error) {
4921 PERR("Could not initialize controls\n");
4922 return hdl->error;
4923 }
4924 if (gspca_dev->autogain)
4925 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, true);
4926 if (sd->autobright)
4927 v4l2_ctrl_auto_cluster(2, &sd->autobright, 0, false);
4928 if (sd->hflip)
4929 v4l2_ctrl_cluster(2, &sd->hflip);
4930 return 0;
4931}
4932
4933
4934static const struct sd_desc sd_desc = {
4935 .name = MODULE_NAME,
4936 .config = sd_config,
4937 .init = sd_init,
4938 .init_controls = sd_init_controls,
4939 .isoc_init = sd_isoc_init,
4940 .start = sd_start,
4941 .stopN = sd_stopN,
4942 .stop0 = sd_stop0,
4943 .pkt_scan = sd_pkt_scan,
4944 .dq_callback = sd_reset_snapshot,
4945 .get_jcomp = sd_get_jcomp,
4946 .set_jcomp = sd_set_jcomp,
4947#if IS_ENABLED(CONFIG_INPUT)
4948 .other_input = 1,
4949#endif
4950};
4951
4952
4953static const struct usb_device_id device_table[] = {
4954 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
4955 {USB_DEVICE(0x041e, 0x4052),
4956 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4957 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
4958 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
4959 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
4960 {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
4961 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
4962 {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
4963 {USB_DEVICE(0x045e, 0x028c),
4964 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4965 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
4966 {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
4967 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
4968 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4969 {USB_DEVICE(0x05a9, 0x0519),
4970 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4971 {USB_DEVICE(0x05a9, 0x0530),
4972 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4973 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
4974 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
4975 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
4976 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
4977 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
4978 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
4979 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4980 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
4981 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
4982 {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
4983 {}
4984};
4985
4986MODULE_DEVICE_TABLE(usb, device_table);
4987
4988
4989static int sd_probe(struct usb_interface *intf,
4990 const struct usb_device_id *id)
4991{
4992 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
4993 THIS_MODULE);
4994}
4995
4996static struct usb_driver sd_driver = {
4997 .name = MODULE_NAME,
4998 .id_table = device_table,
4999 .probe = sd_probe,
5000 .disconnect = gspca_disconnect,
5001#ifdef CONFIG_PM
5002 .suspend = gspca_suspend,
5003 .resume = gspca_resume,
5004 .reset_resume = gspca_resume,
5005#endif
5006};
5007
5008module_usb_driver(sd_driver);
5009
5010module_param(frame_rate, int, 0644);
5011MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");
5012