aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/ov519.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/ov519.c')
-rw-r--r--drivers/media/video/gspca/ov519.c476
1 files changed, 225 insertions, 251 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 83139efc4629..b4f00ec0885c 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -40,14 +40,15 @@ 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
48 unsigned char brightness; 47 unsigned char brightness;
49 unsigned char contrast; 48 unsigned char contrast;
50 unsigned char colors; 49 unsigned char colors;
50 __u8 hflip;
51 __u8 vflip;
51 52
52 char compress; /* Should the next frame be compressed? */ 53 char compress; /* Should the next frame be compressed? */
53 char compress_inited; /* Are compression params uploaded? */ 54 char compress_inited; /* Are compression params uploaded? */
@@ -77,9 +78,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 78static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 79static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 80static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
80 85
81static struct ctrl sd_ctrls[] = { 86static struct ctrl sd_ctrls[] = {
82#define SD_BRIGHTNESS 0
83 { 87 {
84 { 88 {
85 .id = V4L2_CID_BRIGHTNESS, 89 .id = V4L2_CID_BRIGHTNESS,
@@ -88,12 +92,12 @@ static struct ctrl sd_ctrls[] = {
88 .minimum = 0, 92 .minimum = 0,
89 .maximum = 255, 93 .maximum = 255,
90 .step = 1, 94 .step = 1,
91 .default_value = 127, 95#define BRIGHTNESS_DEF 127
96 .default_value = BRIGHTNESS_DEF,
92 }, 97 },
93 .set = sd_setbrightness, 98 .set = sd_setbrightness,
94 .get = sd_getbrightness, 99 .get = sd_getbrightness,
95 }, 100 },
96#define SD_CONTRAST 1
97 { 101 {
98 { 102 {
99 .id = V4L2_CID_CONTRAST, 103 .id = V4L2_CID_CONTRAST,
@@ -102,31 +106,61 @@ static struct ctrl sd_ctrls[] = {
102 .minimum = 0, 106 .minimum = 0,
103 .maximum = 255, 107 .maximum = 255,
104 .step = 1, 108 .step = 1,
105 .default_value = 127, 109#define CONTRAST_DEF 127
110 .default_value = CONTRAST_DEF,
106 }, 111 },
107 .set = sd_setcontrast, 112 .set = sd_setcontrast,
108 .get = sd_getcontrast, 113 .get = sd_getcontrast,
109 }, 114 },
110#define SD_COLOR 2
111 { 115 {
112 { 116 {
113 .id = V4L2_CID_SATURATION, 117 .id = V4L2_CID_SATURATION,
114 .type = V4L2_CTRL_TYPE_INTEGER, 118 .type = V4L2_CTRL_TYPE_INTEGER,
115 .name = "Saturation", 119 .name = "Color",
116 .minimum = 0, 120 .minimum = 0,
117 .maximum = 255, 121 .maximum = 255,
118 .step = 1, 122 .step = 1,
119 .default_value = 127, 123#define COLOR_DEF 127
124 .default_value = COLOR_DEF,
120 }, 125 },
121 .set = sd_setcolors, 126 .set = sd_setcolors,
122 .get = sd_getcolors, 127 .get = sd_getcolors,
123 }, 128 },
129/* next controls work with ov7670 only */
130 {
131 {
132 .id = V4L2_CID_HFLIP,
133 .type = V4L2_CTRL_TYPE_BOOLEAN,
134 .name = "Mirror",
135 .minimum = 0,
136 .maximum = 1,
137 .step = 1,
138#define HFLIP_DEF 0
139 .default_value = HFLIP_DEF,
140 },
141 .set = sd_sethflip,
142 .get = sd_gethflip,
143 },
144 {
145 {
146 .id = V4L2_CID_VFLIP,
147 .type = V4L2_CTRL_TYPE_BOOLEAN,
148 .name = "Vflip",
149 .minimum = 0,
150 .maximum = 1,
151 .step = 1,
152#define VFLIP_DEF 0
153 .default_value = VFLIP_DEF,
154 },
155 .set = sd_setvflip,
156 .get = sd_getvflip,
157 },
124}; 158};
125 159
126static struct v4l2_pix_format vga_mode[] = { 160static struct v4l2_pix_format vga_mode[] = {
127 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 161 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
128 .bytesperline = 320, 162 .bytesperline = 320,
129 .sizeimage = 320 * 240 * 3 / 8 + 589, 163 .sizeimage = 320 * 240 * 3 / 8 + 590,
130 .colorspace = V4L2_COLORSPACE_JPEG, 164 .colorspace = V4L2_COLORSPACE_JPEG,
131 .priv = 1}, 165 .priv = 1},
132 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 166 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -138,12 +172,12 @@ static struct v4l2_pix_format vga_mode[] = {
138static struct v4l2_pix_format sif_mode[] = { 172static struct v4l2_pix_format sif_mode[] = {
139 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 173 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
140 .bytesperline = 176, 174 .bytesperline = 176,
141 .sizeimage = 176 * 144 * 3 / 8 + 589, 175 .sizeimage = 176 * 144 * 3 / 8 + 590,
142 .colorspace = V4L2_COLORSPACE_JPEG, 176 .colorspace = V4L2_COLORSPACE_JPEG,
143 .priv = 1}, 177 .priv = 1},
144 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 178 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
145 .bytesperline = 352, 179 .bytesperline = 352,
146 .sizeimage = 352 * 288 * 3 / 8 + 589, 180 .sizeimage = 352 * 288 * 3 / 8 + 590,
147 .colorspace = V4L2_COLORSPACE_JPEG, 181 .colorspace = V4L2_COLORSPACE_JPEG,
148 .priv = 0}, 182 .priv = 0},
149}; 183};
@@ -225,6 +259,7 @@ static struct v4l2_pix_format sif_mode[] = {
225#define OV7670_REG_VSTART 0x19 /* Vert start high bits */ 259#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
226#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ 260#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
227#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ 261#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
262#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
228#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ 263#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
229#define OV7670_REG_AEW 0x24 /* AGC upper limit */ 264#define OV7670_REG_AEW 0x24 /* AGC upper limit */
230#define OV7670_REG_AEB 0x25 /* AGC lower limit */ 265#define OV7670_REG_AEB 0x25 /* AGC lower limit */
@@ -258,16 +293,6 @@ static struct v4l2_pix_format sif_mode[] = {
258#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ 293#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
259#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ 294#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
260 295
261struct ovsensor_window {
262 short x;
263 short y;
264 short width;
265 short height;
266/* int format; */
267 short quarter; /* Scale width and height down 2x */
268 short clockdiv; /* Clock divisor setting */
269};
270
271static unsigned char ov7670_abs_to_sm(unsigned char v) 296static unsigned char ov7670_abs_to_sm(unsigned char v)
272{ 297{
273 if (v > 127) 298 if (v > 127)
@@ -499,19 +524,6 @@ static int init_ov_sensor(struct sd *sd)
499 return 0; 524 return 0;
500} 525}
501 526
502/* Switch on standard JPEG compression. Returns 0 for success. */
503static int ov519_init_compression(struct sd *sd)
504{
505 if (!sd->compress_inited) {
506 if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) {
507 PDEBUG(D_ERR, "Error switching to compressed mode");
508 return -EIO;
509 }
510 sd->compress_inited = 1;
511 }
512 return 0;
513}
514
515/* 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,
516 * and the read slave will be set to (slave + 1). 528 * and the read slave will be set to (slave + 1).
517 * 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.
@@ -681,21 +693,17 @@ static int ov8xx0_configure(struct sd *sd)
681 return -1; 693 return -1;
682 } 694 }
683 if ((rc & 3) == 1) { 695 if ((rc & 3) == 1) {
684 PDEBUG(D_PROBE, "Sensor is an OV8610");
685 sd->sensor = SEN_OV8610; 696 sd->sensor = SEN_OV8610;
686 } else { 697 } else {
687 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); 698 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
688 return -1; 699 return -1;
689 } 700 }
690 PDEBUG(D_PROBE, "Writing 8610 registers"); 701 PDEBUG(D_PROBE, "Writing 8610 registers");
691 if (write_i2c_regvals(sd, 702 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
692 norm_8610,
693 sizeof norm_8610 / sizeof norm_8610[0]))
694 return -1; 703 return -1;
695 704
696 /* Set sensor-specific vars */ 705 /* Set sensor-specific vars */
697 sd->maxwidth = 640; 706/* sd->sif = 0; already done */
698 sd->maxheight = 480;
699 return 0; 707 return 0;
700} 708}
701 709
@@ -825,7 +833,7 @@ static int ov7xx0_configure(struct sd *sd)
825 { OV7670_REG_COM7, OV7670_COM7_RESET }, 833 { OV7670_REG_COM7, OV7670_COM7_RESET },
826 { OV7670_REG_TSLB, 0x04 }, /* OV */ 834 { OV7670_REG_TSLB, 0x04 }, /* OV */
827 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ 835 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
828 { OV7670_REG_CLKRC, 0x1 }, 836 { OV7670_REG_CLKRC, 0x01 },
829 /* 837 /*
830 * Set the hardware window. These values from OV don't entirely 838 * Set the hardware window. These values from OV don't entirely
831 * make sense - hstop is less than hstart. But they work... 839 * make sense - hstop is less than hstart. But they work...
@@ -839,16 +847,12 @@ static int ov7xx0_configure(struct sd *sd)
839 { 0x70, 0x3a }, { 0x71, 0x35 }, 847 { 0x70, 0x3a }, { 0x71, 0x35 },
840 { 0x72, 0x11 }, { 0x73, 0xf0 }, 848 { 0x72, 0x11 }, { 0x73, 0xf0 },
841 { 0xa2, 0x02 }, 849 { 0xa2, 0x02 },
842/* jfm */ 850/* { OV7670_REG_COM10, 0x0 }, */
843/* { OV7670_REG_COM10, 0x0 }, */
844 851
845 /* Gamma curve values */ 852 /* Gamma curve values */
846 { 0x7a, 0x20 }, 853 { 0x7a, 0x20 },
847/* jfm:win 7b=1c */
848 { 0x7b, 0x10 }, 854 { 0x7b, 0x10 },
849/* jfm:win 7c=28 */
850 { 0x7c, 0x1e }, 855 { 0x7c, 0x1e },
851/* jfm:win 7d=3c */
852 { 0x7d, 0x35 }, 856 { 0x7d, 0x35 },
853 { 0x7e, 0x5a }, { 0x7f, 0x69 }, 857 { 0x7e, 0x5a }, { 0x7f, 0x69 },
854 { 0x80, 0x76 }, { 0x81, 0x80 }, 858 { 0x80, 0x76 }, { 0x81, 0x80 },
@@ -864,13 +868,11 @@ static int ov7xx0_configure(struct sd *sd)
864 | OV7670_COM8_BFILT }, 868 | OV7670_COM8_BFILT },
865 { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, 869 { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 },
866 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ 870 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
867/* jfm:win 14=38 */
868 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ 871 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
869 { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, 872 { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 },
870 { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, 873 { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 },
871 { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, 874 { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 },
872 { OV7670_REG_HAECC2, 0x68 }, 875 { OV7670_REG_HAECC2, 0x68 },
873/* jfm:win a1=0b */
874 { 0xa1, 0x03 }, /* magic */ 876 { 0xa1, 0x03 }, /* magic */
875 { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, 877 { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 },
876 { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, 878 { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 },
@@ -884,8 +886,6 @@ static int ov7xx0_configure(struct sd *sd)
884 /* Almost all of these are magic "reserved" values. */ 886 /* Almost all of these are magic "reserved" values. */
885 { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, 887 { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b },
886 { 0x16, 0x02 }, 888 { 0x16, 0x02 },
887/* jfm */
888/* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */
889 { OV7670_REG_MVFP, 0x07 }, 889 { OV7670_REG_MVFP, 0x07 },
890 { 0x21, 0x02 }, { 0x22, 0x91 }, 890 { 0x21, 0x02 }, { 0x22, 0x91 },
891 { 0x29, 0x07 }, { 0x33, 0x0b }, 891 { 0x29, 0x07 }, { 0x33, 0x0b },
@@ -930,7 +930,10 @@ static int ov7xx0_configure(struct sd *sd)
930 { OV7670_REG_EDGE, 0 }, 930 { OV7670_REG_EDGE, 0 },
931 { 0x75, 0x05 }, { 0x76, 0xe1 }, 931 { 0x75, 0x05 }, { 0x76, 0xe1 },
932 { 0x4c, 0 }, { 0x77, 0x01 }, 932 { 0x4c, 0 }, { 0x77, 0x01 },
933 { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, 933 { OV7670_REG_COM13, OV7670_COM13_GAMMA
934 | OV7670_COM13_UVSAT
935 | 2}, /* was 3 */
936 { 0x4b, 0x09 },
934 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, 937 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 },
935 { 0x56, 0x40 }, 938 { 0x56, 0x40 },
936 939
@@ -956,30 +959,10 @@ static int ov7xx0_configure(struct sd *sd)
956 { 0x79, 0x03 }, { 0xc8, 0x40 }, 959 { 0x79, 0x03 }, { 0xc8, 0x40 },
957 { 0x79, 0x05 }, { 0xc8, 0x30 }, 960 { 0x79, 0x05 }, { 0xc8, 0x30 },
958 { 0x79, 0x26 }, 961 { 0x79, 0x26 },
959 962 };
960 /* Format YUV422 */
961 { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */
962 { OV7670_REG_RGB444, 0 }, /* No RGB444 please */
963 { OV7670_REG_COM1, 0 },
964 { OV7670_REG_COM15, OV7670_COM15_R00FF },
965 { OV7670_REG_COM9, 0x18 },
966 /* 4x gain ceiling; 0x8 is reserved bit */
967 { 0x4f, 0x80 }, /* "matrix coefficient 1" */
968 { 0x50, 0x80 }, /* "matrix coefficient 2" */
969 { 0x52, 0x22 }, /* "matrix coefficient 4" */
970 { 0x53, 0x5e }, /* "matrix coefficient 5" */
971 { 0x54, 0x80 }, /* "matrix coefficient 6" */
972 { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT },
973};
974 963
975 PDEBUG(D_PROBE, "starting OV7xx0 configuration"); 964 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
976 965
977/* jfm:already done? */
978 if (init_ov_sensor(sd) < 0)
979 PDEBUG(D_ERR, "Failed to read sensor ID");
980 else
981 PDEBUG(D_PROBE, "OV7xx0 initialized");
982
983 /* Detect sensor (sub)type */ 966 /* Detect sensor (sub)type */
984 rc = i2c_r(sd, OV7610_REG_COM_I); 967 rc = i2c_r(sd, OV7610_REG_COM_I);
985 968
@@ -1025,20 +1008,25 @@ static int ov7xx0_configure(struct sd *sd)
1025 return low; 1008 return low;
1026 } 1009 }
1027 if (high == 0x76) { 1010 if (high == 0x76) {
1028 if (low == 0x30) { 1011 switch (low) {
1012 case 0x30:
1029 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); 1013 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
1030 sd->sensor = SEN_OV7630; 1014 sd->sensor = SEN_OV7630;
1031 } else if (low == 0x40) { 1015 break;
1016 case 0x40:
1032 PDEBUG(D_PROBE, "Sensor is an OV7645"); 1017 PDEBUG(D_PROBE, "Sensor is an OV7645");
1033 sd->sensor = SEN_OV7640; /* FIXME */ 1018 sd->sensor = SEN_OV7640; /* FIXME */
1034 } else if (low == 0x45) { 1019 break;
1020 case 0x45:
1035 PDEBUG(D_PROBE, "Sensor is an OV7645B"); 1021 PDEBUG(D_PROBE, "Sensor is an OV7645B");
1036 sd->sensor = SEN_OV7640; /* FIXME */ 1022 sd->sensor = SEN_OV7640; /* FIXME */
1037 } else if (low == 0x48) { 1023 break;
1024 case 0x48:
1038 PDEBUG(D_PROBE, "Sensor is an OV7648"); 1025 PDEBUG(D_PROBE, "Sensor is an OV7648");
1039 sd->sensor = SEN_OV7640; /* FIXME */ 1026 sd->sensor = SEN_OV7640; /* FIXME */
1040 } else { 1027 break;
1041 PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); 1028 default:
1029 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
1042 return -1; 1030 return -1;
1043 } 1031 }
1044 } else { 1032 } else {
@@ -1050,34 +1038,34 @@ static int ov7xx0_configure(struct sd *sd)
1050 return -1; 1038 return -1;
1051 } 1039 }
1052 1040
1053 if (sd->sensor == SEN_OV7620) { 1041 switch (sd->sensor) {
1042 case SEN_OV7620:
1054 PDEBUG(D_PROBE, "Writing 7620 registers"); 1043 PDEBUG(D_PROBE, "Writing 7620 registers");
1055 if (write_i2c_regvals(sd, norm_7620, 1044 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
1056 sizeof norm_7620 / sizeof norm_7620[0]))
1057 return -1; 1045 return -1;
1058 } else if (sd->sensor == SEN_OV7630) { 1046 break;
1047 case SEN_OV7630:
1059 PDEBUG(D_ERR, "7630 is not supported by this driver version"); 1048 PDEBUG(D_ERR, "7630 is not supported by this driver version");
1060 return -1; 1049 return -1;
1061 } else if (sd->sensor == SEN_OV7640) { 1050 case SEN_OV7640:
1062 PDEBUG(D_PROBE, "Writing 7640 registers"); 1051 PDEBUG(D_PROBE, "Writing 7640 registers");
1063 if (write_i2c_regvals(sd, norm_7640, 1052 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
1064 sizeof norm_7640 / sizeof norm_7640[0]))
1065 return -1; 1053 return -1;
1066 } else if (sd->sensor == SEN_OV7670) { 1054 break;
1055 case SEN_OV7670:
1067 PDEBUG(D_PROBE, "Writing 7670 registers"); 1056 PDEBUG(D_PROBE, "Writing 7670 registers");
1068 if (write_i2c_regvals(sd, norm_7670, 1057 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
1069 sizeof norm_7670 / sizeof norm_7670[0]))
1070 return -1; 1058 return -1;
1071 } else { 1059 break;
1060 default:
1072 PDEBUG(D_PROBE, "Writing 7610 registers"); 1061 PDEBUG(D_PROBE, "Writing 7610 registers");
1073 if (write_i2c_regvals(sd, norm_7610, 1062 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
1074 sizeof norm_7610 / sizeof norm_7610[0]))
1075 return -1; 1063 return -1;
1064 break;
1076 } 1065 }
1077 1066
1078 /* Set sensor-specific vars */ 1067 /* Set sensor-specific vars */
1079 sd->maxwidth = 640; 1068/* sd->sif = 0; already done */
1080 sd->maxheight = 480;
1081 return 0; 1069 return 0;
1082} 1070}
1083 1071
@@ -1231,43 +1219,45 @@ static int ov6xx0_configure(struct sd *sd)
1231 /* Ugh. The first two bits are the version bits, but 1219 /* Ugh. The first two bits are the version bits, but
1232 * the entire register value must be used. I guess OVT 1220 * the entire register value must be used. I guess OVT
1233 * underestimated how many variants they would make. */ 1221 * underestimated how many variants they would make. */
1234 if (rc == 0x00) { 1222 switch (rc) {
1223 case 0x00:
1235 sd->sensor = SEN_OV6630; 1224 sd->sensor = SEN_OV6630;
1236 PDEBUG(D_ERR, 1225 PDEBUG(D_ERR,
1237 "WARNING: Sensor is an OV66308. Your camera may have"); 1226 "WARNING: Sensor is an OV66308. Your camera may have");
1238 PDEBUG(D_ERR, "been misdetected in previous driver versions."); 1227 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
1239 } else if (rc == 0x01) { 1228 break;
1229 case 0x01:
1240 sd->sensor = SEN_OV6620; 1230 sd->sensor = SEN_OV6620;
1241 PDEBUG(D_PROBE, "Sensor is an OV6620"); 1231 break;
1242 } else if (rc == 0x02) { 1232 case 0x02:
1243 sd->sensor = SEN_OV6630; 1233 sd->sensor = SEN_OV6630;
1244 PDEBUG(D_PROBE, "Sensor is an OV66308AE"); 1234 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
1245 } else if (rc == 0x03) { 1235 break;
1236 case 0x03:
1246 sd->sensor = SEN_OV6630; 1237 sd->sensor = SEN_OV6630;
1247 PDEBUG(D_PROBE, "Sensor is an OV66308AF"); 1238 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
1248 } else if (rc == 0x90) { 1239 break;
1240 case 0x90:
1249 sd->sensor = SEN_OV6630; 1241 sd->sensor = SEN_OV6630;
1250 PDEBUG(D_ERR, 1242 PDEBUG(D_ERR,
1251 "WARNING: Sensor is an OV66307. Your camera may have"); 1243 "WARNING: Sensor is an OV66307. Your camera may have");
1252 PDEBUG(D_ERR, "been misdetected in previous driver versions."); 1244 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
1253 } else { 1245 break;
1246 default:
1254 PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); 1247 PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc);
1255 return -1; 1248 return -1;
1256 } 1249 }
1257 1250
1258 /* Set sensor-specific vars */ 1251 /* Set sensor-specific vars */
1259 sd->maxwidth = 352; 1252 sd->sif = 1;
1260 sd->maxheight = 288;
1261 1253
1262 if (sd->sensor == SEN_OV6620) { 1254 if (sd->sensor == SEN_OV6620) {
1263 PDEBUG(D_PROBE, "Writing 6x20 registers"); 1255 PDEBUG(D_PROBE, "Writing 6x20 registers");
1264 if (write_i2c_regvals(sd, norm_6x20, 1256 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
1265 sizeof norm_6x20 / sizeof norm_6x20[0]))
1266 return -1; 1257 return -1;
1267 } else { 1258 } else {
1268 PDEBUG(D_PROBE, "Writing 6x30 registers"); 1259 PDEBUG(D_PROBE, "Writing 6x30 registers");
1269 if (write_i2c_regvals(sd, norm_6x30, 1260 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
1270 sizeof norm_6x30 / sizeof norm_6x30[0]))
1271 return -1; 1261 return -1;
1272 } 1262 }
1273 return 0; 1263 return 0;
@@ -1276,14 +1266,8 @@ static int ov6xx0_configure(struct sd *sd)
1276/* 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 */
1277static void ov51x_led_control(struct sd *sd, int on) 1267static void ov51x_led_control(struct sd *sd, int on)
1278{ 1268{
1279 PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); 1269/* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */
1280 1270 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1281/* if (sd->bridge == BRG_OV511PLUS) */
1282/* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */
1283/* else if (sd->bridge == BRG_OV519) */
1284 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1285/* else if (sd->bclass == BCL_OV518) */
1286/* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */
1287} 1271}
1288 1272
1289/* this function is called at probe time */ 1273/* this function is called at probe time */
@@ -1293,11 +1277,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1293 struct sd *sd = (struct sd *) gspca_dev; 1277 struct sd *sd = (struct sd *) gspca_dev;
1294 struct cam *cam; 1278 struct cam *cam;
1295 1279
1296/* (from ov519_configure) */
1297 static const struct ov_regvals init_519[] = { 1280 static const struct ov_regvals init_519[] = {
1298 { 0x5a, 0x6d }, /* EnableSystem */ 1281 { 0x5a, 0x6d }, /* EnableSystem */
1299/* jfm trace usbsnoop3-1.txt */
1300/* jfm 53 = fb */
1301 { 0x53, 0x9b }, 1282 { 0x53, 0x9b },
1302 { 0x54, 0xff }, /* set bit2 to enable jpeg */ 1283 { 0x54, 0xff }, /* set bit2 to enable jpeg */
1303 { 0x5d, 0x03 }, 1284 { 0x5d, 0x03 },
@@ -1314,9 +1295,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1314 1295
1315 if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) 1296 if (write_regvals(sd, init_519, ARRAY_SIZE(init_519)))
1316 goto error; 1297 goto error;
1317/* jfm: not seen in windows trace */
1318 if (ov519_init_compression(sd))
1319 goto error;
1320 ov51x_led_control(sd, 0); /* turn LED off */ 1298 ov51x_led_control(sd, 0); /* turn LED off */
1321 1299
1322 /* Test for 76xx */ 1300 /* Test for 76xx */
@@ -1365,16 +1343,18 @@ static int sd_config(struct gspca_dev *gspca_dev,
1365 1343
1366 cam = &gspca_dev->cam; 1344 cam = &gspca_dev->cam;
1367 cam->epaddr = OV511_ENDPOINT_ADDRESS; 1345 cam->epaddr = OV511_ENDPOINT_ADDRESS;
1368 if (sd->maxwidth == 640) { 1346 if (!sd->sif) {
1369 cam->cam_mode = vga_mode; 1347 cam->cam_mode = vga_mode;
1370 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 1348 cam->nmodes = ARRAY_SIZE(vga_mode);
1371 } else { 1349 } else {
1372 cam->cam_mode = sif_mode; 1350 cam->cam_mode = sif_mode;
1373 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; 1351 cam->nmodes = ARRAY_SIZE(sif_mode);
1374 } 1352 }
1375 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 1353 sd->brightness = BRIGHTNESS_DEF;
1376 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 1354 sd->contrast = CONTRAST_DEF;
1377 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; 1355 sd->colors = COLOR_DEF;
1356 sd->hflip = HFLIP_DEF;
1357 sd->vflip = VFLIP_DEF;
1378 return 0; 1358 return 0;
1379error: 1359error:
1380 PDEBUG(D_ERR, "OV519 Config failed"); 1360 PDEBUG(D_ERR, "OV519 Config failed");
@@ -1394,8 +1374,7 @@ static int sd_open(struct gspca_dev *gspca_dev)
1394 * 1374 *
1395 * 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)
1396 */ 1376 */
1397static int ov519_mode_init_regs(struct sd *sd, 1377static int ov519_mode_init_regs(struct sd *sd)
1398 int width, int height)
1399{ 1378{
1400 static const struct ov_regvals mode_init_519_ov7670[] = { 1379 static const struct ov_regvals mode_init_519_ov7670[] = {
1401 { 0x5d, 0x03 }, /* Turn off suspend mode */ 1380 { 0x5d, 0x03 }, /* Turn off suspend mode */
@@ -1441,36 +1420,23 @@ static int ov519_mode_init_regs(struct sd *sd,
1441 /* windows reads 0x55 at this point, why? */ 1420 /* windows reads 0x55 at this point, why? */
1442 }; 1421 };
1443 1422
1444/* int hi_res; */
1445
1446 PDEBUG(D_CONF, "mode init %dx%d", width, height);
1447
1448/* if (width >= 800 && height >= 600)
1449 hi_res = 1;
1450 else
1451 hi_res = 0; */
1452
1453/* if (ov51x_stop(sd) < 0)
1454 return -EIO; */
1455
1456 /******** Set the mode ********/ 1423 /******** Set the mode ********/
1457 if (sd->sensor != SEN_OV7670) { 1424 if (sd->sensor != SEN_OV7670) {
1458 if (write_regvals(sd, mode_init_519, 1425 if (write_regvals(sd, mode_init_519,
1459 ARRAY_SIZE(mode_init_519))) 1426 ARRAY_SIZE(mode_init_519)))
1460 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 }
1461 } else { 1432 } else {
1462 if (write_regvals(sd, mode_init_519_ov7670, 1433 if (write_regvals(sd, mode_init_519_ov7670,
1463 ARRAY_SIZE(mode_init_519_ov7670))) 1434 ARRAY_SIZE(mode_init_519_ov7670)))
1464 return -EIO; 1435 return -EIO;
1465 } 1436 }
1466 1437
1467 if (sd->sensor == SEN_OV7640) { 1438 reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4);
1468 /* Select 8-bit input mode */ 1439 reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3);
1469 reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10);
1470 }
1471
1472 reg_w(sd, OV519_CAM_H_SIZE, width >> 4);
1473 reg_w(sd, OV519_CAM_V_SIZE, height >> 3);
1474 reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); 1440 reg_w(sd, OV519_CAM_X_OFFSETL, 0x00);
1475 reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); 1441 reg_w(sd, OV519_CAM_X_OFFSETH, 0x00);
1476 reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); 1442 reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00);
@@ -1485,9 +1451,10 @@ static int ov519_mode_init_regs(struct sd *sd,
1485 1451
1486/* FIXME: These are only valid at the max resolution. */ 1452/* FIXME: These are only valid at the max resolution. */
1487 sd->clockdiv = 0; 1453 sd->clockdiv = 0;
1488 if (sd->sensor == SEN_OV7640) { 1454 switch (sd->sensor) {
1455 case SEN_OV7640:
1489 switch (sd->frame_rate) { 1456 switch (sd->frame_rate) {
1490/*jfm: default was 30 fps */ 1457/*fixme: default was 30 fps */
1491 case 30: 1458 case 30:
1492 reg_w(sd, 0xa4, 0x0c); 1459 reg_w(sd, 0xa4, 0x0c);
1493 reg_w(sd, 0x23, 0xff); 1460 reg_w(sd, 0x23, 0xff);
@@ -1517,7 +1484,8 @@ static int ov519_mode_init_regs(struct sd *sd,
1517 sd->clockdiv = 1; 1484 sd->clockdiv = 1;
1518 break; 1485 break;
1519 } 1486 }
1520 } else if (sd->sensor == SEN_OV8610) { 1487 break;
1488 case SEN_OV8610:
1521 switch (sd->frame_rate) { 1489 switch (sd->frame_rate) {
1522 default: /* 15 fps */ 1490 default: /* 15 fps */
1523/* case 15: */ 1491/* case 15: */
@@ -1533,41 +1501,37 @@ static int ov519_mode_init_regs(struct sd *sd,
1533 reg_w(sd, 0x23, 0x1b); 1501 reg_w(sd, 0x23, 0x1b);
1534 break; 1502 break;
1535 } 1503 }
1536 sd->clockdiv = 0; 1504 break;
1537 } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ 1505 case SEN_OV7670: /* guesses, based on 7640 */
1538 PDEBUG(D_STREAM, "Setting framerate to %d fps", 1506 PDEBUG(D_STREAM, "Setting framerate to %d fps",
1539 (sd->frame_rate == 0) ? 15 : sd->frame_rate); 1507 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
1508 reg_w(sd, 0xa4, 0x10);
1540 switch (sd->frame_rate) { 1509 switch (sd->frame_rate) {
1541 case 30: 1510 case 30:
1542 reg_w(sd, 0xa4, 0x10);
1543 reg_w(sd, 0x23, 0xff); 1511 reg_w(sd, 0x23, 0xff);
1544 break; 1512 break;
1545 case 20: 1513 case 20:
1546 reg_w(sd, 0xa4, 0x10);
1547 reg_w(sd, 0x23, 0x1b); 1514 reg_w(sd, 0x23, 0x1b);
1548 break; 1515 break;
1549 default: /* 15 fps */ 1516 default:
1550/* case 15: */ 1517/* case 15: */
1551 reg_w(sd, 0xa4, 0x10);
1552 reg_w(sd, 0x23, 0xff); 1518 reg_w(sd, 0x23, 0xff);
1553 sd->clockdiv = 1; 1519 sd->clockdiv = 1;
1554 break; 1520 break;
1555 } 1521 }
1522 break;
1556 } 1523 }
1557 1524
1558/* if (ov51x_restart(sd) < 0)
1559 return -EIO; */
1560
1561 /* Reset it just for good measure */
1562/* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0)
1563 return -EIO; */
1564 return 0; 1525 return 0;
1565} 1526}
1566 1527
1567static int mode_init_ov_sensor_regs(struct sd *sd, 1528static int mode_init_ov_sensor_regs(struct sd *sd)
1568 struct ovsensor_window *win)
1569{ 1529{
1570 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;
1571 1535
1572 /******** Mode (VGA/QVGA) and sensor specific regs ********/ 1536 /******** Mode (VGA/QVGA) and sensor specific regs ********/
1573 switch (sd->sensor) { 1537 switch (sd->sensor) {
@@ -1611,8 +1575,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1611 OV7670_COM7_FMT_MASK); 1575 OV7670_COM7_FMT_MASK);
1612 break; 1576 break;
1613 case SEN_OV6620: 1577 case SEN_OV6620:
1614 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
1615 break;
1616 case SEN_OV6630: 1578 case SEN_OV6630:
1617 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 1579 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
1618 break; 1580 break;
@@ -1621,24 +1583,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1621 } 1583 }
1622 1584
1623 /******** Palette-specific regs ********/ 1585 /******** Palette-specific regs ********/
1624/* Need to do work here for the OV7670 */ 1586 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
1625 1587 /* not valid on the OV6620/OV7620/6630? */
1626 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { 1588 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
1627 /* not valid on the OV6620/OV7620/6630? */ 1589 }
1628 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
1629 }
1630 1590
1631 /* The OV518 needs special treatment. Although both the OV518 1591 /* The OV518 needs special treatment. Although both the OV518
1632 * 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
1633 * bus is actually used. The UV bus is tied to ground. 1593 * bus is actually used. The UV bus is tied to ground.
1634 * Therefore, the OV6630 needs to be in 8-bit multiplexed 1594 * Therefore, the OV6630 needs to be in 8-bit multiplexed
1635 * output mode */ 1595 * output mode */
1636 1596
1637 /* OV7640 is 8-bit only */ 1597 /* OV7640 is 8-bit only */
1638 1598
1639 if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) 1599 if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640)
1640 i2c_w_mask(sd, 0x13, 0x00, 0x20); 1600 i2c_w_mask(sd, 0x13, 0x00, 0x20);
1641/* } */
1642 1601
1643 /******** Clock programming ********/ 1602 /******** Clock programming ********/
1644 /* The OV6620 needs special handling. This prevents the 1603 /* The OV6620 needs special handling. This prevents the
@@ -1647,14 +1606,14 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1647 1606
1648 /* Clock down */ 1607 /* Clock down */
1649 i2c_w(sd, 0x2a, 0x04); 1608 i2c_w(sd, 0x2a, 0x04);
1650 i2c_w(sd, 0x11, win->clockdiv); 1609 i2c_w(sd, 0x11, sd->clockdiv);
1651 i2c_w(sd, 0x2a, 0x84); 1610 i2c_w(sd, 0x2a, 0x84);
1652 /* This next setting is critical. It seems to improve 1611 /* This next setting is critical. It seems to improve
1653 * the gain or the contrast. The "reserved" bits seem 1612 * the gain or the contrast. The "reserved" bits seem
1654 * to have some effect in this case. */ 1613 * to have some effect in this case. */
1655 i2c_w(sd, 0x2d, 0x85); 1614 i2c_w(sd, 0x2d, 0x85);
1656 } else if (win->clockdiv >= 0) { 1615 } else if (sd->clockdiv >= 0) {
1657 i2c_w(sd, 0x11, win->clockdiv); 1616 i2c_w(sd, 0x11, sd->clockdiv);
1658 } 1617 }
1659 1618
1660 /******** Special Features ********/ 1619 /******** Special Features ********/
@@ -1674,7 +1633,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1674 /* is fully tested. */ 1633 /* is fully tested. */
1675 /* 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 */
1676 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { 1635 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
1677 if (win->width == 640 /*&& win->height == 480*/) 1636 if (!qvga)
1678 i2c_w(sd, 0x35, 0x9e); 1637 i2c_w(sd, 0x35, 0x9e);
1679 else 1638 else
1680 i2c_w(sd, 0x35, 0x1e); 1639 i2c_w(sd, 0x35, 0x1e);
@@ -1682,13 +1641,31 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1682 return 0; 1641 return 0;
1683} 1642}
1684 1643
1685static int set_ov_sensor_window(struct sd *sd, 1644static void sethvflip(struct sd *sd)
1686 struct ovsensor_window *win)
1687{ 1645{
1646 if (sd->sensor != SEN_OV7670)
1647 return;
1648 if (sd->gspca_dev.streaming)
1649 ov51x_stop(sd);
1650 i2c_w_mask(sd, OV7670_REG_MVFP,
1651 OV7670_MVFP_MIRROR * sd->hflip
1652 | OV7670_MVFP_VFLIP * sd->vflip,
1653 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
1654 if (sd->gspca_dev.streaming)
1655 ov51x_restart(sd);
1656}
1657
1658static int set_ov_sensor_window(struct sd *sd)
1659{
1660 struct gspca_dev *gspca_dev;
1661 int qvga;
1688 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; 1662 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
1689 int ret, hstart, hstop, vstop, vstart; 1663 int ret, hstart, hstop, vstop, vstart;
1690 __u8 v; 1664 __u8 v;
1691 1665
1666 gspca_dev = &sd->gspca_dev;
1667 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1668
1692 /* The different sensor ICs handle setting up of window differently. 1669 /* The different sensor ICs handle setting up of window differently.
1693 * 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!! */
1694 switch (sd->sensor) { 1671 switch (sd->sensor) {
@@ -1733,7 +1710,7 @@ static int set_ov_sensor_window(struct sd *sd,
1733 switch (sd->sensor) { 1710 switch (sd->sensor) {
1734 case SEN_OV6620: 1711 case SEN_OV6620:
1735 case SEN_OV6630: 1712 case SEN_OV6630:
1736 if (win->quarter) { /* QCIF */ 1713 if (qvga) { /* QCIF */
1737 hwscale = 0; 1714 hwscale = 0;
1738 vwscale = 0; 1715 vwscale = 0;
1739 } else { /* CIF */ 1716 } else { /* CIF */
@@ -1743,7 +1720,7 @@ static int set_ov_sensor_window(struct sd *sd,
1743 } 1720 }
1744 break; 1721 break;
1745 case SEN_OV8610: 1722 case SEN_OV8610:
1746 if (win->quarter) { /* QSVGA */ 1723 if (qvga) { /* QSVGA */
1747 hwscale = 1; 1724 hwscale = 1;
1748 vwscale = 1; 1725 vwscale = 1;
1749 } else { /* SVGA */ 1726 } else { /* SVGA */
@@ -1752,7 +1729,7 @@ static int set_ov_sensor_window(struct sd *sd,
1752 } 1729 }
1753 break; 1730 break;
1754 default: /* SEN_OV7xx0 */ 1731 default: /* SEN_OV7xx0 */
1755 if (win->quarter) { /* QVGA */ 1732 if (qvga) { /* QVGA */
1756 hwscale = 1; 1733 hwscale = 1;
1757 vwscale = 0; 1734 vwscale = 0;
1758 } else { /* VGA */ 1735 } else { /* VGA */
@@ -1761,7 +1738,7 @@ static int set_ov_sensor_window(struct sd *sd,
1761 } 1738 }
1762 } 1739 }
1763 1740
1764 ret = mode_init_ov_sensor_regs(sd, win); 1741 ret = mode_init_ov_sensor_regs(sd);
1765 if (ret < 0) 1742 if (ret < 0)
1766 return ret; 1743 return ret;
1767 1744
@@ -1782,7 +1759,7 @@ static int set_ov_sensor_window(struct sd *sd,
1782 /* I can hard code this for OV7670s */ 1759 /* I can hard code this for OV7670s */
1783 /* 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! */
1784 if (sd->sensor == SEN_OV7670) { 1761 if (sd->sensor == SEN_OV7670) {
1785 if (win->quarter) { /* QVGA from ov7670.c by 1762 if (qvga) { /* QVGA from ov7670.c by
1786 * Jonathan Corbet */ 1763 * Jonathan Corbet */
1787 hstart = 164; 1764 hstart = 164;
1788 hstop = 20; 1765 hstop = 20;
@@ -1796,75 +1773,45 @@ static int set_ov_sensor_window(struct sd *sd,
1796 } 1773 }
1797 /* OV7670 hardware window registers are split across 1774 /* OV7670 hardware window registers are split across
1798 * multiple locations */ 1775 * multiple locations */
1799 i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); 1776 i2c_w(sd, OV7670_REG_HSTART, hstart >> 3);
1800 i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); 1777 i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3);
1801 v = i2c_r(sd, OV7670_REG_HREF); 1778 v = i2c_r(sd, OV7670_REG_HREF);
1802 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); 1779 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
1803 msleep(10); /* need to sleep between read and write to 1780 msleep(10); /* need to sleep between read and write to
1804 * same reg! */ 1781 * same reg! */
1805 i2c_w(sd, OV7670_REG_HREF, v); 1782 i2c_w(sd, OV7670_REG_HREF, v);
1806 1783
1807 i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); 1784 i2c_w(sd, OV7670_REG_VSTART, vstart >> 2);
1808 i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); 1785 i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2);
1809 v = i2c_r(sd, OV7670_REG_VREF); 1786 v = i2c_r(sd, OV7670_REG_VREF);
1810 v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); 1787 v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
1811 msleep(10); /* need to sleep between read and write to 1788 msleep(10); /* need to sleep between read and write to
1812 * same reg! */ 1789 * same reg! */
1813 i2c_w(sd, OV7670_REG_VREF, v); 1790 i2c_w(sd, OV7670_REG_VREF, v);
1814 1791 sethvflip(sd);
1815 } else { 1792 } else {
1816 i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); 1793 i2c_w(sd, 0x17, hwsbase);
1817 i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); 1794 i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
1818 i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); 1795 i2c_w(sd, 0x19, vwsbase);
1819 i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); 1796 i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
1820 } 1797 }
1821 return 0; 1798 return 0;
1822} 1799}
1823 1800
1824static int ov_sensor_mode_setup(struct sd *sd,
1825 int width, int height)
1826{
1827 struct ovsensor_window win;
1828
1829/* win.format = mode; */
1830
1831 /* Unless subcapture is enabled,
1832 * center the image window and downsample
1833 * if possible to increase the field of view */
1834 /* NOTE: OV518(+) and OV519 does downsampling on its own */
1835 win.width = width;
1836 win.height = height;
1837 if (width == sd->maxwidth)
1838 win.quarter = 0;
1839 else
1840 win.quarter = 1;
1841
1842 /* Center it */
1843 win.x = (win.width - width) / 2;
1844 win.y = (win.height - height) / 2;
1845
1846 /* Clock is determined by OV519 frame rate code */
1847 win.clockdiv = sd->clockdiv;
1848
1849 PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv);
1850 return set_ov_sensor_window(sd, &win);
1851}
1852
1853/* -- start the camera -- */ 1801/* -- start the camera -- */
1854static void sd_start(struct gspca_dev *gspca_dev) 1802static void sd_start(struct gspca_dev *gspca_dev)
1855{ 1803{
1856 struct sd *sd = (struct sd *) gspca_dev; 1804 struct sd *sd = (struct sd *) gspca_dev;
1857 int ret; 1805 int ret;
1858 1806
1859 1807 ret = ov519_mode_init_regs(sd);
1860 ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height);
1861 if (ret < 0) 1808 if (ret < 0)
1862 goto out; 1809 goto out;
1863 ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); 1810 ret = set_ov_sensor_window(sd);
1864 if (ret < 0) 1811 if (ret < 0)
1865 goto out; 1812 goto out;
1866 1813
1867 ret = ov51x_restart((struct sd *) gspca_dev); 1814 ret = ov51x_restart(sd);
1868 if (ret < 0) 1815 if (ret < 0)
1869 goto out; 1816 goto out;
1870 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); 1817 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
@@ -1938,12 +1885,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1938{ 1885{
1939 struct sd *sd = (struct sd *) gspca_dev; 1886 struct sd *sd = (struct sd *) gspca_dev;
1940 int val; 1887 int val;
1941/* int was_streaming; */
1942 1888
1943 val = sd->brightness; 1889 val = sd->brightness;
1944 PDEBUG(D_CONF, "brightness:%d", val); 1890 PDEBUG(D_CONF, "brightness:%d", val);
1945/* was_streaming = gspca_dev->streaming; 1891/* if (gspca_dev->streaming)
1946 * if (was_streaming)
1947 * ov51x_stop(sd); */ 1892 * ov51x_stop(sd); */
1948 switch (sd->sensor) { 1893 switch (sd->sensor) {
1949 case SEN_OV8610: 1894 case SEN_OV8610:
@@ -1961,12 +1906,12 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1961 i2c_w(sd, OV7610_REG_BRT, val); 1906 i2c_w(sd, OV7610_REG_BRT, val);
1962 break; 1907 break;
1963 case SEN_OV7670: 1908 case SEN_OV7670:
1964/*jfm - from windblows 1909/*win trace
1965 * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ 1910 * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
1966 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); 1911 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
1967 break; 1912 break;
1968 } 1913 }
1969/* if (was_streaming) 1914/* if (gspca_dev->streaming)
1970 * ov51x_restart(sd); */ 1915 * ov51x_restart(sd); */
1971} 1916}
1972 1917
@@ -1974,12 +1919,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1974{ 1919{
1975 struct sd *sd = (struct sd *) gspca_dev; 1920 struct sd *sd = (struct sd *) gspca_dev;
1976 int val; 1921 int val;
1977/* int was_streaming; */
1978 1922
1979 val = sd->contrast; 1923 val = sd->contrast;
1980 PDEBUG(D_CONF, "contrast:%d", val); 1924 PDEBUG(D_CONF, "contrast:%d", val);
1981/* was_streaming = gspca_dev->streaming; 1925/* if (gspca_dev->streaming)
1982 if (was_streaming)
1983 ov51x_stop(sd); */ 1926 ov51x_stop(sd); */
1984 switch (sd->sensor) { 1927 switch (sd->sensor) {
1985 case SEN_OV7610: 1928 case SEN_OV7610:
@@ -2016,7 +1959,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
2016 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); 1959 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
2017 break; 1960 break;
2018 } 1961 }
2019/* if (was_streaming) 1962/* if (gspca_dev->streaming)
2020 ov51x_restart(sd); */ 1963 ov51x_restart(sd); */
2021} 1964}
2022 1965
@@ -2024,12 +1967,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
2024{ 1967{
2025 struct sd *sd = (struct sd *) gspca_dev; 1968 struct sd *sd = (struct sd *) gspca_dev;
2026 int val; 1969 int val;
2027/* int was_streaming; */
2028 1970
2029 val = sd->colors; 1971 val = sd->colors;
2030 PDEBUG(D_CONF, "saturation:%d", val); 1972 PDEBUG(D_CONF, "saturation:%d", val);
2031/* was_streaming = gspca_dev->streaming; 1973/* if (gspca_dev->streaming)
2032 if (was_streaming)
2033 ov51x_stop(sd); */ 1974 ov51x_stop(sd); */
2034 switch (sd->sensor) { 1975 switch (sd->sensor) {
2035 case SEN_OV8610: 1976 case SEN_OV8610:
@@ -2055,7 +1996,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
2055 /* set REG_COM13 values for UV sat auto mode */ 1996 /* set REG_COM13 values for UV sat auto mode */
2056 break; 1997 break;
2057 } 1998 }
2058/* if (was_streaming) 1999/* if (gspca_dev->streaming)
2059 ov51x_restart(sd); */ 2000 ov51x_restart(sd); */
2060} 2001}
2061 2002
@@ -2110,6 +2051,40 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2110 return 0; 2051 return 0;
2111} 2052}
2112 2053
2054static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2055{
2056 struct sd *sd = (struct sd *) gspca_dev;
2057
2058 sd->hflip = val;
2059 sethvflip(sd);
2060 return 0;
2061}
2062
2063static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
2064{
2065 struct sd *sd = (struct sd *) gspca_dev;
2066
2067 *val = sd->hflip;
2068 return 0;
2069}
2070
2071static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2072{
2073 struct sd *sd = (struct sd *) gspca_dev;
2074
2075 sd->vflip = val;
2076 sethvflip(sd);
2077 return 0;
2078}
2079
2080static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2081{
2082 struct sd *sd = (struct sd *) gspca_dev;
2083
2084 *val = sd->vflip;
2085 return 0;
2086}
2087
2113/* sub-driver description */ 2088/* sub-driver description */
2114static const struct sd_desc sd_desc = { 2089static const struct sd_desc sd_desc = {
2115 .name = MODULE_NAME, 2090 .name = MODULE_NAME,
@@ -2178,4 +2153,3 @@ module_exit(sd_mod_exit);
2178 2153
2179module_param(frame_rate, int, 0644); 2154module_param(frame_rate, int, 0644);
2180MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); 2155MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");
2181