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#include <linux/config.h>
39#include <linux/version.h>
40#include <linux/module.h>
41#include <linux/init.h>
42#include <linux/fs.h>
43#include <linux/vmalloc.h>
44#include <linux/slab.h>
45#include <linux/proc_fs.h>
46#include <linux/ctype.h>
47#include <linux/pagemap.h>
48#include <asm/io.h>
49#include <asm/semaphore.h>
50#include <asm/processor.h>
51#include <linux/wrapper.h>
52#include <linux/mm.h>
53
54#if defined (__i386__)
55 #include <asm/cpufeature.h>
56#endif
57
58#include "ov511.h"
59
60
61
62
63#define DRIVER_VERSION "v1.63 for Linux 2.4"
64#define EMAIL "mark@alpha.dyndns.org"
65#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \
66 & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
67 <cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
68#define DRIVER_DESC "ov511 USB Camera Driver"
69
70#define OV511_I2C_RETRIES 3
71#define ENABLE_Y_QUANTABLE 1
72#define ENABLE_UV_QUANTABLE 1
73
74#define OV511_MAX_UNIT_VIDEO 16
75
76
77#define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3)
78
79#define MAX_DATA_SIZE(w, h) (MAX_FRAME_SIZE(w, h) + sizeof(struct timeval))
80
81
82#define MAX_RAW_DATA_SIZE(w, h) ((w) * (h) * 3 / 2 + 1024)
83
84#define FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM)
85
86
87
88
89
90
91
92static int autobright = 1;
93static int autogain = 1;
94static int autoexp = 1;
95static int debug;
96static int snapshot;
97static int fix_rgb_offset;
98static int force_rgb;
99static int cams = 1;
100static int compress;
101static int testpat;
102static int dumppix;
103static int led = 1;
104static int dump_bridge;
105static int dump_sensor;
106static int printph;
107static int phy = 0x1f;
108static int phuv = 0x05;
109static int pvy = 0x06;
110static int pvuv = 0x06;
111static int qhy = 0x14;
112static int qhuv = 0x03;
113static int qvy = 0x04;
114static int qvuv = 0x04;
115static int lightfreq;
116static int bandingfilter;
117static int clockdiv = -1;
118static int packetsize = -1;
119static int framedrop = -1;
120static int fastset;
121static int force_palette;
122static int backlight;
123static int unit_video[OV511_MAX_UNIT_VIDEO];
124static int remove_zeros;
125static int mirror;
126static int ov518_color;
127
128MODULE_PARM(autobright, "i");
129MODULE_PARM_DESC(autobright, "Sensor automatically changes brightness");
130MODULE_PARM(autogain, "i");
131MODULE_PARM_DESC(autogain, "Sensor automatically changes gain");
132MODULE_PARM(autoexp, "i");
133MODULE_PARM_DESC(autoexp, "Sensor automatically changes exposure");
134MODULE_PARM(debug, "i");
135MODULE_PARM_DESC(debug,
136 "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max");
137MODULE_PARM(snapshot, "i");
138MODULE_PARM_DESC(snapshot, "Enable snapshot mode");
139MODULE_PARM(fix_rgb_offset, "i");
140MODULE_PARM_DESC(fix_rgb_offset,
141 "Fix vertical misalignment of red and blue at 640x480");
142MODULE_PARM(force_rgb, "i");
143MODULE_PARM_DESC(force_rgb, "Read RGB instead of BGR");
144MODULE_PARM(cams, "i");
145MODULE_PARM_DESC(cams, "Number of simultaneous cameras");
146MODULE_PARM(compress, "i");
147MODULE_PARM_DESC(compress, "Turn on compression (not reliable yet)");
148MODULE_PARM(testpat, "i");
149MODULE_PARM_DESC(testpat,
150 "Replace image with vertical bar testpattern (only partially working)");
151MODULE_PARM(dumppix, "i");
152MODULE_PARM_DESC(dumppix, "Dump raw pixel data");
153MODULE_PARM(led, "i");
154MODULE_PARM_DESC(led,
155 "LED policy (OV511+ or later). 0=off, 1=on (default), 2=auto (on when open)");
156MODULE_PARM(dump_bridge, "i");
157MODULE_PARM_DESC(dump_bridge, "Dump the bridge registers");
158MODULE_PARM(dump_sensor, "i");
159MODULE_PARM_DESC(dump_sensor, "Dump the sensor registers");
160MODULE_PARM(printph, "i");
161MODULE_PARM_DESC(printph, "Print frame start/end headers");
162MODULE_PARM(phy, "i");
163MODULE_PARM_DESC(phy, "Prediction range (horiz. Y)");
164MODULE_PARM(phuv, "i");
165MODULE_PARM_DESC(phuv, "Prediction range (horiz. UV)");
166MODULE_PARM(pvy, "i");
167MODULE_PARM_DESC(pvy, "Prediction range (vert. Y)");
168MODULE_PARM(pvuv, "i");
169MODULE_PARM_DESC(pvuv, "Prediction range (vert. UV)");
170MODULE_PARM(qhy, "i");
171MODULE_PARM_DESC(qhy, "Quantization threshold (horiz. Y)");
172MODULE_PARM(qhuv, "i");
173MODULE_PARM_DESC(qhuv, "Quantization threshold (horiz. UV)");
174MODULE_PARM(qvy, "i");
175MODULE_PARM_DESC(qvy, "Quantization threshold (vert. Y)");
176MODULE_PARM(qvuv, "i");
177MODULE_PARM_DESC(qvuv, "Quantization threshold (vert. UV)");
178MODULE_PARM(lightfreq, "i");
179MODULE_PARM_DESC(lightfreq,
180 "Light frequency. Set to 50 or 60 Hz, or zero for default settings");
181MODULE_PARM(bandingfilter, "i");
182MODULE_PARM_DESC(bandingfilter,
183 "Enable banding filter (to reduce effects of fluorescent lighting)");
184MODULE_PARM(clockdiv, "i");
185MODULE_PARM_DESC(clockdiv, "Force pixel clock divisor to a specific value");
186MODULE_PARM(packetsize, "i");
187MODULE_PARM_DESC(packetsize, "Force a specific isoc packet size");
188MODULE_PARM(framedrop, "i");
189MODULE_PARM_DESC(framedrop, "Force a specific frame drop register setting");
190MODULE_PARM(fastset, "i");
191MODULE_PARM_DESC(fastset, "Allows picture settings to take effect immediately");
192MODULE_PARM(force_palette, "i");
193MODULE_PARM_DESC(force_palette, "Force the palette to a specific value");
194MODULE_PARM(backlight, "i");
195MODULE_PARM_DESC(backlight, "For objects that are lit from behind");
196MODULE_PARM(unit_video, "1-" __MODULE_STRING(OV511_MAX_UNIT_VIDEO) "i");
197MODULE_PARM_DESC(unit_video,
198 "Force use of specific minor number(s). 0 is not allowed.");
199MODULE_PARM(remove_zeros, "i");
200MODULE_PARM_DESC(remove_zeros,
201 "Remove zero-padding from uncompressed incoming data");
202MODULE_PARM(mirror, "i");
203MODULE_PARM_DESC(mirror, "Reverse image horizontally");
204MODULE_PARM(ov518_color, "i");
205MODULE_PARM_DESC(ov518_color, "Enable OV518 color (experimental)");
206
207MODULE_AUTHOR(DRIVER_AUTHOR);
208MODULE_DESCRIPTION(DRIVER_DESC);
209MODULE_LICENSE("GPL");
210
211
212
213
214
215static struct usb_driver ov511_driver;
216
217static struct ov51x_decomp_ops *ov511_decomp_ops;
218static struct ov51x_decomp_ops *ov511_mmx_decomp_ops;
219static struct ov51x_decomp_ops *ov518_decomp_ops;
220static struct ov51x_decomp_ops *ov518_mmx_decomp_ops;
221
222
223
224static int i2c_detect_tries = 5;
225
226
227static int ov51x_mmx_available;
228
229static struct usb_device_id device_table [] = {
230 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
231 { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
232 { USB_DEVICE(VEND_OMNIVISION, PROD_OV518) },
233 { USB_DEVICE(VEND_OMNIVISION, PROD_OV518PLUS) },
234 { USB_DEVICE(VEND_MATTEL, PROD_ME2CAM) },
235 { }
236};
237
238MODULE_DEVICE_TABLE (usb, device_table);
239
240static unsigned char yQuanTable511[] = OV511_YQUANTABLE;
241static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE;
242static unsigned char yQuanTable518[] = OV518_YQUANTABLE;
243static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE;
244
245
246
247
248
249
250static struct symbolic_list camlist[] = {
251 { 0, "Generic Camera (no ID)" },
252 { 1, "Mustek WCam 3X" },
253 { 3, "D-Link DSB-C300" },
254 { 4, "Generic OV511/OV7610" },
255 { 5, "Puretek PT-6007" },
256 { 6, "Lifeview USB Life TV (NTSC)" },
257 { 21, "Creative Labs WebCam 3" },
258 { 22, "Lifeview USB Life TV (PAL D/K+B/G)" },
259 { 36, "Koala-Cam" },
260 { 38, "Lifeview USB Life TV (PAL)" },
261 { 41, "Samsung Anycam MPC-M10" },
262 { 43, "Mtekvision Zeca MV402" },
263 { 46, "Suma eON" },
264 { 70, "Lifeview USB Life TV (PAL/SECAM)" },
265 { 100, "Lifeview RoboCam" },
266 { 102, "AverMedia InterCam Elite" },
267 { 112, "MediaForte MV300" },
268 { 134, "Ezonics EZCam II" },
269 { 192, "Webeye 2000B" },
270 { 253, "Alpha Vision Tech. AlphaCam SE" },
271 { -1, NULL }
272};
273
274
275static struct symbolic_list v4l1_plist[] = {
276 { VIDEO_PALETTE_GREY, "GREY" },
277 { VIDEO_PALETTE_HI240, "HI240" },
278 { VIDEO_PALETTE_RGB565, "RGB565" },
279 { VIDEO_PALETTE_RGB24, "RGB24" },
280 { VIDEO_PALETTE_RGB32, "RGB32" },
281 { VIDEO_PALETTE_RGB555, "RGB555" },
282 { VIDEO_PALETTE_YUV422, "YUV422" },
283 { VIDEO_PALETTE_YUYV, "YUYV" },
284 { VIDEO_PALETTE_UYVY, "UYVY" },
285 { VIDEO_PALETTE_YUV420, "YUV420" },
286 { VIDEO_PALETTE_YUV411, "YUV411" },
287 { VIDEO_PALETTE_RAW, "RAW" },
288 { VIDEO_PALETTE_YUV422P,"YUV422P" },
289 { VIDEO_PALETTE_YUV411P,"YUV411P" },
290 { VIDEO_PALETTE_YUV420P,"YUV420P" },
291 { VIDEO_PALETTE_YUV410P,"YUV410P" },
292 { -1, NULL }
293};
294
295static struct symbolic_list brglist[] = {
296 { BRG_OV511, "OV511" },
297 { BRG_OV511PLUS, "OV511+" },
298 { BRG_OV518, "OV518" },
299 { BRG_OV518PLUS, "OV518+" },
300 { -1, NULL }
301};
302
303#if defined(CONFIG_VIDEO_PROC_FS)
304static struct symbolic_list senlist[] = {
305 { SEN_OV76BE, "OV76BE" },
306 { SEN_OV7610, "OV7610" },
307 { SEN_OV7620, "OV7620" },
308 { SEN_OV7620AE, "OV7620AE" },
309 { SEN_OV6620, "OV6620" },
310 { SEN_OV6630, "OV6630" },
311 { SEN_OV6630AE, "OV6630AE" },
312 { SEN_OV6630AF, "OV6630AF" },
313 { SEN_OV8600, "OV8600" },
314 { SEN_KS0127, "KS0127" },
315 { SEN_KS0127B, "KS0127B" },
316 { SEN_SAA7111A, "SAA7111A" },
317 { -1, NULL }
318};
319#endif
320
321
322static struct symbolic_list urb_errlist[] = {
323 { -ENOSR, "Buffer error (overrun)" },
324 { -EPIPE, "Stalled (device not responding)" },
325 { -EOVERFLOW, "Babble (bad cable?)" },
326 { -EPROTO, "Bit-stuff error (bad cable?)" },
327 { -EILSEQ, "CRC/Timeout" },
328 { -ETIMEDOUT, "NAK (device does not respond)" },
329 { -1, NULL }
330};
331
332
333
334
335
336static void ov51x_clear_snapshot(struct usb_ov511 *);
337static int sensor_get_picture(struct usb_ov511 *,
338 struct video_picture *);
339#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
340static int sensor_get_exposure(struct usb_ov511 *, unsigned char *);
341static int ov51x_control_ioctl(struct inode *, struct file *, unsigned int,
342 unsigned long);
343static int ov51x_check_snapshot(struct usb_ov511 *);
344#endif
345
346
347
348
349
350
351
352
353static inline unsigned long
354kvirt_to_pa(unsigned long adr)
355{
356 unsigned long kva, ret;
357
358 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
359 kva |= adr & (PAGE_SIZE-1);
360 ret = __pa(kva);
361 return ret;
362}
363
364static void *
365rvmalloc(unsigned long size)
366{
367 void *mem;
368 unsigned long adr;
369
370 size = PAGE_ALIGN(size);
371 mem = vmalloc_32(size);
372 if (!mem)
373 return NULL;
374
375 memset(mem, 0, size);
376 adr = (unsigned long) mem;
377 while (size > 0) {
378 mem_map_reserve(vmalloc_to_page((void *)adr));
379 adr += PAGE_SIZE;
380 size -= PAGE_SIZE;
381 }
382
383 return mem;
384}
385
386static void
387rvfree(void *mem, unsigned long size)
388{
389 unsigned long adr;
390
391 if (!mem)
392 return;
393
394 adr = (unsigned long) mem;
395 while ((long) size > 0) {
396 mem_map_unreserve(vmalloc_to_page((void *)adr));
397 adr += PAGE_SIZE;
398 size -= PAGE_SIZE;
399 }
400 vfree(mem);
401}
402
403
404
405
406
407
408#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
409
410static struct proc_dir_entry *ov511_proc_entry = NULL;
411extern struct proc_dir_entry *video_proc_entry;
412
413static struct file_operations ov511_control_fops = {
414 .ioctl = ov51x_control_ioctl,
415};
416
417#define YES_NO(x) ((x) ? "yes" : "no")
418
419
420static int
421ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
422 void *data)
423{
424 char *out = page;
425 int i, len;
426 struct usb_ov511 *ov = data;
427 struct video_picture p;
428 unsigned char exp;
429
430 if (!ov || !ov->dev)
431 return -ENODEV;
432
433 sensor_get_picture(ov, &p);
434 sensor_get_exposure(ov, &exp);
435
436
437
438
439 out += sprintf(out, "driver_version : %s\n", DRIVER_VERSION);
440 out += sprintf(out, "custom_id : %d\n", ov->customid);
441 out += sprintf(out, "model : %s\n", ov->desc);
442 out += sprintf(out, "streaming : %s\n", YES_NO(ov->streaming));
443 out += sprintf(out, "grabbing : %s\n", YES_NO(ov->grabbing));
444 out += sprintf(out, "compress : %s\n", YES_NO(ov->compress));
445 out += sprintf(out, "subcapture : %s\n", YES_NO(ov->sub_flag));
446 out += sprintf(out, "sub_size : %d %d %d %d\n",
447 ov->subx, ov->suby, ov->subw, ov->subh);
448 out += sprintf(out, "data_format : %s\n",
449 force_rgb ? "RGB" : "BGR");
450 out += sprintf(out, "brightness : %d\n", p.brightness >> 8);
451 out += sprintf(out, "colour : %d\n", p.colour >> 8);
452 out += sprintf(out, "contrast : %d\n", p.contrast >> 8);
453 out += sprintf(out, "hue : %d\n", p.hue >> 8);
454 out += sprintf(out, "exposure : %d\n", exp);
455 out += sprintf(out, "num_frames : %d\n", OV511_NUMFRAMES);
456 for (i = 0; i < OV511_NUMFRAMES; i++) {
457 out += sprintf(out, "frame : %d\n", i);
458 out += sprintf(out, " depth : %d\n",
459 ov->frame[i].depth);
460 out += sprintf(out, " size : %d %d\n",
461 ov->frame[i].width, ov->frame[i].height);
462 out += sprintf(out, " format : %s\n",
463 symbolic(v4l1_plist, ov->frame[i].format));
464 out += sprintf(out, " data_buffer : 0x%p\n",
465 ov->frame[i].data);
466 }
467 out += sprintf(out, "snap_enabled : %s\n", YES_NO(ov->snap_enabled));
468 out += sprintf(out, "bridge : %s\n",
469 symbolic(brglist, ov->bridge));
470 out += sprintf(out, "sensor : %s\n",
471 symbolic(senlist, ov->sensor));
472 out += sprintf(out, "packet_size : %d\n", ov->packet_size);
473 out += sprintf(out, "framebuffer : 0x%p\n", ov->fbuf);
474 out += sprintf(out, "packet_numbering: %d\n", ov->packet_numbering);
475 out += sprintf(out, "topology : %s\n", ov->usb_path);
476
477 len = out - page;
478 len -= off;
479 if (len < count) {
480 *eof = 1;
481 if (len <= 0)
482 return 0;
483 } else
484 len = count;
485
486 *start = page + off;
487
488 return len;
489}
490
491
492
493
494
495
496
497
498
499
500
501
502static int
503ov511_read_proc_button(char *page, char **start, off_t off, int count, int *eof,
504 void *data)
505{
506 char *out = page;
507 int len, status;
508 struct usb_ov511 *ov = data;
509
510 if (!ov || !ov->dev)
511 return -ENODEV;
512
513 status = ov51x_check_snapshot(ov);
514 out += sprintf(out, "%d", status);
515
516 if (status)
517 ov51x_clear_snapshot(ov);
518
519 len = out - page;
520 len -= off;
521 if (len < count) {
522 *eof = 1;
523 if (len <= 0)
524 return 0;
525 } else {
526 len = count;
527 }
528
529 *start = page + off;
530
531 return len;
532}
533
534static void
535create_proc_ov511_cam(struct usb_ov511 *ov)
536{
537 char dirname[10];
538
539 if (!ov511_proc_entry || !ov)
540 return;
541
542
543 snprintf(dirname, 10, "%d", ov->vdev.minor);
544 PDEBUG(4, "creating /proc/video/ov511/%s/", dirname);
545 ov->proc_devdir = create_proc_entry(dirname, S_IFDIR, ov511_proc_entry);
546 if (!ov->proc_devdir)
547 return;
548 ov->proc_devdir->owner = THIS_MODULE;
549
550
551 PDEBUG(4, "creating /proc/video/ov511/%s/info", dirname);
552 ov->proc_info = create_proc_read_entry("info", S_IFREG|S_IRUGO|S_IWUSR,
553 ov->proc_devdir, ov511_read_proc_info, ov);
554 if (!ov->proc_info)
555 return;
556 ov->proc_info->owner = THIS_MODULE;
557
558
559 if (!snapshot) {
560
561 PDEBUG(4, "creating /proc/video/ov511/%s/button", dirname);
562 ov->proc_button = create_proc_read_entry("button",
563 S_IFREG|S_IRUGO|S_IWUSR, ov->proc_devdir,
564 ov511_read_proc_button, ov);
565 if (!ov->proc_button)
566 return;
567 ov->proc_button->owner = THIS_MODULE;
568 }
569
570
571 PDEBUG(4, "creating /proc/video/ov511/%s/control", dirname);
572 lock_kernel();
573 ov->proc_control = create_proc_entry("control", S_IFREG|S_IRUGO|S_IWUSR,
574 ov->proc_devdir);
575 if (!ov->proc_control) {
576 unlock_kernel();
577 return;
578 }
579 ov->proc_control->owner = THIS_MODULE;
580 ov->proc_control->data = ov;
581 ov->proc_control->proc_fops = &ov511_control_fops;
582 unlock_kernel();
583}
584
585static void
586destroy_proc_ov511_cam(struct usb_ov511 *ov)
587{
588 char dirname[10];
589
590 if (!ov || !ov->proc_devdir)
591 return;
592
593 snprintf(dirname, 10, "%d", ov->vdev.minor);
594
595
596 if (ov->proc_control) {
597 PDEBUG(4, "destroying /proc/video/ov511/%s/control", dirname);
598 remove_proc_entry("control", ov->proc_devdir);
599 ov->proc_control = NULL;
600 }
601
602
603 if (ov->proc_button) {
604 PDEBUG(4, "destroying /proc/video/ov511/%s/button", dirname);
605 remove_proc_entry("button", ov->proc_devdir);
606 ov->proc_button = NULL;
607 }
608
609
610 if (ov->proc_info) {
611 PDEBUG(4, "destroying /proc/video/ov511/%s/info", dirname);
612 remove_proc_entry("info", ov->proc_devdir);
613 ov->proc_info = NULL;
614 }
615
616
617 PDEBUG(4, "destroying /proc/video/ov511/%s/", dirname);
618 remove_proc_entry(dirname, ov511_proc_entry);
619 ov->proc_devdir = NULL;
620}
621
622static void
623proc_ov511_create(void)
624{
625
626
627
628
629 if (video_proc_entry == NULL) {
630 err("Error: /proc/video/ does not exist");
631 return;
632 }
633
634 ov511_proc_entry = create_proc_entry("ov511", S_IFDIR,
635 video_proc_entry);
636
637 if (ov511_proc_entry)
638 ov511_proc_entry->owner = THIS_MODULE;
639 else
640 err("Unable to create /proc/video/ov511");
641}
642
643static void
644proc_ov511_destroy(void)
645{
646 PDEBUG(3, "removing /proc/video/ov511");
647
648 if (ov511_proc_entry == NULL)
649 return;
650
651 remove_proc_entry("ov511", video_proc_entry);
652}
653#endif
654
655
656
657
658
659
660
661
662static int
663reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
664{
665 int rc;
666
667 PDEBUG(5, "0x%02X:0x%02X", reg, value);
668
669 down(&ov->cbuf_lock);
670 ov->cbuf[0] = value;
671 rc = usb_control_msg(ov->dev,
672 usb_sndctrlpipe(ov->dev, 0),
673 (ov->bclass == BCL_OV518)?1:2 ,
674 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
675 0, (__u16)reg, &ov->cbuf[0], 1, HZ);
676 up(&ov->cbuf_lock);
677
678 if (rc < 0)
679 err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc));
680
681 return rc;
682}
683
684
685
686static int
687reg_r(struct usb_ov511 *ov, unsigned char reg)
688{
689 int rc;
690
691 down(&ov->cbuf_lock);
692 rc = usb_control_msg(ov->dev,
693 usb_rcvctrlpipe(ov->dev, 0),
694 (ov->bclass == BCL_OV518)?1:3 ,
695 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
696 0, (__u16)reg, &ov->cbuf[0], 1, HZ);
697
698 if (rc < 0) {
699 err("reg read: error %d: %s", rc, symbolic(urb_errlist, rc));
700 } else {
701 rc = ov->cbuf[0];
702 PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]);
703 }
704
705 up(&ov->cbuf_lock);
706
707 return rc;
708}
709
710
711
712
713
714
715
716static int
717reg_w_mask(struct usb_ov511 *ov,
718 unsigned char reg,
719 unsigned char value,
720 unsigned char mask)
721{
722 int ret;
723 unsigned char oldval, newval;
724
725 ret = reg_r(ov, reg);
726 if (ret < 0)
727 return ret;
728
729 oldval = (unsigned char) ret;
730 oldval &= (~mask);
731 value &= mask;
732 newval = oldval | value;
733
734 return (reg_w(ov, reg, newval));
735}
736
737
738
739
740
741static int
742ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
743{
744 int rc;
745
746 PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n);
747
748 down(&ov->cbuf_lock);
749
750 *((u32 *)ov->cbuf) = __cpu_to_le32(val);
751
752 rc = usb_control_msg(ov->dev,
753 usb_sndctrlpipe(ov->dev, 0),
754 1 ,
755 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
756 0, (__u16)reg, ov->cbuf, n, HZ);
757 up(&ov->cbuf_lock);
758
759 if (rc < 0)
760 err("reg write multiple: error %d: %s", rc,
761 symbolic(urb_errlist, rc));
762
763 return rc;
764}
765
766static int
767ov511_upload_quan_tables(struct usb_ov511 *ov)
768{
769 unsigned char *pYTable = yQuanTable511;
770 unsigned char *pUVTable = uvQuanTable511;
771 unsigned char val0, val1;
772 int i, rc, reg = R511_COMP_LUT_BEGIN;
773
774 PDEBUG(4, "Uploading quantization tables");
775
776 for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) {
777 if (ENABLE_Y_QUANTABLE) {
778 val0 = *pYTable++;
779 val1 = *pYTable++;
780 val0 &= 0x0f;
781 val1 &= 0x0f;
782 val0 |= val1 << 4;
783 rc = reg_w(ov, reg, val0);
784 if (rc < 0)
785 return rc;
786 }
787
788 if (ENABLE_UV_QUANTABLE) {
789 val0 = *pUVTable++;
790 val1 = *pUVTable++;
791 val0 &= 0x0f;
792 val1 &= 0x0f;
793 val0 |= val1 << 4;
794 rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0);
795 if (rc < 0)
796 return rc;
797 }
798
799 reg++;
800 }
801
802 return 0;
803}
804
805
806static int
807ov518_upload_quan_tables(struct usb_ov511 *ov)
808{
809 unsigned char *pYTable = yQuanTable518;
810 unsigned char *pUVTable = uvQuanTable518;
811 unsigned char val0, val1;
812 int i, rc, reg = R511_COMP_LUT_BEGIN;
813
814 PDEBUG(4, "Uploading quantization tables");
815
816 for (i = 0; i < OV518_QUANTABLESIZE / 2; i++) {
817 if (ENABLE_Y_QUANTABLE) {
818 val0 = *pYTable++;
819 val1 = *pYTable++;
820 val0 &= 0x0f;
821 val1 &= 0x0f;
822 val0 |= val1 << 4;
823 rc = reg_w(ov, reg, val0);
824 if (rc < 0)
825 return rc;
826 }
827
828 if (ENABLE_UV_QUANTABLE) {
829 val0 = *pUVTable++;
830 val1 = *pUVTable++;
831 val0 &= 0x0f;
832 val1 &= 0x0f;
833 val0 |= val1 << 4;
834 rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0);
835 if (rc < 0)
836 return rc;
837 }
838
839 reg++;
840 }
841
842 return 0;
843}
844
845static int
846ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type)
847{
848 int rc;
849
850
851 if (ov->bclass == BCL_OV518)
852 reset_type &= 0xfe;
853
854 PDEBUG(4, "Reset: type=0x%02X", reset_type);
855
856 rc = reg_w(ov, R51x_SYS_RESET, reset_type);
857 rc = reg_w(ov, R51x_SYS_RESET, 0);
858
859 if (rc < 0)
860 err("reset: command failed");
861
862 return rc;
863}
864
865
866
867
868
869
870
871
872
873
874
875
876static int
877ov518_i2c_write_internal(struct usb_ov511 *ov,
878 unsigned char reg,
879 unsigned char value)
880{
881 int rc;
882
883 PDEBUG(5, "0x%02X:0x%02X", reg, value);
884
885
886 rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
887 if (rc < 0) return rc;
888
889
890 rc = reg_w(ov, R51x_I2C_DATA, value);
891 if (rc < 0) return rc;
892
893
894 rc = reg_w(ov, R518_I2C_CTL, 0x01);
895 if (rc < 0) return rc;
896
897 return 0;
898}
899
900
901static int
902ov511_i2c_write_internal(struct usb_ov511 *ov,
903 unsigned char reg,
904 unsigned char value)
905{
906 int rc, retries;
907
908 PDEBUG(5, "0x%02X:0x%02X", reg, value);
909
910
911 for (retries = OV511_I2C_RETRIES; ; ) {
912
913 rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
914 if (rc < 0) return rc;
915
916
917 rc = reg_w(ov, R51x_I2C_DATA, value);
918 if (rc < 0) return rc;
919
920
921 rc = reg_w(ov, R511_I2C_CTL, 0x01);
922 if (rc < 0) return rc;
923
924 do rc = reg_r(ov, R511_I2C_CTL);
925 while (rc > 0 && ((rc&1) == 0));
926 if (rc < 0) return rc;
927
928 if ((rc&2) == 0)
929 break;
930#if 0
931
932 reg_w(ov, R511_I2C_CTL, 0x10);
933#endif
934 if (--retries < 0) {
935 err("i2c write retries exhausted");
936 return -1;
937 }
938 }
939
940 return 0;
941}
942
943
944
945
946
947
948static int
949ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
950{
951 int rc, value;
952
953
954 rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
955 if (rc < 0) return rc;
956
957
958 rc = reg_w(ov, R518_I2C_CTL, 0x03);
959 if (rc < 0) return rc;
960
961
962 rc = reg_w(ov, R518_I2C_CTL, 0x05);
963 if (rc < 0) return rc;
964
965 value = reg_r(ov, R51x_I2C_DATA);
966
967 PDEBUG(5, "0x%02X:0x%02X", reg, value);
968
969 return value;
970}
971
972
973
974static int
975ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
976{
977 int rc, value, retries;
978
979
980 for (retries = OV511_I2C_RETRIES; ; ) {
981
982 rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
983 if (rc < 0) return rc;
984
985
986 rc = reg_w(ov, R511_I2C_CTL, 0x03);
987 if (rc < 0) return rc;
988
989 do rc = reg_r(ov, R511_I2C_CTL);
990 while (rc > 0 && ((rc&1) == 0));
991 if (rc < 0) return rc;
992
993 if ((rc&2) == 0)
994 break;
995
996
997 reg_w(ov, R511_I2C_CTL, 0x10);
998
999 if (--retries < 0) {
1000 err("i2c write retries exhausted");
1001 return -1;
1002 }
1003 }
1004
1005
1006 for (retries = OV511_I2C_RETRIES; ; ) {
1007
1008 rc = reg_w(ov, R511_I2C_CTL, 0x05);
1009 if (rc < 0) return rc;
1010
1011 do rc = reg_r(ov, R511_I2C_CTL);
1012 while (rc > 0 && ((rc&1) == 0));
1013 if (rc < 0) return rc;
1014
1015 if ((rc&2) == 0)
1016 break;
1017
1018
1019 rc = reg_w(ov, R511_I2C_CTL, 0x10);
1020 if (rc < 0) return rc;
1021
1022 if (--retries < 0) {
1023 err("i2c read retries exhausted");
1024 return -1;
1025 }
1026 }
1027
1028 value = reg_r(ov, R51x_I2C_DATA);
1029
1030 PDEBUG(5, "0x%02X:0x%02X", reg, value);
1031
1032
1033 rc = reg_w(ov, R511_I2C_CTL, 0x05);
1034 if (rc < 0)
1035 return rc;
1036
1037 return value;
1038}
1039
1040
1041static int
1042i2c_r(struct usb_ov511 *ov, unsigned char reg)
1043{
1044 int rc;
1045
1046 down(&ov->i2c_lock);
1047
1048 if (ov->bclass == BCL_OV518)
1049 rc = ov518_i2c_read_internal(ov, reg);
1050 else
1051 rc = ov511_i2c_read_internal(ov, reg);
1052
1053 up(&ov->i2c_lock);
1054
1055 return rc;
1056}
1057
1058static int
1059i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
1060{
1061 int rc;
1062
1063 down(&ov->i2c_lock);
1064
1065 if (ov->bclass == BCL_OV518)
1066 rc = ov518_i2c_write_internal(ov, reg, value);
1067 else
1068 rc = ov511_i2c_write_internal(ov, reg, value);
1069
1070 up(&ov->i2c_lock);
1071
1072 return rc;
1073}
1074
1075
1076static int
1077ov51x_i2c_write_mask_internal(struct usb_ov511 *ov,
1078 unsigned char reg,
1079 unsigned char value,
1080 unsigned char mask)
1081{
1082 int rc;
1083 unsigned char oldval, newval;
1084
1085 if (mask == 0xff) {
1086 newval = value;
1087 } else {
1088 if (ov->bclass == BCL_OV518)
1089 rc = ov518_i2c_read_internal(ov, reg);
1090 else
1091 rc = ov511_i2c_read_internal(ov, reg);
1092 if (rc < 0)
1093 return rc;
1094
1095 oldval = (unsigned char) rc;
1096 oldval &= (~mask);
1097 value &= mask;
1098 newval = oldval | value;
1099 }
1100
1101 if (ov->bclass == BCL_OV518)
1102 return (ov518_i2c_write_internal(ov, reg, newval));
1103 else
1104 return (ov511_i2c_write_internal(ov, reg, newval));
1105}
1106
1107
1108
1109
1110
1111
1112static int
1113i2c_w_mask(struct usb_ov511 *ov,
1114 unsigned char reg,
1115 unsigned char value,
1116 unsigned char mask)
1117{
1118 int rc;
1119
1120 down(&ov->i2c_lock);
1121 rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
1122 up(&ov->i2c_lock);
1123
1124 return rc;
1125}
1126
1127
1128
1129
1130
1131
1132static inline int
1133i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave)
1134{
1135 int rc;
1136
1137 rc = reg_w(ov, R51x_I2C_W_SID, slave);
1138 if (rc < 0) return rc;
1139
1140 rc = reg_w(ov, R51x_I2C_R_SID, slave + 1);
1141 if (rc < 0) return rc;
1142
1143 return 0;
1144}
1145
1146
1147static int
1148i2c_w_slave(struct usb_ov511 *ov,
1149 unsigned char slave,
1150 unsigned char reg,
1151 unsigned char value,
1152 unsigned char mask)
1153{
1154 int rc = 0;
1155
1156 down(&ov->i2c_lock);
1157
1158
1159 rc = i2c_set_slave_internal(ov, slave);
1160 if (rc < 0) goto out;
1161
1162 rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
1163
1164out:
1165
1166 if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
1167 err("Couldn't restore primary I2C slave");
1168
1169 up(&ov->i2c_lock);
1170 return rc;
1171}
1172
1173
1174static int
1175i2c_r_slave(struct usb_ov511 *ov,
1176 unsigned char slave,
1177 unsigned char reg)
1178{
1179 int rc;
1180
1181 down(&ov->i2c_lock);
1182
1183
1184 rc = i2c_set_slave_internal(ov, slave);
1185 if (rc < 0) goto out;
1186
1187 if (ov->bclass == BCL_OV518)
1188 rc = ov518_i2c_read_internal(ov, reg);
1189 else
1190 rc = ov511_i2c_read_internal(ov, reg);
1191
1192out:
1193
1194 if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
1195 err("Couldn't restore primary I2C slave");
1196
1197 up(&ov->i2c_lock);
1198 return rc;
1199}
1200
1201
1202static int
1203ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
1204{
1205 int rc;
1206
1207 down(&ov->i2c_lock);
1208
1209 rc = i2c_set_slave_internal(ov, sid);
1210 if (rc < 0) goto out;
1211
1212
1213 rc = ov51x_reset(ov, OV511_RESET_NOREGS);
1214 if (rc < 0) goto out;
1215
1216out:
1217 up(&ov->i2c_lock);
1218 return rc;
1219}
1220
1221static int
1222write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals)
1223{
1224 int rc;
1225
1226 while (pRegvals->bus != OV511_DONE_BUS) {
1227 if (pRegvals->bus == OV511_REG_BUS) {
1228 if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0)
1229 return rc;
1230 } else if (pRegvals->bus == OV511_I2C_BUS) {
1231 if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0)
1232 return rc;
1233 } else {
1234 err("Bad regval array");
1235 return -1;
1236 }
1237 pRegvals++;
1238 }
1239 return 0;
1240}
1241
1242#ifdef OV511_DEBUG
1243static void
1244dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn)
1245{
1246 int i, rc;
1247
1248 for (i = reg1; i <= regn; i++) {
1249 rc = i2c_r(ov, i);
1250 info("Sensor[0x%02X] = 0x%02X", i, rc);
1251 }
1252}
1253
1254static void
1255dump_i2c_regs(struct usb_ov511 *ov)
1256{
1257 info("I2C REGS");
1258 dump_i2c_range(ov, 0x00, 0x7C);
1259}
1260
1261static void
1262dump_reg_range(struct usb_ov511 *ov, int reg1, int regn)
1263{
1264 int i, rc;
1265
1266 for (i = reg1; i <= regn; i++) {
1267 rc = reg_r(ov, i);
1268 info("OV511[0x%02X] = 0x%02X", i, rc);
1269 }
1270}
1271
1272static void
1273ov511_dump_regs(struct usb_ov511 *ov)
1274{
1275 info("CAMERA INTERFACE REGS");
1276 dump_reg_range(ov, 0x10, 0x1f);
1277 info("DRAM INTERFACE REGS");
1278 dump_reg_range(ov, 0x20, 0x23);
1279 info("ISO FIFO REGS");
1280 dump_reg_range(ov, 0x30, 0x31);
1281 info("PIO REGS");
1282 dump_reg_range(ov, 0x38, 0x39);
1283 dump_reg_range(ov, 0x3e, 0x3e);
1284 info("I2C REGS");
1285 dump_reg_range(ov, 0x40, 0x49);
1286 info("SYSTEM CONTROL REGS");
1287 dump_reg_range(ov, 0x50, 0x55);
1288 dump_reg_range(ov, 0x5e, 0x5f);
1289 info("OmniCE REGS");
1290 dump_reg_range(ov, 0x70, 0x79);
1291
1292
1293 dump_reg_range(ov, 0x80, 0x9f);
1294 dump_reg_range(ov, 0xa0, 0xbf);
1295
1296}
1297
1298static void
1299ov518_dump_regs(struct usb_ov511 *ov)
1300{
1301 info("VIDEO MODE REGS");
1302 dump_reg_range(ov, 0x20, 0x2f);
1303 info("DATA PUMP AND SNAPSHOT REGS");
1304 dump_reg_range(ov, 0x30, 0x3f);
1305 info("I2C REGS");
1306 dump_reg_range(ov, 0x40, 0x4f);
1307 info("SYSTEM CONTROL AND VENDOR REGS");
1308 dump_reg_range(ov, 0x50, 0x5f);
1309 info("60 - 6F");
1310 dump_reg_range(ov, 0x60, 0x6f);
1311 info("70 - 7F");
1312 dump_reg_range(ov, 0x70, 0x7f);
1313 info("Y QUANTIZATION TABLE");
1314 dump_reg_range(ov, 0x80, 0x8f);
1315 info("UV QUANTIZATION TABLE");
1316 dump_reg_range(ov, 0x90, 0x9f);
1317 info("A0 - BF");
1318 dump_reg_range(ov, 0xa0, 0xbf);
1319 info("CBR");
1320 dump_reg_range(ov, 0xc0, 0xcf);
1321}
1322#endif
1323
1324
1325
1326
1327
1328static inline int
1329ov51x_stop(struct usb_ov511 *ov)
1330{
1331 PDEBUG(4, "stopping");
1332 ov->stopped = 1;
1333 if (ov->bclass == BCL_OV518)
1334 return (reg_w_mask(ov, R51x_SYS_RESET, 0x3a, 0x3a));
1335 else
1336 return (reg_w(ov, R51x_SYS_RESET, 0x3d));
1337}
1338
1339
1340
1341static inline int
1342ov51x_restart(struct usb_ov511 *ov)
1343{
1344 if (ov->stopped) {
1345 PDEBUG(4, "restarting");
1346 ov->stopped = 0;
1347
1348
1349 if (ov->bclass == BCL_OV518)
1350 reg_w(ov, 0x2f, 0x80);
1351
1352 return (reg_w(ov, R51x_SYS_RESET, 0x00));
1353 }
1354
1355 return 0;
1356}
1357
1358
1359static void
1360ov51x_clear_snapshot(struct usb_ov511 *ov)
1361{
1362 if (ov->bclass == BCL_OV511) {
1363 reg_w(ov, R51x_SYS_SNAP, 0x00);
1364 reg_w(ov, R51x_SYS_SNAP, 0x02);
1365 reg_w(ov, R51x_SYS_SNAP, 0x00);
1366 } else if (ov->bclass == BCL_OV518) {
1367 warn("snapshot reset not supported yet on OV518(+)");
1368 } else {
1369 err("clear snap: invalid bridge type");
1370 }
1371}
1372
1373#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1374
1375
1376static int
1377ov51x_check_snapshot(struct usb_ov511 *ov)
1378{
1379 int ret, status = 0;
1380
1381 if (ov->bclass == BCL_OV511) {
1382 ret = reg_r(ov, R51x_SYS_SNAP);
1383 if (ret < 0) {
1384 err("Error checking snspshot status (%d)", ret);
1385 } else if (ret & 0x08) {
1386 status = 1;
1387 }
1388 } else if (ov->bclass == BCL_OV518) {
1389 warn("snapshot check not supported yet on OV518(+)");
1390 } else {
1391 err("check snap: invalid bridge type");
1392 }
1393
1394 return status;
1395}
1396#endif
1397
1398
1399
1400
1401static int
1402init_ov_sensor(struct usb_ov511 *ov)
1403{
1404 int i, success;
1405
1406
1407 if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO;
1408
1409
1410 schedule_timeout(1 + 150 * HZ / 1000);
1411
1412 for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
1413 if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
1414 (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
1415 success = 1;
1416 continue;
1417 }
1418
1419
1420 if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO;
1421
1422 schedule_timeout(1 + 150 * HZ / 1000);
1423
1424 if (i2c_r(ov, 0x00) < 0) return -EIO;
1425 }
1426
1427 if (!success)
1428 return -EIO;
1429
1430 PDEBUG(1, "I2C synced in %d attempt(s)", i);
1431
1432 return 0;
1433}
1434
1435static int
1436ov511_set_packet_size(struct usb_ov511 *ov, int size)
1437{
1438 int alt, mult;
1439
1440 if (ov51x_stop(ov) < 0)
1441 return -EIO;
1442
1443 mult = size >> 5;
1444
1445 if (ov->bridge == BRG_OV511) {
1446 if (size == 0) alt = OV511_ALT_SIZE_0;
1447 else if (size == 257) alt = OV511_ALT_SIZE_257;
1448 else if (size == 513) alt = OV511_ALT_SIZE_513;
1449 else if (size == 769) alt = OV511_ALT_SIZE_769;
1450 else if (size == 993) alt = OV511_ALT_SIZE_993;
1451 else {
1452 err("Set packet size: invalid size (%d)", size);
1453 return -EINVAL;
1454 }
1455 } else if (ov->bridge == BRG_OV511PLUS) {
1456 if (size == 0) alt = OV511PLUS_ALT_SIZE_0;
1457 else if (size == 33) alt = OV511PLUS_ALT_SIZE_33;
1458 else if (size == 129) alt = OV511PLUS_ALT_SIZE_129;
1459 else if (size == 257) alt = OV511PLUS_ALT_SIZE_257;
1460 else if (size == 385) alt = OV511PLUS_ALT_SIZE_385;
1461 else if (size == 513) alt = OV511PLUS_ALT_SIZE_513;
1462 else if (size == 769) alt = OV511PLUS_ALT_SIZE_769;
1463 else if (size == 961) alt = OV511PLUS_ALT_SIZE_961;
1464 else {
1465 err("Set packet size: invalid size (%d)", size);
1466 return -EINVAL;
1467 }
1468 } else {
1469 err("Set packet size: Invalid bridge type");
1470 return -EINVAL;
1471 }
1472
1473 PDEBUG(3, "%d, mult=%d, alt=%d", size, mult, alt);
1474
1475 if (reg_w(ov, R51x_FIFO_PSIZE, mult) < 0)
1476 return -EIO;
1477
1478 if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
1479 err("Set packet size: set interface error");
1480 return -EBUSY;
1481 }
1482
1483 if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
1484 return -EIO;
1485
1486 ov->packet_size = size;
1487
1488 if (ov51x_restart(ov) < 0)
1489 return -EIO;
1490
1491 return 0;
1492}
1493
1494
1495
1496
1497static int
1498ov518_set_packet_size(struct usb_ov511 *ov, int size)
1499{
1500 int alt;
1501
1502 if (ov51x_stop(ov) < 0)
1503 return -EIO;
1504
1505 if (ov->bclass == BCL_OV518) {
1506 if (size == 0) alt = OV518_ALT_SIZE_0;
1507 else if (size == 128) alt = OV518_ALT_SIZE_128;
1508 else if (size == 256) alt = OV518_ALT_SIZE_256;
1509 else if (size == 384) alt = OV518_ALT_SIZE_384;
1510 else if (size == 512) alt = OV518_ALT_SIZE_512;
1511 else if (size == 640) alt = OV518_ALT_SIZE_640;
1512 else if (size == 768) alt = OV518_ALT_SIZE_768;
1513 else if (size == 896) alt = OV518_ALT_SIZE_896;
1514 else {
1515 err("Set packet size: invalid size (%d)", size);
1516 return -EINVAL;
1517 }
1518 } else {
1519 err("Set packet size: Invalid bridge type");
1520 return -EINVAL;
1521 }
1522
1523 PDEBUG(3, "%d, alt=%d", size, alt);
1524
1525 ov->packet_size = size;
1526 if (size > 0) {
1527
1528 ov518_reg_w32(ov, 0x30, size, 2);
1529
1530 if (ov->packet_numbering)
1531 ++ov->packet_size;
1532 }
1533
1534 if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
1535 err("Set packet size: set interface error");
1536 return -EBUSY;
1537 }
1538
1539
1540 if (reg_w(ov, 0x2f, 0x80) < 0)
1541 return -EIO;
1542
1543 if (ov51x_restart(ov) < 0)
1544 return -EIO;
1545
1546 if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
1547 return -EIO;
1548
1549 return 0;
1550}
1551
1552
1553static int
1554ov511_init_compression(struct usb_ov511 *ov)
1555{
1556 int rc = 0;
1557
1558 if (!ov->compress_inited) {
1559 reg_w(ov, 0x70, phy);
1560 reg_w(ov, 0x71, phuv);
1561 reg_w(ov, 0x72, pvy);
1562 reg_w(ov, 0x73, pvuv);
1563 reg_w(ov, 0x74, qhy);
1564 reg_w(ov, 0x75, qhuv);
1565 reg_w(ov, 0x76, qvy);
1566 reg_w(ov, 0x77, qvuv);
1567
1568 if (ov511_upload_quan_tables(ov) < 0) {
1569 err("Error uploading quantization tables");
1570 rc = -EIO;
1571 goto out;
1572 }
1573 }
1574
1575 ov->compress_inited = 1;
1576out:
1577 return rc;
1578}
1579
1580
1581static int
1582ov518_init_compression(struct usb_ov511 *ov)
1583{
1584 int rc = 0;
1585
1586 if (!ov->compress_inited) {
1587 if (ov518_upload_quan_tables(ov) < 0) {
1588 err("Error uploading quantization tables");
1589 rc = -EIO;
1590 goto out;
1591 }
1592 }
1593
1594 ov->compress_inited = 1;
1595out:
1596 return rc;
1597}
1598
1599
1600
1601
1602static int
1603sensor_set_contrast(struct usb_ov511 *ov, unsigned short val)
1604{
1605 int rc;
1606
1607 PDEBUG(3, "%d", val);
1608
1609 if (ov->stop_during_set)
1610 if (ov51x_stop(ov) < 0)
1611 return -EIO;
1612
1613 switch (ov->sensor) {
1614 case SEN_OV7610:
1615 case SEN_OV6620:
1616 {
1617 rc = i2c_w(ov, OV7610_REG_CNT, val >> 8);
1618 if (rc < 0)
1619 goto out;
1620 break;
1621 }
1622 case SEN_OV6630:
1623 {
1624 rc = i2c_w_mask(ov, OV7610_REG_CNT, val >> 12, 0x0f);
1625 if (rc < 0)
1626 goto out;
1627 break;
1628 }
1629 case SEN_OV7620:
1630 {
1631 unsigned char ctab[] = {
1632 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
1633 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
1634 };
1635
1636
1637 rc = i2c_w(ov, 0x64, ctab[val>>12]);
1638 if (rc < 0)
1639 goto out;
1640 break;
1641 }
1642 case SEN_SAA7111A:
1643 {
1644 rc = i2c_w(ov, 0x0b, val >> 9);
1645 if (rc < 0)
1646 goto out;
1647 break;
1648 }
1649 default:
1650 {
1651 PDEBUG(3, "Unsupported with this sensor");
1652 rc = -EPERM;
1653 goto out;
1654 }
1655 }
1656
1657 rc = 0;
1658 ov->contrast = val;
1659out:
1660 if (ov51x_restart(ov) < 0)
1661 return -EIO;
1662
1663 return rc;
1664}
1665
1666
1667static int
1668sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val)
1669{
1670 int rc;
1671
1672 switch (ov->sensor) {
1673 case SEN_OV7610:
1674 case SEN_OV6620:
1675 rc = i2c_r(ov, OV7610_REG_CNT);
1676 if (rc < 0)
1677 return rc;
1678 else
1679 *val = rc << 8;
1680 break;
1681 case SEN_OV6630:
1682 rc = i2c_r(ov, OV7610_REG_CNT);
1683 if (rc < 0)
1684 return rc;
1685 else
1686 *val = rc << 12;
1687 break;
1688 case SEN_OV7620:
1689
1690 rc = i2c_r(ov, 0x64);
1691 if (rc < 0)
1692 return rc;
1693 else
1694 *val = (rc & 0xfe) << 8;
1695 break;
1696 case SEN_SAA7111A:
1697 *val = ov->contrast;
1698 break;
1699 default:
1700 PDEBUG(3, "Unsupported with this sensor");
1701 return -EPERM;
1702 }
1703
1704 PDEBUG(3, "%d", *val);
1705 ov->contrast = *val;
1706
1707 return 0;
1708}
1709
1710
1711
1712
1713static int
1714sensor_set_brightness(struct usb_ov511 *ov, unsigned short val)
1715{
1716 int rc;
1717
1718 PDEBUG(4, "%d", val);
1719
1720 if (ov->stop_during_set)
1721 if (ov51x_stop(ov) < 0)
1722 return -EIO;
1723
1724 switch (ov->sensor) {
1725 case SEN_OV7610:
1726 case SEN_OV76BE:
1727 case SEN_OV6620:
1728 case SEN_OV6630:
1729 rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
1730 if (rc < 0)
1731 goto out;
1732 break;
1733 case SEN_OV7620:
1734
1735 if (!ov->auto_brt) {
1736 rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
1737 if (rc < 0)
1738 goto out;
1739 }
1740 break;
1741 case SEN_SAA7111A:
1742 rc = i2c_w(ov, 0x0a, val >> 8);
1743 if (rc < 0)
1744 goto out;
1745 break;
1746 default:
1747 PDEBUG(3, "Unsupported with this sensor");
1748 rc = -EPERM;
1749 goto out;
1750 }
1751
1752 rc = 0;
1753 ov->brightness = val;
1754out:
1755 if (ov51x_restart(ov) < 0)
1756 return -EIO;
1757
1758 return rc;
1759}
1760
1761
1762static int
1763sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val)
1764{
1765 int rc;
1766
1767 switch (ov->sensor) {
1768 case SEN_OV7610:
1769 case SEN_OV76BE:
1770 case SEN_OV7620:
1771 case SEN_OV6620:
1772 case SEN_OV6630:
1773 rc = i2c_r(ov, OV7610_REG_BRT);
1774 if (rc < 0)
1775 return rc;
1776 else
1777 *val = rc << 8;
1778 break;
1779 case SEN_SAA7111A:
1780 *val = ov->brightness;
1781 break;
1782 default:
1783 PDEBUG(3, "Unsupported with this sensor");
1784 return -EPERM;
1785 }
1786
1787 PDEBUG(3, "%d", *val);
1788 ov->brightness = *val;
1789
1790 return 0;
1791}
1792
1793
1794
1795
1796static int
1797sensor_set_saturation(struct usb_ov511 *ov, unsigned short val)
1798{
1799 int rc;
1800
1801 PDEBUG(3, "%d", val);
1802
1803 if (ov->stop_during_set)
1804 if (ov51x_stop(ov) < 0)
1805 return -EIO;
1806
1807 switch (ov->sensor) {
1808 case SEN_OV7610:
1809 case SEN_OV76BE:
1810 case SEN_OV6620:
1811 case SEN_OV6630:
1812 rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
1813 if (rc < 0)
1814 goto out;
1815 break;
1816 case SEN_OV7620:
1817
1818
1819
1820
1821 rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
1822 if (rc < 0)
1823 goto out;
1824 break;
1825 case SEN_SAA7111A:
1826 rc = i2c_w(ov, 0x0c, val >> 9);
1827 if (rc < 0)
1828 goto out;
1829 break;
1830 default:
1831 PDEBUG(3, "Unsupported with this sensor");
1832 rc = -EPERM;
1833 goto out;
1834 }
1835
1836 rc = 0;
1837 ov->colour = val;
1838out:
1839 if (ov51x_restart(ov) < 0)
1840 return -EIO;
1841
1842 return rc;
1843}
1844
1845
1846static int
1847sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val)
1848{
1849 int rc;
1850
1851 switch (ov->sensor) {
1852 case SEN_OV7610:
1853 case SEN_OV76BE:
1854 case SEN_OV6620:
1855 case SEN_OV6630:
1856 rc = i2c_r(ov, OV7610_REG_SAT);
1857 if (rc < 0)
1858 return rc;
1859 else
1860 *val = rc << 8;
1861 break;
1862 case SEN_OV7620:
1863
1864
1865
1866
1867
1868
1869 rc = i2c_r(ov, OV7610_REG_SAT);
1870 if (rc < 0)
1871 return rc;
1872 else
1873 *val = rc << 8;
1874 break;
1875 case SEN_SAA7111A:
1876 *val = ov->colour;
1877 break;
1878 default:
1879 PDEBUG(3, "Unsupported with this sensor");
1880 return -EPERM;
1881 }
1882
1883 PDEBUG(3, "%d", *val);
1884 ov->colour = *val;
1885
1886 return 0;
1887}
1888
1889
1890
1891
1892static int
1893sensor_set_hue(struct usb_ov511 *ov, unsigned short val)
1894{
1895 int rc;
1896
1897 PDEBUG(3, "%d", val);
1898
1899 if (ov->stop_during_set)
1900 if (ov51x_stop(ov) < 0)
1901 return -EIO;
1902
1903 switch (ov->sensor) {
1904 case SEN_OV7610:
1905 case SEN_OV6620:
1906 case SEN_OV6630:
1907 rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8));
1908 if (rc < 0)
1909 goto out;
1910
1911 rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8);
1912 if (rc < 0)
1913 goto out;
1914 break;
1915 case SEN_OV7620:
1916
1917#if 0
1918 rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb);
1919 if (rc < 0)
1920 goto out;
1921
1922 rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb);
1923 if (rc < 0)
1924 goto out;
1925#endif
1926 break;
1927 case SEN_SAA7111A:
1928 rc = i2c_w(ov, 0x0d, (val + 32768) >> 8);
1929 if (rc < 0)
1930 goto out;
1931 break;
1932 default:
1933 PDEBUG(3, "Unsupported with this sensor");
1934 rc = -EPERM;
1935 goto out;
1936 }
1937
1938 rc = 0;
1939 ov->hue = val;
1940out:
1941 if (ov51x_restart(ov) < 0)
1942 return -EIO;
1943
1944 return rc;
1945}
1946
1947
1948static int
1949sensor_get_hue(struct usb_ov511 *ov, unsigned short *val)
1950{
1951 int rc;
1952
1953 switch (ov->sensor) {
1954 case SEN_OV7610:
1955 case SEN_OV6620:
1956 case SEN_OV6630:
1957 rc = i2c_r(ov, OV7610_REG_BLUE);
1958 if (rc < 0)
1959 return rc;
1960 else
1961 *val = rc << 8;
1962 break;
1963 case SEN_OV7620:
1964 rc = i2c_r(ov, 0x7a);
1965 if (rc < 0)
1966 return rc;
1967 else
1968 *val = rc << 8;
1969 break;
1970 case SEN_SAA7111A:
1971 *val = ov->hue;
1972 break;
1973 default:
1974 PDEBUG(3, "Unsupported with this sensor");
1975 return -EPERM;
1976 }
1977
1978 PDEBUG(3, "%d", *val);
1979 ov->hue = *val;
1980
1981 return 0;
1982}
1983
1984
1985
1986static inline int
1987sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p)
1988{
1989 int rc;
1990
1991 PDEBUG(4, "sensor_set_picture");
1992
1993 ov->whiteness = p->whiteness;
1994
1995
1996
1997
1998 rc = sensor_set_contrast(ov, p->contrast);
1999 if (FATAL_ERROR(rc))
2000 return rc;
2001
2002 rc = sensor_set_brightness(ov, p->brightness);
2003 if (FATAL_ERROR(rc))
2004 return rc;
2005
2006 rc = sensor_set_saturation(ov, p->colour);
2007 if (FATAL_ERROR(rc))
2008 return rc;
2009
2010 rc = sensor_set_hue(ov, p->hue);
2011 if (FATAL_ERROR(rc))
2012 return rc;
2013
2014 return 0;
2015}
2016
2017static int
2018sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p)
2019{
2020 int rc;
2021
2022 PDEBUG(4, "sensor_get_picture");
2023
2024
2025
2026
2027 rc = sensor_get_contrast(ov, &(p->contrast));
2028 if (FATAL_ERROR(rc))
2029 return rc;
2030
2031 rc = sensor_get_brightness(ov, &(p->brightness));
2032 if (FATAL_ERROR(rc))
2033 return rc;
2034
2035 rc = sensor_get_saturation(ov, &(p->colour));
2036 if (FATAL_ERROR(rc))
2037 return rc;
2038
2039 rc = sensor_get_hue(ov, &(p->hue));
2040 if (FATAL_ERROR(rc))
2041 return rc;
2042
2043 p->whiteness = 105 << 8;
2044
2045 return 0;
2046}
2047
2048#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
2049
2050
2051
2052static inline int
2053sensor_set_exposure(struct usb_ov511 *ov, unsigned char val)
2054{
2055 int rc;
2056
2057 PDEBUG(3, "%d", val);
2058
2059 if (ov->stop_during_set)
2060 if (ov51x_stop(ov) < 0)
2061 return -EIO;
2062
2063 switch (ov->sensor) {
2064 case SEN_OV6620:
2065 case SEN_OV6630:
2066 case SEN_OV7610:
2067 case SEN_OV7620:
2068 case SEN_OV76BE:
2069 case SEN_OV8600:
2070 rc = i2c_w(ov, 0x10, val);
2071 if (rc < 0)
2072 goto out;
2073
2074 break;
2075 case SEN_KS0127:
2076 case SEN_KS0127B:
2077 case SEN_SAA7111A:
2078 PDEBUG(3, "Unsupported with this sensor");
2079 return -EPERM;
2080 default:
2081 err("Sensor not supported for set_exposure");
2082 return -EINVAL;
2083 }
2084
2085 rc = 0;
2086 ov->exposure = val;
2087out:
2088 if (ov51x_restart(ov) < 0)
2089 return -EIO;
2090
2091 return rc;
2092}
2093
2094
2095
2096static int
2097sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val)
2098{
2099 int rc;
2100
2101 switch (ov->sensor) {
2102 case SEN_OV7610:
2103 case SEN_OV6620:
2104 case SEN_OV6630:
2105 case SEN_OV7620:
2106 case SEN_OV76BE:
2107 case SEN_OV8600:
2108 rc = i2c_r(ov, 0x10);
2109 if (rc < 0)
2110 return rc;
2111 else
2112 *val = rc;
2113 break;
2114 case SEN_KS0127:
2115 case SEN_KS0127B:
2116 case SEN_SAA7111A:
2117 val = 0;
2118 PDEBUG(3, "Unsupported with this sensor");
2119 return -EPERM;
2120 default:
2121 err("Sensor not supported for get_exposure");
2122 return -EINVAL;
2123 }
2124
2125 PDEBUG(3, "%d", *val);
2126 ov->exposure = *val;
2127
2128 return 0;
2129}
2130#endif
2131
2132
2133static inline void
2134ov51x_led_control(struct usb_ov511 *ov, int enable)
2135{
2136 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2137
2138 if (ov->bridge == BRG_OV511PLUS)
2139 reg_w(ov, R511_SYS_LED_CTL, enable ? 1 : 0);
2140 else if (ov->bclass == BCL_OV518)
2141 reg_w_mask(ov, R518_GPIO_OUT, enable ? 0x02 : 0x00, 0x02);
2142
2143 return;
2144}
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155static int
2156sensor_set_light_freq(struct usb_ov511 *ov, int freq)
2157{
2158 int sixty;
2159
2160 PDEBUG(4, "%d Hz", freq);
2161
2162 if (freq == 60)
2163 sixty = 1;
2164 else if (freq == 50)
2165 sixty = 0;
2166 else {
2167 err("Invalid light freq (%d Hz)", freq);
2168 return -EINVAL;
2169 }
2170
2171 switch (ov->sensor) {
2172 case SEN_OV7610:
2173 i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
2174 i2c_w(ov, 0x2b, sixty?0x00:0xac);
2175 i2c_w_mask(ov, 0x13, 0x10, 0x10);
2176 i2c_w_mask(ov, 0x13, 0x00, 0x10);
2177 break;
2178 case SEN_OV7620:
2179 case SEN_OV76BE:
2180 case SEN_OV8600:
2181 i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
2182 i2c_w(ov, 0x2b, sixty?0x00:0xac);
2183 i2c_w_mask(ov, 0x76, 0x01, 0x01);
2184 break;
2185 case SEN_OV6620:
2186 case SEN_OV6630:
2187 i2c_w(ov, 0x2b, sixty?0xa8:0x28);
2188 i2c_w(ov, 0x2a, sixty?0x84:0xa4);
2189 break;
2190 case SEN_KS0127:
2191 case SEN_KS0127B:
2192 case SEN_SAA7111A:
2193 PDEBUG(5, "Unsupported with this sensor");
2194 return -EPERM;
2195 default:
2196 err("Sensor not supported for set_light_freq");
2197 return -EINVAL;
2198 }
2199
2200 ov->lightfreq = freq;
2201
2202 return 0;
2203}
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214static inline int
2215sensor_set_banding_filter(struct usb_ov511 *ov, int enable)
2216{
2217 int rc;
2218
2219 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2220
2221 if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
2222 || ov->sensor == SEN_SAA7111A) {
2223 PDEBUG(5, "Unsupported with this sensor");
2224 return -EPERM;
2225 }
2226
2227 rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04);
2228 if (rc < 0)
2229 return rc;
2230
2231 ov->bandfilt = enable;
2232
2233 return 0;
2234}
2235
2236
2237
2238
2239
2240
2241
2242static inline int
2243sensor_set_auto_brightness(struct usb_ov511 *ov, int enable)
2244{
2245 int rc;
2246
2247 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2248
2249 if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
2250 || ov->sensor == SEN_SAA7111A) {
2251 PDEBUG(5, "Unsupported with this sensor");
2252 return -EPERM;
2253 }
2254
2255 rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10);
2256 if (rc < 0)
2257 return rc;
2258
2259 ov->auto_brt = enable;
2260
2261 return 0;
2262}
2263
2264
2265
2266
2267
2268
2269
2270static inline int
2271sensor_set_auto_exposure(struct usb_ov511 *ov, int enable)
2272{
2273 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2274
2275 switch (ov->sensor) {
2276 case SEN_OV7610:
2277 i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80);
2278 break;
2279 case SEN_OV6620:
2280 case SEN_OV7620:
2281 case SEN_OV76BE:
2282 case SEN_OV8600:
2283 i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01);
2284 break;
2285 case SEN_OV6630:
2286 i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10);
2287 break;
2288 case SEN_KS0127:
2289 case SEN_KS0127B:
2290 case SEN_SAA7111A:
2291 PDEBUG(5, "Unsupported with this sensor");
2292 return -EPERM;
2293 default:
2294 err("Sensor not supported for set_auto_exposure");
2295 return -EINVAL;
2296 }
2297
2298 ov->auto_exp = enable;
2299
2300 return 0;
2301}
2302
2303
2304
2305
2306
2307
2308
2309
2310static int
2311sensor_set_backlight(struct usb_ov511 *ov, int enable)
2312{
2313 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2314
2315 switch (ov->sensor) {
2316 case SEN_OV7620:
2317 case SEN_OV8600:
2318 i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0);
2319 i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
2320 i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
2321 break;
2322 case SEN_OV6620:
2323 i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0);
2324 i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
2325 i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80);
2326 break;
2327 case SEN_OV6630:
2328 i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0);
2329 i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
2330 i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
2331 break;
2332 case SEN_OV7610:
2333 case SEN_OV76BE:
2334 case SEN_KS0127:
2335 case SEN_KS0127B:
2336 case SEN_SAA7111A:
2337 PDEBUG(5, "Unsupported with this sensor");
2338 return -EPERM;
2339 default:
2340 err("Sensor not supported for set_backlight");
2341 return -EINVAL;
2342 }
2343
2344 ov->backlight = enable;
2345
2346 return 0;
2347}
2348
2349static inline int
2350sensor_set_mirror(struct usb_ov511 *ov, int enable)
2351{
2352 PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
2353
2354 switch (ov->sensor) {
2355 case SEN_OV6620:
2356 case SEN_OV6630:
2357 case SEN_OV7610:
2358 case SEN_OV7620:
2359 case SEN_OV76BE:
2360 case SEN_OV8600:
2361 i2c_w_mask(ov, 0x12, enable?0x40:0x00, 0x40);
2362 break;
2363 case SEN_KS0127:
2364 case SEN_KS0127B:
2365 case SEN_SAA7111A:
2366 PDEBUG(5, "Unsupported with this sensor");
2367 return -EPERM;
2368 default:
2369 err("Sensor not supported for set_mirror");
2370 return -EINVAL;
2371 }
2372
2373 ov->mirror = enable;
2374
2375 return 0;
2376}
2377
2378
2379
2380
2381static inline int
2382get_depth(int palette)
2383{
2384 switch (palette) {
2385 case VIDEO_PALETTE_GREY: return 8;
2386 case VIDEO_PALETTE_YUV420: return 12;
2387 case VIDEO_PALETTE_YUV420P: return 12;
2388 case VIDEO_PALETTE_RGB565: return 16;
2389 case VIDEO_PALETTE_RGB24: return 24;
2390 case VIDEO_PALETTE_YUV422: return 16;
2391 case VIDEO_PALETTE_YUYV: return 16;
2392 case VIDEO_PALETTE_YUV422P: return 16;
2393 default: return 0;
2394 }
2395}
2396
2397
2398static inline long int
2399get_frame_length(struct ov511_frame *frame)
2400{
2401 if (!frame)
2402 return 0;
2403 else
2404 return ((frame->width * frame->height
2405 * get_depth(frame->format)) >> 3);
2406}
2407
2408static int
2409mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
2410 int mode, int sub_flag, int qvga)
2411{
2412 int clock;
2413
2414
2415
2416 switch (ov->sensor) {
2417 case SEN_OV7610:
2418 i2c_w(ov, 0x14, qvga?0x24:0x04);
2419
2420#if 0
2421 i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
2422 i2c_w(ov, 0x24, 0x10);
2423 i2c_w(ov, 0x25, qvga?0x40:0x8a);
2424 i2c_w(ov, 0x2f, qvga?0x30:0xb0);
2425 i2c_w(ov, 0x35, qvga?0x1c:0x9c);
2426#endif
2427 break;
2428 case SEN_OV7620:
2429
2430 i2c_w(ov, 0x14, qvga?0xa4:0x84);
2431 i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
2432 i2c_w(ov, 0x24, qvga?0x20:0x3a);
2433 i2c_w(ov, 0x25, qvga?0x30:0x60);
2434 i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
2435 i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0);
2436 i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
2437 break;
2438 case SEN_OV76BE:
2439
2440 i2c_w(ov, 0x14, qvga?0xa4:0x84);
2441
2442#if 0
2443 i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
2444 i2c_w(ov, 0x24, qvga?0x20:0x3a);
2445 i2c_w(ov, 0x25, qvga?0x30:0x60);
2446 i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
2447 i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0);
2448 i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
2449#endif
2450 break;
2451 case SEN_OV6620:
2452 i2c_w(ov, 0x14, qvga?0x24:0x04);
2453 break;
2454 case SEN_OV6630:
2455 i2c_w(ov, 0x14, qvga?0xa0:0x80);
2456 break;
2457 default:
2458 err("Invalid sensor");
2459 return -EINVAL;
2460 }
2461
2462
2463
2464 if (mode == VIDEO_PALETTE_GREY) {
2465 if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
2466
2467 i2c_w_mask(ov, 0x0e, 0x40, 0x40);
2468 }
2469
2470 if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
2471 && ov518_color) {
2472 i2c_w_mask(ov, 0x12, 0x00, 0x10);
2473 i2c_w_mask(ov, 0x13, 0x00, 0x20);
2474 } else {
2475 i2c_w_mask(ov, 0x13, 0x20, 0x20);
2476 }
2477 } else {
2478 if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
2479
2480 i2c_w_mask(ov, 0x0e, 0x00, 0x40);
2481 }
2482
2483
2484
2485
2486
2487
2488
2489 if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
2490 && ov518_color) {
2491 i2c_w_mask(ov, 0x12, 0x10, 0x10);
2492 i2c_w_mask(ov, 0x13, 0x20, 0x20);
2493 } else {
2494 i2c_w_mask(ov, 0x13, 0x00, 0x20);
2495 }
2496 }
2497
2498
2499
2500
2501
2502
2503
2504 if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
2505 {
2506
2507
2508 i2c_w(ov, 0x2a, 0x04);
2509
2510 if (ov->compress) {
2511
2512 clock = 3;
2513 } else if (clockdiv == -1) {
2514 clock = 3;
2515 } else {
2516 clock = clockdiv;
2517 }
2518
2519 PDEBUG(4, "Setting clock divisor to %d", clock);
2520
2521 i2c_w(ov, 0x11, clock);
2522
2523 i2c_w(ov, 0x2a, 0x84);
2524
2525
2526
2527 i2c_w(ov, 0x2d, 0x85);
2528 }
2529 else
2530 {
2531 if (ov->compress) {
2532 clock = 1;
2533 } else if (clockdiv == -1) {
2534
2535 clock = ((sub_flag ? ov->subw * ov->subh
2536 : width * height)
2537 * (mode == VIDEO_PALETTE_GREY ? 2 : 3) / 2)
2538 / 66000;
2539 } else {
2540 clock = clockdiv;
2541 }
2542
2543 PDEBUG(4, "Setting clock divisor to %d", clock);
2544
2545 i2c_w(ov, 0x11, clock);
2546 }
2547
2548
2549
2550 if (framedrop >= 0)
2551 i2c_w(ov, 0x16, framedrop);
2552
2553
2554 i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02);
2555
2556
2557 i2c_w_mask(ov, 0x12, 0x04, 0x04);
2558
2559
2560
2561
2562 if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
2563 if (width == 640 && height == 480)
2564 i2c_w(ov, 0x35, 0x9e);
2565 else
2566 i2c_w(ov, 0x35, 0x1e);
2567 }
2568
2569 return 0;
2570}
2571
2572static int
2573set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode,
2574 int sub_flag)
2575{
2576 int ret;
2577 int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize;
2578 int hoffset, voffset, hwscale = 0, vwscale = 0;
2579
2580
2581
2582 switch (ov->sensor) {
2583 case SEN_OV7610:
2584 case SEN_OV76BE:
2585 hwsbase = 0x38;
2586 hwebase = 0x3a;
2587 vwsbase = vwebase = 0x05;
2588 break;
2589 case SEN_OV6620:
2590 case SEN_OV6630:
2591 hwsbase = 0x38;
2592 hwebase = 0x3a;
2593 vwsbase = 0x05;
2594 vwebase = 0x06;
2595 break;
2596 case SEN_OV7620:
2597 hwsbase = 0x2f;
2598 hwebase = 0x2f;
2599 vwsbase = vwebase = 0x05;
2600 break;
2601 default:
2602 err("Invalid sensor");
2603 return -EINVAL;
2604 }
2605
2606 if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) {
2607
2608 if ((width > 176 && height > 144)
2609 || ov->bclass == BCL_OV518) {
2610 ret = mode_init_ov_sensor_regs(ov, width, height,
2611 mode, sub_flag, 0);
2612 if (ret < 0)
2613 return ret;
2614 hwscale = 1;
2615 vwscale = 1;
2616 hwsize = 352;
2617 vwsize = 288;
2618 } else if (width > 176 || height > 144) {
2619 err("Illegal dimensions");
2620 return -EINVAL;
2621 } else {
2622 ret = mode_init_ov_sensor_regs(ov, width, height,
2623 mode, sub_flag, 1);
2624 if (ret < 0)
2625 return ret;
2626 hwsize = 176;
2627 vwsize = 144;
2628 }
2629 } else {
2630 if (width > 320 && height > 240) {
2631 ret = mode_init_ov_sensor_regs(ov, width, height,
2632 mode, sub_flag, 0);
2633 if (ret < 0)
2634 return ret;
2635 hwscale = 2;
2636 vwscale = 1;
2637 hwsize = 640;
2638 vwsize = 480;
2639 } else if (width > 320 || height > 240) {
2640 err("Illegal dimensions");
2641 return -EINVAL;
2642 } else {
2643 ret = mode_init_ov_sensor_regs(ov, width, height,
2644 mode, sub_flag, 1);
2645 if (ret < 0)
2646 return ret;
2647 hwscale = 1;
2648 hwsize = 320;
2649 vwsize = 240;
2650 }
2651 }
2652
2653
2654 hoffset = ((hwsize - width) / 2) >> hwscale;
2655 voffset = ((vwsize - height) / 2) >> vwscale;
2656
2657
2658 if (sub_flag) {
2659 i2c_w(ov, 0x17, hwsbase+(ov->subx>>hwscale));
2660 i2c_w(ov, 0x18, hwebase+((ov->subx+ov->subw)>>hwscale));
2661 i2c_w(ov, 0x19, vwsbase+(ov->suby>>vwscale));
2662 i2c_w(ov, 0x1a, vwebase+((ov->suby+ov->subh)>>vwscale));
2663 } else {
2664 i2c_w(ov, 0x17, hwsbase + hoffset);
2665 i2c_w(ov, 0x18, hwebase + hoffset + (hwsize>>hwscale));
2666 i2c_w(ov, 0x19, vwsbase + voffset);
2667 i2c_w(ov, 0x1a, vwebase + voffset + (vwsize>>vwscale));
2668 }
2669
2670#ifdef OV511_DEBUG
2671 if (dump_sensor)
2672 dump_i2c_regs(ov);
2673#endif
2674
2675 return 0;
2676}
2677
2678
2679
2680
2681
2682static int
2683ov511_mode_init_regs(struct usb_ov511 *ov,
2684 int width, int height, int mode, int sub_flag)
2685{
2686 int hsegs, vsegs;
2687
2688 if (sub_flag) {
2689 width = ov->subw;
2690 height = ov->subh;
2691 }
2692
2693 PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
2694 width, height, mode, sub_flag);
2695
2696
2697
2698 if (ov->sensor == SEN_SAA7111A) {
2699 if (width == 320 && height == 240) {
2700
2701 } else if (width == 640 && height == 480) {
2702
2703
2704 width = 320;
2705 } else {
2706 err("SAA7111A only allows 320x240 or 640x480");
2707 return -EINVAL;
2708 }
2709 }
2710
2711
2712 if (width % 8 || height % 8) {
2713 err("Invalid size (%d, %d) (mode = %d)", width, height, mode);
2714 return -EINVAL;
2715 }
2716
2717 if (width < ov->minwidth || height < ov->minheight) {
2718 err("Requested dimensions are too small");
2719 return -EINVAL;
2720 }
2721
2722 if (ov51x_stop(ov) < 0)
2723 return -EIO;
2724
2725 if (mode == VIDEO_PALETTE_GREY) {
2726 reg_w(ov, R511_CAM_UV_EN, 0x00);
2727 reg_w(ov, R511_SNAP_UV_EN, 0x00);
2728 reg_w(ov, R511_SNAP_OPTS, 0x01);
2729 } else {
2730 reg_w(ov, R511_CAM_UV_EN, 0x01);
2731 reg_w(ov, R511_SNAP_UV_EN, 0x01);
2732 reg_w(ov, R511_SNAP_OPTS, 0x03);
2733 }
2734
2735
2736
2737
2738 hsegs = (width >> 3) - 1;
2739 vsegs = (height >> 3) - 1;
2740
2741 reg_w(ov, R511_CAM_PXCNT, hsegs);
2742 reg_w(ov, R511_CAM_LNCNT, vsegs);
2743 reg_w(ov, R511_CAM_PXDIV, 0x00);
2744 reg_w(ov, R511_CAM_LNDIV, 0x00);
2745
2746
2747 reg_w(ov, R511_CAM_OPTS, 0x03);
2748
2749
2750 reg_w(ov, R511_SNAP_PXCNT, hsegs);
2751 reg_w(ov, R511_SNAP_LNCNT, vsegs);
2752 reg_w(ov, R511_SNAP_PXDIV, 0x00);
2753 reg_w(ov, R511_SNAP_LNDIV, 0x00);
2754
2755 if (ov->compress) {
2756
2757 reg_w(ov, R511_COMP_EN, 0x07);
2758 reg_w(ov, R511_COMP_LUT_EN, 0x03);
2759 ov51x_reset(ov, OV511_RESET_OMNICE);
2760 }
2761
2762 if (ov51x_restart(ov) < 0)
2763 return -EIO;
2764
2765 return 0;
2766}
2767
2768
2769
2770
2771
2772
2773
2774
2775static int
2776ov518_mode_init_regs(struct usb_ov511 *ov,
2777 int width, int height, int mode, int sub_flag)
2778{
2779 int hsegs, vsegs, hi_res;
2780
2781 if (sub_flag) {
2782 width = ov->subw;
2783 height = ov->subh;
2784 }
2785
2786 PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
2787 width, height, mode, sub_flag);
2788
2789 if (width % 16 || height % 8) {
2790 err("Invalid size (%d, %d)", width, height);
2791 return -EINVAL;
2792 }
2793
2794 if (width < ov->minwidth || height < ov->minheight) {
2795 err("Requested dimensions are too small");
2796 return -EINVAL;
2797 }
2798
2799 if (width >= 320 && height >= 240) {
2800 hi_res = 1;
2801 } else if (width >= 320 || height >= 240) {
2802 err("Invalid width/height combination (%d, %d)", width, height);
2803 return -EINVAL;
2804 } else {
2805 hi_res = 0;
2806 }
2807
2808 if (ov51x_stop(ov) < 0)
2809 return -EIO;
2810
2811
2812
2813 reg_w(ov, 0x2b, 0);
2814 reg_w(ov, 0x2c, 0);
2815 reg_w(ov, 0x2d, 0);
2816 reg_w(ov, 0x2e, 0);
2817 reg_w(ov, 0x3b, 0);
2818 reg_w(ov, 0x3c, 0);
2819 reg_w(ov, 0x3d, 0);
2820 reg_w(ov, 0x3e, 0);
2821
2822 if (ov->bridge == BRG_OV518 && ov518_color) {
2823
2824 i2c_w_mask(ov, 0x15, 0x00, 0x01);
2825
2826 if (mode == VIDEO_PALETTE_GREY) {
2827
2828 reg_w_mask(ov, 0x20, 0x00, 0x08);
2829
2830
2831 reg_w_mask(ov, 0x28, 0x00, 0xf0);
2832 reg_w_mask(ov, 0x38, 0x00, 0xf0);
2833 } else {
2834
2835 reg_w_mask(ov, 0x20, 0x08, 0x08);
2836
2837
2838 reg_w_mask(ov, 0x28, 0x80, 0xf0);
2839 reg_w_mask(ov, 0x38, 0x80, 0xf0);
2840 }
2841 } else {
2842 reg_w(ov, 0x28, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
2843 reg_w(ov, 0x38, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
2844 }
2845
2846 hsegs = width / 16;
2847 vsegs = height / 4;
2848
2849 reg_w(ov, 0x29, hsegs);
2850 reg_w(ov, 0x2a, vsegs);
2851
2852 reg_w(ov, 0x39, hsegs);
2853 reg_w(ov, 0x3a, vsegs);
2854
2855
2856 reg_w(ov, 0x2f, 0x80);
2857
2858
2859
2860
2861 reg_w(ov, 0x51, 0x02);
2862 reg_w(ov, 0x22, 0x18);
2863 reg_w(ov, 0x23, 0xff);
2864
2865 if (ov->bridge == BRG_OV518PLUS)
2866 reg_w(ov, 0x21, 0x19);
2867 else
2868 reg_w(ov, 0x71, 0x19);
2869
2870
2871
2872 i2c_w(ov, 0x54, 0x23);
2873
2874 reg_w(ov, 0x2f, 0x80);
2875
2876 if (ov->bridge == BRG_OV518PLUS) {
2877 reg_w(ov, 0x24, 0x94);
2878 reg_w(ov, 0x25, 0x90);
2879 ov518_reg_w32(ov, 0xc4, 400, 2);
2880 ov518_reg_w32(ov, 0xc6, 540, 2);
2881 ov518_reg_w32(ov, 0xc7, 540, 2);
2882 ov518_reg_w32(ov, 0xc8, 108, 2);
2883 ov518_reg_w32(ov, 0xca, 131098, 3);
2884 ov518_reg_w32(ov, 0xcb, 532, 2);
2885 ov518_reg_w32(ov, 0xcc, 2400, 2);
2886 ov518_reg_w32(ov, 0xcd, 32, 2);
2887 ov518_reg_w32(ov, 0xce, 608, 2);
2888 } else {
2889 reg_w(ov, 0x24, 0x9f);
2890 reg_w(ov, 0x25, 0x90);
2891 ov518_reg_w32(ov, 0xc4, 400, 2);
2892 ov518_reg_w32(ov, 0xc6, 500, 2);
2893 ov518_reg_w32(ov, 0xc7, 500, 2);
2894 ov518_reg_w32(ov, 0xc8, 142, 2);
2895 ov518_reg_w32(ov, 0xca, 131098, 3);
2896 ov518_reg_w32(ov, 0xcb, 532, 2);
2897 ov518_reg_w32(ov, 0xcc, 2000, 2);
2898 ov518_reg_w32(ov, 0xcd, 32, 2);
2899 ov518_reg_w32(ov, 0xce, 608, 2);
2900 }
2901
2902 reg_w(ov, 0x2f, 0x80);
2903
2904 if (ov51x_restart(ov) < 0)
2905 return -EIO;
2906
2907
2908 if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
2909 return -EIO;
2910
2911 return 0;
2912}
2913
2914
2915static int
2916mode_init_regs(struct usb_ov511 *ov,
2917 int width, int height, int mode, int sub_flag)
2918{
2919 int rc = 0;
2920
2921 if (!ov || !ov->dev)
2922 return -EFAULT;
2923
2924 if (ov->bclass == BCL_OV518) {
2925 rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag);
2926 } else {
2927 rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag);
2928 }
2929
2930 if (FATAL_ERROR(rc))
2931 return rc;
2932
2933 switch (ov->sensor) {
2934 case SEN_OV7610:
2935 case SEN_OV7620:
2936 case SEN_OV76BE:
2937 case SEN_OV8600:
2938 case SEN_OV6620:
2939 case SEN_OV6630:
2940 rc = set_ov_sensor_window(ov, width, height, mode, sub_flag);
2941 break;
2942 case SEN_KS0127:
2943 case SEN_KS0127B:
2944 err("KS0127-series decoders not supported yet");
2945 rc = -EINVAL;
2946 break;
2947 case SEN_SAA7111A:
2948
2949
2950
2951 PDEBUG(1, "SAA status = 0x%02X", i2c_r(ov, 0x1f));
2952 break;
2953 default:
2954 err("Unknown sensor");
2955 rc = -EINVAL;
2956 }
2957
2958 if (FATAL_ERROR(rc))
2959 return rc;
2960
2961
2962 rc = sensor_set_auto_brightness(ov, ov->auto_brt);
2963 if (FATAL_ERROR(rc))
2964 return rc;
2965
2966 rc = sensor_set_auto_exposure(ov, ov->auto_exp);
2967 if (FATAL_ERROR(rc))
2968 return rc;
2969
2970 rc = sensor_set_banding_filter(ov, bandingfilter);
2971 if (FATAL_ERROR(rc))
2972 return rc;
2973
2974 if (ov->lightfreq) {
2975 rc = sensor_set_light_freq(ov, lightfreq);
2976 if (FATAL_ERROR(rc))
2977 return rc;
2978 }
2979
2980 rc = sensor_set_backlight(ov, ov->backlight);
2981 if (FATAL_ERROR(rc))
2982 return rc;
2983
2984 rc = sensor_set_mirror(ov, ov->mirror);
2985 if (FATAL_ERROR(rc))
2986 return rc;
2987
2988 return 0;
2989}
2990
2991
2992
2993
2994static int
2995ov51x_set_default_params(struct usb_ov511 *ov)
2996{
2997 int i;
2998
2999
3000
3001 for (i = 0; i < OV511_NUMFRAMES; i++) {
3002 ov->frame[i].width = ov->maxwidth;
3003 ov->frame[i].height = ov->maxheight;
3004 ov->frame[i].bytes_read = 0;
3005 if (force_palette)
3006 ov->frame[i].format = force_palette;
3007 else
3008 ov->frame[i].format = VIDEO_PALETTE_RGB24;
3009
3010 ov->frame[i].depth = get_depth(ov->frame[i].format);
3011 }
3012
3013 PDEBUG(3, "%dx%d, %s", ov->maxwidth, ov->maxheight,
3014 symbolic(v4l1_plist, ov->frame[0].format));
3015
3016
3017 if (mode_init_regs(ov, ov->maxwidth, ov->maxheight,
3018 ov->frame[0].format, 0) < 0)
3019 return -EINVAL;
3020
3021 return 0;
3022}
3023
3024
3025
3026
3027
3028
3029
3030
3031static int
3032decoder_set_input(struct usb_ov511 *ov, int input)
3033{
3034 PDEBUG(4, "port %d", input);
3035
3036 switch (ov->sensor) {
3037 case SEN_SAA7111A:
3038 {
3039
3040 i2c_w_mask(ov, 0x02, input, 0x07);
3041
3042 i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80);
3043 break;
3044 }
3045 default:
3046 return -EINVAL;
3047 }
3048
3049 return 0;
3050}
3051
3052
3053static int
3054decoder_get_input_name(struct usb_ov511 *ov, int input, char *name)
3055{
3056 switch (ov->sensor) {
3057 case SEN_SAA7111A:
3058 {
3059 if (input < 0 || input > 7)
3060 return -EINVAL;
3061 else if (input < 4)
3062 sprintf(name, "CVBS-%d", input);
3063 else
3064 sprintf(name, "S-Video-%d", input - 4);
3065 break;
3066 }
3067 default:
3068 sprintf(name, "%s", "Camera");
3069 }
3070
3071 return 0;
3072}
3073
3074
3075static int
3076decoder_set_norm(struct usb_ov511 *ov, int norm)
3077{
3078 PDEBUG(4, "%d", norm);
3079
3080 switch (ov->sensor) {
3081 case SEN_SAA7111A:
3082 {
3083 int reg_8, reg_e;
3084
3085 if (norm == VIDEO_MODE_NTSC) {
3086 reg_8 = 0x40;
3087 reg_e = 0x00;
3088 } else if (norm == VIDEO_MODE_PAL) {
3089 reg_8 = 0x00;
3090 reg_e = 0x00;
3091 } else if (norm == VIDEO_MODE_AUTO) {
3092 reg_8 = 0x80;
3093 reg_e = 0x00;
3094 } else if (norm == VIDEO_MODE_SECAM) {
3095 reg_8 = 0x00;
3096 reg_e = 0x50;
3097 } else {
3098 return -EINVAL;
3099 }
3100
3101 i2c_w_mask(ov, 0x08, reg_8, 0xc0);
3102 i2c_w_mask(ov, 0x0e, reg_e, 0x70);
3103 break;
3104 }
3105 default:
3106 return -EINVAL;
3107 }
3108
3109 return 0;
3110}
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145#define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))
3146
3147static inline void
3148move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v,
3149 int rowPixels, unsigned char * rgb, int bits)
3150{
3151 const int rvScale = 91881;
3152 const int guScale = -22553;
3153 const int gvScale = -46801;
3154 const int buScale = 116129;
3155 const int yScale = 65536;
3156 int r, g, b;
3157
3158 g = guScale * u + gvScale * v;
3159 if (force_rgb) {
3160 r = buScale * u;
3161 b = rvScale * v;
3162 } else {
3163 r = rvScale * v;
3164 b = buScale * u;
3165 }
3166
3167 yTL *= yScale; yTR *= yScale;
3168 yBL *= yScale; yBR *= yScale;
3169
3170 if (bits == 24) {
3171
3172 rgb[0] = LIMIT(b+yTL); rgb[1] = LIMIT(g+yTL);
3173 rgb[2] = LIMIT(r+yTL);
3174
3175 rgb[3] = LIMIT(b+yTR); rgb[4] = LIMIT(g+yTR);
3176 rgb[5] = LIMIT(r+yTR);
3177
3178
3179 rgb += 3 * rowPixels;
3180 rgb[0] = LIMIT(b+yBL); rgb[1] = LIMIT(g+yBL);
3181 rgb[2] = LIMIT(r+yBL);
3182
3183 rgb[3] = LIMIT(b+yBR); rgb[4] = LIMIT(g+yBR);
3184 rgb[5] = LIMIT(r+yBR);
3185 } else if (bits == 16) {
3186
3187 rgb[0] = ((LIMIT(b+yTL) >> 3) & 0x1F)
3188 | ((LIMIT(g+yTL) << 3) & 0xE0);
3189 rgb[1] = ((LIMIT(g+yTL) >> 5) & 0x07)
3190 | (LIMIT(r+yTL) & 0xF8);
3191
3192 rgb[2] = ((LIMIT(b+yTR) >> 3) & 0x1F)
3193 | ((LIMIT(g+yTR) << 3) & 0xE0);
3194 rgb[3] = ((LIMIT(g+yTR) >> 5) & 0x07)
3195 | (LIMIT(r+yTR) & 0xF8);
3196
3197
3198 rgb += 2 * rowPixels;
3199
3200 rgb[0] = ((LIMIT(b+yBL) >> 3) & 0x1F)
3201 | ((LIMIT(g+yBL) << 3) & 0xE0);
3202 rgb[1] = ((LIMIT(g+yBL) >> 5) & 0x07)
3203 | (LIMIT(r+yBL) & 0xF8);
3204
3205 rgb[2] = ((LIMIT(b+yBR) >> 3) & 0x1F)
3206 | ((LIMIT(g+yBR) << 3) & 0xE0);
3207 rgb[3] = ((LIMIT(g+yBR) >> 5) & 0x07)
3208 | (LIMIT(r+yBR) & 0xF8);
3209 }
3210}
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221static inline void
3222make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
3223{
3224 unsigned char *pOut1 = pOut;
3225 int x, y;
3226
3227 for (y = 0; y < 8; y++) {
3228 pOut1 = pOut;
3229 for (x = 0; x < 8; x++) {
3230 *pOut1++ = *pIn++;
3231 }
3232 pOut += w;
3233 }
3234}
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246static void
3247yuv400raw_to_yuv400p(struct ov511_frame *frame,
3248 unsigned char *pIn0, unsigned char *pOut0)
3249{
3250 int x, y;
3251 unsigned char *pIn, *pOut, *pOutLine;
3252
3253
3254 pIn = pIn0;
3255 pOutLine = pOut0;
3256 for (y = 0; y < frame->rawheight - 1; y += 8) {
3257 pOut = pOutLine;
3258 for (x = 0; x < frame->rawwidth - 1; x += 8) {
3259 make_8x8(pIn, pOut, frame->rawwidth);
3260 pIn += 64;
3261 pOut += 8;
3262 }
3263 pOutLine += 8 * frame->rawwidth;
3264 }
3265}
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303static void
3304yuv420raw_to_yuv420p(struct ov511_frame *frame,
3305 unsigned char *pIn0, unsigned char *pOut0)
3306{
3307 int k, x, y;
3308 unsigned char *pIn, *pOut, *pOutLine;
3309 const unsigned int a = frame->rawwidth * frame->rawheight;
3310 const unsigned int w = frame->rawwidth / 2;
3311
3312
3313 pIn = pIn0;
3314 pOutLine = pOut0 + a;
3315 for (y = 0; y < frame->rawheight - 1; y += 16) {
3316 pOut = pOutLine;
3317 for (x = 0; x < frame->rawwidth - 1; x += 16) {
3318 make_8x8(pIn, pOut, w);
3319 make_8x8(pIn + 64, pOut + a/4, w);
3320 pIn += 384;
3321 pOut += 8;
3322 }
3323 pOutLine += 8 * w;
3324 }
3325
3326
3327 pIn = pIn0 + 128;
3328 pOutLine = pOut0;
3329 k = 0;
3330 for (y = 0; y < frame->rawheight - 1; y += 8) {
3331 pOut = pOutLine;
3332 for (x = 0; x < frame->rawwidth - 1; x += 8) {
3333 make_8x8(pIn, pOut, frame->rawwidth);
3334 pIn += 64;
3335 pOut += 8;
3336 if ((++k) > 3) {
3337 k = 0;
3338 pIn += 128;
3339 }
3340 }
3341 pOutLine += 8 * frame->rawwidth;
3342 }
3343}
3344
3345
3346
3347
3348
3349
3350
3351static void
3352fixFrameRGBoffset(struct ov511_frame *frame)
3353{
3354 int x, y;
3355 int rowBytes = frame->width*3, w = frame->width;
3356 unsigned char *rgb = frame->data;
3357 const int shift = 1;
3358
3359
3360 if (frame->width < 400)
3361 return;
3362
3363
3364 if (frame->format != VIDEO_PALETTE_RGB24)
3365 return;
3366
3367
3368 for (y = shift; y < frame->height; y++) {
3369 int lp = (y-shift)*rowBytes;
3370 int lc = y*rowBytes;
3371 for (x = 0; x < w; x++)
3372 rgb[lp+x*3+2] = rgb[lc+x*3+2];
3373 }
3374
3375
3376 for (y = frame->height-shift-1; y >= 0; y--) {
3377 int ln = (y + shift) * rowBytes;
3378 int lc = y * rowBytes;
3379 for (x = 0; x < w; x++)
3380 rgb[ln+x*3+0] = rgb[lc+x*3+0];
3381 }
3382}
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394static int
3395request_decompressor(struct usb_ov511 *ov)
3396{
3397 if (!ov)
3398 return -ENODEV;
3399
3400 if (ov->decomp_ops) {
3401 err("ERROR: Decompressor already requested!");
3402 return -EINVAL;
3403 }
3404
3405 lock_kernel();
3406
3407
3408 if (ov->bclass == BCL_OV511) {
3409 if (ov511_mmx_decomp_ops) {
3410 PDEBUG(3, "Using OV511 MMX decompressor");
3411 ov->decomp_ops = ov511_mmx_decomp_ops;
3412 } else if (ov511_decomp_ops) {
3413 PDEBUG(3, "Using OV511 decompressor");
3414 ov->decomp_ops = ov511_decomp_ops;
3415 } else {
3416 err("No decompressor available");
3417 }
3418 } else if (ov->bclass == BCL_OV518) {
3419 if (ov518_mmx_decomp_ops) {
3420 PDEBUG(3, "Using OV518 MMX decompressor");
3421 ov->decomp_ops = ov518_mmx_decomp_ops;
3422 } else if (ov518_decomp_ops) {
3423 PDEBUG(3, "Using OV518 decompressor");
3424 ov->decomp_ops = ov518_decomp_ops;
3425 } else {
3426 err("No decompressor available");
3427 }
3428 } else {
3429 err("Unknown bridge");
3430 }
3431
3432 if (ov->decomp_ops) {
3433 if (!ov->decomp_ops->owner) {
3434 ov->decomp_ops = NULL;
3435 unlock_kernel();
3436 return -ENOSYS;
3437 }
3438 __MOD_INC_USE_COUNT(ov->decomp_ops->owner);
3439 unlock_kernel();
3440 return 0;
3441 } else {
3442 unlock_kernel();
3443 return -ENOSYS;
3444 }
3445}
3446
3447
3448
3449
3450static void
3451release_decompressor(struct usb_ov511 *ov)
3452{
3453 int released = 0;
3454
3455 if (!ov)
3456 return;
3457
3458 lock_kernel();
3459
3460 if (ov->decomp_ops && ov->decomp_ops->owner) {
3461 __MOD_DEC_USE_COUNT(ov->decomp_ops->owner);
3462 released = 1;
3463 }
3464
3465 ov->decomp_ops = NULL;
3466
3467 unlock_kernel();
3468
3469 if (released)
3470 PDEBUG(3, "Decompressor released");
3471}
3472
3473static void
3474decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
3475 unsigned char *pIn0, unsigned char *pOut0)
3476{
3477 if (!ov->decomp_ops)
3478 if (request_decompressor(ov))
3479 return;
3480
3481 PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd);
3482
3483 if (frame->format == VIDEO_PALETTE_GREY
3484 && ov->decomp_ops->decomp_400) {
3485 int ret = ov->decomp_ops->decomp_400(
3486 pIn0,
3487 pOut0,
3488 frame->compbuf,
3489 frame->rawwidth,
3490 frame->rawheight,
3491 frame->bytes_recvd);
3492 PDEBUG(4, "DEBUG: decomp_400 returned %d", ret);
3493 } else if (frame->format != VIDEO_PALETTE_GREY
3494 && ov->decomp_ops->decomp_420) {
3495 int ret = ov->decomp_ops->decomp_420(
3496 pIn0,
3497 pOut0,
3498 frame->compbuf,
3499 frame->rawwidth,
3500 frame->rawheight,
3501 frame->bytes_recvd);
3502 PDEBUG(4, "DEBUG: decomp_420 returned %d", ret);
3503 } else {
3504 err("Decompressor does not support this format");
3505 }
3506}
3507
3508
3509
3510
3511
3512
3513
3514
3515static void
3516yuv420p_to_rgb(struct ov511_frame *frame,
3517 unsigned char *pIn0, unsigned char *pOut0, int bits)
3518{
3519 const int numpix = frame->width * frame->height;
3520 const int bytes = bits >> 3;
3521 int i, j, y00, y01, y10, y11, u, v;
3522 unsigned char *pY = pIn0;
3523 unsigned char *pU = pY + numpix;
3524 unsigned char *pV = pU + numpix / 4;
3525 unsigned char *pOut = pOut0;
3526
3527 for (j = 0; j <= frame->height - 2; j += 2) {
3528 for (i = 0; i <= frame->width - 2; i += 2) {
3529 y00 = *pY;
3530 y01 = *(pY + 1);
3531 y10 = *(pY + frame->width);
3532 y11 = *(pY + frame->width + 1);
3533 u = (*pU++) - 128;
3534 v = (*pV++) - 128;
3535
3536 move_420_block(y00, y01, y10, y11, u, v,
3537 frame->width, pOut, bits);
3538
3539 pY += 2;
3540 pOut += 2 * bytes;
3541 }
3542 pY += frame->width;
3543 pOut += frame->width * bytes;
3544 }
3545}
3546
3547
3548static void
3549yuv420p_to_yuv422(struct ov511_frame *frame,
3550 unsigned char *pIn0, unsigned char *pOut0)
3551{
3552 const int numpix = frame->width * frame->height;
3553 int i, j;
3554 unsigned char *pY = pIn0;
3555 unsigned char *pU = pY + numpix;
3556 unsigned char *pV = pU + numpix / 4;
3557 unsigned char *pOut = pOut0;
3558
3559 for (i = 0; i < numpix; i++) {
3560 *pOut = *(pY + i);
3561 pOut += 2;
3562 }
3563
3564 pOut = pOut0 + 1;
3565 for (j = 0; j <= frame->height - 2 ; j += 2) {
3566 for (i = 0; i <= frame->width - 2; i += 2) {
3567 int u = *pU++;
3568 int v = *pV++;
3569
3570 *pOut = u;
3571 *(pOut+2) = v;
3572 *(pOut+frame->width*2) = u;
3573 *(pOut+frame->width*2+2) = v;
3574 pOut += 4;
3575 }
3576 pOut += (frame->width * 2);
3577 }
3578}
3579
3580
3581static void
3582yuv420p_to_yuv422p(struct ov511_frame *frame, unsigned char *pData)
3583{
3584 const int numpix = frame->width * frame->height;
3585 const int w = frame->width;
3586 int j;
3587 unsigned char *pIn, *pOut;
3588
3589
3590 memset(pData + numpix + numpix / 2, 127, numpix / 2);
3591
3592
3593 pIn = pData + numpix + numpix / 4;
3594 pOut = pData + numpix +numpix / 2;
3595 for (j = 0; j <= frame->height - 2; j += 2) {
3596 memmove(pOut, pIn, w/2);
3597 memmove(pOut + w/2, pIn, w/2);
3598 pIn += w/2;
3599 pOut += w;
3600 }
3601
3602
3603 pIn = pData + numpix + numpix / 4;
3604 pOut = pData + numpix + numpix / 2;
3605 for (j = 0; j <= frame->height - 2; j += 2) {
3606 pIn -= w/2;
3607 pOut -= w;
3608 memmove(pOut, pIn, w/2);
3609 memmove(pOut + w/2, pIn, w/2);
3610 }
3611}
3612
3613
3614
3615
3616
3617static void
3618deinterlace(struct ov511_frame *frame, int rawformat,
3619 unsigned char *pIn0, unsigned char *pOut0)
3620{
3621 const int fieldheight = frame->rawheight / 2;
3622 const int fieldpix = fieldheight * frame->rawwidth;
3623 const int w = frame->width;
3624 int x, y;
3625 unsigned char *pInEven, *pInOdd, *pOut;
3626
3627 PDEBUG(5, "fieldheight=%d", fieldheight);
3628
3629 if (frame->rawheight != frame->height) {
3630 err("invalid height");
3631 return;
3632 }
3633
3634 if ((frame->rawwidth * 2) != frame->width) {
3635 err("invalid width");
3636 return;
3637 }
3638
3639
3640 pInOdd = pIn0;
3641 pInEven = pInOdd + fieldpix;
3642 pOut = pOut0;
3643 for (y = 0; y < fieldheight; y++) {
3644 for (x = 0; x < frame->rawwidth; x++) {
3645 *pOut = *pInEven;
3646 *(pOut+1) = *pInEven++;
3647 *(pOut+w) = *pInOdd;
3648 *(pOut+w+1) = *pInOdd++;
3649 pOut += 2;
3650 }
3651 pOut += w;
3652 }
3653
3654 if (rawformat == RAWFMT_YUV420) {
3655
3656 pInOdd = pIn0 + fieldpix * 2;
3657 pInEven = pInOdd + fieldpix / 4;
3658 for (y = 0; y < fieldheight / 2; y++) {
3659 for (x = 0; x < frame->rawwidth / 2; x++) {
3660 *pOut = *pInEven;
3661 *(pOut+1) = *pInEven++;
3662 *(pOut+w/2) = *pInOdd;
3663 *(pOut+w/2+1) = *pInOdd++;
3664 pOut += 2;
3665 }
3666 pOut += w/2;
3667 }
3668
3669 pInOdd = pIn0 + fieldpix * 2 + fieldpix / 2;
3670 pInEven = pInOdd + fieldpix / 4;
3671 for (y = 0; y < fieldheight / 2; y++) {
3672 for (x = 0; x < frame->rawwidth / 2; x++) {
3673 *pOut = *pInEven;
3674 *(pOut+1) = *pInEven++;
3675 *(pOut+w/2) = *pInOdd;
3676 *(pOut+w/2+1) = *pInOdd++;
3677 pOut += 2;
3678 }
3679 pOut += w/2;
3680 }
3681 }
3682}
3683
3684static void
3685ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame)
3686{
3687
3688 if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) {
3689 if (frame->compressed)
3690 decompress(ov, frame, frame->rawdata,
3691 frame->tempdata);
3692 else
3693 yuv400raw_to_yuv400p(frame, frame->rawdata,
3694 frame->tempdata);
3695
3696 deinterlace(frame, RAWFMT_YUV400, frame->tempdata,
3697 frame->data);
3698 } else {
3699 if (frame->compressed)
3700 decompress(ov, frame, frame->rawdata,
3701 frame->data);
3702 else
3703 yuv400raw_to_yuv400p(frame, frame->rawdata,
3704 frame->data);
3705 }
3706}
3707
3708
3709
3710
3711static void
3712ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame)
3713{
3714
3715 if (frame->compressed)
3716 decompress(ov, frame, frame->rawdata, frame->tempdata);
3717 else
3718 yuv420raw_to_yuv420p(frame, frame->rawdata, frame->tempdata);
3719
3720
3721 if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) {
3722 memcpy(frame->rawdata, frame->tempdata,
3723 MAX_RAW_DATA_SIZE(frame->width, frame->height));
3724 deinterlace(frame, RAWFMT_YUV420, frame->rawdata,
3725 frame->tempdata);
3726 }
3727
3728
3729
3730
3731
3732 switch (frame->format) {
3733 case VIDEO_PALETTE_RGB565:
3734 yuv420p_to_rgb(frame, frame->tempdata, frame->data, 16);
3735 break;
3736 case VIDEO_PALETTE_RGB24:
3737 yuv420p_to_rgb(frame, frame->tempdata, frame->data, 24);
3738 break;
3739 case VIDEO_PALETTE_YUV422:
3740 case VIDEO_PALETTE_YUYV:
3741 yuv420p_to_yuv422(frame, frame->tempdata, frame->data);
3742 break;
3743 case VIDEO_PALETTE_YUV420:
3744 case VIDEO_PALETTE_YUV420P:
3745 memcpy(frame->data, frame->tempdata,
3746 MAX_RAW_DATA_SIZE(frame->width, frame->height));
3747 break;
3748 case VIDEO_PALETTE_YUV422P:
3749
3750 memcpy(frame->data, frame->tempdata,
3751 MAX_RAW_DATA_SIZE(frame->width, frame->height));
3752
3753 yuv420p_to_yuv422p(frame, frame->data);
3754 break;
3755 default:
3756 err("Cannot convert YUV420 to %s",
3757 symbolic(v4l1_plist, frame->format));
3758 }
3759
3760 if (fix_rgb_offset)
3761 fixFrameRGBoffset(frame);
3762}
3763
3764
3765
3766
3767
3768
3769
3770static void
3771ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
3772{
3773 if (dumppix) {
3774 memset(frame->data, 0,
3775 MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
3776 PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd);
3777 memcpy(frame->data, frame->rawdata, frame->bytes_recvd);
3778 } else {
3779 switch (frame->format) {
3780 case VIDEO_PALETTE_GREY:
3781 ov51x_postprocess_grey(ov, frame);
3782 break;
3783 case VIDEO_PALETTE_YUV420:
3784 case VIDEO_PALETTE_YUV420P:
3785 case VIDEO_PALETTE_RGB565:
3786 case VIDEO_PALETTE_RGB24:
3787 case VIDEO_PALETTE_YUV422:
3788 case VIDEO_PALETTE_YUYV:
3789 case VIDEO_PALETTE_YUV422P:
3790 ov51x_postprocess_yuv420(ov, frame);
3791 break;
3792 default:
3793 err("Cannot convert data to %s",
3794 symbolic(v4l1_plist, frame->format));
3795 }
3796 }
3797}
3798
3799
3800
3801
3802
3803
3804
3805static inline void
3806ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
3807{
3808 int num, offset;
3809 int pnum = in[ov->packet_size - 1];
3810 int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight);
3811 struct ov511_frame *frame = &ov->frame[ov->curframe];
3812 struct timeval *ts;
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828 if (printph) {
3829 info("ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x",
3830 pnum, in[0], in[1], in[2], in[3], in[4], in[5], in[6],
3831 in[7], in[8], in[9], in[10], in[11]);
3832 }
3833
3834
3835 if ((in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) ||
3836 (~in[8] & 0x08))
3837 goto check_middle;
3838
3839
3840 if (in[8] & 0x80) {
3841 ts = (struct timeval *)(frame->data
3842 + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
3843 do_gettimeofday(ts);
3844
3845
3846 frame->rawwidth = ((int)(in[9]) + 1) * 8;
3847 frame->rawheight = ((int)(in[10]) + 1) * 8;
3848
3849 PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d",
3850 ov->curframe, pnum, frame->rawwidth, frame->rawheight,
3851 frame->bytes_recvd);
3852
3853
3854 RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
3855 RESTRICT_TO_RANGE(frame->rawheight, ov->minheight,
3856 ov->maxheight);
3857
3858
3859 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
3860
3861 if (frame->scanstate == STATE_LINES) {
3862 int nextf;
3863
3864 frame->grabstate = FRAME_DONE;
3865
3866 if (waitqueue_active(&frame->wq)) {
3867 frame->grabstate = FRAME_DONE;
3868 wake_up_interruptible(&frame->wq);
3869 }
3870
3871
3872
3873 nextf = (ov->curframe + 1) % OV511_NUMFRAMES;
3874 if (ov->frame[nextf].grabstate == FRAME_READY
3875 || ov->frame[nextf].grabstate == FRAME_GRABBING) {
3876 ov->curframe = nextf;
3877 ov->frame[nextf].scanstate = STATE_SCANNING;
3878 } else {
3879 if (frame->grabstate == FRAME_DONE) {
3880 PDEBUG(4, "** Frame done **");
3881 } else {
3882 PDEBUG(4, "Frame not ready? state = %d",
3883 ov->frame[nextf].grabstate);
3884 }
3885
3886 ov->curframe = -1;
3887 }
3888 } else {
3889 PDEBUG(5, "Frame done, but not scanning");
3890 }
3891
3892
3893
3894 } else {
3895
3896 PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
3897
3898
3899
3900 if (in[8] & 0x02) {
3901 frame->snapshot = 1;
3902 PDEBUG(3, "snapshot detected");
3903 }
3904
3905 frame->scanstate = STATE_LINES;
3906 frame->bytes_recvd = 0;
3907 frame->compressed = in[8] & 0x40;
3908 }
3909
3910check_middle:
3911
3912 if (frame->scanstate != STATE_LINES) {
3913 PDEBUG(5, "Not in a frame; packet skipped");
3914 return;
3915 }
3916
3917
3918 if (frame->bytes_recvd == 0)
3919 offset = 9;
3920 else
3921 offset = 0;
3922
3923 num = n - offset - 1;
3924
3925
3926 if (dumppix == 2) {
3927 frame->bytes_recvd += n - 1;
3928 if (frame->bytes_recvd <= max_raw)
3929 memcpy(frame->rawdata + frame->bytes_recvd - (n - 1),
3930 in, n - 1);
3931 else
3932 PDEBUG(3, "Raw data buffer overrun!! (%d)",
3933 frame->bytes_recvd - max_raw);
3934 } else if (!frame->compressed && !remove_zeros) {
3935 frame->bytes_recvd += num;
3936 if (frame->bytes_recvd <= max_raw)
3937 memcpy(frame->rawdata + frame->bytes_recvd - num,
3938 in + offset, num);
3939 else
3940 PDEBUG(3, "Raw data buffer overrun!! (%d)",
3941 frame->bytes_recvd - max_raw);
3942 } else {
3943 int b, read = 0, allzero, copied = 0;
3944 if (offset) {
3945 frame->bytes_recvd += 32 - offset;
3946 memcpy(frame->rawdata, in + offset, 32 - offset);
3947 read += 32;
3948 }
3949
3950 while (read < n - 1) {
3951 allzero = 1;
3952 for (b = 0; b < 32; b++) {
3953 if (in[read + b]) {
3954 allzero = 0;
3955 break;
3956 }
3957 }
3958
3959 if (allzero) {
3960
3961 } else {
3962 if (frame->bytes_recvd + copied + 32 <= max_raw)
3963 {
3964 memcpy(frame->rawdata
3965 + frame->bytes_recvd + copied,
3966 in + read, 32);
3967 copied += 32;
3968 } else {
3969 PDEBUG(3, "Raw data buffer overrun!!");
3970 }
3971 }
3972 read += 32;
3973 }
3974
3975 frame->bytes_recvd += copied;
3976 }
3977}
3978
3979static inline void
3980ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
3981{
3982 int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight);
3983 struct ov511_frame *frame = &ov->frame[ov->curframe];
3984 struct timeval *ts;
3985
3986
3987 if (ov->packet_numbering)
3988 --n;
3989
3990
3991
3992 if ((!(in[0] | in[1] | in[2] | in[3] | in[5])) && in[6]) {
3993 if (printph) {
3994 info("ph: %2x %2x %2x %2x %2x %2x %2x %2x", in[0],
3995 in[1], in[2], in[3], in[4], in[5], in[6], in[7]);
3996 }
3997
3998 if (frame->scanstate == STATE_LINES) {
3999 PDEBUG(4, "Detected frame end/start");
4000 goto eof;
4001 } else {
4002
4003 PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
4004 goto sof;
4005 }
4006 } else {
4007 goto check_middle;
4008 }
4009
4010eof:
4011 ts = (struct timeval *)(frame->data
4012 + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
4013 do_gettimeofday(ts);
4014
4015 PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d",
4016 ov->curframe,
4017 (int)(in[9]), (int)(in[10]), frame->bytes_recvd);
4018
4019
4020
4021 frame->rawwidth = frame->width;
4022 frame->rawheight = frame->height;
4023
4024
4025 RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
4026 RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
4027
4028
4029 RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
4030
4031 if (frame->scanstate == STATE_LINES) {
4032 int nextf;
4033
4034 frame->grabstate = FRAME_DONE;
4035
4036 if (waitqueue_active(&frame->wq)) {
4037 frame->grabstate = FRAME_DONE;
4038 wake_up_interruptible(&frame->wq);
4039 }
4040
4041
4042
4043 nextf = (ov->curframe + 1) % OV511_NUMFRAMES;
4044 if (ov->frame[nextf].grabstate == FRAME_READY
4045 || ov->frame[nextf].grabstate == FRAME_GRABBING) {
4046 ov->curframe = nextf;
4047 ov->frame[nextf].scanstate = STATE_SCANNING;
4048 frame = &ov->frame[nextf];
4049 } else {
4050 if (frame->grabstate == FRAME_DONE) {
4051 PDEBUG(4, "** Frame done **");
4052 } else {
4053 PDEBUG(4, "Frame not ready? state = %d",
4054 ov->frame[nextf].grabstate);
4055 }
4056
4057 ov->curframe = -1;
4058 PDEBUG(4, "SOF dropped (no active frame)");
4059 return;
4060 }
4061 }
4062sof:
4063 PDEBUG(4, "Starting capture on frame %d", frame->framenum);
4064
4065
4066#if 0
4067
4068
4069 if (in[8] & 0x02) {
4070 frame->snapshot = 1;
4071 PDEBUG(3, "snapshot detected");
4072 }
4073#endif
4074 frame->scanstate = STATE_LINES;
4075 frame->bytes_recvd = 0;
4076 frame->compressed = 1;
4077
4078check_middle:
4079
4080 if (frame->scanstate != STATE_LINES) {
4081 PDEBUG(4, "scanstate: no SOF yet");
4082 return;
4083 }
4084
4085
4086 if (dumppix == 2) {
4087 frame->bytes_recvd += n;
4088 if (frame->bytes_recvd <= max_raw)
4089 memcpy(frame->rawdata + frame->bytes_recvd - n, in, n);
4090 else
4091 PDEBUG(3, "Raw data buffer overrun!! (%d)",
4092 frame->bytes_recvd - max_raw);
4093 } else {
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103 int b, read = 0, allzero, copied = 0;
4104
4105 while (read < n) {
4106 allzero = 1;
4107 for (b = 0; b < 8; b++) {
4108 if (in[read + b]) {
4109 allzero = 0;
4110 break;
4111 }
4112 }
4113
4114 if (allzero) {
4115
4116 } else {
4117 if (frame->bytes_recvd + copied + 8 <= max_raw)
4118 {
4119 memcpy(frame->rawdata
4120 + frame->bytes_recvd + copied,
4121 in + read, 8);
4122 copied += 8;
4123 } else {
4124 PDEBUG(3, "Raw data buffer overrun!!");
4125 }
4126 }
4127 read += 8;
4128 }
4129 frame->bytes_recvd += copied;
4130 }
4131}
4132
4133static void
4134ov51x_isoc_irq(struct urb *urb)
4135{
4136 int i;
4137 struct usb_ov511 *ov;
4138 struct ov511_sbuf *sbuf;
4139
4140 if (!urb->context) {
4141 PDEBUG(4, "no context");
4142 return;
4143 }
4144
4145 sbuf = urb->context;
4146 ov = sbuf->ov;
4147
4148 if (!ov || !ov->dev || !ov->user) {
4149 PDEBUG(4, "no device, or not open");
4150 return;
4151 }
4152
4153 if (!ov->streaming) {
4154 PDEBUG(4, "hmmm... not streaming, but got interrupt");
4155 return;
4156 }
4157
4158 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
4159 PDEBUG(4, "URB unlinked");
4160 return;
4161 }
4162
4163 if (urb->status != -EINPROGRESS && urb->status != 0) {
4164 err("ERROR: urb->status=%d: %s", urb->status,
4165 symbolic(urb_errlist, urb->status));
4166 }
4167
4168
4169 PDEBUG(5, "sbuf[%d]: Moving %d packets", sbuf->n,
4170 urb->number_of_packets);
4171 for (i = 0; i < urb->number_of_packets; i++) {
4172
4173 if (ov->curframe >= 0) {
4174 int n = urb->iso_frame_desc[i].actual_length;
4175 int st = urb->iso_frame_desc[i].status;
4176 unsigned char *cdata;
4177
4178 urb->iso_frame_desc[i].actual_length = 0;
4179 urb->iso_frame_desc[i].status = 0;
4180
4181 cdata = urb->transfer_buffer
4182 + urb->iso_frame_desc[i].offset;
4183
4184 if (!n) {
4185 PDEBUG(4, "Zero-length packet");
4186 continue;
4187 }
4188
4189 if (st)
4190 PDEBUG(2, "data error: [%d] len=%d, status=%d",
4191 i, n, st);
4192
4193 if (ov->bclass == BCL_OV511)
4194 ov511_move_data(ov, cdata, n);
4195 else if (ov->bclass == BCL_OV518)
4196 ov518_move_data(ov, cdata, n);
4197 else
4198 err("Unknown bridge device (%d)", ov->bridge);
4199
4200 } else if (waitqueue_active(&ov->wq)) {
4201 wake_up_interruptible(&ov->wq);
4202 }
4203 }
4204
4205
4206 urb->dev = ov->dev;
4207 if ((i = usb_submit_urb(urb)) != 0)
4208 err("usb_submit_urb() ret %d", i);
4209
4210 return;
4211}
4212
4213
4214
4215
4216
4217
4218
4219static int
4220ov51x_init_isoc(struct usb_ov511 *ov)
4221{
4222 struct urb *urb;
4223 int fx, err, n, size;
4224
4225 PDEBUG(3, "*** Initializing capture ***");
4226
4227 ov->curframe = -1;
4228
4229 if (ov->bridge == BRG_OV511) {
4230 if (cams == 1) size = 993;
4231 else if (cams == 2) size = 513;
4232 else if (cams == 3 || cams == 4) size = 257;
4233 else {
4234 err("\"cams\" parameter too high!");
4235 return -1;
4236 }
4237 } else if (ov->bridge == BRG_OV511PLUS) {
4238 if (cams == 1) size = 961;
4239 else if (cams == 2) size = 513;
4240 else if (cams == 3 || cams == 4) size = 257;
4241 else if (cams >= 5 && cams <= 8) size = 129;
4242 else if (cams >= 9 && cams <= 31) size = 33;
4243 else {
4244 err("\"cams\" parameter too high!");
4245 return -1;
4246 }
4247 } else if (ov->bclass == BCL_OV518) {
4248 if (cams == 1) size = 896;
4249 else if (cams == 2) size = 512;
4250 else if (cams == 3 || cams == 4) size = 256;
4251 else if (cams >= 5 && cams <= 8) size = 128;
4252 else {
4253 err("\"cams\" parameter too high!");
4254 return -1;
4255 }
4256 } else {
4257 err("invalid bridge type");
4258 return -1;
4259 }
4260
4261
4262 if (ov->bclass == BCL_OV518) {
4263 if (packetsize == -1) {
4264 ov518_set_packet_size(ov, 640);
4265 } else {
4266 info("Forcing packet size to %d", packetsize);
4267 ov518_set_packet_size(ov, packetsize);
4268 }
4269 } else {
4270 if (packetsize == -1) {
4271 ov511_set_packet_size(ov, size);
4272 } else {
4273 info("Forcing packet size to %d", packetsize);
4274 ov511_set_packet_size(ov, packetsize);
4275 }
4276 }
4277
4278 for (n = 0; n < OV511_NUMSBUF; n++) {
4279 urb = usb_alloc_urb(FRAMES_PER_DESC);
4280
4281 if (!urb) {
4282 err("init isoc: usb_alloc_urb ret. NULL");
4283 return -ENOMEM;
4284 }
4285 ov->sbuf[n].urb = urb;
4286 urb->dev = ov->dev;
4287 urb->context = &ov->sbuf[n];
4288 urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS);
4289 urb->transfer_flags = USB_ISO_ASAP;
4290 urb->transfer_buffer = ov->sbuf[n].data;
4291 urb->complete = ov51x_isoc_irq;
4292 urb->number_of_packets = FRAMES_PER_DESC;
4293 urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC;
4294 urb->interval = 1;
4295 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
4296 urb->iso_frame_desc[fx].offset = ov->packet_size * fx;
4297 urb->iso_frame_desc[fx].length = ov->packet_size;
4298 }
4299 }
4300
4301 ov->streaming = 1;
4302
4303 for (n = 0; n < OV511_NUMSBUF; n++) {
4304 ov->sbuf[n].urb->dev = ov->dev;
4305 err = usb_submit_urb(ov->sbuf[n].urb);
4306 if (err) {
4307 err("init isoc: usb_submit_urb(%d) ret %d", n, err);
4308 return err;
4309 }
4310 }
4311
4312 return 0;
4313}
4314
4315static void
4316ov51x_unlink_isoc(struct usb_ov511 *ov)
4317{
4318 int n;
4319
4320
4321 for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
4322 if (ov->sbuf[n].urb) {
4323 usb_unlink_urb(ov->sbuf[n].urb);
4324 usb_free_urb(ov->sbuf[n].urb);
4325 ov->sbuf[n].urb = NULL;
4326 }
4327 }
4328}
4329
4330static void
4331ov51x_stop_isoc(struct usb_ov511 *ov)
4332{
4333 if (!ov->streaming || !ov->dev)
4334 return;
4335
4336 PDEBUG(3, "*** Stopping capture ***");
4337
4338 if (ov->bclass == BCL_OV518)
4339 ov518_set_packet_size(ov, 0);
4340 else
4341 ov511_set_packet_size(ov, 0);
4342
4343 ov->streaming = 0;
4344
4345 ov51x_unlink_isoc(ov);
4346}
4347
4348static int
4349ov51x_new_frame(struct usb_ov511 *ov, int framenum)
4350{
4351 struct ov511_frame *frame;
4352 int newnum;
4353
4354 PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum);
4355
4356 if (!ov->dev)
4357 return -1;
4358
4359
4360
4361 if (ov->curframe == -1) {
4362 newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES;
4363 if (ov->frame[newnum].grabstate == FRAME_READY)
4364 framenum = newnum;
4365 } else
4366 return 0;
4367
4368 frame = &ov->frame[framenum];
4369
4370 PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum,
4371 frame->width, frame->height);
4372
4373 frame->grabstate = FRAME_GRABBING;
4374 frame->scanstate = STATE_SCANNING;
4375 frame->snapshot = 0;
4376
4377 ov->curframe = framenum;
4378
4379
4380 if (frame->width > ov->maxwidth)
4381 frame->width = ov->maxwidth;
4382
4383 frame->width &= ~7L;
4384
4385 if (frame->height > ov->maxheight)
4386 frame->height = ov->maxheight;
4387
4388 frame->height &= ~3L;
4389
4390 return 0;
4391}
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404static void
4405ov51x_do_dealloc(struct usb_ov511 *ov)
4406{
4407 int i;
4408 PDEBUG(4, "entered");
4409
4410 if (ov->fbuf) {
4411 rvfree(ov->fbuf, OV511_NUMFRAMES
4412 * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
4413 ov->fbuf = NULL;
4414 }
4415
4416 if (ov->rawfbuf) {
4417 vfree(ov->rawfbuf);
4418 ov->rawfbuf = NULL;
4419 }
4420
4421 if (ov->tempfbuf) {
4422 vfree(ov->tempfbuf);
4423 ov->tempfbuf = NULL;
4424 }
4425
4426 for (i = 0; i < OV511_NUMSBUF; i++) {
4427 if (ov->sbuf[i].data) {
4428 kfree(ov->sbuf[i].data);
4429 ov->sbuf[i].data = NULL;
4430 }
4431 }
4432
4433 for (i = 0; i < OV511_NUMFRAMES; i++) {
4434 ov->frame[i].data = NULL;
4435 ov->frame[i].rawdata = NULL;
4436 ov->frame[i].tempdata = NULL;
4437 if (ov->frame[i].compbuf) {
4438 free_page((unsigned long) ov->frame[i].compbuf);
4439 ov->frame[i].compbuf = NULL;
4440 }
4441 }
4442
4443 PDEBUG(4, "buffer memory deallocated");
4444 ov->buf_state = BUF_NOT_ALLOCATED;
4445 PDEBUG(4, "leaving");
4446}
4447
4448static int
4449ov51x_alloc(struct usb_ov511 *ov)
4450{
4451 int i;
4452 const int w = ov->maxwidth;
4453 const int h = ov->maxheight;
4454 const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h);
4455 const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h);
4456
4457 PDEBUG(4, "entered");
4458 down(&ov->buf_lock);
4459
4460 if (ov->buf_state == BUF_ALLOCATED)
4461 goto out;
4462
4463 ov->fbuf = rvmalloc(data_bufsize);
4464 if (!ov->fbuf)
4465 goto error;
4466
4467 ov->rawfbuf = vmalloc(raw_bufsize);
4468 if (!ov->rawfbuf)
4469 goto error;
4470
4471 memset(ov->rawfbuf, 0, raw_bufsize);
4472
4473 ov->tempfbuf = vmalloc(raw_bufsize);
4474 if (!ov->tempfbuf)
4475 goto error;
4476
4477 memset(ov->tempfbuf, 0, raw_bufsize);
4478
4479 for (i = 0; i < OV511_NUMSBUF; i++) {
4480 ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
4481 MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL);
4482 if (!ov->sbuf[i].data)
4483 goto error;
4484
4485 PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data);
4486 }
4487
4488 for (i = 0; i < OV511_NUMFRAMES; i++) {
4489 ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h);
4490 ov->frame[i].rawdata = ov->rawfbuf
4491 + i * MAX_RAW_DATA_SIZE(w, h);
4492 ov->frame[i].tempdata = ov->tempfbuf
4493 + i * MAX_RAW_DATA_SIZE(w, h);
4494
4495 ov->frame[i].compbuf =
4496 (unsigned char *) __get_free_page(GFP_KERNEL);
4497 if (!ov->frame[i].compbuf)
4498 goto error;
4499
4500 PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data);
4501 }
4502
4503 ov->buf_state = BUF_ALLOCATED;
4504out:
4505 up(&ov->buf_lock);
4506 PDEBUG(4, "leaving");
4507 return 0;
4508error:
4509 ov51x_do_dealloc(ov);
4510 up(&ov->buf_lock);
4511 PDEBUG(4, "errored");
4512 return -ENOMEM;
4513}
4514
4515static void
4516ov51x_dealloc(struct usb_ov511 *ov, int now)
4517{
4518 PDEBUG(4, "entered");
4519 down(&ov->buf_lock);
4520 ov51x_do_dealloc(ov);
4521 up(&ov->buf_lock);
4522 PDEBUG(4, "leaving");
4523}
4524
4525
4526
4527
4528
4529
4530
4531static int
4532ov51x_v4l1_open(struct inode *inode, struct file *file)
4533{
4534 struct video_device *vdev = video_devdata(file);
4535 struct usb_ov511 *ov = vdev->priv;
4536 int err, i;
4537
4538 PDEBUG(4, "opening");
4539
4540 down(&ov->lock);
4541
4542 err = -EBUSY;
4543 if (ov->user)
4544 goto out;
4545
4546 err = ov51x_alloc(ov);
4547 if (err < 0)
4548 goto out;
4549
4550 ov->sub_flag = 0;
4551
4552
4553 err = ov51x_set_default_params(ov);
4554 if (err < 0)
4555 goto out;
4556
4557
4558 for (i = 0; i < OV511_NUMFRAMES; i++) {
4559 ov->frame[i].grabstate = FRAME_UNUSED;
4560 ov->frame[i].bytes_read = 0;
4561 }
4562
4563
4564
4565 if (ov->compress && !ov->decomp_ops) {
4566 err = request_decompressor(ov);
4567 if (err && !dumppix)
4568 goto out;
4569 }
4570
4571 err = ov51x_init_isoc(ov);
4572 if (err) {
4573 ov51x_dealloc(ov, 0);
4574 goto out;
4575 }
4576
4577 ov->user++;
4578 file->private_data = vdev;
4579
4580 if (ov->led_policy == LED_AUTO)
4581 ov51x_led_control(ov, 1);
4582
4583out:
4584 up(&ov->lock);
4585 return err;
4586}
4587
4588static int
4589ov51x_v4l1_close(struct inode *inode, struct file *file)
4590{
4591 struct video_device *vdev = file->private_data;
4592 struct usb_ov511 *ov = vdev->priv;
4593
4594 PDEBUG(4, "ov511_close");
4595
4596 down(&ov->lock);
4597
4598 ov->user--;
4599 ov51x_stop_isoc(ov);
4600
4601 release_decompressor(ov);
4602
4603 if (ov->led_policy == LED_AUTO)
4604 ov51x_led_control(ov, 0);
4605
4606 if (ov->dev)
4607 ov51x_dealloc(ov, 0);
4608
4609 up(&ov->lock);
4610
4611
4612
4613 if (!ov->dev) {
4614 down(&ov->cbuf_lock);
4615 kfree(ov->cbuf);
4616 ov->cbuf = NULL;
4617 up(&ov->cbuf_lock);
4618
4619 ov51x_dealloc(ov, 1);
4620 kfree(ov);
4621 ov = NULL;
4622 }
4623
4624 file->private_data = NULL;
4625 return 0;
4626}
4627
4628
4629static int
4630ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file,
4631 unsigned int cmd, void *arg)
4632{
4633 struct video_device *vdev = file->private_data;
4634 struct usb_ov511 *ov = vdev->priv;
4635
4636 PDEBUG(5, "IOCtl: 0x%X", cmd);
4637
4638 if (!ov->dev)
4639 return -EIO;
4640
4641 switch (cmd) {
4642 case VIDIOCGCAP:
4643 {
4644 struct video_capability *b = arg;
4645
4646 PDEBUG(4, "VIDIOCGCAP");
4647
4648 memset(b, 0, sizeof(struct video_capability));
4649 sprintf(b->name, "%s USB Camera",
4650 symbolic(brglist, ov->bridge));
4651 b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
4652 b->channels = ov->num_inputs;
4653 b->audios = 0;
4654 b->maxwidth = ov->maxwidth;
4655 b->maxheight = ov->maxheight;
4656 b->minwidth = ov->minwidth;
4657 b->minheight = ov->minheight;
4658
4659 return 0;
4660 }
4661 case VIDIOCGCHAN:
4662 {
4663 struct video_channel *v = arg;
4664
4665 PDEBUG(4, "VIDIOCGCHAN");
4666
4667 if ((unsigned)(v->channel) >= ov->num_inputs) {
4668 err("Invalid channel (%d)", v->channel);
4669 return -EINVAL;
4670 }
4671
4672 v->norm = ov->norm;
4673 v->type = VIDEO_TYPE_CAMERA;
4674 v->flags = 0;
4675
4676 v->tuners = 0;
4677 decoder_get_input_name(ov, v->channel, v->name);
4678
4679 return 0;
4680 }
4681 case VIDIOCSCHAN:
4682 {
4683 struct video_channel *v = arg;
4684 int err;
4685
4686 PDEBUG(4, "VIDIOCSCHAN");
4687
4688
4689 if (!ov->has_decoder) {
4690 if (v->channel == 0)
4691 return 0;
4692 else
4693 return -EINVAL;
4694 }
4695
4696 if (v->norm != VIDEO_MODE_PAL &&
4697 v->norm != VIDEO_MODE_NTSC &&
4698 v->norm != VIDEO_MODE_SECAM &&
4699 v->norm != VIDEO_MODE_AUTO) {
4700 err("Invalid norm (%d)", v->norm);
4701 return -EINVAL;
4702 }
4703
4704 if ((unsigned)(v->channel) >= ov->num_inputs) {
4705 err("Invalid channel (%d)", v->channel);
4706 return -EINVAL;
4707 }
4708
4709 err = decoder_set_input(ov, v->channel);
4710 if (err)
4711 return err;
4712
4713 err = decoder_set_norm(ov, v->norm);
4714 if (err)
4715 return err;
4716
4717 return 0;
4718 }
4719 case VIDIOCGPICT:
4720 {
4721 struct video_picture *p = arg;
4722
4723 PDEBUG(4, "VIDIOCGPICT");
4724
4725 memset(p, 0, sizeof(struct video_picture));
4726 if (sensor_get_picture(ov, p))
4727 return -EIO;
4728
4729
4730 p->depth = ov->frame[0].depth;
4731 p->palette = ov->frame[0].format;
4732
4733 return 0;
4734 }
4735 case VIDIOCSPICT:
4736 {
4737 struct video_picture *p = arg;
4738 int i;
4739
4740 PDEBUG(4, "VIDIOCSPICT");
4741
4742 if (!get_depth(p->palette))
4743 return -EINVAL;
4744
4745 if (sensor_set_picture(ov, p))
4746 return -EIO;
4747
4748 if (force_palette && p->palette != force_palette) {
4749 info("Palette rejected (%s)",
4750 symbolic(v4l1_plist, p->palette));
4751 return -EINVAL;
4752 }
4753
4754
4755 if (p->palette != ov->frame[0].format) {
4756 PDEBUG(4, "Detected format change");
4757
4758
4759
4760 interruptible_sleep_on(&ov->wq);
4761 if (signal_pending(current)) return -EINTR;
4762
4763 mode_init_regs(ov, ov->frame[0].width,
4764 ov->frame[0].height, p->palette, ov->sub_flag);
4765 }
4766
4767 PDEBUG(4, "Setting depth=%d, palette=%s",
4768 p->depth, symbolic(v4l1_plist, p->palette));
4769
4770 for (i = 0; i < OV511_NUMFRAMES; i++) {
4771 ov->frame[i].depth = p->depth;
4772 ov->frame[i].format = p->palette;
4773 }
4774
4775 return 0;
4776 }
4777 case VIDIOCGCAPTURE:
4778 {
4779 int *vf = arg;
4780
4781 PDEBUG(4, "VIDIOCGCAPTURE");
4782
4783 ov->sub_flag = *vf;
4784 return 0;
4785 }
4786 case VIDIOCSCAPTURE:
4787 {
4788 struct video_capture *vc = arg;
4789
4790 PDEBUG(4, "VIDIOCSCAPTURE");
4791
4792 if (vc->flags)
4793 return -EINVAL;
4794 if (vc->decimation)
4795 return -EINVAL;
4796
4797 vc->x &= ~3L;
4798 vc->y &= ~1L;
4799 vc->y &= ~31L;
4800
4801 if (vc->width == 0)
4802 vc->width = 32;
4803
4804 vc->height /= 16;
4805 vc->height *= 16;
4806 if (vc->height == 0)
4807 vc->height = 16;
4808
4809 ov->subx = vc->x;
4810 ov->suby = vc->y;
4811 ov->subw = vc->width;
4812 ov->subh = vc->height;
4813
4814 return 0;
4815 }
4816 case VIDIOCSWIN:
4817 {
4818 struct video_window *vw = arg;
4819 int i, result;
4820
4821 PDEBUG(4, "VIDIOCSWIN: %dx%d", vw->width, vw->height);
4822
4823#if 0
4824 if (vw->flags)
4825 return -EINVAL;
4826 if (vw->clipcount)
4827 return -EINVAL;
4828 if (vw->height != ov->maxheight)
4829 return -EINVAL;
4830 if (vw->width != ov->maxwidth)
4831 return -EINVAL;
4832#endif
4833
4834
4835
4836 interruptible_sleep_on(&ov->wq);
4837 if (signal_pending(current)) return -EINTR;
4838
4839 result = mode_init_regs(ov, vw->width, vw->height,
4840 ov->frame[0].format, ov->sub_flag);
4841 if (result < 0)
4842 return result;
4843
4844 for (i = 0; i < OV511_NUMFRAMES; i++) {
4845 ov->frame[i].width = vw->width;
4846 ov->frame[i].height = vw->height;
4847 }
4848
4849 return 0;
4850 }
4851 case VIDIOCGWIN:
4852 {
4853 struct video_window *vw = arg;
4854
4855 memset(vw, 0, sizeof(struct video_window));
4856 vw->x = 0;
4857 vw->y = 0;
4858 vw->width = ov->frame[0].width;
4859 vw->height = ov->frame[0].height;
4860 vw->flags = 30;
4861
4862 PDEBUG(4, "VIDIOCGWIN: %dx%d", vw->width, vw->height);
4863
4864 return 0;
4865 }
4866 case VIDIOCGMBUF:
4867 {
4868 struct video_mbuf *vm = arg;
4869 int i;
4870
4871 PDEBUG(4, "VIDIOCGMBUF");
4872
4873 memset(vm, 0, sizeof(struct video_mbuf));
4874 vm->size = OV511_NUMFRAMES
4875 * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
4876 vm->frames = OV511_NUMFRAMES;
4877
4878 vm->offsets[0] = 0;
4879 for (i = 1; i < OV511_NUMFRAMES; i++) {
4880 vm->offsets[i] = vm->offsets[i-1]
4881 + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
4882 }
4883
4884 return 0;
4885 }
4886 case VIDIOCMCAPTURE:
4887 {
4888 struct video_mmap *vm = arg;
4889 int ret, depth;
4890 unsigned int f = vm->frame;
4891
4892 PDEBUG(4, "VIDIOCMCAPTURE: frame: %d, %dx%d, %s", f, vm->width,
4893 vm->height, symbolic(v4l1_plist, vm->format));
4894
4895 depth = get_depth(vm->format);
4896 if (!depth) {
4897 PDEBUG(2, "VIDIOCMCAPTURE: invalid format (%s)",
4898 symbolic(v4l1_plist, vm->format));
4899 return -EINVAL;
4900 }
4901
4902 if (f >= OV511_NUMFRAMES) {
4903 err("VIDIOCMCAPTURE: invalid frame (%d)", f);
4904 return -EINVAL;
4905 }
4906
4907 if (vm->width > ov->maxwidth
4908 || vm->height > ov->maxheight) {
4909 err("VIDIOCMCAPTURE: requested dimensions too big");
4910 return -EINVAL;
4911 }
4912
4913 if (ov->frame[f].grabstate == FRAME_GRABBING) {
4914 PDEBUG(4, "VIDIOCMCAPTURE: already grabbing");
4915 return -EBUSY;
4916 }
4917
4918 if (force_palette && (vm->format != force_palette)) {
4919 PDEBUG(2, "palette rejected (%s)",
4920 symbolic(v4l1_plist, vm->format));
4921 return -EINVAL;
4922 }
4923
4924 if ((ov->frame[f].width != vm->width) ||
4925 (ov->frame[f].height != vm->height) ||
4926 (ov->frame[f].format != vm->format) ||
4927 (ov->frame[f].sub_flag != ov->sub_flag) ||
4928 (ov->frame[f].depth != depth)) {
4929 PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters");
4930
4931
4932
4933 interruptible_sleep_on(&ov->wq);
4934 if (signal_pending(current)) return -EINTR;
4935 ret = mode_init_regs(ov, vm->width, vm->height,
4936 vm->format, ov->sub_flag);
4937#if 0
4938 if (ret < 0) {
4939 PDEBUG(1, "Got error while initializing regs ");
4940 return ret;
4941 }
4942#endif
4943 ov->frame[f].width = vm->width;
4944 ov->frame[f].height = vm->height;
4945 ov->frame[f].format = vm->format;
4946 ov->frame[f].sub_flag = ov->sub_flag;
4947 ov->frame[f].depth = depth;
4948 }
4949
4950
4951 ov->frame[f].grabstate = FRAME_READY;
4952
4953 PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", f);
4954
4955 return ov51x_new_frame(ov, f);
4956 }
4957 case VIDIOCSYNC:
4958 {
4959 unsigned int fnum = *((unsigned int *) arg);
4960 struct ov511_frame *frame;
4961 int rc;
4962
4963 if (fnum >= OV511_NUMFRAMES) {
4964 err("VIDIOCSYNC: invalid frame (%d)", fnum);
4965 return -EINVAL;
4966 }
4967
4968 frame = &ov->frame[fnum];
4969
4970 PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum,
4971 frame->grabstate);
4972
4973 switch (frame->grabstate) {
4974 case FRAME_UNUSED:
4975 return -EINVAL;
4976 case FRAME_READY:
4977 case FRAME_GRABBING:
4978 case FRAME_ERROR:
4979redo:
4980 if (!ov->dev)
4981 return -EIO;
4982
4983 rc = wait_event_interruptible(frame->wq,
4984 (frame->grabstate == FRAME_DONE)
4985 || (frame->grabstate == FRAME_ERROR));
4986
4987 if (rc)
4988 return rc;
4989
4990 if (frame->grabstate == FRAME_ERROR) {
4991 int ret;
4992
4993 if ((ret = ov51x_new_frame(ov, fnum)) < 0)
4994 return ret;
4995 goto redo;
4996 }
4997
4998 case FRAME_DONE:
4999 if (ov->snap_enabled && !frame->snapshot) {
5000 int ret;
5001 if ((ret = ov51x_new_frame(ov, fnum)) < 0)
5002 return ret;
5003 goto redo;
5004 }
5005
5006 frame->grabstate = FRAME_UNUSED;
5007
5008
5009
5010 if ((ov->snap_enabled) && (frame->snapshot)) {
5011 frame->snapshot = 0;
5012 ov51x_clear_snapshot(ov);
5013 }
5014
5015
5016 ov51x_postprocess(ov, frame);
5017
5018 break;
5019 }
5020
5021 return 0;
5022 }
5023 case VIDIOCGFBUF:
5024 {
5025 struct video_buffer *vb = arg;
5026
5027 PDEBUG(4, "VIDIOCGFBUF");
5028
5029 memset(vb, 0, sizeof(struct video_buffer));
5030
5031 return 0;
5032 }
5033 case VIDIOCGUNIT:
5034 {
5035 struct video_unit *vu = arg;
5036
5037 PDEBUG(4, "VIDIOCGUNIT");
5038
5039 memset(vu, 0, sizeof(struct video_unit));
5040
5041 vu->video = ov->vdev.minor;
5042 vu->vbi = VIDEO_NO_UNIT;
5043 vu->radio = VIDEO_NO_UNIT;
5044 vu->audio = VIDEO_NO_UNIT;
5045 vu->teletext = VIDEO_NO_UNIT;
5046
5047 return 0;
5048 }
5049 case OV511IOC_WI2C:
5050 {
5051 struct ov511_i2c_struct *w = arg;
5052
5053 return i2c_w_slave(ov, w->slave, w->reg, w->value, w->mask);
5054 }
5055 case OV511IOC_RI2C:
5056 {
5057 struct ov511_i2c_struct *r = arg;
5058 int rc;
5059
5060 rc = i2c_r_slave(ov, r->slave, r->reg);
5061 if (rc < 0)
5062 return rc;
5063
5064 r->value = rc;
5065 return 0;
5066 }
5067 default:
5068 PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd);
5069 return -ENOIOCTLCMD;
5070 }
5071
5072 return 0;
5073}
5074
5075static int
5076ov51x_v4l1_ioctl(struct inode *inode, struct file *file,
5077 unsigned int cmd, unsigned long arg)
5078{
5079 struct video_device *vdev = file->private_data;
5080 struct usb_ov511 *ov = vdev->priv;
5081 int rc;
5082
5083 if (down_interruptible(&ov->lock))
5084 return -EINTR;
5085
5086 rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal);
5087
5088 up(&ov->lock);
5089 return rc;
5090}
5091
5092static int
5093ov51x_v4l1_read(struct file *file, char *buf, size_t cnt, loff_t *ppos)
5094{
5095 struct video_device *vdev = file->private_data;
5096 int noblock = file->f_flags&O_NONBLOCK;
5097 unsigned long count = cnt;
5098 struct usb_ov511 *ov = vdev->priv;
5099 int i, rc = 0, frmx = -1;
5100 struct ov511_frame *frame;
5101
5102 if (down_interruptible(&ov->lock))
5103 return -EINTR;
5104
5105 PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
5106
5107 if (!vdev || !buf) {
5108 rc = -EFAULT;
5109 goto error;
5110 }
5111
5112 if (!ov->dev) {
5113 rc = -EIO;
5114 goto error;
5115 }
5116
5117
5118
5119 if (ov->frame[0].grabstate >= FRAME_DONE)
5120 frmx = 0;
5121 else if (ov->frame[1].grabstate >= FRAME_DONE)
5122 frmx = 1;
5123
5124
5125 if (noblock && (frmx == -1)) {
5126 rc = -EAGAIN;
5127 goto error;
5128 }
5129
5130
5131
5132 if (frmx == -1) {
5133 if (ov->frame[0].grabstate == FRAME_GRABBING)
5134 frmx = 0;
5135 else if (ov->frame[1].grabstate == FRAME_GRABBING)
5136 frmx = 1;
5137 }
5138
5139
5140 if (frmx == -1) {
5141 if ((rc = ov51x_new_frame(ov, frmx = 0))) {
5142 err("read: ov51x_new_frame error");
5143 goto error;
5144 }
5145 }
5146
5147 frame = &ov->frame[frmx];
5148
5149restart:
5150 if (!ov->dev) {
5151 rc = -EIO;
5152 goto error;
5153 }
5154
5155
5156 PDEBUG(4, "Waiting image grabbing");
5157 rc = wait_event_interruptible(frame->wq,
5158 (frame->grabstate == FRAME_DONE)
5159 || (frame->grabstate == FRAME_ERROR));
5160
5161 if (rc)
5162 goto error;
5163
5164 PDEBUG(4, "Got image, frame->grabstate = %d", frame->grabstate);
5165 PDEBUG(4, "bytes_recvd = %d", frame->bytes_recvd);
5166
5167 if (frame->grabstate == FRAME_ERROR) {
5168 frame->bytes_read = 0;
5169 err("** ick! ** Errored frame %d", ov->curframe);
5170 if (ov51x_new_frame(ov, frmx)) {
5171 err("read: ov51x_new_frame error");
5172 goto error;
5173 }
5174 goto restart;
5175 }
5176
5177
5178
5179 if (ov->snap_enabled)
5180 PDEBUG(4, "Waiting snapshot frame");
5181 if (ov->snap_enabled && !frame->snapshot) {
5182 frame->bytes_read = 0;
5183 if ((rc = ov51x_new_frame(ov, frmx))) {
5184 err("read: ov51x_new_frame error");
5185 goto error;
5186 }
5187 goto restart;
5188 }
5189
5190
5191 if (ov->snap_enabled && frame->snapshot) {
5192 frame->snapshot = 0;
5193 ov51x_clear_snapshot(ov);
5194 }
5195
5196
5197 ov51x_postprocess(ov, frame);
5198
5199 PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx,
5200 frame->bytes_read,
5201 get_frame_length(frame));
5202
5203
5204
5205
5206
5207
5208
5209 count = get_frame_length(frame);
5210
5211 PDEBUG(4, "Copy to user space: %ld bytes", count);
5212 if ((i = copy_to_user(buf, frame->data + frame->bytes_read, count))) {
5213 PDEBUG(4, "Copy failed! %d bytes not copied", i);
5214 rc = -EFAULT;
5215 goto error;
5216 }
5217
5218 frame->bytes_read += count;
5219 PDEBUG(4, "{copy} count used=%ld, new bytes_read=%ld",
5220 count, frame->bytes_read);
5221
5222
5223 if (frame->bytes_read
5224 >= get_frame_length(frame)) {
5225 frame->bytes_read = 0;
5226
5227
5228
5229 ov->frame[frmx].grabstate = FRAME_UNUSED;
5230 if ((rc = ov51x_new_frame(ov, !frmx))) {
5231 err("ov51x_new_frame returned error");
5232 goto error;
5233 }
5234 }
5235
5236 PDEBUG(4, "read finished, returning %ld (sweet)", count);
5237
5238 up(&ov->lock);
5239 return count;
5240
5241error:
5242 up(&ov->lock);
5243 return rc;
5244}
5245
5246static int
5247ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma)
5248{
5249 struct video_device *vdev = file->private_data;
5250 unsigned long start = vma->vm_start;
5251 unsigned long size = vma->vm_end - vma->vm_start;
5252 struct usb_ov511 *ov = vdev->priv;
5253 unsigned long page, pos;
5254
5255 if (ov->dev == NULL)
5256 return -EIO;
5257
5258 PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
5259
5260 if (size > (((OV511_NUMFRAMES
5261 * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
5262 + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
5263 return -EINVAL;
5264
5265 if (down_interruptible(&ov->lock))
5266 return -EINTR;
5267
5268 pos = (unsigned long)ov->fbuf;
5269 while (size > 0) {
5270 page = kvirt_to_pa(pos);
5271 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
5272 up(&ov->lock);
5273 return -EAGAIN;
5274 }
5275 start += PAGE_SIZE;
5276 pos += PAGE_SIZE;
5277 if (size > PAGE_SIZE)
5278 size -= PAGE_SIZE;
5279 else
5280 size = 0;
5281 }
5282
5283 up(&ov->lock);
5284 return 0;
5285}
5286
5287static struct file_operations ov511_fops = {
5288 .owner = THIS_MODULE,
5289 .open = ov51x_v4l1_open,
5290 .release = ov51x_v4l1_close,
5291 .read = ov51x_v4l1_read,
5292 .mmap = ov51x_v4l1_mmap,
5293 .ioctl = ov51x_v4l1_ioctl,
5294 .llseek = no_llseek,
5295};
5296
5297static struct video_device vdev_template = {
5298 .owner = THIS_MODULE,
5299 .name = "OV511 USB Camera",
5300 .type = VID_TYPE_CAPTURE,
5301 .hardware = VID_HARDWARE_OV511,
5302 .fops = &ov511_fops,
5303};
5304
5305#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
5306static int
5307ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
5308 unsigned long ularg)
5309{
5310 struct proc_dir_entry *pde = inode->u.generic_ip;
5311 struct usb_ov511 *ov;
5312 void *arg = (void *) ularg;
5313 int rc;
5314
5315 if (!pde)
5316 return -ENOENT;
5317
5318 ov = pde->data;
5319 if (!ov)
5320 return -ENODEV;
5321
5322 if (!ov->dev)
5323 return -EIO;
5324
5325
5326
5327 switch (cmd) {
5328 case OV511IOC_GINTVER:
5329 {
5330 int ver = OV511_INTERFACE_VER;
5331
5332 PDEBUG(4, "Get interface version: %d", ver);
5333 if (copy_to_user(arg, &ver, sizeof(ver)))
5334 return -EFAULT;
5335
5336 return 0;
5337 }
5338 case OV511IOC_GUSHORT:
5339 {
5340 struct ov511_ushort_opt opt;
5341
5342 if (copy_from_user(&opt, arg, sizeof(opt)))
5343 return -EFAULT;
5344
5345 switch (opt.optnum) {
5346 case OV511_USOPT_BRIGHT:
5347 rc = sensor_get_brightness(ov, &(opt.val));
5348 if (rc) return rc;
5349 break;
5350 case OV511_USOPT_SAT:
5351 rc = sensor_get_saturation(ov, &(opt.val));
5352 if (rc) return rc;
5353 break;
5354 case OV511_USOPT_HUE:
5355 rc = sensor_get_hue(ov, &(opt.val));
5356 if (rc) return rc;
5357 break;
5358 case OV511_USOPT_CONTRAST:
5359 rc = sensor_get_contrast(ov, &(opt.val));
5360 if (rc) return rc;
5361 break;
5362 default:
5363 err("Invalid get short option number");
5364 return -EINVAL;
5365 }
5366
5367 if (copy_to_user(arg, &opt, sizeof(opt)))
5368 return -EFAULT;
5369
5370 return 0;
5371 }
5372 case OV511IOC_SUSHORT:
5373 {
5374 struct ov511_ushort_opt opt;
5375
5376 if (copy_from_user(&opt, arg, sizeof(opt)))
5377 return -EFAULT;
5378
5379 switch (opt.optnum) {
5380 case OV511_USOPT_BRIGHT:
5381 rc = sensor_set_brightness(ov, opt.val);
5382 if (rc) return rc;
5383 break;
5384 case OV511_USOPT_SAT:
5385 rc = sensor_set_saturation(ov, opt.val);
5386 if (rc) return rc;
5387 break;
5388 case OV511_USOPT_HUE:
5389 rc = sensor_set_hue(ov, opt.val);
5390 if (rc) return rc;
5391 break;
5392 case OV511_USOPT_CONTRAST:
5393 rc = sensor_set_contrast(ov, opt.val);
5394 if (rc) return rc;
5395 break;
5396 default:
5397 err("Invalid set short option number");
5398 return -EINVAL;
5399 }
5400
5401 return 0;
5402 }
5403 case OV511IOC_GUINT:
5404 {
5405 struct ov511_uint_opt opt;
5406
5407 if (copy_from_user(&opt, arg, sizeof(opt)))
5408 return -EFAULT;
5409
5410 switch (opt.optnum) {
5411 case OV511_UIOPT_POWER_FREQ:
5412 opt.val = ov->lightfreq;
5413 break;
5414 case OV511_UIOPT_BFILTER:
5415 opt.val = ov->bandfilt;
5416 break;
5417 case OV511_UIOPT_LED:
5418 opt.val = ov->led_policy;
5419 break;
5420 case OV511_UIOPT_DEBUG:
5421 opt.val = debug;
5422 break;
5423 case OV511_UIOPT_COMPRESS:
5424 opt.val = ov->compress;
5425 break;
5426 default:
5427 err("Invalid get int option number");
5428 return -EINVAL;
5429 }
5430
5431 if (copy_to_user(arg, &opt, sizeof(opt)))
5432 return -EFAULT;
5433
5434 return 0;
5435 }
5436 case OV511IOC_SUINT:
5437 {
5438 struct ov511_uint_opt opt;
5439
5440 if (copy_from_user(&opt, arg, sizeof(opt)))
5441 return -EFAULT;
5442
5443 switch (opt.optnum) {
5444 case OV511_UIOPT_POWER_FREQ:
5445 rc = sensor_set_light_freq(ov, opt.val);
5446 if (rc) return rc;
5447 break;
5448 case OV511_UIOPT_BFILTER:
5449 rc = sensor_set_banding_filter(ov, opt.val);
5450 if (rc) return rc;
5451 break;
5452 case OV511_UIOPT_LED:
5453 if (opt.val <= 2) {
5454 ov->led_policy = opt.val;
5455 if (ov->led_policy == LED_OFF)
5456 ov51x_led_control(ov, 0);
5457 else if (ov->led_policy == LED_ON)
5458 ov51x_led_control(ov, 1);
5459 } else {
5460 return -EINVAL;
5461 }
5462 break;
5463 case OV511_UIOPT_DEBUG:
5464 if (opt.val <= 5)
5465 debug = opt.val;
5466 else
5467 return -EINVAL;
5468 break;
5469 case OV511_UIOPT_COMPRESS:
5470 ov->compress = opt.val;
5471 if (ov->compress) {
5472 if (ov->bclass == BCL_OV511)
5473 ov511_init_compression(ov);
5474 else if (ov->bclass == BCL_OV518)
5475 ov518_init_compression(ov);
5476 }
5477 break;
5478 default:
5479 err("Invalid get int option number");
5480 return -EINVAL;
5481 }
5482
5483 return 0;
5484 }
5485 case OV511IOC_WI2C:
5486 {
5487 struct ov511_i2c_struct w;
5488
5489 if (copy_from_user(&w, arg, sizeof(w)))
5490 return -EFAULT;
5491
5492 return i2c_w_slave(ov, w.slave, w.reg, w.value, w.mask);
5493 }
5494 case OV511IOC_RI2C:
5495 {
5496 struct ov511_i2c_struct r;
5497
5498 if (copy_from_user(&r, arg, sizeof(r)))
5499 return -EFAULT;
5500
5501 rc = i2c_r_slave(ov, r.slave, r.reg);
5502 if (rc < 0)
5503 return rc;
5504
5505 r.value = rc;
5506
5507 if (copy_to_user(arg, &r, sizeof(r)))
5508 return -EFAULT;
5509
5510 return 0;
5511 }
5512 default:
5513 return -EINVAL;
5514 }
5515
5516 return 0;
5517}
5518#endif
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529static int
5530ov7xx0_configure(struct usb_ov511 *ov)
5531{
5532 int i, success;
5533 int rc;
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546 static struct ov511_regvals aRegvalsNorm7610[] = {
5547 { OV511_I2C_BUS, 0x10, 0xff },
5548 { OV511_I2C_BUS, 0x16, 0x06 },
5549 { OV511_I2C_BUS, 0x28, 0x24 },
5550 { OV511_I2C_BUS, 0x2b, 0xac },
5551 { OV511_I2C_BUS, 0x12, 0x00 },
5552 { OV511_I2C_BUS, 0x38, 0x81 },
5553 { OV511_I2C_BUS, 0x28, 0x24 },
5554 { OV511_I2C_BUS, 0x0f, 0x85 },
5555 { OV511_I2C_BUS, 0x15, 0x01 },
5556 { OV511_I2C_BUS, 0x20, 0x1c },
5557 { OV511_I2C_BUS, 0x23, 0x2a },
5558 { OV511_I2C_BUS, 0x24, 0x10 },
5559 { OV511_I2C_BUS, 0x25, 0x8a },
5560 { OV511_I2C_BUS, 0x26, 0xa2 },
5561 { OV511_I2C_BUS, 0x27, 0xc2 },
5562 { OV511_I2C_BUS, 0x2a, 0x04 },
5563 { OV511_I2C_BUS, 0x2c, 0xfe },
5564 { OV511_I2C_BUS, 0x2d, 0x93 },
5565 { OV511_I2C_BUS, 0x30, 0x71 },
5566 { OV511_I2C_BUS, 0x31, 0x60 },
5567 { OV511_I2C_BUS, 0x32, 0x26 },
5568 { OV511_I2C_BUS, 0x33, 0x20 },
5569 { OV511_I2C_BUS, 0x34, 0x48 },
5570 { OV511_I2C_BUS, 0x12, 0x24 },
5571 { OV511_I2C_BUS, 0x11, 0x01 },
5572 { OV511_I2C_BUS, 0x0c, 0x24 },
5573 { OV511_I2C_BUS, 0x0d, 0x24 },
5574 { OV511_DONE_BUS, 0x0, 0x00 },
5575 };
5576
5577 static struct ov511_regvals aRegvalsNorm7620[] = {
5578 { OV511_I2C_BUS, 0x00, 0x00 },
5579 { OV511_I2C_BUS, 0x01, 0x80 },
5580 { OV511_I2C_BUS, 0x02, 0x80 },
5581 { OV511_I2C_BUS, 0x03, 0xc0 },
5582 { OV511_I2C_BUS, 0x06, 0x60 },
5583 { OV511_I2C_BUS, 0x07, 0x00 },
5584 { OV511_I2C_BUS, 0x0c, 0x24 },
5585 { OV511_I2C_BUS, 0x0c, 0x24 },
5586 { OV511_I2C_BUS, 0x0d, 0x24 },
5587 { OV511_I2C_BUS, 0x11, 0x01 },
5588 { OV511_I2C_BUS, 0x12, 0x24 },
5589 { OV511_I2C_BUS, 0x13, 0x01 },
5590 { OV511_I2C_BUS, 0x14, 0x84 },
5591 { OV511_I2C_BUS, 0x15, 0x01 },
5592 { OV511_I2C_BUS, 0x16, 0x03 },
5593 { OV511_I2C_BUS, 0x17, 0x2f },
5594 { OV511_I2C_BUS, 0x18, 0xcf },
5595 { OV511_I2C_BUS, 0x19, 0x06 },
5596 { OV511_I2C_BUS, 0x1a, 0xf5 },
5597 { OV511_I2C_BUS, 0x1b, 0x00 },
5598 { OV511_I2C_BUS, 0x20, 0x18 },
5599 { OV511_I2C_BUS, 0x21, 0x80 },
5600 { OV511_I2C_BUS, 0x22, 0x80 },
5601 { OV511_I2C_BUS, 0x23, 0x00 },
5602 { OV511_I2C_BUS, 0x26, 0xa2 },
5603 { OV511_I2C_BUS, 0x27, 0xea },
5604 { OV511_I2C_BUS, 0x28, 0x20 },
5605 { OV511_I2C_BUS, 0x29, 0x00 },
5606 { OV511_I2C_BUS, 0x2a, 0x10 },
5607 { OV511_I2C_BUS, 0x2b, 0x00 },
5608 { OV511_I2C_BUS, 0x2c, 0x88 },
5609 { OV511_I2C_BUS, 0x2d, 0x91 },
5610 { OV511_I2C_BUS, 0x2e, 0x80 },
5611 { OV511_I2C_BUS, 0x2f, 0x44 },
5612 { OV511_I2C_BUS, 0x60, 0x27 },
5613 { OV511_I2C_BUS, 0x61, 0x02 },
5614 { OV511_I2C_BUS, 0x62, 0x5f },
5615 { OV511_I2C_BUS, 0x63, 0xd5 },
5616 { OV511_I2C_BUS, 0x64, 0x57 },
5617 { OV511_I2C_BUS, 0x65, 0x83 },
5618 { OV511_I2C_BUS, 0x66, 0x55 },
5619 { OV511_I2C_BUS, 0x67, 0x92 },
5620 { OV511_I2C_BUS, 0x68, 0xcf },
5621 { OV511_I2C_BUS, 0x69, 0x76 },
5622 { OV511_I2C_BUS, 0x6a, 0x22 },
5623 { OV511_I2C_BUS, 0x6b, 0x00 },
5624 { OV511_I2C_BUS, 0x6c, 0x02 },
5625 { OV511_I2C_BUS, 0x6d, 0x44 },
5626 { OV511_I2C_BUS, 0x6e, 0x80 },
5627 { OV511_I2C_BUS, 0x6f, 0x1d },
5628 { OV511_I2C_BUS, 0x70, 0x8b },
5629 { OV511_I2C_BUS, 0x71, 0x00 },
5630 { OV511_I2C_BUS, 0x72, 0x14 },
5631 { OV511_I2C_BUS, 0x73, 0x54 },
5632 { OV511_I2C_BUS, 0x74, 0x00 },
5633 { OV511_I2C_BUS, 0x75, 0x8e },
5634 { OV511_I2C_BUS, 0x76, 0x00 },
5635 { OV511_I2C_BUS, 0x77, 0xff },
5636 { OV511_I2C_BUS, 0x78, 0x80 },
5637 { OV511_I2C_BUS, 0x79, 0x80 },
5638 { OV511_I2C_BUS, 0x7a, 0x80 },
5639 { OV511_I2C_BUS, 0x7b, 0xe2 },
5640 { OV511_I2C_BUS, 0x7c, 0x00 },
5641 { OV511_DONE_BUS, 0x0, 0x00 },
5642 };
5643
5644 PDEBUG(4, "starting configuration");
5645
5646
5647 ov->primary_i2c_slave = OV7xx0_SID;
5648 if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
5649 return -1;
5650
5651 if (init_ov_sensor(ov) >= 0) {
5652 PDEBUG(1, "OV7xx0 sensor initalized (method 1)");
5653 } else {
5654
5655 if (i2c_w(ov, 0x12, 0x80) < 0) return -1;
5656
5657
5658 schedule_timeout(1 + 150 * HZ / 1000);
5659
5660 i = 0;
5661 success = 0;
5662 while (i <= i2c_detect_tries) {
5663 if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
5664 (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
5665 success = 1;
5666 break;
5667 } else {
5668 i++;
5669 }
5670 }
5671
5672
5673
5674 if ((i >= i2c_detect_tries) && (success == 0)) {
5675 err("Failed to read sensor ID. You might not have an");
5676 err("OV7610/20, or it may be not responding. Report");
5677 err("this to " EMAIL);
5678 err("This is only a warning. You can attempt to use");
5679 err("your camera anyway");
5680
5681
5682 } else {
5683 PDEBUG(1, "OV7xx0 initialized (method 2, %dx)", i+1);
5684 }
5685 }
5686
5687
5688 rc = i2c_r(ov, OV7610_REG_COM_I);
5689
5690 if (rc < 0) {
5691 err("Error detecting sensor type");
5692 return -1;
5693 } else if ((rc & 3) == 3) {
5694 info("Sensor is an OV7610");
5695 ov->sensor = SEN_OV7610;
5696 } else if ((rc & 3) == 1) {
5697
5698 if (i2c_r(ov, 0x15) & 1)
5699 info("Sensor is an OV7620AE");
5700 else
5701 info("Sensor is an OV76BE");
5702
5703
5704
5705
5706 if (ov->bridge == BRG_OV511PLUS) {
5707 info("Enabling 511+/7620AE workaround");
5708 ov->sensor = SEN_OV7620;
5709 } else {
5710 ov->sensor = SEN_OV76BE;
5711 }
5712 } else if ((rc & 3) == 0) {
5713 info("Sensor is an OV7620");
5714 ov->sensor = SEN_OV7620;
5715 } else {
5716 err("Unknown image sensor version: %d", rc & 3);
5717 return -1;
5718 }
5719
5720 if (ov->sensor == SEN_OV7620) {
5721 PDEBUG(4, "Writing 7620 registers");
5722 if (write_regvals(ov, aRegvalsNorm7620))
5723 return -1;
5724 } else {
5725 PDEBUG(4, "Writing 7610 registers");
5726 if (write_regvals(ov, aRegvalsNorm7610))
5727 return -1;
5728 }
5729
5730
5731 ov->maxwidth = 640;
5732 ov->maxheight = 480;
5733 ov->minwidth = 64;
5734 ov->minheight = 48;
5735
5736
5737 ov->brightness = 0x80 << 8;
5738 ov->contrast = 0x80 << 8;
5739 ov->colour = 0x80 << 8;
5740 ov->hue = 0x80 << 8;
5741
5742 return 0;
5743}
5744
5745
5746static int
5747ov6xx0_configure(struct usb_ov511 *ov)
5748{
5749 int rc;
5750
5751 static struct ov511_regvals aRegvalsNorm6x20[] = {
5752 { OV511_I2C_BUS, 0x12, 0x80 },
5753 { OV511_I2C_BUS, 0x11, 0x01 },
5754 { OV511_I2C_BUS, 0x03, 0x60 },
5755 { OV511_I2C_BUS, 0x05, 0x7f },
5756 { OV511_I2C_BUS, 0x07, 0xa8 },
5757
5758 { OV511_I2C_BUS, 0x0c, 0x24 },
5759 { OV511_I2C_BUS, 0x0d, 0x24 },
5760 { OV511_I2C_BUS, 0x0f, 0x15 },
5761 { OV511_I2C_BUS, 0x10, 0x75 },
5762 { OV511_I2C_BUS, 0x12, 0x24 },
5763 { OV511_I2C_BUS, 0x14, 0x04 },
5764
5765 { OV511_I2C_BUS, 0x16, 0x06 },
5766
5767 { OV511_I2C_BUS, 0x26, 0xb2 },
5768
5769 { OV511_I2C_BUS, 0x28, 0x05 },
5770 { OV511_I2C_BUS, 0x2a, 0x04 },
5771
5772 { OV511_I2C_BUS, 0x2d, 0x99 },
5773 { OV511_I2C_BUS, 0x33, 0xa0 },
5774 { OV511_I2C_BUS, 0x34, 0xd2 },
5775 { OV511_I2C_BUS, 0x38, 0x8b },
5776 { OV511_I2C_BUS, 0x39, 0x40 },
5777
5778 { OV511_I2C_BUS, 0x3c, 0x39 },
5779 { OV511_I2C_BUS, 0x3c, 0x3c },
5780 { OV511_I2C_BUS, 0x3c, 0x24 },
5781
5782 { OV511_I2C_BUS, 0x3d, 0x80 },
5783
5784
5785 { OV511_I2C_BUS, 0x4a, 0x80 },
5786 { OV511_I2C_BUS, 0x4b, 0x80 },
5787 { OV511_I2C_BUS, 0x4d, 0xd2 },
5788 { OV511_I2C_BUS, 0x4e, 0xc1 },
5789 { OV511_I2C_BUS, 0x4f, 0x04 },
5790
5791
5792 { OV511_DONE_BUS, 0x0, 0x00 },
5793 };
5794
5795 static struct ov511_regvals aRegvalsNorm6x30[] = {
5796 { OV511_I2C_BUS, 0x12, 0x80 },
5797 { OV511_I2C_BUS, 0x11, 0x00 },
5798 { OV511_I2C_BUS, 0x03, 0x60 },
5799 { OV511_I2C_BUS, 0x05, 0x7f },
5800 { OV511_I2C_BUS, 0x07, 0xa8 },
5801
5802 { OV511_I2C_BUS, 0x0c, 0x24 },
5803 { OV511_I2C_BUS, 0x0d, 0x24 },
5804 { OV511_I2C_BUS, 0x0e, 0x20 },
5805
5806 { OV511_I2C_BUS, 0x16, 0x03 },
5807
5808
5809 { OV511_I2C_BUS, 0x23, 0xc0 },
5810 { OV511_I2C_BUS, 0x25, 0x9a },
5811
5812
5813
5814
5815
5816
5817 { OV511_I2C_BUS, 0x2a, 0x04 },
5818
5819 { OV511_I2C_BUS, 0x2d, 0x99 },
5820
5821
5822
5823
5824
5825
5826
5827 { OV511_I2C_BUS, 0x3d, 0x80 },
5828
5829
5830
5831
5832
5833
5834 { OV511_I2C_BUS, 0x4d, 0x10 },
5835 { OV511_I2C_BUS, 0x4e, 0x40 },
5836
5837
5838 { OV511_I2C_BUS, 0x4f, 0x07 },
5839
5840 { OV511_I2C_BUS, 0x54, 0x23 },
5841 { OV511_I2C_BUS, 0x57, 0x81 },
5842 { OV511_I2C_BUS, 0x59, 0x01 },
5843 { OV511_I2C_BUS, 0x5a, 0x2c },
5844 { OV511_I2C_BUS, 0x5b, 0x0f },
5845
5846 { OV511_DONE_BUS, 0x0, 0x00 },
5847 };
5848
5849 PDEBUG(4, "starting sensor configuration");
5850
5851 if (init_ov_sensor(ov) < 0) {
5852 err("Failed to read sensor ID. You might not have an OV6xx0,");
5853 err("or it may be not responding. Report this to " EMAIL);
5854 return -1;
5855 } else {
5856 PDEBUG(1, "OV6xx0 sensor detected");
5857 }
5858
5859
5860 rc = i2c_r(ov, OV7610_REG_COM_I);
5861
5862 if (rc < 0) {
5863 err("Error detecting sensor type");
5864 return -1;
5865 }
5866
5867 if ((rc & 3) == 0) {
5868 ov->sensor = SEN_OV6630;
5869 info("Sensor is an OV6630");
5870 } else if ((rc & 3) == 1) {
5871 ov->sensor = SEN_OV6620;
5872 info("Sensor is an OV6620");
5873 } else if ((rc & 3) == 2) {
5874 ov->sensor = SEN_OV6630;
5875 info("Sensor is an OV6630AE");
5876 } else if ((rc & 3) == 3) {
5877 ov->sensor = SEN_OV6630;
5878 info("Sensor is an OV6630AF");
5879 }
5880
5881
5882 ov->maxwidth = 352;
5883 ov->maxheight = 288;
5884 ov->minwidth = 64;
5885 ov->minheight = 48;
5886
5887
5888 ov->brightness = 0x80 << 8;
5889 ov->contrast = 0x80 << 8;
5890 ov->colour = 0x80 << 8;
5891 ov->hue = 0x80 << 8;
5892
5893 if (ov->sensor == SEN_OV6620) {
5894 PDEBUG(4, "Writing 6x20 registers");
5895 if (write_regvals(ov, aRegvalsNorm6x20))
5896 return -1;
5897 } else {
5898 PDEBUG(4, "Writing 6x30 registers");
5899 if (write_regvals(ov, aRegvalsNorm6x30))
5900 return -1;
5901 }
5902
5903 return 0;
5904}
5905
5906
5907static int
5908ks0127_configure(struct usb_ov511 *ov)
5909{
5910 int rc;
5911
5912
5913#if 0
5914 if (ov51x_init_ks_sensor(ov) < 0) {
5915 err("Failed to initialize the KS0127");
5916 return -1;
5917 } else {
5918 PDEBUG(1, "KS012x(B) sensor detected");
5919 }
5920#endif
5921
5922
5923 rc = i2c_r(ov, 0x00);
5924 if (rc < 0) {
5925 err("Error detecting sensor type");
5926 return -1;
5927 } else if (rc & 0x08) {
5928 rc = i2c_r(ov, 0x3d);
5929 if (rc < 0) {
5930 err("Error detecting sensor type");
5931 return -1;
5932 } else if ((rc & 0x0f) == 0) {
5933 info("Sensor is a KS0127");
5934 ov->sensor = SEN_KS0127;
5935 } else if ((rc & 0x0f) == 9) {
5936 info("Sensor is a KS0127B Rev. A");
5937 ov->sensor = SEN_KS0127B;
5938 }
5939 } else {
5940 err("Error: Sensor is an unsupported KS0122");
5941 return -1;
5942 }
5943
5944
5945 ov->maxwidth = 640;
5946 ov->maxheight = 480;
5947 ov->minwidth = 64;
5948 ov->minheight = 48;
5949
5950
5951 ov->brightness = 0x80 << 8;
5952 ov->contrast = 0x80 << 8;
5953 ov->colour = 0x80 << 8;
5954 ov->hue = 0x80 << 8;
5955
5956
5957 err("This sensor is not supported yet.");
5958 return -1;
5959
5960 return 0;
5961}
5962
5963
5964static int
5965saa7111a_configure(struct usb_ov511 *ov)
5966{
5967 int rc;
5968
5969
5970
5971 static struct ov511_regvals aRegvalsNormSAA7111A[] = {
5972 { OV511_I2C_BUS, 0x06, 0xce },
5973 { OV511_I2C_BUS, 0x07, 0x00 },
5974 { OV511_I2C_BUS, 0x10, 0x44 },
5975 { OV511_I2C_BUS, 0x0e, 0x01 },
5976 { OV511_I2C_BUS, 0x00, 0x00 },
5977 { OV511_I2C_BUS, 0x01, 0x00 },
5978 { OV511_I2C_BUS, 0x03, 0x23 },
5979 { OV511_I2C_BUS, 0x04, 0x00 },
5980 { OV511_I2C_BUS, 0x05, 0x00 },
5981 { OV511_I2C_BUS, 0x08, 0xc8 },
5982 { OV511_I2C_BUS, 0x09, 0x01 },
5983 { OV511_I2C_BUS, 0x0a, 0x80 },
5984 { OV511_I2C_BUS, 0x0b, 0x40 },
5985 { OV511_I2C_BUS, 0x0c, 0x40 },
5986 { OV511_I2C_BUS, 0x0d, 0x00 },
5987 { OV511_I2C_BUS, 0x0f, 0x00 },
5988 { OV511_I2C_BUS, 0x11, 0x0c },
5989 { OV511_I2C_BUS, 0x12, 0x00 },
5990 { OV511_I2C_BUS, 0x13, 0x00 },
5991 { OV511_I2C_BUS, 0x14, 0x00 },
5992 { OV511_I2C_BUS, 0x15, 0x00 },
5993 { OV511_I2C_BUS, 0x16, 0x00 },
5994 { OV511_I2C_BUS, 0x17, 0x00 },
5995 { OV511_I2C_BUS, 0x02, 0xc0 },
5996 { OV511_DONE_BUS, 0x0, 0x00 },
5997 };
5998
5999
6000#if 0
6001 if (ov51x_init_saa_sensor(ov) < 0) {
6002 err("Failed to initialize the SAA7111A");
6003 return -1;
6004 } else {
6005 PDEBUG(1, "SAA7111A sensor detected");
6006 }
6007#endif
6008
6009
6010 if (ov->pal) {
6011 ov->maxwidth = 320;
6012 ov->maxheight = 240;
6013 } else {
6014 ov->maxwidth = 640;
6015 ov->maxheight = 480;
6016 }
6017
6018 ov->minwidth = 320;
6019 ov->minheight = 240;
6020
6021 ov->has_decoder = 1;
6022 ov->num_inputs = 8;
6023 ov->norm = VIDEO_MODE_AUTO;
6024 ov->stop_during_set = 0;
6025
6026
6027
6028 ov->brightness = 0x80 << 8;
6029 ov->contrast = 0x40 << 9;
6030 ov->colour = 0x40 << 9;
6031 ov->hue = 32768;
6032
6033 PDEBUG(4, "Writing SAA7111A registers");
6034 if (write_regvals(ov, aRegvalsNormSAA7111A))
6035 return -1;
6036
6037
6038
6039 rc = i2c_r(ov, 0x00);
6040
6041 if (rc < 0) {
6042 err("Error detecting sensor version");
6043 return -1;
6044 } else {
6045 info("Sensor is an SAA7111A (version 0x%x)", rc);
6046 ov->sensor = SEN_SAA7111A;
6047 }
6048
6049
6050
6051
6052 if (ov->bclass == BCL_OV511)
6053 reg_w(ov, 0x11, 0x00);
6054 else
6055 warn("SAA7111A not yet supported with OV518/OV518+");
6056
6057 return 0;
6058}
6059
6060
6061static int
6062ov511_configure(struct usb_ov511 *ov)
6063{
6064 static struct ov511_regvals aRegvalsInit511[] = {
6065 { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
6066 { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
6067 { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
6068 { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
6069 { OV511_REG_BUS, R51x_SYS_RESET, 0x3f },
6070 { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
6071 { OV511_REG_BUS, R51x_SYS_RESET, 0x3d },
6072 { OV511_DONE_BUS, 0x0, 0x00},
6073 };
6074
6075 static struct ov511_regvals aRegvalsNorm511[] = {
6076 { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 },
6077 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
6078 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
6079 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
6080 { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f },
6081 { OV511_REG_BUS, R511_COMP_EN, 0x00 },
6082 { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
6083 { OV511_DONE_BUS, 0x0, 0x00 },
6084 };
6085
6086 static struct ov511_regvals aRegvalsNorm511Plus[] = {
6087 { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff },
6088 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
6089 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
6090 { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
6091 { OV511_REG_BUS, R511_FIFO_OPTS, 0xff },
6092 { OV511_REG_BUS, R511_COMP_EN, 0x00 },
6093 { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
6094 { OV511_DONE_BUS, 0x0, 0x00 },
6095 };
6096
6097 PDEBUG(4, "");
6098
6099 ov->customid = reg_r(ov, R511_SYS_CUST_ID);
6100 if (ov->customid < 0) {
6101 err("Unable to read camera bridge registers");
6102 goto error;
6103 }
6104
6105 PDEBUG (1, "CustomID = %d", ov->customid);
6106 ov->desc = symbolic(camlist, ov->customid);
6107 info("model: %s", ov->desc);
6108
6109 if (0 == strcmp(ov->desc, NOT_DEFINED_STR)) {
6110 err("Camera type (%d) not recognized", ov->customid);
6111 err("Please notify " EMAIL " of the name,");
6112 err("manufacturer, model, and this number of your camera.");
6113 err("Also include the output of the detection process.");
6114 }
6115
6116 if (ov->customid == 70)
6117 ov->pal = 1;
6118
6119 if (write_regvals(ov, aRegvalsInit511)) goto error;
6120
6121 if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
6122 ov51x_led_control(ov, 0);
6123
6124
6125
6126 if (ov->bridge == BRG_OV511) {
6127 if (write_regvals(ov, aRegvalsNorm511)) goto error;
6128 } else if (ov->bridge == BRG_OV511PLUS) {
6129 if (write_regvals(ov, aRegvalsNorm511Plus)) goto error;
6130 } else {
6131 err("Invalid bridge");
6132 }
6133
6134 if (ov511_init_compression(ov)) goto error;
6135
6136 ov->packet_numbering = 1;
6137 ov511_set_packet_size(ov, 0);
6138
6139 ov->snap_enabled = snapshot;
6140
6141
6142 PDEBUG(3, "Testing for 0V7xx0");
6143 ov->primary_i2c_slave = OV7xx0_SID;
6144 if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
6145 goto error;
6146
6147 if (i2c_w(ov, 0x12, 0x80) < 0) {
6148
6149 PDEBUG(3, "Testing for 0V6xx0");
6150 ov->primary_i2c_slave = OV6xx0_SID;
6151 if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
6152 goto error;
6153
6154 if (i2c_w(ov, 0x12, 0x80) < 0) {
6155
6156 PDEBUG(3, "Testing for 0V8xx0");
6157 ov->primary_i2c_slave = OV8xx0_SID;
6158 if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
6159 goto error;
6160
6161 if (i2c_w(ov, 0x12, 0x80) < 0) {
6162
6163 PDEBUG(3, "Testing for SAA7111A");
6164 ov->primary_i2c_slave = SAA7111A_SID;
6165 if (ov51x_set_slave_ids(ov, SAA7111A_SID) < 0)
6166 goto error;
6167
6168 if (i2c_w(ov, 0x0d, 0x00) < 0) {
6169
6170 PDEBUG(3, "Testing for KS0127");
6171 ov->primary_i2c_slave = KS0127_SID;
6172 if (ov51x_set_slave_ids(ov, KS0127_SID) < 0)
6173 goto error;
6174
6175 if (i2c_w(ov, 0x10, 0x00) < 0) {
6176 err("Can't determine sensor slave IDs");
6177 goto error;
6178 } else {
6179 if (ks0127_configure(ov) < 0) {
6180 err("Failed to configure KS0127");
6181 goto error;
6182 }
6183 }
6184 } else {
6185 if (saa7111a_configure(ov) < 0) {
6186 err("Failed to configure SAA7111A");
6187 goto error;
6188 }
6189 }
6190 } else {
6191 err("Detected unsupported OV8xx0 sensor");
6192 goto error;
6193 }
6194 } else {
6195 if (ov6xx0_configure(ov) < 0) {
6196 err("Failed to configure OV6xx0");
6197 goto error;
6198 }
6199 }
6200 } else {
6201 if (ov7xx0_configure(ov) < 0) {
6202 err("Failed to configure OV7xx0");
6203 goto error;
6204 }
6205 }
6206
6207 return 0;
6208
6209error:
6210 err("OV511 Config failed");
6211
6212 return -EBUSY;
6213}
6214
6215
6216static int
6217ov518_configure(struct usb_ov511 *ov)
6218{
6219
6220 static struct ov511_regvals aRegvalsInit518[] = {
6221 { OV511_REG_BUS, R51x_SYS_RESET, 0x40 },
6222 { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
6223 { OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
6224 { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
6225 { OV511_REG_BUS, R51x_SYS_RESET, 0x00 },
6226 { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
6227 { OV511_REG_BUS, 0x46, 0x00 },
6228 { OV511_REG_BUS, 0x5d, 0x03 },
6229 { OV511_DONE_BUS, 0x0, 0x00},
6230 };
6231
6232 static struct ov511_regvals aRegvalsNorm518[] = {
6233 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
6234 { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
6235 { OV511_REG_BUS, 0x31, 0x0f },
6236 { OV511_REG_BUS, 0x5d, 0x03 },
6237 { OV511_REG_BUS, 0x24, 0x9f },
6238 { OV511_REG_BUS, 0x25, 0x90 },
6239 { OV511_REG_BUS, 0x20, 0x00 },
6240 { OV511_REG_BUS, 0x51, 0x04 },
6241 { OV511_REG_BUS, 0x71, 0x19 },
6242 { OV511_DONE_BUS, 0x0, 0x00 },
6243 };
6244
6245 static struct ov511_regvals aRegvalsNorm518Plus[] = {
6246 { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
6247 { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
6248 { OV511_REG_BUS, 0x31, 0x0f },
6249 { OV511_REG_BUS, 0x5d, 0x03 },
6250 { OV511_REG_BUS, 0x24, 0x9f },
6251 { OV511_REG_BUS, 0x25, 0x90 },
6252 { OV511_REG_BUS, 0x20, 0x60 },
6253 { OV511_REG_BUS, 0x51, 0x02 },
6254 { OV511_REG_BUS, 0x71, 0x19 },
6255 { OV511_REG_BUS, 0x40, 0xff },
6256 { OV511_REG_BUS, 0x41, 0x42 },
6257 { OV511_REG_BUS, 0x46, 0x00 },
6258 { OV511_REG_BUS, 0x33, 0x04 },
6259 { OV511_REG_BUS, 0x21, 0x19 },
6260 { OV511_REG_BUS, 0x3f, 0x10 },
6261 { OV511_DONE_BUS, 0x0, 0x00 },
6262 };
6263
6264 PDEBUG(4, "");
6265
6266
6267 info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID));
6268
6269
6270 ov->desc = symbolic(camlist, 0);
6271
6272 if (write_regvals(ov, aRegvalsInit518)) goto error;
6273
6274
6275 if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0) goto error;
6276
6277
6278 if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
6279 ov51x_led_control(ov, 0);
6280 else
6281 ov51x_led_control(ov, 1);
6282
6283
6284
6285 if (!dumppix && !ov->compress) {
6286 ov->compress = 1;
6287 warn("Compression required with OV518...enabling");
6288 }
6289
6290 if (ov->bridge == BRG_OV518) {
6291 if (write_regvals(ov, aRegvalsNorm518)) goto error;
6292 } else if (ov->bridge == BRG_OV518PLUS) {
6293 if (write_regvals(ov, aRegvalsNorm518Plus)) goto error;
6294 } else {
6295 err("Invalid bridge");
6296 }
6297
6298 if (reg_w(ov, 0x2f, 0x80) < 0) goto error;
6299
6300 if (ov518_init_compression(ov)) goto error;
6301
6302 if (ov->bridge == BRG_OV518)
6303 {
6304 struct usb_interface *ifp = &ov->dev->config[0].interface[0];
6305 __u16 mxps = ifp->altsetting[7].endpoint[0].wMaxPacketSize;
6306
6307
6308 if (mxps == 897)
6309 ov->packet_numbering = 1;
6310 else
6311 ov->packet_numbering = 0;
6312 } else {
6313
6314 ov->packet_numbering = 1;
6315 }
6316
6317 ov518_set_packet_size(ov, 0);
6318
6319 ov->snap_enabled = snapshot;
6320
6321
6322 ov->primary_i2c_slave = OV7xx0_SID;
6323 if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
6324 goto error;
6325
6326
6327
6328
6329
6330 if (init_ov_sensor(ov) < 0) {
6331
6332 ov->primary_i2c_slave = OV6xx0_SID;
6333 if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
6334 goto error;
6335
6336 if (init_ov_sensor(ov) < 0) {
6337
6338 ov->primary_i2c_slave = OV8xx0_SID;
6339 if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
6340 goto error;
6341
6342 if (init_ov_sensor(ov) < 0) {
6343 err("Can't determine sensor slave IDs");
6344 goto error;
6345 } else {
6346 err("Detected unsupported OV8xx0 sensor");
6347 goto error;
6348 }
6349 } else {
6350 if (ov6xx0_configure(ov) < 0) {
6351 err("Failed to configure OV6xx0");
6352 goto error;
6353 }
6354 }
6355 } else {
6356 if (ov7xx0_configure(ov) < 0) {
6357 err("Failed to configure OV7xx0");
6358 goto error;
6359 }
6360 }
6361
6362 ov->maxwidth = 352;
6363 ov->maxheight = 288;
6364
6365
6366 ov->minwidth = 160;
6367 ov->minheight = 120;
6368
6369 return 0;
6370
6371error:
6372 err("OV518 Config failed");
6373
6374 return -EBUSY;
6375}
6376
6377
6378
6379
6380
6381
6382
6383
6384static void *
6385ov51x_probe(struct usb_device *dev, unsigned int ifnum,
6386 const struct usb_device_id *id)
6387{
6388 struct usb_interface_descriptor *interface;
6389 struct usb_ov511 *ov;
6390 int i;
6391 int registered = 0;
6392
6393 PDEBUG(1, "probing for device...");
6394
6395
6396 if (dev->descriptor.bNumConfigurations != 1)
6397 return NULL;
6398
6399 interface = &dev->actconfig->interface[ifnum].altsetting[0];
6400
6401
6402 if (interface->bInterfaceClass != 0xFF)
6403 return NULL;
6404 if (interface->bInterfaceSubClass != 0x00)
6405 return NULL;
6406
6407
6408 MOD_INC_USE_COUNT;
6409
6410 if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
6411 err("couldn't kmalloc ov struct");
6412 goto error_out;
6413 }
6414
6415 memset(ov, 0, sizeof(*ov));
6416
6417 ov->dev = dev;
6418 ov->iface = interface->bInterfaceNumber;
6419 ov->led_policy = led;
6420 ov->compress = compress;
6421 ov->lightfreq = lightfreq;
6422 ov->num_inputs = 1;
6423 ov->stop_during_set = !fastset;
6424 ov->backlight = backlight;
6425 ov->mirror = mirror;
6426 ov->auto_brt = autobright;
6427 ov->auto_gain = autogain;
6428 ov->auto_exp = autoexp;
6429
6430 switch (dev->descriptor.idProduct) {
6431 case PROD_OV511:
6432 ov->bridge = BRG_OV511;
6433 ov->bclass = BCL_OV511;
6434 break;
6435 case PROD_OV511PLUS:
6436 ov->bridge = BRG_OV511PLUS;
6437 ov->bclass = BCL_OV511;
6438 break;
6439 case PROD_OV518:
6440 ov->bridge = BRG_OV518;
6441 ov->bclass = BCL_OV518;
6442 break;
6443 case PROD_OV518PLUS:
6444 ov->bridge = BRG_OV518PLUS;
6445 ov->bclass = BCL_OV518;
6446 break;
6447 case PROD_ME2CAM:
6448 if (dev->descriptor.idVendor != VEND_MATTEL)
6449 goto error;
6450 ov->bridge = BRG_OV511PLUS;
6451 ov->bclass = BCL_OV511;
6452 break;
6453 default:
6454 err("Unknown product ID 0x%04x", dev->descriptor.idProduct);
6455 goto error_dealloc;
6456 }
6457
6458 info("USB %s video device found", symbolic(brglist, ov->bridge));
6459
6460
6461
6462 if (force_rgb)
6463 info("data format set to RGB");
6464
6465 init_waitqueue_head(&ov->wq);
6466
6467 init_MUTEX(&ov->lock);
6468 init_MUTEX(&ov->buf_lock);
6469 init_MUTEX(&ov->param_lock);
6470 init_MUTEX(&ov->i2c_lock);
6471 init_MUTEX(&ov->cbuf_lock);
6472
6473 ov->buf_state = BUF_NOT_ALLOCATED;
6474
6475 if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) {
6476 err("usb_make_path error");
6477 goto error_dealloc;
6478 }
6479
6480
6481
6482 ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL);
6483 if (!ov->cbuf)
6484 goto error;
6485
6486 if (ov->bclass == BCL_OV518) {
6487 if (ov518_configure(ov) < 0)
6488 goto error;
6489 } else {
6490 if (ov511_configure(ov) < 0)
6491 goto error;
6492 }
6493
6494 for (i = 0; i < OV511_NUMFRAMES; i++) {
6495 ov->frame[i].framenum = i;
6496 init_waitqueue_head(&ov->frame[i].wq);
6497 }
6498
6499 for (i = 0; i < OV511_NUMSBUF; i++) {
6500 ov->sbuf[i].ov = ov;
6501 spin_lock_init(&ov->sbuf[i].lock);
6502 ov->sbuf[i].n = i;
6503 }
6504
6505
6506
6507 if (ov51x_set_default_params(ov) < 0)
6508 goto error;
6509
6510#ifdef OV511_DEBUG
6511 if (dump_bridge) {
6512 if (ov->bclass == BCL_OV511)
6513 ov511_dump_regs(ov);
6514 else
6515 ov518_dump_regs(ov);
6516 }
6517#endif
6518
6519 memcpy(&ov->vdev, &vdev_template, sizeof(vdev_template));
6520 ov->vdev.priv = ov;
6521
6522 for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
6523
6524 if (unit_video[i] == 0)
6525 break;
6526
6527 if (video_register_device(&ov->vdev, VFL_TYPE_GRABBER,
6528 unit_video[i]) >= 0) {
6529 registered = 1;
6530 break;
6531 }
6532 }
6533
6534
6535 if (!registered &&
6536 video_register_device(&ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
6537 err("video_register_device failed");
6538 goto error;
6539 }
6540
6541 info("Device at %s registered to minor %d", ov->usb_path,
6542 ov->vdev.minor);
6543
6544#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
6545 create_proc_ov511_cam(ov);
6546#endif
6547
6548 MOD_DEC_USE_COUNT;
6549 return ov;
6550
6551error:
6552#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
6553
6554 destroy_proc_ov511_cam(ov);
6555#endif
6556
6557 if (ov->cbuf) {
6558 down(&ov->cbuf_lock);
6559 kfree(ov->cbuf);
6560 ov->cbuf = NULL;
6561 up(&ov->cbuf_lock);
6562 }
6563
6564error_dealloc:
6565 if (ov) {
6566 kfree(ov);
6567 ov = NULL;
6568 }
6569
6570error_out:
6571 MOD_DEC_USE_COUNT;
6572 err("Camera initialization failed");
6573 return NULL;
6574}
6575
6576
6577static void
6578ov51x_disconnect(struct usb_device *dev, void *ptr)
6579{
6580 struct usb_ov511 *ov = (struct usb_ov511 *) ptr;
6581 int n;
6582
6583 MOD_INC_USE_COUNT;
6584
6585 PDEBUG(3, "");
6586
6587 video_unregister_device(&ov->vdev);
6588 if (ov->user)
6589 PDEBUG(3, "Device open...deferring video_unregister_device");
6590
6591 for (n = 0; n < OV511_NUMFRAMES; n++)
6592 ov->frame[n].grabstate = FRAME_ERROR;
6593
6594 ov->curframe = -1;
6595
6596
6597 for (n = 0; n < OV511_NUMFRAMES; n++)
6598 if (waitqueue_active(&ov->frame[n].wq))
6599 wake_up_interruptible(&ov->frame[n].wq);
6600 if (waitqueue_active(&ov->wq))
6601 wake_up_interruptible(&ov->wq);
6602
6603 ov->streaming = 0;
6604
6605 ov51x_unlink_isoc(ov);
6606
6607#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
6608 destroy_proc_ov511_cam(ov);
6609#endif
6610
6611 ov->dev = NULL;
6612
6613
6614 if (ov && !ov->user) {
6615 down(&ov->cbuf_lock);
6616 kfree(ov->cbuf);
6617 ov->cbuf = NULL;
6618 up(&ov->cbuf_lock);
6619
6620 ov51x_dealloc(ov, 1);
6621 kfree(ov);
6622 ov = NULL;
6623 }
6624
6625 MOD_DEC_USE_COUNT;
6626
6627 PDEBUG(3, "Disconnect complete");
6628}
6629
6630static struct usb_driver ov511_driver = {
6631 .name = "ov511",
6632 .id_table = device_table,
6633 .probe = ov51x_probe,
6634 .disconnect = ov51x_disconnect
6635};
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645int
6646ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, int ov518,
6647 int mmx)
6648{
6649 if (ver != DECOMP_INTERFACE_VER) {
6650 err("Decompression module has incompatible");
6651 err("interface version %d", ver);
6652 err("Interface version %d is required", DECOMP_INTERFACE_VER);
6653 return -EINVAL;
6654 }
6655
6656 if (!ops)
6657 return -EFAULT;
6658
6659 if (mmx && !ov51x_mmx_available) {
6660 err("MMX not available on this system or kernel");
6661 return -EINVAL;
6662 }
6663
6664 lock_kernel();
6665
6666 if (ov518) {
6667 if (mmx) {
6668 if (ov518_mmx_decomp_ops)
6669 goto err_in_use;
6670 else
6671 ov518_mmx_decomp_ops = ops;
6672 } else {
6673 if (ov518_decomp_ops)
6674 goto err_in_use;
6675 else
6676 ov518_decomp_ops = ops;
6677 }
6678 } else {
6679 if (mmx) {
6680 if (ov511_mmx_decomp_ops)
6681 goto err_in_use;
6682 else
6683 ov511_mmx_decomp_ops = ops;
6684 } else {
6685 if (ov511_decomp_ops)
6686 goto err_in_use;
6687 else
6688 ov511_decomp_ops = ops;
6689 }
6690 }
6691
6692 MOD_INC_USE_COUNT;
6693
6694 unlock_kernel();
6695 return 0;
6696
6697err_in_use:
6698 unlock_kernel();
6699 return -EBUSY;
6700}
6701
6702void
6703ov511_deregister_decomp_module(int ov518, int mmx)
6704{
6705 lock_kernel();
6706
6707 if (ov518) {
6708 if (mmx)
6709 ov518_mmx_decomp_ops = NULL;
6710 else
6711 ov518_decomp_ops = NULL;
6712 } else {
6713 if (mmx)
6714 ov511_mmx_decomp_ops = NULL;
6715 else
6716 ov511_decomp_ops = NULL;
6717 }
6718
6719 MOD_DEC_USE_COUNT;
6720
6721 unlock_kernel();
6722}
6723
6724static int __init
6725usb_ov511_init(void)
6726{
6727#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
6728 proc_ov511_create();
6729#endif
6730
6731 if (usb_register(&ov511_driver) < 0)
6732 return -1;
6733
6734#if defined (__i386__)
6735 if (test_bit(X86_FEATURE_MMX, boot_cpu_data.x86_capability))
6736 ov51x_mmx_available = 1;
6737#endif
6738
6739 info(DRIVER_VERSION " : " DRIVER_DESC);
6740
6741 return 0;
6742}
6743
6744static void __exit
6745usb_ov511_exit(void)
6746{
6747 usb_deregister(&ov511_driver);
6748 info("driver deregistered");
6749
6750#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
6751 proc_ov511_destroy();
6752#endif
6753}
6754
6755module_init(usb_ov511_init);
6756module_exit(usb_ov511_exit);
6757
6758EXPORT_SYMBOL(ov511_register_decomp_module);
6759EXPORT_SYMBOL(ov511_deregister_decomp_module);
6760