aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-06-14 18:10:40 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-23 02:12:47 -0400
commitb282d87332f5b3c2ac2e289f772b33067e4be77b (patch)
tree4e025e4d818e1ddf71c501dd695de87c230ab8cf /drivers/media
parent1876bb923c98c605eca69f0bfe295f7b5f5eba28 (diff)
V4L/DVB (12080): gspca_ov519: Fix ov518+ with OV7620AE (Trust spacecam 320)
gspca_ov519: Fix ov518+ with OV7620AE (Trust spacecam 320) Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/gspca/ov519.c91
1 files changed, 55 insertions, 36 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 1f8e2613ecc5..3aebc744368d 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -269,37 +269,43 @@ static const struct v4l2_pix_format ov519_sif_mode[] = {
269 .priv = 0}, 269 .priv = 0},
270}; 270};
271 271
272/* Note some of the sizeimage values for the ov511 / ov518 may seem
273 larger then necessary, however they need to be this big as the ov511 /
274 ov518 always fills the entire isoc frame, using 0 padding bytes when
275 it doesn't have any data. So with low framerates the amount of data
276 transfered can become quite large (libv4l will remove all the 0 padding
277 in userspace). */
272static const struct v4l2_pix_format ov518_vga_mode[] = { 278static const struct v4l2_pix_format ov518_vga_mode[] = {
273 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, 279 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
274 .bytesperline = 320, 280 .bytesperline = 320,
275 .sizeimage = 320 * 240 * 3 / 8 + 590, 281 .sizeimage = 320 * 240 * 3,
276 .colorspace = V4L2_COLORSPACE_JPEG, 282 .colorspace = V4L2_COLORSPACE_JPEG,
277 .priv = 1}, 283 .priv = 1},
278 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, 284 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
279 .bytesperline = 640, 285 .bytesperline = 640,
280 .sizeimage = 640 * 480 * 3 / 8 + 590, 286 .sizeimage = 640 * 480 * 2,
281 .colorspace = V4L2_COLORSPACE_JPEG, 287 .colorspace = V4L2_COLORSPACE_JPEG,
282 .priv = 0}, 288 .priv = 0},
283}; 289};
284static const struct v4l2_pix_format ov518_sif_mode[] = { 290static const struct v4l2_pix_format ov518_sif_mode[] = {
285 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, 291 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
286 .bytesperline = 160, 292 .bytesperline = 160,
287 .sizeimage = 40000, 293 .sizeimage = 70000,
288 .colorspace = V4L2_COLORSPACE_JPEG, 294 .colorspace = V4L2_COLORSPACE_JPEG,
289 .priv = 3}, 295 .priv = 3},
290 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, 296 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
291 .bytesperline = 176, 297 .bytesperline = 176,
292 .sizeimage = 40000, 298 .sizeimage = 70000,
293 .colorspace = V4L2_COLORSPACE_JPEG, 299 .colorspace = V4L2_COLORSPACE_JPEG,
294 .priv = 1}, 300 .priv = 1},
295 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, 301 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
296 .bytesperline = 320, 302 .bytesperline = 320,
297 .sizeimage = 320 * 240 * 3 / 8 + 590, 303 .sizeimage = 320 * 240 * 3,
298 .colorspace = V4L2_COLORSPACE_JPEG, 304 .colorspace = V4L2_COLORSPACE_JPEG,
299 .priv = 2}, 305 .priv = 2},
300 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE, 306 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
301 .bytesperline = 352, 307 .bytesperline = 352,
302 .sizeimage = 352 * 288 * 3 / 8 + 590, 308 .sizeimage = 352 * 288 * 3,
303 .colorspace = V4L2_COLORSPACE_JPEG, 309 .colorspace = V4L2_COLORSPACE_JPEG,
304 .priv = 0}, 310 .priv = 0},
305}; 311};
@@ -319,12 +325,12 @@ static const struct v4l2_pix_format ov511_vga_mode[] = {
319static const struct v4l2_pix_format ov511_sif_mode[] = { 325static const struct v4l2_pix_format ov511_sif_mode[] = {
320 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, 326 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
321 .bytesperline = 160, 327 .bytesperline = 160,
322 .sizeimage = 40000, 328 .sizeimage = 70000,
323 .colorspace = V4L2_COLORSPACE_JPEG, 329 .colorspace = V4L2_COLORSPACE_JPEG,
324 .priv = 3}, 330 .priv = 3},
325 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, 331 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
326 .bytesperline = 176, 332 .bytesperline = 176,
327 .sizeimage = 40000, 333 .sizeimage = 70000,
328 .colorspace = V4L2_COLORSPACE_JPEG, 334 .colorspace = V4L2_COLORSPACE_JPEG,
329 .priv = 1}, 335 .priv = 1},
330 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE, 336 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
@@ -698,7 +704,7 @@ static const struct ov_i2c_regvals norm_7620[] = {
698 { 0x23, 0x00 }, 704 { 0x23, 0x00 },
699 { 0x26, 0xa2 }, 705 { 0x26, 0xa2 },
700 { 0x27, 0xea }, 706 { 0x27, 0xea },
701 { 0x28, 0x20 }, 707 { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
702 { 0x29, 0x00 }, 708 { 0x29, 0x00 },
703 { 0x2a, 0x10 }, 709 { 0x2a, 0x10 },
704 { 0x2b, 0x00 }, 710 { 0x2b, 0x00 },
@@ -1525,7 +1531,6 @@ static int ov8xx0_configure(struct sd *sd)
1525 } 1531 }
1526 1532
1527 /* Set sensor-specific vars */ 1533 /* Set sensor-specific vars */
1528/* sd->sif = 0; already done */
1529 return 0; 1534 return 0;
1530} 1535}
1531 1536
@@ -1562,15 +1567,13 @@ static int ov7xx0_configure(struct sd *sd)
1562 } 1567 }
1563 } else if ((rc & 3) == 1) { 1568 } else if ((rc & 3) == 1) {
1564 /* I don't know what's different about the 76BE yet. */ 1569 /* I don't know what's different about the 76BE yet. */
1565 if (i2c_r(sd, 0x15) & 1) 1570 if (i2c_r(sd, 0x15) & 1) {
1566 PDEBUG(D_PROBE, "Sensor is an OV7620AE"); 1571 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
1567 else 1572 sd->sensor = SEN_OV7620;
1573 } else {
1568 PDEBUG(D_PROBE, "Sensor is an OV76BE"); 1574 PDEBUG(D_PROBE, "Sensor is an OV76BE");
1569 1575 sd->sensor = SEN_OV76BE;
1570 /* OV511+ will return all zero isoc data unless we 1576 }
1571 * configure the sensor as a 7620. Someone needs to
1572 * find the exact reg. setting that causes this. */
1573 sd->sensor = SEN_OV76BE;
1574 } else if ((rc & 3) == 0) { 1577 } else if ((rc & 3) == 0) {
1575 /* try to read product id registers */ 1578 /* try to read product id registers */
1576 high = i2c_r(sd, 0x0a); 1579 high = i2c_r(sd, 0x0a);
@@ -1616,7 +1619,6 @@ static int ov7xx0_configure(struct sd *sd)
1616 } 1619 }
1617 1620
1618 /* Set sensor-specific vars */ 1621 /* Set sensor-specific vars */
1619/* sd->sif = 0; already done */
1620 return 0; 1622 return 0;
1621} 1623}
1622 1624
@@ -2198,11 +2200,11 @@ static int ov511_mode_init_regs(struct sd *sd)
2198 for more sensors we need to do this for them too */ 2200 for more sensors we need to do this for them too */
2199 case SEN_OV7620: 2201 case SEN_OV7620:
2200 case SEN_OV7640: 2202 case SEN_OV7640:
2203 case SEN_OV76BE:
2201 if (sd->gspca_dev.width == 320) 2204 if (sd->gspca_dev.width == 320)
2202 interlaced = 1; 2205 interlaced = 1;
2203 /* Fall through */ 2206 /* Fall through */
2204 case SEN_OV6630: 2207 case SEN_OV6630:
2205 case SEN_OV76BE:
2206 case SEN_OV7610: 2208 case SEN_OV7610:
2207 case SEN_OV7670: 2209 case SEN_OV7670:
2208 switch (sd->frame_rate) { 2210 switch (sd->frame_rate) {
@@ -2268,7 +2270,19 @@ static int ov511_mode_init_regs(struct sd *sd)
2268 */ 2270 */
2269static int ov518_mode_init_regs(struct sd *sd) 2271static int ov518_mode_init_regs(struct sd *sd)
2270{ 2272{
2271 int hsegs, vsegs; 2273 int hsegs, vsegs, packet_size;
2274 struct usb_host_interface *alt;
2275 struct usb_interface *intf;
2276
2277 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
2278 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
2279 if (!alt) {
2280 PDEBUG(D_ERR, "Couldn't get altsetting");
2281 return -EIO;
2282 }
2283
2284 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
2285 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
2272 2286
2273 /******** Set the mode ********/ 2287 /******** Set the mode ********/
2274 2288
@@ -2305,20 +2319,30 @@ static int ov518_mode_init_regs(struct sd *sd)
2305 /* Windows driver does this here; who knows why */ 2319 /* Windows driver does this here; who knows why */
2306 reg_w(sd, 0x2f, 0x80); 2320 reg_w(sd, 0x2f, 0x80);
2307 2321
2308 /******** Set the framerate (to 30 FPS) ********/ 2322 /******** Set the framerate ********/
2309 if (sd->bridge == BRIDGE_OV518PLUS) 2323 sd->clockdiv = 1;
2310 sd->clockdiv = 1;
2311 else
2312 sd->clockdiv = 0;
2313 2324
2314 /* Mode independent, but framerate dependent, regs */ 2325 /* Mode independent, but framerate dependent, regs */
2315 reg_w(sd, 0x51, 0x04); /* Clock divider; lower==faster */ 2326 /* 0x51: Clock divider; Only works on some cams which use 2 crystals */
2327 reg_w(sd, 0x51, 0x04);
2316 reg_w(sd, 0x22, 0x18); 2328 reg_w(sd, 0x22, 0x18);
2317 reg_w(sd, 0x23, 0xff); 2329 reg_w(sd, 0x23, 0xff);
2318 2330
2319 if (sd->bridge == BRIDGE_OV518PLUS) 2331 if (sd->bridge == BRIDGE_OV518PLUS) {
2320 reg_w(sd, 0x21, 0x19); 2332 switch (sd->sensor) {
2321 else 2333 case SEN_OV7620:
2334 if (sd->gspca_dev.width == 320) {
2335 reg_w(sd, 0x20, 0x00);
2336 reg_w(sd, 0x21, 0x19);
2337 } else {
2338 reg_w(sd, 0x20, 0x60);
2339 reg_w(sd, 0x21, 0x1f);
2340 }
2341 break;
2342 default:
2343 reg_w(sd, 0x21, 0x19);
2344 }
2345 } else
2322 reg_w(sd, 0x71, 0x17); /* Compression-related? */ 2346 reg_w(sd, 0x71, 0x17); /* Compression-related? */
2323 2347
2324 /* FIXME: Sensor-specific */ 2348 /* FIXME: Sensor-specific */
@@ -2537,21 +2561,16 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
2537 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 2561 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
2538 break; 2562 break;
2539 case SEN_OV7620: 2563 case SEN_OV7620:
2540/* i2c_w(sd, 0x2b, 0x00); */ 2564 case SEN_OV76BE:
2541 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 2565 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
2542 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); 2566 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
2543 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); 2567 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
2544 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); 2568 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
2545 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); 2569 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
2546 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); 2570 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
2547 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); 2571 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
2548 break; 2572 break;
2549 case SEN_OV76BE:
2550/* i2c_w(sd, 0x2b, 0x00); */
2551 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
2552 break;
2553 case SEN_OV7640: 2573 case SEN_OV7640:
2554/* i2c_w(sd, 0x2b, 0x00); */
2555 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 2574 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
2556 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); 2575 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
2557/* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */ 2576/* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */