diff options
-rw-r--r-- | drivers/media/video/gspca/ov519.c | 91 |
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). */ | ||
272 | static const struct v4l2_pix_format ov518_vga_mode[] = { | 278 | static 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 | }; |
284 | static const struct v4l2_pix_format ov518_sif_mode[] = { | 290 | static 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[] = { | |||
319 | static const struct v4l2_pix_format ov511_sif_mode[] = { | 325 | static 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 | */ |
2269 | static int ov518_mode_init_regs(struct sd *sd) | 2271 | static 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); */ |