|
@@ -58,6 +58,7 @@ struct sd {
|
|
|
#define BRIDGE_OV518 2
|
|
|
#define BRIDGE_OV518PLUS 3
|
|
|
#define BRIDGE_OV519 4
|
|
|
+#define BRIDGE_OVFX2 5
|
|
|
#define BRIDGE_MASK 7
|
|
|
|
|
|
char invert_led;
|
|
@@ -81,15 +82,17 @@ struct sd {
|
|
|
|
|
|
char sensor; /* Type of image sensor chip (SEN_*) */
|
|
|
#define SEN_UNKNOWN 0
|
|
|
-#define SEN_OV6620 1
|
|
|
-#define SEN_OV6630 2
|
|
|
-#define SEN_OV66308AF 3
|
|
|
-#define SEN_OV7610 4
|
|
|
-#define SEN_OV7620 5
|
|
|
-#define SEN_OV7640 6
|
|
|
-#define SEN_OV7670 7
|
|
|
-#define SEN_OV76BE 8
|
|
|
-#define SEN_OV8610 9
|
|
|
+#define SEN_OV2610 1
|
|
|
+#define SEN_OV3610 2
|
|
|
+#define SEN_OV6620 3
|
|
|
+#define SEN_OV6630 4
|
|
|
+#define SEN_OV66308AF 5
|
|
|
+#define SEN_OV7610 6
|
|
|
+#define SEN_OV7620 7
|
|
|
+#define SEN_OV7640 8
|
|
|
+#define SEN_OV7670 9
|
|
|
+#define SEN_OV76BE 10
|
|
|
+#define SEN_OV8610 11
|
|
|
};
|
|
|
|
|
|
/* V4L2 controls supported by the driver */
|
|
@@ -345,6 +348,70 @@ static const struct v4l2_pix_format ov511_sif_mode[] = {
|
|
|
.priv = 0},
|
|
|
};
|
|
|
|
|
|
+static const struct v4l2_pix_format ovfx2_vga_mode[] = {
|
|
|
+ {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 320,
|
|
|
+ .sizeimage = 320 * 240,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB,
|
|
|
+ .priv = 1},
|
|
|
+ {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 640,
|
|
|
+ .sizeimage = 640 * 480,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB,
|
|
|
+ .priv = 0},
|
|
|
+};
|
|
|
+static const struct v4l2_pix_format ovfx2_cif_mode[] = {
|
|
|
+ {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 160,
|
|
|
+ .sizeimage = 160 * 120,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB,
|
|
|
+ .priv = 3},
|
|
|
+ {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 176,
|
|
|
+ .sizeimage = 176 * 144,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB,
|
|
|
+ .priv = 1},
|
|
|
+ {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 320,
|
|
|
+ .sizeimage = 320 * 240,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB,
|
|
|
+ .priv = 2},
|
|
|
+ {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 352,
|
|
|
+ .sizeimage = 352 * 288,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB,
|
|
|
+ .priv = 0},
|
|
|
+};
|
|
|
+static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
|
|
|
+ {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 1600,
|
|
|
+ .sizeimage = 1600 * 1200,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB},
|
|
|
+};
|
|
|
+static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
|
|
|
+ {2080, 1544, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 2080,
|
|
|
+ .sizeimage = 2080 * 1544,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB},
|
|
|
+ {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 1600,
|
|
|
+ .sizeimage = 1600 * 1200,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB},
|
|
|
+ {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 1024,
|
|
|
+ .sizeimage = 1024 * 768,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB},
|
|
|
+ {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 800,
|
|
|
+ .sizeimage = 800 * 600,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB},
|
|
|
+ {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
|
|
|
+ .bytesperline = 640,
|
|
|
+ .sizeimage = 640 * 480,
|
|
|
+ .colorspace = V4L2_COLORSPACE_SRGB},
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
/* Registers common to OV511 / OV518 */
|
|
|
#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
|
|
|
#define R51x_SYS_RESET 0x50
|
|
@@ -509,6 +576,696 @@ struct ov_i2c_regvals {
|
|
|
__u8 val;
|
|
|
};
|
|
|
|
|
|
+/* Settings for OV2610 camera chip */
|
|
|
+static const struct ov_i2c_regvals norm_2610[] =
|
|
|
+{
|
|
|
+ { 0x10, 0x80 }, /* reset */
|
|
|
+};
|
|
|
+
|
|
|
+static const struct ov_i2c_regvals norm_3620b[] =
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * From the datasheet: "Note that after writing to register COMH
|
|
|
+ * (0x12) to change the sensor mode, registers related to the
|
|
|
+ * sensor’s cropping window will be reset back to their default
|
|
|
+ * values."
|
|
|
+ *
|
|
|
+ * "wait 4096 external clock ... to make sure the sensor is
|
|
|
+ * stable and ready to access registers" i.e. 160us at 24MHz
|
|
|
+ */
|
|
|
+
|
|
|
+ { 0x12, 0x80 }, /* COMH reset */
|
|
|
+ { 0x12, 0x00 }, /* QXGA, master */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 11 CLKRC "Clock Rate Control"
|
|
|
+ * [7] internal frequency doublers: on
|
|
|
+ * [6] video port mode: master
|
|
|
+ * [5:0] clock divider: 1
|
|
|
+ */
|
|
|
+ { 0x11, 0x80 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 13 COMI "Common Control I"
|
|
|
+ * = 192 (0xC0) 11000000
|
|
|
+ * COMI[7] "AEC speed selection"
|
|
|
+ * = 1 (0x01) 1....... "Faster AEC correction"
|
|
|
+ * COMI[6] "AEC speed step selection"
|
|
|
+ * = 1 (0x01) .1...... "Big steps, fast"
|
|
|
+ * COMI[5] "Banding filter on off"
|
|
|
+ * = 0 (0x00) ..0..... "Off"
|
|
|
+ * COMI[4] "Banding filter option"
|
|
|
+ * = 0 (0x00) ...0.... "Main clock is 48 MHz and
|
|
|
+ * the PLL is ON"
|
|
|
+ * COMI[3] "Reserved"
|
|
|
+ * = 0 (0x00) ....0...
|
|
|
+ * COMI[2] "AGC auto manual control selection"
|
|
|
+ * = 0 (0x00) .....0.. "Manual"
|
|
|
+ * COMI[1] "AWB auto manual control selection"
|
|
|
+ * = 0 (0x00) ......0. "Manual"
|
|
|
+ * COMI[0] "Exposure control"
|
|
|
+ * = 0 (0x00) .......0 "Manual"
|
|
|
+ */
|
|
|
+ { 0x13, 0xC0 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 09 COMC "Common Control C"
|
|
|
+ * = 8 (0x08) 00001000
|
|
|
+ * COMC[7:5] "Reserved"
|
|
|
+ * = 0 (0x00) 000.....
|
|
|
+ * COMC[4] "Sleep Mode Enable"
|
|
|
+ * = 0 (0x00) ...0.... "Normal mode"
|
|
|
+ * COMC[3:2] "Sensor sampling reset timing selection"
|
|
|
+ * = 2 (0x02) ....10.. "Longer reset time"
|
|
|
+ * COMC[1:0] "Output drive current select"
|
|
|
+ * = 0 (0x00) ......00 "Weakest"
|
|
|
+ */
|
|
|
+ { 0x09, 0x08 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 0C COMD "Common Control D"
|
|
|
+ * = 8 (0x08) 00001000
|
|
|
+ * COMD[7] "Reserved"
|
|
|
+ * = 0 (0x00) 0.......
|
|
|
+ * COMD[6] "Swap MSB and LSB at the output port"
|
|
|
+ * = 0 (0x00) .0...... "False"
|
|
|
+ * COMD[5:3] "Reserved"
|
|
|
+ * = 1 (0x01) ..001...
|
|
|
+ * COMD[2] "Output Average On Off"
|
|
|
+ * = 0 (0x00) .....0.. "Output Normal"
|
|
|
+ * COMD[1] "Sensor precharge voltage selection"
|
|
|
+ * = 0 (0x00) ......0. "Selects internal
|
|
|
+ * reference precharge
|
|
|
+ * voltage"
|
|
|
+ * COMD[0] "Snapshot option"
|
|
|
+ * = 0 (0x00) .......0 "Enable live video output
|
|
|
+ * after snapshot sequence"
|
|
|
+ */
|
|
|
+ { 0x0c, 0x08 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 0D COME "Common Control E"
|
|
|
+ * = 161 (0xA1) 10100001
|
|
|
+ * COME[7] "Output average option"
|
|
|
+ * = 1 (0x01) 1....... "Output average of 4 pixels"
|
|
|
+ * COME[6] "Anti-blooming control"
|
|
|
+ * = 0 (0x00) .0...... "Off"
|
|
|
+ * COME[5:3] "Reserved"
|
|
|
+ * = 4 (0x04) ..100...
|
|
|
+ * COME[2] "Clock output power down pin status"
|
|
|
+ * = 0 (0x00) .....0.. "Tri-state data output pin
|
|
|
+ * on power down"
|
|
|
+ * COME[1] "Data output pin status selection at power down"
|
|
|
+ * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
|
|
|
+ * HREF, and CHSYNC pins on
|
|
|
+ * power down"
|
|
|
+ * COME[0] "Auto zero circuit select"
|
|
|
+ * = 1 (0x01) .......1 "On"
|
|
|
+ */
|
|
|
+ { 0x0d, 0xA1 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 0E COMF "Common Control F"
|
|
|
+ * = 112 (0x70) 01110000
|
|
|
+ * COMF[7] "System clock selection"
|
|
|
+ * = 0 (0x00) 0....... "Use 24 MHz system clock"
|
|
|
+ * COMF[6:4] "Reserved"
|
|
|
+ * = 7 (0x07) .111....
|
|
|
+ * COMF[3] "Manual auto negative offset canceling selection"
|
|
|
+ * = 0 (0x00) ....0... "Auto detect negative
|
|
|
+ * offset and cancel it"
|
|
|
+ * COMF[2:0] "Reserved"
|
|
|
+ * = 0 (0x00) .....000
|
|
|
+ */
|
|
|
+ { 0x0e, 0x70 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 0F COMG "Common Control G"
|
|
|
+ * = 66 (0x42) 01000010
|
|
|
+ * COMG[7] "Optical black output selection"
|
|
|
+ * = 0 (0x00) 0....... "Disable"
|
|
|
+ * COMG[6] "Black level calibrate selection"
|
|
|
+ * = 1 (0x01) .1...... "Use optical black pixels
|
|
|
+ * to calibrate"
|
|
|
+ * COMG[5:4] "Reserved"
|
|
|
+ * = 0 (0x00) ..00....
|
|
|
+ * COMG[3] "Channel offset adjustment"
|
|
|
+ * = 0 (0x00) ....0... "Disable offset adjustment"
|
|
|
+ * COMG[2] "ADC black level calibration option"
|
|
|
+ * = 0 (0x00) .....0.. "Use B/G line and G/R
|
|
|
+ * line to calibrate each
|
|
|
+ * channel's black level"
|
|
|
+ * COMG[1] "Reserved"
|
|
|
+ * = 1 (0x01) ......1.
|
|
|
+ * COMG[0] "ADC black level calibration enable"
|
|
|
+ * = 0 (0x00) .......0 "Disable"
|
|
|
+ */
|
|
|
+ { 0x0f, 0x42 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 14 COMJ "Common Control J"
|
|
|
+ * = 198 (0xC6) 11000110
|
|
|
+ * COMJ[7:6] "AGC gain ceiling"
|
|
|
+ * = 3 (0x03) 11...... "8x"
|
|
|
+ * COMJ[5:4] "Reserved"
|
|
|
+ * = 0 (0x00) ..00....
|
|
|
+ * COMJ[3] "Auto banding filter"
|
|
|
+ * = 0 (0x00) ....0... "Banding filter is always
|
|
|
+ * on off depending on
|
|
|
+ * COMI[5] setting"
|
|
|
+ * COMJ[2] "VSYNC drop option"
|
|
|
+ * = 1 (0x01) .....1.. "SYNC is dropped if frame
|
|
|
+ * data is dropped"
|
|
|
+ * COMJ[1] "Frame data drop"
|
|
|
+ * = 1 (0x01) ......1. "Drop frame data if
|
|
|
+ * exposure is not within
|
|
|
+ * tolerance. In AEC mode,
|
|
|
+ * data is normally dropped
|
|
|
+ * when data is out of
|
|
|
+ * range."
|
|
|
+ * COMJ[0] "Reserved"
|
|
|
+ * = 0 (0x00) .......0
|
|
|
+ */
|
|
|
+ { 0x14, 0xC6 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 15 COMK "Common Control K"
|
|
|
+ * = 2 (0x02) 00000010
|
|
|
+ * COMK[7] "CHSYNC pin output swap"
|
|
|
+ * = 0 (0x00) 0....... "CHSYNC"
|
|
|
+ * COMK[6] "HREF pin output swap"
|
|
|
+ * = 0 (0x00) .0...... "HREF"
|
|
|
+ * COMK[5] "PCLK output selection"
|
|
|
+ * = 0 (0x00) ..0..... "PCLK always output"
|
|
|
+ * COMK[4] "PCLK edge selection"
|
|
|
+ * = 0 (0x00) ...0.... "Data valid on falling edge"
|
|
|
+ * COMK[3] "HREF output polarity"
|
|
|
+ * = 0 (0x00) ....0... "positive"
|
|
|
+ * COMK[2] "Reserved"
|
|
|
+ * = 0 (0x00) .....0..
|
|
|
+ * COMK[1] "VSYNC polarity"
|
|
|
+ * = 1 (0x01) ......1. "negative"
|
|
|
+ * COMK[0] "HSYNC polarity"
|
|
|
+ * = 0 (0x00) .......0 "positive"
|
|
|
+ */
|
|
|
+ { 0x15, 0x02 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 33 CHLF "Current Control"
|
|
|
+ * = 9 (0x09) 00001001
|
|
|
+ * CHLF[7:6] "Sensor current control"
|
|
|
+ * = 0 (0x00) 00......
|
|
|
+ * CHLF[5] "Sensor current range control"
|
|
|
+ * = 0 (0x00) ..0..... "normal range"
|
|
|
+ * CHLF[4] "Sensor current"
|
|
|
+ * = 0 (0x00) ...0.... "normal current"
|
|
|
+ * CHLF[3] "Sensor buffer current control"
|
|
|
+ * = 1 (0x01) ....1... "half current"
|
|
|
+ * CHLF[2] "Column buffer current control"
|
|
|
+ * = 0 (0x00) .....0.. "normal current"
|
|
|
+ * CHLF[1] "Analog DSP current control"
|
|
|
+ * = 0 (0x00) ......0. "normal current"
|
|
|
+ * CHLF[1] "ADC current control"
|
|
|
+ * = 0 (0x00) ......0. "normal current"
|
|
|
+ */
|
|
|
+ { 0x33, 0x09 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 34 VBLM "Blooming Control"
|
|
|
+ * = 80 (0x50) 01010000
|
|
|
+ * VBLM[7] "Hard soft reset switch"
|
|
|
+ * = 0 (0x00) 0....... "Hard reset"
|
|
|
+ * VBLM[6:4] "Blooming voltage selection"
|
|
|
+ * = 5 (0x05) .101....
|
|
|
+ * VBLM[3:0] "Sensor current control"
|
|
|
+ * = 0 (0x00) ....0000
|
|
|
+ */
|
|
|
+ { 0x34, 0x50 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 36 VCHG "Sensor Precharge Voltage Control"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ * VCHG[7] "Reserved"
|
|
|
+ * = 0 (0x00) 0.......
|
|
|
+ * VCHG[6:4] "Sensor precharge voltage control"
|
|
|
+ * = 0 (0x00) .000....
|
|
|
+ * VCHG[3:0] "Sensor array common reference"
|
|
|
+ * = 0 (0x00) ....0000
|
|
|
+ */
|
|
|
+ { 0x36, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 37 ADC "ADC Reference Control"
|
|
|
+ * = 4 (0x04) 00000100
|
|
|
+ * ADC[7:4] "Reserved"
|
|
|
+ * = 0 (0x00) 0000....
|
|
|
+ * ADC[3] "ADC input signal range"
|
|
|
+ * = 0 (0x00) ....0... "Input signal 1.0x"
|
|
|
+ * ADC[2:0] "ADC range control"
|
|
|
+ * = 4 (0x04) .....100
|
|
|
+ */
|
|
|
+ { 0x37, 0x04 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 38 ACOM "Analog Common Ground"
|
|
|
+ * = 82 (0x52) 01010010
|
|
|
+ * ACOM[7] "Analog gain control"
|
|
|
+ * = 0 (0x00) 0....... "Gain 1x"
|
|
|
+ * ACOM[6] "Analog black level calibration"
|
|
|
+ * = 1 (0x01) .1...... "On"
|
|
|
+ * ACOM[5:0] "Reserved"
|
|
|
+ * = 18 (0x12) ..010010
|
|
|
+ */
|
|
|
+ { 0x38, 0x52 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 3A FREFA "Internal Reference Adjustment"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ * FREFA[7:0] "Range"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x3a, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 3C FVOPT "Internal Reference Adjustment"
|
|
|
+ * = 31 (0x1F) 00011111
|
|
|
+ * FVOPT[7:0] "Range"
|
|
|
+ * = 31 (0x1F) 00011111
|
|
|
+ */
|
|
|
+ { 0x3c, 0x1F },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 44 Undocumented = 0 (0x00) 00000000
|
|
|
+ * 44[7:0] "It's a secret"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x44, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 40 Undocumented = 0 (0x00) 00000000
|
|
|
+ * 40[7:0] "It's a secret"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x40, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 41 Undocumented = 0 (0x00) 00000000
|
|
|
+ * 41[7:0] "It's a secret"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x41, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 42 Undocumented = 0 (0x00) 00000000
|
|
|
+ * 42[7:0] "It's a secret"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x42, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 43 Undocumented = 0 (0x00) 00000000
|
|
|
+ * 43[7:0] "It's a secret"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x43, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 45 Undocumented = 128 (0x80) 10000000
|
|
|
+ * 45[7:0] "It's a secret"
|
|
|
+ * = 128 (0x80) 10000000
|
|
|
+ */
|
|
|
+ { 0x45, 0x80 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 48 Undocumented = 192 (0xC0) 11000000
|
|
|
+ * 48[7:0] "It's a secret"
|
|
|
+ * = 192 (0xC0) 11000000
|
|
|
+ */
|
|
|
+ { 0x48, 0xC0 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 49 Undocumented = 25 (0x19) 00011001
|
|
|
+ * 49[7:0] "It's a secret"
|
|
|
+ * = 25 (0x19) 00011001
|
|
|
+ */
|
|
|
+ { 0x49, 0x19 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 4B Undocumented = 128 (0x80) 10000000
|
|
|
+ * 4B[7:0] "It's a secret"
|
|
|
+ * = 128 (0x80) 10000000
|
|
|
+ */
|
|
|
+ { 0x4B, 0x80 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 4D Undocumented = 196 (0xC4) 11000100
|
|
|
+ * 4D[7:0] "It's a secret"
|
|
|
+ * = 196 (0xC4) 11000100
|
|
|
+ */
|
|
|
+ { 0x4D, 0xC4 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 35 VREF "Reference Voltage Control"
|
|
|
+ * = 76 (0x4C) 01001100
|
|
|
+ * VREF[7:5] "Column high reference control"
|
|
|
+ * = 2 (0x02) 010..... "higher voltage"
|
|
|
+ * VREF[4:2] "Column low reference control"
|
|
|
+ * = 3 (0x03) ...011.. "Highest voltage"
|
|
|
+ * VREF[1:0] "Reserved"
|
|
|
+ * = 0 (0x00) ......00
|
|
|
+ */
|
|
|
+ { 0x35, 0x4C },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 3D Undocumented = 0 (0x00) 00000000
|
|
|
+ * 3D[7:0] "It's a secret"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x3D, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 3E Undocumented = 0 (0x00) 00000000
|
|
|
+ * 3E[7:0] "It's a secret"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x3E, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 3B FREFB "Internal Reference Adjustment"
|
|
|
+ * = 24 (0x18) 00011000
|
|
|
+ * FREFB[7:0] "Range"
|
|
|
+ * = 24 (0x18) 00011000
|
|
|
+ */
|
|
|
+ { 0x3b, 0x18 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 33 CHLF "Current Control"
|
|
|
+ * = 25 (0x19) 00011001
|
|
|
+ * CHLF[7:6] "Sensor current control"
|
|
|
+ * = 0 (0x00) 00......
|
|
|
+ * CHLF[5] "Sensor current range control"
|
|
|
+ * = 0 (0x00) ..0..... "normal range"
|
|
|
+ * CHLF[4] "Sensor current"
|
|
|
+ * = 1 (0x01) ...1.... "double current"
|
|
|
+ * CHLF[3] "Sensor buffer current control"
|
|
|
+ * = 1 (0x01) ....1... "half current"
|
|
|
+ * CHLF[2] "Column buffer current control"
|
|
|
+ * = 0 (0x00) .....0.. "normal current"
|
|
|
+ * CHLF[1] "Analog DSP current control"
|
|
|
+ * = 0 (0x00) ......0. "normal current"
|
|
|
+ * CHLF[1] "ADC current control"
|
|
|
+ * = 0 (0x00) ......0. "normal current"
|
|
|
+ */
|
|
|
+ { 0x33, 0x19 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 34 VBLM "Blooming Control"
|
|
|
+ * = 90 (0x5A) 01011010
|
|
|
+ * VBLM[7] "Hard soft reset switch"
|
|
|
+ * = 0 (0x00) 0....... "Hard reset"
|
|
|
+ * VBLM[6:4] "Blooming voltage selection"
|
|
|
+ * = 5 (0x05) .101....
|
|
|
+ * VBLM[3:0] "Sensor current control"
|
|
|
+ * = 10 (0x0A) ....1010
|
|
|
+ */
|
|
|
+ { 0x34, 0x5A },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 3B FREFB "Internal Reference Adjustment"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ * FREFB[7:0] "Range"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x3b, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 33 CHLF "Current Control"
|
|
|
+ * = 9 (0x09) 00001001
|
|
|
+ * CHLF[7:6] "Sensor current control"
|
|
|
+ * = 0 (0x00) 00......
|
|
|
+ * CHLF[5] "Sensor current range control"
|
|
|
+ * = 0 (0x00) ..0..... "normal range"
|
|
|
+ * CHLF[4] "Sensor current"
|
|
|
+ * = 0 (0x00) ...0.... "normal current"
|
|
|
+ * CHLF[3] "Sensor buffer current control"
|
|
|
+ * = 1 (0x01) ....1... "half current"
|
|
|
+ * CHLF[2] "Column buffer current control"
|
|
|
+ * = 0 (0x00) .....0.. "normal current"
|
|
|
+ * CHLF[1] "Analog DSP current control"
|
|
|
+ * = 0 (0x00) ......0. "normal current"
|
|
|
+ * CHLF[1] "ADC current control"
|
|
|
+ * = 0 (0x00) ......0. "normal current"
|
|
|
+ */
|
|
|
+ { 0x33, 0x09 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 34 VBLM "Blooming Control"
|
|
|
+ * = 80 (0x50) 01010000
|
|
|
+ * VBLM[7] "Hard soft reset switch"
|
|
|
+ * = 0 (0x00) 0....... "Hard reset"
|
|
|
+ * VBLM[6:4] "Blooming voltage selection"
|
|
|
+ * = 5 (0x05) .101....
|
|
|
+ * VBLM[3:0] "Sensor current control"
|
|
|
+ * = 0 (0x00) ....0000
|
|
|
+ */
|
|
|
+ { 0x34, 0x50 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 12 COMH "Common Control H"
|
|
|
+ * = 64 (0x40) 01000000
|
|
|
+ * COMH[7] "SRST"
|
|
|
+ * = 0 (0x00) 0....... "No-op"
|
|
|
+ * COMH[6:4] "Resolution selection"
|
|
|
+ * = 4 (0x04) .100.... "XGA"
|
|
|
+ * COMH[3] "Master slave selection"
|
|
|
+ * = 0 (0x00) ....0... "Master mode"
|
|
|
+ * COMH[2] "Internal B/R channel option"
|
|
|
+ * = 0 (0x00) .....0.. "B/R use same channel"
|
|
|
+ * COMH[1] "Color bar test pattern"
|
|
|
+ * = 0 (0x00) ......0. "Off"
|
|
|
+ * COMH[0] "Reserved"
|
|
|
+ * = 0 (0x00) .......0
|
|
|
+ */
|
|
|
+ { 0x12, 0x40 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 17 HREFST "Horizontal window start"
|
|
|
+ * = 31 (0x1F) 00011111
|
|
|
+ * HREFST[7:0] "Horizontal window start, 8 MSBs"
|
|
|
+ * = 31 (0x1F) 00011111
|
|
|
+ */
|
|
|
+ { 0x17, 0x1F },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 18 HREFEND "Horizontal window end"
|
|
|
+ * = 95 (0x5F) 01011111
|
|
|
+ * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
|
|
|
+ * = 95 (0x5F) 01011111
|
|
|
+ */
|
|
|
+ { 0x18, 0x5F },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 19 VSTRT "Vertical window start"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x19, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 1A VEND "Vertical window end"
|
|
|
+ * = 96 (0x60) 01100000
|
|
|
+ * VEND[7:0] "Vertical Window End, 8 MSBs"
|
|
|
+ * = 96 (0x60) 01100000
|
|
|
+ */
|
|
|
+ { 0x1a, 0x60 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 32 COMM "Common Control M"
|
|
|
+ * = 18 (0x12) 00010010
|
|
|
+ * COMM[7:6] "Pixel clock divide option"
|
|
|
+ * = 0 (0x00) 00...... "/1"
|
|
|
+ * COMM[5:3] "Horizontal window end position, 3 LSBs"
|
|
|
+ * = 2 (0x02) ..010...
|
|
|
+ * COMM[2:0] "Horizontal window start position, 3 LSBs"
|
|
|
+ * = 2 (0x02) .....010
|
|
|
+ */
|
|
|
+ { 0x32, 0x12 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 03 COMA "Common Control A"
|
|
|
+ * = 74 (0x4A) 01001010
|
|
|
+ * COMA[7:4] "AWB Update Threshold"
|
|
|
+ * = 4 (0x04) 0100....
|
|
|
+ * COMA[3:2] "Vertical window end line control 2 LSBs"
|
|
|
+ * = 2 (0x02) ....10..
|
|
|
+ * COMA[1:0] "Vertical window start line control 2 LSBs"
|
|
|
+ * = 2 (0x02) ......10
|
|
|
+ */
|
|
|
+ { 0x03, 0x4A },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 11 CLKRC "Clock Rate Control"
|
|
|
+ * = 128 (0x80) 10000000
|
|
|
+ * CLKRC[7] "Internal frequency doublers on off seclection"
|
|
|
+ * = 1 (0x01) 1....... "On"
|
|
|
+ * CLKRC[6] "Digital video master slave selection"
|
|
|
+ * = 0 (0x00) .0...... "Master mode, sensor
|
|
|
+ * provides PCLK"
|
|
|
+ * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
|
|
|
+ * = 0 (0x00) ..000000
|
|
|
+ */
|
|
|
+ { 0x11, 0x80 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 12 COMH "Common Control H"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ * COMH[7] "SRST"
|
|
|
+ * = 0 (0x00) 0....... "No-op"
|
|
|
+ * COMH[6:4] "Resolution selection"
|
|
|
+ * = 0 (0x00) .000.... "QXGA"
|
|
|
+ * COMH[3] "Master slave selection"
|
|
|
+ * = 0 (0x00) ....0... "Master mode"
|
|
|
+ * COMH[2] "Internal B/R channel option"
|
|
|
+ * = 0 (0x00) .....0.. "B/R use same channel"
|
|
|
+ * COMH[1] "Color bar test pattern"
|
|
|
+ * = 0 (0x00) ......0. "Off"
|
|
|
+ * COMH[0] "Reserved"
|
|
|
+ * = 0 (0x00) .......0
|
|
|
+ */
|
|
|
+ { 0x12, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 12 COMH "Common Control H"
|
|
|
+ * = 64 (0x40) 01000000
|
|
|
+ * COMH[7] "SRST"
|
|
|
+ * = 0 (0x00) 0....... "No-op"
|
|
|
+ * COMH[6:4] "Resolution selection"
|
|
|
+ * = 4 (0x04) .100.... "XGA"
|
|
|
+ * COMH[3] "Master slave selection"
|
|
|
+ * = 0 (0x00) ....0... "Master mode"
|
|
|
+ * COMH[2] "Internal B/R channel option"
|
|
|
+ * = 0 (0x00) .....0.. "B/R use same channel"
|
|
|
+ * COMH[1] "Color bar test pattern"
|
|
|
+ * = 0 (0x00) ......0. "Off"
|
|
|
+ * COMH[0] "Reserved"
|
|
|
+ * = 0 (0x00) .......0
|
|
|
+ */
|
|
|
+ { 0x12, 0x40 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 17 HREFST "Horizontal window start"
|
|
|
+ * = 31 (0x1F) 00011111
|
|
|
+ * HREFST[7:0] "Horizontal window start, 8 MSBs"
|
|
|
+ * = 31 (0x1F) 00011111
|
|
|
+ */
|
|
|
+ { 0x17, 0x1F },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 18 HREFEND "Horizontal window end"
|
|
|
+ * = 95 (0x5F) 01011111
|
|
|
+ * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
|
|
|
+ * = 95 (0x5F) 01011111
|
|
|
+ */
|
|
|
+ { 0x18, 0x5F },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 19 VSTRT "Vertical window start"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
|
|
|
+ * = 0 (0x00) 00000000
|
|
|
+ */
|
|
|
+ { 0x19, 0x00 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 1A VEND "Vertical window end"
|
|
|
+ * = 96 (0x60) 01100000
|
|
|
+ * VEND[7:0] "Vertical Window End, 8 MSBs"
|
|
|
+ * = 96 (0x60) 01100000
|
|
|
+ */
|
|
|
+ { 0x1a, 0x60 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 32 COMM "Common Control M"
|
|
|
+ * = 18 (0x12) 00010010
|
|
|
+ * COMM[7:6] "Pixel clock divide option"
|
|
|
+ * = 0 (0x00) 00...... "/1"
|
|
|
+ * COMM[5:3] "Horizontal window end position, 3 LSBs"
|
|
|
+ * = 2 (0x02) ..010...
|
|
|
+ * COMM[2:0] "Horizontal window start position, 3 LSBs"
|
|
|
+ * = 2 (0x02) .....010
|
|
|
+ */
|
|
|
+ { 0x32, 0x12 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 03 COMA "Common Control A"
|
|
|
+ * = 74 (0x4A) 01001010
|
|
|
+ * COMA[7:4] "AWB Update Threshold"
|
|
|
+ * = 4 (0x04) 0100....
|
|
|
+ * COMA[3:2] "Vertical window end line control 2 LSBs"
|
|
|
+ * = 2 (0x02) ....10..
|
|
|
+ * COMA[1:0] "Vertical window start line control 2 LSBs"
|
|
|
+ * = 2 (0x02) ......10
|
|
|
+ */
|
|
|
+ { 0x03, 0x4A },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 02 RED "Red Gain Control"
|
|
|
+ * = 175 (0xAF) 10101111
|
|
|
+ * RED[7] "Action"
|
|
|
+ * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
|
|
|
+ * RED[6:0] "Value"
|
|
|
+ * = 47 (0x2F) .0101111
|
|
|
+ */
|
|
|
+ { 0x02, 0xAF },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 2D ADDVSL "VSYNC Pulse Width"
|
|
|
+ * = 210 (0xD2) 11010010
|
|
|
+ * ADDVSL[7:0] "VSYNC pulse width, LSB"
|
|
|
+ * = 210 (0xD2) 11010010
|
|
|
+ */
|
|
|
+ { 0x2d, 0xD2 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 00 GAIN = 24 (0x18) 00011000
|
|
|
+ * GAIN[7:6] "Reserved"
|
|
|
+ * = 0 (0x00) 00......
|
|
|
+ * GAIN[5] "Double"
|
|
|
+ * = 0 (0x00) ..0..... "False"
|
|
|
+ * GAIN[4] "Double"
|
|
|
+ * = 1 (0x01) ...1.... "True"
|
|
|
+ * GAIN[3:0] "Range"
|
|
|
+ * = 8 (0x08) ....1000
|
|
|
+ */
|
|
|
+ { 0x00, 0x18 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 01 BLUE "Blue Gain Control"
|
|
|
+ * = 240 (0xF0) 11110000
|
|
|
+ * BLUE[7] "Action"
|
|
|
+ * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
|
|
|
+ * BLUE[6:0] "Value"
|
|
|
+ * = 112 (0x70) .1110000
|
|
|
+ */
|
|
|
+ { 0x01, 0xF0 },
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 10 AEC "Automatic Exposure Control"
|
|
|
+ * = 10 (0x0A) 00001010
|
|
|
+ * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
|
|
|
+ * = 10 (0x0A) 00001010
|
|
|
+ */
|
|
|
+ { 0x10, 0x0A },
|
|
|
+
|
|
|
+ { 0xE1, 0x67 },
|
|
|
+ { 0xE3, 0x03 },
|
|
|
+ { 0xE4, 0x26 },
|
|
|
+ { 0xE5, 0x3E },
|
|
|
+ { 0xF8, 0x01 },
|
|
|
+ { 0xFF, 0x01 },
|
|
|
+};
|
|
|
+
|
|
|
static const struct ov_i2c_regvals norm_6x20[] = {
|
|
|
{ 0x12, 0x80 }, /* reset */
|
|
|
{ 0x11, 0x01 },
|
|
@@ -1514,6 +2271,39 @@ static int write_i2c_regvals(struct sd *sd,
|
|
|
*
|
|
|
***************************************************************************/
|
|
|
|
|
|
+/* This initializes the OV2x10 / OV3610 / OV3620 */
|
|
|
+static int ov_hires_configure(struct sd *sd)
|
|
|
+{
|
|
|
+ int high, low;
|
|
|
+
|
|
|
+ if (sd->bridge != BRIDGE_OVFX2) {
|
|
|
+ PDEBUG(D_ERR, "error hires sensors only supported with ovfx2");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ PDEBUG(D_PROBE, "starting ov hires configuration");
|
|
|
+
|
|
|
+ /* Detect sensor (sub)type */
|
|
|
+ high = i2c_r(sd, 0x0a);
|
|
|
+ low = i2c_r(sd, 0x0b);
|
|
|
+ /* info("%x, %x", high, low); */
|
|
|
+ if (high == 0x96 && low == 0x40) {
|
|
|
+ PDEBUG(D_PROBE, "Sensor is an OV2610");
|
|
|
+ sd->sensor = SEN_OV2610;
|
|
|
+ } else if (high == 0x36 && (low & 0x0f) == 0x00) {
|
|
|
+ PDEBUG(D_PROBE, "Sensor is an OV3610");
|
|
|
+ sd->sensor = SEN_OV3610;
|
|
|
+ } else {
|
|
|
+ PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x",
|
|
|
+ high, low);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Set sensor-specific vars */
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
|
|
|
* the same register settings as the OV8610, since they are very similar.
|
|
|
*/
|
|
@@ -2024,6 +2814,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|
|
PDEBUG(D_ERR, "Failed to configure OV8xx0");
|
|
|
goto error;
|
|
|
}
|
|
|
+ /* Test for 3xxx / 2xxx */
|
|
|
+ } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
|
|
|
+ if (ov_hires_configure(sd) < 0) {
|
|
|
+ PDEBUG(D_ERR, "Failed to configure high res OV");
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
} else {
|
|
|
PDEBUG(D_ERR, "Can't determine sensor slave IDs");
|
|
|
goto error;
|
|
@@ -2060,6 +2856,21 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|
|
cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
|
|
|
}
|
|
|
break;
|
|
|
+ case BRIDGE_OVFX2:
|
|
|
+ if (sd->sensor == SEN_OV2610) {
|
|
|
+ cam->cam_mode = ovfx2_ov2610_mode;
|
|
|
+ cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
|
|
|
+ } else if (sd->sensor == SEN_OV3610) {
|
|
|
+ cam->cam_mode = ovfx2_ov3610_mode;
|
|
|
+ cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
|
|
|
+ } else if (!sd->sif) {
|
|
|
+ cam->cam_mode = ov519_vga_mode;
|
|
|
+ cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
|
|
|
+ } else {
|
|
|
+ cam->cam_mode = ov519_sif_mode;
|
|
|
+ cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
sd->brightness = BRIGHTNESS_DEF;
|
|
|
if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
|
|
@@ -2083,6 +2894,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|
|
/* OV8610 Frequency filter control should work but needs testing */
|
|
|
if (sd->sensor == SEN_OV8610)
|
|
|
gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
|
|
|
+ /* No controls for the OV2610/OV3610 */
|
|
|
+ if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
|
|
|
+ gspca_dev->ctrl_dis |= 0xFF;
|
|
|
|
|
|
return 0;
|
|
|
error:
|
|
@@ -2097,6 +2911,20 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
|
|
|
|
|
/* initialize the sensor */
|
|
|
switch (sd->sensor) {
|
|
|
+ case SEN_OV2610:
|
|
|
+ if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
|
|
|
+ return -EIO;
|
|
|
+ /* Enable autogain, autoexpo, awb, bandfilter */
|
|
|
+ if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
|
|
|
+ return -EIO;
|
|
|
+ break;
|
|
|
+ case SEN_OV3610:
|
|
|
+ if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
|
|
|
+ return -EIO;
|
|
|
+ /* Enable autogain, autoexpo, awb, bandfilter */
|
|
|
+ if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
|
|
|
+ return -EIO;
|
|
|
+ break;
|
|
|
case SEN_OV6620:
|
|
|
if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
|
|
|
return -EIO;
|
|
@@ -2546,6 +3374,42 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
|
|
|
|
|
|
/******** Mode (VGA/QVGA) and sensor specific regs ********/
|
|
|
switch (sd->sensor) {
|
|
|
+ case SEN_OV2610:
|
|
|
+ i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
|
|
|
+ i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
|
|
|
+ i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
|
|
|
+ i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
|
|
|
+ i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
|
|
|
+ i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
|
|
|
+ i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
|
|
|
+ return 0;
|
|
|
+ case SEN_OV3610: {
|
|
|
+ int xstart, xend, ystart, yend;
|
|
|
+
|
|
|
+ if (qvga) {
|
|
|
+ xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
|
|
|
+ ystart = (772 - gspca_dev->height) / 2;
|
|
|
+ } else {
|
|
|
+ xstart = (2080 - gspca_dev->width) / 2 + (0x10 << 4);
|
|
|
+ ystart = (1544 - gspca_dev->height) / 2;
|
|
|
+ }
|
|
|
+ xend = xstart + gspca_dev->width;
|
|
|
+ yend = ystart + gspca_dev->height;
|
|
|
+ /* Writing to the COMH register resets the other windowing regs
|
|
|
+ to their default values, so we must do this first. */
|
|
|
+ i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
|
|
|
+ i2c_w_mask(sd, 0x32,
|
|
|
+ (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
|
|
|
+ 0x3f);
|
|
|
+ i2c_w_mask(sd, 0x03,
|
|
|
+ (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
|
|
|
+ 0x0f);
|
|
|
+ i2c_w(sd, 0x17, xstart >> 4);
|
|
|
+ i2c_w(sd, 0x18, xend >> 4);
|
|
|
+ i2c_w(sd, 0x19, ystart >> 3);
|
|
|
+ i2c_w(sd, 0x1a, yend >> 3);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
case SEN_OV8610:
|
|
|
/* For OV8610 qvga means qsvga */
|
|
|
i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
|
|
@@ -2653,6 +3517,10 @@ static int set_ov_sensor_window(struct sd *sd)
|
|
|
int ret, hstart, hstop, vstop, vstart;
|
|
|
__u8 v;
|
|
|
|
|
|
+ /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
|
|
|
+ if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
|
|
|
+ return mode_init_ov_sensor_regs(sd);
|
|
|
+
|
|
|
gspca_dev = &sd->gspca_dev;
|
|
|
qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
|
|
|
crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2;
|
|
@@ -3115,7 +3983,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
|
|
|
|
|
static void setautobrightness(struct sd *sd)
|
|
|
{
|
|
|
- if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
|
|
|
+ if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 ||
|
|
|
+ sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
|
|
|
return;
|
|
|
|
|
|
i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
|
|
@@ -3123,6 +3992,9 @@ static void setautobrightness(struct sd *sd)
|
|
|
|
|
|
static void setfreq(struct sd *sd)
|
|
|
{
|
|
|
+ if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
|
|
|
+ return;
|
|
|
+
|
|
|
if (sd->sensor == SEN_OV7670) {
|
|
|
switch (sd->freq) {
|
|
|
case 0: /* Banding filter disabled */
|