diff options
-rw-r--r-- | drivers/media/video/gspca/sonixb.c | 174 |
1 files changed, 82 insertions, 92 deletions
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index f6bef896d3a..4f9c9ecb06e 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c | |||
@@ -41,6 +41,7 @@ struct sd { | |||
41 | unsigned char brightness; | 41 | unsigned char brightness; |
42 | unsigned char autogain; | 42 | unsigned char autogain; |
43 | unsigned char autogain_ignore_frames; | 43 | unsigned char autogain_ignore_frames; |
44 | unsigned char frames_to_drop; | ||
44 | unsigned char freq; /* light freq filter setting */ | 45 | unsigned char freq; /* light freq filter setting */ |
45 | unsigned char saturation; | 46 | unsigned char saturation; |
46 | unsigned char hue; | 47 | unsigned char hue; |
@@ -51,13 +52,13 @@ struct sd { | |||
51 | #define SENSOR_HV7131R 0 | 52 | #define SENSOR_HV7131R 0 |
52 | #define SENSOR_OV6650 1 | 53 | #define SENSOR_OV6650 1 |
53 | #define SENSOR_OV7630 2 | 54 | #define SENSOR_OV7630 2 |
54 | #define SENSOR_OV7630_3 3 | 55 | #define SENSOR_PAS106 3 |
55 | #define SENSOR_PAS106 4 | 56 | #define SENSOR_PAS202 4 |
56 | #define SENSOR_PAS202 5 | 57 | #define SENSOR_TAS5110 5 |
57 | #define SENSOR_TAS5110 6 | 58 | #define SENSOR_TAS5130CXX 6 |
58 | #define SENSOR_TAS5130CXX 7 | ||
59 | char sensor_has_gain; | 59 | char sensor_has_gain; |
60 | __u8 sensor_addr; | 60 | __u8 sensor_addr; |
61 | __u8 reg11; | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | #define COMP2 0x8f | 64 | #define COMP2 0x8f |
@@ -318,7 +319,7 @@ static const __u8 initOv7630_3[] = { | |||
318 | 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ | 319 | 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ |
319 | 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */ | 320 | 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */ |
320 | }; | 321 | }; |
321 | static const __u8 ov7630_sensor_init_com[][8] = { | 322 | static const __u8 ov7630_sensor_init[][8] = { |
322 | {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, | 323 | {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, |
323 | {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, | 324 | {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, |
324 | /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ | 325 | /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ |
@@ -339,17 +340,6 @@ static const __u8 ov7630_sensor_init_com[][8] = { | |||
339 | {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10}, | 340 | {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10}, |
340 | {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, | 341 | {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, |
341 | }; | 342 | }; |
342 | static const __u8 ov7630_sensor_init[][8] = { | ||
343 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */ | ||
344 | {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */ | ||
345 | {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16}, | ||
346 | {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16}, | ||
347 | {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ | ||
348 | }; | ||
349 | static const __u8 ov7630_sensor_init_3[][8] = { | ||
350 | {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10}, | ||
351 | {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10}, | ||
352 | }; | ||
353 | 343 | ||
354 | static const __u8 initPas106[] = { | 344 | static const __u8 initPas106[] = { |
355 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, | 345 | 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, |
@@ -539,7 +529,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
539 | 529 | ||
540 | switch (sd->sensor) { | 530 | switch (sd->sensor) { |
541 | case SENSOR_OV6650: | 531 | case SENSOR_OV6650: |
542 | case SENSOR_OV7630_3: | ||
543 | case SENSOR_OV7630: { | 532 | case SENSOR_OV7630: { |
544 | __u8 i2cOV[] = | 533 | __u8 i2cOV[] = |
545 | {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; | 534 | {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; |
@@ -632,7 +621,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev) | |||
632 | case SENSOR_OV6650: | 621 | case SENSOR_OV6650: |
633 | gain >>= 1; | 622 | gain >>= 1; |
634 | /* fall thru */ | 623 | /* fall thru */ |
635 | case SENSOR_OV7630_3: { | 624 | case SENSOR_OV7630: { |
636 | __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; | 625 | __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; |
637 | 626 | ||
638 | i2c[1] = sd->sensor_addr; | 627 | i2c[1] = sd->sensor_addr; |
@@ -687,7 +676,7 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
687 | break; | 676 | break; |
688 | } | 677 | } |
689 | case SENSOR_OV6650: | 678 | case SENSOR_OV6650: |
690 | case SENSOR_OV7630_3: { | 679 | case SENSOR_OV7630: { |
691 | /* The ov6650 / ov7630 have 2 registers which both influence | 680 | /* The ov6650 / ov7630 have 2 registers which both influence |
692 | exposure, register 11, whose low nibble sets the nr off fps | 681 | exposure, register 11, whose low nibble sets the nr off fps |
693 | according to: fps = 30 / (low_nibble + 1) | 682 | according to: fps = 30 / (low_nibble + 1) |
@@ -702,16 +691,20 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
702 | The code maps our 0 - 510 ms exposure ctrl to these 2 | 691 | The code maps our 0 - 510 ms exposure ctrl to these 2 |
703 | registers, trying to keep fps as high as possible. | 692 | registers, trying to keep fps as high as possible. |
704 | */ | 693 | */ |
705 | __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; | 694 | __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}; |
706 | int reg10, reg11; | 695 | int reg10, reg11, reg10_max; |
696 | |||
707 | /* ov6645 datasheet says reg10_max is 9a, but that uses | 697 | /* ov6645 datasheet says reg10_max is 9a, but that uses |
708 | tline * 2 * reg10 as formula for calculating texpo, the | 698 | tline * 2 * reg10 as formula for calculating texpo, the |
709 | ov6650 probably uses the same formula as the 7730 which uses | 699 | ov6650 probably uses the same formula as the 7730 which uses |
710 | tline * 4 * reg10, which explains why the reg10max we've | 700 | tline * 4 * reg10, which explains why the reg10max we've |
711 | found experimentally for the ov6650 is exactly half that of | 701 | found experimentally for the ov6650 is exactly half that of |
712 | the ov6645. The ov7630 datasheet says the max is 0x41. */ | 702 | the ov6645. The ov7630 datasheet says the max is 0x41. */ |
713 | const int reg10_max = (sd->sensor == SENSOR_OV6650) | 703 | if (sd->sensor == SENSOR_OV6650) { |
714 | ? 0x4d : 0x41; | 704 | reg10_max = 0x4d; |
705 | i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */ | ||
706 | } else | ||
707 | reg10_max = 0x41; | ||
715 | 708 | ||
716 | reg11 = (60 * sd->exposure + 999) / 1000; | 709 | reg11 = (60 * sd->exposure + 999) / 1000; |
717 | if (reg11 < 1) | 710 | if (reg11 < 1) |
@@ -732,20 +725,23 @@ static void setexposure(struct gspca_dev *gspca_dev) | |||
732 | else if (reg10 > reg10_max) | 725 | else if (reg10 > reg10_max) |
733 | reg10 = reg10_max; | 726 | reg10 = reg10_max; |
734 | 727 | ||
728 | /* In 640x480, if the reg11 has less than 3, the image is | ||
729 | unstable (not enough bandwidth). */ | ||
730 | if (gspca_dev->width == 640 && reg11 < 3) | ||
731 | reg11 = 3; | ||
732 | |||
735 | /* Write reg 10 and reg11 low nibble */ | 733 | /* Write reg 10 and reg11 low nibble */ |
736 | i2c[1] = sd->sensor_addr; | 734 | i2c[1] = sd->sensor_addr; |
737 | i2c[3] = reg10; | 735 | i2c[3] = reg10; |
738 | i2c[4] |= reg11 - 1; | 736 | i2c[4] |= reg11 - 1; |
739 | if (sd->sensor == SENSOR_OV7630_3) { | 737 | |
740 | __u8 reg76 = reg10 & 0x03; | 738 | /* If register 11 didn't change, don't change it */ |
741 | __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00, | 739 | if (sd->reg11 == reg11 ) |
742 | 0x00, 0x00, 0x00, 0x10}; | 740 | i2c[0] = 0xa0; |
743 | reg10 >>= 2; | 741 | |
744 | i2c_reg76[3] = reg76; | 742 | if (i2c_w(gspca_dev, i2c) == 0) |
745 | if (i2c_w(gspca_dev, i2c_reg76) < 0) | 743 | sd->reg11 = reg11; |
746 | PDEBUG(D_ERR, "i2c error exposure"); | 744 | else |
747 | } | ||
748 | if (i2c_w(gspca_dev, i2c) < 0) | ||
749 | PDEBUG(D_ERR, "i2c error exposure"); | 745 | PDEBUG(D_ERR, "i2c error exposure"); |
750 | break; | 746 | break; |
751 | } | 747 | } |
@@ -758,11 +754,11 @@ static void setfreq(struct gspca_dev *gspca_dev) | |||
758 | 754 | ||
759 | switch (sd->sensor) { | 755 | switch (sd->sensor) { |
760 | case SENSOR_OV6650: | 756 | case SENSOR_OV6650: |
761 | case SENSOR_OV7630_3: { | 757 | case SENSOR_OV7630: { |
762 | /* Framerate adjust register for artificial light 50 hz flicker | 758 | /* Framerate adjust register for artificial light 50 hz flicker |
763 | compensation, identical to ov6630 0x2b register, see ov6630 | 759 | compensation, for the ov6650 this is identical to ov6630 |
764 | datasheet. | 760 | 0x2b register, see ov6630 datasheet. |
765 | 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */ | 761 | 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ |
766 | __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; | 762 | __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; |
767 | switch (sd->freq) { | 763 | switch (sd->freq) { |
768 | default: | 764 | default: |
@@ -789,7 +785,6 @@ static void setsaturation(struct gspca_dev *gspca_dev) | |||
789 | 785 | ||
790 | switch (sd->sensor) { | 786 | switch (sd->sensor) { |
791 | /* case SENSOR_OV6650: */ | 787 | /* case SENSOR_OV6650: */ |
792 | case SENSOR_OV7630_3: | ||
793 | case SENSOR_OV7630: { | 788 | case SENSOR_OV7630: { |
794 | __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}; | 789 | __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}; |
795 | i2c[1] = sd->sensor_addr; | 790 | i2c[1] = sd->sensor_addr; |
@@ -810,7 +805,6 @@ static void sethue(struct gspca_dev *gspca_dev) | |||
810 | 805 | ||
811 | switch (sd->sensor) { | 806 | switch (sd->sensor) { |
812 | /* case SENSOR_OV6650: */ | 807 | /* case SENSOR_OV6650: */ |
813 | case SENSOR_OV7630_3: | ||
814 | case SENSOR_OV7630: { | 808 | case SENSOR_OV7630: { |
815 | __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}; | 809 | __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}; |
816 | i2c[1] = sd->sensor_addr; | 810 | i2c[1] = sd->sensor_addr; |
@@ -830,7 +824,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
830 | 824 | ||
831 | switch (sd->sensor) { | 825 | switch (sd->sensor) { |
832 | /* case SENSOR_OV6650: */ | 826 | /* case SENSOR_OV6650: */ |
833 | case SENSOR_OV7630_3: | ||
834 | case SENSOR_OV7630: { | 827 | case SENSOR_OV7630: { |
835 | __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}; | 828 | __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}; |
836 | i2c[1] = sd->sensor_addr; | 829 | i2c[1] = sd->sensor_addr; |
@@ -880,8 +873,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
880 | 873 | ||
881 | sd->fr_h_sz = 12; /* default size of the frame header */ | 874 | sd->fr_h_sz = 12; /* default size of the frame header */ |
882 | sd->sd_desc.nctrls = 2; /* default nb of ctrls */ | 875 | sd->sd_desc.nctrls = 2; /* default nb of ctrls */ |
883 | sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ | ||
884 | |||
885 | product = id->idProduct; | 876 | product = id->idProduct; |
886 | /* switch (id->idVendor) { */ | 877 | /* switch (id->idVendor) { */ |
887 | /* case 0x0c45: * Sonix */ | 878 | /* case 0x0c45: * Sonix */ |
@@ -912,17 +903,14 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
912 | case 0x6019: /* SN9C101 */ | 903 | case 0x6019: /* SN9C101 */ |
913 | case 0x602c: /* SN9C102 */ | 904 | case 0x602c: /* SN9C102 */ |
914 | case 0x602e: /* SN9C102 */ | 905 | case 0x602e: /* SN9C102 */ |
915 | sd->sensor = SENSOR_OV7630; | ||
916 | sd->sensor_addr = 0x21; | ||
917 | break; | ||
918 | case 0x60b0: /* SN9C103 */ | 906 | case 0x60b0: /* SN9C103 */ |
919 | sd->sensor = SENSOR_OV7630_3; | 907 | sd->sensor = SENSOR_OV7630; |
920 | sd->sensor_addr = 0x21; | 908 | sd->sensor_addr = 0x21; |
921 | sd->fr_h_sz = 18; /* size of frame header */ | ||
922 | sd->sensor_has_gain = 1; | 909 | sd->sensor_has_gain = 1; |
923 | sd->sd_desc.nctrls = 8; | 910 | sd->sd_desc.nctrls = 5; |
924 | sd->sd_desc.dq_callback = do_autogain; | 911 | sd->sd_desc.dq_callback = do_autogain; |
925 | sd->autogain = 0; | 912 | if (product == 0x60b0) |
913 | sd->fr_h_sz = 18; /* size of frame header */ | ||
926 | break; | 914 | break; |
927 | case 0x6024: /* SN9C102 */ | 915 | case 0x6024: /* SN9C102 */ |
928 | case 0x6025: /* SN9C102 */ | 916 | case 0x6025: /* SN9C102 */ |
@@ -948,7 +936,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
948 | if (!sif) { | 936 | if (!sif) { |
949 | cam->cam_mode = vga_mode; | 937 | cam->cam_mode = vga_mode; |
950 | cam->nmodes = ARRAY_SIZE(vga_mode); | 938 | cam->nmodes = ARRAY_SIZE(vga_mode); |
951 | if (sd->sensor == SENSOR_OV7630_3) { | 939 | if (product == 0x60b0) { /* SN9C103 with OV7630 */ |
952 | /* We only have 320x240 & 640x480 */ | 940 | /* We only have 320x240 & 640x480 */ |
953 | cam->cam_mode++; | 941 | cam->cam_mode++; |
954 | cam->nmodes--; | 942 | cam->nmodes--; |
@@ -960,12 +948,15 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
960 | sd->brightness = BRIGHTNESS_DEF; | 948 | sd->brightness = BRIGHTNESS_DEF; |
961 | sd->gain = GAIN_DEF; | 949 | sd->gain = GAIN_DEF; |
962 | sd->exposure = EXPOSURE_DEF; | 950 | sd->exposure = EXPOSURE_DEF; |
951 | sd->autogain = AUTOGAIN_DEF; | ||
963 | sd->freq = FREQ_DEF; | 952 | sd->freq = FREQ_DEF; |
964 | sd->contrast = CONTRAST_DEF; | 953 | sd->contrast = CONTRAST_DEF; |
965 | sd->saturation = SATURATION_DEF; | 954 | sd->saturation = SATURATION_DEF; |
966 | sd->hue = HUE_DEF; | 955 | sd->hue = HUE_DEF; |
967 | if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ | 956 | |
957 | if (product == 0x60b0) /* SN9C103 with OV7630 */ | ||
968 | reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); | 958 | reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); |
959 | |||
969 | return 0; | 960 | return 0; |
970 | } | 961 | } |
971 | 962 | ||
@@ -999,7 +990,7 @@ static void pas106_i2cinit(struct gspca_dev *gspca_dev) | |||
999 | static void sd_start(struct gspca_dev *gspca_dev) | 990 | static void sd_start(struct gspca_dev *gspca_dev) |
1000 | { | 991 | { |
1001 | struct sd *sd = (struct sd *) gspca_dev; | 992 | struct sd *sd = (struct sd *) gspca_dev; |
1002 | int mode, l; | 993 | int mode, l = 0x1f; |
1003 | const __u8 *sn9c10x; | 994 | const __u8 *sn9c10x; |
1004 | __u8 reg01, reg17; | 995 | __u8 reg01, reg17; |
1005 | __u8 reg17_19[3]; | 996 | __u8 reg17_19[3]; |
@@ -1019,13 +1010,11 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1019 | reg17_19[2] = 0x20; | 1010 | reg17_19[2] = 0x20; |
1020 | break; | 1011 | break; |
1021 | case SENSOR_OV7630: | 1012 | case SENSOR_OV7630: |
1022 | sn9c10x = initOv7630; | 1013 | if (sd->fr_h_sz == 18) { /* SN9C103 */ |
1023 | reg17_19[0] = 0x68; | 1014 | sn9c10x = initOv7630_3; |
1024 | reg17_19[1] = (mode << 4) | COMP2; | 1015 | l = sizeof initOv7630_3; |
1025 | reg17_19[2] = MCK_INIT1; | 1016 | } else |
1026 | break; | 1017 | sn9c10x = initOv7630; |
1027 | case SENSOR_OV7630_3: | ||
1028 | sn9c10x = initOv7630_3; | ||
1029 | reg17_19[0] = 0x68; | 1018 | reg17_19[0] = 0x68; |
1030 | reg17_19[1] = (mode << 4) | COMP2; | 1019 | reg17_19[1] = (mode << 4) | COMP2; |
1031 | reg17_19[2] = MCK_INIT1; | 1020 | reg17_19[2] = MCK_INIT1; |
@@ -1056,30 +1045,22 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1056 | reg17_19[2] = mode ? 0x23 : 0x43; | 1045 | reg17_19[2] = mode ? 0x23 : 0x43; |
1057 | break; | 1046 | break; |
1058 | } | 1047 | } |
1059 | switch (sd->sensor) { | 1048 | |
1060 | case SENSOR_OV7630: | 1049 | /* Special case for SN9C101/2 with OV 7630 */ |
1050 | /* HDG: is this really necessary we overwrite the values immediately | ||
1051 | afterwards with the ones from the template ?? */ | ||
1052 | if (sd->sensor == SENSOR_OV7630 && sd->fr_h_sz == 12) { | ||
1061 | reg01 = 0x06; | 1053 | reg01 = 0x06; |
1062 | reg17 = 0x29; | 1054 | reg17 = 0x29; |
1063 | l = sizeof initOv7630; | 1055 | } else { |
1064 | break; | ||
1065 | case SENSOR_OV7630_3: | ||
1066 | reg01 = 0x44; | ||
1067 | reg17 = 0x68; | ||
1068 | l = sizeof initOv7630_3; | ||
1069 | break; | ||
1070 | default: | ||
1071 | reg01 = sn9c10x[0]; | 1056 | reg01 = sn9c10x[0]; |
1072 | reg17 = sn9c10x[0x17 - 1]; | 1057 | reg17 = sn9c10x[0x17 - 1]; |
1073 | l = 0x1f; | ||
1074 | break; | ||
1075 | } | 1058 | } |
1076 | 1059 | ||
1077 | /* reg 0x01 bit 2 video transfert on */ | 1060 | /* reg 0x01 bit 2 video transfert on */ |
1078 | reg_w(gspca_dev, 0x01, ®01, 1); | 1061 | reg_w(gspca_dev, 0x01, ®01, 1); |
1079 | /* reg 0x17 SensorClk enable inv Clk 0x60 */ | 1062 | /* reg 0x17 SensorClk enable inv Clk 0x60 */ |
1080 | reg_w(gspca_dev, 0x17, ®17, 1); | 1063 | reg_w(gspca_dev, 0x17, ®17, 1); |
1081 | /*fixme: for ov7630 102 | ||
1082 | reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */ | ||
1083 | /* Set the registers from the template */ | 1064 | /* Set the registers from the template */ |
1084 | reg_w_big(gspca_dev, 0x01, sn9c10x, l); | 1065 | reg_w_big(gspca_dev, 0x01, sn9c10x, l); |
1085 | switch (sd->sensor) { | 1066 | switch (sd->sensor) { |
@@ -1092,17 +1073,13 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1092 | sizeof ov6650_sensor_init); | 1073 | sizeof ov6650_sensor_init); |
1093 | break; | 1074 | break; |
1094 | case SENSOR_OV7630: | 1075 | case SENSOR_OV7630: |
1095 | i2c_w_vector(gspca_dev, ov7630_sensor_init_com, | ||
1096 | sizeof ov7630_sensor_init_com); | ||
1097 | msleep(200); | ||
1098 | i2c_w_vector(gspca_dev, ov7630_sensor_init, | 1076 | i2c_w_vector(gspca_dev, ov7630_sensor_init, |
1099 | sizeof ov7630_sensor_init); | 1077 | sizeof ov7630_sensor_init); |
1100 | break; | 1078 | if (sd->fr_h_sz == 18) { /* SN9C103 */ |
1101 | case SENSOR_OV7630_3: | 1079 | const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00, |
1102 | i2c_w_vector(gspca_dev, ov7630_sensor_init_com, | 1080 | 0x00, 0x00, 0x10 }; |
1103 | sizeof ov7630_sensor_init_com); | 1081 | i2c_w(gspca_dev, i2c); |
1104 | msleep(200); | 1082 | } |
1105 | i2c_w(gspca_dev, ov7630_sensor_init_3[mode]); | ||
1106 | break; | 1083 | break; |
1107 | case SENSOR_PAS106: | 1084 | case SENSOR_PAS106: |
1108 | pas106_i2cinit(gspca_dev); | 1085 | pas106_i2cinit(gspca_dev); |
@@ -1142,6 +1119,8 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1142 | reg_w(gspca_dev, 0x18, ®17_19[1], 2); | 1119 | reg_w(gspca_dev, 0x18, ®17_19[1], 2); |
1143 | msleep(20); | 1120 | msleep(20); |
1144 | 1121 | ||
1122 | sd->reg11 = -1; | ||
1123 | |||
1145 | setgain(gspca_dev); | 1124 | setgain(gspca_dev); |
1146 | setbrightness(gspca_dev); | 1125 | setbrightness(gspca_dev); |
1147 | setexposure(gspca_dev); | 1126 | setexposure(gspca_dev); |
@@ -1150,6 +1129,7 @@ static void sd_start(struct gspca_dev *gspca_dev) | |||
1150 | sethue(gspca_dev); | 1129 | sethue(gspca_dev); |
1151 | setcontrast(gspca_dev); | 1130 | setcontrast(gspca_dev); |
1152 | 1131 | ||
1132 | sd->frames_to_drop = 0; | ||
1153 | sd->autogain_ignore_frames = 0; | 1133 | sd->autogain_ignore_frames = 0; |
1154 | atomic_set(&sd->avg_lum, -1); | 1134 | atomic_set(&sd->avg_lum, -1); |
1155 | } | 1135 | } |
@@ -1195,21 +1175,31 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
1195 | && data[3 + i] == 0xc4 | 1175 | && data[3 + i] == 0xc4 |
1196 | && data[4 + i] == 0xc4 | 1176 | && data[4 + i] == 0xc4 |
1197 | && data[5 + i] == 0x96) { /* start of frame */ | 1177 | && data[5 + i] == 0x96) { /* start of frame */ |
1198 | frame = gspca_frame_add(gspca_dev, LAST_PACKET, | 1178 | int lum = -1; |
1199 | frame, data, 0); | 1179 | int pkt_type = LAST_PACKET; |
1180 | |||
1200 | if (len - i < sd->fr_h_sz) { | 1181 | if (len - i < sd->fr_h_sz) { |
1201 | atomic_set(&sd->avg_lum, -1); | ||
1202 | PDEBUG(D_STREAM, "packet too short to" | 1182 | PDEBUG(D_STREAM, "packet too short to" |
1203 | " get avg brightness"); | 1183 | " get avg brightness"); |
1204 | } else if (sd->fr_h_sz == 12) { | 1184 | } else if (sd->fr_h_sz == 12) { |
1205 | atomic_set(&sd->avg_lum, | 1185 | lum = data[i + 8] + (data[i + 9] << 8); |
1206 | data[i + 8] + | ||
1207 | (data[i + 9] << 8)); | ||
1208 | } else { | 1186 | } else { |
1209 | atomic_set(&sd->avg_lum, | 1187 | lum = data[i + 9] + |
1210 | data[i + 9] + | 1188 | (data[i + 10] << 8); |
1211 | (data[i + 10] << 8)); | ||
1212 | } | 1189 | } |
1190 | if (lum == 0) { | ||
1191 | lum = -1; | ||
1192 | sd->frames_to_drop = 2; | ||
1193 | } | ||
1194 | atomic_set(&sd->avg_lum, lum); | ||
1195 | |||
1196 | if (sd->frames_to_drop) { | ||
1197 | sd->frames_to_drop--; | ||
1198 | pkt_type = DISCARD_PACKET; | ||
1199 | } | ||
1200 | |||
1201 | frame = gspca_frame_add(gspca_dev, pkt_type, | ||
1202 | frame, data, 0); | ||
1213 | data += i + sd->fr_h_sz; | 1203 | data += i + sd->fr_h_sz; |
1214 | len -= i + sd->fr_h_sz; | 1204 | len -= i + sd->fr_h_sz; |
1215 | gspca_frame_add(gspca_dev, FIRST_PACKET, | 1205 | gspca_frame_add(gspca_dev, FIRST_PACKET, |