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