diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2008-08-01 05:37:51 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-08-06 05:57:23 -0400 |
commit | 594f5b8b3cce6d3137ebf260b7386520b2534385 (patch) | |
tree | 859d7376a082fb0ebfa43bf8b4e11d4cd131a9ef /drivers/media | |
parent | a674a3b492d8085fd02ee49ed11cb42c63f0f71a (diff) |
V4L/DVB (8602): gspca: Fix small bugs, simplify and cleanup ov519.
The hflip and vflip controls work for ov519 - ov7670 only.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/gspca/ov519.c | 394 |
1 files changed, 143 insertions, 251 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index b825941089b4..b4f00ec0885c 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -40,8 +40,7 @@ struct sd { | |||
40 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 40 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
41 | 41 | ||
42 | /* Determined by sensor type */ | 42 | /* Determined by sensor type */ |
43 | short maxwidth; | 43 | char sif; |
44 | short maxheight; | ||
45 | 44 | ||
46 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ | 45 | unsigned char primary_i2c_slave; /* I2C write id of sensor */ |
47 | 46 | ||
@@ -85,7 +84,6 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); | |||
85 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); | 84 | static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); |
86 | 85 | ||
87 | static struct ctrl sd_ctrls[] = { | 86 | static struct ctrl sd_ctrls[] = { |
88 | #define SD_BRIGHTNESS 0 | ||
89 | { | 87 | { |
90 | { | 88 | { |
91 | .id = V4L2_CID_BRIGHTNESS, | 89 | .id = V4L2_CID_BRIGHTNESS, |
@@ -94,12 +92,12 @@ static struct ctrl sd_ctrls[] = { | |||
94 | .minimum = 0, | 92 | .minimum = 0, |
95 | .maximum = 255, | 93 | .maximum = 255, |
96 | .step = 1, | 94 | .step = 1, |
97 | .default_value = 127, | 95 | #define BRIGHTNESS_DEF 127 |
96 | .default_value = BRIGHTNESS_DEF, | ||
98 | }, | 97 | }, |
99 | .set = sd_setbrightness, | 98 | .set = sd_setbrightness, |
100 | .get = sd_getbrightness, | 99 | .get = sd_getbrightness, |
101 | }, | 100 | }, |
102 | #define SD_CONTRAST 1 | ||
103 | { | 101 | { |
104 | { | 102 | { |
105 | .id = V4L2_CID_CONTRAST, | 103 | .id = V4L2_CID_CONTRAST, |
@@ -108,21 +106,22 @@ static struct ctrl sd_ctrls[] = { | |||
108 | .minimum = 0, | 106 | .minimum = 0, |
109 | .maximum = 255, | 107 | .maximum = 255, |
110 | .step = 1, | 108 | .step = 1, |
111 | .default_value = 127, | 109 | #define CONTRAST_DEF 127 |
110 | .default_value = CONTRAST_DEF, | ||
112 | }, | 111 | }, |
113 | .set = sd_setcontrast, | 112 | .set = sd_setcontrast, |
114 | .get = sd_getcontrast, | 113 | .get = sd_getcontrast, |
115 | }, | 114 | }, |
116 | #define SD_COLOR 2 | ||
117 | { | 115 | { |
118 | { | 116 | { |
119 | .id = V4L2_CID_SATURATION, | 117 | .id = V4L2_CID_SATURATION, |
120 | .type = V4L2_CTRL_TYPE_INTEGER, | 118 | .type = V4L2_CTRL_TYPE_INTEGER, |
121 | .name = "Saturation", | 119 | .name = "Color", |
122 | .minimum = 0, | 120 | .minimum = 0, |
123 | .maximum = 255, | 121 | .maximum = 255, |
124 | .step = 1, | 122 | .step = 1, |
125 | .default_value = 127, | 123 | #define COLOR_DEF 127 |
124 | .default_value = COLOR_DEF, | ||
126 | }, | 125 | }, |
127 | .set = sd_setcolors, | 126 | .set = sd_setcolors, |
128 | .get = sd_getcolors, | 127 | .get = sd_getcolors, |
@@ -161,7 +160,7 @@ static struct ctrl sd_ctrls[] = { | |||
161 | static struct v4l2_pix_format vga_mode[] = { | 160 | static struct v4l2_pix_format vga_mode[] = { |
162 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 161 | {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
163 | .bytesperline = 320, | 162 | .bytesperline = 320, |
164 | .sizeimage = 320 * 240 * 3 / 8 + 589, | 163 | .sizeimage = 320 * 240 * 3 / 8 + 590, |
165 | .colorspace = V4L2_COLORSPACE_JPEG, | 164 | .colorspace = V4L2_COLORSPACE_JPEG, |
166 | .priv = 1}, | 165 | .priv = 1}, |
167 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 166 | {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
@@ -173,12 +172,12 @@ static struct v4l2_pix_format vga_mode[] = { | |||
173 | static struct v4l2_pix_format sif_mode[] = { | 172 | static struct v4l2_pix_format sif_mode[] = { |
174 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 173 | {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
175 | .bytesperline = 176, | 174 | .bytesperline = 176, |
176 | .sizeimage = 176 * 144 * 3 / 8 + 589, | 175 | .sizeimage = 176 * 144 * 3 / 8 + 590, |
177 | .colorspace = V4L2_COLORSPACE_JPEG, | 176 | .colorspace = V4L2_COLORSPACE_JPEG, |
178 | .priv = 1}, | 177 | .priv = 1}, |
179 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, | 178 | {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, |
180 | .bytesperline = 352, | 179 | .bytesperline = 352, |
181 | .sizeimage = 352 * 288 * 3 / 8 + 589, | 180 | .sizeimage = 352 * 288 * 3 / 8 + 590, |
182 | .colorspace = V4L2_COLORSPACE_JPEG, | 181 | .colorspace = V4L2_COLORSPACE_JPEG, |
183 | .priv = 0}, | 182 | .priv = 0}, |
184 | }; | 183 | }; |
@@ -294,16 +293,6 @@ static struct v4l2_pix_format sif_mode[] = { | |||
294 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ | 293 | #define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ |
295 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ | 294 | #define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ |
296 | 295 | ||
297 | struct ovsensor_window { | ||
298 | short x; | ||
299 | short y; | ||
300 | short width; | ||
301 | short height; | ||
302 | /* int format; */ | ||
303 | short quarter; /* Scale width and height down 2x */ | ||
304 | short clockdiv; /* Clock divisor setting */ | ||
305 | }; | ||
306 | |||
307 | static unsigned char ov7670_abs_to_sm(unsigned char v) | 296 | static unsigned char ov7670_abs_to_sm(unsigned char v) |
308 | { | 297 | { |
309 | if (v > 127) | 298 | if (v > 127) |
@@ -535,19 +524,6 @@ static int init_ov_sensor(struct sd *sd) | |||
535 | return 0; | 524 | return 0; |
536 | } | 525 | } |
537 | 526 | ||
538 | /* Switch on standard JPEG compression. Returns 0 for success. */ | ||
539 | static int ov519_init_compression(struct sd *sd) | ||
540 | { | ||
541 | if (!sd->compress_inited) { | ||
542 | if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) { | ||
543 | PDEBUG(D_ERR, "Error switching to compressed mode"); | ||
544 | return -EIO; | ||
545 | } | ||
546 | sd->compress_inited = 1; | ||
547 | } | ||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | /* Set the read and write slave IDs. The "slave" argument is the write slave, | 527 | /* Set the read and write slave IDs. The "slave" argument is the write slave, |
552 | * and the read slave will be set to (slave + 1). | 528 | * and the read slave will be set to (slave + 1). |
553 | * This should not be called from outside the i2c I/O functions. | 529 | * This should not be called from outside the i2c I/O functions. |
@@ -717,21 +693,17 @@ static int ov8xx0_configure(struct sd *sd) | |||
717 | return -1; | 693 | return -1; |
718 | } | 694 | } |
719 | if ((rc & 3) == 1) { | 695 | if ((rc & 3) == 1) { |
720 | PDEBUG(D_PROBE, "Sensor is an OV8610"); | ||
721 | sd->sensor = SEN_OV8610; | 696 | sd->sensor = SEN_OV8610; |
722 | } else { | 697 | } else { |
723 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); | 698 | PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); |
724 | return -1; | 699 | return -1; |
725 | } | 700 | } |
726 | PDEBUG(D_PROBE, "Writing 8610 registers"); | 701 | PDEBUG(D_PROBE, "Writing 8610 registers"); |
727 | if (write_i2c_regvals(sd, | 702 | if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610))) |
728 | norm_8610, | ||
729 | sizeof norm_8610 / sizeof norm_8610[0])) | ||
730 | return -1; | 703 | return -1; |
731 | 704 | ||
732 | /* Set sensor-specific vars */ | 705 | /* Set sensor-specific vars */ |
733 | sd->maxwidth = 640; | 706 | /* sd->sif = 0; already done */ |
734 | sd->maxheight = 480; | ||
735 | return 0; | 707 | return 0; |
736 | } | 708 | } |
737 | 709 | ||
@@ -861,7 +833,7 @@ static int ov7xx0_configure(struct sd *sd) | |||
861 | { OV7670_REG_COM7, OV7670_COM7_RESET }, | 833 | { OV7670_REG_COM7, OV7670_COM7_RESET }, |
862 | { OV7670_REG_TSLB, 0x04 }, /* OV */ | 834 | { OV7670_REG_TSLB, 0x04 }, /* OV */ |
863 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ | 835 | { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ |
864 | { OV7670_REG_CLKRC, 0x1 }, | 836 | { OV7670_REG_CLKRC, 0x01 }, |
865 | /* | 837 | /* |
866 | * Set the hardware window. These values from OV don't entirely | 838 | * Set the hardware window. These values from OV don't entirely |
867 | * make sense - hstop is less than hstart. But they work... | 839 | * make sense - hstop is less than hstart. But they work... |
@@ -875,16 +847,12 @@ static int ov7xx0_configure(struct sd *sd) | |||
875 | { 0x70, 0x3a }, { 0x71, 0x35 }, | 847 | { 0x70, 0x3a }, { 0x71, 0x35 }, |
876 | { 0x72, 0x11 }, { 0x73, 0xf0 }, | 848 | { 0x72, 0x11 }, { 0x73, 0xf0 }, |
877 | { 0xa2, 0x02 }, | 849 | { 0xa2, 0x02 }, |
878 | /* jfm */ | 850 | /* { OV7670_REG_COM10, 0x0 }, */ |
879 | /* { OV7670_REG_COM10, 0x0 }, */ | ||
880 | 851 | ||
881 | /* Gamma curve values */ | 852 | /* Gamma curve values */ |
882 | { 0x7a, 0x20 }, | 853 | { 0x7a, 0x20 }, |
883 | /* jfm:win 7b=1c */ | ||
884 | { 0x7b, 0x10 }, | 854 | { 0x7b, 0x10 }, |
885 | /* jfm:win 7c=28 */ | ||
886 | { 0x7c, 0x1e }, | 855 | { 0x7c, 0x1e }, |
887 | /* jfm:win 7d=3c */ | ||
888 | { 0x7d, 0x35 }, | 856 | { 0x7d, 0x35 }, |
889 | { 0x7e, 0x5a }, { 0x7f, 0x69 }, | 857 | { 0x7e, 0x5a }, { 0x7f, 0x69 }, |
890 | { 0x80, 0x76 }, { 0x81, 0x80 }, | 858 | { 0x80, 0x76 }, { 0x81, 0x80 }, |
@@ -900,13 +868,11 @@ static int ov7xx0_configure(struct sd *sd) | |||
900 | | OV7670_COM8_BFILT }, | 868 | | OV7670_COM8_BFILT }, |
901 | { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, | 869 | { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, |
902 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ | 870 | { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ |
903 | /* jfm:win 14=38 */ | ||
904 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ | 871 | { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ |
905 | { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, | 872 | { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, |
906 | { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, | 873 | { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, |
907 | { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, | 874 | { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, |
908 | { OV7670_REG_HAECC2, 0x68 }, | 875 | { OV7670_REG_HAECC2, 0x68 }, |
909 | /* jfm:win a1=0b */ | ||
910 | { 0xa1, 0x03 }, /* magic */ | 876 | { 0xa1, 0x03 }, /* magic */ |
911 | { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, | 877 | { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, |
912 | { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, | 878 | { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, |
@@ -920,8 +886,6 @@ static int ov7xx0_configure(struct sd *sd) | |||
920 | /* Almost all of these are magic "reserved" values. */ | 886 | /* Almost all of these are magic "reserved" values. */ |
921 | { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, | 887 | { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, |
922 | { 0x16, 0x02 }, | 888 | { 0x16, 0x02 }, |
923 | /* jfm */ | ||
924 | /* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */ | ||
925 | { OV7670_REG_MVFP, 0x07 }, | 889 | { OV7670_REG_MVFP, 0x07 }, |
926 | { 0x21, 0x02 }, { 0x22, 0x91 }, | 890 | { 0x21, 0x02 }, { 0x22, 0x91 }, |
927 | { 0x29, 0x07 }, { 0x33, 0x0b }, | 891 | { 0x29, 0x07 }, { 0x33, 0x0b }, |
@@ -995,17 +959,10 @@ static int ov7xx0_configure(struct sd *sd) | |||
995 | { 0x79, 0x03 }, { 0xc8, 0x40 }, | 959 | { 0x79, 0x03 }, { 0xc8, 0x40 }, |
996 | { 0x79, 0x05 }, { 0xc8, 0x30 }, | 960 | { 0x79, 0x05 }, { 0xc8, 0x30 }, |
997 | { 0x79, 0x26 }, | 961 | { 0x79, 0x26 }, |
998 | 962 | }; | |
999 | }; | ||
1000 | 963 | ||
1001 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); | 964 | PDEBUG(D_PROBE, "starting OV7xx0 configuration"); |
1002 | 965 | ||
1003 | /* jfm:already done? */ | ||
1004 | if (init_ov_sensor(sd) < 0) | ||
1005 | PDEBUG(D_ERR, "Failed to read sensor ID"); | ||
1006 | else | ||
1007 | PDEBUG(D_PROBE, "OV7xx0 initialized"); | ||
1008 | |||
1009 | /* Detect sensor (sub)type */ | 966 | /* Detect sensor (sub)type */ |
1010 | rc = i2c_r(sd, OV7610_REG_COM_I); | 967 | rc = i2c_r(sd, OV7610_REG_COM_I); |
1011 | 968 | ||
@@ -1051,20 +1008,25 @@ static int ov7xx0_configure(struct sd *sd) | |||
1051 | return low; | 1008 | return low; |
1052 | } | 1009 | } |
1053 | if (high == 0x76) { | 1010 | if (high == 0x76) { |
1054 | if (low == 0x30) { | 1011 | switch (low) { |
1012 | case 0x30: | ||
1055 | PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); | 1013 | PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); |
1056 | sd->sensor = SEN_OV7630; | 1014 | sd->sensor = SEN_OV7630; |
1057 | } else if (low == 0x40) { | 1015 | break; |
1016 | case 0x40: | ||
1058 | PDEBUG(D_PROBE, "Sensor is an OV7645"); | 1017 | PDEBUG(D_PROBE, "Sensor is an OV7645"); |
1059 | sd->sensor = SEN_OV7640; /* FIXME */ | 1018 | sd->sensor = SEN_OV7640; /* FIXME */ |
1060 | } else if (low == 0x45) { | 1019 | break; |
1020 | case 0x45: | ||
1061 | PDEBUG(D_PROBE, "Sensor is an OV7645B"); | 1021 | PDEBUG(D_PROBE, "Sensor is an OV7645B"); |
1062 | sd->sensor = SEN_OV7640; /* FIXME */ | 1022 | sd->sensor = SEN_OV7640; /* FIXME */ |
1063 | } else if (low == 0x48) { | 1023 | break; |
1024 | case 0x48: | ||
1064 | PDEBUG(D_PROBE, "Sensor is an OV7648"); | 1025 | PDEBUG(D_PROBE, "Sensor is an OV7648"); |
1065 | sd->sensor = SEN_OV7640; /* FIXME */ | 1026 | sd->sensor = SEN_OV7640; /* FIXME */ |
1066 | } else { | 1027 | break; |
1067 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); | 1028 | default: |
1029 | PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low); | ||
1068 | return -1; | 1030 | return -1; |
1069 | } | 1031 | } |
1070 | } else { | 1032 | } else { |
@@ -1076,34 +1038,34 @@ static int ov7xx0_configure(struct sd *sd) | |||
1076 | return -1; | 1038 | return -1; |
1077 | } | 1039 | } |
1078 | 1040 | ||
1079 | if (sd->sensor == SEN_OV7620) { | 1041 | switch (sd->sensor) { |
1042 | case SEN_OV7620: | ||
1080 | PDEBUG(D_PROBE, "Writing 7620 registers"); | 1043 | PDEBUG(D_PROBE, "Writing 7620 registers"); |
1081 | if (write_i2c_regvals(sd, norm_7620, | 1044 | if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620))) |
1082 | sizeof norm_7620 / sizeof norm_7620[0])) | ||
1083 | return -1; | 1045 | return -1; |
1084 | } else if (sd->sensor == SEN_OV7630) { | 1046 | break; |
1047 | case SEN_OV7630: | ||
1085 | PDEBUG(D_ERR, "7630 is not supported by this driver version"); | 1048 | PDEBUG(D_ERR, "7630 is not supported by this driver version"); |
1086 | return -1; | 1049 | return -1; |
1087 | } else if (sd->sensor == SEN_OV7640) { | 1050 | case SEN_OV7640: |
1088 | PDEBUG(D_PROBE, "Writing 7640 registers"); | 1051 | PDEBUG(D_PROBE, "Writing 7640 registers"); |
1089 | if (write_i2c_regvals(sd, norm_7640, | 1052 | if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640))) |
1090 | sizeof norm_7640 / sizeof norm_7640[0])) | ||
1091 | return -1; | 1053 | return -1; |
1092 | } else if (sd->sensor == SEN_OV7670) { | 1054 | break; |
1055 | case SEN_OV7670: | ||
1093 | PDEBUG(D_PROBE, "Writing 7670 registers"); | 1056 | PDEBUG(D_PROBE, "Writing 7670 registers"); |
1094 | if (write_i2c_regvals(sd, norm_7670, | 1057 | if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670))) |
1095 | sizeof norm_7670 / sizeof norm_7670[0])) | ||
1096 | return -1; | 1058 | return -1; |
1097 | } else { | 1059 | break; |
1060 | default: | ||
1098 | PDEBUG(D_PROBE, "Writing 7610 registers"); | 1061 | PDEBUG(D_PROBE, "Writing 7610 registers"); |
1099 | if (write_i2c_regvals(sd, norm_7610, | 1062 | if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610))) |
1100 | sizeof norm_7610 / sizeof norm_7610[0])) | ||
1101 | return -1; | 1063 | return -1; |
1064 | break; | ||
1102 | } | 1065 | } |
1103 | 1066 | ||
1104 | /* Set sensor-specific vars */ | 1067 | /* Set sensor-specific vars */ |
1105 | sd->maxwidth = 640; | 1068 | /* sd->sif = 0; already done */ |
1106 | sd->maxheight = 480; | ||
1107 | return 0; | 1069 | return 0; |
1108 | } | 1070 | } |
1109 | 1071 | ||
@@ -1257,43 +1219,45 @@ static int ov6xx0_configure(struct sd *sd) | |||
1257 | /* Ugh. The first two bits are the version bits, but | 1219 | /* Ugh. The first two bits are the version bits, but |
1258 | * the entire register value must be used. I guess OVT | 1220 | * the entire register value must be used. I guess OVT |
1259 | * underestimated how many variants they would make. */ | 1221 | * underestimated how many variants they would make. */ |
1260 | if (rc == 0x00) { | 1222 | switch (rc) { |
1223 | case 0x00: | ||
1261 | sd->sensor = SEN_OV6630; | 1224 | sd->sensor = SEN_OV6630; |
1262 | PDEBUG(D_ERR, | 1225 | PDEBUG(D_ERR, |
1263 | "WARNING: Sensor is an OV66308. Your camera may have"); | 1226 | "WARNING: Sensor is an OV66308. Your camera may have"); |
1264 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | 1227 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); |
1265 | } else if (rc == 0x01) { | 1228 | break; |
1229 | case 0x01: | ||
1266 | sd->sensor = SEN_OV6620; | 1230 | sd->sensor = SEN_OV6620; |
1267 | PDEBUG(D_PROBE, "Sensor is an OV6620"); | 1231 | break; |
1268 | } else if (rc == 0x02) { | 1232 | case 0x02: |
1269 | sd->sensor = SEN_OV6630; | 1233 | sd->sensor = SEN_OV6630; |
1270 | PDEBUG(D_PROBE, "Sensor is an OV66308AE"); | 1234 | PDEBUG(D_PROBE, "Sensor is an OV66308AE"); |
1271 | } else if (rc == 0x03) { | 1235 | break; |
1236 | case 0x03: | ||
1272 | sd->sensor = SEN_OV6630; | 1237 | sd->sensor = SEN_OV6630; |
1273 | PDEBUG(D_PROBE, "Sensor is an OV66308AF"); | 1238 | PDEBUG(D_PROBE, "Sensor is an OV66308AF"); |
1274 | } else if (rc == 0x90) { | 1239 | break; |
1240 | case 0x90: | ||
1275 | sd->sensor = SEN_OV6630; | 1241 | sd->sensor = SEN_OV6630; |
1276 | PDEBUG(D_ERR, | 1242 | PDEBUG(D_ERR, |
1277 | "WARNING: Sensor is an OV66307. Your camera may have"); | 1243 | "WARNING: Sensor is an OV66307. Your camera may have"); |
1278 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); | 1244 | PDEBUG(D_ERR, "been misdetected in previous driver versions."); |
1279 | } else { | 1245 | break; |
1246 | default: | ||
1280 | PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); | 1247 | PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); |
1281 | return -1; | 1248 | return -1; |
1282 | } | 1249 | } |
1283 | 1250 | ||
1284 | /* Set sensor-specific vars */ | 1251 | /* Set sensor-specific vars */ |
1285 | sd->maxwidth = 352; | 1252 | sd->sif = 1; |
1286 | sd->maxheight = 288; | ||
1287 | 1253 | ||
1288 | if (sd->sensor == SEN_OV6620) { | 1254 | if (sd->sensor == SEN_OV6620) { |
1289 | PDEBUG(D_PROBE, "Writing 6x20 registers"); | 1255 | PDEBUG(D_PROBE, "Writing 6x20 registers"); |
1290 | if (write_i2c_regvals(sd, norm_6x20, | 1256 | if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20))) |
1291 | sizeof norm_6x20 / sizeof norm_6x20[0])) | ||
1292 | return -1; | 1257 | return -1; |
1293 | } else { | 1258 | } else { |
1294 | PDEBUG(D_PROBE, "Writing 6x30 registers"); | 1259 | PDEBUG(D_PROBE, "Writing 6x30 registers"); |
1295 | if (write_i2c_regvals(sd, norm_6x30, | 1260 | if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30))) |
1296 | sizeof norm_6x30 / sizeof norm_6x30[0])) | ||
1297 | return -1; | 1261 | return -1; |
1298 | } | 1262 | } |
1299 | return 0; | 1263 | return 0; |
@@ -1302,14 +1266,8 @@ static int ov6xx0_configure(struct sd *sd) | |||
1302 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ | 1266 | /* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ |
1303 | static void ov51x_led_control(struct sd *sd, int on) | 1267 | static void ov51x_led_control(struct sd *sd, int on) |
1304 | { | 1268 | { |
1305 | PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); | 1269 | /* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */ |
1306 | 1270 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | |
1307 | /* if (sd->bridge == BRG_OV511PLUS) */ | ||
1308 | /* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */ | ||
1309 | /* else if (sd->bridge == BRG_OV519) */ | ||
1310 | reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ | ||
1311 | /* else if (sd->bclass == BCL_OV518) */ | ||
1312 | /* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */ | ||
1313 | } | 1271 | } |
1314 | 1272 | ||
1315 | /* this function is called at probe time */ | 1273 | /* this function is called at probe time */ |
@@ -1319,11 +1277,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1319 | struct sd *sd = (struct sd *) gspca_dev; | 1277 | struct sd *sd = (struct sd *) gspca_dev; |
1320 | struct cam *cam; | 1278 | struct cam *cam; |
1321 | 1279 | ||
1322 | /* (from ov519_configure) */ | ||
1323 | static const struct ov_regvals init_519[] = { | 1280 | static const struct ov_regvals init_519[] = { |
1324 | { 0x5a, 0x6d }, /* EnableSystem */ | 1281 | { 0x5a, 0x6d }, /* EnableSystem */ |
1325 | /* jfm trace usbsnoop3-1.txt */ | ||
1326 | /* jfm 53 = fb */ | ||
1327 | { 0x53, 0x9b }, | 1282 | { 0x53, 0x9b }, |
1328 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ | 1283 | { 0x54, 0xff }, /* set bit2 to enable jpeg */ |
1329 | { 0x5d, 0x03 }, | 1284 | { 0x5d, 0x03 }, |
@@ -1340,9 +1295,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1340 | 1295 | ||
1341 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) | 1296 | if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) |
1342 | goto error; | 1297 | goto error; |
1343 | /* jfm: not seen in windows trace */ | ||
1344 | if (ov519_init_compression(sd)) | ||
1345 | goto error; | ||
1346 | ov51x_led_control(sd, 0); /* turn LED off */ | 1298 | ov51x_led_control(sd, 0); /* turn LED off */ |
1347 | 1299 | ||
1348 | /* Test for 76xx */ | 1300 | /* Test for 76xx */ |
@@ -1391,16 +1343,16 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1391 | 1343 | ||
1392 | cam = &gspca_dev->cam; | 1344 | cam = &gspca_dev->cam; |
1393 | cam->epaddr = OV511_ENDPOINT_ADDRESS; | 1345 | cam->epaddr = OV511_ENDPOINT_ADDRESS; |
1394 | if (sd->maxwidth == 640) { | 1346 | if (!sd->sif) { |
1395 | cam->cam_mode = vga_mode; | 1347 | cam->cam_mode = vga_mode; |
1396 | cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; | 1348 | cam->nmodes = ARRAY_SIZE(vga_mode); |
1397 | } else { | 1349 | } else { |
1398 | cam->cam_mode = sif_mode; | 1350 | cam->cam_mode = sif_mode; |
1399 | cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; | 1351 | cam->nmodes = ARRAY_SIZE(sif_mode); |
1400 | } | 1352 | } |
1401 | sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; | 1353 | sd->brightness = BRIGHTNESS_DEF; |
1402 | sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; | 1354 | sd->contrast = CONTRAST_DEF; |
1403 | sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; | 1355 | sd->colors = COLOR_DEF; |
1404 | sd->hflip = HFLIP_DEF; | 1356 | sd->hflip = HFLIP_DEF; |
1405 | sd->vflip = VFLIP_DEF; | 1357 | sd->vflip = VFLIP_DEF; |
1406 | return 0; | 1358 | return 0; |
@@ -1422,8 +1374,7 @@ static int sd_open(struct gspca_dev *gspca_dev) | |||
1422 | * | 1374 | * |
1423 | * Do not put any sensor-specific code in here (including I2C I/O functions) | 1375 | * Do not put any sensor-specific code in here (including I2C I/O functions) |
1424 | */ | 1376 | */ |
1425 | static int ov519_mode_init_regs(struct sd *sd, | 1377 | static int ov519_mode_init_regs(struct sd *sd) |
1426 | int width, int height) | ||
1427 | { | 1378 | { |
1428 | static const struct ov_regvals mode_init_519_ov7670[] = { | 1379 | static const struct ov_regvals mode_init_519_ov7670[] = { |
1429 | { 0x5d, 0x03 }, /* Turn off suspend mode */ | 1380 | { 0x5d, 0x03 }, /* Turn off suspend mode */ |
@@ -1469,36 +1420,23 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
1469 | /* windows reads 0x55 at this point, why? */ | 1420 | /* windows reads 0x55 at this point, why? */ |
1470 | }; | 1421 | }; |
1471 | 1422 | ||
1472 | /* int hi_res; */ | ||
1473 | |||
1474 | PDEBUG(D_CONF, "mode init %dx%d", width, height); | ||
1475 | |||
1476 | /* if (width >= 800 && height >= 600) | ||
1477 | hi_res = 1; | ||
1478 | else | ||
1479 | hi_res = 0; */ | ||
1480 | |||
1481 | /* if (ov51x_stop(sd) < 0) | ||
1482 | return -EIO; */ | ||
1483 | |||
1484 | /******** Set the mode ********/ | 1423 | /******** Set the mode ********/ |
1485 | if (sd->sensor != SEN_OV7670) { | 1424 | if (sd->sensor != SEN_OV7670) { |
1486 | if (write_regvals(sd, mode_init_519, | 1425 | if (write_regvals(sd, mode_init_519, |
1487 | ARRAY_SIZE(mode_init_519))) | 1426 | ARRAY_SIZE(mode_init_519))) |
1488 | return -EIO; | 1427 | return -EIO; |
1428 | if (sd->sensor == SEN_OV7640) { | ||
1429 | /* Select 8-bit input mode */ | ||
1430 | reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); | ||
1431 | } | ||
1489 | } else { | 1432 | } else { |
1490 | if (write_regvals(sd, mode_init_519_ov7670, | 1433 | if (write_regvals(sd, mode_init_519_ov7670, |
1491 | ARRAY_SIZE(mode_init_519_ov7670))) | 1434 | ARRAY_SIZE(mode_init_519_ov7670))) |
1492 | return -EIO; | 1435 | return -EIO; |
1493 | } | 1436 | } |
1494 | 1437 | ||
1495 | if (sd->sensor == SEN_OV7640) { | 1438 | reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4); |
1496 | /* Select 8-bit input mode */ | 1439 | reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3); |
1497 | reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); | ||
1498 | } | ||
1499 | |||
1500 | reg_w(sd, OV519_CAM_H_SIZE, width >> 4); | ||
1501 | reg_w(sd, OV519_CAM_V_SIZE, height >> 3); | ||
1502 | reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); | 1440 | reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); |
1503 | reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); | 1441 | reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); |
1504 | reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); | 1442 | reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); |
@@ -1513,9 +1451,10 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
1513 | 1451 | ||
1514 | /* FIXME: These are only valid at the max resolution. */ | 1452 | /* FIXME: These are only valid at the max resolution. */ |
1515 | sd->clockdiv = 0; | 1453 | sd->clockdiv = 0; |
1516 | if (sd->sensor == SEN_OV7640) { | 1454 | switch (sd->sensor) { |
1455 | case SEN_OV7640: | ||
1517 | switch (sd->frame_rate) { | 1456 | switch (sd->frame_rate) { |
1518 | /*jfm: default was 30 fps */ | 1457 | /*fixme: default was 30 fps */ |
1519 | case 30: | 1458 | case 30: |
1520 | reg_w(sd, 0xa4, 0x0c); | 1459 | reg_w(sd, 0xa4, 0x0c); |
1521 | reg_w(sd, 0x23, 0xff); | 1460 | reg_w(sd, 0x23, 0xff); |
@@ -1545,7 +1484,8 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
1545 | sd->clockdiv = 1; | 1484 | sd->clockdiv = 1; |
1546 | break; | 1485 | break; |
1547 | } | 1486 | } |
1548 | } else if (sd->sensor == SEN_OV8610) { | 1487 | break; |
1488 | case SEN_OV8610: | ||
1549 | switch (sd->frame_rate) { | 1489 | switch (sd->frame_rate) { |
1550 | default: /* 15 fps */ | 1490 | default: /* 15 fps */ |
1551 | /* case 15: */ | 1491 | /* case 15: */ |
@@ -1561,41 +1501,37 @@ static int ov519_mode_init_regs(struct sd *sd, | |||
1561 | reg_w(sd, 0x23, 0x1b); | 1501 | reg_w(sd, 0x23, 0x1b); |
1562 | break; | 1502 | break; |
1563 | } | 1503 | } |
1564 | sd->clockdiv = 0; | 1504 | break; |
1565 | } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ | 1505 | case SEN_OV7670: /* guesses, based on 7640 */ |
1566 | PDEBUG(D_STREAM, "Setting framerate to %d fps", | 1506 | PDEBUG(D_STREAM, "Setting framerate to %d fps", |
1567 | (sd->frame_rate == 0) ? 15 : sd->frame_rate); | 1507 | (sd->frame_rate == 0) ? 15 : sd->frame_rate); |
1508 | reg_w(sd, 0xa4, 0x10); | ||
1568 | switch (sd->frame_rate) { | 1509 | switch (sd->frame_rate) { |
1569 | case 30: | 1510 | case 30: |
1570 | reg_w(sd, 0xa4, 0x10); | ||
1571 | reg_w(sd, 0x23, 0xff); | 1511 | reg_w(sd, 0x23, 0xff); |
1572 | break; | 1512 | break; |
1573 | case 20: | 1513 | case 20: |
1574 | reg_w(sd, 0xa4, 0x10); | ||
1575 | reg_w(sd, 0x23, 0x1b); | 1514 | reg_w(sd, 0x23, 0x1b); |
1576 | break; | 1515 | break; |
1577 | default: /* 15 fps */ | 1516 | default: |
1578 | /* case 15: */ | 1517 | /* case 15: */ |
1579 | reg_w(sd, 0xa4, 0x10); | ||
1580 | reg_w(sd, 0x23, 0xff); | 1518 | reg_w(sd, 0x23, 0xff); |
1581 | sd->clockdiv = 1; | 1519 | sd->clockdiv = 1; |
1582 | break; | 1520 | break; |
1583 | } | 1521 | } |
1522 | break; | ||
1584 | } | 1523 | } |
1585 | 1524 | ||
1586 | /* if (ov51x_restart(sd) < 0) | ||
1587 | return -EIO; */ | ||
1588 | |||
1589 | /* Reset it just for good measure */ | ||
1590 | /* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0) | ||
1591 | return -EIO; */ | ||
1592 | return 0; | 1525 | return 0; |
1593 | } | 1526 | } |
1594 | 1527 | ||
1595 | static int mode_init_ov_sensor_regs(struct sd *sd, | 1528 | static int mode_init_ov_sensor_regs(struct sd *sd) |
1596 | struct ovsensor_window *win) | ||
1597 | { | 1529 | { |
1598 | int qvga = win->quarter; | 1530 | struct gspca_dev *gspca_dev; |
1531 | int qvga; | ||
1532 | |||
1533 | gspca_dev = &sd->gspca_dev; | ||
1534 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
1599 | 1535 | ||
1600 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ | 1536 | /******** Mode (VGA/QVGA) and sensor specific regs ********/ |
1601 | switch (sd->sensor) { | 1537 | switch (sd->sensor) { |
@@ -1639,8 +1575,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1639 | OV7670_COM7_FMT_MASK); | 1575 | OV7670_COM7_FMT_MASK); |
1640 | break; | 1576 | break; |
1641 | case SEN_OV6620: | 1577 | case SEN_OV6620: |
1642 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | ||
1643 | break; | ||
1644 | case SEN_OV6630: | 1578 | case SEN_OV6630: |
1645 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); | 1579 | i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); |
1646 | break; | 1580 | break; |
@@ -1649,24 +1583,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1649 | } | 1583 | } |
1650 | 1584 | ||
1651 | /******** Palette-specific regs ********/ | 1585 | /******** Palette-specific regs ********/ |
1652 | /* Need to do work here for the OV7670 */ | 1586 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { |
1653 | 1587 | /* not valid on the OV6620/OV7620/6630? */ | |
1654 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | 1588 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); |
1655 | /* not valid on the OV6620/OV7620/6630? */ | 1589 | } |
1656 | i2c_w_mask(sd, 0x0e, 0x00, 0x40); | ||
1657 | } | ||
1658 | 1590 | ||
1659 | /* The OV518 needs special treatment. Although both the OV518 | 1591 | /* The OV518 needs special treatment. Although both the OV518 |
1660 | * and the OV6630 support a 16-bit video bus, only the 8 bit Y | 1592 | * and the OV6630 support a 16-bit video bus, only the 8 bit Y |
1661 | * bus is actually used. The UV bus is tied to ground. | 1593 | * bus is actually used. The UV bus is tied to ground. |
1662 | * Therefore, the OV6630 needs to be in 8-bit multiplexed | 1594 | * Therefore, the OV6630 needs to be in 8-bit multiplexed |
1663 | * output mode */ | 1595 | * output mode */ |
1664 | 1596 | ||
1665 | /* OV7640 is 8-bit only */ | 1597 | /* OV7640 is 8-bit only */ |
1666 | 1598 | ||
1667 | if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) | 1599 | if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) |
1668 | i2c_w_mask(sd, 0x13, 0x00, 0x20); | 1600 | i2c_w_mask(sd, 0x13, 0x00, 0x20); |
1669 | /* } */ | ||
1670 | 1601 | ||
1671 | /******** Clock programming ********/ | 1602 | /******** Clock programming ********/ |
1672 | /* The OV6620 needs special handling. This prevents the | 1603 | /* The OV6620 needs special handling. This prevents the |
@@ -1675,14 +1606,14 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1675 | 1606 | ||
1676 | /* Clock down */ | 1607 | /* Clock down */ |
1677 | i2c_w(sd, 0x2a, 0x04); | 1608 | i2c_w(sd, 0x2a, 0x04); |
1678 | i2c_w(sd, 0x11, win->clockdiv); | 1609 | i2c_w(sd, 0x11, sd->clockdiv); |
1679 | i2c_w(sd, 0x2a, 0x84); | 1610 | i2c_w(sd, 0x2a, 0x84); |
1680 | /* This next setting is critical. It seems to improve | 1611 | /* This next setting is critical. It seems to improve |
1681 | * the gain or the contrast. The "reserved" bits seem | 1612 | * the gain or the contrast. The "reserved" bits seem |
1682 | * to have some effect in this case. */ | 1613 | * to have some effect in this case. */ |
1683 | i2c_w(sd, 0x2d, 0x85); | 1614 | i2c_w(sd, 0x2d, 0x85); |
1684 | } else if (win->clockdiv >= 0) { | 1615 | } else if (sd->clockdiv >= 0) { |
1685 | i2c_w(sd, 0x11, win->clockdiv); | 1616 | i2c_w(sd, 0x11, sd->clockdiv); |
1686 | } | 1617 | } |
1687 | 1618 | ||
1688 | /******** Special Features ********/ | 1619 | /******** Special Features ********/ |
@@ -1702,7 +1633,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1702 | /* is fully tested. */ | 1633 | /* is fully tested. */ |
1703 | /* 7620/6620/6630? don't have register 0x35, so play it safe */ | 1634 | /* 7620/6620/6630? don't have register 0x35, so play it safe */ |
1704 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { | 1635 | if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { |
1705 | if (win->width == 640 /*&& win->height == 480*/) | 1636 | if (!qvga) |
1706 | i2c_w(sd, 0x35, 0x9e); | 1637 | i2c_w(sd, 0x35, 0x9e); |
1707 | else | 1638 | else |
1708 | i2c_w(sd, 0x35, 0x1e); | 1639 | i2c_w(sd, 0x35, 0x1e); |
@@ -1710,33 +1641,31 @@ static int mode_init_ov_sensor_regs(struct sd *sd, | |||
1710 | return 0; | 1641 | return 0; |
1711 | } | 1642 | } |
1712 | 1643 | ||
1713 | static void sethflip(struct sd *sd) | 1644 | static void sethvflip(struct sd *sd) |
1714 | { | ||
1715 | if (sd->gspca_dev.streaming) | ||
1716 | ov51x_stop(sd); | ||
1717 | i2c_w_mask(sd, OV7670_REG_MVFP, | ||
1718 | OV7670_MVFP_MIRROR * sd->hflip, OV7670_MVFP_MIRROR); | ||
1719 | if (sd->gspca_dev.streaming) | ||
1720 | ov51x_restart(sd); | ||
1721 | } | ||
1722 | |||
1723 | static void setvflip(struct sd *sd) | ||
1724 | { | 1645 | { |
1646 | if (sd->sensor != SEN_OV7670) | ||
1647 | return; | ||
1725 | if (sd->gspca_dev.streaming) | 1648 | if (sd->gspca_dev.streaming) |
1726 | ov51x_stop(sd); | 1649 | ov51x_stop(sd); |
1727 | i2c_w_mask(sd, OV7670_REG_MVFP, | 1650 | i2c_w_mask(sd, OV7670_REG_MVFP, |
1728 | OV7670_MVFP_VFLIP * sd->vflip, OV7670_MVFP_VFLIP); | 1651 | OV7670_MVFP_MIRROR * sd->hflip |
1652 | | OV7670_MVFP_VFLIP * sd->vflip, | ||
1653 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); | ||
1729 | if (sd->gspca_dev.streaming) | 1654 | if (sd->gspca_dev.streaming) |
1730 | ov51x_restart(sd); | 1655 | ov51x_restart(sd); |
1731 | } | 1656 | } |
1732 | 1657 | ||
1733 | static int set_ov_sensor_window(struct sd *sd, | 1658 | static int set_ov_sensor_window(struct sd *sd) |
1734 | struct ovsensor_window *win) | ||
1735 | { | 1659 | { |
1660 | struct gspca_dev *gspca_dev; | ||
1661 | int qvga; | ||
1736 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; | 1662 | int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; |
1737 | int ret, hstart, hstop, vstop, vstart; | 1663 | int ret, hstart, hstop, vstop, vstart; |
1738 | __u8 v; | 1664 | __u8 v; |
1739 | 1665 | ||
1666 | gspca_dev = &sd->gspca_dev; | ||
1667 | qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | ||
1668 | |||
1740 | /* The different sensor ICs handle setting up of window differently. | 1669 | /* The different sensor ICs handle setting up of window differently. |
1741 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ | 1670 | * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ |
1742 | switch (sd->sensor) { | 1671 | switch (sd->sensor) { |
@@ -1781,7 +1710,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1781 | switch (sd->sensor) { | 1710 | switch (sd->sensor) { |
1782 | case SEN_OV6620: | 1711 | case SEN_OV6620: |
1783 | case SEN_OV6630: | 1712 | case SEN_OV6630: |
1784 | if (win->quarter) { /* QCIF */ | 1713 | if (qvga) { /* QCIF */ |
1785 | hwscale = 0; | 1714 | hwscale = 0; |
1786 | vwscale = 0; | 1715 | vwscale = 0; |
1787 | } else { /* CIF */ | 1716 | } else { /* CIF */ |
@@ -1791,7 +1720,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1791 | } | 1720 | } |
1792 | break; | 1721 | break; |
1793 | case SEN_OV8610: | 1722 | case SEN_OV8610: |
1794 | if (win->quarter) { /* QSVGA */ | 1723 | if (qvga) { /* QSVGA */ |
1795 | hwscale = 1; | 1724 | hwscale = 1; |
1796 | vwscale = 1; | 1725 | vwscale = 1; |
1797 | } else { /* SVGA */ | 1726 | } else { /* SVGA */ |
@@ -1800,7 +1729,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1800 | } | 1729 | } |
1801 | break; | 1730 | break; |
1802 | default: /* SEN_OV7xx0 */ | 1731 | default: /* SEN_OV7xx0 */ |
1803 | if (win->quarter) { /* QVGA */ | 1732 | if (qvga) { /* QVGA */ |
1804 | hwscale = 1; | 1733 | hwscale = 1; |
1805 | vwscale = 0; | 1734 | vwscale = 0; |
1806 | } else { /* VGA */ | 1735 | } else { /* VGA */ |
@@ -1809,7 +1738,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1809 | } | 1738 | } |
1810 | } | 1739 | } |
1811 | 1740 | ||
1812 | ret = mode_init_ov_sensor_regs(sd, win); | 1741 | ret = mode_init_ov_sensor_regs(sd); |
1813 | if (ret < 0) | 1742 | if (ret < 0) |
1814 | return ret; | 1743 | return ret; |
1815 | 1744 | ||
@@ -1830,7 +1759,7 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1830 | /* I can hard code this for OV7670s */ | 1759 | /* I can hard code this for OV7670s */ |
1831 | /* Yes, these numbers do look odd, but they're tested and work! */ | 1760 | /* Yes, these numbers do look odd, but they're tested and work! */ |
1832 | if (sd->sensor == SEN_OV7670) { | 1761 | if (sd->sensor == SEN_OV7670) { |
1833 | if (win->quarter) { /* QVGA from ov7670.c by | 1762 | if (qvga) { /* QVGA from ov7670.c by |
1834 | * Jonathan Corbet */ | 1763 | * Jonathan Corbet */ |
1835 | hstart = 164; | 1764 | hstart = 164; |
1836 | hstop = 20; | 1765 | hstop = 20; |
@@ -1844,76 +1773,45 @@ static int set_ov_sensor_window(struct sd *sd, | |||
1844 | } | 1773 | } |
1845 | /* OV7670 hardware window registers are split across | 1774 | /* OV7670 hardware window registers are split across |
1846 | * multiple locations */ | 1775 | * multiple locations */ |
1847 | i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); | 1776 | i2c_w(sd, OV7670_REG_HSTART, hstart >> 3); |
1848 | i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); | 1777 | i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3); |
1849 | v = i2c_r(sd, OV7670_REG_HREF); | 1778 | v = i2c_r(sd, OV7670_REG_HREF); |
1850 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); | 1779 | v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); |
1851 | msleep(10); /* need to sleep between read and write to | 1780 | msleep(10); /* need to sleep between read and write to |
1852 | * same reg! */ | 1781 | * same reg! */ |
1853 | i2c_w(sd, OV7670_REG_HREF, v); | 1782 | i2c_w(sd, OV7670_REG_HREF, v); |
1854 | 1783 | ||
1855 | i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); | 1784 | i2c_w(sd, OV7670_REG_VSTART, vstart >> 2); |
1856 | i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); | 1785 | i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2); |
1857 | v = i2c_r(sd, OV7670_REG_VREF); | 1786 | v = i2c_r(sd, OV7670_REG_VREF); |
1858 | v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); | 1787 | v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); |
1859 | msleep(10); /* need to sleep between read and write to | 1788 | msleep(10); /* need to sleep between read and write to |
1860 | * same reg! */ | 1789 | * same reg! */ |
1861 | i2c_w(sd, OV7670_REG_VREF, v); | 1790 | i2c_w(sd, OV7670_REG_VREF, v); |
1862 | sethflip(sd); | 1791 | sethvflip(sd); |
1863 | setvflip(sd); | ||
1864 | } else { | 1792 | } else { |
1865 | i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); | 1793 | i2c_w(sd, 0x17, hwsbase); |
1866 | i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); | 1794 | i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale)); |
1867 | i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); | 1795 | i2c_w(sd, 0x19, vwsbase); |
1868 | i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); | 1796 | i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale)); |
1869 | } | 1797 | } |
1870 | return 0; | 1798 | return 0; |
1871 | } | 1799 | } |
1872 | 1800 | ||
1873 | static int ov_sensor_mode_setup(struct sd *sd, | ||
1874 | int width, int height) | ||
1875 | { | ||
1876 | struct ovsensor_window win; | ||
1877 | |||
1878 | /* win.format = mode; */ | ||
1879 | |||
1880 | /* Unless subcapture is enabled, | ||
1881 | * center the image window and downsample | ||
1882 | * if possible to increase the field of view */ | ||
1883 | /* NOTE: OV518(+) and OV519 does downsampling on its own */ | ||
1884 | win.width = width; | ||
1885 | win.height = height; | ||
1886 | if (width == sd->maxwidth) | ||
1887 | win.quarter = 0; | ||
1888 | else | ||
1889 | win.quarter = 1; | ||
1890 | |||
1891 | /* Center it */ | ||
1892 | win.x = (win.width - width) / 2; | ||
1893 | win.y = (win.height - height) / 2; | ||
1894 | |||
1895 | /* Clock is determined by OV519 frame rate code */ | ||
1896 | win.clockdiv = sd->clockdiv; | ||
1897 | |||
1898 | PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv); | ||
1899 | return set_ov_sensor_window(sd, &win); | ||
1900 | } | ||
1901 | |||
1902 | /* -- start the camera -- */ | 1801 | /* -- start the camera -- */ |
1903 | static void sd_start(struct gspca_dev *gspca_dev) | 1802 | static void sd_start(struct gspca_dev *gspca_dev) |
1904 | { | 1803 | { |
1905 | struct sd *sd = (struct sd *) gspca_dev; | 1804 | struct sd *sd = (struct sd *) gspca_dev; |
1906 | int ret; | 1805 | int ret; |
1907 | 1806 | ||
1908 | 1807 | ret = ov519_mode_init_regs(sd); | |
1909 | ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height); | ||
1910 | if (ret < 0) | 1808 | if (ret < 0) |
1911 | goto out; | 1809 | goto out; |
1912 | ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); | 1810 | ret = set_ov_sensor_window(sd); |
1913 | if (ret < 0) | 1811 | if (ret < 0) |
1914 | goto out; | 1812 | goto out; |
1915 | 1813 | ||
1916 | ret = ov51x_restart((struct sd *) gspca_dev); | 1814 | ret = ov51x_restart(sd); |
1917 | if (ret < 0) | 1815 | if (ret < 0) |
1918 | goto out; | 1816 | goto out; |
1919 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); | 1817 | PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); |
@@ -1987,12 +1885,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
1987 | { | 1885 | { |
1988 | struct sd *sd = (struct sd *) gspca_dev; | 1886 | struct sd *sd = (struct sd *) gspca_dev; |
1989 | int val; | 1887 | int val; |
1990 | /* int was_streaming; */ | ||
1991 | 1888 | ||
1992 | val = sd->brightness; | 1889 | val = sd->brightness; |
1993 | PDEBUG(D_CONF, "brightness:%d", val); | 1890 | PDEBUG(D_CONF, "brightness:%d", val); |
1994 | /* was_streaming = gspca_dev->streaming; | 1891 | /* if (gspca_dev->streaming) |
1995 | * if (was_streaming) | ||
1996 | * ov51x_stop(sd); */ | 1892 | * ov51x_stop(sd); */ |
1997 | switch (sd->sensor) { | 1893 | switch (sd->sensor) { |
1998 | case SEN_OV8610: | 1894 | case SEN_OV8610: |
@@ -2010,12 +1906,12 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
2010 | i2c_w(sd, OV7610_REG_BRT, val); | 1906 | i2c_w(sd, OV7610_REG_BRT, val); |
2011 | break; | 1907 | break; |
2012 | case SEN_OV7670: | 1908 | case SEN_OV7670: |
2013 | /*jfm - from windblows | 1909 | /*win trace |
2014 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ | 1910 | * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ |
2015 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); | 1911 | i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); |
2016 | break; | 1912 | break; |
2017 | } | 1913 | } |
2018 | /* if (was_streaming) | 1914 | /* if (gspca_dev->streaming) |
2019 | * ov51x_restart(sd); */ | 1915 | * ov51x_restart(sd); */ |
2020 | } | 1916 | } |
2021 | 1917 | ||
@@ -2023,12 +1919,10 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
2023 | { | 1919 | { |
2024 | struct sd *sd = (struct sd *) gspca_dev; | 1920 | struct sd *sd = (struct sd *) gspca_dev; |
2025 | int val; | 1921 | int val; |
2026 | /* int was_streaming; */ | ||
2027 | 1922 | ||
2028 | val = sd->contrast; | 1923 | val = sd->contrast; |
2029 | PDEBUG(D_CONF, "contrast:%d", val); | 1924 | PDEBUG(D_CONF, "contrast:%d", val); |
2030 | /* was_streaming = gspca_dev->streaming; | 1925 | /* if (gspca_dev->streaming) |
2031 | if (was_streaming) | ||
2032 | ov51x_stop(sd); */ | 1926 | ov51x_stop(sd); */ |
2033 | switch (sd->sensor) { | 1927 | switch (sd->sensor) { |
2034 | case SEN_OV7610: | 1928 | case SEN_OV7610: |
@@ -2065,7 +1959,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
2065 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); | 1959 | i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); |
2066 | break; | 1960 | break; |
2067 | } | 1961 | } |
2068 | /* if (was_streaming) | 1962 | /* if (gspca_dev->streaming) |
2069 | ov51x_restart(sd); */ | 1963 | ov51x_restart(sd); */ |
2070 | } | 1964 | } |
2071 | 1965 | ||
@@ -2073,12 +1967,10 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
2073 | { | 1967 | { |
2074 | struct sd *sd = (struct sd *) gspca_dev; | 1968 | struct sd *sd = (struct sd *) gspca_dev; |
2075 | int val; | 1969 | int val; |
2076 | /* int was_streaming; */ | ||
2077 | 1970 | ||
2078 | val = sd->colors; | 1971 | val = sd->colors; |
2079 | PDEBUG(D_CONF, "saturation:%d", val); | 1972 | PDEBUG(D_CONF, "saturation:%d", val); |
2080 | /* was_streaming = gspca_dev->streaming; | 1973 | /* if (gspca_dev->streaming) |
2081 | if (was_streaming) | ||
2082 | ov51x_stop(sd); */ | 1974 | ov51x_stop(sd); */ |
2083 | switch (sd->sensor) { | 1975 | switch (sd->sensor) { |
2084 | case SEN_OV8610: | 1976 | case SEN_OV8610: |
@@ -2104,7 +1996,7 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
2104 | /* set REG_COM13 values for UV sat auto mode */ | 1996 | /* set REG_COM13 values for UV sat auto mode */ |
2105 | break; | 1997 | break; |
2106 | } | 1998 | } |
2107 | /* if (was_streaming) | 1999 | /* if (gspca_dev->streaming) |
2108 | ov51x_restart(sd); */ | 2000 | ov51x_restart(sd); */ |
2109 | } | 2001 | } |
2110 | 2002 | ||
@@ -2164,7 +2056,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val) | |||
2164 | struct sd *sd = (struct sd *) gspca_dev; | 2056 | struct sd *sd = (struct sd *) gspca_dev; |
2165 | 2057 | ||
2166 | sd->hflip = val; | 2058 | sd->hflip = val; |
2167 | sethflip(sd); | 2059 | sethvflip(sd); |
2168 | return 0; | 2060 | return 0; |
2169 | } | 2061 | } |
2170 | 2062 | ||
@@ -2181,7 +2073,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) | |||
2181 | struct sd *sd = (struct sd *) gspca_dev; | 2073 | struct sd *sd = (struct sd *) gspca_dev; |
2182 | 2074 | ||
2183 | sd->vflip = val; | 2075 | sd->vflip = val; |
2184 | setvflip(sd); | 2076 | sethvflip(sd); |
2185 | return 0; | 2077 | return 0; |
2186 | } | 2078 | } |
2187 | 2079 | ||