diff options
Diffstat (limited to 'drivers/media/video/gspca/ov519.c')
-rw-r--r-- | drivers/media/video/gspca/ov519.c | 1495 |
1 files changed, 1313 insertions, 182 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index a5c190e93799..ad9ec339981d 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -2,14 +2,19 @@ | |||
2 | * OV519 driver | 2 | * OV519 driver |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) | 4 | * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) |
5 | * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> | ||
5 | * | 6 | * |
6 | * This module is adapted from the ov51x-jpeg package, which itself | 7 | * This module is adapted from the ov51x-jpeg package, which itself |
7 | * was adapted from the ov511 driver. | 8 | * was adapted from the ov511 driver. |
8 | * | 9 | * |
9 | * Original copyright for the ov511 driver is: | 10 | * Original copyright for the ov511 driver is: |
10 | * | 11 | * |
11 | * Copyright (c) 1999-2004 Mark W. McClelland | 12 | * Copyright (c) 1999-2006 Mark W. McClelland |
12 | * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach | 13 | * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach |
14 | * Many improvements by Bret Wallach <bwallac1@san.rr.com> | ||
15 | * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000) | ||
16 | * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org> | ||
17 | * Changes by Claudio Matsuoka <claudio@conectiva.com> | ||
13 | * | 18 | * |
14 | * ov51x-jpeg original copyright is: | 19 | * ov51x-jpeg original copyright is: |
15 | * | 20 | * |
@@ -58,6 +63,8 @@ struct sd { | |||
58 | #define BRIDGE_OV518 2 | 63 | #define BRIDGE_OV518 2 |
59 | #define BRIDGE_OV518PLUS 3 | 64 | #define BRIDGE_OV518PLUS 3 |
60 | #define BRIDGE_OV519 4 | 65 | #define BRIDGE_OV519 4 |
66 | #define BRIDGE_OVFX2 5 | ||
67 | #define BRIDGE_W9968CF 6 | ||
61 | #define BRIDGE_MASK 7 | 68 | #define BRIDGE_MASK 7 |
62 | 69 | ||
63 | char invert_led; | 70 | char invert_led; |
@@ -73,6 +80,10 @@ struct sd { | |||
73 | __u8 vflip; | 80 | __u8 vflip; |
74 | __u8 autobrightness; | 81 | __u8 autobrightness; |
75 | __u8 freq; | 82 | __u8 freq; |
83 | __u8 quality; | ||
84 | #define QUALITY_MIN 50 | ||
85 | #define QUALITY_MAX 70 | ||
86 | #define QUALITY_DEF 50 | ||
76 | 87 | ||
77 | __u8 stopped; /* Streaming is temporarily paused */ | 88 | __u8 stopped; /* Streaming is temporarily paused */ |
78 | 89 | ||
@@ -81,17 +92,31 @@ struct sd { | |||
81 | 92 | ||
82 | char sensor; /* Type of image sensor chip (SEN_*) */ | 93 | char sensor; /* Type of image sensor chip (SEN_*) */ |
83 | #define SEN_UNKNOWN 0 | 94 | #define SEN_UNKNOWN 0 |
84 | #define SEN_OV6620 1 | 95 | #define SEN_OV2610 1 |
85 | #define SEN_OV6630 2 | 96 | #define SEN_OV3610 2 |
86 | #define SEN_OV66308AF 3 | 97 | #define SEN_OV6620 3 |
87 | #define SEN_OV7610 4 | 98 | #define SEN_OV6630 4 |
88 | #define SEN_OV7620 5 | 99 | #define SEN_OV66308AF 5 |
89 | #define SEN_OV7640 6 | 100 | #define SEN_OV7610 6 |
90 | #define SEN_OV7670 7 | 101 | #define SEN_OV7620 7 |
91 | #define SEN_OV76BE 8 | 102 | #define SEN_OV7640 8 |
92 | #define SEN_OV8610 9 | 103 | #define SEN_OV7670 9 |
104 | #define SEN_OV76BE 10 | ||
105 | #define SEN_OV8610 11 | ||
106 | |||
107 | u8 sensor_addr; | ||
108 | int sensor_width; | ||
109 | int sensor_height; | ||
110 | int sensor_reg_cache[256]; | ||
111 | |||
112 | u8 *jpeg_hdr; | ||
93 | }; | 113 | }; |
94 | 114 | ||
115 | /* Note this is a bit of a hack, but the w9968cf driver needs the code for all | ||
116 | the ov sensors which is already present here. When we have the time we | ||
117 | really should move the sensor drivers to v4l2 sub drivers. */ | ||
118 | #include "w996Xcf.c" | ||
119 | |||
95 | /* V4L2 controls supported by the driver */ | 120 | /* V4L2 controls supported by the driver */ |
96 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); | 121 | static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); |
97 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); | 122 | static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); |
@@ -345,6 +370,75 @@ static const struct v4l2_pix_format ov511_sif_mode[] = { | |||
345 | .priv = 0}, | 370 | .priv = 0}, |
346 | }; | 371 | }; |
347 | 372 | ||
373 | static const struct v4l2_pix_format ovfx2_vga_mode[] = { | ||
374 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
375 | .bytesperline = 320, | ||
376 | .sizeimage = 320 * 240, | ||
377 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
378 | .priv = 1}, | ||
379 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
380 | .bytesperline = 640, | ||
381 | .sizeimage = 640 * 480, | ||
382 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
383 | .priv = 0}, | ||
384 | }; | ||
385 | static const struct v4l2_pix_format ovfx2_cif_mode[] = { | ||
386 | {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
387 | .bytesperline = 160, | ||
388 | .sizeimage = 160 * 120, | ||
389 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
390 | .priv = 3}, | ||
391 | {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
392 | .bytesperline = 176, | ||
393 | .sizeimage = 176 * 144, | ||
394 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
395 | .priv = 1}, | ||
396 | {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
397 | .bytesperline = 320, | ||
398 | .sizeimage = 320 * 240, | ||
399 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
400 | .priv = 2}, | ||
401 | {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
402 | .bytesperline = 352, | ||
403 | .sizeimage = 352 * 288, | ||
404 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
405 | .priv = 0}, | ||
406 | }; | ||
407 | static const struct v4l2_pix_format ovfx2_ov2610_mode[] = { | ||
408 | {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
409 | .bytesperline = 1600, | ||
410 | .sizeimage = 1600 * 1200, | ||
411 | .colorspace = V4L2_COLORSPACE_SRGB}, | ||
412 | }; | ||
413 | static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { | ||
414 | {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
415 | .bytesperline = 640, | ||
416 | .sizeimage = 640 * 480, | ||
417 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
418 | .priv = 1}, | ||
419 | {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
420 | .bytesperline = 800, | ||
421 | .sizeimage = 800 * 600, | ||
422 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
423 | .priv = 1}, | ||
424 | {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
425 | .bytesperline = 1024, | ||
426 | .sizeimage = 1024 * 768, | ||
427 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
428 | .priv = 1}, | ||
429 | {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
430 | .bytesperline = 1600, | ||
431 | .sizeimage = 1600 * 1200, | ||
432 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
433 | .priv = 0}, | ||
434 | {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, | ||
435 | .bytesperline = 2048, | ||
436 | .sizeimage = 2048 * 1536, | ||
437 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
438 | .priv = 0}, | ||
439 | }; | ||
440 | |||
441 | |||
348 | /* Registers common to OV511 / OV518 */ | 442 | /* Registers common to OV511 / OV518 */ |
349 | #define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ | 443 | #define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ |
350 | #define R51x_SYS_RESET 0x50 | 444 | #define R51x_SYS_RESET 0x50 |
@@ -406,6 +500,30 @@ static const struct v4l2_pix_format ov511_sif_mode[] = { | |||
406 | 500 | ||
407 | #define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ | 501 | #define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ |
408 | 502 | ||
503 | /* | ||
504 | * The FX2 chip does not give us a zero length read at end of frame. | ||
505 | * It does, however, give a short read at the end of a frame, if | ||
506 | * neccessary, rather than run two frames together. | ||
507 | * | ||
508 | * By choosing the right bulk transfer size, we are guaranteed to always | ||
509 | * get a short read for the last read of each frame. Frame sizes are | ||
510 | * always a composite number (width * height, or a multiple) so if we | ||
511 | * choose a prime number, we are guaranteed that the last read of a | ||
512 | * frame will be short. | ||
513 | * | ||
514 | * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB, | ||
515 | * otherwise EOVERFLOW "babbling" errors occur. I have not been able | ||
516 | * to figure out why. [PMiller] | ||
517 | * | ||
518 | * The constant (13 * 4096) is the largest "prime enough" number less than 64KB. | ||
519 | * | ||
520 | * It isn't enough to know the number of bytes per frame, in case we | ||
521 | * have data dropouts or buffer overruns (even though the FX2 double | ||
522 | * buffers, there are some pretty strict real time constraints for | ||
523 | * isochronous transfer for larger frame sizes). | ||
524 | */ | ||
525 | #define OVFX2_BULK_SIZE (13 * 4096) | ||
526 | |||
409 | /* I2C registers */ | 527 | /* I2C registers */ |
410 | #define R51x_I2C_W_SID 0x41 | 528 | #define R51x_I2C_W_SID 0x41 |
411 | #define R51x_I2C_SADDR_3 0x42 | 529 | #define R51x_I2C_SADDR_3 0x42 |
@@ -413,9 +531,11 @@ static const struct v4l2_pix_format ov511_sif_mode[] = { | |||
413 | #define R51x_I2C_R_SID 0x44 | 531 | #define R51x_I2C_R_SID 0x44 |
414 | #define R51x_I2C_DATA 0x45 | 532 | #define R51x_I2C_DATA 0x45 |
415 | #define R518_I2C_CTL 0x47 /* OV518(+) only */ | 533 | #define R518_I2C_CTL 0x47 /* OV518(+) only */ |
534 | #define OVFX2_I2C_ADDR 0x00 | ||
416 | 535 | ||
417 | /* I2C ADDRESSES */ | 536 | /* I2C ADDRESSES */ |
418 | #define OV7xx0_SID 0x42 | 537 | #define OV7xx0_SID 0x42 |
538 | #define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */ | ||
419 | #define OV8xx0_SID 0xa0 | 539 | #define OV8xx0_SID 0xa0 |
420 | #define OV6xx0_SID 0xc0 | 540 | #define OV6xx0_SID 0xc0 |
421 | 541 | ||
@@ -508,6 +628,696 @@ struct ov_i2c_regvals { | |||
508 | __u8 val; | 628 | __u8 val; |
509 | }; | 629 | }; |
510 | 630 | ||
631 | /* Settings for OV2610 camera chip */ | ||
632 | static const struct ov_i2c_regvals norm_2610[] = | ||
633 | { | ||
634 | { 0x12, 0x80 }, /* reset */ | ||
635 | }; | ||
636 | |||
637 | static const struct ov_i2c_regvals norm_3620b[] = | ||
638 | { | ||
639 | /* | ||
640 | * From the datasheet: "Note that after writing to register COMH | ||
641 | * (0x12) to change the sensor mode, registers related to the | ||
642 | * sensor’s cropping window will be reset back to their default | ||
643 | * values." | ||
644 | * | ||
645 | * "wait 4096 external clock ... to make sure the sensor is | ||
646 | * stable and ready to access registers" i.e. 160us at 24MHz | ||
647 | */ | ||
648 | |||
649 | { 0x12, 0x80 }, /* COMH reset */ | ||
650 | { 0x12, 0x00 }, /* QXGA, master */ | ||
651 | |||
652 | /* | ||
653 | * 11 CLKRC "Clock Rate Control" | ||
654 | * [7] internal frequency doublers: on | ||
655 | * [6] video port mode: master | ||
656 | * [5:0] clock divider: 1 | ||
657 | */ | ||
658 | { 0x11, 0x80 }, | ||
659 | |||
660 | /* | ||
661 | * 13 COMI "Common Control I" | ||
662 | * = 192 (0xC0) 11000000 | ||
663 | * COMI[7] "AEC speed selection" | ||
664 | * = 1 (0x01) 1....... "Faster AEC correction" | ||
665 | * COMI[6] "AEC speed step selection" | ||
666 | * = 1 (0x01) .1...... "Big steps, fast" | ||
667 | * COMI[5] "Banding filter on off" | ||
668 | * = 0 (0x00) ..0..... "Off" | ||
669 | * COMI[4] "Banding filter option" | ||
670 | * = 0 (0x00) ...0.... "Main clock is 48 MHz and | ||
671 | * the PLL is ON" | ||
672 | * COMI[3] "Reserved" | ||
673 | * = 0 (0x00) ....0... | ||
674 | * COMI[2] "AGC auto manual control selection" | ||
675 | * = 0 (0x00) .....0.. "Manual" | ||
676 | * COMI[1] "AWB auto manual control selection" | ||
677 | * = 0 (0x00) ......0. "Manual" | ||
678 | * COMI[0] "Exposure control" | ||
679 | * = 0 (0x00) .......0 "Manual" | ||
680 | */ | ||
681 | { 0x13, 0xC0 }, | ||
682 | |||
683 | /* | ||
684 | * 09 COMC "Common Control C" | ||
685 | * = 8 (0x08) 00001000 | ||
686 | * COMC[7:5] "Reserved" | ||
687 | * = 0 (0x00) 000..... | ||
688 | * COMC[4] "Sleep Mode Enable" | ||
689 | * = 0 (0x00) ...0.... "Normal mode" | ||
690 | * COMC[3:2] "Sensor sampling reset timing selection" | ||
691 | * = 2 (0x02) ....10.. "Longer reset time" | ||
692 | * COMC[1:0] "Output drive current select" | ||
693 | * = 0 (0x00) ......00 "Weakest" | ||
694 | */ | ||
695 | { 0x09, 0x08 }, | ||
696 | |||
697 | /* | ||
698 | * 0C COMD "Common Control D" | ||
699 | * = 8 (0x08) 00001000 | ||
700 | * COMD[7] "Reserved" | ||
701 | * = 0 (0x00) 0....... | ||
702 | * COMD[6] "Swap MSB and LSB at the output port" | ||
703 | * = 0 (0x00) .0...... "False" | ||
704 | * COMD[5:3] "Reserved" | ||
705 | * = 1 (0x01) ..001... | ||
706 | * COMD[2] "Output Average On Off" | ||
707 | * = 0 (0x00) .....0.. "Output Normal" | ||
708 | * COMD[1] "Sensor precharge voltage selection" | ||
709 | * = 0 (0x00) ......0. "Selects internal | ||
710 | * reference precharge | ||
711 | * voltage" | ||
712 | * COMD[0] "Snapshot option" | ||
713 | * = 0 (0x00) .......0 "Enable live video output | ||
714 | * after snapshot sequence" | ||
715 | */ | ||
716 | { 0x0c, 0x08 }, | ||
717 | |||
718 | /* | ||
719 | * 0D COME "Common Control E" | ||
720 | * = 161 (0xA1) 10100001 | ||
721 | * COME[7] "Output average option" | ||
722 | * = 1 (0x01) 1....... "Output average of 4 pixels" | ||
723 | * COME[6] "Anti-blooming control" | ||
724 | * = 0 (0x00) .0...... "Off" | ||
725 | * COME[5:3] "Reserved" | ||
726 | * = 4 (0x04) ..100... | ||
727 | * COME[2] "Clock output power down pin status" | ||
728 | * = 0 (0x00) .....0.. "Tri-state data output pin | ||
729 | * on power down" | ||
730 | * COME[1] "Data output pin status selection at power down" | ||
731 | * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK, | ||
732 | * HREF, and CHSYNC pins on | ||
733 | * power down" | ||
734 | * COME[0] "Auto zero circuit select" | ||
735 | * = 1 (0x01) .......1 "On" | ||
736 | */ | ||
737 | { 0x0d, 0xA1 }, | ||
738 | |||
739 | /* | ||
740 | * 0E COMF "Common Control F" | ||
741 | * = 112 (0x70) 01110000 | ||
742 | * COMF[7] "System clock selection" | ||
743 | * = 0 (0x00) 0....... "Use 24 MHz system clock" | ||
744 | * COMF[6:4] "Reserved" | ||
745 | * = 7 (0x07) .111.... | ||
746 | * COMF[3] "Manual auto negative offset canceling selection" | ||
747 | * = 0 (0x00) ....0... "Auto detect negative | ||
748 | * offset and cancel it" | ||
749 | * COMF[2:0] "Reserved" | ||
750 | * = 0 (0x00) .....000 | ||
751 | */ | ||
752 | { 0x0e, 0x70 }, | ||
753 | |||
754 | /* | ||
755 | * 0F COMG "Common Control G" | ||
756 | * = 66 (0x42) 01000010 | ||
757 | * COMG[7] "Optical black output selection" | ||
758 | * = 0 (0x00) 0....... "Disable" | ||
759 | * COMG[6] "Black level calibrate selection" | ||
760 | * = 1 (0x01) .1...... "Use optical black pixels | ||
761 | * to calibrate" | ||
762 | * COMG[5:4] "Reserved" | ||
763 | * = 0 (0x00) ..00.... | ||
764 | * COMG[3] "Channel offset adjustment" | ||
765 | * = 0 (0x00) ....0... "Disable offset adjustment" | ||
766 | * COMG[2] "ADC black level calibration option" | ||
767 | * = 0 (0x00) .....0.. "Use B/G line and G/R | ||
768 | * line to calibrate each | ||
769 | * channel's black level" | ||
770 | * COMG[1] "Reserved" | ||
771 | * = 1 (0x01) ......1. | ||
772 | * COMG[0] "ADC black level calibration enable" | ||
773 | * = 0 (0x00) .......0 "Disable" | ||
774 | */ | ||
775 | { 0x0f, 0x42 }, | ||
776 | |||
777 | /* | ||
778 | * 14 COMJ "Common Control J" | ||
779 | * = 198 (0xC6) 11000110 | ||
780 | * COMJ[7:6] "AGC gain ceiling" | ||
781 | * = 3 (0x03) 11...... "8x" | ||
782 | * COMJ[5:4] "Reserved" | ||
783 | * = 0 (0x00) ..00.... | ||
784 | * COMJ[3] "Auto banding filter" | ||
785 | * = 0 (0x00) ....0... "Banding filter is always | ||
786 | * on off depending on | ||
787 | * COMI[5] setting" | ||
788 | * COMJ[2] "VSYNC drop option" | ||
789 | * = 1 (0x01) .....1.. "SYNC is dropped if frame | ||
790 | * data is dropped" | ||
791 | * COMJ[1] "Frame data drop" | ||
792 | * = 1 (0x01) ......1. "Drop frame data if | ||
793 | * exposure is not within | ||
794 | * tolerance. In AEC mode, | ||
795 | * data is normally dropped | ||
796 | * when data is out of | ||
797 | * range." | ||
798 | * COMJ[0] "Reserved" | ||
799 | * = 0 (0x00) .......0 | ||
800 | */ | ||
801 | { 0x14, 0xC6 }, | ||
802 | |||
803 | /* | ||
804 | * 15 COMK "Common Control K" | ||
805 | * = 2 (0x02) 00000010 | ||
806 | * COMK[7] "CHSYNC pin output swap" | ||
807 | * = 0 (0x00) 0....... "CHSYNC" | ||
808 | * COMK[6] "HREF pin output swap" | ||
809 | * = 0 (0x00) .0...... "HREF" | ||
810 | * COMK[5] "PCLK output selection" | ||
811 | * = 0 (0x00) ..0..... "PCLK always output" | ||
812 | * COMK[4] "PCLK edge selection" | ||
813 | * = 0 (0x00) ...0.... "Data valid on falling edge" | ||
814 | * COMK[3] "HREF output polarity" | ||
815 | * = 0 (0x00) ....0... "positive" | ||
816 | * COMK[2] "Reserved" | ||
817 | * = 0 (0x00) .....0.. | ||
818 | * COMK[1] "VSYNC polarity" | ||
819 | * = 1 (0x01) ......1. "negative" | ||
820 | * COMK[0] "HSYNC polarity" | ||
821 | * = 0 (0x00) .......0 "positive" | ||
822 | */ | ||
823 | { 0x15, 0x02 }, | ||
824 | |||
825 | /* | ||
826 | * 33 CHLF "Current Control" | ||
827 | * = 9 (0x09) 00001001 | ||
828 | * CHLF[7:6] "Sensor current control" | ||
829 | * = 0 (0x00) 00...... | ||
830 | * CHLF[5] "Sensor current range control" | ||
831 | * = 0 (0x00) ..0..... "normal range" | ||
832 | * CHLF[4] "Sensor current" | ||
833 | * = 0 (0x00) ...0.... "normal current" | ||
834 | * CHLF[3] "Sensor buffer current control" | ||
835 | * = 1 (0x01) ....1... "half current" | ||
836 | * CHLF[2] "Column buffer current control" | ||
837 | * = 0 (0x00) .....0.. "normal current" | ||
838 | * CHLF[1] "Analog DSP current control" | ||
839 | * = 0 (0x00) ......0. "normal current" | ||
840 | * CHLF[1] "ADC current control" | ||
841 | * = 0 (0x00) ......0. "normal current" | ||
842 | */ | ||
843 | { 0x33, 0x09 }, | ||
844 | |||
845 | /* | ||
846 | * 34 VBLM "Blooming Control" | ||
847 | * = 80 (0x50) 01010000 | ||
848 | * VBLM[7] "Hard soft reset switch" | ||
849 | * = 0 (0x00) 0....... "Hard reset" | ||
850 | * VBLM[6:4] "Blooming voltage selection" | ||
851 | * = 5 (0x05) .101.... | ||
852 | * VBLM[3:0] "Sensor current control" | ||
853 | * = 0 (0x00) ....0000 | ||
854 | */ | ||
855 | { 0x34, 0x50 }, | ||
856 | |||
857 | /* | ||
858 | * 36 VCHG "Sensor Precharge Voltage Control" | ||
859 | * = 0 (0x00) 00000000 | ||
860 | * VCHG[7] "Reserved" | ||
861 | * = 0 (0x00) 0....... | ||
862 | * VCHG[6:4] "Sensor precharge voltage control" | ||
863 | * = 0 (0x00) .000.... | ||
864 | * VCHG[3:0] "Sensor array common reference" | ||
865 | * = 0 (0x00) ....0000 | ||
866 | */ | ||
867 | { 0x36, 0x00 }, | ||
868 | |||
869 | /* | ||
870 | * 37 ADC "ADC Reference Control" | ||
871 | * = 4 (0x04) 00000100 | ||
872 | * ADC[7:4] "Reserved" | ||
873 | * = 0 (0x00) 0000.... | ||
874 | * ADC[3] "ADC input signal range" | ||
875 | * = 0 (0x00) ....0... "Input signal 1.0x" | ||
876 | * ADC[2:0] "ADC range control" | ||
877 | * = 4 (0x04) .....100 | ||
878 | */ | ||
879 | { 0x37, 0x04 }, | ||
880 | |||
881 | /* | ||
882 | * 38 ACOM "Analog Common Ground" | ||
883 | * = 82 (0x52) 01010010 | ||
884 | * ACOM[7] "Analog gain control" | ||
885 | * = 0 (0x00) 0....... "Gain 1x" | ||
886 | * ACOM[6] "Analog black level calibration" | ||
887 | * = 1 (0x01) .1...... "On" | ||
888 | * ACOM[5:0] "Reserved" | ||
889 | * = 18 (0x12) ..010010 | ||
890 | */ | ||
891 | { 0x38, 0x52 }, | ||
892 | |||
893 | /* | ||
894 | * 3A FREFA "Internal Reference Adjustment" | ||
895 | * = 0 (0x00) 00000000 | ||
896 | * FREFA[7:0] "Range" | ||
897 | * = 0 (0x00) 00000000 | ||
898 | */ | ||
899 | { 0x3a, 0x00 }, | ||
900 | |||
901 | /* | ||
902 | * 3C FVOPT "Internal Reference Adjustment" | ||
903 | * = 31 (0x1F) 00011111 | ||
904 | * FVOPT[7:0] "Range" | ||
905 | * = 31 (0x1F) 00011111 | ||
906 | */ | ||
907 | { 0x3c, 0x1F }, | ||
908 | |||
909 | /* | ||
910 | * 44 Undocumented = 0 (0x00) 00000000 | ||
911 | * 44[7:0] "It's a secret" | ||
912 | * = 0 (0x00) 00000000 | ||
913 | */ | ||
914 | { 0x44, 0x00 }, | ||
915 | |||
916 | /* | ||
917 | * 40 Undocumented = 0 (0x00) 00000000 | ||
918 | * 40[7:0] "It's a secret" | ||
919 | * = 0 (0x00) 00000000 | ||
920 | */ | ||
921 | { 0x40, 0x00 }, | ||
922 | |||
923 | /* | ||
924 | * 41 Undocumented = 0 (0x00) 00000000 | ||
925 | * 41[7:0] "It's a secret" | ||
926 | * = 0 (0x00) 00000000 | ||
927 | */ | ||
928 | { 0x41, 0x00 }, | ||
929 | |||
930 | /* | ||
931 | * 42 Undocumented = 0 (0x00) 00000000 | ||
932 | * 42[7:0] "It's a secret" | ||
933 | * = 0 (0x00) 00000000 | ||
934 | */ | ||
935 | { 0x42, 0x00 }, | ||
936 | |||
937 | /* | ||
938 | * 43 Undocumented = 0 (0x00) 00000000 | ||
939 | * 43[7:0] "It's a secret" | ||
940 | * = 0 (0x00) 00000000 | ||
941 | */ | ||
942 | { 0x43, 0x00 }, | ||
943 | |||
944 | /* | ||
945 | * 45 Undocumented = 128 (0x80) 10000000 | ||
946 | * 45[7:0] "It's a secret" | ||
947 | * = 128 (0x80) 10000000 | ||
948 | */ | ||
949 | { 0x45, 0x80 }, | ||
950 | |||
951 | /* | ||
952 | * 48 Undocumented = 192 (0xC0) 11000000 | ||
953 | * 48[7:0] "It's a secret" | ||
954 | * = 192 (0xC0) 11000000 | ||
955 | */ | ||
956 | { 0x48, 0xC0 }, | ||
957 | |||
958 | /* | ||
959 | * 49 Undocumented = 25 (0x19) 00011001 | ||
960 | * 49[7:0] "It's a secret" | ||
961 | * = 25 (0x19) 00011001 | ||
962 | */ | ||
963 | { 0x49, 0x19 }, | ||
964 | |||
965 | /* | ||
966 | * 4B Undocumented = 128 (0x80) 10000000 | ||
967 | * 4B[7:0] "It's a secret" | ||
968 | * = 128 (0x80) 10000000 | ||
969 | */ | ||
970 | { 0x4B, 0x80 }, | ||
971 | |||
972 | /* | ||
973 | * 4D Undocumented = 196 (0xC4) 11000100 | ||
974 | * 4D[7:0] "It's a secret" | ||
975 | * = 196 (0xC4) 11000100 | ||
976 | */ | ||
977 | { 0x4D, 0xC4 }, | ||
978 | |||
979 | /* | ||
980 | * 35 VREF "Reference Voltage Control" | ||
981 | * = 76 (0x4C) 01001100 | ||
982 | * VREF[7:5] "Column high reference control" | ||
983 | * = 2 (0x02) 010..... "higher voltage" | ||
984 | * VREF[4:2] "Column low reference control" | ||
985 | * = 3 (0x03) ...011.. "Highest voltage" | ||
986 | * VREF[1:0] "Reserved" | ||
987 | * = 0 (0x00) ......00 | ||
988 | */ | ||
989 | { 0x35, 0x4C }, | ||
990 | |||
991 | /* | ||
992 | * 3D Undocumented = 0 (0x00) 00000000 | ||
993 | * 3D[7:0] "It's a secret" | ||
994 | * = 0 (0x00) 00000000 | ||
995 | */ | ||
996 | { 0x3D, 0x00 }, | ||
997 | |||
998 | /* | ||
999 | * 3E Undocumented = 0 (0x00) 00000000 | ||
1000 | * 3E[7:0] "It's a secret" | ||
1001 | * = 0 (0x00) 00000000 | ||
1002 | */ | ||
1003 | { 0x3E, 0x00 }, | ||
1004 | |||
1005 | /* | ||
1006 | * 3B FREFB "Internal Reference Adjustment" | ||
1007 | * = 24 (0x18) 00011000 | ||
1008 | * FREFB[7:0] "Range" | ||
1009 | * = 24 (0x18) 00011000 | ||
1010 | */ | ||
1011 | { 0x3b, 0x18 }, | ||
1012 | |||
1013 | /* | ||
1014 | * 33 CHLF "Current Control" | ||
1015 | * = 25 (0x19) 00011001 | ||
1016 | * CHLF[7:6] "Sensor current control" | ||
1017 | * = 0 (0x00) 00...... | ||
1018 | * CHLF[5] "Sensor current range control" | ||
1019 | * = 0 (0x00) ..0..... "normal range" | ||
1020 | * CHLF[4] "Sensor current" | ||
1021 | * = 1 (0x01) ...1.... "double current" | ||
1022 | * CHLF[3] "Sensor buffer current control" | ||
1023 | * = 1 (0x01) ....1... "half current" | ||
1024 | * CHLF[2] "Column buffer current control" | ||
1025 | * = 0 (0x00) .....0.. "normal current" | ||
1026 | * CHLF[1] "Analog DSP current control" | ||
1027 | * = 0 (0x00) ......0. "normal current" | ||
1028 | * CHLF[1] "ADC current control" | ||
1029 | * = 0 (0x00) ......0. "normal current" | ||
1030 | */ | ||
1031 | { 0x33, 0x19 }, | ||
1032 | |||
1033 | /* | ||
1034 | * 34 VBLM "Blooming Control" | ||
1035 | * = 90 (0x5A) 01011010 | ||
1036 | * VBLM[7] "Hard soft reset switch" | ||
1037 | * = 0 (0x00) 0....... "Hard reset" | ||
1038 | * VBLM[6:4] "Blooming voltage selection" | ||
1039 | * = 5 (0x05) .101.... | ||
1040 | * VBLM[3:0] "Sensor current control" | ||
1041 | * = 10 (0x0A) ....1010 | ||
1042 | */ | ||
1043 | { 0x34, 0x5A }, | ||
1044 | |||
1045 | /* | ||
1046 | * 3B FREFB "Internal Reference Adjustment" | ||
1047 | * = 0 (0x00) 00000000 | ||
1048 | * FREFB[7:0] "Range" | ||
1049 | * = 0 (0x00) 00000000 | ||
1050 | */ | ||
1051 | { 0x3b, 0x00 }, | ||
1052 | |||
1053 | /* | ||
1054 | * 33 CHLF "Current Control" | ||
1055 | * = 9 (0x09) 00001001 | ||
1056 | * CHLF[7:6] "Sensor current control" | ||
1057 | * = 0 (0x00) 00...... | ||
1058 | * CHLF[5] "Sensor current range control" | ||
1059 | * = 0 (0x00) ..0..... "normal range" | ||
1060 | * CHLF[4] "Sensor current" | ||
1061 | * = 0 (0x00) ...0.... "normal current" | ||
1062 | * CHLF[3] "Sensor buffer current control" | ||
1063 | * = 1 (0x01) ....1... "half current" | ||
1064 | * CHLF[2] "Column buffer current control" | ||
1065 | * = 0 (0x00) .....0.. "normal current" | ||
1066 | * CHLF[1] "Analog DSP current control" | ||
1067 | * = 0 (0x00) ......0. "normal current" | ||
1068 | * CHLF[1] "ADC current control" | ||
1069 | * = 0 (0x00) ......0. "normal current" | ||
1070 | */ | ||
1071 | { 0x33, 0x09 }, | ||
1072 | |||
1073 | /* | ||
1074 | * 34 VBLM "Blooming Control" | ||
1075 | * = 80 (0x50) 01010000 | ||
1076 | * VBLM[7] "Hard soft reset switch" | ||
1077 | * = 0 (0x00) 0....... "Hard reset" | ||
1078 | * VBLM[6:4] "Blooming voltage selection" | ||
1079 | * = 5 (0x05) .101.... | ||
1080 | * VBLM[3:0] "Sensor current control" | ||
1081 | * = 0 (0x00) ....0000 | ||
1082 | */ | ||
1083 | { 0x34, 0x50 }, | ||
1084 | |||
1085 | /* | ||
1086 | * 12 COMH "Common Control H" | ||
1087 | * = 64 (0x40) 01000000 | ||
1088 | * COMH[7] "SRST" | ||
1089 | * = 0 (0x00) 0....... "No-op" | ||
1090 | * COMH[6:4] "Resolution selection" | ||
1091 | * = 4 (0x04) .100.... "XGA" | ||
1092 | * COMH[3] "Master slave selection" | ||
1093 | * = 0 (0x00) ....0... "Master mode" | ||
1094 | * COMH[2] "Internal B/R channel option" | ||
1095 | * = 0 (0x00) .....0.. "B/R use same channel" | ||
1096 | * COMH[1] "Color bar test pattern" | ||
1097 | * = 0 (0x00) ......0. "Off" | ||
1098 | * COMH[0] "Reserved" | ||
1099 | * = 0 (0x00) .......0 | ||
1100 | */ | ||
1101 | { 0x12, 0x40 }, | ||
1102 | |||
1103 | /* | ||
1104 | * 17 HREFST "Horizontal window start" | ||
1105 | * = 31 (0x1F) 00011111 | ||
1106 | * HREFST[7:0] "Horizontal window start, 8 MSBs" | ||
1107 | * = 31 (0x1F) 00011111 | ||
1108 | */ | ||
1109 | { 0x17, 0x1F }, | ||
1110 | |||
1111 | /* | ||
1112 | * 18 HREFEND "Horizontal window end" | ||
1113 | * = 95 (0x5F) 01011111 | ||
1114 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" | ||
1115 | * = 95 (0x5F) 01011111 | ||
1116 | */ | ||
1117 | { 0x18, 0x5F }, | ||
1118 | |||
1119 | /* | ||
1120 | * 19 VSTRT "Vertical window start" | ||
1121 | * = 0 (0x00) 00000000 | ||
1122 | * VSTRT[7:0] "Vertical Window Start, 8 MSBs" | ||
1123 | * = 0 (0x00) 00000000 | ||
1124 | */ | ||
1125 | { 0x19, 0x00 }, | ||
1126 | |||
1127 | /* | ||
1128 | * 1A VEND "Vertical window end" | ||
1129 | * = 96 (0x60) 01100000 | ||
1130 | * VEND[7:0] "Vertical Window End, 8 MSBs" | ||
1131 | * = 96 (0x60) 01100000 | ||
1132 | */ | ||
1133 | { 0x1a, 0x60 }, | ||
1134 | |||
1135 | /* | ||
1136 | * 32 COMM "Common Control M" | ||
1137 | * = 18 (0x12) 00010010 | ||
1138 | * COMM[7:6] "Pixel clock divide option" | ||
1139 | * = 0 (0x00) 00...... "/1" | ||
1140 | * COMM[5:3] "Horizontal window end position, 3 LSBs" | ||
1141 | * = 2 (0x02) ..010... | ||
1142 | * COMM[2:0] "Horizontal window start position, 3 LSBs" | ||
1143 | * = 2 (0x02) .....010 | ||
1144 | */ | ||
1145 | { 0x32, 0x12 }, | ||
1146 | |||
1147 | /* | ||
1148 | * 03 COMA "Common Control A" | ||
1149 | * = 74 (0x4A) 01001010 | ||
1150 | * COMA[7:4] "AWB Update Threshold" | ||
1151 | * = 4 (0x04) 0100.... | ||
1152 | * COMA[3:2] "Vertical window end line control 2 LSBs" | ||
1153 | * = 2 (0x02) ....10.. | ||
1154 | * COMA[1:0] "Vertical window start line control 2 LSBs" | ||
1155 | * = 2 (0x02) ......10 | ||
1156 | */ | ||
1157 | { 0x03, 0x4A }, | ||
1158 | |||
1159 | /* | ||
1160 | * 11 CLKRC "Clock Rate Control" | ||
1161 | * = 128 (0x80) 10000000 | ||
1162 | * CLKRC[7] "Internal frequency doublers on off seclection" | ||
1163 | * = 1 (0x01) 1....... "On" | ||
1164 | * CLKRC[6] "Digital video master slave selection" | ||
1165 | * = 0 (0x00) .0...... "Master mode, sensor | ||
1166 | * provides PCLK" | ||
1167 | * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }" | ||
1168 | * = 0 (0x00) ..000000 | ||
1169 | */ | ||
1170 | { 0x11, 0x80 }, | ||
1171 | |||
1172 | /* | ||
1173 | * 12 COMH "Common Control H" | ||
1174 | * = 0 (0x00) 00000000 | ||
1175 | * COMH[7] "SRST" | ||
1176 | * = 0 (0x00) 0....... "No-op" | ||
1177 | * COMH[6:4] "Resolution selection" | ||
1178 | * = 0 (0x00) .000.... "QXGA" | ||
1179 | * COMH[3] "Master slave selection" | ||
1180 | * = 0 (0x00) ....0... "Master mode" | ||
1181 | * COMH[2] "Internal B/R channel option" | ||
1182 | * = 0 (0x00) .....0.. "B/R use same channel" | ||
1183 | * COMH[1] "Color bar test pattern" | ||
1184 | * = 0 (0x00) ......0. "Off" | ||
1185 | * COMH[0] "Reserved" | ||
1186 | * = 0 (0x00) .......0 | ||
1187 | */ | ||
1188 | { 0x12, 0x00 }, | ||
1189 | |||
1190 | /* | ||
1191 | * 12 COMH "Common Control H" | ||
1192 | * = 64 (0x40) 01000000 | ||
1193 | * COMH[7] "SRST" | ||
1194 | * = 0 (0x00) 0....... "No-op" | ||
1195 | * COMH[6:4] "Resolution selection" | ||
1196 | * = 4 (0x04) .100.... "XGA" | ||
1197 | * COMH[3] "Master slave selection" | ||
1198 | * = 0 (0x00) ....0... "Master mode" | ||
1199 | * COMH[2] "Internal B/R channel option" | ||
1200 | * = 0 (0x00) .....0.. "B/R use same channel" | ||
1201 | * COMH[1] "Color bar test pattern" | ||
1202 | * = 0 (0x00) ......0. "Off" | ||
1203 | * COMH[0] "Reserved" | ||
1204 | * = 0 (0x00) .......0 | ||
1205 | */ | ||
1206 | { 0x12, 0x40 }, | ||
1207 | |||
1208 | /* | ||
1209 | * 17 HREFST "Horizontal window start" | ||
1210 | * = 31 (0x1F) 00011111 | ||
1211 | * HREFST[7:0] "Horizontal window start, 8 MSBs" | ||
1212 | * = 31 (0x1F) 00011111 | ||
1213 | */ | ||
1214 | { 0x17, 0x1F }, | ||
1215 | |||
1216 | /* | ||
1217 | * 18 HREFEND "Horizontal window end" | ||
1218 | * = 95 (0x5F) 01011111 | ||
1219 | * HREFEND[7:0] "Horizontal Window End, 8 MSBs" | ||
1220 | * = 95 (0x5F) 01011111 | ||
1221 | */ | ||
1222 | { 0x18, 0x5F }, | ||
1223 | |||
1224 | /* | ||
1225 | * 19 VSTRT "Vertical window start" | ||
1226 | * = 0 (0x00) 00000000 | ||
1227 | * VSTRT[7:0] "Vertical Window Start, 8 MSBs" | ||
1228 | * = 0 (0x00) 00000000 | ||
1229 | */ | ||
1230 | { 0x19, 0x00 }, | ||
1231 | |||
1232 | /* | ||
1233 | * 1A VEND "Vertical window end" | ||
1234 | * = 96 (0x60) 01100000 | ||
1235 | * VEND[7:0] "Vertical Window End, 8 MSBs" | ||
1236 | * = 96 (0x60) 01100000 | ||
1237 | */ | ||
1238 | { 0x1a, 0x60 }, | ||
1239 | |||
1240 | /* | ||
1241 | * 32 COMM "Common Control M" | ||
1242 | * = 18 (0x12) 00010010 | ||
1243 | * COMM[7:6] "Pixel clock divide option" | ||
1244 | * = 0 (0x00) 00...... "/1" | ||
1245 | * COMM[5:3] "Horizontal window end position, 3 LSBs" | ||
1246 | * = 2 (0x02) ..010... | ||
1247 | * COMM[2:0] "Horizontal window start position, 3 LSBs" | ||
1248 | * = 2 (0x02) .....010 | ||
1249 | */ | ||
1250 | { 0x32, 0x12 }, | ||
1251 | |||
1252 | /* | ||
1253 | * 03 COMA "Common Control A" | ||
1254 | * = 74 (0x4A) 01001010 | ||
1255 | * COMA[7:4] "AWB Update Threshold" | ||
1256 | * = 4 (0x04) 0100.... | ||
1257 | * COMA[3:2] "Vertical window end line control 2 LSBs" | ||
1258 | * = 2 (0x02) ....10.. | ||
1259 | * COMA[1:0] "Vertical window start line control 2 LSBs" | ||
1260 | * = 2 (0x02) ......10 | ||
1261 | */ | ||
1262 | { 0x03, 0x4A }, | ||
1263 | |||
1264 | /* | ||
1265 | * 02 RED "Red Gain Control" | ||
1266 | * = 175 (0xAF) 10101111 | ||
1267 | * RED[7] "Action" | ||
1268 | * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))" | ||
1269 | * RED[6:0] "Value" | ||
1270 | * = 47 (0x2F) .0101111 | ||
1271 | */ | ||
1272 | { 0x02, 0xAF }, | ||
1273 | |||
1274 | /* | ||
1275 | * 2D ADDVSL "VSYNC Pulse Width" | ||
1276 | * = 210 (0xD2) 11010010 | ||
1277 | * ADDVSL[7:0] "VSYNC pulse width, LSB" | ||
1278 | * = 210 (0xD2) 11010010 | ||
1279 | */ | ||
1280 | { 0x2d, 0xD2 }, | ||
1281 | |||
1282 | /* | ||
1283 | * 00 GAIN = 24 (0x18) 00011000 | ||
1284 | * GAIN[7:6] "Reserved" | ||
1285 | * = 0 (0x00) 00...... | ||
1286 | * GAIN[5] "Double" | ||
1287 | * = 0 (0x00) ..0..... "False" | ||
1288 | * GAIN[4] "Double" | ||
1289 | * = 1 (0x01) ...1.... "True" | ||
1290 | * GAIN[3:0] "Range" | ||
1291 | * = 8 (0x08) ....1000 | ||
1292 | */ | ||
1293 | { 0x00, 0x18 }, | ||
1294 | |||
1295 | /* | ||
1296 | * 01 BLUE "Blue Gain Control" | ||
1297 | * = 240 (0xF0) 11110000 | ||
1298 | * BLUE[7] "Action" | ||
1299 | * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))" | ||
1300 | * BLUE[6:0] "Value" | ||
1301 | * = 112 (0x70) .1110000 | ||
1302 | */ | ||
1303 | { 0x01, 0xF0 }, | ||
1304 | |||
1305 | /* | ||
1306 | * 10 AEC "Automatic Exposure Control" | ||
1307 | * = 10 (0x0A) 00001010 | ||
1308 | * AEC[7:0] "Automatic Exposure Control, 8 MSBs" | ||
1309 | * = 10 (0x0A) 00001010 | ||
1310 | */ | ||
1311 | { 0x10, 0x0A }, | ||
1312 | |||
1313 | { 0xE1, 0x67 }, | ||
1314 | { 0xE3, 0x03 }, | ||
1315 | { 0xE4, 0x26 }, | ||
1316 | { 0xE5, 0x3E }, | ||
1317 | { 0xF8, 0x01 }, | ||
1318 | { 0xFF, 0x01 }, | ||
1319 | }; | ||
1320 | |||
511 | static const struct ov_i2c_regvals norm_6x20[] = { | 1321 | static const struct ov_i2c_regvals norm_6x20[] = { |
512 | { 0x12, 0x80 }, /* reset */ | 1322 | { 0x12, 0x80 }, /* reset */ |
513 | { 0x11, 0x01 }, | 1323 | { 0x11, 0x01 }, |
@@ -678,6 +1488,7 @@ static const struct ov_i2c_regvals norm_7610[] = { | |||
678 | }; | 1488 | }; |
679 | 1489 | ||
680 | static const struct ov_i2c_regvals norm_7620[] = { | 1490 | static const struct ov_i2c_regvals norm_7620[] = { |
1491 | { 0x12, 0x80 }, /* reset */ | ||
681 | { 0x00, 0x00 }, /* gain */ | 1492 | { 0x00, 0x00 }, /* gain */ |
682 | { 0x01, 0x80 }, /* blue gain */ | 1493 | { 0x01, 0x80 }, /* blue gain */ |
683 | { 0x02, 0x80 }, /* red gain */ | 1494 | { 0x02, 0x80 }, /* red gain */ |
@@ -1042,10 +1853,28 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) | |||
1042 | } | 1853 | } |
1043 | 1854 | ||
1044 | /* Write a OV519 register */ | 1855 | /* Write a OV519 register */ |
1045 | static int reg_w(struct sd *sd, __u16 index, __u8 value) | 1856 | static int reg_w(struct sd *sd, __u16 index, __u16 value) |
1046 | { | 1857 | { |
1047 | int ret; | 1858 | int ret, req = 0; |
1048 | int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1; | 1859 | |
1860 | switch (sd->bridge) { | ||
1861 | case BRIDGE_OV511: | ||
1862 | case BRIDGE_OV511PLUS: | ||
1863 | req = 2; | ||
1864 | break; | ||
1865 | case BRIDGE_OVFX2: | ||
1866 | req = 0x0a; | ||
1867 | /* fall through */ | ||
1868 | case BRIDGE_W9968CF: | ||
1869 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
1870 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | ||
1871 | req, | ||
1872 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
1873 | value, index, NULL, 0, 500); | ||
1874 | goto leave; | ||
1875 | default: | ||
1876 | req = 1; | ||
1877 | } | ||
1049 | 1878 | ||
1050 | sd->gspca_dev.usb_buf[0] = value; | 1879 | sd->gspca_dev.usb_buf[0] = value; |
1051 | ret = usb_control_msg(sd->gspca_dev.dev, | 1880 | ret = usb_control_msg(sd->gspca_dev.dev, |
@@ -1054,17 +1883,35 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) | |||
1054 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 1883 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
1055 | 0, index, | 1884 | 0, index, |
1056 | sd->gspca_dev.usb_buf, 1, 500); | 1885 | sd->gspca_dev.usb_buf, 1, 500); |
1057 | if (ret < 0) | 1886 | leave: |
1058 | PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); | 1887 | if (ret < 0) { |
1059 | return ret; | 1888 | PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed", |
1889 | value, index); | ||
1890 | return ret; | ||
1891 | } | ||
1892 | |||
1893 | PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index); | ||
1894 | return 0; | ||
1060 | } | 1895 | } |
1061 | 1896 | ||
1062 | /* Read from a OV519 register */ | 1897 | /* Read from a OV519 register, note not valid for the w9968cf!! */ |
1063 | /* returns: negative is error, pos or zero is data */ | 1898 | /* returns: negative is error, pos or zero is data */ |
1064 | static int reg_r(struct sd *sd, __u16 index) | 1899 | static int reg_r(struct sd *sd, __u16 index) |
1065 | { | 1900 | { |
1066 | int ret; | 1901 | int ret; |
1067 | int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1; | 1902 | int req; |
1903 | |||
1904 | switch (sd->bridge) { | ||
1905 | case BRIDGE_OV511: | ||
1906 | case BRIDGE_OV511PLUS: | ||
1907 | req = 3; | ||
1908 | break; | ||
1909 | case BRIDGE_OVFX2: | ||
1910 | req = 0x0b; | ||
1911 | break; | ||
1912 | default: | ||
1913 | req = 1; | ||
1914 | } | ||
1068 | 1915 | ||
1069 | ret = usb_control_msg(sd->gspca_dev.dev, | 1916 | ret = usb_control_msg(sd->gspca_dev.dev, |
1070 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | 1917 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), |
@@ -1072,10 +1919,12 @@ static int reg_r(struct sd *sd, __u16 index) | |||
1072 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 1919 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
1073 | 0, index, sd->gspca_dev.usb_buf, 1, 500); | 1920 | 0, index, sd->gspca_dev.usb_buf, 1, 500); |
1074 | 1921 | ||
1075 | if (ret >= 0) | 1922 | if (ret >= 0) { |
1076 | ret = sd->gspca_dev.usb_buf[0]; | 1923 | ret = sd->gspca_dev.usb_buf[0]; |
1077 | else | 1924 | PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret); |
1925 | } else | ||
1078 | PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); | 1926 | PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); |
1927 | |||
1079 | return ret; | 1928 | return ret; |
1080 | } | 1929 | } |
1081 | 1930 | ||
@@ -1095,6 +1944,7 @@ static int reg_r8(struct sd *sd, | |||
1095 | ret = sd->gspca_dev.usb_buf[0]; | 1944 | ret = sd->gspca_dev.usb_buf[0]; |
1096 | else | 1945 | else |
1097 | PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); | 1946 | PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); |
1947 | |||
1098 | return ret; | 1948 | return ret; |
1099 | } | 1949 | } |
1100 | 1950 | ||
@@ -1140,9 +1990,12 @@ static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n) | |||
1140 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 1990 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
1141 | 0, index, | 1991 | 0, index, |
1142 | sd->gspca_dev.usb_buf, n, 500); | 1992 | sd->gspca_dev.usb_buf, n, 500); |
1143 | if (ret < 0) | 1993 | if (ret < 0) { |
1144 | PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); | 1994 | PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value); |
1145 | return ret; | 1995 | return ret; |
1996 | } | ||
1997 | |||
1998 | return 0; | ||
1146 | } | 1999 | } |
1147 | 2000 | ||
1148 | static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) | 2001 | static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value) |
@@ -1324,32 +2177,110 @@ static int ov518_i2c_r(struct sd *sd, __u8 reg) | |||
1324 | return value; | 2177 | return value; |
1325 | } | 2178 | } |
1326 | 2179 | ||
2180 | static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value) | ||
2181 | { | ||
2182 | int ret; | ||
2183 | |||
2184 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
2185 | usb_sndctrlpipe(sd->gspca_dev.dev, 0), | ||
2186 | 0x02, | ||
2187 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
2188 | (__u16)value, (__u16)reg, NULL, 0, 500); | ||
2189 | |||
2190 | if (ret < 0) { | ||
2191 | PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg); | ||
2192 | return ret; | ||
2193 | } | ||
2194 | |||
2195 | PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); | ||
2196 | return 0; | ||
2197 | } | ||
2198 | |||
2199 | static int ovfx2_i2c_r(struct sd *sd, __u8 reg) | ||
2200 | { | ||
2201 | int ret; | ||
2202 | |||
2203 | ret = usb_control_msg(sd->gspca_dev.dev, | ||
2204 | usb_rcvctrlpipe(sd->gspca_dev.dev, 0), | ||
2205 | 0x03, | ||
2206 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
2207 | 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500); | ||
2208 | |||
2209 | if (ret >= 0) { | ||
2210 | ret = sd->gspca_dev.usb_buf[0]; | ||
2211 | PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret); | ||
2212 | } else | ||
2213 | PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg); | ||
2214 | |||
2215 | return ret; | ||
2216 | } | ||
2217 | |||
1327 | static int i2c_w(struct sd *sd, __u8 reg, __u8 value) | 2218 | static int i2c_w(struct sd *sd, __u8 reg, __u8 value) |
1328 | { | 2219 | { |
2220 | int ret = -1; | ||
2221 | |||
2222 | if (sd->sensor_reg_cache[reg] == value) | ||
2223 | return 0; | ||
2224 | |||
1329 | switch (sd->bridge) { | 2225 | switch (sd->bridge) { |
1330 | case BRIDGE_OV511: | 2226 | case BRIDGE_OV511: |
1331 | case BRIDGE_OV511PLUS: | 2227 | case BRIDGE_OV511PLUS: |
1332 | return ov511_i2c_w(sd, reg, value); | 2228 | ret = ov511_i2c_w(sd, reg, value); |
2229 | break; | ||
1333 | case BRIDGE_OV518: | 2230 | case BRIDGE_OV518: |
1334 | case BRIDGE_OV518PLUS: | 2231 | case BRIDGE_OV518PLUS: |
1335 | case BRIDGE_OV519: | 2232 | case BRIDGE_OV519: |
1336 | return ov518_i2c_w(sd, reg, value); | 2233 | ret = ov518_i2c_w(sd, reg, value); |
2234 | break; | ||
2235 | case BRIDGE_OVFX2: | ||
2236 | ret = ovfx2_i2c_w(sd, reg, value); | ||
2237 | break; | ||
2238 | case BRIDGE_W9968CF: | ||
2239 | ret = w9968cf_i2c_w(sd, reg, value); | ||
2240 | break; | ||
1337 | } | 2241 | } |
1338 | return -1; /* Should never happen */ | 2242 | |
2243 | if (ret >= 0) { | ||
2244 | /* Up on sensor reset empty the register cache */ | ||
2245 | if (reg == 0x12 && (value & 0x80)) | ||
2246 | memset(sd->sensor_reg_cache, -1, | ||
2247 | sizeof(sd->sensor_reg_cache)); | ||
2248 | else | ||
2249 | sd->sensor_reg_cache[reg] = value; | ||
2250 | } | ||
2251 | |||
2252 | return ret; | ||
1339 | } | 2253 | } |
1340 | 2254 | ||
1341 | static int i2c_r(struct sd *sd, __u8 reg) | 2255 | static int i2c_r(struct sd *sd, __u8 reg) |
1342 | { | 2256 | { |
2257 | int ret = -1; | ||
2258 | |||
2259 | if (sd->sensor_reg_cache[reg] != -1) | ||
2260 | return sd->sensor_reg_cache[reg]; | ||
2261 | |||
1343 | switch (sd->bridge) { | 2262 | switch (sd->bridge) { |
1344 | case BRIDGE_OV511: | 2263 | case BRIDGE_OV511: |
1345 | case BRIDGE_OV511PLUS: | 2264 | case BRIDGE_OV511PLUS: |
1346 | return ov511_i2c_r(sd, reg); | 2265 | ret = ov511_i2c_r(sd, reg); |
2266 | break; | ||
1347 | case BRIDGE_OV518: | 2267 | case BRIDGE_OV518: |
1348 | case BRIDGE_OV518PLUS: | 2268 | case BRIDGE_OV518PLUS: |
1349 | case BRIDGE_OV519: | 2269 | case BRIDGE_OV519: |
1350 | return ov518_i2c_r(sd, reg); | 2270 | ret = ov518_i2c_r(sd, reg); |
2271 | break; | ||
2272 | case BRIDGE_OVFX2: | ||
2273 | ret = ovfx2_i2c_r(sd, reg); | ||
2274 | break; | ||
2275 | case BRIDGE_W9968CF: | ||
2276 | ret = w9968cf_i2c_r(sd, reg); | ||
2277 | break; | ||
1351 | } | 2278 | } |
1352 | return -1; /* Should never happen */ | 2279 | |
2280 | if (ret >= 0) | ||
2281 | sd->sensor_reg_cache[reg] = ret; | ||
2282 | |||
2283 | return ret; | ||
1353 | } | 2284 | } |
1354 | 2285 | ||
1355 | /* Writes bits at positions specified by mask to an I2C reg. Bits that are in | 2286 | /* Writes bits at positions specified by mask to an I2C reg. Bits that are in |
@@ -1389,6 +2320,10 @@ static inline int ov51x_stop(struct sd *sd) | |||
1389 | return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); | 2320 | return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a); |
1390 | case BRIDGE_OV519: | 2321 | case BRIDGE_OV519: |
1391 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); | 2322 | return reg_w(sd, OV519_SYS_RESET1, 0x0f); |
2323 | case BRIDGE_OVFX2: | ||
2324 | return reg_w_mask(sd, 0x0f, 0x00, 0x02); | ||
2325 | case BRIDGE_W9968CF: | ||
2326 | return reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */ | ||
1392 | } | 2327 | } |
1393 | 2328 | ||
1394 | return 0; | 2329 | return 0; |
@@ -1418,18 +2353,27 @@ static inline int ov51x_restart(struct sd *sd) | |||
1418 | return reg_w(sd, R51x_SYS_RESET, 0x00); | 2353 | return reg_w(sd, R51x_SYS_RESET, 0x00); |
1419 | case BRIDGE_OV519: | 2354 | case BRIDGE_OV519: |
1420 | return reg_w(sd, OV519_SYS_RESET1, 0x00); | 2355 | return reg_w(sd, OV519_SYS_RESET1, 0x00); |
2356 | case BRIDGE_OVFX2: | ||
2357 | return reg_w_mask(sd, 0x0f, 0x02, 0x02); | ||
2358 | case BRIDGE_W9968CF: | ||
2359 | return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */ | ||
1421 | } | 2360 | } |
1422 | 2361 | ||
1423 | return 0; | 2362 | return 0; |
1424 | } | 2363 | } |
1425 | 2364 | ||
2365 | static int ov51x_set_slave_ids(struct sd *sd, __u8 slave); | ||
2366 | |||
1426 | /* This does an initial reset of an OmniVision sensor and ensures that I2C | 2367 | /* This does an initial reset of an OmniVision sensor and ensures that I2C |
1427 | * is synchronized. Returns <0 on failure. | 2368 | * is synchronized. Returns <0 on failure. |
1428 | */ | 2369 | */ |
1429 | static int init_ov_sensor(struct sd *sd) | 2370 | static int init_ov_sensor(struct sd *sd, __u8 slave) |
1430 | { | 2371 | { |
1431 | int i; | 2372 | int i; |
1432 | 2373 | ||
2374 | if (ov51x_set_slave_ids(sd, slave) < 0) | ||
2375 | return -EIO; | ||
2376 | |||
1433 | /* Reset the sensor */ | 2377 | /* Reset the sensor */ |
1434 | if (i2c_w(sd, 0x12, 0x80) < 0) | 2378 | if (i2c_w(sd, 0x12, 0x80) < 0) |
1435 | return -EIO; | 2379 | return -EIO; |
@@ -1466,6 +2410,14 @@ static int ov51x_set_slave_ids(struct sd *sd, | |||
1466 | { | 2410 | { |
1467 | int rc; | 2411 | int rc; |
1468 | 2412 | ||
2413 | switch (sd->bridge) { | ||
2414 | case BRIDGE_OVFX2: | ||
2415 | return reg_w(sd, OVFX2_I2C_ADDR, slave); | ||
2416 | case BRIDGE_W9968CF: | ||
2417 | sd->sensor_addr = slave; | ||
2418 | return 0; | ||
2419 | } | ||
2420 | |||
1469 | rc = reg_w(sd, R51x_I2C_W_SID, slave); | 2421 | rc = reg_w(sd, R51x_I2C_W_SID, slave); |
1470 | if (rc < 0) | 2422 | if (rc < 0) |
1471 | return rc; | 2423 | return rc; |
@@ -1508,6 +2460,39 @@ static int write_i2c_regvals(struct sd *sd, | |||
1508 | * | 2460 | * |
1509 | ***************************************************************************/ | 2461 | ***************************************************************************/ |
1510 | 2462 | ||
2463 | /* This initializes the OV2x10 / OV3610 / OV3620 */ | ||
2464 | static int ov_hires_configure(struct sd *sd) | ||
2465 | { | ||
2466 | int high, low; | ||
2467 | |||
2468 | if (sd->bridge != BRIDGE_OVFX2) { | ||
2469 | PDEBUG(D_ERR, "error hires sensors only supported with ovfx2"); | ||
2470 | return -1; | ||
2471 | } | ||
2472 | |||
2473 | PDEBUG(D_PROBE, "starting ov hires configuration"); | ||
2474 | |||
2475 | /* Detect sensor (sub)type */ | ||
2476 | high = i2c_r(sd, 0x0a); | ||
2477 | low = i2c_r(sd, 0x0b); | ||
2478 | /* info("%x, %x", high, low); */ | ||
2479 | if (high == 0x96 && low == 0x40) { | ||
2480 | PDEBUG(D_PROBE, "Sensor is an OV2610"); | ||
2481 | sd->sensor = SEN_OV2610; | ||
2482 | } else if (high == 0x36 && (low & 0x0f) == 0x00) { | ||
2483 | PDEBUG(D_PROBE, "Sensor is an OV3610"); | ||
2484 | sd->sensor = SEN_OV3610; | ||
2485 | } else { | ||
2486 | PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x", | ||
2487 | high, low); | ||
2488 | return -1; | ||
2489 | } | ||
2490 | |||
2491 | /* Set sensor-specific vars */ | ||
2492 | return 0; | ||
2493 | } | ||
2494 | |||
2495 | |||
1511 | /* This initializes the OV8110, OV8610 sensor. The OV8110 uses | 2496 | /* This initializes the OV8110, OV8610 sensor. The OV8110 uses |
1512 | * the same register settings as the OV8610, since they are very similar. | 2497 | * the same register settings as the OV8610, since they are very similar. |
1513 | */ | 2498 | */ |
@@ -1966,12 +2951,29 @@ static int ov519_configure(struct sd *sd) | |||
1966 | return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); | 2951 | return write_regvals(sd, init_519, ARRAY_SIZE(init_519)); |
1967 | } | 2952 | } |
1968 | 2953 | ||
2954 | static int ovfx2_configure(struct sd *sd) | ||
2955 | { | ||
2956 | static const struct ov_regvals init_fx2[] = { | ||
2957 | { 0x00, 0x60 }, | ||
2958 | { 0x02, 0x01 }, | ||
2959 | { 0x0f, 0x1d }, | ||
2960 | { 0xe9, 0x82 }, | ||
2961 | { 0xea, 0xc7 }, | ||
2962 | { 0xeb, 0x10 }, | ||
2963 | { 0xec, 0xf6 }, | ||
2964 | }; | ||
2965 | |||
2966 | sd->stopped = 1; | ||
2967 | |||
2968 | return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2)); | ||
2969 | } | ||
2970 | |||
1969 | /* this function is called at probe time */ | 2971 | /* this function is called at probe time */ |
1970 | static int sd_config(struct gspca_dev *gspca_dev, | 2972 | static int sd_config(struct gspca_dev *gspca_dev, |
1971 | const struct usb_device_id *id) | 2973 | const struct usb_device_id *id) |
1972 | { | 2974 | { |
1973 | struct sd *sd = (struct sd *) gspca_dev; | 2975 | struct sd *sd = (struct sd *) gspca_dev; |
1974 | struct cam *cam; | 2976 | struct cam *cam = &gspca_dev->cam; |
1975 | int ret = 0; | 2977 | int ret = 0; |
1976 | 2978 | ||
1977 | sd->bridge = id->driver_info & BRIDGE_MASK; | 2979 | sd->bridge = id->driver_info & BRIDGE_MASK; |
@@ -1989,6 +2991,16 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1989 | case BRIDGE_OV519: | 2991 | case BRIDGE_OV519: |
1990 | ret = ov519_configure(sd); | 2992 | ret = ov519_configure(sd); |
1991 | break; | 2993 | break; |
2994 | case BRIDGE_OVFX2: | ||
2995 | ret = ovfx2_configure(sd); | ||
2996 | cam->bulk_size = OVFX2_BULK_SIZE; | ||
2997 | cam->bulk_nurbs = MAX_NURBS; | ||
2998 | cam->bulk = 1; | ||
2999 | break; | ||
3000 | case BRIDGE_W9968CF: | ||
3001 | ret = w9968cf_configure(sd); | ||
3002 | cam->reverse_alts = 1; | ||
3003 | break; | ||
1992 | } | 3004 | } |
1993 | 3005 | ||
1994 | if (ret) | 3006 | if (ret) |
@@ -1996,49 +3008,39 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1996 | 3008 | ||
1997 | ov51x_led_control(sd, 0); /* turn LED off */ | 3009 | ov51x_led_control(sd, 0); /* turn LED off */ |
1998 | 3010 | ||
1999 | /* Test for 76xx */ | ||
2000 | if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0) | ||
2001 | goto error; | ||
2002 | |||
2003 | /* The OV519 must be more aggressive about sensor detection since | 3011 | /* The OV519 must be more aggressive about sensor detection since |
2004 | * I2C write will never fail if the sensor is not present. We have | 3012 | * I2C write will never fail if the sensor is not present. We have |
2005 | * to try to initialize the sensor to detect its presence */ | 3013 | * to try to initialize the sensor to detect its presence */ |
2006 | if (init_ov_sensor(sd) >= 0) { | 3014 | |
3015 | /* Test for 76xx */ | ||
3016 | if (init_ov_sensor(sd, OV7xx0_SID) >= 0) { | ||
2007 | if (ov7xx0_configure(sd) < 0) { | 3017 | if (ov7xx0_configure(sd) < 0) { |
2008 | PDEBUG(D_ERR, "Failed to configure OV7xx0"); | 3018 | PDEBUG(D_ERR, "Failed to configure OV7xx0"); |
2009 | goto error; | 3019 | goto error; |
2010 | } | 3020 | } |
2011 | } else { | 3021 | /* Test for 6xx0 */ |
2012 | 3022 | } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) { | |
2013 | /* Test for 6xx0 */ | 3023 | if (ov6xx0_configure(sd) < 0) { |
2014 | if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0) | 3024 | PDEBUG(D_ERR, "Failed to configure OV6xx0"); |
3025 | goto error; | ||
3026 | } | ||
3027 | /* Test for 8xx0 */ | ||
3028 | } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) { | ||
3029 | if (ov8xx0_configure(sd) < 0) { | ||
3030 | PDEBUG(D_ERR, "Failed to configure OV8xx0"); | ||
2015 | goto error; | 3031 | goto error; |
2016 | |||
2017 | if (init_ov_sensor(sd) >= 0) { | ||
2018 | if (ov6xx0_configure(sd) < 0) { | ||
2019 | PDEBUG(D_ERR, "Failed to configure OV6xx0"); | ||
2020 | goto error; | ||
2021 | } | ||
2022 | } else { | ||
2023 | |||
2024 | /* Test for 8xx0 */ | ||
2025 | if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0) | ||
2026 | goto error; | ||
2027 | |||
2028 | if (init_ov_sensor(sd) < 0) { | ||
2029 | PDEBUG(D_ERR, | ||
2030 | "Can't determine sensor slave IDs"); | ||
2031 | goto error; | ||
2032 | } | ||
2033 | if (ov8xx0_configure(sd) < 0) { | ||
2034 | PDEBUG(D_ERR, | ||
2035 | "Failed to configure OV8xx0 sensor"); | ||
2036 | goto error; | ||
2037 | } | ||
2038 | } | 3032 | } |
3033 | /* Test for 3xxx / 2xxx */ | ||
3034 | } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) { | ||
3035 | if (ov_hires_configure(sd) < 0) { | ||
3036 | PDEBUG(D_ERR, "Failed to configure high res OV"); | ||
3037 | goto error; | ||
3038 | } | ||
3039 | } else { | ||
3040 | PDEBUG(D_ERR, "Can't determine sensor slave IDs"); | ||
3041 | goto error; | ||
2039 | } | 3042 | } |
2040 | 3043 | ||
2041 | cam = &gspca_dev->cam; | ||
2042 | switch (sd->bridge) { | 3044 | switch (sd->bridge) { |
2043 | case BRIDGE_OV511: | 3045 | case BRIDGE_OV511: |
2044 | case BRIDGE_OV511PLUS: | 3046 | case BRIDGE_OV511PLUS: |
@@ -2069,6 +3071,31 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2069 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | 3071 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); |
2070 | } | 3072 | } |
2071 | break; | 3073 | break; |
3074 | case BRIDGE_OVFX2: | ||
3075 | if (sd->sensor == SEN_OV2610) { | ||
3076 | cam->cam_mode = ovfx2_ov2610_mode; | ||
3077 | cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode); | ||
3078 | } else if (sd->sensor == SEN_OV3610) { | ||
3079 | cam->cam_mode = ovfx2_ov3610_mode; | ||
3080 | cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); | ||
3081 | } else if (!sd->sif) { | ||
3082 | cam->cam_mode = ov519_vga_mode; | ||
3083 | cam->nmodes = ARRAY_SIZE(ov519_vga_mode); | ||
3084 | } else { | ||
3085 | cam->cam_mode = ov519_sif_mode; | ||
3086 | cam->nmodes = ARRAY_SIZE(ov519_sif_mode); | ||
3087 | } | ||
3088 | break; | ||
3089 | case BRIDGE_W9968CF: | ||
3090 | cam->cam_mode = w9968cf_vga_mode; | ||
3091 | cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode); | ||
3092 | if (sd->sif) | ||
3093 | cam->nmodes--; | ||
3094 | |||
3095 | /* w9968cf needs initialisation once the sensor is known */ | ||
3096 | if (w9968cf_init(sd) < 0) | ||
3097 | goto error; | ||
3098 | break; | ||
2072 | } | 3099 | } |
2073 | sd->brightness = BRIGHTNESS_DEF; | 3100 | sd->brightness = BRIGHTNESS_DEF; |
2074 | if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF) | 3101 | if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF) |
@@ -2087,11 +3114,15 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
2087 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | | 3114 | gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | |
2088 | (1 << OV7670_FREQ_IDX); | 3115 | (1 << OV7670_FREQ_IDX); |
2089 | } | 3116 | } |
3117 | sd->quality = QUALITY_DEF; | ||
2090 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) | 3118 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) |
2091 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; | 3119 | gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX; |
2092 | /* OV8610 Frequency filter control should work but needs testing */ | 3120 | /* OV8610 Frequency filter control should work but needs testing */ |
2093 | if (sd->sensor == SEN_OV8610) | 3121 | if (sd->sensor == SEN_OV8610) |
2094 | gspca_dev->ctrl_dis |= 1 << FREQ_IDX; | 3122 | gspca_dev->ctrl_dis |= 1 << FREQ_IDX; |
3123 | /* No controls for the OV2610/OV3610 */ | ||
3124 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | ||
3125 | gspca_dev->ctrl_dis |= 0xFF; | ||
2095 | 3126 | ||
2096 | return 0; | 3127 | return 0; |
2097 | error: | 3128 | error: |
@@ -2106,6 +3137,20 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
2106 | 3137 | ||
2107 | /* initialize the sensor */ | 3138 | /* initialize the sensor */ |
2108 | switch (sd->sensor) { | 3139 | switch (sd->sensor) { |
3140 | case SEN_OV2610: | ||
3141 | if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610))) | ||
3142 | return -EIO; | ||
3143 | /* Enable autogain, autoexpo, awb, bandfilter */ | ||
3144 | if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0) | ||
3145 | return -EIO; | ||
3146 | break; | ||
3147 | case SEN_OV3610: | ||
3148 | if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b))) | ||
3149 | return -EIO; | ||
3150 | /* Enable autogain, autoexpo, awb, bandfilter */ | ||
3151 | if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0) | ||
3152 | return -EIO; | ||
3153 | break; | ||
2109 | case SEN_OV6620: | 3154 | case SEN_OV6620: |
2110 | if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) | 3155 | if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) |
2111 | return -EIO; | 3156 | return -EIO; |
@@ -2548,19 +3593,60 @@ static int ov519_mode_init_regs(struct sd *sd) | |||
2548 | static int mode_init_ov_sensor_regs(struct sd *sd) | 3593 | static int mode_init_ov_sensor_regs(struct sd *sd) |
2549 | { | 3594 | { |
2550 | struct gspca_dev *gspca_dev; | 3595 | struct gspca_dev *gspca_dev; |
2551 | int qvga; | 3596 | int qvga, xstart, xend, ystart, yend; |
3597 | __u8 v; | ||
2552 | 3598 | ||
2553 | gspca_dev = &sd->gspca_dev; | 3599 | gspca_dev = &sd->gspca_dev; |
2554 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; | 3600 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; |
2555 | 3601 | ||
2556 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ | 3602 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ |
2557 | switch (sd->sensor) { | 3603 | switch (sd->sensor) { |
3604 | case SEN_OV2610: | ||
3605 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
3606 | i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); | ||
3607 | i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); | ||
3608 | i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); | ||
3609 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); | ||
3610 | i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); | ||
3611 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); | ||
3612 | return 0; | ||
3613 | case SEN_OV3610: | ||
3614 | if (qvga) { | ||
3615 | xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); | ||
3616 | ystart = (776 - gspca_dev->height) / 2; | ||
3617 | } else { | ||
3618 | xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4); | ||
3619 | ystart = (1544 - gspca_dev->height) / 2; | ||
3620 | } | ||
3621 | xend = xstart + gspca_dev->width; | ||
3622 | yend = ystart + gspca_dev->height; | ||
3623 | /* Writing to the COMH register resets the other windowing regs | ||
3624 | to their default values, so we must do this first. */ | ||
3625 | i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0); | ||
3626 | i2c_w_mask(sd, 0x32, | ||
3627 | (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7), | ||
3628 | 0x3f); | ||
3629 | i2c_w_mask(sd, 0x03, | ||
3630 | (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3), | ||
3631 | 0x0f); | ||
3632 | i2c_w(sd, 0x17, xstart >> 4); | ||
3633 | i2c_w(sd, 0x18, xend >> 4); | ||
3634 | i2c_w(sd, 0x19, ystart >> 3); | ||
3635 | i2c_w(sd, 0x1a, yend >> 3); | ||
3636 | return 0; | ||
2558 | case SEN_OV8610: | 3637 | case SEN_OV8610: |
2559 | /* For OV8610 qvga means qsvga */ | 3638 | /* For OV8610 qvga means qsvga */ |
2560 | i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); | 3639 | i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); |
3640 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ | ||
3641 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ | ||
3642 | i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */ | ||
3643 | i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */ | ||
2561 | break; | 3644 | break; |
2562 | case SEN_OV7610: | 3645 | case SEN_OV7610: |
2563 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 3646 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
3647 | i2c_w(sd, 0x35, qvga?0x1e:0x9e); | ||
3648 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ | ||
3649 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ | ||
2564 | break; | 3650 | break; |
2565 | case SEN_OV7620: | 3651 | case SEN_OV7620: |
2566 | case SEN_OV76BE: | 3652 | case SEN_OV76BE: |
@@ -2571,6 +3657,10 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
2571 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); | 3657 | i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); |
2572 | i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0); | 3658 | i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0); |
2573 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); | 3659 | i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); |
3660 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ | ||
3661 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ | ||
3662 | if (sd->sensor == SEN_OV76BE) | ||
3663 | i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e); | ||
2574 | break; | 3664 | break; |
2575 | case SEN_OV7640: | 3665 | case SEN_OV7640: |
2576 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 3666 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
@@ -2580,6 +3670,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
2580 | /* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ | 3670 | /* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ |
2581 | /* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ | 3671 | /* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ |
2582 | /* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ | 3672 | /* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ |
3673 | i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */ | ||
2583 | break; | 3674 | break; |
2584 | case SEN_OV7670: | 3675 | case SEN_OV7670: |
2585 | /* set COM7_FMT_VGA or COM7_FMT_QVGA | 3676 | /* set COM7_FMT_VGA or COM7_FMT_QVGA |
@@ -2588,55 +3679,56 @@ static int mode_init_ov_sensor_regs(struct sd *sd) | |||
2588 | i2c_w_mask(sd, OV7670_REG_COM7, | 3679 | i2c_w_mask(sd, OV7670_REG_COM7, |
2589 | qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, | 3680 | qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, |
2590 | OV7670_COM7_FMT_MASK); | 3681 | OV7670_COM7_FMT_MASK); |
3682 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ | ||
3683 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB, | ||
3684 | OV7670_COM8_AWB); | ||
3685 | if (qvga) { /* QVGA from ov7670.c by | ||
3686 | * Jonathan Corbet */ | ||
3687 | xstart = 164; | ||
3688 | xend = 28; | ||
3689 | ystart = 14; | ||
3690 | yend = 494; | ||
3691 | } else { /* VGA */ | ||
3692 | xstart = 158; | ||
3693 | xend = 14; | ||
3694 | ystart = 10; | ||
3695 | yend = 490; | ||
3696 | } | ||
3697 | /* OV7670 hardware window registers are split across | ||
3698 | * multiple locations */ | ||
3699 | i2c_w(sd, OV7670_REG_HSTART, xstart >> 3); | ||
3700 | i2c_w(sd, OV7670_REG_HSTOP, xend >> 3); | ||
3701 | v = i2c_r(sd, OV7670_REG_HREF); | ||
3702 | v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07); | ||
3703 | msleep(10); /* need to sleep between read and write to | ||
3704 | * same reg! */ | ||
3705 | i2c_w(sd, OV7670_REG_HREF, v); | ||
3706 | |||
3707 | i2c_w(sd, OV7670_REG_VSTART, ystart >> 2); | ||
3708 | i2c_w(sd, OV7670_REG_VSTOP, yend >> 2); | ||
3709 | v = i2c_r(sd, OV7670_REG_VREF); | ||
3710 | v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03); | ||
3711 | msleep(10); /* need to sleep between read and write to | ||
3712 | * same reg! */ | ||
3713 | i2c_w(sd, OV7670_REG_VREF, v); | ||
2591 | break; | 3714 | break; |
2592 | case SEN_OV6620: | 3715 | case SEN_OV6620: |
3716 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
3717 | i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */ | ||
3718 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ | ||
3719 | break; | ||
2593 | case SEN_OV6630: | 3720 | case SEN_OV6630: |
2594 | case SEN_OV66308AF: | 3721 | case SEN_OV66308AF: |
2595 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 3722 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
3723 | i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */ | ||
2596 | break; | 3724 | break; |
2597 | default: | 3725 | default: |
2598 | return -EINVAL; | 3726 | return -EINVAL; |
2599 | } | 3727 | } |
2600 | 3728 | ||
2601 | /******** Palette-specific regs ********/ | ||
2602 | |||
2603 | /* The OV518 needs special treatment. Although both the OV518 | ||
2604 | * and the OV6630 support a 16-bit video bus, only the 8 bit Y | ||
2605 | * bus is actually used. The UV bus is tied to ground. | ||
2606 | * Therefore, the OV6630 needs to be in 8-bit multiplexed | ||
2607 | * output mode */ | ||
2608 | |||
2609 | /* OV7640 is 8-bit only */ | ||
2610 | |||
2611 | if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV66308AF && | ||
2612 | sd->sensor != SEN_OV7640) | ||
2613 | i2c_w_mask(sd, 0x13, 0x00, 0x20); | ||
2614 | |||
2615 | /******** Clock programming ********/ | 3729 | /******** Clock programming ********/ |
2616 | i2c_w(sd, 0x11, sd->clockdiv); | 3730 | i2c_w(sd, 0x11, sd->clockdiv); |
2617 | 3731 | ||
2618 | /******** Special Features ********/ | ||
2619 | /* no evidence this is possible with OV7670, either */ | ||
2620 | /* Test Pattern */ | ||
2621 | if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670) | ||
2622 | i2c_w_mask(sd, 0x12, 0x00, 0x02); | ||
2623 | |||
2624 | /* Enable auto white balance */ | ||
2625 | if (sd->sensor == SEN_OV7670) | ||
2626 | i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB, | ||
2627 | OV7670_COM8_AWB); | ||
2628 | else | ||
2629 | i2c_w_mask(sd, 0x12, 0x04, 0x04); | ||
2630 | |||
2631 | /* This will go away as soon as ov51x_mode_init_sensor_regs() */ | ||
2632 | /* is fully tested. */ | ||
2633 | /* 7620/6620/6630? don't have register 0x35, so play it safe */ | ||
2634 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | ||
2635 | if (!qvga) | ||
2636 | i2c_w(sd, 0x35, 0x9e); | ||
2637 | else | ||
2638 | i2c_w(sd, 0x35, 0x1e); | ||
2639 | } | ||
2640 | return 0; | 3732 | return 0; |
2641 | } | 3733 | } |
2642 | 3734 | ||
@@ -2659,8 +3751,12 @@ static int set_ov_sensor_window(struct sd *sd) | |||
2659 | struct gspca_dev *gspca_dev; | 3751 | struct gspca_dev *gspca_dev; |
2660 | int qvga, crop; | 3752 | int qvga, crop; |
2661 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; | 3753 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; |
2662 | int ret, hstart, hstop, vstop, vstart; | 3754 | int ret; |
2663 | __u8 v; | 3755 | |
3756 | /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ | ||
3757 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 || | ||
3758 | sd->sensor == SEN_OV7670) | ||
3759 | return mode_init_ov_sensor_regs(sd); | ||
2664 | 3760 | ||
2665 | gspca_dev = &sd->gspca_dev; | 3761 | gspca_dev = &sd->gspca_dev; |
2666 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; | 3762 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1; |
@@ -2708,11 +3804,6 @@ static int set_ov_sensor_window(struct sd *sd) | |||
2708 | hwebase = 0x1a; | 3804 | hwebase = 0x1a; |
2709 | vwsbase = vwebase = 0x03; | 3805 | vwsbase = vwebase = 0x03; |
2710 | break; | 3806 | break; |
2711 | case SEN_OV7670: | ||
2712 | /*handling of OV7670 hardware sensor start and stop values | ||
2713 | * is very odd, compared to the other OV sensors */ | ||
2714 | vwsbase = vwebase = hwebase = hwsbase = 0x00; | ||
2715 | break; | ||
2716 | default: | 3807 | default: |
2717 | return -EINVAL; | 3808 | return -EINVAL; |
2718 | } | 3809 | } |
@@ -2753,58 +3844,11 @@ static int set_ov_sensor_window(struct sd *sd) | |||
2753 | if (ret < 0) | 3844 | if (ret < 0) |
2754 | return ret; | 3845 | return ret; |
2755 | 3846 | ||
2756 | if (sd->sensor == SEN_OV8610) { | 3847 | i2c_w(sd, 0x17, hwsbase); |
2757 | i2c_w_mask(sd, 0x2d, 0x05, 0x40); | 3848 | i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale)); |
2758 | /* old 0x95, new 0x05 from windrv 090403 */ | 3849 | i2c_w(sd, 0x19, vwsbase); |
2759 | /* bits 5-7: reserved */ | 3850 | i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale)); |
2760 | i2c_w_mask(sd, 0x28, 0x20, 0x20); | ||
2761 | /* bit 5: progressive mode on */ | ||
2762 | } | ||
2763 | |||
2764 | /* The below is wrong for OV7670s because their window registers | ||
2765 | * only store the high bits in 0x17 to 0x1a */ | ||
2766 | |||
2767 | /* SRH Use sd->max values instead of requested win values */ | ||
2768 | /* SCS Since we're sticking with only the max hardware widths | ||
2769 | * for a given mode */ | ||
2770 | /* I can hard code this for OV7670s */ | ||
2771 | /* Yes, these numbers do look odd, but they're tested and work! */ | ||
2772 | if (sd->sensor == SEN_OV7670) { | ||
2773 | if (qvga) { /* QVGA from ov7670.c by | ||
2774 | * Jonathan Corbet */ | ||
2775 | hstart = 164; | ||
2776 | hstop = 28; | ||
2777 | vstart = 14; | ||
2778 | vstop = 494; | ||
2779 | } else { /* VGA */ | ||
2780 | hstart = 158; | ||
2781 | hstop = 14; | ||
2782 | vstart = 10; | ||
2783 | vstop = 490; | ||
2784 | } | ||
2785 | /* OV7670 hardware window registers are split across | ||
2786 | * multiple locations */ | ||
2787 | i2c_w(sd, OV7670_REG_HSTART, hstart >> 3); | ||
2788 | i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3); | ||
2789 | v = i2c_r(sd, OV7670_REG_HREF); | ||
2790 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); | ||
2791 | msleep(10); /* need to sleep between read and write to | ||
2792 | * same reg! */ | ||
2793 | i2c_w(sd, OV7670_REG_HREF, v); | ||
2794 | 3851 | ||
2795 | i2c_w(sd, OV7670_REG_VSTART, vstart >> 2); | ||
2796 | i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2); | ||
2797 | v = i2c_r(sd, OV7670_REG_VREF); | ||
2798 | v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); | ||
2799 | msleep(10); /* need to sleep between read and write to | ||
2800 | * same reg! */ | ||
2801 | i2c_w(sd, OV7670_REG_VREF, v); | ||
2802 | } else { | ||
2803 | i2c_w(sd, 0x17, hwsbase); | ||
2804 | i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); | ||
2805 | i2c_w(sd, 0x19, vwsbase); | ||
2806 | i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale)); | ||
2807 | } | ||
2808 | return 0; | 3852 | return 0; |
2809 | } | 3853 | } |
2810 | 3854 | ||
@@ -2814,6 +3858,10 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2814 | struct sd *sd = (struct sd *) gspca_dev; | 3858 | struct sd *sd = (struct sd *) gspca_dev; |
2815 | int ret = 0; | 3859 | int ret = 0; |
2816 | 3860 | ||
3861 | /* Default for most bridges, allow bridge_mode_init_regs to override */ | ||
3862 | sd->sensor_width = sd->gspca_dev.width; | ||
3863 | sd->sensor_height = sd->gspca_dev.height; | ||
3864 | |||
2817 | switch (sd->bridge) { | 3865 | switch (sd->bridge) { |
2818 | case BRIDGE_OV511: | 3866 | case BRIDGE_OV511: |
2819 | case BRIDGE_OV511PLUS: | 3867 | case BRIDGE_OV511PLUS: |
@@ -2826,6 +3874,10 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2826 | case BRIDGE_OV519: | 3874 | case BRIDGE_OV519: |
2827 | ret = ov519_mode_init_regs(sd); | 3875 | ret = ov519_mode_init_regs(sd); |
2828 | break; | 3876 | break; |
3877 | /* case BRIDGE_OVFX2: nothing to do */ | ||
3878 | case BRIDGE_W9968CF: | ||
3879 | ret = w9968cf_mode_init_regs(sd); | ||
3880 | break; | ||
2829 | } | 3881 | } |
2830 | if (ret < 0) | 3882 | if (ret < 0) |
2831 | goto out; | 3883 | goto out; |
@@ -2859,10 +3911,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
2859 | ov51x_led_control(sd, 0); | 3911 | ov51x_led_control(sd, 0); |
2860 | } | 3912 | } |
2861 | 3913 | ||
3914 | static void sd_stop0(struct gspca_dev *gspca_dev) | ||
3915 | { | ||
3916 | struct sd *sd = (struct sd *) gspca_dev; | ||
3917 | |||
3918 | if (sd->bridge == BRIDGE_W9968CF) | ||
3919 | w9968cf_stop0(sd); | ||
3920 | } | ||
3921 | |||
2862 | static void ov511_pkt_scan(struct gspca_dev *gspca_dev, | 3922 | static void ov511_pkt_scan(struct gspca_dev *gspca_dev, |
2863 | struct gspca_frame *frame, /* target */ | 3923 | u8 *in, /* isoc packet */ |
2864 | __u8 *in, /* isoc packet */ | 3924 | int len) /* iso packet length */ |
2865 | int len) /* iso packet length */ | ||
2866 | { | 3925 | { |
2867 | struct sd *sd = (struct sd *) gspca_dev; | 3926 | struct sd *sd = (struct sd *) gspca_dev; |
2868 | 3927 | ||
@@ -2893,11 +3952,11 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev, | |||
2893 | return; | 3952 | return; |
2894 | } | 3953 | } |
2895 | /* Add 11 byte footer to frame, might be usefull */ | 3954 | /* Add 11 byte footer to frame, might be usefull */ |
2896 | gspca_frame_add(gspca_dev, LAST_PACKET, frame, in, 11); | 3955 | gspca_frame_add(gspca_dev, LAST_PACKET, in, 11); |
2897 | return; | 3956 | return; |
2898 | } else { | 3957 | } else { |
2899 | /* Frame start */ | 3958 | /* Frame start */ |
2900 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, in, 0); | 3959 | gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0); |
2901 | sd->packet_nr = 0; | 3960 | sd->packet_nr = 0; |
2902 | } | 3961 | } |
2903 | } | 3962 | } |
@@ -2906,12 +3965,11 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev, | |||
2906 | len--; | 3965 | len--; |
2907 | 3966 | ||
2908 | /* intermediate packet */ | 3967 | /* intermediate packet */ |
2909 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, in, len); | 3968 | gspca_frame_add(gspca_dev, INTER_PACKET, in, len); |
2910 | } | 3969 | } |
2911 | 3970 | ||
2912 | static void ov518_pkt_scan(struct gspca_dev *gspca_dev, | 3971 | static void ov518_pkt_scan(struct gspca_dev *gspca_dev, |
2913 | struct gspca_frame *frame, /* target */ | 3972 | u8 *data, /* isoc packet */ |
2914 | __u8 *data, /* isoc packet */ | ||
2915 | int len) /* iso packet length */ | 3973 | int len) /* iso packet length */ |
2916 | { | 3974 | { |
2917 | struct sd *sd = (struct sd *) gspca_dev; | 3975 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -2919,8 +3977,8 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev, | |||
2919 | /* A false positive here is likely, until OVT gives me | 3977 | /* A false positive here is likely, until OVT gives me |
2920 | * the definitive SOF/EOF format */ | 3978 | * the definitive SOF/EOF format */ |
2921 | if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { | 3979 | if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) { |
2922 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); | 3980 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); |
2923 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); | 3981 | gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); |
2924 | sd->packet_nr = 0; | 3982 | sd->packet_nr = 0; |
2925 | } | 3983 | } |
2926 | 3984 | ||
@@ -2944,12 +4002,11 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev, | |||
2944 | } | 4002 | } |
2945 | 4003 | ||
2946 | /* intermediate packet */ | 4004 | /* intermediate packet */ |
2947 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); | 4005 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
2948 | } | 4006 | } |
2949 | 4007 | ||
2950 | static void ov519_pkt_scan(struct gspca_dev *gspca_dev, | 4008 | static void ov519_pkt_scan(struct gspca_dev *gspca_dev, |
2951 | struct gspca_frame *frame, /* target */ | 4009 | u8 *data, /* isoc packet */ |
2952 | __u8 *data, /* isoc packet */ | ||
2953 | int len) /* iso packet length */ | 4010 | int len) /* iso packet length */ |
2954 | { | 4011 | { |
2955 | /* Header of ov519 is 16 bytes: | 4012 | /* Header of ov519 is 16 bytes: |
@@ -2972,7 +4029,7 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev, | |||
2972 | len -= HDRSZ; | 4029 | len -= HDRSZ; |
2973 | #undef HDRSZ | 4030 | #undef HDRSZ |
2974 | if (data[0] == 0xff || data[1] == 0xd8) | 4031 | if (data[0] == 0xff || data[1] == 0xd8) |
2975 | gspca_frame_add(gspca_dev, FIRST_PACKET, frame, | 4032 | gspca_frame_add(gspca_dev, FIRST_PACKET, |
2976 | data, len); | 4033 | data, len); |
2977 | else | 4034 | else |
2978 | gspca_dev->last_packet_type = DISCARD_PACKET; | 4035 | gspca_dev->last_packet_type = DISCARD_PACKET; |
@@ -2980,20 +4037,31 @@ static void ov519_pkt_scan(struct gspca_dev *gspca_dev, | |||
2980 | case 0x51: /* end of frame */ | 4037 | case 0x51: /* end of frame */ |
2981 | if (data[9] != 0) | 4038 | if (data[9] != 0) |
2982 | gspca_dev->last_packet_type = DISCARD_PACKET; | 4039 | gspca_dev->last_packet_type = DISCARD_PACKET; |
2983 | gspca_frame_add(gspca_dev, LAST_PACKET, frame, | 4040 | gspca_frame_add(gspca_dev, LAST_PACKET, |
2984 | data, 0); | 4041 | NULL, 0); |
2985 | return; | 4042 | return; |
2986 | } | 4043 | } |
2987 | } | 4044 | } |
2988 | 4045 | ||
2989 | /* intermediate packet */ | 4046 | /* intermediate packet */ |
2990 | gspca_frame_add(gspca_dev, INTER_PACKET, frame, | 4047 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); |
2991 | data, len); | 4048 | } |
4049 | |||
4050 | static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev, | ||
4051 | u8 *data, /* isoc packet */ | ||
4052 | int len) /* iso packet length */ | ||
4053 | { | ||
4054 | /* A short read signals EOF */ | ||
4055 | if (len < OVFX2_BULK_SIZE) { | ||
4056 | gspca_frame_add(gspca_dev, LAST_PACKET, data, len); | ||
4057 | gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); | ||
4058 | return; | ||
4059 | } | ||
4060 | gspca_frame_add(gspca_dev, INTER_PACKET, data, len); | ||
2992 | } | 4061 | } |
2993 | 4062 | ||
2994 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 4063 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
2995 | struct gspca_frame *frame, /* target */ | 4064 | u8 *data, /* isoc packet */ |
2996 | __u8 *data, /* isoc packet */ | ||
2997 | int len) /* iso packet length */ | 4065 | int len) /* iso packet length */ |
2998 | { | 4066 | { |
2999 | struct sd *sd = (struct sd *) gspca_dev; | 4067 | struct sd *sd = (struct sd *) gspca_dev; |
@@ -3001,14 +4069,20 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
3001 | switch (sd->bridge) { | 4069 | switch (sd->bridge) { |
3002 | case BRIDGE_OV511: | 4070 | case BRIDGE_OV511: |
3003 | case BRIDGE_OV511PLUS: | 4071 | case BRIDGE_OV511PLUS: |
3004 | ov511_pkt_scan(gspca_dev, frame, data, len); | 4072 | ov511_pkt_scan(gspca_dev, data, len); |
3005 | break; | 4073 | break; |
3006 | case BRIDGE_OV518: | 4074 | case BRIDGE_OV518: |
3007 | case BRIDGE_OV518PLUS: | 4075 | case BRIDGE_OV518PLUS: |
3008 | ov518_pkt_scan(gspca_dev, frame, data, len); | 4076 | ov518_pkt_scan(gspca_dev, data, len); |
3009 | break; | 4077 | break; |
3010 | case BRIDGE_OV519: | 4078 | case BRIDGE_OV519: |
3011 | ov519_pkt_scan(gspca_dev, frame, data, len); | 4079 | ov519_pkt_scan(gspca_dev, data, len); |
4080 | break; | ||
4081 | case BRIDGE_OVFX2: | ||
4082 | ovfx2_pkt_scan(gspca_dev, data, len); | ||
4083 | break; | ||
4084 | case BRIDGE_W9968CF: | ||
4085 | w9968cf_pkt_scan(gspca_dev, data, len); | ||
3012 | break; | 4086 | break; |
3013 | } | 4087 | } |
3014 | } | 4088 | } |
@@ -3124,7 +4198,8 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
3124 | 4198 | ||
3125 | static void setautobrightness(struct sd *sd) | 4199 | static void setautobrightness(struct sd *sd) |
3126 | { | 4200 | { |
3127 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670) | 4201 | if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 || |
4202 | sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | ||
3128 | return; | 4203 | return; |
3129 | 4204 | ||
3130 | i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10); | 4205 | i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10); |
@@ -3132,6 +4207,9 @@ static void setautobrightness(struct sd *sd) | |||
3132 | 4207 | ||
3133 | static void setfreq(struct sd *sd) | 4208 | static void setfreq(struct sd *sd) |
3134 | { | 4209 | { |
4210 | if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610) | ||
4211 | return; | ||
4212 | |||
3135 | if (sd->sensor == SEN_OV7670) { | 4213 | if (sd->sensor == SEN_OV7670) { |
3136 | switch (sd->freq) { | 4214 | switch (sd->freq) { |
3137 | case 0: /* Banding filter disabled */ | 4215 | case 0: /* Banding filter disabled */ |
@@ -3301,8 +4379,12 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) | |||
3301 | struct sd *sd = (struct sd *) gspca_dev; | 4379 | struct sd *sd = (struct sd *) gspca_dev; |
3302 | 4380 | ||
3303 | sd->freq = val; | 4381 | sd->freq = val; |
3304 | if (gspca_dev->streaming) | 4382 | if (gspca_dev->streaming) { |
3305 | setfreq(sd); | 4383 | setfreq(sd); |
4384 | /* Ugly but necessary */ | ||
4385 | if (sd->bridge == BRIDGE_W9968CF) | ||
4386 | w9968cf_set_crop_window(sd); | ||
4387 | } | ||
3306 | return 0; | 4388 | return 0; |
3307 | } | 4389 | } |
3308 | 4390 | ||
@@ -3343,6 +4425,45 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, | |||
3343 | return -EINVAL; | 4425 | return -EINVAL; |
3344 | } | 4426 | } |
3345 | 4427 | ||
4428 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | ||
4429 | struct v4l2_jpegcompression *jcomp) | ||
4430 | { | ||
4431 | struct sd *sd = (struct sd *) gspca_dev; | ||
4432 | |||
4433 | if (sd->bridge != BRIDGE_W9968CF) | ||
4434 | return -EINVAL; | ||
4435 | |||
4436 | memset(jcomp, 0, sizeof *jcomp); | ||
4437 | jcomp->quality = sd->quality; | ||
4438 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT | | ||
4439 | V4L2_JPEG_MARKER_DRI; | ||
4440 | return 0; | ||
4441 | } | ||
4442 | |||
4443 | static int sd_set_jcomp(struct gspca_dev *gspca_dev, | ||
4444 | struct v4l2_jpegcompression *jcomp) | ||
4445 | { | ||
4446 | struct sd *sd = (struct sd *) gspca_dev; | ||
4447 | |||
4448 | if (sd->bridge != BRIDGE_W9968CF) | ||
4449 | return -EINVAL; | ||
4450 | |||
4451 | if (gspca_dev->streaming) | ||
4452 | return -EBUSY; | ||
4453 | |||
4454 | if (jcomp->quality < QUALITY_MIN) | ||
4455 | sd->quality = QUALITY_MIN; | ||
4456 | else if (jcomp->quality > QUALITY_MAX) | ||
4457 | sd->quality = QUALITY_MAX; | ||
4458 | else | ||
4459 | sd->quality = jcomp->quality; | ||
4460 | |||
4461 | /* Return resulting jcomp params to app */ | ||
4462 | sd_get_jcomp(gspca_dev, jcomp); | ||
4463 | |||
4464 | return 0; | ||
4465 | } | ||
4466 | |||
3346 | /* sub-driver description */ | 4467 | /* sub-driver description */ |
3347 | static const struct sd_desc sd_desc = { | 4468 | static const struct sd_desc sd_desc = { |
3348 | .name = MODULE_NAME, | 4469 | .name = MODULE_NAME, |
@@ -3352,18 +4473,23 @@ static const struct sd_desc sd_desc = { | |||
3352 | .init = sd_init, | 4473 | .init = sd_init, |
3353 | .start = sd_start, | 4474 | .start = sd_start, |
3354 | .stopN = sd_stopN, | 4475 | .stopN = sd_stopN, |
4476 | .stop0 = sd_stop0, | ||
3355 | .pkt_scan = sd_pkt_scan, | 4477 | .pkt_scan = sd_pkt_scan, |
3356 | .querymenu = sd_querymenu, | 4478 | .querymenu = sd_querymenu, |
4479 | .get_jcomp = sd_get_jcomp, | ||
4480 | .set_jcomp = sd_set_jcomp, | ||
3357 | }; | 4481 | }; |
3358 | 4482 | ||
3359 | /* -- module initialisation -- */ | 4483 | /* -- module initialisation -- */ |
3360 | static const __devinitdata struct usb_device_id device_table[] = { | 4484 | static const __devinitdata struct usb_device_id device_table[] = { |
4485 | {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF }, | ||
3361 | {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, | 4486 | {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, |
3362 | {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, | 4487 | {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, |
3363 | {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, | 4488 | {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 }, |
3364 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, | 4489 | {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 }, |
3365 | {USB_DEVICE(0x041e, 0x4064), | 4490 | {USB_DEVICE(0x041e, 0x4064), |
3366 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | 4491 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, |
4492 | {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 }, | ||
3367 | {USB_DEVICE(0x041e, 0x4068), | 4493 | {USB_DEVICE(0x041e, 0x4068), |
3368 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, | 4494 | .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED }, |
3369 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, | 4495 | {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 }, |
@@ -3373,11 +4499,16 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
3373 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, | 4499 | {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 }, |
3374 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, | 4500 | {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 }, |
3375 | {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 }, | 4501 | {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 }, |
4502 | {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 }, | ||
3376 | {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, | 4503 | {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 }, |
3377 | {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, | 4504 | {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 }, |
3378 | {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS }, | 4505 | {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS }, |
3379 | {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, | 4506 | {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS }, |
3380 | {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS }, | 4507 | {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS }, |
4508 | {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 }, | ||
4509 | {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 }, | ||
4510 | {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF }, | ||
4511 | {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 }, | ||
3381 | {} | 4512 | {} |
3382 | }; | 4513 | }; |
3383 | 4514 | ||