[media] gspca - ov519: New sensor ov7660 with bridge ov530 (ov519)
[mchehab@redhat.com: Some CodingStyle fixes] Tested-by: Anca Emanuel <anca.emanuel@gmail.com> Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
7491f785dd
commit
42e142f6b7
|
@ -82,7 +82,7 @@ struct sd {
|
||||||
#define BRIDGE_OV511PLUS 1
|
#define BRIDGE_OV511PLUS 1
|
||||||
#define BRIDGE_OV518 2
|
#define BRIDGE_OV518 2
|
||||||
#define BRIDGE_OV518PLUS 3
|
#define BRIDGE_OV518PLUS 3
|
||||||
#define BRIDGE_OV519 4
|
#define BRIDGE_OV519 4 /* = ov530 */
|
||||||
#define BRIDGE_OVFX2 5
|
#define BRIDGE_OVFX2 5
|
||||||
#define BRIDGE_W9968CF 6
|
#define BRIDGE_W9968CF 6
|
||||||
#define BRIDGE_MASK 7
|
#define BRIDGE_MASK 7
|
||||||
|
@ -127,6 +127,7 @@ enum sensors {
|
||||||
SEN_OV7620AE,
|
SEN_OV7620AE,
|
||||||
SEN_OV7640,
|
SEN_OV7640,
|
||||||
SEN_OV7648,
|
SEN_OV7648,
|
||||||
|
SEN_OV7660,
|
||||||
SEN_OV7670,
|
SEN_OV7670,
|
||||||
SEN_OV76BE,
|
SEN_OV76BE,
|
||||||
SEN_OV8610,
|
SEN_OV8610,
|
||||||
|
@ -183,7 +184,7 @@ static const struct ctrl sd_ctrls[] = {
|
||||||
},
|
},
|
||||||
.set_control = setcolors,
|
.set_control = setcolors,
|
||||||
},
|
},
|
||||||
/* The flip controls work with ov7670 only */
|
/* The flip controls work for sensors ov7660 and ov7670 only */
|
||||||
[HFLIP] = {
|
[HFLIP] = {
|
||||||
{
|
{
|
||||||
.id = V4L2_CID_HFLIP,
|
.id = V4L2_CID_HFLIP,
|
||||||
|
@ -268,6 +269,8 @@ static const unsigned ctrl_dis[] = {
|
||||||
(1 << AUTOBRIGHT) |
|
(1 << AUTOBRIGHT) |
|
||||||
(1 << CONTRAST),
|
(1 << CONTRAST),
|
||||||
|
|
||||||
|
[SEN_OV7660] = (1 << AUTOBRIGHT),
|
||||||
|
|
||||||
[SEN_OV7670] = (1 << COLORS) |
|
[SEN_OV7670] = (1 << COLORS) |
|
||||||
(1 << AUTOBRIGHT),
|
(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_ID_LOW 0x1d /* manufacturer ID LSB */
|
||||||
#define OV7610_REG_COM_I 0x29 /* misc settings */
|
#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_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
|
||||||
#define OV7670_R01_BLUE 0x01 /* blue gain */
|
#define OV7670_R01_BLUE 0x01 /* blue gain */
|
||||||
#define OV7670_R02_RED 0x02 /* red 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_COM15_R00FF 0xc0 * 00 to FF */
|
||||||
#define OV7670_R41_COM16 0x41 /* Control 16 */
|
#define OV7670_R41_COM16 0x41 /* Control 16 */
|
||||||
#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
|
#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
|
||||||
|
/* end of ov7660 common registers */
|
||||||
#define OV7670_R55_BRIGHT 0x55 /* Brightness */
|
#define OV7670_R55_BRIGHT 0x55 /* Brightness */
|
||||||
#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
|
#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
|
||||||
#define OV7670_R69_GFIX 0x69 /* Fix gain control */
|
#define OV7670_R69_GFIX 0x69 /* Fix gain control */
|
||||||
|
@ -1577,6 +1581,150 @@ static const struct ov_i2c_regvals norm_7640[] = {
|
||||||
{ 0x12, 0x14 },
|
{ 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,
|
/* 7670. Defaults taken from OmniVision provided data,
|
||||||
* as provided by Jonathan Corbet of OLPC */
|
* as provided by Jonathan Corbet of OLPC */
|
||||||
static const struct ov_i2c_regvals norm_7670[] = {
|
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");
|
PDEBUG(D_PROBE, "Sensor is an OV7648");
|
||||||
sd->sensor = SEN_OV7648;
|
sd->sensor = SEN_OV7648;
|
||||||
break;
|
break;
|
||||||
|
case 0x60:
|
||||||
|
PDEBUG(D_PROBE, "Sensor is a OV7660");
|
||||||
|
sd->sensor = SEN_OV7660;
|
||||||
|
sd->invert_led = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
|
PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
|
||||||
return;
|
return;
|
||||||
|
@ -2935,6 +3088,91 @@ static void ovfx2_configure(struct sd *sd)
|
||||||
write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
|
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 */
|
/* this function is called at probe time */
|
||||||
static int sd_config(struct gspca_dev *gspca_dev,
|
static int sd_config(struct gspca_dev *gspca_dev,
|
||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
|
@ -3118,6 +3356,34 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
||||||
case SEN_OV7648:
|
case SEN_OV7648:
|
||||||
write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
|
write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
|
||||||
break;
|
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:
|
case SEN_OV7670:
|
||||||
sd->ctrls[FREQ].max = 3; /* auto */
|
sd->ctrls[FREQ].max = 3; /* auto */
|
||||||
sd->ctrls[FREQ].def = 3;
|
sd->ctrls[FREQ].def = 3;
|
||||||
|
@ -3431,16 +3697,21 @@ static void ov519_mode_init_regs(struct sd *sd)
|
||||||
};
|
};
|
||||||
|
|
||||||
/******** Set the mode ********/
|
/******** Set the mode ********/
|
||||||
if (sd->sensor != SEN_OV7670) {
|
switch (sd->sensor) {
|
||||||
|
default:
|
||||||
write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
|
write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
|
||||||
if (sd->sensor == SEN_OV7640 ||
|
if (sd->sensor == SEN_OV7640 ||
|
||||||
sd->sensor == SEN_OV7648) {
|
sd->sensor == SEN_OV7648) {
|
||||||
/* Select 8-bit input mode */
|
/* Select 8-bit input mode */
|
||||||
reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
|
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,
|
write_regvals(sd, mode_init_519_ov7670,
|
||||||
ARRAY_SIZE(mode_init_519_ov7670));
|
ARRAY_SIZE(mode_init_519_ov7670));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
|
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);
|
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)
|
static void sethvflip(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) 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;
|
int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
|
||||||
|
|
||||||
/* mode setup is fully handled in mode_init_ov_sensor_regs for these */
|
/* mode setup is fully handled in mode_init_ov_sensor_regs for these */
|
||||||
if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
|
switch (sd->sensor) {
|
||||||
sd->sensor == SEN_OV7670) {
|
case SEN_OV2610:
|
||||||
|
case SEN_OV3610:
|
||||||
|
case SEN_OV7670:
|
||||||
mode_init_ov_sensor_regs(sd);
|
mode_init_ov_sensor_regs(sd);
|
||||||
return;
|
return;
|
||||||
|
case SEN_OV7660:
|
||||||
|
ov519_set_mode(sd);
|
||||||
|
ov519_set_fr(sd);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gspca_dev = &sd->gspca_dev;
|
gspca_dev = &sd->gspca_dev;
|
||||||
qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
|
qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
|
||||||
crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
|
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;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
int val;
|
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;
|
val = sd->ctrls[BRIGHTNESS].val;
|
||||||
switch (sd->sensor) {
|
switch (sd->sensor) {
|
||||||
|
@ -4120,6 +4415,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
||||||
if (!sd->ctrls[AUTOBRIGHT].val)
|
if (!sd->ctrls[AUTOBRIGHT].val)
|
||||||
i2c_w(sd, OV7610_REG_BRT, val);
|
i2c_w(sd, OV7610_REG_BRT, val);
|
||||||
break;
|
break;
|
||||||
|
case SEN_OV7660:
|
||||||
|
write_i2c_regvals(sd, brit_7660[val],
|
||||||
|
ARRAY_SIZE(brit_7660[0]));
|
||||||
|
break;
|
||||||
case SEN_OV7670:
|
case SEN_OV7670:
|
||||||
/*win trace
|
/*win trace
|
||||||
* i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
|
* 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;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
int val;
|
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;
|
val = sd->ctrls[CONTRAST].val;
|
||||||
switch (sd->sensor) {
|
switch (sd->sensor) {
|
||||||
|
@ -4163,6 +4520,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
||||||
i2c_w(sd, 0x64, ctab[val >> 4]);
|
i2c_w(sd, 0x64, ctab[val >> 4]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SEN_OV7660:
|
||||||
|
write_i2c_regvals(sd, contrast_7660[val],
|
||||||
|
ARRAY_SIZE(contrast_7660[0]));
|
||||||
|
break;
|
||||||
case SEN_OV7670:
|
case SEN_OV7670:
|
||||||
/* check that this isn't just the same as ov7610 */
|
/* check that this isn't just the same as ov7610 */
|
||||||
i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
|
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;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
int val;
|
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;
|
val = sd->ctrls[COLORS].val;
|
||||||
switch (sd->sensor) {
|
switch (sd->sensor) {
|
||||||
|
@ -4197,6 +4570,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
||||||
case SEN_OV7648:
|
case SEN_OV7648:
|
||||||
i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
|
i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
|
||||||
break;
|
break;
|
||||||
|
case SEN_OV7660:
|
||||||
|
write_i2c_regvals(sd, colors_7660[val],
|
||||||
|
ARRAY_SIZE(colors_7660[0]));
|
||||||
|
break;
|
||||||
case SEN_OV7670:
|
case SEN_OV7670:
|
||||||
/* supported later once I work out how to do it
|
/* supported later once I work out how to do it
|
||||||
* transparently fail now! */
|
* transparently fail now! */
|
||||||
|
@ -4214,7 +4591,8 @@ static void setautobright(struct gspca_dev *gspca_dev)
|
||||||
|
|
||||||
static void setfreq_i(struct sd *sd)
|
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) {
|
switch (sd->ctrls[FREQ].val) {
|
||||||
case 0: /* Banding filter disabled */
|
case 0: /* Banding filter disabled */
|
||||||
i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
|
i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
|
||||||
|
|
Loading…
Reference in New Issue