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