aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2010-11-13 03:10:27 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:16:44 -0500
commit42e142f6b72493b5daec9950c4c83d20ccf56a0d (patch)
tree34ac08f662b5513ee91a7ef157d0d6f9fdfd4aca /drivers
parent7491f785dd02bc35551e0463d798959b15644c1d (diff)
[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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/ov519.c394
1 files changed, 386 insertions, 8 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 08f07c3488d8..0ed21dbb46cd 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -82,7 +82,7 @@ struct sd {
82#define BRIDGE_OV511PLUS 1 82#define BRIDGE_OV511PLUS 1
83#define BRIDGE_OV518 2 83#define BRIDGE_OV518 2
84#define BRIDGE_OV518PLUS 3 84#define BRIDGE_OV518PLUS 3
85#define BRIDGE_OV519 4 85#define BRIDGE_OV519 4 /* = ov530 */
86#define BRIDGE_OVFX2 5 86#define BRIDGE_OVFX2 5
87#define BRIDGE_W9968CF 6 87#define BRIDGE_W9968CF 6
88#define BRIDGE_MASK 7 88#define BRIDGE_MASK 7
@@ -127,6 +127,7 @@ enum sensors {
127 SEN_OV7620AE, 127 SEN_OV7620AE,
128 SEN_OV7640, 128 SEN_OV7640,
129 SEN_OV7648, 129 SEN_OV7648,
130 SEN_OV7660,
130 SEN_OV7670, 131 SEN_OV7670,
131 SEN_OV76BE, 132 SEN_OV76BE,
132 SEN_OV8610, 133 SEN_OV8610,
@@ -183,7 +184,7 @@ static const struct ctrl sd_ctrls[] = {
183 }, 184 },
184 .set_control = setcolors, 185 .set_control = setcolors,
185 }, 186 },
186/* The flip controls work with ov7670 only */ 187/* The flip controls work for sensors ov7660 and ov7670 only */
187[HFLIP] = { 188[HFLIP] = {
188 { 189 {
189 .id = V4L2_CID_HFLIP, 190 .id = V4L2_CID_HFLIP,
@@ -268,6 +269,8 @@ static const unsigned ctrl_dis[] = {
268 (1 << AUTOBRIGHT) | 269 (1 << AUTOBRIGHT) |
269 (1 << CONTRAST), 270 (1 << CONTRAST),
270 271
272[SEN_OV7660] = (1 << AUTOBRIGHT),
273
271[SEN_OV7670] = (1 << COLORS) | 274[SEN_OV7670] = (1 << COLORS) |
272 (1 << AUTOBRIGHT), 275 (1 << AUTOBRIGHT),
273 276
@@ -572,7 +575,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
572#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */ 575#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
573#define OV7610_REG_COM_I 0x29 /* misc settings */ 576#define OV7610_REG_COM_I 0x29 /* misc settings */
574 577
575/* OV7670 registers */ 578/* OV7660 and OV7670 registers */
576#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ 579#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
577#define OV7670_R01_BLUE 0x01 /* blue gain */ 580#define OV7670_R01_BLUE 0x01 /* blue gain */
578#define OV7670_R02_RED 0x02 /* red gain */ 581#define OV7670_R02_RED 0x02 /* red gain */
@@ -625,6 +628,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
625/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */ 628/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */
626#define OV7670_R41_COM16 0x41 /* Control 16 */ 629#define OV7670_R41_COM16 0x41 /* Control 16 */
627#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */ 630#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
631/* end of ov7660 common registers */
628#define OV7670_R55_BRIGHT 0x55 /* Brightness */ 632#define OV7670_R55_BRIGHT 0x55 /* Brightness */
629#define OV7670_R56_CONTRAS 0x56 /* Contrast control */ 633#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
630#define OV7670_R69_GFIX 0x69 /* Fix gain control */ 634#define OV7670_R69_GFIX 0x69 /* Fix gain control */
@@ -1577,6 +1581,150 @@ static const struct ov_i2c_regvals norm_7640[] = {
1577 { 0x12, 0x14 }, 1581 { 0x12, 0x14 },
1578}; 1582};
1579 1583
1584static const struct ov_regvals init_519_ov7660[] = {
1585 { 0x5d, 0x03 }, /* Turn off suspend mode */
1586 { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */
1587 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
1588 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
1589 { 0xa3, 0x18 },
1590 { 0xa4, 0x04 },
1591 { 0xa5, 0x28 },
1592 { 0x37, 0x00 }, /* SetUsbInit */
1593 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
1594 /* Enable both fields, YUV Input, disable defect comp (why?) */
1595 { 0x20, 0x0c }, /* 0x0d does U <-> V swap */
1596 { 0x21, 0x38 },
1597 { 0x22, 0x1d },
1598 { 0x17, 0x50 }, /* undocumented */
1599 { 0x37, 0x00 }, /* undocumented */
1600 { 0x40, 0xff }, /* I2C timeout counter */
1601 { 0x46, 0x00 }, /* I2C clock prescaler */
1602};
1603static const struct ov_i2c_regvals norm_7660[] = {
1604 {OV7670_R12_COM7, OV7670_COM7_RESET},
1605 {OV7670_R11_CLKRC, 0x81},
1606 {0x92, 0x00}, /* DM_LNL */
1607 {0x93, 0x00}, /* DM_LNH */
1608 {0x9d, 0x4c}, /* BD50ST */
1609 {0x9e, 0x3f}, /* BD60ST */
1610 {OV7670_R3B_COM11, 0x02},
1611 {OV7670_R13_COM8, 0xf5},
1612 {OV7670_R10_AECH, 0x00},
1613 {OV7670_R00_GAIN, 0x00},
1614 {OV7670_R01_BLUE, 0x7c},
1615 {OV7670_R02_RED, 0x9d},
1616 {OV7670_R12_COM7, 0x00},
1617 {OV7670_R04_COM1, 00},
1618 {OV7670_R18_HSTOP, 0x01},
1619 {OV7670_R17_HSTART, 0x13},
1620 {OV7670_R32_HREF, 0x92},
1621 {OV7670_R19_VSTART, 0x02},
1622 {OV7670_R1A_VSTOP, 0x7a},
1623 {OV7670_R03_VREF, 0x00},
1624 {OV7670_R0E_COM5, 0x04},
1625 {OV7670_R0F_COM6, 0x62},
1626 {OV7670_R15_COM10, 0x00},
1627 {0x16, 0x02}, /* RSVD */
1628 {0x1b, 0x00}, /* PSHFT */
1629 {OV7670_R1E_MVFP, 0x01},
1630 {0x29, 0x3c}, /* RSVD */
1631 {0x33, 0x00}, /* CHLF */
1632 {0x34, 0x07}, /* ARBLM */
1633 {0x35, 0x84}, /* RSVD */
1634 {0x36, 0x00}, /* RSVD */
1635 {0x37, 0x04}, /* ADC */
1636 {0x39, 0x43}, /* OFON */
1637 {OV7670_R3A_TSLB, 0x00},
1638 {OV7670_R3C_COM12, 0x6c},
1639 {OV7670_R3D_COM13, 0x98},
1640 {OV7670_R3F_EDGE, 0x23},
1641 {OV7670_R40_COM15, 0xc1},
1642 {OV7670_R41_COM16, 0x22},
1643 {0x6b, 0x0a}, /* DBLV */
1644 {0xa1, 0x08}, /* RSVD */
1645 {0x69, 0x80}, /* HV */
1646 {0x43, 0xf0}, /* RSVD.. */
1647 {0x44, 0x10},
1648 {0x45, 0x78},
1649 {0x46, 0xa8},
1650 {0x47, 0x60},
1651 {0x48, 0x80},
1652 {0x59, 0xba},
1653 {0x5a, 0x9a},
1654 {0x5b, 0x22},
1655 {0x5c, 0xb9},
1656 {0x5d, 0x9b},
1657 {0x5e, 0x10},
1658 {0x5f, 0xe0},
1659 {0x60, 0x85},
1660 {0x61, 0x60},
1661 {0x9f, 0x9d}, /* RSVD */
1662 {0xa0, 0xa0}, /* DSPC2 */
1663 {0x4f, 0x60}, /* matrix */
1664 {0x50, 0x64},
1665 {0x51, 0x04},
1666 {0x52, 0x18},
1667 {0x53, 0x3c},
1668 {0x54, 0x54},
1669 {0x55, 0x40},
1670 {0x56, 0x40},
1671 {0x57, 0x40},
1672 {0x58, 0x0d}, /* matrix sign */
1673 {0x8b, 0xcc}, /* RSVD */
1674 {0x8c, 0xcc},
1675 {0x8d, 0xcf},
1676 {0x6c, 0x40}, /* gamma curve */
1677 {0x6d, 0xe0},
1678 {0x6e, 0xa0},
1679 {0x6f, 0x80},
1680 {0x70, 0x70},
1681 {0x71, 0x80},
1682 {0x72, 0x60},
1683 {0x73, 0x60},
1684 {0x74, 0x50},
1685 {0x75, 0x40},
1686 {0x76, 0x38},
1687 {0x77, 0x3c},
1688 {0x78, 0x32},
1689 {0x79, 0x1a},
1690 {0x7a, 0x28},
1691 {0x7b, 0x24},
1692 {0x7c, 0x04}, /* gamma curve */
1693 {0x7d, 0x12},
1694 {0x7e, 0x26},
1695 {0x7f, 0x46},
1696 {0x80, 0x54},
1697 {0x81, 0x64},
1698 {0x82, 0x70},
1699 {0x83, 0x7c},
1700 {0x84, 0x86},
1701 {0x85, 0x8e},
1702 {0x86, 0x9c},
1703 {0x87, 0xab},
1704 {0x88, 0xc4},
1705 {0x89, 0xd1},
1706 {0x8a, 0xe5},
1707 {OV7670_R14_COM9, 0x1e},
1708 {OV7670_R24_AEW, 0x80},
1709 {OV7670_R25_AEB, 0x72},
1710 {OV7670_R26_VPT, 0xb3},
1711 {0x62, 0x80}, /* LCC1 */
1712 {0x63, 0x80}, /* LCC2 */
1713 {0x64, 0x06}, /* LCC3 */
1714 {0x65, 0x00}, /* LCC4 */
1715 {0x66, 0x01}, /* LCC5 */
1716 {0x94, 0x0e}, /* RSVD.. */
1717 {0x95, 0x14},
1718 {OV7670_R13_COM8, OV7670_COM8_FASTAEC
1719 | OV7670_COM8_AECSTEP
1720 | OV7670_COM8_BFILT
1721 | 0x10
1722 | OV7670_COM8_AGC
1723 | OV7670_COM8_AWB
1724 | OV7670_COM8_AEC},
1725 {0xa1, 0xc8}
1726};
1727
1580/* 7670. Defaults taken from OmniVision provided data, 1728/* 7670. Defaults taken from OmniVision provided data,
1581* as provided by Jonathan Corbet of OLPC */ 1729* as provided by Jonathan Corbet of OLPC */
1582static const struct ov_i2c_regvals norm_7670[] = { 1730static const struct ov_i2c_regvals norm_7670[] = {
@@ -2574,6 +2722,11 @@ static void ov7xx0_configure(struct sd *sd)
2574 PDEBUG(D_PROBE, "Sensor is an OV7648"); 2722 PDEBUG(D_PROBE, "Sensor is an OV7648");
2575 sd->sensor = SEN_OV7648; 2723 sd->sensor = SEN_OV7648;
2576 break; 2724 break;
2725 case 0x60:
2726 PDEBUG(D_PROBE, "Sensor is a OV7660");
2727 sd->sensor = SEN_OV7660;
2728 sd->invert_led = 0;
2729 break;
2577 default: 2730 default:
2578 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); 2731 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
2579 return; 2732 return;
@@ -2935,6 +3088,91 @@ static void ovfx2_configure(struct sd *sd)
2935 write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2)); 3088 write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
2936} 3089}
2937 3090
3091/* set the mode */
3092/* This function works for ov7660 only */
3093static void ov519_set_mode(struct sd *sd)
3094{
3095 static const struct ov_regvals bridge_ov7660[2][10] = {
3096 {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
3097 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3098 {0x25, 0x01}, {0x26, 0x00}},
3099 {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
3100 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3101 {0x25, 0x03}, {0x26, 0x00}}
3102 };
3103 static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
3104 {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
3105 {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
3106 };
3107 static const struct ov_i2c_regvals sensor_ov7660_2[] = {
3108 {OV7670_R17_HSTART, 0x13},
3109 {OV7670_R18_HSTOP, 0x01},
3110 {OV7670_R32_HREF, 0x92},
3111 {OV7670_R19_VSTART, 0x02},
3112 {OV7670_R1A_VSTOP, 0x7a},
3113 {OV7670_R03_VREF, 0x00},
3114/* {0x33, 0x00}, */
3115/* {0x34, 0x07}, */
3116/* {0x36, 0x00}, */
3117/* {0x6b, 0x0a}, */
3118 };
3119
3120 write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
3121 ARRAY_SIZE(bridge_ov7660[0]));
3122 write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
3123 ARRAY_SIZE(sensor_ov7660[0]));
3124 write_i2c_regvals(sd, sensor_ov7660_2,
3125 ARRAY_SIZE(sensor_ov7660_2));
3126}
3127
3128/* set the frame rate */
3129/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */
3130static void ov519_set_fr(struct sd *sd)
3131{
3132 int fr;
3133 u8 clock;
3134 /* frame rate table with indices:
3135 * - mode = 0: 320x240, 1: 640x480
3136 * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5
3137 * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock)
3138 */
3139 static const u8 fr_tb[2][6][3] = {
3140 {{0x04, 0xff, 0x00},
3141 {0x04, 0x1f, 0x00},
3142 {0x04, 0x1b, 0x00},
3143 {0x04, 0x15, 0x00},
3144 {0x04, 0x09, 0x00},
3145 {0x04, 0x01, 0x00}},
3146 {{0x0c, 0xff, 0x00},
3147 {0x0c, 0x1f, 0x00},
3148 {0x0c, 0x1b, 0x00},
3149 {0x04, 0xff, 0x01},
3150 {0x04, 0x1f, 0x01},
3151 {0x04, 0x1b, 0x01}},
3152 };
3153
3154 if (frame_rate > 0)
3155 sd->frame_rate = frame_rate;
3156 if (sd->frame_rate >= 30)
3157 fr = 0;
3158 else if (sd->frame_rate >= 25)
3159 fr = 1;
3160 else if (sd->frame_rate >= 20)
3161 fr = 2;
3162 else if (sd->frame_rate >= 15)
3163 fr = 3;
3164 else if (sd->frame_rate >= 10)
3165 fr = 4;
3166 else
3167 fr = 5;
3168 reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
3169 reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
3170 clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
3171 if (sd->sensor == SEN_OV7660)
3172 clock |= 0x80; /* enable double clock */
3173 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
3174}
3175
2938/* this function is called at probe time */ 3176/* this function is called at probe time */
2939static int sd_config(struct gspca_dev *gspca_dev, 3177static int sd_config(struct gspca_dev *gspca_dev,
2940 const struct usb_device_id *id) 3178 const struct usb_device_id *id)
@@ -3118,6 +3356,34 @@ static int sd_init(struct gspca_dev *gspca_dev)
3118 case SEN_OV7648: 3356 case SEN_OV7648:
3119 write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)); 3357 write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
3120 break; 3358 break;
3359 case SEN_OV7660:
3360 i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
3361 msleep(14);
3362 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
3363 write_regvals(sd, init_519_ov7660,
3364 ARRAY_SIZE(init_519_ov7660));
3365 write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
3366 sd->gspca_dev.curr_mode = 1; /* 640x480 */
3367 sd->frame_rate = 15;
3368 ov519_set_mode(sd);
3369 ov519_set_fr(sd);
3370 sd->ctrls[COLORS].max = 4; /* 0..4 */
3371 sd->ctrls[COLORS].val =
3372 sd->ctrls[COLORS].def = 2;
3373 setcolors(gspca_dev);
3374 sd->ctrls[CONTRAST].max = 6; /* 0..6 */
3375 sd->ctrls[CONTRAST].val =
3376 sd->ctrls[CONTRAST].def = 3;
3377 setcontrast(gspca_dev);
3378 sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */
3379 sd->ctrls[BRIGHTNESS].val =
3380 sd->ctrls[BRIGHTNESS].def = 3;
3381 setbrightness(gspca_dev);
3382 sd_reset_snapshot(gspca_dev);
3383 ov51x_restart(sd);
3384 ov51x_stop(sd); /* not in win traces */
3385 ov51x_led_control(sd, 0);
3386 break;
3121 case SEN_OV7670: 3387 case SEN_OV7670:
3122 sd->ctrls[FREQ].max = 3; /* auto */ 3388 sd->ctrls[FREQ].max = 3; /* auto */
3123 sd->ctrls[FREQ].def = 3; 3389 sd->ctrls[FREQ].def = 3;
@@ -3431,16 +3697,21 @@ static void ov519_mode_init_regs(struct sd *sd)
3431 }; 3697 };
3432 3698
3433 /******** Set the mode ********/ 3699 /******** Set the mode ********/
3434 if (sd->sensor != SEN_OV7670) { 3700 switch (sd->sensor) {
3701 default:
3435 write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519)); 3702 write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
3436 if (sd->sensor == SEN_OV7640 || 3703 if (sd->sensor == SEN_OV7640 ||
3437 sd->sensor == SEN_OV7648) { 3704 sd->sensor == SEN_OV7648) {
3438 /* Select 8-bit input mode */ 3705 /* Select 8-bit input mode */
3439 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10); 3706 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
3440 } 3707 }
3441 } else { 3708 break;
3709 case SEN_OV7660:
3710 return; /* done by ov519_set_mode/fr() */
3711 case SEN_OV7670:
3442 write_regvals(sd, mode_init_519_ov7670, 3712 write_regvals(sd, mode_init_519_ov7670,
3443 ARRAY_SIZE(mode_init_519_ov7670)); 3713 ARRAY_SIZE(mode_init_519_ov7670));
3714 break;
3444 } 3715 }
3445 3716
3446 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4); 3717 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)
3682 i2c_w(sd, 0x11, sd->clockdiv); 3953 i2c_w(sd, 0x11, sd->clockdiv);
3683} 3954}
3684 3955
3956/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */
3685static void sethvflip(struct gspca_dev *gspca_dev) 3957static void sethvflip(struct gspca_dev *gspca_dev)
3686{ 3958{
3687 struct sd *sd = (struct sd *) gspca_dev; 3959 struct sd *sd = (struct sd *) gspca_dev;
@@ -3703,11 +3975,18 @@ static void set_ov_sensor_window(struct sd *sd)
3703 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; 3975 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
3704 3976
3705 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ 3977 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
3706 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 || 3978 switch (sd->sensor) {
3707 sd->sensor == SEN_OV7670) { 3979 case SEN_OV2610:
3980 case SEN_OV3610:
3981 case SEN_OV7670:
3708 mode_init_ov_sensor_regs(sd); 3982 mode_init_ov_sensor_regs(sd);
3709 return; 3983 return;
3984 case SEN_OV7660:
3985 ov519_set_mode(sd);
3986 ov519_set_fr(sd);
3987 return;
3710 } 3988 }
3989
3711 gspca_dev = &sd->gspca_dev; 3990 gspca_dev = &sd->gspca_dev;
3712 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1; 3991 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
3713 crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2; 3992 crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
@@ -4101,6 +4380,22 @@ static void setbrightness(struct gspca_dev *gspca_dev)
4101{ 4380{
4102 struct sd *sd = (struct sd *) gspca_dev; 4381 struct sd *sd = (struct sd *) gspca_dev;
4103 int val; 4382 int val;
4383 static const struct ov_i2c_regvals brit_7660[][7] = {
4384 {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
4385 {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
4386 {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
4387 {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
4388 {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
4389 {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
4390 {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
4391 {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
4392 {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
4393 {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
4394 {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
4395 {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
4396 {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
4397 {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
4398 };
4104 4399
4105 val = sd->ctrls[BRIGHTNESS].val; 4400 val = sd->ctrls[BRIGHTNESS].val;
4106 switch (sd->sensor) { 4401 switch (sd->sensor) {
@@ -4120,6 +4415,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
4120 if (!sd->ctrls[AUTOBRIGHT].val) 4415 if (!sd->ctrls[AUTOBRIGHT].val)
4121 i2c_w(sd, OV7610_REG_BRT, val); 4416 i2c_w(sd, OV7610_REG_BRT, val);
4122 break; 4417 break;
4418 case SEN_OV7660:
4419 write_i2c_regvals(sd, brit_7660[val],
4420 ARRAY_SIZE(brit_7660[0]));
4421 break;
4123 case SEN_OV7670: 4422 case SEN_OV7670:
4124/*win trace 4423/*win trace
4125 * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */ 4424 * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
@@ -4132,6 +4431,64 @@ static void setcontrast(struct gspca_dev *gspca_dev)
4132{ 4431{
4133 struct sd *sd = (struct sd *) gspca_dev; 4432 struct sd *sd = (struct sd *) gspca_dev;
4134 int val; 4433 int val;
4434 static const struct ov_i2c_regvals contrast_7660[][31] = {
4435 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
4436 {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
4437 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
4438 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
4439 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
4440 {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
4441 {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
4442 {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
4443 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
4444 {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
4445 {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
4446 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
4447 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
4448 {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
4449 {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
4450 {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
4451 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
4452 {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
4453 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
4454 {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
4455 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
4456 {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
4457 {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
4458 {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
4459 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
4460 {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
4461 {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
4462 {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
4463 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
4464 {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
4465 {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
4466 {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
4467 {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
4468 {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
4469 {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
4470 {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
4471 {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
4472 {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
4473 {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
4474 {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
4475 {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
4476 {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
4477 {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
4478 {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
4479 {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
4480 {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
4481 {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
4482 {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
4483 {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
4484 {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
4485 {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
4486 {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
4487 {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
4488 {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
4489 {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
4490 {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
4491 };
4135 4492
4136 val = sd->ctrls[CONTRAST].val; 4493 val = sd->ctrls[CONTRAST].val;
4137 switch (sd->sensor) { 4494 switch (sd->sensor) {
@@ -4163,6 +4520,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
4163 i2c_w(sd, 0x64, ctab[val >> 4]); 4520 i2c_w(sd, 0x64, ctab[val >> 4]);
4164 break; 4521 break;
4165 } 4522 }
4523 case SEN_OV7660:
4524 write_i2c_regvals(sd, contrast_7660[val],
4525 ARRAY_SIZE(contrast_7660[0]));
4526 break;
4166 case SEN_OV7670: 4527 case SEN_OV7670:
4167 /* check that this isn't just the same as ov7610 */ 4528 /* check that this isn't just the same as ov7610 */
4168 i2c_w(sd, OV7670_R56_CONTRAS, val >> 1); 4529 i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
@@ -4174,6 +4535,18 @@ static void setcolors(struct gspca_dev *gspca_dev)
4174{ 4535{
4175 struct sd *sd = (struct sd *) gspca_dev; 4536 struct sd *sd = (struct sd *) gspca_dev;
4176 int val; 4537 int val;
4538 static const struct ov_i2c_regvals colors_7660[][6] = {
4539 {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
4540 {0x53, 0x19}, {0x54, 0x23}},
4541 {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
4542 {0x53, 0x2c}, {0x54, 0x3e}},
4543 {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
4544 {0x53, 0x40}, {0x54, 0x59}},
4545 {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
4546 {0x53, 0x53}, {0x54, 0x73}},
4547 {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
4548 {0x53, 0x66}, {0x54, 0x8e}},
4549 };
4177 4550
4178 val = sd->ctrls[COLORS].val; 4551 val = sd->ctrls[COLORS].val;
4179 switch (sd->sensor) { 4552 switch (sd->sensor) {
@@ -4197,6 +4570,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
4197 case SEN_OV7648: 4570 case SEN_OV7648:
4198 i2c_w(sd, OV7610_REG_SAT, val & 0xf0); 4571 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4199 break; 4572 break;
4573 case SEN_OV7660:
4574 write_i2c_regvals(sd, colors_7660[val],
4575 ARRAY_SIZE(colors_7660[0]));
4576 break;
4200 case SEN_OV7670: 4577 case SEN_OV7670:
4201 /* supported later once I work out how to do it 4578 /* supported later once I work out how to do it
4202 * transparently fail now! */ 4579 * transparently fail now! */
@@ -4214,7 +4591,8 @@ static void setautobright(struct gspca_dev *gspca_dev)
4214 4591
4215static void setfreq_i(struct sd *sd) 4592static void setfreq_i(struct sd *sd)
4216{ 4593{
4217 if (sd->sensor == SEN_OV7670) { 4594 if (sd->sensor == SEN_OV7660
4595 || sd->sensor == SEN_OV7670) {
4218 switch (sd->ctrls[FREQ].val) { 4596 switch (sd->ctrls[FREQ].val) {
4219 case 0: /* Banding filter disabled */ 4597 case 0: /* Banding filter disabled */
4220 i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT); 4598 i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);