aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-06-07 11:10:39 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 18:07:42 -0400
commit49809d6a511960e5ccfb85b780894f45ac119065 (patch)
treeef00b16e944adf94774f65e47ddff6787e75b991
parent253f13d5cd05204aa3174ffb53490f2b0fad055c (diff)
V4L/DVB (11970): gspca - ov519: Add support for the ov518 bridge.
Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/ov519.c520
-rw-r--r--include/linux/videodev2.h3
2 files changed, 488 insertions, 35 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 1fff37b79891..188866ac6cef 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -50,6 +50,13 @@ static int i2c_detect_tries = 10;
50struct sd { 50struct sd {
51 struct gspca_dev gspca_dev; /* !! must be the first item */ 51 struct gspca_dev gspca_dev; /* !! must be the first item */
52 52
53 char bridge;
54#define BRIDGE_OV511 0
55#define BRIDGE_OV511PLUS 1
56#define BRIDGE_OV518 2
57#define BRIDGE_OV518PLUS 3
58#define BRIDGE_OV519 4
59
53 /* Determined by sensor type */ 60 /* Determined by sensor type */
54 __u8 sif; 61 __u8 sif;
55 62
@@ -87,6 +94,9 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 94static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
88static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 95static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 96static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
97static void setbrightness(struct gspca_dev *gspca_dev);
98static void setcontrast(struct gspca_dev *gspca_dev);
99static void setcolors(struct gspca_dev *gspca_dev);
90 100
91static struct ctrl sd_ctrls[] = { 101static struct ctrl sd_ctrls[] = {
92 { 102 {
@@ -164,7 +174,7 @@ static struct ctrl sd_ctrls[] = {
164 }, 174 },
165}; 175};
166 176
167static const struct v4l2_pix_format vga_mode[] = { 177static const struct v4l2_pix_format ov519_vga_mode[] = {
168 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 178 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
169 .bytesperline = 320, 179 .bytesperline = 320,
170 .sizeimage = 320 * 240 * 3 / 8 + 590, 180 .sizeimage = 320 * 240 * 3 / 8 + 590,
@@ -176,7 +186,7 @@ static const struct v4l2_pix_format vga_mode[] = {
176 .colorspace = V4L2_COLORSPACE_JPEG, 186 .colorspace = V4L2_COLORSPACE_JPEG,
177 .priv = 0}, 187 .priv = 0},
178}; 188};
179static const struct v4l2_pix_format sif_mode[] = { 189static const struct v4l2_pix_format ov519_sif_mode[] = {
180 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 190 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
181 .bytesperline = 176, 191 .bytesperline = 176,
182 .sizeimage = 176 * 144 * 3 / 8 + 590, 192 .sizeimage = 176 * 144 * 3 / 8 + 590,
@@ -189,6 +199,47 @@ static const struct v4l2_pix_format sif_mode[] = {
189 .priv = 0}, 199 .priv = 0},
190}; 200};
191 201
202static const struct v4l2_pix_format ov518_vga_mode[] = {
203 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
204 .bytesperline = 320,
205 .sizeimage = 320 * 240 * 3 / 8 + 590,
206 .colorspace = V4L2_COLORSPACE_JPEG,
207 .priv = 1},
208 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
209 .bytesperline = 640,
210 .sizeimage = 640 * 480 * 3 / 8 + 590,
211 .colorspace = V4L2_COLORSPACE_JPEG,
212 .priv = 0},
213};
214static const struct v4l2_pix_format ov518_sif_mode[] = {
215 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
216 .bytesperline = 176,
217 .sizeimage = 40000,
218 .colorspace = V4L2_COLORSPACE_JPEG,
219 .priv = 1},
220 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
221 .bytesperline = 352,
222 .sizeimage = 352 * 288 * 3 / 8 + 590,
223 .colorspace = V4L2_COLORSPACE_JPEG,
224 .priv = 0},
225};
226
227
228/* Registers common to OV511 / OV518 */
229#define R51x_SYS_RESET 0x50
230#define R51x_SYS_INIT 0x53
231#define R51x_SYS_SNAP 0x52
232#define R51x_SYS_CUST_ID 0x5F
233#define R51x_COMP_LUT_BEGIN 0x80
234
235/* OV511 Camera interface register numbers */
236#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
237#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
238
239/* OV518 Camera interface register numbers */
240#define R518_GPIO_OUT 0x56 /* OV518(+) only */
241#define R518_GPIO_CTL 0x57 /* OV518(+) only */
242
192/* OV519 Camera interface register numbers */ 243/* OV519 Camera interface register numbers */
193#define OV519_R10_H_SIZE 0x10 244#define OV519_R10_H_SIZE 0x10
194#define OV519_R11_V_SIZE 0x11 245#define OV519_R11_V_SIZE 0x11
@@ -224,6 +275,8 @@ static const struct v4l2_pix_format sif_mode[] = {
224 275
225/* OV7610 registers */ 276/* OV7610 registers */
226#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ 277#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
278#define OV7610_REG_BLUE 0x01 /* blue channel balance */
279#define OV7610_REG_RED 0x02 /* red channel balance */
227#define OV7610_REG_SAT 0x03 /* saturation */ 280#define OV7610_REG_SAT 0x03 /* saturation */
228#define OV8610_REG_HUE 0x04 /* 04 reserved */ 281#define OV8610_REG_HUE 0x04 /* 04 reserved */
229#define OV7610_REG_CNT 0x05 /* Y contrast */ 282#define OV7610_REG_CNT 0x05 /* Y contrast */
@@ -846,11 +899,12 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
846static int reg_w(struct sd *sd, __u16 index, __u8 value) 899static int reg_w(struct sd *sd, __u16 index, __u8 value)
847{ 900{
848 int ret; 901 int ret;
902 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 2 : 1;
849 903
850 sd->gspca_dev.usb_buf[0] = value; 904 sd->gspca_dev.usb_buf[0] = value;
851 ret = usb_control_msg(sd->gspca_dev.dev, 905 ret = usb_control_msg(sd->gspca_dev.dev,
852 usb_sndctrlpipe(sd->gspca_dev.dev, 0), 906 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
853 1, /* REQ_IO (ov518/519) */ 907 req,
854 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 908 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
855 0, index, 909 0, index,
856 sd->gspca_dev.usb_buf, 1, 500); 910 sd->gspca_dev.usb_buf, 1, 500);
@@ -864,10 +918,11 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value)
864static int reg_r(struct sd *sd, __u16 index) 918static int reg_r(struct sd *sd, __u16 index)
865{ 919{
866 int ret; 920 int ret;
921 int req = (sd->bridge <= BRIDGE_OV511PLUS) ? 3 : 1;
867 922
868 ret = usb_control_msg(sd->gspca_dev.dev, 923 ret = usb_control_msg(sd->gspca_dev.dev,
869 usb_rcvctrlpipe(sd->gspca_dev.dev, 0), 924 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
870 1, /* REQ_IO */ 925 req,
871 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 926 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
872 0, index, sd->gspca_dev.usb_buf, 1, 500); 927 0, index, sd->gspca_dev.usb_buf, 1, 500);
873 928
@@ -924,6 +979,28 @@ static int reg_w_mask(struct sd *sd,
924} 979}
925 980
926/* 981/*
982 * Writes multiple (n) byte value to a single register. Only valid with certain
983 * registers (0x30 and 0xc4 - 0xce).
984 */
985static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
986{
987 int ret;
988
989 *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
990
991 ret = usb_control_msg(sd->gspca_dev.dev,
992 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
993 1 /* REG_IO */,
994 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
995 0, index,
996 sd->gspca_dev.usb_buf, n, 500);
997 if (ret < 0)
998 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
999 return ret;
1000}
1001
1002
1003/*
927 * The OV518 I2C I/O procedure is different, hence, this function. 1004 * The OV518 I2C I/O procedure is different, hence, this function.
928 * This is normally only called from i2c_w(). Note that this function 1005 * This is normally only called from i2c_w(). Note that this function
929 * always succeeds regardless of whether the sensor is present and working. 1006 * always succeeds regardless of whether the sensor is present and working.
@@ -1014,20 +1091,47 @@ static inline int ov51x_stop(struct sd *sd)
1014{ 1091{
1015 PDEBUG(D_STREAM, "stopping"); 1092 PDEBUG(D_STREAM, "stopping");
1016 sd->stopped = 1; 1093 sd->stopped = 1;
1017 return reg_w(sd, OV519_SYS_RESET1, 0x0f); 1094 switch (sd->bridge) {
1095 case BRIDGE_OV511:
1096 case BRIDGE_OV511PLUS:
1097 return reg_w(sd, R51x_SYS_RESET, 0x3d);
1098 case BRIDGE_OV518:
1099 case BRIDGE_OV518PLUS:
1100 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
1101 case BRIDGE_OV519:
1102 return reg_w(sd, OV519_SYS_RESET1, 0x0f);
1103 }
1104
1105 return 0;
1018} 1106}
1019 1107
1020/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not 1108/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
1021 * actually stopped (for performance). */ 1109 * actually stopped (for performance). */
1022static inline int ov51x_restart(struct sd *sd) 1110static inline int ov51x_restart(struct sd *sd)
1023{ 1111{
1112 int rc;
1113
1024 PDEBUG(D_STREAM, "restarting"); 1114 PDEBUG(D_STREAM, "restarting");
1025 if (!sd->stopped) 1115 if (!sd->stopped)
1026 return 0; 1116 return 0;
1027 sd->stopped = 0; 1117 sd->stopped = 0;
1028 1118
1029 /* Reinitialize the stream */ 1119 /* Reinitialize the stream */
1030 return reg_w(sd, OV519_SYS_RESET1, 0x00); 1120 switch (sd->bridge) {
1121 case BRIDGE_OV511:
1122 case BRIDGE_OV511PLUS:
1123 return reg_w(sd, R51x_SYS_RESET, 0x00);
1124 case BRIDGE_OV518:
1125 case BRIDGE_OV518PLUS:
1126 rc = reg_w(sd, 0x2f, 0x80);
1127 if (rc < 0)
1128 return rc;
1129 return reg_w(sd, R51x_SYS_RESET, 0x00);
1130 case BRIDGE_OV519:
1131 return reg_w(sd, OV519_SYS_RESET1, 0x00);
1132 }
1133
1134 return 0;
1031} 1135}
1032 1136
1033/* This does an initial reset of an OmniVision sensor and ensures that I2C 1137/* This does an initial reset of an OmniVision sensor and ensures that I2C
@@ -1287,16 +1391,161 @@ static int ov6xx0_configure(struct sd *sd)
1287/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ 1391/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
1288static void ov51x_led_control(struct sd *sd, int on) 1392static void ov51x_led_control(struct sd *sd, int on)
1289{ 1393{
1290 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ 1394 switch (sd->bridge) {
1395 /* OV511 has no LED control */
1396 case BRIDGE_OV511PLUS:
1397 reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
1398 break;
1399 case BRIDGE_OV518:
1400 case BRIDGE_OV518PLUS:
1401 reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
1402 break;
1403 case BRIDGE_OV519:
1404 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1405 break;
1406 }
1291} 1407}
1292 1408
1293/* this function is called at probe time */ 1409/* OV518 quantization tables are 8x4 (instead of 8x8) */
1294static int sd_config(struct gspca_dev *gspca_dev, 1410static int ov518_upload_quan_tables(struct sd *sd)
1295 const struct usb_device_id *id) 1411{
1412 const unsigned char yQuanTable518[] = {
1413 5, 4, 5, 6, 6, 7, 7, 7,
1414 5, 5, 5, 5, 6, 7, 7, 7,
1415 6, 6, 6, 6, 7, 7, 7, 8,
1416 7, 7, 6, 7, 7, 7, 8, 8
1417 };
1418
1419 const unsigned char uvQuanTable518[] = {
1420 6, 6, 6, 7, 7, 7, 7, 7,
1421 6, 6, 6, 7, 7, 7, 7, 7,
1422 6, 6, 6, 7, 7, 7, 7, 8,
1423 7, 7, 7, 7, 7, 7, 8, 8
1424 };
1425
1426 const unsigned char *pYTable = yQuanTable518;
1427 const unsigned char *pUVTable = uvQuanTable518;
1428 unsigned char val0, val1;
1429 int i, rc, reg = R51x_COMP_LUT_BEGIN;
1430
1431 PDEBUG(D_PROBE, "Uploading quantization tables");
1432
1433 for (i = 0; i < 16; i++) {
1434 val0 = *pYTable++;
1435 val1 = *pYTable++;
1436 val0 &= 0x0f;
1437 val1 &= 0x0f;
1438 val0 |= val1 << 4;
1439 rc = reg_w(sd, reg, val0);
1440 if (rc < 0)
1441 return rc;
1442
1443 val0 = *pUVTable++;
1444 val1 = *pUVTable++;
1445 val0 &= 0x0f;
1446 val1 &= 0x0f;
1447 val0 |= val1 << 4;
1448 rc = reg_w(sd, reg + 16, val0);
1449 if (rc < 0)
1450 return rc;
1451
1452 reg++;
1453 }
1454
1455 return 0;
1456}
1457
1458/* This initializes the OV518/OV518+ and the sensor */
1459static int ov518_configure(struct gspca_dev *gspca_dev)
1296{ 1460{
1297 struct sd *sd = (struct sd *) gspca_dev; 1461 struct sd *sd = (struct sd *) gspca_dev;
1298 struct cam *cam; 1462 int rc;
1463
1464 /* For 518 and 518+ */
1465 static struct ov_regvals init_518[] = {
1466 { R51x_SYS_RESET, 0x40 },
1467 { R51x_SYS_INIT, 0xe1 },
1468 { R51x_SYS_RESET, 0x3e },
1469 { R51x_SYS_INIT, 0xe1 },
1470 { R51x_SYS_RESET, 0x00 },
1471 { R51x_SYS_INIT, 0xe1 },
1472 { 0x46, 0x00 },
1473 { 0x5d, 0x03 },
1474 };
1475
1476 static struct ov_regvals norm_518[] = {
1477 { R51x_SYS_SNAP, 0x02 }, /* Reset */
1478 { R51x_SYS_SNAP, 0x01 }, /* Enable */
1479 { 0x31, 0x0f },
1480 { 0x5d, 0x03 },
1481 { 0x24, 0x9f },
1482 { 0x25, 0x90 },
1483 { 0x20, 0x00 },
1484 { 0x51, 0x04 },
1485 { 0x71, 0x19 },
1486 { 0x2f, 0x80 },
1487 };
1488
1489 static struct ov_regvals norm_518_p[] = {
1490 { R51x_SYS_SNAP, 0x02 }, /* Reset */
1491 { R51x_SYS_SNAP, 0x01 }, /* Enable */
1492 { 0x31, 0x0f },
1493 { 0x5d, 0x03 },
1494 { 0x24, 0x9f },
1495 { 0x25, 0x90 },
1496 { 0x20, 0x60 },
1497 { 0x51, 0x02 },
1498 { 0x71, 0x19 },
1499 { 0x40, 0xff },
1500 { 0x41, 0x42 },
1501 { 0x46, 0x00 },
1502 { 0x33, 0x04 },
1503 { 0x21, 0x19 },
1504 { 0x3f, 0x10 },
1505 { 0x2f, 0x80 },
1506 };
1507
1508 /* First 5 bits of custom ID reg are a revision ID on OV518 */
1509 PDEBUG(D_PROBE, "Device revision %d",
1510 0x1F & reg_r(sd, R51x_SYS_CUST_ID));
1511
1512 rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
1513 if (rc < 0)
1514 return rc;
1515
1516 /* Set LED GPIO pin to output mode */
1517 rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
1518 if (rc < 0)
1519 return rc;
1299 1520
1521 switch (sd->bridge) {
1522 case BRIDGE_OV518:
1523 rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
1524 if (rc < 0)
1525 return rc;
1526 break;
1527 case BRIDGE_OV518PLUS:
1528 rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
1529 if (rc < 0)
1530 return rc;
1531 break;
1532 }
1533
1534 rc = ov518_upload_quan_tables(sd);
1535 if (rc < 0) {
1536 PDEBUG(D_ERR, "Error uploading quantization tables");
1537 return rc;
1538 }
1539
1540 rc = reg_w(sd, 0x2f, 0x80);
1541 if (rc < 0)
1542 return rc;
1543
1544 return 0;
1545}
1546
1547static int ov519_configure(struct sd *sd)
1548{
1300 static const struct ov_regvals init_519[] = { 1549 static const struct ov_regvals init_519[] = {
1301 { 0x5a, 0x6d }, /* EnableSystem */ 1550 { 0x5a, 0x6d }, /* EnableSystem */
1302 { 0x53, 0x9b }, 1551 { 0x53, 0x9b },
@@ -1313,8 +1562,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
1313 /* windows reads 0x55 at this point*/ 1562 /* windows reads 0x55 at this point*/
1314 }; 1563 };
1315 1564
1316 if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) 1565 return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
1566}
1567
1568/* this function is called at probe time */
1569static int sd_config(struct gspca_dev *gspca_dev,
1570 const struct usb_device_id *id)
1571{
1572 struct sd *sd = (struct sd *) gspca_dev;
1573 struct cam *cam;
1574 int ret = 0;
1575
1576 sd->bridge = id->driver_info;
1577
1578 switch (sd->bridge) {
1579 case BRIDGE_OV518:
1580 case BRIDGE_OV518PLUS:
1581 ret = ov518_configure(gspca_dev);
1582 break;
1583 case BRIDGE_OV519:
1584 ret = ov519_configure(sd);
1585 break;
1586 }
1587
1588 if (ret)
1317 goto error; 1589 goto error;
1590
1318 ov51x_led_control(sd, 0); /* turn LED off */ 1591 ov51x_led_control(sd, 0); /* turn LED off */
1319 1592
1320 /* Test for 76xx */ 1593 /* Test for 76xx */
@@ -1360,12 +1633,26 @@ static int sd_config(struct gspca_dev *gspca_dev,
1360 } 1633 }
1361 1634
1362 cam = &gspca_dev->cam; 1635 cam = &gspca_dev->cam;
1363 if (!sd->sif) { 1636 switch (sd->bridge) {
1364 cam->cam_mode = vga_mode; 1637 case BRIDGE_OV518:
1365 cam->nmodes = ARRAY_SIZE(vga_mode); 1638 case BRIDGE_OV518PLUS:
1366 } else { 1639 if (!sd->sif) {
1367 cam->cam_mode = sif_mode; 1640 cam->cam_mode = ov518_vga_mode;
1368 cam->nmodes = ARRAY_SIZE(sif_mode); 1641 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
1642 } else {
1643 cam->cam_mode = ov518_sif_mode;
1644 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
1645 }
1646 break;
1647 case BRIDGE_OV519:
1648 if (!sd->sif) {
1649 cam->cam_mode = ov519_vga_mode;
1650 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
1651 } else {
1652 cam->cam_mode = ov519_sif_mode;
1653 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
1654 }
1655 break;
1369 } 1656 }
1370 sd->brightness = BRIGHTNESS_DEF; 1657 sd->brightness = BRIGHTNESS_DEF;
1371 sd->contrast = CONTRAST_DEF; 1658 sd->contrast = CONTRAST_DEF;
@@ -1422,6 +1709,106 @@ static int sd_init(struct gspca_dev *gspca_dev)
1422 return 0; 1709 return 0;
1423} 1710}
1424 1711
1712/* Sets up the OV518/OV518+ with the given image parameters
1713 *
1714 * OV518 needs a completely different approach, until we can figure out what
1715 * the individual registers do. Also, only 15 FPS is supported now.
1716 *
1717 * Do not put any sensor-specific code in here (including I2C I/O functions)
1718 */
1719static int ov518_mode_init_regs(struct sd *sd)
1720{
1721 int hsegs, vsegs;
1722
1723 /******** Set the mode ********/
1724
1725 reg_w(sd, 0x2b, 0);
1726 reg_w(sd, 0x2c, 0);
1727 reg_w(sd, 0x2d, 0);
1728 reg_w(sd, 0x2e, 0);
1729 reg_w(sd, 0x3b, 0);
1730 reg_w(sd, 0x3c, 0);
1731 reg_w(sd, 0x3d, 0);
1732 reg_w(sd, 0x3e, 0);
1733
1734 if (sd->bridge == BRIDGE_OV518) {
1735 /* Set 8-bit (YVYU) input format */
1736 reg_w_mask(sd, 0x20, 0x08, 0x08);
1737
1738 /* Set 12-bit (4:2:0) output format */
1739 reg_w_mask(sd, 0x28, 0x80, 0xf0);
1740 reg_w_mask(sd, 0x38, 0x80, 0xf0);
1741 } else {
1742 reg_w(sd, 0x28, 0x80);
1743 reg_w(sd, 0x38, 0x80);
1744 }
1745
1746 hsegs = sd->gspca_dev.width / 16;
1747 vsegs = sd->gspca_dev.height / 4;
1748
1749 reg_w(sd, 0x29, hsegs);
1750 reg_w(sd, 0x2a, vsegs);
1751
1752 reg_w(sd, 0x39, hsegs);
1753 reg_w(sd, 0x3a, vsegs);
1754
1755 /* Windows driver does this here; who knows why */
1756 reg_w(sd, 0x2f, 0x80);
1757
1758 /******** Set the framerate (to 30 FPS) ********/
1759 if (sd->bridge == BRIDGE_OV518PLUS)
1760 sd->clockdiv = 1;
1761 else
1762 sd->clockdiv = 0;
1763
1764 /* Mode independent, but framerate dependent, regs */
1765 reg_w(sd, 0x51, 0x04); /* Clock divider; lower==faster */
1766 reg_w(sd, 0x22, 0x18);
1767 reg_w(sd, 0x23, 0xff);
1768
1769 if (sd->bridge == BRIDGE_OV518PLUS)
1770 reg_w(sd, 0x21, 0x19);
1771 else
1772 reg_w(sd, 0x71, 0x17); /* Compression-related? */
1773
1774 /* FIXME: Sensor-specific */
1775 /* Bit 5 is what matters here. Of course, it is "reserved" */
1776 i2c_w(sd, 0x54, 0x23);
1777
1778 reg_w(sd, 0x2f, 0x80);
1779
1780 if (sd->bridge == BRIDGE_OV518PLUS) {
1781 reg_w(sd, 0x24, 0x94);
1782 reg_w(sd, 0x25, 0x90);
1783 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
1784 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
1785 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
1786 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
1787 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
1788 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
1789 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
1790 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
1791 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
1792 } else {
1793 reg_w(sd, 0x24, 0x9f);
1794 reg_w(sd, 0x25, 0x90);
1795 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
1796 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
1797 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
1798 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
1799 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
1800 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
1801 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
1802 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
1803 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
1804 }
1805
1806 reg_w(sd, 0x2f, 0x80);
1807
1808 return 0;
1809}
1810
1811
1425/* Sets up the OV519 with the given image parameters 1812/* Sets up the OV519 with the given image parameters
1426 * 1813 *
1427 * OV519 needs a completely different approach, until we can figure out what 1814 * OV519 needs a completely different approach, until we can figure out what
@@ -1740,6 +2127,11 @@ static int set_ov_sensor_window(struct sd *sd)
1740 hwebase = 0x3a; 2127 hwebase = 0x3a;
1741 vwsbase = 0x05; 2128 vwsbase = 0x05;
1742 vwebase = 0x06; 2129 vwebase = 0x06;
2130 if (qvga) {
2131 /* HDG: this fixes U and V getting swapped */
2132 hwsbase--;
2133 vwsbase--;
2134 }
1743 break; 2135 break;
1744 case SEN_OV7620: 2136 case SEN_OV7620:
1745 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ 2137 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
@@ -1855,15 +2247,28 @@ static int set_ov_sensor_window(struct sd *sd)
1855static int sd_start(struct gspca_dev *gspca_dev) 2247static int sd_start(struct gspca_dev *gspca_dev)
1856{ 2248{
1857 struct sd *sd = (struct sd *) gspca_dev; 2249 struct sd *sd = (struct sd *) gspca_dev;
1858 int ret; 2250 int ret = 0;
1859 2251
1860 ret = ov519_mode_init_regs(sd); 2252 switch (sd->bridge) {
2253 case BRIDGE_OV518:
2254 case BRIDGE_OV518PLUS:
2255 ret = ov518_mode_init_regs(sd);
2256 break;
2257 case BRIDGE_OV519:
2258 ret = ov519_mode_init_regs(sd);
2259 break;
2260 }
1861 if (ret < 0) 2261 if (ret < 0)
1862 goto out; 2262 goto out;
2263
1863 ret = set_ov_sensor_window(sd); 2264 ret = set_ov_sensor_window(sd);
1864 if (ret < 0) 2265 if (ret < 0)
1865 goto out; 2266 goto out;
1866 2267
2268 setcontrast(gspca_dev);
2269 setbrightness(gspca_dev);
2270 setcolors(gspca_dev);
2271
1867 ret = ov51x_restart(sd); 2272 ret = ov51x_restart(sd);
1868 if (ret < 0) 2273 if (ret < 0)
1869 goto out; 2274 goto out;
@@ -1882,7 +2287,30 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1882 ov51x_led_control(sd, 0); 2287 ov51x_led_control(sd, 0);
1883} 2288}
1884 2289
1885static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2290static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
2291 struct gspca_frame *frame, /* target */
2292 __u8 *data, /* isoc packet */
2293 int len) /* iso packet length */
2294{
2295 PDEBUG(D_STREAM, "ov518_pkt_scan: %d bytes", len);
2296
2297 if (len & 7) {
2298 len--;
2299 PDEBUG(D_STREAM, "packet number: %d\n", (int)data[len]);
2300 }
2301
2302 /* A false positive here is likely, until OVT gives me
2303 * the definitive SOF/EOF format */
2304 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
2305 gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
2306 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
2307 }
2308
2309 /* intermediate packet */
2310 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
2311}
2312
2313static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
1886 struct gspca_frame *frame, /* target */ 2314 struct gspca_frame *frame, /* target */
1887 __u8 *data, /* isoc packet */ 2315 __u8 *data, /* isoc packet */
1888 int len) /* iso packet length */ 2316 int len) /* iso packet length */
@@ -1926,6 +2354,27 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1926 data, len); 2354 data, len);
1927} 2355}
1928 2356
2357static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2358 struct gspca_frame *frame, /* target */
2359 __u8 *data, /* isoc packet */
2360 int len) /* iso packet length */
2361{
2362 struct sd *sd = (struct sd *) gspca_dev;
2363
2364 switch (sd->bridge) {
2365 case BRIDGE_OV511:
2366 case BRIDGE_OV511PLUS:
2367 break;
2368 case BRIDGE_OV518:
2369 case BRIDGE_OV518PLUS:
2370 ov518_pkt_scan(gspca_dev, frame, data, len);
2371 break;
2372 case BRIDGE_OV519:
2373 ov519_pkt_scan(gspca_dev, frame, data, len);
2374 break;
2375 }
2376}
2377
1929/* -- management routines -- */ 2378/* -- management routines -- */
1930 2379
1931static void setbrightness(struct gspca_dev *gspca_dev) 2380static void setbrightness(struct gspca_dev *gspca_dev)
@@ -1970,6 +2419,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1970 break; 2419 break;
1971 case SEN_OV6630: 2420 case SEN_OV6630:
1972 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); 2421 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
2422 break;
1973 case SEN_OV8610: { 2423 case SEN_OV8610: {
1974 static const __u8 ctab[] = { 2424 static const __u8 ctab[] = {
1975 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f 2425 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
@@ -2136,19 +2586,21 @@ static const struct sd_desc sd_desc = {
2136 2586
2137/* -- module initialisation -- */ 2587/* -- module initialisation -- */
2138static const __devinitdata struct usb_device_id device_table[] = { 2588static const __devinitdata struct usb_device_id device_table[] = {
2139 {USB_DEVICE(0x041e, 0x4052)}, 2589 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
2140 {USB_DEVICE(0x041e, 0x405f)}, 2590 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
2141 {USB_DEVICE(0x041e, 0x4060)}, 2591 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
2142 {USB_DEVICE(0x041e, 0x4061)}, 2592 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
2143 {USB_DEVICE(0x041e, 0x4064)}, 2593 {USB_DEVICE(0x041e, 0x4064), .driver_info = BRIDGE_OV519 },
2144 {USB_DEVICE(0x041e, 0x4068)}, 2594 {USB_DEVICE(0x041e, 0x4068), .driver_info = BRIDGE_OV519 },
2145 {USB_DEVICE(0x045e, 0x028c)}, 2595 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
2146 {USB_DEVICE(0x054c, 0x0154)}, 2596 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
2147 {USB_DEVICE(0x054c, 0x0155)}, 2597 {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
2148 {USB_DEVICE(0x05a9, 0x0519)}, 2598 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
2149 {USB_DEVICE(0x05a9, 0x0530)}, 2599 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
2150 {USB_DEVICE(0x05a9, 0x4519)}, 2600 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
2151 {USB_DEVICE(0x05a9, 0x8519)}, 2601 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
2602 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
2603 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
2152 {} 2604 {}
2153}; 2605};
2154 2606
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index ebb2ea6b4995..f24eceecc5a6 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -347,7 +347,8 @@ struct v4l2_pix_format {
347#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ 347#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */
348#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ 348#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
349#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ 349#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
350#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ 350#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
351#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
351 352
352/* 353/*
353 * F O R M A T E N U M E R A T I O N 354 * F O R M A T E N U M E R A T I O N