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 gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n",
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 gspca_dbg(gspca_dev, D_USBO, "SET %02x 0000 %04x %02x\n",
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 gspca_err(gspca_dev, "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 gspca_dbg(gspca_dev, D_USBI, "GET %02x 0000 %04x %02x\n",
2082 req, index, ret);
2083 } else {
2084 gspca_err(gspca_dev, "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 gspca_err(gspca_dev, "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 gspca_err(gspca_dev, "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 gspca_dbg(gspca_dev, D_USBO, "ov511_i2c_w %02x %02x\n", 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 gspca_dbg(gspca_dev, D_USBO, "i2c write retries exhausted\n");
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 gspca_dbg(gspca_dev, D_USBI, "i2c write retries exhausted\n");
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 gspca_dbg(gspca_dev, D_USBI, "i2c read retries exhausted\n");
2259 return -1;
2260 }
2261 }
2262
2263 value = reg_r(sd, R51x_I2C_DATA);
2264
2265 gspca_dbg(gspca_dev, D_USBI, "ov511_i2c_r %02x %02x\n", 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 gspca_dbg(gspca_dev, D_USBO, "ov518_i2c_w %02x %02x\n", 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 gspca_dbg(gspca_dev, D_USBI, "ov518_i2c_r %02x %02x\n", 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 gspca_err(gspca_dev, "ovfx2_i2c_w %02x failed %d\n", reg, ret);
2344 sd->gspca_dev.usb_err = ret;
2345 }
2346
2347 gspca_dbg(gspca_dev, D_USBO, "ovfx2_i2c_w %02x %02x\n", 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 gspca_dbg(gspca_dev, D_USBI, "ovfx2_i2c_r %02x %02x\n",
2367 reg, ret);
2368 } else {
2369 gspca_err(gspca_dev, "ovfx2_i2c_r %02x failed %d\n", reg, ret);
2370 sd->gspca_dev.usb_err = ret;
2371 }
2372
2373 return ret;
2374}
2375
2376static void i2c_w(struct sd *sd, u8 reg, u8 value)
2377{
2378 if (sd->sensor_reg_cache[reg] == value)
2379 return;
2380
2381 switch (sd->bridge) {
2382 case BRIDGE_OV511:
2383 case BRIDGE_OV511PLUS:
2384 ov511_i2c_w(sd, reg, value);
2385 break;
2386 case BRIDGE_OV518:
2387 case BRIDGE_OV518PLUS:
2388 case BRIDGE_OV519:
2389 ov518_i2c_w(sd, reg, value);
2390 break;
2391 case BRIDGE_OVFX2:
2392 ovfx2_i2c_w(sd, reg, value);
2393 break;
2394 case BRIDGE_W9968CF:
2395 w9968cf_i2c_w(sd, reg, value);
2396 break;
2397 }
2398
2399 if (sd->gspca_dev.usb_err >= 0) {
2400
2401 if (reg == 0x12 && (value & 0x80))
2402 memset(sd->sensor_reg_cache, -1,
2403 sizeof(sd->sensor_reg_cache));
2404 else
2405 sd->sensor_reg_cache[reg] = value;
2406 }
2407}
2408
2409static int i2c_r(struct sd *sd, u8 reg)
2410{
2411 int ret = -1;
2412
2413 if (sd->sensor_reg_cache[reg] != -1)
2414 return sd->sensor_reg_cache[reg];
2415
2416 switch (sd->bridge) {
2417 case BRIDGE_OV511:
2418 case BRIDGE_OV511PLUS:
2419 ret = ov511_i2c_r(sd, reg);
2420 break;
2421 case BRIDGE_OV518:
2422 case BRIDGE_OV518PLUS:
2423 case BRIDGE_OV519:
2424 ret = ov518_i2c_r(sd, reg);
2425 break;
2426 case BRIDGE_OVFX2:
2427 ret = ovfx2_i2c_r(sd, reg);
2428 break;
2429 case BRIDGE_W9968CF:
2430 ret = w9968cf_i2c_r(sd, reg);
2431 break;
2432 }
2433
2434 if (ret >= 0)
2435 sd->sensor_reg_cache[reg] = ret;
2436
2437 return ret;
2438}
2439
2440
2441
2442
2443
2444
2445static void i2c_w_mask(struct sd *sd,
2446 u8 reg,
2447 u8 value,
2448 u8 mask)
2449{
2450 int rc;
2451 u8 oldval;
2452
2453 value &= mask;
2454 rc = i2c_r(sd, reg);
2455 if (rc < 0)
2456 return;
2457 oldval = rc & ~mask;
2458 value |= oldval;
2459 i2c_w(sd, reg, value);
2460}
2461
2462
2463
2464static inline void ov51x_stop(struct sd *sd)
2465{
2466 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2467
2468 gspca_dbg(gspca_dev, D_STREAM, "stopping\n");
2469 sd->stopped = 1;
2470 switch (sd->bridge) {
2471 case BRIDGE_OV511:
2472 case BRIDGE_OV511PLUS:
2473 reg_w(sd, R51x_SYS_RESET, 0x3d);
2474 break;
2475 case BRIDGE_OV518:
2476 case BRIDGE_OV518PLUS:
2477 reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
2478 break;
2479 case BRIDGE_OV519:
2480 reg_w(sd, OV519_R51_RESET1, 0x0f);
2481 reg_w(sd, OV519_R51_RESET1, 0x00);
2482 reg_w(sd, 0x22, 0x00);
2483 break;
2484 case BRIDGE_OVFX2:
2485 reg_w_mask(sd, 0x0f, 0x00, 0x02);
2486 break;
2487 case BRIDGE_W9968CF:
2488 reg_w(sd, 0x3c, 0x0a05);
2489 break;
2490 }
2491}
2492
2493
2494
2495static inline void ov51x_restart(struct sd *sd)
2496{
2497 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2498
2499 gspca_dbg(gspca_dev, D_STREAM, "restarting\n");
2500 if (!sd->stopped)
2501 return;
2502 sd->stopped = 0;
2503
2504
2505 switch (sd->bridge) {
2506 case BRIDGE_OV511:
2507 case BRIDGE_OV511PLUS:
2508 reg_w(sd, R51x_SYS_RESET, 0x00);
2509 break;
2510 case BRIDGE_OV518:
2511 case BRIDGE_OV518PLUS:
2512 reg_w(sd, 0x2f, 0x80);
2513 reg_w(sd, R51x_SYS_RESET, 0x00);
2514 break;
2515 case BRIDGE_OV519:
2516 reg_w(sd, OV519_R51_RESET1, 0x0f);
2517 reg_w(sd, OV519_R51_RESET1, 0x00);
2518 reg_w(sd, 0x22, 0x1d);
2519 break;
2520 case BRIDGE_OVFX2:
2521 reg_w_mask(sd, 0x0f, 0x02, 0x02);
2522 break;
2523 case BRIDGE_W9968CF:
2524 reg_w(sd, 0x3c, 0x8a05);
2525 break;
2526 }
2527}
2528
2529static void ov51x_set_slave_ids(struct sd *sd, u8 slave);
2530
2531
2532
2533
2534static int init_ov_sensor(struct sd *sd, u8 slave)
2535{
2536 int i;
2537 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2538
2539 ov51x_set_slave_ids(sd, slave);
2540
2541
2542 i2c_w(sd, 0x12, 0x80);
2543
2544
2545 msleep(150);
2546
2547 for (i = 0; i < i2c_detect_tries; i++) {
2548 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
2549 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
2550 gspca_dbg(gspca_dev, D_PROBE, "I2C synced in %d attempt(s)\n",
2551 i);
2552 return 0;
2553 }
2554
2555
2556 i2c_w(sd, 0x12, 0x80);
2557
2558
2559 msleep(150);
2560
2561
2562 if (i2c_r(sd, 0x00) < 0)
2563 return -1;
2564 }
2565 return -1;
2566}
2567
2568
2569
2570
2571
2572
2573static void ov51x_set_slave_ids(struct sd *sd,
2574 u8 slave)
2575{
2576 switch (sd->bridge) {
2577 case BRIDGE_OVFX2:
2578 reg_w(sd, OVFX2_I2C_ADDR, slave);
2579 return;
2580 case BRIDGE_W9968CF:
2581 sd->sensor_addr = slave;
2582 return;
2583 }
2584
2585 reg_w(sd, R51x_I2C_W_SID, slave);
2586 reg_w(sd, R51x_I2C_R_SID, slave + 1);
2587}
2588
2589static void write_regvals(struct sd *sd,
2590 const struct ov_regvals *regvals,
2591 int n)
2592{
2593 while (--n >= 0) {
2594 reg_w(sd, regvals->reg, regvals->val);
2595 regvals++;
2596 }
2597}
2598
2599static void write_i2c_regvals(struct sd *sd,
2600 const struct ov_i2c_regvals *regvals,
2601 int n)
2602{
2603 while (--n >= 0) {
2604 i2c_w(sd, regvals->reg, regvals->val);
2605 regvals++;
2606 }
2607}
2608
2609
2610
2611
2612
2613
2614
2615
2616static void ov_hires_configure(struct sd *sd)
2617{
2618 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2619 int high, low;
2620
2621 if (sd->bridge != BRIDGE_OVFX2) {
2622 gspca_err(gspca_dev, "error hires sensors only supported with ovfx2\n");
2623 return;
2624 }
2625
2626 gspca_dbg(gspca_dev, D_PROBE, "starting ov hires configuration\n");
2627
2628
2629 high = i2c_r(sd, 0x0a);
2630 low = i2c_r(sd, 0x0b);
2631
2632 switch (high) {
2633 case 0x96:
2634 switch (low) {
2635 case 0x40:
2636 gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV2610\n");
2637 sd->sensor = SEN_OV2610;
2638 return;
2639 case 0x41:
2640 gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV2610AE\n");
2641 sd->sensor = SEN_OV2610AE;
2642 return;
2643 case 0xb1:
2644 gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV9600\n");
2645 sd->sensor = SEN_OV9600;
2646 return;
2647 }
2648 break;
2649 case 0x36:
2650 if ((low & 0x0f) == 0x00) {
2651 gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV3610\n");
2652 sd->sensor = SEN_OV3610;
2653 return;
2654 }
2655 break;
2656 }
2657 gspca_err(gspca_dev, "Error unknown sensor type: %02x%02x\n",
2658 high, low);
2659}
2660
2661
2662
2663
2664static void ov8xx0_configure(struct sd *sd)
2665{
2666 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2667 int rc;
2668
2669 gspca_dbg(gspca_dev, D_PROBE, "starting ov8xx0 configuration\n");
2670
2671
2672 rc = i2c_r(sd, OV7610_REG_COM_I);
2673 if (rc < 0) {
2674 gspca_err(gspca_dev, "Error detecting sensor type\n");
2675 return;
2676 }
2677 if ((rc & 3) == 1)
2678 sd->sensor = SEN_OV8610;
2679 else
2680 gspca_err(gspca_dev, "Unknown image sensor version: %d\n",
2681 rc & 3);
2682}
2683
2684
2685
2686
2687static void ov7xx0_configure(struct sd *sd)
2688{
2689 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2690 int rc, high, low;
2691
2692 gspca_dbg(gspca_dev, D_PROBE, "starting OV7xx0 configuration\n");
2693
2694
2695 rc = i2c_r(sd, OV7610_REG_COM_I);
2696
2697
2698
2699 if (rc < 0) {
2700 gspca_err(gspca_dev, "Error detecting sensor type\n");
2701 return;
2702 }
2703 if ((rc & 3) == 3) {
2704
2705 high = i2c_r(sd, 0x0a);
2706 low = i2c_r(sd, 0x0b);
2707
2708 if (high == 0x76 && (low & 0xf0) == 0x70) {
2709 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV76%02x\n",
2710 low);
2711 sd->sensor = SEN_OV7670;
2712 } else {
2713 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7610\n");
2714 sd->sensor = SEN_OV7610;
2715 }
2716 } else if ((rc & 3) == 1) {
2717
2718 if (i2c_r(sd, 0x15) & 1) {
2719 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7620AE\n");
2720 sd->sensor = SEN_OV7620AE;
2721 } else {
2722 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV76BE\n");
2723 sd->sensor = SEN_OV76BE;
2724 }
2725 } else if ((rc & 3) == 0) {
2726
2727 high = i2c_r(sd, 0x0a);
2728 if (high < 0) {
2729 gspca_err(gspca_dev, "Error detecting camera chip PID\n");
2730 return;
2731 }
2732 low = i2c_r(sd, 0x0b);
2733 if (low < 0) {
2734 gspca_err(gspca_dev, "Error detecting camera chip VER\n");
2735 return;
2736 }
2737 if (high == 0x76) {
2738 switch (low) {
2739 case 0x30:
2740 gspca_err(gspca_dev, "Sensor is an OV7630/OV7635\n");
2741 gspca_err(gspca_dev, "7630 is not supported by this driver\n");
2742 return;
2743 case 0x40:
2744 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7645\n");
2745 sd->sensor = SEN_OV7640;
2746 break;
2747 case 0x45:
2748 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7645B\n");
2749 sd->sensor = SEN_OV7640;
2750 break;
2751 case 0x48:
2752 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7648\n");
2753 sd->sensor = SEN_OV7648;
2754 break;
2755 case 0x60:
2756 gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV7660\n");
2757 sd->sensor = SEN_OV7660;
2758 break;
2759 default:
2760 gspca_err(gspca_dev, "Unknown sensor: 0x76%02x\n",
2761 low);
2762 return;
2763 }
2764 } else {
2765 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7620\n");
2766 sd->sensor = SEN_OV7620;
2767 }
2768 } else {
2769 gspca_err(gspca_dev, "Unknown image sensor version: %d\n",
2770 rc & 3);
2771 }
2772}
2773
2774
2775static void ov6xx0_configure(struct sd *sd)
2776{
2777 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2778 int rc;
2779
2780 gspca_dbg(gspca_dev, D_PROBE, "starting OV6xx0 configuration\n");
2781
2782
2783 rc = i2c_r(sd, OV7610_REG_COM_I);
2784 if (rc < 0) {
2785 gspca_err(gspca_dev, "Error detecting sensor type\n");
2786 return;
2787 }
2788
2789
2790
2791
2792 switch (rc) {
2793 case 0x00:
2794 sd->sensor = SEN_OV6630;
2795 pr_warn("WARNING: Sensor is an OV66308. Your camera may have been misdetected in previous driver versions.\n");
2796 break;
2797 case 0x01:
2798 sd->sensor = SEN_OV6620;
2799 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV6620\n");
2800 break;
2801 case 0x02:
2802 sd->sensor = SEN_OV6630;
2803 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV66308AE\n");
2804 break;
2805 case 0x03:
2806 sd->sensor = SEN_OV66308AF;
2807 gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV66308AF\n");
2808 break;
2809 case 0x90:
2810 sd->sensor = SEN_OV6630;
2811 pr_warn("WARNING: Sensor is an OV66307. Your camera may have been misdetected in previous driver versions.\n");
2812 break;
2813 default:
2814 gspca_err(gspca_dev, "FATAL: Unknown sensor version: 0x%02x\n",
2815 rc);
2816 return;
2817 }
2818
2819
2820 sd->sif = 1;
2821}
2822
2823
2824static void ov51x_led_control(struct sd *sd, int on)
2825{
2826 if (sd->invert_led)
2827 on = !on;
2828
2829 switch (sd->bridge) {
2830
2831 case BRIDGE_OV511PLUS:
2832 reg_w(sd, R511_SYS_LED_CTL, on);
2833 break;
2834 case BRIDGE_OV518:
2835 case BRIDGE_OV518PLUS:
2836 reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02);
2837 break;
2838 case BRIDGE_OV519:
2839 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1);
2840 break;
2841 }
2842}
2843
2844static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
2845{
2846 struct sd *sd = (struct sd *) gspca_dev;
2847
2848 if (!sd->snapshot_needs_reset)
2849 return;
2850
2851
2852
2853
2854 sd->snapshot_needs_reset = 0;
2855
2856 switch (sd->bridge) {
2857 case BRIDGE_OV511:
2858 case BRIDGE_OV511PLUS:
2859 reg_w(sd, R51x_SYS_SNAP, 0x02);
2860 reg_w(sd, R51x_SYS_SNAP, 0x00);
2861 break;
2862 case BRIDGE_OV518:
2863 case BRIDGE_OV518PLUS:
2864 reg_w(sd, R51x_SYS_SNAP, 0x02);
2865 reg_w(sd, R51x_SYS_SNAP, 0x01);
2866 break;
2867 case BRIDGE_OV519:
2868 reg_w(sd, R51x_SYS_RESET, 0x40);
2869 reg_w(sd, R51x_SYS_RESET, 0x00);
2870 break;
2871 }
2872}
2873
2874static void ov51x_upload_quan_tables(struct sd *sd)
2875{
2876 static const unsigned char yQuanTable511[] = {
2877 0, 1, 1, 2, 2, 3, 3, 4,
2878 1, 1, 1, 2, 2, 3, 4, 4,
2879 1, 1, 2, 2, 3, 4, 4, 4,
2880 2, 2, 2, 3, 4, 4, 4, 4,
2881 2, 2, 3, 4, 4, 5, 5, 5,
2882 3, 3, 4, 4, 5, 5, 5, 5,
2883 3, 4, 4, 4, 5, 5, 5, 5,
2884 4, 4, 4, 4, 5, 5, 5, 5
2885 };
2886
2887 static const unsigned char uvQuanTable511[] = {
2888 0, 2, 2, 3, 4, 4, 4, 4,
2889 2, 2, 2, 4, 4, 4, 4, 4,
2890 2, 2, 3, 4, 4, 4, 4, 4,
2891 3, 4, 4, 4, 4, 4, 4, 4,
2892 4, 4, 4, 4, 4, 4, 4, 4,
2893 4, 4, 4, 4, 4, 4, 4, 4,
2894 4, 4, 4, 4, 4, 4, 4, 4,
2895 4, 4, 4, 4, 4, 4, 4, 4
2896 };
2897
2898
2899 static const unsigned char yQuanTable518[] = {
2900 5, 4, 5, 6, 6, 7, 7, 7,
2901 5, 5, 5, 5, 6, 7, 7, 7,
2902 6, 6, 6, 6, 7, 7, 7, 8,
2903 7, 7, 6, 7, 7, 7, 8, 8
2904 };
2905 static const unsigned char uvQuanTable518[] = {
2906 6, 6, 6, 7, 7, 7, 7, 7,
2907 6, 6, 6, 7, 7, 7, 7, 7,
2908 6, 6, 6, 7, 7, 7, 7, 8,
2909 7, 7, 7, 7, 7, 7, 8, 8
2910 };
2911
2912 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
2913 const unsigned char *pYTable, *pUVTable;
2914 unsigned char val0, val1;
2915 int i, size, reg = R51x_COMP_LUT_BEGIN;
2916
2917 gspca_dbg(gspca_dev, D_PROBE, "Uploading quantization tables\n");
2918
2919 if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
2920 pYTable = yQuanTable511;
2921 pUVTable = uvQuanTable511;
2922 size = 32;
2923 } else {
2924 pYTable = yQuanTable518;
2925 pUVTable = uvQuanTable518;
2926 size = 16;
2927 }
2928
2929 for (i = 0; i < size; i++) {
2930 val0 = *pYTable++;
2931 val1 = *pYTable++;
2932 val0 &= 0x0f;
2933 val1 &= 0x0f;
2934 val0 |= val1 << 4;
2935 reg_w(sd, reg, val0);
2936
2937 val0 = *pUVTable++;
2938 val1 = *pUVTable++;
2939 val0 &= 0x0f;
2940 val1 &= 0x0f;
2941 val0 |= val1 << 4;
2942 reg_w(sd, reg + size, val0);
2943
2944 reg++;
2945 }
2946}
2947
2948
2949static void ov511_configure(struct gspca_dev *gspca_dev)
2950{
2951 struct sd *sd = (struct sd *) gspca_dev;
2952
2953
2954 static const struct ov_regvals init_511[] = {
2955 { R51x_SYS_RESET, 0x7f },
2956 { R51x_SYS_INIT, 0x01 },
2957 { R51x_SYS_RESET, 0x7f },
2958 { R51x_SYS_INIT, 0x01 },
2959 { R51x_SYS_RESET, 0x3f },
2960 { R51x_SYS_INIT, 0x01 },
2961 { R51x_SYS_RESET, 0x3d },
2962 };
2963
2964 static const struct ov_regvals norm_511[] = {
2965 { R511_DRAM_FLOW_CTL, 0x01 },
2966 { R51x_SYS_SNAP, 0x00 },
2967 { R51x_SYS_SNAP, 0x02 },
2968 { R51x_SYS_SNAP, 0x00 },
2969 { R511_FIFO_OPTS, 0x1f },
2970 { R511_COMP_EN, 0x00 },
2971 { R511_COMP_LUT_EN, 0x03 },
2972 };
2973
2974 static const struct ov_regvals norm_511_p[] = {
2975 { R511_DRAM_FLOW_CTL, 0xff },
2976 { R51x_SYS_SNAP, 0x00 },
2977 { R51x_SYS_SNAP, 0x02 },
2978 { R51x_SYS_SNAP, 0x00 },
2979 { R511_FIFO_OPTS, 0xff },
2980 { R511_COMP_EN, 0x00 },
2981 { R511_COMP_LUT_EN, 0x03 },
2982 };
2983
2984 static const struct ov_regvals compress_511[] = {
2985 { 0x70, 0x1f },
2986 { 0x71, 0x05 },
2987 { 0x72, 0x06 },
2988 { 0x73, 0x06 },
2989 { 0x74, 0x14 },
2990 { 0x75, 0x03 },
2991 { 0x76, 0x04 },
2992 { 0x77, 0x04 },
2993 };
2994
2995 gspca_dbg(gspca_dev, D_PROBE, "Device custom id %x\n",
2996 reg_r(sd, R51x_SYS_CUST_ID));
2997
2998 write_regvals(sd, init_511, ARRAY_SIZE(init_511));
2999
3000 switch (sd->bridge) {
3001 case BRIDGE_OV511:
3002 write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
3003 break;
3004 case BRIDGE_OV511PLUS:
3005 write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
3006 break;
3007 }
3008
3009
3010 write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
3011
3012 ov51x_upload_quan_tables(sd);
3013}
3014
3015
3016static void ov518_configure(struct gspca_dev *gspca_dev)
3017{
3018 struct sd *sd = (struct sd *) gspca_dev;
3019
3020
3021 static const struct ov_regvals init_518[] = {
3022 { R51x_SYS_RESET, 0x40 },
3023 { R51x_SYS_INIT, 0xe1 },
3024 { R51x_SYS_RESET, 0x3e },
3025 { R51x_SYS_INIT, 0xe1 },
3026 { R51x_SYS_RESET, 0x00 },
3027 { R51x_SYS_INIT, 0xe1 },
3028 { 0x46, 0x00 },
3029 { 0x5d, 0x03 },
3030 };
3031
3032 static const struct ov_regvals norm_518[] = {
3033 { R51x_SYS_SNAP, 0x02 },
3034 { R51x_SYS_SNAP, 0x01 },
3035 { 0x31, 0x0f },
3036 { 0x5d, 0x03 },
3037 { 0x24, 0x9f },
3038 { 0x25, 0x90 },
3039 { 0x20, 0x00 },
3040 { 0x51, 0x04 },
3041 { 0x71, 0x19 },
3042 { 0x2f, 0x80 },
3043 };
3044
3045 static const struct ov_regvals norm_518_p[] = {
3046 { R51x_SYS_SNAP, 0x02 },
3047 { R51x_SYS_SNAP, 0x01 },
3048 { 0x31, 0x0f },
3049 { 0x5d, 0x03 },
3050 { 0x24, 0x9f },
3051 { 0x25, 0x90 },
3052 { 0x20, 0x60 },
3053 { 0x51, 0x02 },
3054 { 0x71, 0x19 },
3055 { 0x40, 0xff },
3056 { 0x41, 0x42 },
3057 { 0x46, 0x00 },
3058 { 0x33, 0x04 },
3059 { 0x21, 0x19 },
3060 { 0x3f, 0x10 },
3061 { 0x2f, 0x80 },
3062 };
3063
3064
3065 sd->revision = reg_r(sd, R51x_SYS_CUST_ID) & 0x1f;
3066 gspca_dbg(gspca_dev, D_PROBE, "Device revision %d\n", sd->revision);
3067
3068 write_regvals(sd, init_518, ARRAY_SIZE(init_518));
3069
3070
3071 reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
3072
3073 switch (sd->bridge) {
3074 case BRIDGE_OV518:
3075 write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
3076 break;
3077 case BRIDGE_OV518PLUS:
3078 write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
3079 break;
3080 }
3081
3082 ov51x_upload_quan_tables(sd);
3083
3084 reg_w(sd, 0x2f, 0x80);
3085}
3086
3087static void ov519_configure(struct sd *sd)
3088{
3089 static const struct ov_regvals init_519[] = {
3090 { 0x5a, 0x6d },
3091 { 0x53, 0x9b },
3092 { OV519_R54_EN_CLK1, 0xff },
3093 { 0x5d, 0x03 },
3094 { 0x49, 0x01 },
3095 { 0x48, 0x00 },
3096
3097
3098 { OV519_GPIO_IO_CTRL0, 0xee },
3099 { OV519_R51_RESET1, 0x0f },
3100 { OV519_R51_RESET1, 0x00 },
3101 { 0x22, 0x00 },
3102
3103 };
3104
3105 write_regvals(sd, init_519, ARRAY_SIZE(init_519));
3106}
3107
3108static void ovfx2_configure(struct sd *sd)
3109{
3110 static const struct ov_regvals init_fx2[] = {
3111 { 0x00, 0x60 },
3112 { 0x02, 0x01 },
3113 { 0x0f, 0x1d },
3114 { 0xe9, 0x82 },
3115 { 0xea, 0xc7 },
3116 { 0xeb, 0x10 },
3117 { 0xec, 0xf6 },
3118 };
3119
3120 sd->stopped = 1;
3121
3122 write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
3123}
3124
3125
3126
3127static void ov519_set_mode(struct sd *sd)
3128{
3129 static const struct ov_regvals bridge_ov7660[2][10] = {
3130 {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
3131 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3132 {0x25, 0x01}, {0x26, 0x00}},
3133 {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
3134 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3135 {0x25, 0x03}, {0x26, 0x00}}
3136 };
3137 static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
3138 {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
3139 {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
3140 };
3141 static const struct ov_i2c_regvals sensor_ov7660_2[] = {
3142 {OV7670_R17_HSTART, 0x13},
3143 {OV7670_R18_HSTOP, 0x01},
3144 {OV7670_R32_HREF, 0x92},
3145 {OV7670_R19_VSTART, 0x02},
3146 {OV7670_R1A_VSTOP, 0x7a},
3147 {OV7670_R03_VREF, 0x00},
3148
3149
3150
3151
3152 };
3153
3154 write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
3155 ARRAY_SIZE(bridge_ov7660[0]));
3156 write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
3157 ARRAY_SIZE(sensor_ov7660[0]));
3158 write_i2c_regvals(sd, sensor_ov7660_2,
3159 ARRAY_SIZE(sensor_ov7660_2));
3160}
3161
3162
3163
3164static void ov519_set_fr(struct sd *sd)
3165{
3166 int fr;
3167 u8 clock;
3168
3169
3170
3171
3172
3173 static const u8 fr_tb[2][6][3] = {
3174 {{0x04, 0xff, 0x00},
3175 {0x04, 0x1f, 0x00},
3176 {0x04, 0x1b, 0x00},
3177 {0x04, 0x15, 0x00},
3178 {0x04, 0x09, 0x00},
3179 {0x04, 0x01, 0x00}},
3180 {{0x0c, 0xff, 0x00},
3181 {0x0c, 0x1f, 0x00},
3182 {0x0c, 0x1b, 0x00},
3183 {0x04, 0xff, 0x01},
3184 {0x04, 0x1f, 0x01},
3185 {0x04, 0x1b, 0x01}},
3186 };
3187
3188 if (frame_rate > 0)
3189 sd->frame_rate = frame_rate;
3190 if (sd->frame_rate >= 30)
3191 fr = 0;
3192 else if (sd->frame_rate >= 25)
3193 fr = 1;
3194 else if (sd->frame_rate >= 20)
3195 fr = 2;
3196 else if (sd->frame_rate >= 15)
3197 fr = 3;
3198 else if (sd->frame_rate >= 10)
3199 fr = 4;
3200 else
3201 fr = 5;
3202 reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
3203 reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
3204 clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
3205 if (sd->sensor == SEN_OV7660)
3206 clock |= 0x80;
3207 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
3208}
3209
3210static void setautogain(struct gspca_dev *gspca_dev, s32 val)
3211{
3212 struct sd *sd = (struct sd *) gspca_dev;
3213
3214 i2c_w_mask(sd, 0x13, val ? 0x05 : 0x00, 0x05);
3215}
3216
3217
3218static int sd_config(struct gspca_dev *gspca_dev,
3219 const struct usb_device_id *id)
3220{
3221 struct sd *sd = (struct sd *) gspca_dev;
3222 struct cam *cam = &gspca_dev->cam;
3223
3224 sd->bridge = id->driver_info & BRIDGE_MASK;
3225 sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0;
3226
3227 switch (sd->bridge) {
3228 case BRIDGE_OV511:
3229 case BRIDGE_OV511PLUS:
3230 cam->cam_mode = ov511_vga_mode;
3231 cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
3232 break;
3233 case BRIDGE_OV518:
3234 case BRIDGE_OV518PLUS:
3235 cam->cam_mode = ov518_vga_mode;
3236 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
3237 break;
3238 case BRIDGE_OV519:
3239 cam->cam_mode = ov519_vga_mode;
3240 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3241 break;
3242 case BRIDGE_OVFX2:
3243 cam->cam_mode = ov519_vga_mode;
3244 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3245 cam->bulk_size = OVFX2_BULK_SIZE;
3246 cam->bulk_nurbs = MAX_NURBS;
3247 cam->bulk = 1;
3248 break;
3249 case BRIDGE_W9968CF:
3250 cam->cam_mode = w9968cf_vga_mode;
3251 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
3252 break;
3253 }
3254
3255 sd->frame_rate = 15;
3256
3257 return 0;
3258}
3259
3260
3261static int sd_init(struct gspca_dev *gspca_dev)
3262{
3263 struct sd *sd = (struct sd *) gspca_dev;
3264 struct cam *cam = &gspca_dev->cam;
3265
3266 switch (sd->bridge) {
3267 case BRIDGE_OV511:
3268 case BRIDGE_OV511PLUS:
3269 ov511_configure(gspca_dev);
3270 break;
3271 case BRIDGE_OV518:
3272 case BRIDGE_OV518PLUS:
3273 ov518_configure(gspca_dev);
3274 break;
3275 case BRIDGE_OV519:
3276 ov519_configure(sd);
3277 break;
3278 case BRIDGE_OVFX2:
3279 ovfx2_configure(sd);
3280 break;
3281 case BRIDGE_W9968CF:
3282 w9968cf_configure(sd);
3283 break;
3284 }
3285
3286
3287
3288
3289 sd->sensor = -1;
3290
3291
3292 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
3293 ov7xx0_configure(sd);
3294
3295
3296 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
3297 ov6xx0_configure(sd);
3298
3299
3300 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
3301 ov8xx0_configure(sd);
3302
3303
3304 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
3305 ov_hires_configure(sd);
3306 } else {
3307 gspca_err(gspca_dev, "Can't determine sensor slave IDs\n");
3308 goto error;
3309 }
3310
3311 if (sd->sensor < 0)
3312 goto error;
3313
3314 ov51x_led_control(sd, 0);
3315
3316 switch (sd->bridge) {
3317 case BRIDGE_OV511:
3318 case BRIDGE_OV511PLUS:
3319 if (sd->sif) {
3320 cam->cam_mode = ov511_sif_mode;
3321 cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
3322 }
3323 break;
3324 case BRIDGE_OV518:
3325 case BRIDGE_OV518PLUS:
3326 if (sd->sif) {
3327 cam->cam_mode = ov518_sif_mode;
3328 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
3329 }
3330 break;
3331 case BRIDGE_OV519:
3332 if (sd->sif) {
3333 cam->cam_mode = ov519_sif_mode;
3334 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3335 }
3336 break;
3337 case BRIDGE_OVFX2:
3338 switch (sd->sensor) {
3339 case SEN_OV2610:
3340 case SEN_OV2610AE:
3341 cam->cam_mode = ovfx2_ov2610_mode;
3342 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3343 break;
3344 case SEN_OV3610:
3345 cam->cam_mode = ovfx2_ov3610_mode;
3346 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3347 break;
3348 case SEN_OV9600:
3349 cam->cam_mode = ovfx2_ov9600_mode;
3350 cam->nmodes = ARRAY_SIZE(ovfx2_ov9600_mode);
3351 break;
3352 default:
3353 if (sd->sif) {
3354 cam->cam_mode = ov519_sif_mode;
3355 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3356 }
3357 break;
3358 }
3359 break;
3360 case BRIDGE_W9968CF:
3361 if (sd->sif)
3362 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1;
3363
3364
3365 w9968cf_init(sd);
3366 break;
3367 }
3368
3369
3370 switch (sd->sensor) {
3371 case SEN_OV2610:
3372 write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610));
3373
3374
3375 i2c_w_mask(sd, 0x13, 0x27, 0x27);
3376 break;
3377 case SEN_OV2610AE:
3378 write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae));
3379
3380
3381 i2c_w_mask(sd, 0x13, 0x05, 0x05);
3382 break;
3383 case SEN_OV3610:
3384 write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
3385
3386
3387 i2c_w_mask(sd, 0x13, 0x27, 0x27);
3388 break;
3389 case SEN_OV6620:
3390 write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20));
3391 break;
3392 case SEN_OV6630:
3393 case SEN_OV66308AF:
3394 write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30));
3395 break;
3396 default:
3397
3398
3399 write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610));
3400 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
3401 break;
3402 case SEN_OV7620:
3403 case SEN_OV7620AE:
3404 write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620));
3405 break;
3406 case SEN_OV7640:
3407 case SEN_OV7648:
3408 write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
3409 break;
3410 case SEN_OV7660:
3411 i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
3412 msleep(14);
3413 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
3414 write_regvals(sd, init_519_ov7660,
3415 ARRAY_SIZE(init_519_ov7660));
3416 write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
3417 sd->gspca_dev.curr_mode = 1;
3418 ov519_set_mode(sd);
3419 ov519_set_fr(sd);
3420 sd_reset_snapshot(gspca_dev);
3421 ov51x_restart(sd);
3422 ov51x_stop(sd);
3423 ov51x_led_control(sd, 0);
3424 break;
3425 case SEN_OV7670:
3426 write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670));
3427 break;
3428 case SEN_OV8610:
3429 write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610));
3430 break;
3431 case SEN_OV9600:
3432 write_i2c_regvals(sd, norm_9600, ARRAY_SIZE(norm_9600));
3433
3434
3435
3436 break;
3437 }
3438 return gspca_dev->usb_err;
3439error:
3440 gspca_err(gspca_dev, "OV519 Config failed\n");
3441 return -EINVAL;
3442}
3443
3444
3445static int sd_isoc_init(struct gspca_dev *gspca_dev)
3446{
3447 struct sd *sd = (struct sd *) gspca_dev;
3448
3449 switch (sd->bridge) {
3450 case BRIDGE_OVFX2:
3451 if (gspca_dev->pixfmt.width != 800)
3452 gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
3453 else
3454 gspca_dev->cam.bulk_size = 7 * 4096;
3455 break;
3456 }
3457 return 0;
3458}
3459
3460
3461
3462
3463
3464static void ov511_mode_init_regs(struct sd *sd)
3465{
3466 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
3467 int hsegs, vsegs, packet_size, fps, needed;
3468 int interlaced = 0;
3469 struct usb_host_interface *alt;
3470 struct usb_interface *intf;
3471
3472 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3473 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3474 if (!alt) {
3475 gspca_err(gspca_dev, "Couldn't get altsetting\n");
3476 sd->gspca_dev.usb_err = -EIO;
3477 return;
3478 }
3479
3480 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3481 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3482
3483 reg_w(sd, R511_CAM_UV_EN, 0x01);
3484 reg_w(sd, R511_SNAP_UV_EN, 0x01);
3485 reg_w(sd, R511_SNAP_OPTS, 0x03);
3486
3487
3488
3489
3490 hsegs = (sd->gspca_dev.pixfmt.width >> 3) - 1;
3491 vsegs = (sd->gspca_dev.pixfmt.height >> 3) - 1;
3492
3493 reg_w(sd, R511_CAM_PXCNT, hsegs);
3494 reg_w(sd, R511_CAM_LNCNT, vsegs);
3495 reg_w(sd, R511_CAM_PXDIV, 0x00);
3496 reg_w(sd, R511_CAM_LNDIV, 0x00);
3497
3498
3499 reg_w(sd, R511_CAM_OPTS, 0x03);
3500
3501
3502 reg_w(sd, R511_SNAP_PXCNT, hsegs);
3503 reg_w(sd, R511_SNAP_LNCNT, vsegs);
3504 reg_w(sd, R511_SNAP_PXDIV, 0x00);
3505 reg_w(sd, R511_SNAP_LNDIV, 0x00);
3506
3507
3508 if (frame_rate > 0)
3509 sd->frame_rate = frame_rate;
3510
3511 switch (sd->sensor) {
3512 case SEN_OV6620:
3513
3514 sd->clockdiv = 3;
3515 break;
3516
3517
3518
3519 case SEN_OV7620:
3520 case SEN_OV7620AE:
3521 case SEN_OV7640:
3522 case SEN_OV7648:
3523 case SEN_OV76BE:
3524 if (sd->gspca_dev.pixfmt.width == 320)
3525 interlaced = 1;
3526
3527 case SEN_OV6630:
3528 case SEN_OV7610:
3529 case SEN_OV7670:
3530 switch (sd->frame_rate) {
3531 case 30:
3532 case 25:
3533
3534 if (sd->gspca_dev.pixfmt.width != 640) {
3535 sd->clockdiv = 0;
3536 break;
3537 }
3538
3539
3540 default:
3541
3542
3543 sd->clockdiv = 1;
3544 break;
3545 case 10:
3546 sd->clockdiv = 2;
3547 break;
3548 case 5:
3549 sd->clockdiv = 5;
3550 break;
3551 }
3552 if (interlaced) {
3553 sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
3554
3555 if (sd->clockdiv > 10)
3556 sd->clockdiv = 10;
3557 }
3558 break;
3559
3560 case SEN_OV8610:
3561
3562 sd->clockdiv = 0;
3563 break;
3564 }
3565
3566
3567 fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
3568 needed = fps * sd->gspca_dev.pixfmt.width *
3569 sd->gspca_dev.pixfmt.height * 3 / 2;
3570
3571 if (needed > 1000 * packet_size) {
3572
3573 reg_w(sd, R511_COMP_EN, 0x07);
3574 reg_w(sd, R511_COMP_LUT_EN, 0x03);
3575 } else {
3576 reg_w(sd, R511_COMP_EN, 0x06);
3577 reg_w(sd, R511_COMP_LUT_EN, 0x00);
3578 }
3579
3580 reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
3581 reg_w(sd, R51x_SYS_RESET, 0);
3582}
3583
3584
3585
3586
3587
3588
3589
3590
3591static void ov518_mode_init_regs(struct sd *sd)
3592{
3593 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
3594 int hsegs, vsegs, packet_size;
3595 struct usb_host_interface *alt;
3596 struct usb_interface *intf;
3597
3598 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3599 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3600 if (!alt) {
3601 gspca_err(gspca_dev, "Couldn't get altsetting\n");
3602 sd->gspca_dev.usb_err = -EIO;
3603 return;
3604 }
3605
3606 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3607 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
3608
3609
3610 reg_w(sd, 0x2b, 0);
3611 reg_w(sd, 0x2c, 0);
3612 reg_w(sd, 0x2d, 0);
3613 reg_w(sd, 0x2e, 0);
3614 reg_w(sd, 0x3b, 0);
3615 reg_w(sd, 0x3c, 0);
3616 reg_w(sd, 0x3d, 0);
3617 reg_w(sd, 0x3e, 0);
3618
3619 if (sd->bridge == BRIDGE_OV518) {
3620
3621 reg_w_mask(sd, 0x20, 0x08, 0x08);
3622
3623
3624 reg_w_mask(sd, 0x28, 0x80, 0xf0);
3625 reg_w_mask(sd, 0x38, 0x80, 0xf0);
3626 } else {
3627 reg_w(sd, 0x28, 0x80);
3628 reg_w(sd, 0x38, 0x80);
3629 }
3630
3631 hsegs = sd->gspca_dev.pixfmt.width / 16;
3632 vsegs = sd->gspca_dev.pixfmt.height / 4;
3633
3634 reg_w(sd, 0x29, hsegs);
3635 reg_w(sd, 0x2a, vsegs);
3636
3637 reg_w(sd, 0x39, hsegs);
3638 reg_w(sd, 0x3a, vsegs);
3639
3640
3641 reg_w(sd, 0x2f, 0x80);
3642
3643
3644 if (sd->bridge == BRIDGE_OV518PLUS && sd->revision == 0 &&
3645 sd->sensor == SEN_OV7620AE)
3646 sd->clockdiv = 0;
3647 else
3648 sd->clockdiv = 1;
3649
3650
3651
3652 reg_w(sd, 0x51, 0x04);
3653 reg_w(sd, 0x22, 0x18);
3654 reg_w(sd, 0x23, 0xff);
3655
3656 if (sd->bridge == BRIDGE_OV518PLUS) {
3657 switch (sd->sensor) {
3658 case SEN_OV7620AE:
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671 if (sd->revision > 0 &&
3672 sd->gspca_dev.pixfmt.width == 640) {
3673 reg_w(sd, 0x20, 0x60);
3674 reg_w(sd, 0x21, 0x1f);
3675 } else {
3676 reg_w(sd, 0x20, 0x00);
3677 reg_w(sd, 0x21, 0x19);
3678 }
3679 break;
3680 case SEN_OV7620:
3681 reg_w(sd, 0x20, 0x00);
3682 reg_w(sd, 0x21, 0x19);
3683 break;
3684 default:
3685 reg_w(sd, 0x21, 0x19);
3686 }
3687 } else
3688 reg_w(sd, 0x71, 0x17);
3689
3690
3691
3692 i2c_w(sd, 0x54, 0x23);
3693
3694 reg_w(sd, 0x2f, 0x80);
3695
3696 if (sd->bridge == BRIDGE_OV518PLUS) {
3697 reg_w(sd, 0x24, 0x94);
3698 reg_w(sd, 0x25, 0x90);
3699 ov518_reg_w32(sd, 0xc4, 400, 2);
3700 ov518_reg_w32(sd, 0xc6, 540, 2);
3701 ov518_reg_w32(sd, 0xc7, 540, 2);
3702 ov518_reg_w32(sd, 0xc8, 108, 2);
3703 ov518_reg_w32(sd, 0xca, 131098, 3);
3704 ov518_reg_w32(sd, 0xcb, 532, 2);
3705 ov518_reg_w32(sd, 0xcc, 2400, 2);
3706 ov518_reg_w32(sd, 0xcd, 32, 2);
3707 ov518_reg_w32(sd, 0xce, 608, 2);
3708 } else {
3709 reg_w(sd, 0x24, 0x9f);
3710 reg_w(sd, 0x25, 0x90);
3711 ov518_reg_w32(sd, 0xc4, 400, 2);
3712 ov518_reg_w32(sd, 0xc6, 381, 2);
3713 ov518_reg_w32(sd, 0xc7, 381, 2);
3714 ov518_reg_w32(sd, 0xc8, 128, 2);
3715 ov518_reg_w32(sd, 0xca, 183331, 3);
3716 ov518_reg_w32(sd, 0xcb, 746, 2);
3717 ov518_reg_w32(sd, 0xcc, 1750, 2);
3718 ov518_reg_w32(sd, 0xcd, 45, 2);
3719 ov518_reg_w32(sd, 0xce, 851, 2);
3720 }
3721
3722 reg_w(sd, 0x2f, 0x80);
3723}
3724
3725
3726
3727
3728
3729
3730
3731
3732static void ov519_mode_init_regs(struct sd *sd)
3733{
3734 static const struct ov_regvals mode_init_519_ov7670[] = {
3735 { 0x5d, 0x03 },
3736 { 0x53, 0x9f },
3737 { OV519_R54_EN_CLK1, 0x0f },
3738 { 0xa2, 0x20 },
3739 { 0xa3, 0x18 },
3740 { 0xa4, 0x04 },
3741 { 0xa5, 0x28 },
3742 { 0x37, 0x00 },
3743 { 0x55, 0x02 },
3744
3745 { 0x20, 0x0c },
3746 { 0x21, 0x38 },
3747 { 0x22, 0x1d },
3748 { 0x17, 0x50 },
3749 { 0x37, 0x00 },
3750 { 0x40, 0xff },
3751 { 0x46, 0x00 },
3752 { 0x59, 0x04 },
3753 { 0xff, 0x00 },
3754
3755 };
3756
3757 static const struct ov_regvals mode_init_519[] = {
3758 { 0x5d, 0x03 },
3759 { 0x53, 0x9f },
3760 { OV519_R54_EN_CLK1, 0x0f },
3761 { 0xa2, 0x20 },
3762 { 0xa3, 0x18 },
3763 { 0xa4, 0x04 },
3764 { 0xa5, 0x28 },
3765 { 0x37, 0x00 },
3766 { 0x55, 0x02 },
3767
3768 { 0x22, 0x1d },
3769 { 0x17, 0x50 },
3770 { 0x37, 0x00 },
3771 { 0x40, 0xff },
3772 { 0x46, 0x00 },
3773 { 0x59, 0x04 },
3774 { 0xff, 0x00 },
3775
3776 };
3777
3778 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
3779
3780
3781 switch (sd->sensor) {
3782 default:
3783 write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
3784 if (sd->sensor == SEN_OV7640 ||
3785 sd->sensor == SEN_OV7648) {
3786
3787 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
3788 }
3789 break;
3790 case SEN_OV7660:
3791 return;
3792 case SEN_OV7670:
3793 write_regvals(sd, mode_init_519_ov7670,
3794 ARRAY_SIZE(mode_init_519_ov7670));
3795 break;
3796 }
3797
3798 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.pixfmt.width >> 4);
3799 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.pixfmt.height >> 3);
3800 if (sd->sensor == SEN_OV7670 &&
3801 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3802 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
3803 else if (sd->sensor == SEN_OV7648 &&
3804 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3805 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
3806 else
3807 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
3808 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
3809 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
3810 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
3811 reg_w(sd, OV519_R16_DIVIDER, 0x00);
3812 reg_w(sd, OV519_R25_FORMAT, 0x03);
3813 reg_w(sd, 0x26, 0x00);
3814
3815
3816 if (frame_rate > 0)
3817 sd->frame_rate = frame_rate;
3818
3819
3820 sd->clockdiv = 0;
3821 switch (sd->sensor) {
3822 case SEN_OV7640:
3823 case SEN_OV7648:
3824 switch (sd->frame_rate) {
3825 default:
3826
3827 reg_w(sd, 0xa4, 0x0c);
3828 reg_w(sd, 0x23, 0xff);
3829 break;
3830 case 25:
3831 reg_w(sd, 0xa4, 0x0c);
3832 reg_w(sd, 0x23, 0x1f);
3833 break;
3834 case 20:
3835 reg_w(sd, 0xa4, 0x0c);
3836 reg_w(sd, 0x23, 0x1b);
3837 break;
3838 case 15:
3839 reg_w(sd, 0xa4, 0x04);
3840 reg_w(sd, 0x23, 0xff);
3841 sd->clockdiv = 1;
3842 break;
3843 case 10:
3844 reg_w(sd, 0xa4, 0x04);
3845 reg_w(sd, 0x23, 0x1f);
3846 sd->clockdiv = 1;
3847 break;
3848 case 5:
3849 reg_w(sd, 0xa4, 0x04);
3850 reg_w(sd, 0x23, 0x1b);
3851 sd->clockdiv = 1;
3852 break;
3853 }
3854 break;
3855 case SEN_OV8610:
3856 switch (sd->frame_rate) {
3857 default:
3858
3859 reg_w(sd, 0xa4, 0x06);
3860 reg_w(sd, 0x23, 0xff);
3861 break;
3862 case 10:
3863 reg_w(sd, 0xa4, 0x06);
3864 reg_w(sd, 0x23, 0x1f);
3865 break;
3866 case 5:
3867 reg_w(sd, 0xa4, 0x06);
3868 reg_w(sd, 0x23, 0x1b);
3869 break;
3870 }
3871 break;
3872 case SEN_OV7670:
3873 gspca_dbg(gspca_dev, D_STREAM, "Setting framerate to %d fps\n",
3874 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
3875 reg_w(sd, 0xa4, 0x10);
3876 switch (sd->frame_rate) {
3877 case 30:
3878 reg_w(sd, 0x23, 0xff);
3879 break;
3880 case 20:
3881 reg_w(sd, 0x23, 0x1b);
3882 break;
3883 default:
3884
3885 reg_w(sd, 0x23, 0xff);
3886 sd->clockdiv = 1;
3887 break;
3888 }
3889 break;
3890 }
3891}
3892
3893static void mode_init_ov_sensor_regs(struct sd *sd)
3894{
3895 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
3896 int qvga, xstart, xend, ystart, yend;
3897 u8 v;
3898
3899 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
3900
3901
3902 switch (sd->sensor) {
3903 case SEN_OV2610:
3904 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3905 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3906 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3907 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3908 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3909 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3910 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3911 return;
3912 case SEN_OV2610AE: {
3913 u8 v;
3914
3915
3916
3917
3918
3919 v = 80;
3920 if (qvga) {
3921 if (sd->frame_rate < 25)
3922 v = 0x81;
3923 } else {
3924 if (sd->frame_rate < 10)
3925 v = 0x81;
3926 }
3927 i2c_w(sd, 0x11, v);
3928 i2c_w(sd, 0x12, qvga ? 0x60 : 0x20);
3929 return;
3930 }
3931 case SEN_OV3610:
3932 if (qvga) {
3933 xstart = (1040 - gspca_dev->pixfmt.width) / 2 +
3934 (0x1f << 4);
3935 ystart = (776 - gspca_dev->pixfmt.height) / 2;
3936 } else {
3937 xstart = (2076 - gspca_dev->pixfmt.width) / 2 +
3938 (0x10 << 4);
3939 ystart = (1544 - gspca_dev->pixfmt.height) / 2;
3940 }
3941 xend = xstart + gspca_dev->pixfmt.width;
3942 yend = ystart + gspca_dev->pixfmt.height;
3943
3944
3945 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3946 i2c_w_mask(sd, 0x32,
3947 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3948 0x3f);
3949 i2c_w_mask(sd, 0x03,
3950 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3951 0x0f);
3952 i2c_w(sd, 0x17, xstart >> 4);
3953 i2c_w(sd, 0x18, xend >> 4);
3954 i2c_w(sd, 0x19, ystart >> 3);
3955 i2c_w(sd, 0x1a, yend >> 3);
3956 return;
3957 case SEN_OV8610:
3958
3959 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
3960 i2c_w_mask(sd, 0x13, 0x00, 0x20);
3961 i2c_w_mask(sd, 0x12, 0x04, 0x06);
3962 i2c_w_mask(sd, 0x2d, 0x00, 0x40);
3963 i2c_w_mask(sd, 0x28, 0x20, 0x20);
3964 break;
3965 case SEN_OV7610:
3966 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3967 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
3968 i2c_w_mask(sd, 0x13, 0x00, 0x20);
3969 i2c_w_mask(sd, 0x12, 0x04, 0x06);
3970 break;
3971 case SEN_OV7620:
3972 case SEN_OV7620AE:
3973 case SEN_OV76BE:
3974 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3975 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3976 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3977 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3978 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3979 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
3980 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3981 i2c_w_mask(sd, 0x13, 0x00, 0x20);
3982 i2c_w_mask(sd, 0x12, 0x04, 0x06);
3983 if (sd->sensor == SEN_OV76BE)
3984 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
3985 break;
3986 case SEN_OV7640:
3987 case SEN_OV7648:
3988 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3989 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3990
3991
3992 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3993
3994 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3995
3996 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3997 i2c_w_mask(sd, 0x12, 0x04, 0x04);
3998 break;
3999 case SEN_OV7670:
4000
4001
4002
4003 i2c_w_mask(sd, OV7670_R12_COM7,
4004 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
4005 OV7670_COM7_FMT_MASK);
4006 i2c_w_mask(sd, 0x13, 0x00, 0x20);
4007 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
4008 OV7670_COM8_AWB);
4009 if (qvga) {
4010
4011 xstart = 164;
4012 xend = 28;
4013 ystart = 14;
4014 yend = 494;
4015 } else {
4016 xstart = 158;
4017 xend = 14;
4018 ystart = 10;
4019 yend = 490;
4020 }
4021
4022
4023 i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
4024 i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
4025 v = i2c_r(sd, OV7670_R32_HREF);
4026 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
4027 msleep(10);
4028
4029 i2c_w(sd, OV7670_R32_HREF, v);
4030
4031 i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
4032 i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
4033 v = i2c_r(sd, OV7670_R03_VREF);
4034 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
4035 msleep(10);
4036
4037 i2c_w(sd, OV7670_R03_VREF, v);
4038 break;
4039 case SEN_OV6620:
4040 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4041 i2c_w_mask(sd, 0x13, 0x00, 0x20);
4042 i2c_w_mask(sd, 0x12, 0x04, 0x06);
4043 break;
4044 case SEN_OV6630:
4045 case SEN_OV66308AF:
4046 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4047 i2c_w_mask(sd, 0x12, 0x04, 0x06);
4048 break;
4049 case SEN_OV9600: {
4050 const struct ov_i2c_regvals *vals;
4051 static const struct ov_i2c_regvals sxga_15[] = {
4052 {0x11, 0x80}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75}
4053 };
4054 static const struct ov_i2c_regvals sxga_7_5[] = {
4055 {0x11, 0x81}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75}
4056 };
4057 static const struct ov_i2c_regvals vga_30[] = {
4058 {0x11, 0x81}, {0x14, 0x7e}, {0x24, 0x70}, {0x25, 0x60}
4059 };
4060 static const struct ov_i2c_regvals vga_15[] = {
4061 {0x11, 0x83}, {0x14, 0x3e}, {0x24, 0x80}, {0x25, 0x70}
4062 };
4063
4064
4065
4066
4067
4068 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0x40);
4069 if (qvga)
4070 vals = sd->frame_rate < 30 ? vga_15 : vga_30;
4071 else
4072 vals = sd->frame_rate < 15 ? sxga_7_5 : sxga_15;
4073 write_i2c_regvals(sd, vals, ARRAY_SIZE(sxga_15));
4074 return;
4075 }
4076 default:
4077 return;
4078 }
4079
4080
4081 i2c_w(sd, 0x11, sd->clockdiv);
4082}
4083
4084
4085static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
4086{
4087 struct sd *sd = (struct sd *) gspca_dev;
4088
4089 if (sd->gspca_dev.streaming)
4090 reg_w(sd, OV519_R51_RESET1, 0x0f);
4091 i2c_w_mask(sd, OV7670_R1E_MVFP,
4092 OV7670_MVFP_MIRROR * hflip | OV7670_MVFP_VFLIP * vflip,
4093 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
4094 if (sd->gspca_dev.streaming)
4095 reg_w(sd, OV519_R51_RESET1, 0x00);
4096}
4097
4098static void set_ov_sensor_window(struct sd *sd)
4099{
4100 struct gspca_dev *gspca_dev;
4101 int qvga, crop;
4102 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
4103
4104
4105 switch (sd->sensor) {
4106 case SEN_OV2610:
4107 case SEN_OV2610AE:
4108 case SEN_OV3610:
4109 case SEN_OV7670:
4110 case SEN_OV9600:
4111 mode_init_ov_sensor_regs(sd);
4112 return;
4113 case SEN_OV7660:
4114 ov519_set_mode(sd);
4115 ov519_set_fr(sd);
4116 return;
4117 }
4118
4119 gspca_dev = &sd->gspca_dev;
4120 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
4121 crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
4122
4123
4124
4125 switch (sd->sensor) {
4126 case SEN_OV8610:
4127 hwsbase = 0x1e;
4128 hwebase = 0x1e;
4129 vwsbase = 0x02;
4130 vwebase = 0x02;
4131 break;
4132 case SEN_OV7610:
4133 case SEN_OV76BE:
4134 hwsbase = 0x38;
4135 hwebase = 0x3a;
4136 vwsbase = vwebase = 0x05;
4137 break;
4138 case SEN_OV6620:
4139 case SEN_OV6630:
4140 case SEN_OV66308AF:
4141 hwsbase = 0x38;
4142 hwebase = 0x3a;
4143 vwsbase = 0x05;
4144 vwebase = 0x06;
4145 if (sd->sensor == SEN_OV66308AF && qvga)
4146
4147 hwsbase++;
4148 if (crop) {
4149 hwsbase += 8;
4150 hwebase += 8;
4151 vwsbase += 11;
4152 vwebase += 11;
4153 }
4154 break;
4155 case SEN_OV7620:
4156 case SEN_OV7620AE:
4157 hwsbase = 0x2f;
4158 hwebase = 0x2f;
4159 vwsbase = vwebase = 0x05;
4160 break;
4161 case SEN_OV7640:
4162 case SEN_OV7648:
4163 hwsbase = 0x1a;
4164 hwebase = 0x1a;
4165 vwsbase = vwebase = 0x03;
4166 break;
4167 default:
4168 return;
4169 }
4170
4171 switch (sd->sensor) {
4172 case SEN_OV6620:
4173 case SEN_OV6630:
4174 case SEN_OV66308AF:
4175 if (qvga) {
4176 hwscale = 0;
4177 vwscale = 0;
4178 } else {
4179 hwscale = 1;
4180 vwscale = 1;
4181
4182 }
4183 break;
4184 case SEN_OV8610:
4185 if (qvga) {
4186 hwscale = 1;
4187 vwscale = 1;
4188 } else {
4189 hwscale = 2;
4190 vwscale = 2;
4191 }
4192 break;
4193 default:
4194 if (qvga) {
4195 hwscale = 1;
4196 vwscale = 0;
4197 } else {
4198 hwscale = 2;
4199 vwscale = 1;
4200 }
4201 }
4202
4203 mode_init_ov_sensor_regs(sd);
4204
4205 i2c_w(sd, 0x17, hwsbase);
4206 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
4207 i2c_w(sd, 0x19, vwsbase);
4208 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
4209}
4210
4211
4212static int sd_start(struct gspca_dev *gspca_dev)
4213{
4214 struct sd *sd = (struct sd *) gspca_dev;
4215
4216
4217 sd->sensor_width = sd->gspca_dev.pixfmt.width;
4218 sd->sensor_height = sd->gspca_dev.pixfmt.height;
4219
4220 switch (sd->bridge) {
4221 case BRIDGE_OV511:
4222 case BRIDGE_OV511PLUS:
4223 ov511_mode_init_regs(sd);
4224 break;
4225 case BRIDGE_OV518:
4226 case BRIDGE_OV518PLUS:
4227 ov518_mode_init_regs(sd);
4228 break;
4229 case BRIDGE_OV519:
4230 ov519_mode_init_regs(sd);
4231 break;
4232
4233 case BRIDGE_W9968CF:
4234 w9968cf_mode_init_regs(sd);
4235 break;
4236 }
4237
4238 set_ov_sensor_window(sd);
4239
4240
4241
4242 sd->snapshot_needs_reset = 1;
4243 sd_reset_snapshot(gspca_dev);
4244
4245 sd->first_frame = 3;
4246
4247 ov51x_restart(sd);
4248 ov51x_led_control(sd, 1);
4249 return gspca_dev->usb_err;
4250}
4251
4252static void sd_stopN(struct gspca_dev *gspca_dev)
4253{
4254 struct sd *sd = (struct sd *) gspca_dev;
4255
4256 ov51x_stop(sd);
4257 ov51x_led_control(sd, 0);
4258}
4259
4260static void sd_stop0(struct gspca_dev *gspca_dev)
4261{
4262 struct sd *sd = (struct sd *) gspca_dev;
4263
4264 if (!sd->gspca_dev.present)
4265 return;
4266 if (sd->bridge == BRIDGE_W9968CF)
4267 w9968cf_stop0(sd);
4268
4269#if IS_ENABLED(CONFIG_INPUT)
4270
4271 if (sd->snapshot_pressed) {
4272 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
4273 input_sync(gspca_dev->input_dev);
4274 sd->snapshot_pressed = 0;
4275 }
4276#endif
4277 if (sd->bridge == BRIDGE_OV519)
4278 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
4279}
4280
4281static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
4282{
4283 struct sd *sd = (struct sd *) gspca_dev;
4284
4285 if (sd->snapshot_pressed != state) {
4286#if IS_ENABLED(CONFIG_INPUT)
4287 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
4288 input_sync(gspca_dev->input_dev);
4289#endif
4290 if (state)
4291 sd->snapshot_needs_reset = 1;
4292
4293 sd->snapshot_pressed = state;
4294 } else {
4295
4296
4297
4298 switch (sd->bridge) {
4299 case BRIDGE_OV511:
4300 case BRIDGE_OV511PLUS:
4301 case BRIDGE_OV519:
4302 if (state)
4303 sd->snapshot_needs_reset = 1;
4304 break;
4305 }
4306 }
4307}
4308
4309static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
4310 u8 *in,
4311 int len)
4312{
4313 struct sd *sd = (struct sd *) gspca_dev;
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
4329 (in[8] & 0x08)) {
4330 ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
4331 if (in[8] & 0x80) {
4332
4333 if ((in[9] + 1) * 8 != gspca_dev->pixfmt.width ||
4334 (in[10] + 1) * 8 != gspca_dev->pixfmt.height) {
4335 gspca_err(gspca_dev, "Invalid frame size, got: %dx%d, requested: %dx%d\n",
4336 (in[9] + 1) * 8, (in[10] + 1) * 8,
4337 gspca_dev->pixfmt.width,
4338 gspca_dev->pixfmt.height);
4339 gspca_dev->last_packet_type = DISCARD_PACKET;
4340 return;
4341 }
4342
4343 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
4344 return;
4345 } else {
4346
4347 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
4348 sd->packet_nr = 0;
4349 }
4350 }
4351
4352
4353 len--;
4354
4355
4356 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
4357}
4358
4359static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
4360 u8 *data,
4361 int len)
4362{
4363 struct sd *sd = (struct sd *) gspca_dev;
4364
4365
4366
4367 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
4368 ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
4369 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4370 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
4371 sd->packet_nr = 0;
4372 }
4373
4374 if (gspca_dev->last_packet_type == DISCARD_PACKET)
4375 return;
4376
4377
4378 if (len & 7) {
4379 len--;
4380 if (sd->packet_nr == data[len])
4381 sd->packet_nr++;
4382
4383
4384
4385 else if (sd->packet_nr == 0 || data[len]) {
4386 gspca_err(gspca_dev, "Invalid packet nr: %d (expect: %d)\n",
4387 (int)data[len], (int)sd->packet_nr);
4388 gspca_dev->last_packet_type = DISCARD_PACKET;
4389 return;
4390 }
4391 }
4392
4393
4394 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4395}
4396
4397static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
4398 u8 *data,
4399 int len)
4400{
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4414 switch (data[3]) {
4415 case 0x50:
4416
4417
4418
4419#define HDRSZ 16
4420 data += HDRSZ;
4421 len -= HDRSZ;
4422#undef HDRSZ
4423 if (data[0] == 0xff || data[1] == 0xd8)
4424 gspca_frame_add(gspca_dev, FIRST_PACKET,
4425 data, len);
4426 else
4427 gspca_dev->last_packet_type = DISCARD_PACKET;
4428 return;
4429 case 0x51:
4430 ov51x_handle_button(gspca_dev, data[11] & 1);
4431 if (data[9] != 0)
4432 gspca_dev->last_packet_type = DISCARD_PACKET;
4433 gspca_frame_add(gspca_dev, LAST_PACKET,
4434 NULL, 0);
4435 return;
4436 }
4437 }
4438
4439
4440 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4441}
4442
4443static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
4444 u8 *data,
4445 int len)
4446{
4447 struct sd *sd = (struct sd *) gspca_dev;
4448
4449 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4450
4451
4452 if (len < gspca_dev->cam.bulk_size) {
4453
4454
4455 if (sd->first_frame) {
4456 sd->first_frame--;
4457 if (gspca_dev->image_len <
4458 sd->gspca_dev.pixfmt.width *
4459 sd->gspca_dev.pixfmt.height)
4460 gspca_dev->last_packet_type = DISCARD_PACKET;
4461 }
4462 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4463 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
4464 }
4465}
4466
4467static void sd_pkt_scan(struct gspca_dev *gspca_dev,
4468 u8 *data,
4469 int len)
4470{
4471 struct sd *sd = (struct sd *) gspca_dev;
4472
4473 switch (sd->bridge) {
4474 case BRIDGE_OV511:
4475 case BRIDGE_OV511PLUS:
4476 ov511_pkt_scan(gspca_dev, data, len);
4477 break;
4478 case BRIDGE_OV518:
4479 case BRIDGE_OV518PLUS:
4480 ov518_pkt_scan(gspca_dev, data, len);
4481 break;
4482 case BRIDGE_OV519:
4483 ov519_pkt_scan(gspca_dev, data, len);
4484 break;
4485 case BRIDGE_OVFX2:
4486 ovfx2_pkt_scan(gspca_dev, data, len);
4487 break;
4488 case BRIDGE_W9968CF:
4489 w9968cf_pkt_scan(gspca_dev, data, len);
4490 break;
4491 }
4492}
4493
4494
4495
4496static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
4497{
4498 struct sd *sd = (struct sd *) gspca_dev;
4499 static const struct ov_i2c_regvals brit_7660[][7] = {
4500 {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
4501 {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
4502 {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
4503 {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
4504 {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
4505 {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
4506 {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
4507 {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
4508 {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
4509 {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
4510 {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
4511 {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
4512 {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
4513 {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
4514 };
4515
4516 switch (sd->sensor) {
4517 case SEN_OV8610:
4518 case SEN_OV7610:
4519 case SEN_OV76BE:
4520 case SEN_OV6620:
4521 case SEN_OV6630:
4522 case SEN_OV66308AF:
4523 case SEN_OV7640:
4524 case SEN_OV7648:
4525 i2c_w(sd, OV7610_REG_BRT, val);
4526 break;
4527 case SEN_OV7620:
4528 case SEN_OV7620AE:
4529 i2c_w(sd, OV7610_REG_BRT, val);
4530 break;
4531 case SEN_OV7660:
4532 write_i2c_regvals(sd, brit_7660[val],
4533 ARRAY_SIZE(brit_7660[0]));
4534 break;
4535 case SEN_OV7670:
4536
4537
4538 i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
4539 break;
4540 }
4541}
4542
4543static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
4544{
4545 struct sd *sd = (struct sd *) gspca_dev;
4546 static const struct ov_i2c_regvals contrast_7660[][31] = {
4547 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
4548 {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
4549 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
4550 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
4551 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
4552 {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
4553 {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
4554 {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
4555 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
4556 {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
4557 {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
4558 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
4559 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
4560 {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
4561 {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
4562 {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
4563 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
4564 {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
4565 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
4566 {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
4567 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
4568 {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
4569 {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
4570 {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
4571 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
4572 {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
4573 {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
4574 {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
4575 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
4576 {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
4577 {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
4578 {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
4579 {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
4580 {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
4581 {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
4582 {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
4583 {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
4584 {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
4585 {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
4586 {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
4587 {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
4588 {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
4589 {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
4590 {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
4591 {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
4592 {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
4593 {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
4594 {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
4595 {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
4596 {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
4597 {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
4598 {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
4599 {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
4600 {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
4601 {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
4602 {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
4603 };
4604
4605 switch (sd->sensor) {
4606 case SEN_OV7610:
4607 case SEN_OV6620:
4608 i2c_w(sd, OV7610_REG_CNT, val);
4609 break;
4610 case SEN_OV6630:
4611 case SEN_OV66308AF:
4612 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
4613 break;
4614 case SEN_OV8610: {
4615 static const u8 ctab[] = {
4616 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
4617 };
4618
4619
4620 i2c_w(sd, 0x64, ctab[val >> 5]);
4621 break;
4622 }
4623 case SEN_OV7620:
4624 case SEN_OV7620AE: {
4625 static const u8 ctab[] = {
4626 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4627 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
4628 };
4629
4630
4631 i2c_w(sd, 0x64, ctab[val >> 4]);
4632 break;
4633 }
4634 case SEN_OV7660:
4635 write_i2c_regvals(sd, contrast_7660[val],
4636 ARRAY_SIZE(contrast_7660[0]));
4637 break;
4638 case SEN_OV7670:
4639
4640 i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
4641 break;
4642 }
4643}
4644
4645static void setexposure(struct gspca_dev *gspca_dev, s32 val)
4646{
4647 struct sd *sd = (struct sd *) gspca_dev;
4648
4649 i2c_w(sd, 0x10, val);
4650}
4651
4652static void setcolors(struct gspca_dev *gspca_dev, s32 val)
4653{
4654 struct sd *sd = (struct sd *) gspca_dev;
4655 static const struct ov_i2c_regvals colors_7660[][6] = {
4656 {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
4657 {0x53, 0x19}, {0x54, 0x23}},
4658 {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
4659 {0x53, 0x2c}, {0x54, 0x3e}},
4660 {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
4661 {0x53, 0x40}, {0x54, 0x59}},
4662 {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
4663 {0x53, 0x53}, {0x54, 0x73}},
4664 {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
4665 {0x53, 0x66}, {0x54, 0x8e}},
4666 };
4667
4668 switch (sd->sensor) {
4669 case SEN_OV8610:
4670 case SEN_OV7610:
4671 case SEN_OV76BE:
4672 case SEN_OV6620:
4673 case SEN_OV6630:
4674 case SEN_OV66308AF:
4675 i2c_w(sd, OV7610_REG_SAT, val);
4676 break;
4677 case SEN_OV7620:
4678 case SEN_OV7620AE:
4679
4680
4681
4682
4683 i2c_w(sd, OV7610_REG_SAT, val);
4684 break;
4685 case SEN_OV7640:
4686 case SEN_OV7648:
4687 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4688 break;
4689 case SEN_OV7660:
4690 write_i2c_regvals(sd, colors_7660[val],
4691 ARRAY_SIZE(colors_7660[0]));
4692 break;
4693 case SEN_OV7670:
4694
4695
4696
4697 break;
4698 }
4699}
4700
4701static void setautobright(struct gspca_dev *gspca_dev, s32 val)
4702{
4703 struct sd *sd = (struct sd *) gspca_dev;
4704
4705 i2c_w_mask(sd, 0x2d, val ? 0x10 : 0x00, 0x10);
4706}
4707
4708static void setfreq_i(struct sd *sd, s32 val)
4709{
4710 if (sd->sensor == SEN_OV7660
4711 || sd->sensor == SEN_OV7670) {
4712 switch (val) {
4713 case 0:
4714 i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
4715 break;
4716 case 1:
4717 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
4718 OV7670_COM8_BFILT);
4719 i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
4720 break;
4721 case 2:
4722 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
4723 OV7670_COM8_BFILT);
4724 i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
4725 break;
4726 case 3:
4727 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
4728 OV7670_COM8_BFILT);
4729 i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
4730 0x18);
4731 break;
4732 }
4733 } else {
4734 switch (val) {
4735 case 0:
4736 i2c_w_mask(sd, 0x2d, 0x00, 0x04);
4737 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4738 break;
4739 case 1:
4740 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4741 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4742
4743 if (sd->sensor == SEN_OV6620 ||
4744 sd->sensor == SEN_OV6630 ||
4745 sd->sensor == SEN_OV66308AF)
4746 i2c_w(sd, 0x2b, 0x5e);
4747 else
4748 i2c_w(sd, 0x2b, 0xac);
4749 break;
4750 case 2:
4751 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4752 if (sd->sensor == SEN_OV6620 ||
4753 sd->sensor == SEN_OV6630 ||
4754 sd->sensor == SEN_OV66308AF) {
4755
4756 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4757 i2c_w(sd, 0x2b, 0xa8);
4758 } else {
4759
4760 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4761 }
4762 break;
4763 }
4764 }
4765}
4766
4767static void setfreq(struct gspca_dev *gspca_dev, s32 val)
4768{
4769 struct sd *sd = (struct sd *) gspca_dev;
4770
4771 setfreq_i(sd, val);
4772
4773
4774 if (sd->bridge == BRIDGE_W9968CF)
4775 w9968cf_set_crop_window(sd);
4776}
4777
4778static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4779 struct v4l2_jpegcompression *jcomp)
4780{
4781 struct sd *sd = (struct sd *) gspca_dev;
4782
4783 if (sd->bridge != BRIDGE_W9968CF)
4784 return -ENOTTY;
4785
4786 memset(jcomp, 0, sizeof *jcomp);
4787 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
4788 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4789 V4L2_JPEG_MARKER_DRI;
4790 return 0;
4791}
4792
4793static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4794 const struct v4l2_jpegcompression *jcomp)
4795{
4796 struct sd *sd = (struct sd *) gspca_dev;
4797
4798 if (sd->bridge != BRIDGE_W9968CF)
4799 return -ENOTTY;
4800
4801 v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
4802 return 0;
4803}
4804
4805static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
4806{
4807 struct gspca_dev *gspca_dev =
4808 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
4809 struct sd *sd = (struct sd *)gspca_dev;
4810
4811 gspca_dev->usb_err = 0;
4812
4813 switch (ctrl->id) {
4814 case V4L2_CID_AUTOGAIN:
4815 gspca_dev->exposure->val = i2c_r(sd, 0x10);
4816 break;
4817 }
4818 return 0;
4819}
4820
4821static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
4822{
4823 struct gspca_dev *gspca_dev =
4824 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
4825 struct sd *sd = (struct sd *)gspca_dev;
4826
4827 gspca_dev->usb_err = 0;
4828
4829 if (!gspca_dev->streaming)
4830 return 0;
4831
4832 switch (ctrl->id) {
4833 case V4L2_CID_BRIGHTNESS:
4834 setbrightness(gspca_dev, ctrl->val);
4835 break;
4836 case V4L2_CID_CONTRAST:
4837 setcontrast(gspca_dev, ctrl->val);
4838 break;
4839 case V4L2_CID_POWER_LINE_FREQUENCY:
4840 setfreq(gspca_dev, ctrl->val);
4841 break;
4842 case V4L2_CID_AUTOBRIGHTNESS:
4843 if (ctrl->is_new)
4844 setautobright(gspca_dev, ctrl->val);
4845 if (!ctrl->val && sd->brightness->is_new)
4846 setbrightness(gspca_dev, sd->brightness->val);
4847 break;
4848 case V4L2_CID_SATURATION:
4849 setcolors(gspca_dev, ctrl->val);
4850 break;
4851 case V4L2_CID_HFLIP:
4852 sethvflip(gspca_dev, ctrl->val, sd->vflip->val);
4853 break;
4854 case V4L2_CID_AUTOGAIN:
4855 if (ctrl->is_new)
4856 setautogain(gspca_dev, ctrl->val);
4857 if (!ctrl->val && gspca_dev->exposure->is_new)
4858 setexposure(gspca_dev, gspca_dev->exposure->val);
4859 break;
4860 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
4861 return -EBUSY;
4862 }
4863 return gspca_dev->usb_err;
4864}
4865
4866static const struct v4l2_ctrl_ops sd_ctrl_ops = {
4867 .g_volatile_ctrl = sd_g_volatile_ctrl,
4868 .s_ctrl = sd_s_ctrl,
4869};
4870
4871static int sd_init_controls(struct gspca_dev *gspca_dev)
4872{
4873 struct sd *sd = (struct sd *)gspca_dev;
4874 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
4875
4876 gspca_dev->vdev.ctrl_handler = hdl;
4877 v4l2_ctrl_handler_init(hdl, 10);
4878 if (valid_controls[sd->sensor].has_brightness)
4879 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4880 V4L2_CID_BRIGHTNESS, 0,
4881 sd->sensor == SEN_OV7660 ? 6 : 255, 1,
4882 sd->sensor == SEN_OV7660 ? 3 : 127);
4883 if (valid_controls[sd->sensor].has_contrast) {
4884 if (sd->sensor == SEN_OV7660)
4885 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4886 V4L2_CID_CONTRAST, 0, 6, 1, 3);
4887 else
4888 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4889 V4L2_CID_CONTRAST, 0, 255, 1,
4890 (sd->sensor == SEN_OV6630 ||
4891 sd->sensor == SEN_OV66308AF) ? 200 : 127);
4892 }
4893 if (valid_controls[sd->sensor].has_sat)
4894 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4895 V4L2_CID_SATURATION, 0,
4896 sd->sensor == SEN_OV7660 ? 4 : 255, 1,
4897 sd->sensor == SEN_OV7660 ? 2 : 127);
4898 if (valid_controls[sd->sensor].has_exposure)
4899 gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4900 V4L2_CID_EXPOSURE, 0, 255, 1, 127);
4901 if (valid_controls[sd->sensor].has_hvflip) {
4902 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4903 V4L2_CID_HFLIP, 0, 1, 1, 0);
4904 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4905 V4L2_CID_VFLIP, 0, 1, 1, 0);
4906 }
4907 if (valid_controls[sd->sensor].has_autobright)
4908 sd->autobright = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4909 V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, 1);
4910 if (valid_controls[sd->sensor].has_autogain)
4911 gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4912 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
4913 if (valid_controls[sd->sensor].has_freq) {
4914 if (sd->sensor == SEN_OV7670)
4915 sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
4916 V4L2_CID_POWER_LINE_FREQUENCY,
4917 V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
4918 V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
4919 else
4920 sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
4921 V4L2_CID_POWER_LINE_FREQUENCY,
4922 V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0);
4923 }
4924 if (sd->bridge == BRIDGE_W9968CF)
4925 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
4926 V4L2_CID_JPEG_COMPRESSION_QUALITY,
4927 QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
4928
4929 if (hdl->error) {
4930 gspca_err(gspca_dev, "Could not initialize controls\n");
4931 return hdl->error;
4932 }
4933 if (gspca_dev->autogain)
4934 v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, true);
4935 if (sd->autobright)
4936 v4l2_ctrl_auto_cluster(2, &sd->autobright, 0, false);
4937 if (sd->hflip)
4938 v4l2_ctrl_cluster(2, &sd->hflip);
4939 return 0;
4940}
4941
4942
4943static const struct sd_desc sd_desc = {
4944 .name = MODULE_NAME,
4945 .config = sd_config,
4946 .init = sd_init,
4947 .init_controls = sd_init_controls,
4948 .isoc_init = sd_isoc_init,
4949 .start = sd_start,
4950 .stopN = sd_stopN,
4951 .stop0 = sd_stop0,
4952 .pkt_scan = sd_pkt_scan,
4953 .dq_callback = sd_reset_snapshot,
4954 .get_jcomp = sd_get_jcomp,
4955 .set_jcomp = sd_set_jcomp,
4956#if IS_ENABLED(CONFIG_INPUT)
4957 .other_input = 1,
4958#endif
4959};
4960
4961
4962static const struct usb_device_id device_table[] = {
4963 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
4964 {USB_DEVICE(0x041e, 0x4052),
4965 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4966 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
4967 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
4968 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
4969 {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
4970 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
4971 {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
4972 {USB_DEVICE(0x045e, 0x028c),
4973 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4974 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
4975 {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
4976 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
4977 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4978 {USB_DEVICE(0x05a9, 0x0519),
4979 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4980 {USB_DEVICE(0x05a9, 0x0530),
4981 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
4982 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
4983 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
4984 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
4985 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
4986 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
4987 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
4988 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4989 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
4990 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
4991 {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
4992 {}
4993};
4994
4995MODULE_DEVICE_TABLE(usb, device_table);
4996
4997
4998static int sd_probe(struct usb_interface *intf,
4999 const struct usb_device_id *id)
5000{
5001 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
5002 THIS_MODULE);
5003}
5004
5005static struct usb_driver sd_driver = {
5006 .name = MODULE_NAME,
5007 .id_table = device_table,
5008 .probe = sd_probe,
5009 .disconnect = gspca_disconnect,
5010#ifdef CONFIG_PM
5011 .suspend = gspca_suspend,
5012 .resume = gspca_resume,
5013 .reset_resume = gspca_resume,
5014#endif
5015};
5016
5017module_usb_driver(sd_driver);
5018
5019module_param(frame_rate, int, 0644);
5020MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");
5021