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