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