|
@@ -82,7 +82,7 @@ struct sd {
|
|
|
#define BRIDGE_OV511PLUS 1
|
|
|
#define BRIDGE_OV518 2
|
|
|
#define BRIDGE_OV518PLUS 3
|
|
|
-#define BRIDGE_OV519 4
|
|
|
+#define BRIDGE_OV519 4 /* = ov530 */
|
|
|
#define BRIDGE_OVFX2 5
|
|
|
#define BRIDGE_W9968CF 6
|
|
|
#define BRIDGE_MASK 7
|
|
@@ -127,6 +127,7 @@ enum sensors {
|
|
|
SEN_OV7620AE,
|
|
|
SEN_OV7640,
|
|
|
SEN_OV7648,
|
|
|
+ SEN_OV7660,
|
|
|
SEN_OV7670,
|
|
|
SEN_OV76BE,
|
|
|
SEN_OV8610,
|
|
@@ -183,7 +184,7 @@ static const struct ctrl sd_ctrls[] = {
|
|
|
},
|
|
|
.set_control = setcolors,
|
|
|
},
|
|
|
-/* The flip controls work with ov7670 only */
|
|
|
+/* The flip controls work for sensors ov7660 and ov7670 only */
|
|
|
[HFLIP] = {
|
|
|
{
|
|
|
.id = V4L2_CID_HFLIP,
|
|
@@ -268,6 +269,8 @@ static const unsigned ctrl_dis[] = {
|
|
|
(1 << AUTOBRIGHT) |
|
|
|
(1 << CONTRAST),
|
|
|
|
|
|
+[SEN_OV7660] = (1 << AUTOBRIGHT),
|
|
|
+
|
|
|
[SEN_OV7670] = (1 << COLORS) |
|
|
|
(1 << AUTOBRIGHT),
|
|
|
|
|
@@ -572,7 +575,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
|
|
|
#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
|
|
|
#define OV7610_REG_COM_I 0x29 /* misc settings */
|
|
|
|
|
|
-/* OV7670 registers */
|
|
|
+/* OV7660 and OV7670 registers */
|
|
|
#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
|
|
|
#define OV7670_R01_BLUE 0x01 /* blue gain */
|
|
|
#define OV7670_R02_RED 0x02 /* red gain */
|
|
@@ -625,6 +628,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
|
|
|
/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */
|
|
|
#define OV7670_R41_COM16 0x41 /* Control 16 */
|
|
|
#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
|
|
|
+/* end of ov7660 common registers */
|
|
|
#define OV7670_R55_BRIGHT 0x55 /* Brightness */
|
|
|
#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
|
|
|
#define OV7670_R69_GFIX 0x69 /* Fix gain control */
|
|
@@ -1577,6 +1581,150 @@ static const struct ov_i2c_regvals norm_7640[] = {
|
|
|
{ 0x12, 0x14 },
|
|
|
};
|
|
|
|
|
|
+static const struct ov_regvals init_519_ov7660[] = {
|
|
|
+ { 0x5d, 0x03 }, /* Turn off suspend mode */
|
|
|
+ { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */
|
|
|
+ { 0x54, 0x0f }, /* bit2 (jpeg enable) */
|
|
|
+ { 0xa2, 0x20 }, /* a2-a5 are undocumented */
|
|
|
+ { 0xa3, 0x18 },
|
|
|
+ { 0xa4, 0x04 },
|
|
|
+ { 0xa5, 0x28 },
|
|
|
+ { 0x37, 0x00 }, /* SetUsbInit */
|
|
|
+ { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
|
|
|
+ /* Enable both fields, YUV Input, disable defect comp (why?) */
|
|
|
+ { 0x20, 0x0c }, /* 0x0d does U <-> V swap */
|
|
|
+ { 0x21, 0x38 },
|
|
|
+ { 0x22, 0x1d },
|
|
|
+ { 0x17, 0x50 }, /* undocumented */
|
|
|
+ { 0x37, 0x00 }, /* undocumented */
|
|
|
+ { 0x40, 0xff }, /* I2C timeout counter */
|
|
|
+ { 0x46, 0x00 }, /* I2C clock prescaler */
|
|
|
+};
|
|
|
+static const struct ov_i2c_regvals norm_7660[] = {
|
|
|
+ {OV7670_R12_COM7, OV7670_COM7_RESET},
|
|
|
+ {OV7670_R11_CLKRC, 0x81},
|
|
|
+ {0x92, 0x00}, /* DM_LNL */
|
|
|
+ {0x93, 0x00}, /* DM_LNH */
|
|
|
+ {0x9d, 0x4c}, /* BD50ST */
|
|
|
+ {0x9e, 0x3f}, /* BD60ST */
|
|
|
+ {OV7670_R3B_COM11, 0x02},
|
|
|
+ {OV7670_R13_COM8, 0xf5},
|
|
|
+ {OV7670_R10_AECH, 0x00},
|
|
|
+ {OV7670_R00_GAIN, 0x00},
|
|
|
+ {OV7670_R01_BLUE, 0x7c},
|
|
|
+ {OV7670_R02_RED, 0x9d},
|
|
|
+ {OV7670_R12_COM7, 0x00},
|
|
|
+ {OV7670_R04_COM1, 00},
|
|
|
+ {OV7670_R18_HSTOP, 0x01},
|
|
|
+ {OV7670_R17_HSTART, 0x13},
|
|
|
+ {OV7670_R32_HREF, 0x92},
|
|
|
+ {OV7670_R19_VSTART, 0x02},
|
|
|
+ {OV7670_R1A_VSTOP, 0x7a},
|
|
|
+ {OV7670_R03_VREF, 0x00},
|
|
|
+ {OV7670_R0E_COM5, 0x04},
|
|
|
+ {OV7670_R0F_COM6, 0x62},
|
|
|
+ {OV7670_R15_COM10, 0x00},
|
|
|
+ {0x16, 0x02}, /* RSVD */
|
|
|
+ {0x1b, 0x00}, /* PSHFT */
|
|
|
+ {OV7670_R1E_MVFP, 0x01},
|
|
|
+ {0x29, 0x3c}, /* RSVD */
|
|
|
+ {0x33, 0x00}, /* CHLF */
|
|
|
+ {0x34, 0x07}, /* ARBLM */
|
|
|
+ {0x35, 0x84}, /* RSVD */
|
|
|
+ {0x36, 0x00}, /* RSVD */
|
|
|
+ {0x37, 0x04}, /* ADC */
|
|
|
+ {0x39, 0x43}, /* OFON */
|
|
|
+ {OV7670_R3A_TSLB, 0x00},
|
|
|
+ {OV7670_R3C_COM12, 0x6c},
|
|
|
+ {OV7670_R3D_COM13, 0x98},
|
|
|
+ {OV7670_R3F_EDGE, 0x23},
|
|
|
+ {OV7670_R40_COM15, 0xc1},
|
|
|
+ {OV7670_R41_COM16, 0x22},
|
|
|
+ {0x6b, 0x0a}, /* DBLV */
|
|
|
+ {0xa1, 0x08}, /* RSVD */
|
|
|
+ {0x69, 0x80}, /* HV */
|
|
|
+ {0x43, 0xf0}, /* RSVD.. */
|
|
|
+ {0x44, 0x10},
|
|
|
+ {0x45, 0x78},
|
|
|
+ {0x46, 0xa8},
|
|
|
+ {0x47, 0x60},
|
|
|
+ {0x48, 0x80},
|
|
|
+ {0x59, 0xba},
|
|
|
+ {0x5a, 0x9a},
|
|
|
+ {0x5b, 0x22},
|
|
|
+ {0x5c, 0xb9},
|
|
|
+ {0x5d, 0x9b},
|
|
|
+ {0x5e, 0x10},
|
|
|
+ {0x5f, 0xe0},
|
|
|
+ {0x60, 0x85},
|
|
|
+ {0x61, 0x60},
|
|
|
+ {0x9f, 0x9d}, /* RSVD */
|
|
|
+ {0xa0, 0xa0}, /* DSPC2 */
|
|
|
+ {0x4f, 0x60}, /* matrix */
|
|
|
+ {0x50, 0x64},
|
|
|
+ {0x51, 0x04},
|
|
|
+ {0x52, 0x18},
|
|
|
+ {0x53, 0x3c},
|
|
|
+ {0x54, 0x54},
|
|
|
+ {0x55, 0x40},
|
|
|
+ {0x56, 0x40},
|
|
|
+ {0x57, 0x40},
|
|
|
+ {0x58, 0x0d}, /* matrix sign */
|
|
|
+ {0x8b, 0xcc}, /* RSVD */
|
|
|
+ {0x8c, 0xcc},
|
|
|
+ {0x8d, 0xcf},
|
|
|
+ {0x6c, 0x40}, /* gamma curve */
|
|
|
+ {0x6d, 0xe0},
|
|
|
+ {0x6e, 0xa0},
|
|
|
+ {0x6f, 0x80},
|
|
|
+ {0x70, 0x70},
|
|
|
+ {0x71, 0x80},
|
|
|
+ {0x72, 0x60},
|
|
|
+ {0x73, 0x60},
|
|
|
+ {0x74, 0x50},
|
|
|
+ {0x75, 0x40},
|
|
|
+ {0x76, 0x38},
|
|
|
+ {0x77, 0x3c},
|
|
|
+ {0x78, 0x32},
|
|
|
+ {0x79, 0x1a},
|
|
|
+ {0x7a, 0x28},
|
|
|
+ {0x7b, 0x24},
|
|
|
+ {0x7c, 0x04}, /* gamma curve */
|
|
|
+ {0x7d, 0x12},
|
|
|
+ {0x7e, 0x26},
|
|
|
+ {0x7f, 0x46},
|
|
|
+ {0x80, 0x54},
|
|
|
+ {0x81, 0x64},
|
|
|
+ {0x82, 0x70},
|
|
|
+ {0x83, 0x7c},
|
|
|
+ {0x84, 0x86},
|
|
|
+ {0x85, 0x8e},
|
|
|
+ {0x86, 0x9c},
|
|
|
+ {0x87, 0xab},
|
|
|
+ {0x88, 0xc4},
|
|
|
+ {0x89, 0xd1},
|
|
|
+ {0x8a, 0xe5},
|
|
|
+ {OV7670_R14_COM9, 0x1e},
|
|
|
+ {OV7670_R24_AEW, 0x80},
|
|
|
+ {OV7670_R25_AEB, 0x72},
|
|
|
+ {OV7670_R26_VPT, 0xb3},
|
|
|
+ {0x62, 0x80}, /* LCC1 */
|
|
|
+ {0x63, 0x80}, /* LCC2 */
|
|
|
+ {0x64, 0x06}, /* LCC3 */
|
|
|
+ {0x65, 0x00}, /* LCC4 */
|
|
|
+ {0x66, 0x01}, /* LCC5 */
|
|
|
+ {0x94, 0x0e}, /* RSVD.. */
|
|
|
+ {0x95, 0x14},
|
|
|
+ {OV7670_R13_COM8, OV7670_COM8_FASTAEC
|
|
|
+ | OV7670_COM8_AECSTEP
|
|
|
+ | OV7670_COM8_BFILT
|
|
|
+ | 0x10
|
|
|
+ | OV7670_COM8_AGC
|
|
|
+ | OV7670_COM8_AWB
|
|
|
+ | OV7670_COM8_AEC},
|
|
|
+ {0xa1, 0xc8}
|
|
|
+};
|
|
|
+
|
|
|
/* 7670. Defaults taken from OmniVision provided data,
|
|
|
* as provided by Jonathan Corbet of OLPC */
|
|
|
static const struct ov_i2c_regvals norm_7670[] = {
|
|
@@ -2574,6 +2722,11 @@ static void ov7xx0_configure(struct sd *sd)
|
|
|
PDEBUG(D_PROBE, "Sensor is an OV7648");
|
|
|
sd->sensor = SEN_OV7648;
|
|
|
break;
|
|
|
+ case 0x60:
|
|
|
+ PDEBUG(D_PROBE, "Sensor is a OV7660");
|
|
|
+ sd->sensor = SEN_OV7660;
|
|
|
+ sd->invert_led = 0;
|
|
|
+ break;
|
|
|
default:
|
|
|
PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
|
|
|
return;
|
|
@@ -2935,6 +3088,91 @@ static void ovfx2_configure(struct sd *sd)
|
|
|
write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
|
|
|
}
|
|
|
|
|
|
+/* set the mode */
|
|
|
+/* This function works for ov7660 only */
|
|
|
+static void ov519_set_mode(struct sd *sd)
|
|
|
+{
|
|
|
+ static const struct ov_regvals bridge_ov7660[2][10] = {
|
|
|
+ {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
|
|
|
+ {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
|
|
|
+ {0x25, 0x01}, {0x26, 0x00}},
|
|
|
+ {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
|
|
|
+ {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
|
|
|
+ {0x25, 0x03}, {0x26, 0x00}}
|
|
|
+ };
|
|
|
+ static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
|
|
|
+ {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
|
|
|
+ {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
|
|
|
+ };
|
|
|
+ static const struct ov_i2c_regvals sensor_ov7660_2[] = {
|
|
|
+ {OV7670_R17_HSTART, 0x13},
|
|
|
+ {OV7670_R18_HSTOP, 0x01},
|
|
|
+ {OV7670_R32_HREF, 0x92},
|
|
|
+ {OV7670_R19_VSTART, 0x02},
|
|
|
+ {OV7670_R1A_VSTOP, 0x7a},
|
|
|
+ {OV7670_R03_VREF, 0x00},
|
|
|
+/* {0x33, 0x00}, */
|
|
|
+/* {0x34, 0x07}, */
|
|
|
+/* {0x36, 0x00}, */
|
|
|
+/* {0x6b, 0x0a}, */
|
|
|
+ };
|
|
|
+
|
|
|
+ write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
|
|
|
+ ARRAY_SIZE(bridge_ov7660[0]));
|
|
|
+ write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
|
|
|
+ ARRAY_SIZE(sensor_ov7660[0]));
|
|
|
+ write_i2c_regvals(sd, sensor_ov7660_2,
|
|
|
+ ARRAY_SIZE(sensor_ov7660_2));
|
|
|
+}
|
|
|
+
|
|
|
+/* set the frame rate */
|
|
|
+/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */
|
|
|
+static void ov519_set_fr(struct sd *sd)
|
|
|
+{
|
|
|
+ int fr;
|
|
|
+ u8 clock;
|
|
|
+ /* frame rate table with indices:
|
|
|
+ * - mode = 0: 320x240, 1: 640x480
|
|
|
+ * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5
|
|
|
+ * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock)
|
|
|
+ */
|
|
|
+ static const u8 fr_tb[2][6][3] = {
|
|
|
+ {{0x04, 0xff, 0x00},
|
|
|
+ {0x04, 0x1f, 0x00},
|
|
|
+ {0x04, 0x1b, 0x00},
|
|
|
+ {0x04, 0x15, 0x00},
|
|
|
+ {0x04, 0x09, 0x00},
|
|
|
+ {0x04, 0x01, 0x00}},
|
|
|
+ {{0x0c, 0xff, 0x00},
|
|
|
+ {0x0c, 0x1f, 0x00},
|
|
|
+ {0x0c, 0x1b, 0x00},
|
|
|
+ {0x04, 0xff, 0x01},
|
|
|
+ {0x04, 0x1f, 0x01},
|
|
|
+ {0x04, 0x1b, 0x01}},
|
|
|
+ };
|
|
|
+
|
|
|
+ if (frame_rate > 0)
|
|
|
+ sd->frame_rate = frame_rate;
|
|
|
+ if (sd->frame_rate >= 30)
|
|
|
+ fr = 0;
|
|
|
+ else if (sd->frame_rate >= 25)
|
|
|
+ fr = 1;
|
|
|
+ else if (sd->frame_rate >= 20)
|
|
|
+ fr = 2;
|
|
|
+ else if (sd->frame_rate >= 15)
|
|
|
+ fr = 3;
|
|
|
+ else if (sd->frame_rate >= 10)
|
|
|
+ fr = 4;
|
|
|
+ else
|
|
|
+ fr = 5;
|
|
|
+ reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
|
|
|
+ reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
|
|
|
+ clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
|
|
|
+ if (sd->sensor == SEN_OV7660)
|
|
|
+ clock |= 0x80; /* enable double clock */
|
|
|
+ ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
|
|
|
+}
|
|
|
+
|
|
|
/* this function is called at probe time */
|
|
|
static int sd_config(struct gspca_dev *gspca_dev,
|
|
|
const struct usb_device_id *id)
|
|
@@ -3118,6 +3356,34 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
|
|
case SEN_OV7648:
|
|
|
write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
|
|
|
break;
|
|
|
+ case SEN_OV7660:
|
|
|
+ i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
|
|
|
+ msleep(14);
|
|
|
+ reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
|
|
|
+ write_regvals(sd, init_519_ov7660,
|
|
|
+ ARRAY_SIZE(init_519_ov7660));
|
|
|
+ write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
|
|
|
+ sd->gspca_dev.curr_mode = 1; /* 640x480 */
|
|
|
+ sd->frame_rate = 15;
|
|
|
+ ov519_set_mode(sd);
|
|
|
+ ov519_set_fr(sd);
|
|
|
+ sd->ctrls[COLORS].max = 4; /* 0..4 */
|
|
|
+ sd->ctrls[COLORS].val =
|
|
|
+ sd->ctrls[COLORS].def = 2;
|
|
|
+ setcolors(gspca_dev);
|
|
|
+ sd->ctrls[CONTRAST].max = 6; /* 0..6 */
|
|
|
+ sd->ctrls[CONTRAST].val =
|
|
|
+ sd->ctrls[CONTRAST].def = 3;
|
|
|
+ setcontrast(gspca_dev);
|
|
|
+ sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */
|
|
|
+ sd->ctrls[BRIGHTNESS].val =
|
|
|
+ sd->ctrls[BRIGHTNESS].def = 3;
|
|
|
+ setbrightness(gspca_dev);
|
|
|
+ sd_reset_snapshot(gspca_dev);
|
|
|
+ ov51x_restart(sd);
|
|
|
+ ov51x_stop(sd); /* not in win traces */
|
|
|
+ ov51x_led_control(sd, 0);
|
|
|
+ break;
|
|
|
case SEN_OV7670:
|
|
|
sd->ctrls[FREQ].max = 3; /* auto */
|
|
|
sd->ctrls[FREQ].def = 3;
|
|
@@ -3431,16 +3697,21 @@ static void ov519_mode_init_regs(struct sd *sd)
|
|
|
};
|
|
|
|
|
|
/******** Set the mode ********/
|
|
|
- if (sd->sensor != SEN_OV7670) {
|
|
|
+ switch (sd->sensor) {
|
|
|
+ default:
|
|
|
write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
|
|
|
if (sd->sensor == SEN_OV7640 ||
|
|
|
sd->sensor == SEN_OV7648) {
|
|
|
/* Select 8-bit input mode */
|
|
|
reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
|
|
|
}
|
|
|
- } else {
|
|
|
+ break;
|
|
|
+ case SEN_OV7660:
|
|
|
+ return; /* done by ov519_set_mode/fr() */
|
|
|
+ case SEN_OV7670:
|
|
|
write_regvals(sd, mode_init_519_ov7670,
|
|
|
ARRAY_SIZE(mode_init_519_ov7670));
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
|
|
@@ -3682,6 +3953,7 @@ static void mode_init_ov_sensor_regs(struct sd *sd)
|
|
|
i2c_w(sd, 0x11, sd->clockdiv);
|
|
|
}
|
|
|
|
|
|
+/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */
|
|
|
static void sethvflip(struct gspca_dev *gspca_dev)
|
|
|
{
|
|
|
struct sd *sd = (struct sd *) gspca_dev;
|
|
@@ -3703,11 +3975,18 @@ static void set_ov_sensor_window(struct sd *sd)
|
|
|
int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
|
|
|
|
|
|
/* mode setup is fully handled in mode_init_ov_sensor_regs for these */
|
|
|
- if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
|
|
|
- sd->sensor == SEN_OV7670) {
|
|
|
+ switch (sd->sensor) {
|
|
|
+ case SEN_OV2610:
|
|
|
+ case SEN_OV3610:
|
|
|
+ case SEN_OV7670:
|
|
|
mode_init_ov_sensor_regs(sd);
|
|
|
return;
|
|
|
+ case SEN_OV7660:
|
|
|
+ ov519_set_mode(sd);
|
|
|
+ ov519_set_fr(sd);
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
gspca_dev = &sd->gspca_dev;
|
|
|
qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
|
|
|
crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
|
|
@@ -4101,6 +4380,22 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
|
|
{
|
|
|
struct sd *sd = (struct sd *) gspca_dev;
|
|
|
int val;
|
|
|
+ static const struct ov_i2c_regvals brit_7660[][7] = {
|
|
|
+ {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
|
|
|
+ {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
|
|
|
+ {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
|
|
|
+ {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
|
|
|
+ {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
|
|
|
+ {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
|
|
|
+ {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
|
|
|
+ {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
|
|
|
+ {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
|
|
|
+ {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
|
|
|
+ {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
|
|
|
+ {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
|
|
|
+ {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
|
|
|
+ {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
|
|
|
+ };
|
|
|
|
|
|
val = sd->ctrls[BRIGHTNESS].val;
|
|
|
switch (sd->sensor) {
|
|
@@ -4120,6 +4415,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
|
|
if (!sd->ctrls[AUTOBRIGHT].val)
|
|
|
i2c_w(sd, OV7610_REG_BRT, val);
|
|
|
break;
|
|
|
+ case SEN_OV7660:
|
|
|
+ write_i2c_regvals(sd, brit_7660[val],
|
|
|
+ ARRAY_SIZE(brit_7660[0]));
|
|
|
+ break;
|
|
|
case SEN_OV7670:
|
|
|
/*win trace
|
|
|
* i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
|
|
@@ -4132,6 +4431,64 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|
|
{
|
|
|
struct sd *sd = (struct sd *) gspca_dev;
|
|
|
int val;
|
|
|
+ static const struct ov_i2c_regvals contrast_7660[][31] = {
|
|
|
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
|
|
|
+ {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
|
|
|
+ {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
|
|
|
+ {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
|
|
|
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
|
|
|
+ {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
|
|
|
+ {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
|
|
|
+ {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
|
|
|
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
|
|
|
+ {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
|
|
|
+ {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
|
|
|
+ {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
|
|
|
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
|
|
|
+ {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
|
|
|
+ {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
|
|
|
+ {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
|
|
|
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
|
|
|
+ {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
|
|
|
+ {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
|
|
|
+ {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
|
|
|
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
|
|
|
+ {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
|
|
|
+ {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
|
|
|
+ {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
|
|
|
+ {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
|
|
|
+ {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
|
|
|
+ {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
|
|
|
+ {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
|
|
|
+ {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
|
|
|
+ {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
|
|
|
+ {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
|
|
|
+ {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
|
|
|
+ {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
|
|
|
+ {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
|
|
|
+ {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
|
|
|
+ {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
|
|
|
+ {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
|
|
|
+ {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
|
|
|
+ {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
|
|
|
+ {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
|
|
|
+ {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
|
|
|
+ {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
|
|
|
+ {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
|
|
|
+ {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
|
|
|
+ {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
|
|
|
+ {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
|
|
|
+ {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
|
|
|
+ {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
|
|
|
+ {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
|
|
|
+ {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
|
|
|
+ {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
|
|
|
+ {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
|
|
|
+ {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
|
|
|
+ {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
|
|
|
+ {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
|
|
|
+ {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
|
|
|
+ };
|
|
|
|
|
|
val = sd->ctrls[CONTRAST].val;
|
|
|
switch (sd->sensor) {
|
|
@@ -4163,6 +4520,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
|
|
i2c_w(sd, 0x64, ctab[val >> 4]);
|
|
|
break;
|
|
|
}
|
|
|
+ case SEN_OV7660:
|
|
|
+ write_i2c_regvals(sd, contrast_7660[val],
|
|
|
+ ARRAY_SIZE(contrast_7660[0]));
|
|
|
+ break;
|
|
|
case SEN_OV7670:
|
|
|
/* check that this isn't just the same as ov7610 */
|
|
|
i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
|
|
@@ -4174,6 +4535,18 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
|
|
{
|
|
|
struct sd *sd = (struct sd *) gspca_dev;
|
|
|
int val;
|
|
|
+ static const struct ov_i2c_regvals colors_7660[][6] = {
|
|
|
+ {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
|
|
|
+ {0x53, 0x19}, {0x54, 0x23}},
|
|
|
+ {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
|
|
|
+ {0x53, 0x2c}, {0x54, 0x3e}},
|
|
|
+ {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
|
|
|
+ {0x53, 0x40}, {0x54, 0x59}},
|
|
|
+ {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
|
|
|
+ {0x53, 0x53}, {0x54, 0x73}},
|
|
|
+ {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
|
|
|
+ {0x53, 0x66}, {0x54, 0x8e}},
|
|
|
+ };
|
|
|
|
|
|
val = sd->ctrls[COLORS].val;
|
|
|
switch (sd->sensor) {
|
|
@@ -4197,6 +4570,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
|
|
case SEN_OV7648:
|
|
|
i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
|
|
|
break;
|
|
|
+ case SEN_OV7660:
|
|
|
+ write_i2c_regvals(sd, colors_7660[val],
|
|
|
+ ARRAY_SIZE(colors_7660[0]));
|
|
|
+ break;
|
|
|
case SEN_OV7670:
|
|
|
/* supported later once I work out how to do it
|
|
|
* transparently fail now! */
|
|
@@ -4214,7 +4591,8 @@ static void setautobright(struct gspca_dev *gspca_dev)
|
|
|
|
|
|
static void setfreq_i(struct sd *sd)
|
|
|
{
|
|
|
- if (sd->sensor == SEN_OV7670) {
|
|
|
+ if (sd->sensor == SEN_OV7660
|
|
|
+ || sd->sensor == SEN_OV7670) {
|
|
|
switch (sd->ctrls[FREQ].val) {
|
|
|
case 0: /* Banding filter disabled */
|
|
|
i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
|