.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * ov534-ov7xxx gspca driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
13 | 14 | * PS3 Eye camera - brightness, contrast, awb, agc, aec controls |
---|
14 | 15 | * added by Max Thrun <bear24rw@gmail.com> |
---|
15 | 16 | * PS3 Eye camera - FPS range extended by Joseph Howse |
---|
16 | | - * <josephhowse@nummist.com> http://nummist.com |
---|
17 | | - * |
---|
18 | | - * This program is free software; you can redistribute it and/or modify |
---|
19 | | - * it under the terms of the GNU General Public License as published by |
---|
20 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
21 | | - * any later version. |
---|
22 | | - * |
---|
23 | | - * This program is distributed in the hope that it will be useful, |
---|
24 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
25 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
26 | | - * GNU General Public License for more details. |
---|
| 17 | + * <josephhowse@nummist.com> https://nummist.com |
---|
27 | 18 | */ |
---|
28 | 19 | |
---|
29 | 20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
103 | 94 | .sizeimage = 640 * 480 * 2, |
---|
104 | 95 | .colorspace = V4L2_COLORSPACE_SRGB, |
---|
105 | 96 | .priv = 0}, |
---|
| 97 | + {320, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, |
---|
| 98 | + .bytesperline = 320, |
---|
| 99 | + .sizeimage = 320 * 240, |
---|
| 100 | + .colorspace = V4L2_COLORSPACE_SRGB, |
---|
| 101 | + .priv = 1}, |
---|
| 102 | + {640, 480, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE, |
---|
| 103 | + .bytesperline = 640, |
---|
| 104 | + .sizeimage = 640 * 480, |
---|
| 105 | + .colorspace = V4L2_COLORSPACE_SRGB, |
---|
| 106 | + .priv = 0}, |
---|
106 | 107 | }; |
---|
107 | 108 | static const struct v4l2_pix_format ov767x_mode[] = { |
---|
108 | 109 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
---|
.. | .. |
---|
124 | 125 | .nrates = ARRAY_SIZE(qvga_rates), |
---|
125 | 126 | }, |
---|
126 | 127 | { /* 640x480 */ |
---|
| 128 | + .rates = vga_rates, |
---|
| 129 | + .nrates = ARRAY_SIZE(vga_rates), |
---|
| 130 | + }, |
---|
| 131 | + { /* 320x240 SGBRG8 */ |
---|
| 132 | + .rates = qvga_rates, |
---|
| 133 | + .nrates = ARRAY_SIZE(qvga_rates), |
---|
| 134 | + }, |
---|
| 135 | + { /* 640x480 SGBRG8 */ |
---|
127 | 136 | .rates = vga_rates, |
---|
128 | 137 | .nrates = ARRAY_SIZE(vga_rates), |
---|
129 | 138 | }, |
---|
.. | .. |
---|
411 | 420 | }; |
---|
412 | 421 | |
---|
413 | 422 | static const u8 bridge_init_772x[][2] = { |
---|
414 | | - { 0xc2, 0x0c }, |
---|
415 | 423 | { 0x88, 0xf8 }, |
---|
416 | | - { 0xc3, 0x69 }, |
---|
417 | 424 | { 0x89, 0xff }, |
---|
418 | 425 | { 0x76, 0x03 }, |
---|
419 | 426 | { 0x92, 0x01 }, |
---|
.. | .. |
---|
439 | 446 | { 0x1f, 0x81 }, |
---|
440 | 447 | { 0x34, 0x05 }, |
---|
441 | 448 | { 0xe3, 0x04 }, |
---|
442 | | - { 0x88, 0x00 }, |
---|
443 | 449 | { 0x89, 0x00 }, |
---|
444 | 450 | { 0x76, 0x00 }, |
---|
445 | 451 | { 0xe7, 0x2e }, |
---|
.. | .. |
---|
447 | 453 | { 0x25, 0x42 }, |
---|
448 | 454 | { 0x21, 0xf0 }, |
---|
449 | 455 | |
---|
450 | | - { 0x1c, 0x00 }, |
---|
451 | | - { 0x1d, 0x40 }, |
---|
452 | | - { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ |
---|
453 | | - { 0x1d, 0x00 }, /* payload size */ |
---|
454 | | - |
---|
455 | | - { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ |
---|
456 | | - { 0x1d, 0x58 }, /* frame size */ |
---|
457 | | - { 0x1d, 0x00 }, /* frame size */ |
---|
458 | | - |
---|
459 | 456 | { 0x1c, 0x0a }, |
---|
460 | 457 | { 0x1d, 0x08 }, /* turn on UVC header */ |
---|
461 | 458 | { 0x1d, 0x0e }, /* .. */ |
---|
462 | | - |
---|
463 | | - { 0x8d, 0x1c }, |
---|
464 | | - { 0x8e, 0x80 }, |
---|
465 | | - { 0xe5, 0x04 }, |
---|
466 | | - |
---|
467 | | - { 0xc0, 0x50 }, |
---|
468 | | - { 0xc1, 0x3c }, |
---|
469 | | - { 0xc2, 0x0c }, |
---|
470 | 459 | }; |
---|
471 | 460 | static const u8 sensor_init_772x[][2] = { |
---|
472 | 461 | { 0x12, 0x80 }, |
---|
.. | .. |
---|
545 | 534 | { 0x8c, 0xe8 }, |
---|
546 | 535 | { 0x8d, 0x20 }, |
---|
547 | 536 | |
---|
548 | | - { 0x0c, 0x90 }, |
---|
549 | | - |
---|
550 | 537 | { 0x2b, 0x00 }, |
---|
551 | 538 | { 0x22, 0x7f }, |
---|
552 | 539 | { 0x23, 0x03 }, |
---|
553 | 540 | { 0x11, 0x01 }, |
---|
554 | | - { 0x0c, 0xd0 }, |
---|
555 | 541 | { 0x64, 0xff }, |
---|
556 | 542 | { 0x0d, 0x41 }, |
---|
557 | 543 | |
---|
.. | .. |
---|
559 | 545 | { 0x0e, 0xcd }, |
---|
560 | 546 | { 0xac, 0xbf }, |
---|
561 | 547 | { 0x8e, 0x00 }, /* De-noise threshold */ |
---|
562 | | - { 0x0c, 0xd0 } |
---|
563 | 548 | }; |
---|
564 | | -static const u8 bridge_start_vga_772x[][2] = { |
---|
| 549 | +static const u8 bridge_start_vga_yuyv_772x[][2] = { |
---|
| 550 | + {0x88, 0x00}, |
---|
565 | 551 | {0x1c, 0x00}, |
---|
566 | 552 | {0x1d, 0x40}, |
---|
567 | 553 | {0x1d, 0x02}, |
---|
.. | .. |
---|
569 | 555 | {0x1d, 0x02}, |
---|
570 | 556 | {0x1d, 0x58}, |
---|
571 | 557 | {0x1d, 0x00}, |
---|
| 558 | + {0x8d, 0x1c}, |
---|
| 559 | + {0x8e, 0x80}, |
---|
572 | 560 | {0xc0, 0x50}, |
---|
573 | 561 | {0xc1, 0x3c}, |
---|
| 562 | + {0xc2, 0x0c}, |
---|
| 563 | + {0xc3, 0x69}, |
---|
574 | 564 | }; |
---|
575 | | -static const u8 sensor_start_vga_772x[][2] = { |
---|
| 565 | +static const u8 sensor_start_vga_yuyv_772x[][2] = { |
---|
576 | 566 | {0x12, 0x00}, |
---|
577 | 567 | {0x17, 0x26}, |
---|
578 | 568 | {0x18, 0xa0}, |
---|
.. | .. |
---|
581 | 571 | {0x29, 0xa0}, |
---|
582 | 572 | {0x2c, 0xf0}, |
---|
583 | 573 | {0x65, 0x20}, |
---|
| 574 | + {0x67, 0x00}, |
---|
584 | 575 | }; |
---|
585 | | -static const u8 bridge_start_qvga_772x[][2] = { |
---|
| 576 | +static const u8 bridge_start_qvga_yuyv_772x[][2] = { |
---|
| 577 | + {0x88, 0x00}, |
---|
586 | 578 | {0x1c, 0x00}, |
---|
587 | 579 | {0x1d, 0x40}, |
---|
588 | 580 | {0x1d, 0x02}, |
---|
.. | .. |
---|
590 | 582 | {0x1d, 0x01}, |
---|
591 | 583 | {0x1d, 0x4b}, |
---|
592 | 584 | {0x1d, 0x00}, |
---|
| 585 | + {0x8d, 0x1c}, |
---|
| 586 | + {0x8e, 0x80}, |
---|
593 | 587 | {0xc0, 0x28}, |
---|
594 | 588 | {0xc1, 0x1e}, |
---|
| 589 | + {0xc2, 0x0c}, |
---|
| 590 | + {0xc3, 0x69}, |
---|
595 | 591 | }; |
---|
596 | | -static const u8 sensor_start_qvga_772x[][2] = { |
---|
| 592 | +static const u8 sensor_start_qvga_yuyv_772x[][2] = { |
---|
597 | 593 | {0x12, 0x40}, |
---|
598 | 594 | {0x17, 0x3f}, |
---|
599 | 595 | {0x18, 0x50}, |
---|
.. | .. |
---|
602 | 598 | {0x29, 0x50}, |
---|
603 | 599 | {0x2c, 0x78}, |
---|
604 | 600 | {0x65, 0x2f}, |
---|
| 601 | + {0x67, 0x00}, |
---|
| 602 | +}; |
---|
| 603 | +static const u8 bridge_start_vga_gbrg_772x[][2] = { |
---|
| 604 | + {0x88, 0x08}, |
---|
| 605 | + {0x1c, 0x00}, |
---|
| 606 | + {0x1d, 0x00}, |
---|
| 607 | + {0x1d, 0x02}, |
---|
| 608 | + {0x1d, 0x00}, |
---|
| 609 | + {0x1d, 0x01}, |
---|
| 610 | + {0x1d, 0x2c}, |
---|
| 611 | + {0x1d, 0x00}, |
---|
| 612 | + {0x8d, 0x00}, |
---|
| 613 | + {0x8e, 0x00}, |
---|
| 614 | + {0xc0, 0x50}, |
---|
| 615 | + {0xc1, 0x3c}, |
---|
| 616 | + {0xc2, 0x01}, |
---|
| 617 | + {0xc3, 0x01}, |
---|
| 618 | +}; |
---|
| 619 | +static const u8 sensor_start_vga_gbrg_772x[][2] = { |
---|
| 620 | + {0x12, 0x01}, |
---|
| 621 | + {0x17, 0x26}, |
---|
| 622 | + {0x18, 0xa0}, |
---|
| 623 | + {0x19, 0x07}, |
---|
| 624 | + {0x1a, 0xf0}, |
---|
| 625 | + {0x29, 0xa0}, |
---|
| 626 | + {0x2c, 0xf0}, |
---|
| 627 | + {0x65, 0x20}, |
---|
| 628 | + {0x67, 0x02}, |
---|
| 629 | +}; |
---|
| 630 | +static const u8 bridge_start_qvga_gbrg_772x[][2] = { |
---|
| 631 | + {0x88, 0x08}, |
---|
| 632 | + {0x1c, 0x00}, |
---|
| 633 | + {0x1d, 0x00}, |
---|
| 634 | + {0x1d, 0x02}, |
---|
| 635 | + {0x1d, 0x00}, |
---|
| 636 | + {0x1d, 0x00}, |
---|
| 637 | + {0x1d, 0x4b}, |
---|
| 638 | + {0x1d, 0x00}, |
---|
| 639 | + {0x8d, 0x00}, |
---|
| 640 | + {0x8e, 0x00}, |
---|
| 641 | + {0xc0, 0x28}, |
---|
| 642 | + {0xc1, 0x1e}, |
---|
| 643 | + {0xc2, 0x01}, |
---|
| 644 | + {0xc3, 0x01}, |
---|
| 645 | +}; |
---|
| 646 | +static const u8 sensor_start_qvga_gbrg_772x[][2] = { |
---|
| 647 | + {0x12, 0x41}, |
---|
| 648 | + {0x17, 0x3f}, |
---|
| 649 | + {0x18, 0x50}, |
---|
| 650 | + {0x19, 0x03}, |
---|
| 651 | + {0x1a, 0x78}, |
---|
| 652 | + {0x29, 0x50}, |
---|
| 653 | + {0x2c, 0x78}, |
---|
| 654 | + {0x65, 0x2f}, |
---|
| 655 | + {0x67, 0x02}, |
---|
605 | 656 | }; |
---|
606 | 657 | |
---|
607 | 658 | static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) |
---|
.. | .. |
---|
684 | 735 | int i; |
---|
685 | 736 | |
---|
686 | 737 | for (i = 0; i < 5; i++) { |
---|
687 | | - msleep(10); |
---|
| 738 | + usleep_range(10000, 20000); |
---|
688 | 739 | data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); |
---|
689 | 740 | |
---|
690 | 741 | switch (data) { |
---|
.. | .. |
---|
1282 | 1333 | |
---|
1283 | 1334 | /* reset sensor */ |
---|
1284 | 1335 | sccb_reg_write(gspca_dev, 0x12, 0x80); |
---|
1285 | | - msleep(10); |
---|
| 1336 | + usleep_range(10000, 20000); |
---|
1286 | 1337 | |
---|
1287 | 1338 | /* probe the sensor */ |
---|
1288 | 1339 | sccb_reg_read(gspca_dev, 0x0a); |
---|
.. | .. |
---|
1320 | 1371 | { |
---|
1321 | 1372 | struct sd *sd = (struct sd *) gspca_dev; |
---|
1322 | 1373 | int mode; |
---|
1323 | | - static const struct reg_array bridge_start[NSENSORS][2] = { |
---|
| 1374 | + static const struct reg_array bridge_start[NSENSORS][4] = { |
---|
1324 | 1375 | [SENSOR_OV767x] = {{bridge_start_qvga_767x, |
---|
1325 | 1376 | ARRAY_SIZE(bridge_start_qvga_767x)}, |
---|
1326 | 1377 | {bridge_start_vga_767x, |
---|
1327 | 1378 | ARRAY_SIZE(bridge_start_vga_767x)}}, |
---|
1328 | | - [SENSOR_OV772x] = {{bridge_start_qvga_772x, |
---|
1329 | | - ARRAY_SIZE(bridge_start_qvga_772x)}, |
---|
1330 | | - {bridge_start_vga_772x, |
---|
1331 | | - ARRAY_SIZE(bridge_start_vga_772x)}}, |
---|
| 1379 | + [SENSOR_OV772x] = {{bridge_start_qvga_yuyv_772x, |
---|
| 1380 | + ARRAY_SIZE(bridge_start_qvga_yuyv_772x)}, |
---|
| 1381 | + {bridge_start_vga_yuyv_772x, |
---|
| 1382 | + ARRAY_SIZE(bridge_start_vga_yuyv_772x)}, |
---|
| 1383 | + {bridge_start_qvga_gbrg_772x, |
---|
| 1384 | + ARRAY_SIZE(bridge_start_qvga_gbrg_772x)}, |
---|
| 1385 | + {bridge_start_vga_gbrg_772x, |
---|
| 1386 | + ARRAY_SIZE(bridge_start_vga_gbrg_772x)} }, |
---|
1332 | 1387 | }; |
---|
1333 | | - static const struct reg_array sensor_start[NSENSORS][2] = { |
---|
| 1388 | + static const struct reg_array sensor_start[NSENSORS][4] = { |
---|
1334 | 1389 | [SENSOR_OV767x] = {{sensor_start_qvga_767x, |
---|
1335 | 1390 | ARRAY_SIZE(sensor_start_qvga_767x)}, |
---|
1336 | 1391 | {sensor_start_vga_767x, |
---|
1337 | 1392 | ARRAY_SIZE(sensor_start_vga_767x)}}, |
---|
1338 | | - [SENSOR_OV772x] = {{sensor_start_qvga_772x, |
---|
1339 | | - ARRAY_SIZE(sensor_start_qvga_772x)}, |
---|
1340 | | - {sensor_start_vga_772x, |
---|
1341 | | - ARRAY_SIZE(sensor_start_vga_772x)}}, |
---|
| 1393 | + [SENSOR_OV772x] = {{sensor_start_qvga_yuyv_772x, |
---|
| 1394 | + ARRAY_SIZE(sensor_start_qvga_yuyv_772x)}, |
---|
| 1395 | + {sensor_start_vga_yuyv_772x, |
---|
| 1396 | + ARRAY_SIZE(sensor_start_vga_yuyv_772x)}, |
---|
| 1397 | + {sensor_start_qvga_gbrg_772x, |
---|
| 1398 | + ARRAY_SIZE(sensor_start_qvga_gbrg_772x)}, |
---|
| 1399 | + {sensor_start_vga_gbrg_772x, |
---|
| 1400 | + ARRAY_SIZE(sensor_start_vga_gbrg_772x)} }, |
---|
1342 | 1401 | }; |
---|
1343 | 1402 | |
---|
1344 | 1403 | /* (from ms-win trace) */ |
---|
.. | .. |
---|
1444 | 1503 | /* If this packet is marked as EOF, end the frame */ |
---|
1445 | 1504 | } else if (data[1] & UVC_STREAM_EOF) { |
---|
1446 | 1505 | sd->last_pts = 0; |
---|
1447 | | - if (gspca_dev->pixfmt.pixelformat == V4L2_PIX_FMT_YUYV |
---|
| 1506 | + if (gspca_dev->pixfmt.pixelformat != V4L2_PIX_FMT_JPEG |
---|
1448 | 1507 | && gspca_dev->image_len + len - 12 != |
---|
1449 | | - gspca_dev->pixfmt.width * |
---|
1450 | | - gspca_dev->pixfmt.height * 2) { |
---|
| 1508 | + gspca_dev->pixfmt.sizeimage) { |
---|
1451 | 1509 | gspca_dbg(gspca_dev, D_PACK, "wrong sized frame\n"); |
---|
1452 | 1510 | goto discard; |
---|
1453 | 1511 | } |
---|