blob: 994a5e927d2d7435d374b66992d7a71f7e4e1b3f [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/**
2 * OV519 driver
3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03005 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03006 *
Romain Beauxis2961e872008-12-05 06:25:26 -03007 * This module is adapted from the ov51x-jpeg package, which itself
8 * was adapted from the ov511 driver.
9 *
10 * Original copyright for the ov511 driver is:
11 *
Hans de Goedeb46aaa02009-10-12 10:07:57 -030012 * Copyright (c) 1999-2006 Mark W. McClelland
Romain Beauxis2961e872008-12-05 06:25:26 -030013 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
Hans de Goedeb46aaa02009-10-12 10:07:57 -030014 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
15 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
16 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
17 * Changes by Claudio Matsuoka <claudio@conectiva.com>
Romain Beauxis2961e872008-12-05 06:25:26 -030018 *
19 * ov51x-jpeg original copyright is:
20 *
21 * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org>
22 * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 *
38 */
39#define MODULE_NAME "ov519"
40
41#include "gspca.h"
42
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030043MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
44MODULE_DESCRIPTION("OV519 USB Camera Driver");
45MODULE_LICENSE("GPL");
46
47/* global parameters */
48static int frame_rate;
49
50/* Number of times to retry a failed I2C transaction. Increase this if you
51 * are getting "Failed to read sensor ID..." */
52static int i2c_detect_tries = 10;
53
54/* ov519 device descriptor */
55struct sd {
56 struct gspca_dev gspca_dev; /* !! must be the first item */
57
Hans de Goede92918a52009-06-14 06:21:35 -030058 __u8 packet_nr;
59
Hans de Goede49809d62009-06-07 12:10:39 -030060 char bridge;
61#define BRIDGE_OV511 0
62#define BRIDGE_OV511PLUS 1
63#define BRIDGE_OV518 2
64#define BRIDGE_OV518PLUS 3
65#define BRIDGE_OV519 4
Hans de Goede635118d2009-10-11 09:49:03 -030066#define BRIDGE_OVFX2 5
Hans de Goedea511ba92009-10-16 07:13:07 -030067#define BRIDGE_W9968CF 6
Hans de Goede9e4d8252009-06-14 06:25:06 -030068#define BRIDGE_MASK 7
69
70 char invert_led;
71#define BRIDGE_INVERT_LED 8
Hans de Goede49809d62009-06-07 12:10:39 -030072
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030073 /* Determined by sensor type */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -030074 __u8 sif;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030075
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -030076 __u8 brightness;
77 __u8 contrast;
78 __u8 colors;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -030079 __u8 hflip;
80 __u8 vflip;
Hans de Goede02ab18b2009-06-14 04:32:04 -030081 __u8 autobrightness;
82 __u8 freq;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030083
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -030084 __u8 stopped; /* Streaming is temporarily paused */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030085
Hans de Goede1876bb92009-06-14 06:45:50 -030086 __u8 frame_rate; /* current Framerate */
87 __u8 clockdiv; /* clockdiv override */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030088
89 char sensor; /* Type of image sensor chip (SEN_*) */
90#define SEN_UNKNOWN 0
Hans de Goede635118d2009-10-11 09:49:03 -030091#define SEN_OV2610 1
92#define SEN_OV3610 2
93#define SEN_OV6620 3
94#define SEN_OV6630 4
95#define SEN_OV66308AF 5
96#define SEN_OV7610 6
97#define SEN_OV7620 7
98#define SEN_OV7640 8
99#define SEN_OV7670 9
100#define SEN_OV76BE 10
101#define SEN_OV8610 11
Hans de Goedea511ba92009-10-16 07:13:07 -0300102
103 u8 sensor_addr;
104 int sensor_width;
105 int sensor_height;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300106};
107
Hans de Goedea511ba92009-10-16 07:13:07 -0300108/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
109 the ov sensors which is already present here. When we have the time we
110 really should move the sensor drivers to v4l2 sub drivers. */
111#include "w996Xcf.c"
112
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300113/* V4L2 controls supported by the driver */
114static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
115static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
116static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
117static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
118static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
119static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300120static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
121static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
122static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
123static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede02ab18b2009-06-14 04:32:04 -0300124static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val);
125static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val);
126static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
127static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede49809d62009-06-07 12:10:39 -0300128static void setbrightness(struct gspca_dev *gspca_dev);
129static void setcontrast(struct gspca_dev *gspca_dev);
130static void setcolors(struct gspca_dev *gspca_dev);
Hans de Goede02ab18b2009-06-14 04:32:04 -0300131static void setautobrightness(struct sd *sd);
132static void setfreq(struct sd *sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300133
Hans de Goede02ab18b2009-06-14 04:32:04 -0300134static const struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300135 {
136 {
137 .id = V4L2_CID_BRIGHTNESS,
138 .type = V4L2_CTRL_TYPE_INTEGER,
139 .name = "Brightness",
140 .minimum = 0,
141 .maximum = 255,
142 .step = 1,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300143#define BRIGHTNESS_DEF 127
144 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300145 },
146 .set = sd_setbrightness,
147 .get = sd_getbrightness,
148 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300149 {
150 {
151 .id = V4L2_CID_CONTRAST,
152 .type = V4L2_CTRL_TYPE_INTEGER,
153 .name = "Contrast",
154 .minimum = 0,
155 .maximum = 255,
156 .step = 1,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300157#define CONTRAST_DEF 127
158 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300159 },
160 .set = sd_setcontrast,
161 .get = sd_getcontrast,
162 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300163 {
164 {
165 .id = V4L2_CID_SATURATION,
166 .type = V4L2_CTRL_TYPE_INTEGER,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300167 .name = "Color",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300168 .minimum = 0,
169 .maximum = 255,
170 .step = 1,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300171#define COLOR_DEF 127
172 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300173 },
174 .set = sd_setcolors,
175 .get = sd_getcolors,
176 },
Hans de Goede02ab18b2009-06-14 04:32:04 -0300177/* The flip controls work with ov7670 only */
Jean-Francois Moinede004482008-09-03 17:12:16 -0300178#define HFLIP_IDX 3
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300179 {
180 {
181 .id = V4L2_CID_HFLIP,
182 .type = V4L2_CTRL_TYPE_BOOLEAN,
183 .name = "Mirror",
184 .minimum = 0,
185 .maximum = 1,
186 .step = 1,
187#define HFLIP_DEF 0
188 .default_value = HFLIP_DEF,
189 },
190 .set = sd_sethflip,
191 .get = sd_gethflip,
192 },
Jean-Francois Moinede004482008-09-03 17:12:16 -0300193#define VFLIP_IDX 4
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300194 {
195 {
196 .id = V4L2_CID_VFLIP,
197 .type = V4L2_CTRL_TYPE_BOOLEAN,
198 .name = "Vflip",
199 .minimum = 0,
200 .maximum = 1,
201 .step = 1,
202#define VFLIP_DEF 0
203 .default_value = VFLIP_DEF,
204 },
205 .set = sd_setvflip,
206 .get = sd_getvflip,
207 },
Hans de Goede02ab18b2009-06-14 04:32:04 -0300208#define AUTOBRIGHT_IDX 5
209 {
210 {
211 .id = V4L2_CID_AUTOBRIGHTNESS,
212 .type = V4L2_CTRL_TYPE_BOOLEAN,
213 .name = "Auto Brightness",
214 .minimum = 0,
215 .maximum = 1,
216 .step = 1,
217#define AUTOBRIGHT_DEF 1
218 .default_value = AUTOBRIGHT_DEF,
219 },
220 .set = sd_setautobrightness,
221 .get = sd_getautobrightness,
222 },
223#define FREQ_IDX 6
224 {
225 {
226 .id = V4L2_CID_POWER_LINE_FREQUENCY,
227 .type = V4L2_CTRL_TYPE_MENU,
228 .name = "Light frequency filter",
229 .minimum = 0,
230 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
231 .step = 1,
232#define FREQ_DEF 0
233 .default_value = FREQ_DEF,
234 },
235 .set = sd_setfreq,
236 .get = sd_getfreq,
237 },
238#define OV7670_FREQ_IDX 7
239 {
240 {
241 .id = V4L2_CID_POWER_LINE_FREQUENCY,
242 .type = V4L2_CTRL_TYPE_MENU,
243 .name = "Light frequency filter",
244 .minimum = 0,
245 .maximum = 3, /* 0: 0, 1: 50Hz, 2:60Hz 3: Auto Hz */
246 .step = 1,
247#define OV7670_FREQ_DEF 3
248 .default_value = OV7670_FREQ_DEF,
249 },
250 .set = sd_setfreq,
251 .get = sd_getfreq,
252 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300253};
254
Hans de Goede49809d62009-06-07 12:10:39 -0300255static const struct v4l2_pix_format ov519_vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300256 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
257 .bytesperline = 320,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300258 .sizeimage = 320 * 240 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300259 .colorspace = V4L2_COLORSPACE_JPEG,
260 .priv = 1},
261 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
262 .bytesperline = 640,
263 .sizeimage = 640 * 480 * 3 / 8 + 590,
264 .colorspace = V4L2_COLORSPACE_JPEG,
265 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300266};
Hans de Goede49809d62009-06-07 12:10:39 -0300267static const struct v4l2_pix_format ov519_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300268 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
269 .bytesperline = 160,
270 .sizeimage = 160 * 120 * 3 / 8 + 590,
271 .colorspace = V4L2_COLORSPACE_JPEG,
272 .priv = 3},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300273 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
274 .bytesperline = 176,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300275 .sizeimage = 176 * 144 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300276 .colorspace = V4L2_COLORSPACE_JPEG,
277 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300278 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
279 .bytesperline = 320,
280 .sizeimage = 320 * 240 * 3 / 8 + 590,
281 .colorspace = V4L2_COLORSPACE_JPEG,
282 .priv = 2},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300283 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
284 .bytesperline = 352,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300285 .sizeimage = 352 * 288 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300286 .colorspace = V4L2_COLORSPACE_JPEG,
287 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300288};
289
Hans de Goedeb282d872009-06-14 19:10:40 -0300290/* Note some of the sizeimage values for the ov511 / ov518 may seem
291 larger then necessary, however they need to be this big as the ov511 /
292 ov518 always fills the entire isoc frame, using 0 padding bytes when
293 it doesn't have any data. So with low framerates the amount of data
294 transfered can become quite large (libv4l will remove all the 0 padding
295 in userspace). */
Hans de Goede49809d62009-06-07 12:10:39 -0300296static const struct v4l2_pix_format ov518_vga_mode[] = {
297 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
298 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300299 .sizeimage = 320 * 240 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300300 .colorspace = V4L2_COLORSPACE_JPEG,
301 .priv = 1},
302 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
303 .bytesperline = 640,
Hans de Goedeb282d872009-06-14 19:10:40 -0300304 .sizeimage = 640 * 480 * 2,
Hans de Goede49809d62009-06-07 12:10:39 -0300305 .colorspace = V4L2_COLORSPACE_JPEG,
306 .priv = 0},
307};
308static const struct v4l2_pix_format ov518_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300309 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
310 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300311 .sizeimage = 70000,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300312 .colorspace = V4L2_COLORSPACE_JPEG,
313 .priv = 3},
Hans de Goede49809d62009-06-07 12:10:39 -0300314 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
315 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300316 .sizeimage = 70000,
Hans de Goede49809d62009-06-07 12:10:39 -0300317 .colorspace = V4L2_COLORSPACE_JPEG,
318 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300319 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
320 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300321 .sizeimage = 320 * 240 * 3,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300322 .colorspace = V4L2_COLORSPACE_JPEG,
323 .priv = 2},
Hans de Goede49809d62009-06-07 12:10:39 -0300324 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
325 .bytesperline = 352,
Hans de Goedeb282d872009-06-14 19:10:40 -0300326 .sizeimage = 352 * 288 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300327 .colorspace = V4L2_COLORSPACE_JPEG,
328 .priv = 0},
329};
330
Hans de Goede1876bb92009-06-14 06:45:50 -0300331static const struct v4l2_pix_format ov511_vga_mode[] = {
332 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
333 .bytesperline = 320,
334 .sizeimage = 320 * 240 * 3,
335 .colorspace = V4L2_COLORSPACE_JPEG,
336 .priv = 1},
337 {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
338 .bytesperline = 640,
339 .sizeimage = 640 * 480 * 2,
340 .colorspace = V4L2_COLORSPACE_JPEG,
341 .priv = 0},
342};
343static const struct v4l2_pix_format ov511_sif_mode[] = {
344 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
345 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300346 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300347 .colorspace = V4L2_COLORSPACE_JPEG,
348 .priv = 3},
349 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
350 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300351 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300352 .colorspace = V4L2_COLORSPACE_JPEG,
353 .priv = 1},
354 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
355 .bytesperline = 320,
356 .sizeimage = 320 * 240 * 3,
357 .colorspace = V4L2_COLORSPACE_JPEG,
358 .priv = 2},
359 {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
360 .bytesperline = 352,
361 .sizeimage = 352 * 288 * 3,
362 .colorspace = V4L2_COLORSPACE_JPEG,
363 .priv = 0},
364};
Hans de Goede49809d62009-06-07 12:10:39 -0300365
Hans de Goede635118d2009-10-11 09:49:03 -0300366static const struct v4l2_pix_format ovfx2_vga_mode[] = {
367 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
368 .bytesperline = 320,
369 .sizeimage = 320 * 240,
370 .colorspace = V4L2_COLORSPACE_SRGB,
371 .priv = 1},
372 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
373 .bytesperline = 640,
374 .sizeimage = 640 * 480,
375 .colorspace = V4L2_COLORSPACE_SRGB,
376 .priv = 0},
377};
378static const struct v4l2_pix_format ovfx2_cif_mode[] = {
379 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
380 .bytesperline = 160,
381 .sizeimage = 160 * 120,
382 .colorspace = V4L2_COLORSPACE_SRGB,
383 .priv = 3},
384 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
385 .bytesperline = 176,
386 .sizeimage = 176 * 144,
387 .colorspace = V4L2_COLORSPACE_SRGB,
388 .priv = 1},
389 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
390 .bytesperline = 320,
391 .sizeimage = 320 * 240,
392 .colorspace = V4L2_COLORSPACE_SRGB,
393 .priv = 2},
394 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
395 .bytesperline = 352,
396 .sizeimage = 352 * 288,
397 .colorspace = V4L2_COLORSPACE_SRGB,
398 .priv = 0},
399};
400static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
401 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
402 .bytesperline = 1600,
403 .sizeimage = 1600 * 1200,
404 .colorspace = V4L2_COLORSPACE_SRGB},
405};
406static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300407 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
408 .bytesperline = 640,
409 .sizeimage = 640 * 480,
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300410 .colorspace = V4L2_COLORSPACE_SRGB,
411 .priv = 1},
412 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
413 .bytesperline = 800,
414 .sizeimage = 800 * 600,
415 .colorspace = V4L2_COLORSPACE_SRGB,
416 .priv = 1},
417 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
418 .bytesperline = 1024,
419 .sizeimage = 1024 * 768,
420 .colorspace = V4L2_COLORSPACE_SRGB,
421 .priv = 1},
422 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
423 .bytesperline = 1600,
424 .sizeimage = 1600 * 1200,
425 .colorspace = V4L2_COLORSPACE_SRGB,
426 .priv = 0},
427 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
428 .bytesperline = 2048,
429 .sizeimage = 2048 * 1536,
430 .colorspace = V4L2_COLORSPACE_SRGB,
431 .priv = 0},
Hans de Goede635118d2009-10-11 09:49:03 -0300432};
433
434
Hans de Goede49809d62009-06-07 12:10:39 -0300435/* Registers common to OV511 / OV518 */
Hans de Goede1876bb92009-06-14 06:45:50 -0300436#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
Hans de Goede49809d62009-06-07 12:10:39 -0300437#define R51x_SYS_RESET 0x50
Hans de Goede1876bb92009-06-14 06:45:50 -0300438 /* Reset type flags */
439 #define OV511_RESET_OMNICE 0x08
Hans de Goede49809d62009-06-07 12:10:39 -0300440#define R51x_SYS_INIT 0x53
441#define R51x_SYS_SNAP 0x52
442#define R51x_SYS_CUST_ID 0x5F
443#define R51x_COMP_LUT_BEGIN 0x80
444
445/* OV511 Camera interface register numbers */
Hans de Goede1876bb92009-06-14 06:45:50 -0300446#define R511_CAM_DELAY 0x10
447#define R511_CAM_EDGE 0x11
448#define R511_CAM_PXCNT 0x12
449#define R511_CAM_LNCNT 0x13
450#define R511_CAM_PXDIV 0x14
451#define R511_CAM_LNDIV 0x15
452#define R511_CAM_UV_EN 0x16
453#define R511_CAM_LINE_MODE 0x17
454#define R511_CAM_OPTS 0x18
455
456#define R511_SNAP_FRAME 0x19
457#define R511_SNAP_PXCNT 0x1A
458#define R511_SNAP_LNCNT 0x1B
459#define R511_SNAP_PXDIV 0x1C
460#define R511_SNAP_LNDIV 0x1D
461#define R511_SNAP_UV_EN 0x1E
462#define R511_SNAP_UV_EN 0x1E
463#define R511_SNAP_OPTS 0x1F
464
465#define R511_DRAM_FLOW_CTL 0x20
466#define R511_FIFO_OPTS 0x31
467#define R511_I2C_CTL 0x40
Hans de Goede49809d62009-06-07 12:10:39 -0300468#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
Hans de Goede1876bb92009-06-14 06:45:50 -0300469#define R511_COMP_EN 0x78
470#define R511_COMP_LUT_EN 0x79
Hans de Goede49809d62009-06-07 12:10:39 -0300471
472/* OV518 Camera interface register numbers */
473#define R518_GPIO_OUT 0x56 /* OV518(+) only */
474#define R518_GPIO_CTL 0x57 /* OV518(+) only */
475
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300476/* OV519 Camera interface register numbers */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -0300477#define OV519_R10_H_SIZE 0x10
478#define OV519_R11_V_SIZE 0x11
479#define OV519_R12_X_OFFSETL 0x12
480#define OV519_R13_X_OFFSETH 0x13
481#define OV519_R14_Y_OFFSETL 0x14
482#define OV519_R15_Y_OFFSETH 0x15
483#define OV519_R16_DIVIDER 0x16
484#define OV519_R20_DFR 0x20
485#define OV519_R25_FORMAT 0x25
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300486
487/* OV519 System Controller register numbers */
488#define OV519_SYS_RESET1 0x51
489#define OV519_SYS_EN_CLK1 0x54
490
491#define OV519_GPIO_DATA_OUT0 0x71
492#define OV519_GPIO_IO_CTRL0 0x72
493
494#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
495
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300496/*
497 * The FX2 chip does not give us a zero length read at end of frame.
498 * It does, however, give a short read at the end of a frame, if
499 * neccessary, rather than run two frames together.
500 *
501 * By choosing the right bulk transfer size, we are guaranteed to always
502 * get a short read for the last read of each frame. Frame sizes are
503 * always a composite number (width * height, or a multiple) so if we
504 * choose a prime number, we are guaranteed that the last read of a
505 * frame will be short.
506 *
507 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
508 * otherwise EOVERFLOW "babbling" errors occur. I have not been able
509 * to figure out why. [PMiller]
510 *
511 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
512 *
513 * It isn't enough to know the number of bytes per frame, in case we
514 * have data dropouts or buffer overruns (even though the FX2 double
515 * buffers, there are some pretty strict real time constraints for
516 * isochronous transfer for larger frame sizes).
517 */
518#define OVFX2_BULK_SIZE (13 * 4096)
519
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300520/* I2C registers */
521#define R51x_I2C_W_SID 0x41
522#define R51x_I2C_SADDR_3 0x42
523#define R51x_I2C_SADDR_2 0x43
524#define R51x_I2C_R_SID 0x44
525#define R51x_I2C_DATA 0x45
526#define R518_I2C_CTL 0x47 /* OV518(+) only */
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300527#define OVFX2_I2C_ADDR 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300528
529/* I2C ADDRESSES */
530#define OV7xx0_SID 0x42
Hans de Goede229bb7d2009-10-11 07:41:46 -0300531#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300532#define OV8xx0_SID 0xa0
533#define OV6xx0_SID 0xc0
534
535/* OV7610 registers */
536#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
Hans de Goede49809d62009-06-07 12:10:39 -0300537#define OV7610_REG_BLUE 0x01 /* blue channel balance */
538#define OV7610_REG_RED 0x02 /* red channel balance */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300539#define OV7610_REG_SAT 0x03 /* saturation */
540#define OV8610_REG_HUE 0x04 /* 04 reserved */
541#define OV7610_REG_CNT 0x05 /* Y contrast */
542#define OV7610_REG_BRT 0x06 /* Y brightness */
543#define OV7610_REG_COM_C 0x14 /* misc common regs */
544#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
545#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
546#define OV7610_REG_COM_I 0x29 /* misc settings */
547
548/* OV7670 registers */
549#define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
550#define OV7670_REG_BLUE 0x01 /* blue gain */
551#define OV7670_REG_RED 0x02 /* red gain */
552#define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
553#define OV7670_REG_COM1 0x04 /* Control 1 */
554#define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */
555#define OV7670_REG_COM3 0x0c /* Control 3 */
556#define OV7670_REG_COM4 0x0d /* Control 4 */
557#define OV7670_REG_COM5 0x0e /* All "reserved" */
558#define OV7670_REG_COM6 0x0f /* Control 6 */
559#define OV7670_REG_AECH 0x10 /* More bits of AEC value */
560#define OV7670_REG_CLKRC 0x11 /* Clock control */
561#define OV7670_REG_COM7 0x12 /* Control 7 */
562#define OV7670_COM7_FMT_VGA 0x00
563#define OV7670_COM7_YUV 0x00 /* YUV */
564#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
565#define OV7670_COM7_FMT_MASK 0x38
566#define OV7670_COM7_RESET 0x80 /* Register reset */
567#define OV7670_REG_COM8 0x13 /* Control 8 */
568#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
569#define OV7670_COM8_AWB 0x02 /* White balance enable */
570#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
571#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
572#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
573#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
574#define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */
575#define OV7670_REG_COM10 0x15 /* Control 10 */
576#define OV7670_REG_HSTART 0x17 /* Horiz start high bits */
577#define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */
578#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
579#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
580#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300581#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300582#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
583#define OV7670_REG_AEW 0x24 /* AGC upper limit */
584#define OV7670_REG_AEB 0x25 /* AGC lower limit */
585#define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */
586#define OV7670_REG_HREF 0x32 /* HREF pieces */
587#define OV7670_REG_TSLB 0x3a /* lots of stuff */
588#define OV7670_REG_COM11 0x3b /* Control 11 */
589#define OV7670_COM11_EXP 0x02
590#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
591#define OV7670_REG_COM12 0x3c /* Control 12 */
592#define OV7670_REG_COM13 0x3d /* Control 13 */
593#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
594#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
595#define OV7670_REG_COM14 0x3e /* Control 14 */
596#define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */
597#define OV7670_REG_COM15 0x40 /* Control 15 */
598#define OV7670_COM15_R00FF 0xc0 /* 00 to FF */
599#define OV7670_REG_COM16 0x41 /* Control 16 */
600#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
601#define OV7670_REG_BRIGHT 0x55 /* Brightness */
602#define OV7670_REG_CONTRAS 0x56 /* Contrast control */
603#define OV7670_REG_GFIX 0x69 /* Fix gain control */
604#define OV7670_REG_RGB444 0x8c /* RGB 444 control */
605#define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */
606#define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
607#define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */
608#define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
609#define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
610#define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
611#define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
612#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
613#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
614
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300615struct ov_regvals {
616 __u8 reg;
617 __u8 val;
618};
619struct ov_i2c_regvals {
620 __u8 reg;
621 __u8 val;
622};
623
Hans de Goede635118d2009-10-11 09:49:03 -0300624/* Settings for OV2610 camera chip */
625static const struct ov_i2c_regvals norm_2610[] =
626{
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300627 { 0x12, 0x80 }, /* reset */
Hans de Goede635118d2009-10-11 09:49:03 -0300628};
629
630static const struct ov_i2c_regvals norm_3620b[] =
631{
632 /*
633 * From the datasheet: "Note that after writing to register COMH
634 * (0x12) to change the sensor mode, registers related to the
635 * sensor’s cropping window will be reset back to their default
636 * values."
637 *
638 * "wait 4096 external clock ... to make sure the sensor is
639 * stable and ready to access registers" i.e. 160us at 24MHz
640 */
641
642 { 0x12, 0x80 }, /* COMH reset */
643 { 0x12, 0x00 }, /* QXGA, master */
644
645 /*
646 * 11 CLKRC "Clock Rate Control"
647 * [7] internal frequency doublers: on
648 * [6] video port mode: master
649 * [5:0] clock divider: 1
650 */
651 { 0x11, 0x80 },
652
653 /*
654 * 13 COMI "Common Control I"
655 * = 192 (0xC0) 11000000
656 * COMI[7] "AEC speed selection"
657 * = 1 (0x01) 1....... "Faster AEC correction"
658 * COMI[6] "AEC speed step selection"
659 * = 1 (0x01) .1...... "Big steps, fast"
660 * COMI[5] "Banding filter on off"
661 * = 0 (0x00) ..0..... "Off"
662 * COMI[4] "Banding filter option"
663 * = 0 (0x00) ...0.... "Main clock is 48 MHz and
664 * the PLL is ON"
665 * COMI[3] "Reserved"
666 * = 0 (0x00) ....0...
667 * COMI[2] "AGC auto manual control selection"
668 * = 0 (0x00) .....0.. "Manual"
669 * COMI[1] "AWB auto manual control selection"
670 * = 0 (0x00) ......0. "Manual"
671 * COMI[0] "Exposure control"
672 * = 0 (0x00) .......0 "Manual"
673 */
674 { 0x13, 0xC0 },
675
676 /*
677 * 09 COMC "Common Control C"
678 * = 8 (0x08) 00001000
679 * COMC[7:5] "Reserved"
680 * = 0 (0x00) 000.....
681 * COMC[4] "Sleep Mode Enable"
682 * = 0 (0x00) ...0.... "Normal mode"
683 * COMC[3:2] "Sensor sampling reset timing selection"
684 * = 2 (0x02) ....10.. "Longer reset time"
685 * COMC[1:0] "Output drive current select"
686 * = 0 (0x00) ......00 "Weakest"
687 */
688 { 0x09, 0x08 },
689
690 /*
691 * 0C COMD "Common Control D"
692 * = 8 (0x08) 00001000
693 * COMD[7] "Reserved"
694 * = 0 (0x00) 0.......
695 * COMD[6] "Swap MSB and LSB at the output port"
696 * = 0 (0x00) .0...... "False"
697 * COMD[5:3] "Reserved"
698 * = 1 (0x01) ..001...
699 * COMD[2] "Output Average On Off"
700 * = 0 (0x00) .....0.. "Output Normal"
701 * COMD[1] "Sensor precharge voltage selection"
702 * = 0 (0x00) ......0. "Selects internal
703 * reference precharge
704 * voltage"
705 * COMD[0] "Snapshot option"
706 * = 0 (0x00) .......0 "Enable live video output
707 * after snapshot sequence"
708 */
709 { 0x0c, 0x08 },
710
711 /*
712 * 0D COME "Common Control E"
713 * = 161 (0xA1) 10100001
714 * COME[7] "Output average option"
715 * = 1 (0x01) 1....... "Output average of 4 pixels"
716 * COME[6] "Anti-blooming control"
717 * = 0 (0x00) .0...... "Off"
718 * COME[5:3] "Reserved"
719 * = 4 (0x04) ..100...
720 * COME[2] "Clock output power down pin status"
721 * = 0 (0x00) .....0.. "Tri-state data output pin
722 * on power down"
723 * COME[1] "Data output pin status selection at power down"
724 * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
725 * HREF, and CHSYNC pins on
726 * power down"
727 * COME[0] "Auto zero circuit select"
728 * = 1 (0x01) .......1 "On"
729 */
730 { 0x0d, 0xA1 },
731
732 /*
733 * 0E COMF "Common Control F"
734 * = 112 (0x70) 01110000
735 * COMF[7] "System clock selection"
736 * = 0 (0x00) 0....... "Use 24 MHz system clock"
737 * COMF[6:4] "Reserved"
738 * = 7 (0x07) .111....
739 * COMF[3] "Manual auto negative offset canceling selection"
740 * = 0 (0x00) ....0... "Auto detect negative
741 * offset and cancel it"
742 * COMF[2:0] "Reserved"
743 * = 0 (0x00) .....000
744 */
745 { 0x0e, 0x70 },
746
747 /*
748 * 0F COMG "Common Control G"
749 * = 66 (0x42) 01000010
750 * COMG[7] "Optical black output selection"
751 * = 0 (0x00) 0....... "Disable"
752 * COMG[6] "Black level calibrate selection"
753 * = 1 (0x01) .1...... "Use optical black pixels
754 * to calibrate"
755 * COMG[5:4] "Reserved"
756 * = 0 (0x00) ..00....
757 * COMG[3] "Channel offset adjustment"
758 * = 0 (0x00) ....0... "Disable offset adjustment"
759 * COMG[2] "ADC black level calibration option"
760 * = 0 (0x00) .....0.. "Use B/G line and G/R
761 * line to calibrate each
762 * channel's black level"
763 * COMG[1] "Reserved"
764 * = 1 (0x01) ......1.
765 * COMG[0] "ADC black level calibration enable"
766 * = 0 (0x00) .......0 "Disable"
767 */
768 { 0x0f, 0x42 },
769
770 /*
771 * 14 COMJ "Common Control J"
772 * = 198 (0xC6) 11000110
773 * COMJ[7:6] "AGC gain ceiling"
774 * = 3 (0x03) 11...... "8x"
775 * COMJ[5:4] "Reserved"
776 * = 0 (0x00) ..00....
777 * COMJ[3] "Auto banding filter"
778 * = 0 (0x00) ....0... "Banding filter is always
779 * on off depending on
780 * COMI[5] setting"
781 * COMJ[2] "VSYNC drop option"
782 * = 1 (0x01) .....1.. "SYNC is dropped if frame
783 * data is dropped"
784 * COMJ[1] "Frame data drop"
785 * = 1 (0x01) ......1. "Drop frame data if
786 * exposure is not within
787 * tolerance. In AEC mode,
788 * data is normally dropped
789 * when data is out of
790 * range."
791 * COMJ[0] "Reserved"
792 * = 0 (0x00) .......0
793 */
794 { 0x14, 0xC6 },
795
796 /*
797 * 15 COMK "Common Control K"
798 * = 2 (0x02) 00000010
799 * COMK[7] "CHSYNC pin output swap"
800 * = 0 (0x00) 0....... "CHSYNC"
801 * COMK[6] "HREF pin output swap"
802 * = 0 (0x00) .0...... "HREF"
803 * COMK[5] "PCLK output selection"
804 * = 0 (0x00) ..0..... "PCLK always output"
805 * COMK[4] "PCLK edge selection"
806 * = 0 (0x00) ...0.... "Data valid on falling edge"
807 * COMK[3] "HREF output polarity"
808 * = 0 (0x00) ....0... "positive"
809 * COMK[2] "Reserved"
810 * = 0 (0x00) .....0..
811 * COMK[1] "VSYNC polarity"
812 * = 1 (0x01) ......1. "negative"
813 * COMK[0] "HSYNC polarity"
814 * = 0 (0x00) .......0 "positive"
815 */
816 { 0x15, 0x02 },
817
818 /*
819 * 33 CHLF "Current Control"
820 * = 9 (0x09) 00001001
821 * CHLF[7:6] "Sensor current control"
822 * = 0 (0x00) 00......
823 * CHLF[5] "Sensor current range control"
824 * = 0 (0x00) ..0..... "normal range"
825 * CHLF[4] "Sensor current"
826 * = 0 (0x00) ...0.... "normal current"
827 * CHLF[3] "Sensor buffer current control"
828 * = 1 (0x01) ....1... "half current"
829 * CHLF[2] "Column buffer current control"
830 * = 0 (0x00) .....0.. "normal current"
831 * CHLF[1] "Analog DSP current control"
832 * = 0 (0x00) ......0. "normal current"
833 * CHLF[1] "ADC current control"
834 * = 0 (0x00) ......0. "normal current"
835 */
836 { 0x33, 0x09 },
837
838 /*
839 * 34 VBLM "Blooming Control"
840 * = 80 (0x50) 01010000
841 * VBLM[7] "Hard soft reset switch"
842 * = 0 (0x00) 0....... "Hard reset"
843 * VBLM[6:4] "Blooming voltage selection"
844 * = 5 (0x05) .101....
845 * VBLM[3:0] "Sensor current control"
846 * = 0 (0x00) ....0000
847 */
848 { 0x34, 0x50 },
849
850 /*
851 * 36 VCHG "Sensor Precharge Voltage Control"
852 * = 0 (0x00) 00000000
853 * VCHG[7] "Reserved"
854 * = 0 (0x00) 0.......
855 * VCHG[6:4] "Sensor precharge voltage control"
856 * = 0 (0x00) .000....
857 * VCHG[3:0] "Sensor array common reference"
858 * = 0 (0x00) ....0000
859 */
860 { 0x36, 0x00 },
861
862 /*
863 * 37 ADC "ADC Reference Control"
864 * = 4 (0x04) 00000100
865 * ADC[7:4] "Reserved"
866 * = 0 (0x00) 0000....
867 * ADC[3] "ADC input signal range"
868 * = 0 (0x00) ....0... "Input signal 1.0x"
869 * ADC[2:0] "ADC range control"
870 * = 4 (0x04) .....100
871 */
872 { 0x37, 0x04 },
873
874 /*
875 * 38 ACOM "Analog Common Ground"
876 * = 82 (0x52) 01010010
877 * ACOM[7] "Analog gain control"
878 * = 0 (0x00) 0....... "Gain 1x"
879 * ACOM[6] "Analog black level calibration"
880 * = 1 (0x01) .1...... "On"
881 * ACOM[5:0] "Reserved"
882 * = 18 (0x12) ..010010
883 */
884 { 0x38, 0x52 },
885
886 /*
887 * 3A FREFA "Internal Reference Adjustment"
888 * = 0 (0x00) 00000000
889 * FREFA[7:0] "Range"
890 * = 0 (0x00) 00000000
891 */
892 { 0x3a, 0x00 },
893
894 /*
895 * 3C FVOPT "Internal Reference Adjustment"
896 * = 31 (0x1F) 00011111
897 * FVOPT[7:0] "Range"
898 * = 31 (0x1F) 00011111
899 */
900 { 0x3c, 0x1F },
901
902 /*
903 * 44 Undocumented = 0 (0x00) 00000000
904 * 44[7:0] "It's a secret"
905 * = 0 (0x00) 00000000
906 */
907 { 0x44, 0x00 },
908
909 /*
910 * 40 Undocumented = 0 (0x00) 00000000
911 * 40[7:0] "It's a secret"
912 * = 0 (0x00) 00000000
913 */
914 { 0x40, 0x00 },
915
916 /*
917 * 41 Undocumented = 0 (0x00) 00000000
918 * 41[7:0] "It's a secret"
919 * = 0 (0x00) 00000000
920 */
921 { 0x41, 0x00 },
922
923 /*
924 * 42 Undocumented = 0 (0x00) 00000000
925 * 42[7:0] "It's a secret"
926 * = 0 (0x00) 00000000
927 */
928 { 0x42, 0x00 },
929
930 /*
931 * 43 Undocumented = 0 (0x00) 00000000
932 * 43[7:0] "It's a secret"
933 * = 0 (0x00) 00000000
934 */
935 { 0x43, 0x00 },
936
937 /*
938 * 45 Undocumented = 128 (0x80) 10000000
939 * 45[7:0] "It's a secret"
940 * = 128 (0x80) 10000000
941 */
942 { 0x45, 0x80 },
943
944 /*
945 * 48 Undocumented = 192 (0xC0) 11000000
946 * 48[7:0] "It's a secret"
947 * = 192 (0xC0) 11000000
948 */
949 { 0x48, 0xC0 },
950
951 /*
952 * 49 Undocumented = 25 (0x19) 00011001
953 * 49[7:0] "It's a secret"
954 * = 25 (0x19) 00011001
955 */
956 { 0x49, 0x19 },
957
958 /*
959 * 4B Undocumented = 128 (0x80) 10000000
960 * 4B[7:0] "It's a secret"
961 * = 128 (0x80) 10000000
962 */
963 { 0x4B, 0x80 },
964
965 /*
966 * 4D Undocumented = 196 (0xC4) 11000100
967 * 4D[7:0] "It's a secret"
968 * = 196 (0xC4) 11000100
969 */
970 { 0x4D, 0xC4 },
971
972 /*
973 * 35 VREF "Reference Voltage Control"
974 * = 76 (0x4C) 01001100
975 * VREF[7:5] "Column high reference control"
976 * = 2 (0x02) 010..... "higher voltage"
977 * VREF[4:2] "Column low reference control"
978 * = 3 (0x03) ...011.. "Highest voltage"
979 * VREF[1:0] "Reserved"
980 * = 0 (0x00) ......00
981 */
982 { 0x35, 0x4C },
983
984 /*
985 * 3D Undocumented = 0 (0x00) 00000000
986 * 3D[7:0] "It's a secret"
987 * = 0 (0x00) 00000000
988 */
989 { 0x3D, 0x00 },
990
991 /*
992 * 3E Undocumented = 0 (0x00) 00000000
993 * 3E[7:0] "It's a secret"
994 * = 0 (0x00) 00000000
995 */
996 { 0x3E, 0x00 },
997
998 /*
999 * 3B FREFB "Internal Reference Adjustment"
1000 * = 24 (0x18) 00011000
1001 * FREFB[7:0] "Range"
1002 * = 24 (0x18) 00011000
1003 */
1004 { 0x3b, 0x18 },
1005
1006 /*
1007 * 33 CHLF "Current Control"
1008 * = 25 (0x19) 00011001
1009 * CHLF[7:6] "Sensor current control"
1010 * = 0 (0x00) 00......
1011 * CHLF[5] "Sensor current range control"
1012 * = 0 (0x00) ..0..... "normal range"
1013 * CHLF[4] "Sensor current"
1014 * = 1 (0x01) ...1.... "double current"
1015 * CHLF[3] "Sensor buffer current control"
1016 * = 1 (0x01) ....1... "half current"
1017 * CHLF[2] "Column buffer current control"
1018 * = 0 (0x00) .....0.. "normal current"
1019 * CHLF[1] "Analog DSP current control"
1020 * = 0 (0x00) ......0. "normal current"
1021 * CHLF[1] "ADC current control"
1022 * = 0 (0x00) ......0. "normal current"
1023 */
1024 { 0x33, 0x19 },
1025
1026 /*
1027 * 34 VBLM "Blooming Control"
1028 * = 90 (0x5A) 01011010
1029 * VBLM[7] "Hard soft reset switch"
1030 * = 0 (0x00) 0....... "Hard reset"
1031 * VBLM[6:4] "Blooming voltage selection"
1032 * = 5 (0x05) .101....
1033 * VBLM[3:0] "Sensor current control"
1034 * = 10 (0x0A) ....1010
1035 */
1036 { 0x34, 0x5A },
1037
1038 /*
1039 * 3B FREFB "Internal Reference Adjustment"
1040 * = 0 (0x00) 00000000
1041 * FREFB[7:0] "Range"
1042 * = 0 (0x00) 00000000
1043 */
1044 { 0x3b, 0x00 },
1045
1046 /*
1047 * 33 CHLF "Current Control"
1048 * = 9 (0x09) 00001001
1049 * CHLF[7:6] "Sensor current control"
1050 * = 0 (0x00) 00......
1051 * CHLF[5] "Sensor current range control"
1052 * = 0 (0x00) ..0..... "normal range"
1053 * CHLF[4] "Sensor current"
1054 * = 0 (0x00) ...0.... "normal current"
1055 * CHLF[3] "Sensor buffer current control"
1056 * = 1 (0x01) ....1... "half current"
1057 * CHLF[2] "Column buffer current control"
1058 * = 0 (0x00) .....0.. "normal current"
1059 * CHLF[1] "Analog DSP current control"
1060 * = 0 (0x00) ......0. "normal current"
1061 * CHLF[1] "ADC current control"
1062 * = 0 (0x00) ......0. "normal current"
1063 */
1064 { 0x33, 0x09 },
1065
1066 /*
1067 * 34 VBLM "Blooming Control"
1068 * = 80 (0x50) 01010000
1069 * VBLM[7] "Hard soft reset switch"
1070 * = 0 (0x00) 0....... "Hard reset"
1071 * VBLM[6:4] "Blooming voltage selection"
1072 * = 5 (0x05) .101....
1073 * VBLM[3:0] "Sensor current control"
1074 * = 0 (0x00) ....0000
1075 */
1076 { 0x34, 0x50 },
1077
1078 /*
1079 * 12 COMH "Common Control H"
1080 * = 64 (0x40) 01000000
1081 * COMH[7] "SRST"
1082 * = 0 (0x00) 0....... "No-op"
1083 * COMH[6:4] "Resolution selection"
1084 * = 4 (0x04) .100.... "XGA"
1085 * COMH[3] "Master slave selection"
1086 * = 0 (0x00) ....0... "Master mode"
1087 * COMH[2] "Internal B/R channel option"
1088 * = 0 (0x00) .....0.. "B/R use same channel"
1089 * COMH[1] "Color bar test pattern"
1090 * = 0 (0x00) ......0. "Off"
1091 * COMH[0] "Reserved"
1092 * = 0 (0x00) .......0
1093 */
1094 { 0x12, 0x40 },
1095
1096 /*
1097 * 17 HREFST "Horizontal window start"
1098 * = 31 (0x1F) 00011111
1099 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1100 * = 31 (0x1F) 00011111
1101 */
1102 { 0x17, 0x1F },
1103
1104 /*
1105 * 18 HREFEND "Horizontal window end"
1106 * = 95 (0x5F) 01011111
1107 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1108 * = 95 (0x5F) 01011111
1109 */
1110 { 0x18, 0x5F },
1111
1112 /*
1113 * 19 VSTRT "Vertical window start"
1114 * = 0 (0x00) 00000000
1115 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1116 * = 0 (0x00) 00000000
1117 */
1118 { 0x19, 0x00 },
1119
1120 /*
1121 * 1A VEND "Vertical window end"
1122 * = 96 (0x60) 01100000
1123 * VEND[7:0] "Vertical Window End, 8 MSBs"
1124 * = 96 (0x60) 01100000
1125 */
1126 { 0x1a, 0x60 },
1127
1128 /*
1129 * 32 COMM "Common Control M"
1130 * = 18 (0x12) 00010010
1131 * COMM[7:6] "Pixel clock divide option"
1132 * = 0 (0x00) 00...... "/1"
1133 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1134 * = 2 (0x02) ..010...
1135 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1136 * = 2 (0x02) .....010
1137 */
1138 { 0x32, 0x12 },
1139
1140 /*
1141 * 03 COMA "Common Control A"
1142 * = 74 (0x4A) 01001010
1143 * COMA[7:4] "AWB Update Threshold"
1144 * = 4 (0x04) 0100....
1145 * COMA[3:2] "Vertical window end line control 2 LSBs"
1146 * = 2 (0x02) ....10..
1147 * COMA[1:0] "Vertical window start line control 2 LSBs"
1148 * = 2 (0x02) ......10
1149 */
1150 { 0x03, 0x4A },
1151
1152 /*
1153 * 11 CLKRC "Clock Rate Control"
1154 * = 128 (0x80) 10000000
1155 * CLKRC[7] "Internal frequency doublers on off seclection"
1156 * = 1 (0x01) 1....... "On"
1157 * CLKRC[6] "Digital video master slave selection"
1158 * = 0 (0x00) .0...... "Master mode, sensor
1159 * provides PCLK"
1160 * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
1161 * = 0 (0x00) ..000000
1162 */
1163 { 0x11, 0x80 },
1164
1165 /*
1166 * 12 COMH "Common Control H"
1167 * = 0 (0x00) 00000000
1168 * COMH[7] "SRST"
1169 * = 0 (0x00) 0....... "No-op"
1170 * COMH[6:4] "Resolution selection"
1171 * = 0 (0x00) .000.... "QXGA"
1172 * COMH[3] "Master slave selection"
1173 * = 0 (0x00) ....0... "Master mode"
1174 * COMH[2] "Internal B/R channel option"
1175 * = 0 (0x00) .....0.. "B/R use same channel"
1176 * COMH[1] "Color bar test pattern"
1177 * = 0 (0x00) ......0. "Off"
1178 * COMH[0] "Reserved"
1179 * = 0 (0x00) .......0
1180 */
1181 { 0x12, 0x00 },
1182
1183 /*
1184 * 12 COMH "Common Control H"
1185 * = 64 (0x40) 01000000
1186 * COMH[7] "SRST"
1187 * = 0 (0x00) 0....... "No-op"
1188 * COMH[6:4] "Resolution selection"
1189 * = 4 (0x04) .100.... "XGA"
1190 * COMH[3] "Master slave selection"
1191 * = 0 (0x00) ....0... "Master mode"
1192 * COMH[2] "Internal B/R channel option"
1193 * = 0 (0x00) .....0.. "B/R use same channel"
1194 * COMH[1] "Color bar test pattern"
1195 * = 0 (0x00) ......0. "Off"
1196 * COMH[0] "Reserved"
1197 * = 0 (0x00) .......0
1198 */
1199 { 0x12, 0x40 },
1200
1201 /*
1202 * 17 HREFST "Horizontal window start"
1203 * = 31 (0x1F) 00011111
1204 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1205 * = 31 (0x1F) 00011111
1206 */
1207 { 0x17, 0x1F },
1208
1209 /*
1210 * 18 HREFEND "Horizontal window end"
1211 * = 95 (0x5F) 01011111
1212 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1213 * = 95 (0x5F) 01011111
1214 */
1215 { 0x18, 0x5F },
1216
1217 /*
1218 * 19 VSTRT "Vertical window start"
1219 * = 0 (0x00) 00000000
1220 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1221 * = 0 (0x00) 00000000
1222 */
1223 { 0x19, 0x00 },
1224
1225 /*
1226 * 1A VEND "Vertical window end"
1227 * = 96 (0x60) 01100000
1228 * VEND[7:0] "Vertical Window End, 8 MSBs"
1229 * = 96 (0x60) 01100000
1230 */
1231 { 0x1a, 0x60 },
1232
1233 /*
1234 * 32 COMM "Common Control M"
1235 * = 18 (0x12) 00010010
1236 * COMM[7:6] "Pixel clock divide option"
1237 * = 0 (0x00) 00...... "/1"
1238 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1239 * = 2 (0x02) ..010...
1240 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1241 * = 2 (0x02) .....010
1242 */
1243 { 0x32, 0x12 },
1244
1245 /*
1246 * 03 COMA "Common Control A"
1247 * = 74 (0x4A) 01001010
1248 * COMA[7:4] "AWB Update Threshold"
1249 * = 4 (0x04) 0100....
1250 * COMA[3:2] "Vertical window end line control 2 LSBs"
1251 * = 2 (0x02) ....10..
1252 * COMA[1:0] "Vertical window start line control 2 LSBs"
1253 * = 2 (0x02) ......10
1254 */
1255 { 0x03, 0x4A },
1256
1257 /*
1258 * 02 RED "Red Gain Control"
1259 * = 175 (0xAF) 10101111
1260 * RED[7] "Action"
1261 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1262 * RED[6:0] "Value"
1263 * = 47 (0x2F) .0101111
1264 */
1265 { 0x02, 0xAF },
1266
1267 /*
1268 * 2D ADDVSL "VSYNC Pulse Width"
1269 * = 210 (0xD2) 11010010
1270 * ADDVSL[7:0] "VSYNC pulse width, LSB"
1271 * = 210 (0xD2) 11010010
1272 */
1273 { 0x2d, 0xD2 },
1274
1275 /*
1276 * 00 GAIN = 24 (0x18) 00011000
1277 * GAIN[7:6] "Reserved"
1278 * = 0 (0x00) 00......
1279 * GAIN[5] "Double"
1280 * = 0 (0x00) ..0..... "False"
1281 * GAIN[4] "Double"
1282 * = 1 (0x01) ...1.... "True"
1283 * GAIN[3:0] "Range"
1284 * = 8 (0x08) ....1000
1285 */
1286 { 0x00, 0x18 },
1287
1288 /*
1289 * 01 BLUE "Blue Gain Control"
1290 * = 240 (0xF0) 11110000
1291 * BLUE[7] "Action"
1292 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1293 * BLUE[6:0] "Value"
1294 * = 112 (0x70) .1110000
1295 */
1296 { 0x01, 0xF0 },
1297
1298 /*
1299 * 10 AEC "Automatic Exposure Control"
1300 * = 10 (0x0A) 00001010
1301 * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
1302 * = 10 (0x0A) 00001010
1303 */
1304 { 0x10, 0x0A },
1305
1306 { 0xE1, 0x67 },
1307 { 0xE3, 0x03 },
1308 { 0xE4, 0x26 },
1309 { 0xE5, 0x3E },
1310 { 0xF8, 0x01 },
1311 { 0xFF, 0x01 },
1312};
1313
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001314static const struct ov_i2c_regvals norm_6x20[] = {
1315 { 0x12, 0x80 }, /* reset */
1316 { 0x11, 0x01 },
1317 { 0x03, 0x60 },
1318 { 0x05, 0x7f }, /* For when autoadjust is off */
1319 { 0x07, 0xa8 },
1320 /* The ratio of 0x0c and 0x0d controls the white point */
1321 { 0x0c, 0x24 },
1322 { 0x0d, 0x24 },
1323 { 0x0f, 0x15 }, /* COMS */
1324 { 0x10, 0x75 }, /* AEC Exposure time */
1325 { 0x12, 0x24 }, /* Enable AGC */
1326 { 0x14, 0x04 },
1327 /* 0x16: 0x06 helps frame stability with moving objects */
1328 { 0x16, 0x06 },
1329/* { 0x20, 0x30 }, * Aperture correction enable */
1330 { 0x26, 0xb2 }, /* BLC enable */
1331 /* 0x28: 0x05 Selects RGB format if RGB on */
1332 { 0x28, 0x05 },
1333 { 0x2a, 0x04 }, /* Disable framerate adjust */
1334/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
Hans de Goedeae49c402009-06-14 19:15:07 -03001335 { 0x2d, 0x85 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001336 { 0x33, 0xa0 }, /* Color Processing Parameter */
1337 { 0x34, 0xd2 }, /* Max A/D range */
1338 { 0x38, 0x8b },
1339 { 0x39, 0x40 },
1340
1341 { 0x3c, 0x39 }, /* Enable AEC mode changing */
1342 { 0x3c, 0x3c }, /* Change AEC mode */
1343 { 0x3c, 0x24 }, /* Disable AEC mode changing */
1344
1345 { 0x3d, 0x80 },
1346 /* These next two registers (0x4a, 0x4b) are undocumented.
1347 * They control the color balance */
1348 { 0x4a, 0x80 },
1349 { 0x4b, 0x80 },
1350 { 0x4d, 0xd2 }, /* This reduces noise a bit */
1351 { 0x4e, 0xc1 },
1352 { 0x4f, 0x04 },
1353/* Do 50-53 have any effect? */
1354/* Toggle 0x12[2] off and on here? */
1355};
1356
1357static const struct ov_i2c_regvals norm_6x30[] = {
1358 { 0x12, 0x80 }, /* Reset */
1359 { 0x00, 0x1f }, /* Gain */
1360 { 0x01, 0x99 }, /* Blue gain */
1361 { 0x02, 0x7c }, /* Red gain */
1362 { 0x03, 0xc0 }, /* Saturation */
1363 { 0x05, 0x0a }, /* Contrast */
1364 { 0x06, 0x95 }, /* Brightness */
1365 { 0x07, 0x2d }, /* Sharpness */
1366 { 0x0c, 0x20 },
1367 { 0x0d, 0x20 },
Hans de Goede02ab18b2009-06-14 04:32:04 -03001368 { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001369 { 0x0f, 0x05 },
1370 { 0x10, 0x9a },
1371 { 0x11, 0x00 }, /* Pixel clock = fastest */
1372 { 0x12, 0x24 }, /* Enable AGC and AWB */
1373 { 0x13, 0x21 },
1374 { 0x14, 0x80 },
1375 { 0x15, 0x01 },
1376 { 0x16, 0x03 },
1377 { 0x17, 0x38 },
1378 { 0x18, 0xea },
1379 { 0x19, 0x04 },
1380 { 0x1a, 0x93 },
1381 { 0x1b, 0x00 },
1382 { 0x1e, 0xc4 },
1383 { 0x1f, 0x04 },
1384 { 0x20, 0x20 },
1385 { 0x21, 0x10 },
1386 { 0x22, 0x88 },
1387 { 0x23, 0xc0 }, /* Crystal circuit power level */
1388 { 0x25, 0x9a }, /* Increase AEC black ratio */
1389 { 0x26, 0xb2 }, /* BLC enable */
1390 { 0x27, 0xa2 },
1391 { 0x28, 0x00 },
1392 { 0x29, 0x00 },
1393 { 0x2a, 0x84 }, /* 60 Hz power */
1394 { 0x2b, 0xa8 }, /* 60 Hz power */
1395 { 0x2c, 0xa0 },
1396 { 0x2d, 0x95 }, /* Enable auto-brightness */
1397 { 0x2e, 0x88 },
1398 { 0x33, 0x26 },
1399 { 0x34, 0x03 },
1400 { 0x36, 0x8f },
1401 { 0x37, 0x80 },
1402 { 0x38, 0x83 },
1403 { 0x39, 0x80 },
1404 { 0x3a, 0x0f },
1405 { 0x3b, 0x3c },
1406 { 0x3c, 0x1a },
1407 { 0x3d, 0x80 },
1408 { 0x3e, 0x80 },
1409 { 0x3f, 0x0e },
1410 { 0x40, 0x00 }, /* White bal */
1411 { 0x41, 0x00 }, /* White bal */
1412 { 0x42, 0x80 },
1413 { 0x43, 0x3f }, /* White bal */
1414 { 0x44, 0x80 },
1415 { 0x45, 0x20 },
1416 { 0x46, 0x20 },
1417 { 0x47, 0x80 },
1418 { 0x48, 0x7f },
1419 { 0x49, 0x00 },
1420 { 0x4a, 0x00 },
1421 { 0x4b, 0x80 },
1422 { 0x4c, 0xd0 },
1423 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
1424 { 0x4e, 0x40 },
1425 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
1426 { 0x50, 0xff },
1427 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
1428 { 0x55, 0xff },
1429 { 0x56, 0x12 },
1430 { 0x57, 0x81 },
1431 { 0x58, 0x75 },
1432 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
1433 { 0x5a, 0x2c },
1434 { 0x5b, 0x0f }, /* AWB chrominance levels */
1435 { 0x5c, 0x10 },
1436 { 0x3d, 0x80 },
1437 { 0x27, 0xa6 },
1438 { 0x12, 0x20 }, /* Toggle AWB */
1439 { 0x12, 0x24 },
1440};
1441
1442/* Lawrence Glaister <lg@jfm.bc.ca> reports:
1443 *
1444 * Register 0x0f in the 7610 has the following effects:
1445 *
1446 * 0x85 (AEC method 1): Best overall, good contrast range
1447 * 0x45 (AEC method 2): Very overexposed
1448 * 0xa5 (spec sheet default): Ok, but the black level is
1449 * shifted resulting in loss of contrast
1450 * 0x05 (old driver setting): very overexposed, too much
1451 * contrast
1452 */
1453static const struct ov_i2c_regvals norm_7610[] = {
1454 { 0x10, 0xff },
1455 { 0x16, 0x06 },
1456 { 0x28, 0x24 },
1457 { 0x2b, 0xac },
1458 { 0x12, 0x00 },
1459 { 0x38, 0x81 },
1460 { 0x28, 0x24 }, /* 0c */
1461 { 0x0f, 0x85 }, /* lg's setting */
1462 { 0x15, 0x01 },
1463 { 0x20, 0x1c },
1464 { 0x23, 0x2a },
1465 { 0x24, 0x10 },
1466 { 0x25, 0x8a },
1467 { 0x26, 0xa2 },
1468 { 0x27, 0xc2 },
1469 { 0x2a, 0x04 },
1470 { 0x2c, 0xfe },
1471 { 0x2d, 0x93 },
1472 { 0x30, 0x71 },
1473 { 0x31, 0x60 },
1474 { 0x32, 0x26 },
1475 { 0x33, 0x20 },
1476 { 0x34, 0x48 },
1477 { 0x12, 0x24 },
1478 { 0x11, 0x01 },
1479 { 0x0c, 0x24 },
1480 { 0x0d, 0x24 },
1481};
1482
1483static const struct ov_i2c_regvals norm_7620[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03001484 { 0x12, 0x80 }, /* reset */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001485 { 0x00, 0x00 }, /* gain */
1486 { 0x01, 0x80 }, /* blue gain */
1487 { 0x02, 0x80 }, /* red gain */
1488 { 0x03, 0xc0 }, /* OV7670_REG_VREF */
1489 { 0x06, 0x60 },
1490 { 0x07, 0x00 },
1491 { 0x0c, 0x24 },
1492 { 0x0c, 0x24 },
1493 { 0x0d, 0x24 },
1494 { 0x11, 0x01 },
1495 { 0x12, 0x24 },
1496 { 0x13, 0x01 },
1497 { 0x14, 0x84 },
1498 { 0x15, 0x01 },
1499 { 0x16, 0x03 },
1500 { 0x17, 0x2f },
1501 { 0x18, 0xcf },
1502 { 0x19, 0x06 },
1503 { 0x1a, 0xf5 },
1504 { 0x1b, 0x00 },
1505 { 0x20, 0x18 },
1506 { 0x21, 0x80 },
1507 { 0x22, 0x80 },
1508 { 0x23, 0x00 },
1509 { 0x26, 0xa2 },
1510 { 0x27, 0xea },
Hans de Goedeb282d872009-06-14 19:10:40 -03001511 { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001512 { 0x29, 0x00 },
1513 { 0x2a, 0x10 },
1514 { 0x2b, 0x00 },
1515 { 0x2c, 0x88 },
1516 { 0x2d, 0x91 },
1517 { 0x2e, 0x80 },
1518 { 0x2f, 0x44 },
1519 { 0x60, 0x27 },
1520 { 0x61, 0x02 },
1521 { 0x62, 0x5f },
1522 { 0x63, 0xd5 },
1523 { 0x64, 0x57 },
1524 { 0x65, 0x83 },
1525 { 0x66, 0x55 },
1526 { 0x67, 0x92 },
1527 { 0x68, 0xcf },
1528 { 0x69, 0x76 },
1529 { 0x6a, 0x22 },
1530 { 0x6b, 0x00 },
1531 { 0x6c, 0x02 },
1532 { 0x6d, 0x44 },
1533 { 0x6e, 0x80 },
1534 { 0x6f, 0x1d },
1535 { 0x70, 0x8b },
1536 { 0x71, 0x00 },
1537 { 0x72, 0x14 },
1538 { 0x73, 0x54 },
1539 { 0x74, 0x00 },
1540 { 0x75, 0x8e },
1541 { 0x76, 0x00 },
1542 { 0x77, 0xff },
1543 { 0x78, 0x80 },
1544 { 0x79, 0x80 },
1545 { 0x7a, 0x80 },
1546 { 0x7b, 0xe2 },
1547 { 0x7c, 0x00 },
1548};
1549
1550/* 7640 and 7648. The defaults should be OK for most registers. */
1551static const struct ov_i2c_regvals norm_7640[] = {
1552 { 0x12, 0x80 },
1553 { 0x12, 0x14 },
1554};
1555
1556/* 7670. Defaults taken from OmniVision provided data,
1557* as provided by Jonathan Corbet of OLPC */
1558static const struct ov_i2c_regvals norm_7670[] = {
1559 { OV7670_REG_COM7, OV7670_COM7_RESET },
1560 { OV7670_REG_TSLB, 0x04 }, /* OV */
1561 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
1562 { OV7670_REG_CLKRC, 0x01 },
1563/*
1564 * Set the hardware window. These values from OV don't entirely
1565 * make sense - hstop is less than hstart. But they work...
1566 */
1567 { OV7670_REG_HSTART, 0x13 },
1568 { OV7670_REG_HSTOP, 0x01 },
1569 { OV7670_REG_HREF, 0xb6 },
1570 { OV7670_REG_VSTART, 0x02 },
1571 { OV7670_REG_VSTOP, 0x7a },
1572 { OV7670_REG_VREF, 0x0a },
1573
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001574 { OV7670_REG_COM3, 0x00 },
1575 { OV7670_REG_COM14, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001576/* Mystery scaling numbers */
1577 { 0x70, 0x3a },
1578 { 0x71, 0x35 },
1579 { 0x72, 0x11 },
1580 { 0x73, 0xf0 },
1581 { 0xa2, 0x02 },
1582/* { OV7670_REG_COM10, 0x0 }, */
1583
1584/* Gamma curve values */
1585 { 0x7a, 0x20 },
1586 { 0x7b, 0x10 },
1587 { 0x7c, 0x1e },
1588 { 0x7d, 0x35 },
1589 { 0x7e, 0x5a },
1590 { 0x7f, 0x69 },
1591 { 0x80, 0x76 },
1592 { 0x81, 0x80 },
1593 { 0x82, 0x88 },
1594 { 0x83, 0x8f },
1595 { 0x84, 0x96 },
1596 { 0x85, 0xa3 },
1597 { 0x86, 0xaf },
1598 { 0x87, 0xc4 },
1599 { 0x88, 0xd7 },
1600 { 0x89, 0xe8 },
1601
1602/* AGC and AEC parameters. Note we start by disabling those features,
1603 then turn them only after tweaking the values. */
1604 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
1605 | OV7670_COM8_AECSTEP
1606 | OV7670_COM8_BFILT },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001607 { OV7670_REG_GAIN, 0x00 },
1608 { OV7670_REG_AECH, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001609 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
1610 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
1611 { OV7670_REG_BD50MAX, 0x05 },
1612 { OV7670_REG_BD60MAX, 0x07 },
1613 { OV7670_REG_AEW, 0x95 },
1614 { OV7670_REG_AEB, 0x33 },
1615 { OV7670_REG_VPT, 0xe3 },
1616 { OV7670_REG_HAECC1, 0x78 },
1617 { OV7670_REG_HAECC2, 0x68 },
1618 { 0xa1, 0x03 }, /* magic */
1619 { OV7670_REG_HAECC3, 0xd8 },
1620 { OV7670_REG_HAECC4, 0xd8 },
1621 { OV7670_REG_HAECC5, 0xf0 },
1622 { OV7670_REG_HAECC6, 0x90 },
1623 { OV7670_REG_HAECC7, 0x94 },
1624 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
1625 | OV7670_COM8_AECSTEP
1626 | OV7670_COM8_BFILT
1627 | OV7670_COM8_AGC
1628 | OV7670_COM8_AEC },
1629
1630/* Almost all of these are magic "reserved" values. */
1631 { OV7670_REG_COM5, 0x61 },
1632 { OV7670_REG_COM6, 0x4b },
1633 { 0x16, 0x02 },
1634 { OV7670_REG_MVFP, 0x07 },
1635 { 0x21, 0x02 },
1636 { 0x22, 0x91 },
1637 { 0x29, 0x07 },
1638 { 0x33, 0x0b },
1639 { 0x35, 0x0b },
1640 { 0x37, 0x1d },
1641 { 0x38, 0x71 },
1642 { 0x39, 0x2a },
1643 { OV7670_REG_COM12, 0x78 },
1644 { 0x4d, 0x40 },
1645 { 0x4e, 0x20 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001646 { OV7670_REG_GFIX, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001647 { 0x6b, 0x4a },
1648 { 0x74, 0x10 },
1649 { 0x8d, 0x4f },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001650 { 0x8e, 0x00 },
1651 { 0x8f, 0x00 },
1652 { 0x90, 0x00 },
1653 { 0x91, 0x00 },
1654 { 0x96, 0x00 },
1655 { 0x9a, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001656 { 0xb0, 0x84 },
1657 { 0xb1, 0x0c },
1658 { 0xb2, 0x0e },
1659 { 0xb3, 0x82 },
1660 { 0xb8, 0x0a },
1661
1662/* More reserved magic, some of which tweaks white balance */
1663 { 0x43, 0x0a },
1664 { 0x44, 0xf0 },
1665 { 0x45, 0x34 },
1666 { 0x46, 0x58 },
1667 { 0x47, 0x28 },
1668 { 0x48, 0x3a },
1669 { 0x59, 0x88 },
1670 { 0x5a, 0x88 },
1671 { 0x5b, 0x44 },
1672 { 0x5c, 0x67 },
1673 { 0x5d, 0x49 },
1674 { 0x5e, 0x0e },
1675 { 0x6c, 0x0a },
1676 { 0x6d, 0x55 },
1677 { 0x6e, 0x11 },
1678 { 0x6f, 0x9f },
1679 /* "9e for advance AWB" */
1680 { 0x6a, 0x40 },
1681 { OV7670_REG_BLUE, 0x40 },
1682 { OV7670_REG_RED, 0x60 },
1683 { OV7670_REG_COM8, OV7670_COM8_FASTAEC
1684 | OV7670_COM8_AECSTEP
1685 | OV7670_COM8_BFILT
1686 | OV7670_COM8_AGC
1687 | OV7670_COM8_AEC
1688 | OV7670_COM8_AWB },
1689
1690/* Matrix coefficients */
1691 { 0x4f, 0x80 },
1692 { 0x50, 0x80 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001693 { 0x51, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001694 { 0x52, 0x22 },
1695 { 0x53, 0x5e },
1696 { 0x54, 0x80 },
1697 { 0x58, 0x9e },
1698
1699 { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001700 { OV7670_REG_EDGE, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001701 { 0x75, 0x05 },
1702 { 0x76, 0xe1 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001703 { 0x4c, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001704 { 0x77, 0x01 },
1705 { OV7670_REG_COM13, OV7670_COM13_GAMMA
1706 | OV7670_COM13_UVSAT
1707 | 2}, /* was 3 */
1708 { 0x4b, 0x09 },
1709 { 0xc9, 0x60 },
1710 { OV7670_REG_COM16, 0x38 },
1711 { 0x56, 0x40 },
1712
1713 { 0x34, 0x11 },
1714 { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
1715 { 0xa4, 0x88 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001716 { 0x96, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001717 { 0x97, 0x30 },
1718 { 0x98, 0x20 },
1719 { 0x99, 0x30 },
1720 { 0x9a, 0x84 },
1721 { 0x9b, 0x29 },
1722 { 0x9c, 0x03 },
1723 { 0x9d, 0x4c },
1724 { 0x9e, 0x3f },
1725 { 0x78, 0x04 },
1726
1727/* Extra-weird stuff. Some sort of multiplexor register */
1728 { 0x79, 0x01 },
1729 { 0xc8, 0xf0 },
1730 { 0x79, 0x0f },
1731 { 0xc8, 0x00 },
1732 { 0x79, 0x10 },
1733 { 0xc8, 0x7e },
1734 { 0x79, 0x0a },
1735 { 0xc8, 0x80 },
1736 { 0x79, 0x0b },
1737 { 0xc8, 0x01 },
1738 { 0x79, 0x0c },
1739 { 0xc8, 0x0f },
1740 { 0x79, 0x0d },
1741 { 0xc8, 0x20 },
1742 { 0x79, 0x09 },
1743 { 0xc8, 0x80 },
1744 { 0x79, 0x02 },
1745 { 0xc8, 0xc0 },
1746 { 0x79, 0x03 },
1747 { 0xc8, 0x40 },
1748 { 0x79, 0x05 },
1749 { 0xc8, 0x30 },
1750 { 0x79, 0x26 },
1751};
1752
1753static const struct ov_i2c_regvals norm_8610[] = {
1754 { 0x12, 0x80 },
1755 { 0x00, 0x00 },
1756 { 0x01, 0x80 },
1757 { 0x02, 0x80 },
1758 { 0x03, 0xc0 },
1759 { 0x04, 0x30 },
1760 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
1761 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
1762 { 0x0a, 0x86 },
1763 { 0x0b, 0xb0 },
1764 { 0x0c, 0x20 },
1765 { 0x0d, 0x20 },
1766 { 0x11, 0x01 },
1767 { 0x12, 0x25 },
1768 { 0x13, 0x01 },
1769 { 0x14, 0x04 },
1770 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
1771 { 0x16, 0x03 },
1772 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
1773 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
1774 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
1775 { 0x1a, 0xf5 },
1776 { 0x1b, 0x00 },
1777 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
1778 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
1779 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
1780 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
1781 { 0x26, 0xa2 },
1782 { 0x27, 0xea },
1783 { 0x28, 0x00 },
1784 { 0x29, 0x00 },
1785 { 0x2a, 0x80 },
1786 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
1787 { 0x2c, 0xac },
1788 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
1789 { 0x2e, 0x80 },
1790 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
1791 { 0x4c, 0x00 },
1792 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
1793 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
1794 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
1795 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
1796 { 0x63, 0xff },
1797 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
1798 * maybe thats wrong */
1799 { 0x65, 0x00 },
1800 { 0x66, 0x55 },
1801 { 0x67, 0xb0 },
1802 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
1803 { 0x69, 0x02 },
1804 { 0x6a, 0x22 },
1805 { 0x6b, 0x00 },
1806 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
1807 * deleting bit7 colors the first images red */
1808 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
1809 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
1810 { 0x6f, 0x01 },
1811 { 0x70, 0x8b },
1812 { 0x71, 0x00 },
1813 { 0x72, 0x14 },
1814 { 0x73, 0x54 },
1815 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
1816 { 0x75, 0x0e },
1817 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
1818 { 0x77, 0xff },
1819 { 0x78, 0x80 },
1820 { 0x79, 0x80 },
1821 { 0x7a, 0x80 },
1822 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
1823 { 0x7c, 0x00 },
1824 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
1825 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
1826 { 0x7f, 0xfb },
1827 { 0x80, 0x28 },
1828 { 0x81, 0x00 },
1829 { 0x82, 0x23 },
1830 { 0x83, 0x0b },
1831 { 0x84, 0x00 },
1832 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
1833 { 0x86, 0xc9 },
1834 { 0x87, 0x00 },
1835 { 0x88, 0x00 },
1836 { 0x89, 0x01 },
1837 { 0x12, 0x20 },
1838 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
1839};
1840
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001841static unsigned char ov7670_abs_to_sm(unsigned char v)
1842{
1843 if (v > 127)
1844 return v & 0x7f;
1845 return (128 - v) | 0x80;
1846}
1847
1848/* Write a OV519 register */
Hans de Goedea511ba92009-10-16 07:13:07 -03001849static int reg_w(struct sd *sd, __u16 index, __u16 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001850{
Hans de Goedea511ba92009-10-16 07:13:07 -03001851 int ret, req = 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001852
1853 switch (sd->bridge) {
1854 case BRIDGE_OV511:
1855 case BRIDGE_OV511PLUS:
1856 req = 2;
1857 break;
1858 case BRIDGE_OVFX2:
Hans de Goedea511ba92009-10-16 07:13:07 -03001859 req = 0x0a;
1860 /* fall through */
1861 case BRIDGE_W9968CF:
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001862 ret = usb_control_msg(sd->gspca_dev.dev,
1863 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goedea511ba92009-10-16 07:13:07 -03001864 req,
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001865 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Hans de Goedea511ba92009-10-16 07:13:07 -03001866 value, index, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001867 goto leave;
1868 default:
1869 req = 1;
1870 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001871
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001872 sd->gspca_dev.usb_buf[0] = value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001873 ret = usb_control_msg(sd->gspca_dev.dev,
1874 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03001875 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001876 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1877 0, index,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001878 sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001879leave:
Hans de Goedea511ba92009-10-16 07:13:07 -03001880 if (ret < 0) {
1881 PDEBUG(D_ERR, "Write reg 0x%04x -> [0x%02x] failed",
1882 value, index);
1883 return ret;
1884 }
1885
1886 PDEBUG(D_USBO, "Write reg 0x%04x -> [0x%02x]", value, index);
1887 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001888}
1889
Hans de Goedea511ba92009-10-16 07:13:07 -03001890/* Read from a OV519 register, note not valid for the w9968cf!! */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001891/* returns: negative is error, pos or zero is data */
1892static int reg_r(struct sd *sd, __u16 index)
1893{
1894 int ret;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03001895 int req;
1896
1897 switch (sd->bridge) {
1898 case BRIDGE_OV511:
1899 case BRIDGE_OV511PLUS:
1900 req = 3;
1901 break;
1902 case BRIDGE_OVFX2:
1903 req = 0x0b;
1904 break;
1905 default:
1906 req = 1;
1907 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001908
1909 ret = usb_control_msg(sd->gspca_dev.dev,
1910 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03001911 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001912 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001913 0, index, sd->gspca_dev.usb_buf, 1, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001914
Hans de Goedea511ba92009-10-16 07:13:07 -03001915 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001916 ret = sd->gspca_dev.usb_buf[0];
Hans de Goedea511ba92009-10-16 07:13:07 -03001917 PDEBUG(D_USBI, "Read reg [0x%02X] -> 0x%04X", index, ret);
1918 } else
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001919 PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
Hans de Goedea511ba92009-10-16 07:13:07 -03001920
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001921 return ret;
1922}
1923
1924/* Read 8 values from a OV519 register */
1925static int reg_r8(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001926 __u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001927{
1928 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001929
1930 ret = usb_control_msg(sd->gspca_dev.dev,
1931 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
1932 1, /* REQ_IO */
1933 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001934 0, index, sd->gspca_dev.usb_buf, 8, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001935
1936 if (ret >= 0)
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001937 ret = sd->gspca_dev.usb_buf[0];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001938 else
1939 PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
Hans de Goedea511ba92009-10-16 07:13:07 -03001940
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001941 return ret;
1942}
1943
1944/*
1945 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
1946 * the same position as 1's in "mask" are cleared and set to "value". Bits
1947 * that are in the same position as 0's in "mask" are preserved, regardless
1948 * of their respective state in "value".
1949 */
1950static int reg_w_mask(struct sd *sd,
1951 __u16 index,
1952 __u8 value,
1953 __u8 mask)
1954{
1955 int ret;
1956 __u8 oldval;
1957
1958 if (mask != 0xff) {
1959 value &= mask; /* Enforce mask on value */
1960 ret = reg_r(sd, index);
1961 if (ret < 0)
1962 return ret;
1963
1964 oldval = ret & ~mask; /* Clear the masked bits */
1965 value |= oldval; /* Set the desired bits */
1966 }
1967 return reg_w(sd, index, value);
1968}
1969
1970/*
Hans de Goede49809d62009-06-07 12:10:39 -03001971 * Writes multiple (n) byte value to a single register. Only valid with certain
1972 * registers (0x30 and 0xc4 - 0xce).
1973 */
1974static int ov518_reg_w32(struct sd *sd, __u16 index, u32 value, int n)
1975{
1976 int ret;
1977
1978 *((u32 *)sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
1979
1980 ret = usb_control_msg(sd->gspca_dev.dev,
1981 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
1982 1 /* REG_IO */,
1983 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1984 0, index,
1985 sd->gspca_dev.usb_buf, n, 500);
Hans de Goedea511ba92009-10-16 07:13:07 -03001986 if (ret < 0) {
Hans de Goede49809d62009-06-07 12:10:39 -03001987 PDEBUG(D_ERR, "Write reg32 [%02x] %08x failed", index, value);
Hans de Goedea511ba92009-10-16 07:13:07 -03001988 return ret;
1989 }
1990
1991 return 0;
Hans de Goede49809d62009-06-07 12:10:39 -03001992}
1993
Hans de Goede1876bb92009-06-14 06:45:50 -03001994static int ov511_i2c_w(struct sd *sd, __u8 reg, __u8 value)
1995{
1996 int rc, retries;
1997
1998 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
1999
2000 /* Three byte write cycle */
2001 for (retries = 6; ; ) {
2002 /* Select camera register */
2003 rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
2004 if (rc < 0)
2005 return rc;
2006
2007 /* Write "value" to I2C data port of OV511 */
2008 rc = reg_w(sd, R51x_I2C_DATA, value);
2009 if (rc < 0)
2010 return rc;
2011
2012 /* Initiate 3-byte write cycle */
2013 rc = reg_w(sd, R511_I2C_CTL, 0x01);
2014 if (rc < 0)
2015 return rc;
2016
2017 do
2018 rc = reg_r(sd, R511_I2C_CTL);
2019 while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
2020
2021 if (rc < 0)
2022 return rc;
2023
2024 if ((rc & 2) == 0) /* Ack? */
2025 break;
2026 if (--retries < 0) {
2027 PDEBUG(D_USBO, "i2c write retries exhausted");
2028 return -1;
2029 }
2030 }
2031
2032 return 0;
2033}
2034
2035static int ov511_i2c_r(struct sd *sd, __u8 reg)
2036{
2037 int rc, value, retries;
2038
2039 /* Two byte write cycle */
2040 for (retries = 6; ; ) {
2041 /* Select camera register */
2042 rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
2043 if (rc < 0)
2044 return rc;
2045
2046 /* Initiate 2-byte write cycle */
2047 rc = reg_w(sd, R511_I2C_CTL, 0x03);
2048 if (rc < 0)
2049 return rc;
2050
2051 do
2052 rc = reg_r(sd, R511_I2C_CTL);
2053 while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
2054
2055 if (rc < 0)
2056 return rc;
2057
2058 if ((rc & 2) == 0) /* Ack? */
2059 break;
2060
2061 /* I2C abort */
2062 reg_w(sd, R511_I2C_CTL, 0x10);
2063
2064 if (--retries < 0) {
2065 PDEBUG(D_USBI, "i2c write retries exhausted");
2066 return -1;
2067 }
2068 }
2069
2070 /* Two byte read cycle */
2071 for (retries = 6; ; ) {
2072 /* Initiate 2-byte read cycle */
2073 rc = reg_w(sd, R511_I2C_CTL, 0x05);
2074 if (rc < 0)
2075 return rc;
2076
2077 do
2078 rc = reg_r(sd, R511_I2C_CTL);
2079 while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
2080
2081 if (rc < 0)
2082 return rc;
2083
2084 if ((rc & 2) == 0) /* Ack? */
2085 break;
2086
2087 /* I2C abort */
2088 rc = reg_w(sd, R511_I2C_CTL, 0x10);
2089 if (rc < 0)
2090 return rc;
2091
2092 if (--retries < 0) {
2093 PDEBUG(D_USBI, "i2c read retries exhausted");
2094 return -1;
2095 }
2096 }
2097
2098 value = reg_r(sd, R51x_I2C_DATA);
2099
2100 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
2101
2102 /* This is needed to make i2c_w() work */
2103 rc = reg_w(sd, R511_I2C_CTL, 0x05);
2104 if (rc < 0)
2105 return rc;
2106
2107 return value;
2108}
Hans de Goede49809d62009-06-07 12:10:39 -03002109
2110/*
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002111 * The OV518 I2C I/O procedure is different, hence, this function.
2112 * This is normally only called from i2c_w(). Note that this function
2113 * always succeeds regardless of whether the sensor is present and working.
2114 */
Hans de Goede1876bb92009-06-14 06:45:50 -03002115static int ov518_i2c_w(struct sd *sd,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002116 __u8 reg,
2117 __u8 value)
2118{
2119 int rc;
2120
2121 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2122
2123 /* Select camera register */
2124 rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
2125 if (rc < 0)
2126 return rc;
2127
2128 /* Write "value" to I2C data port of OV511 */
2129 rc = reg_w(sd, R51x_I2C_DATA, value);
2130 if (rc < 0)
2131 return rc;
2132
2133 /* Initiate 3-byte write cycle */
2134 rc = reg_w(sd, R518_I2C_CTL, 0x01);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002135 if (rc < 0)
2136 return rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002137
2138 /* wait for write complete */
2139 msleep(4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002140 return reg_r8(sd, R518_I2C_CTL);
2141}
2142
2143/*
2144 * returns: negative is error, pos or zero is data
2145 *
2146 * The OV518 I2C I/O procedure is different, hence, this function.
2147 * This is normally only called from i2c_r(). Note that this function
2148 * always succeeds regardless of whether the sensor is present and working.
2149 */
Hans de Goede1876bb92009-06-14 06:45:50 -03002150static int ov518_i2c_r(struct sd *sd, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002151{
2152 int rc, value;
2153
2154 /* Select camera register */
2155 rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
2156 if (rc < 0)
2157 return rc;
2158
2159 /* Initiate 2-byte write cycle */
2160 rc = reg_w(sd, R518_I2C_CTL, 0x03);
2161 if (rc < 0)
2162 return rc;
2163
2164 /* Initiate 2-byte read cycle */
2165 rc = reg_w(sd, R518_I2C_CTL, 0x05);
2166 if (rc < 0)
2167 return rc;
2168 value = reg_r(sd, R51x_I2C_DATA);
2169 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
2170 return value;
2171}
2172
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002173static int ovfx2_i2c_w(struct sd *sd, __u8 reg, __u8 value)
2174{
2175 int ret;
2176
2177 ret = usb_control_msg(sd->gspca_dev.dev,
2178 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2179 0x02,
2180 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2181 (__u16)value, (__u16)reg, NULL, 0, 500);
2182
Hans de Goedea511ba92009-10-16 07:13:07 -03002183 if (ret < 0) {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002184 PDEBUG(D_ERR, "i2c 0x%02x -> [0x%02x] failed", value, reg);
Hans de Goedea511ba92009-10-16 07:13:07 -03002185 return ret;
2186 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002187
Hans de Goedea511ba92009-10-16 07:13:07 -03002188 PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
2189 return 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002190}
2191
2192static int ovfx2_i2c_r(struct sd *sd, __u8 reg)
2193{
2194 int ret;
2195
2196 ret = usb_control_msg(sd->gspca_dev.dev,
2197 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2198 0x03,
2199 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2200 0, (__u16)reg, sd->gspca_dev.usb_buf, 1, 500);
2201
2202 if (ret >= 0) {
2203 ret = sd->gspca_dev.usb_buf[0];
2204 PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, ret);
2205 } else
2206 PDEBUG(D_ERR, "i2c read [0x%02x] failed", reg);
2207
2208 return ret;
2209}
2210
Hans de Goede1876bb92009-06-14 06:45:50 -03002211static int i2c_w(struct sd *sd, __u8 reg, __u8 value)
2212{
2213 switch (sd->bridge) {
2214 case BRIDGE_OV511:
2215 case BRIDGE_OV511PLUS:
2216 return ov511_i2c_w(sd, reg, value);
2217 case BRIDGE_OV518:
2218 case BRIDGE_OV518PLUS:
2219 case BRIDGE_OV519:
2220 return ov518_i2c_w(sd, reg, value);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002221 case BRIDGE_OVFX2:
2222 return ovfx2_i2c_w(sd, reg, value);
Hans de Goedea511ba92009-10-16 07:13:07 -03002223 case BRIDGE_W9968CF:
2224 return w9968cf_i2c_w(sd, reg, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002225 }
2226 return -1; /* Should never happen */
2227}
2228
2229static int i2c_r(struct sd *sd, __u8 reg)
2230{
2231 switch (sd->bridge) {
2232 case BRIDGE_OV511:
2233 case BRIDGE_OV511PLUS:
2234 return ov511_i2c_r(sd, reg);
2235 case BRIDGE_OV518:
2236 case BRIDGE_OV518PLUS:
2237 case BRIDGE_OV519:
2238 return ov518_i2c_r(sd, reg);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002239 case BRIDGE_OVFX2:
2240 return ovfx2_i2c_r(sd, reg);
Hans de Goedea511ba92009-10-16 07:13:07 -03002241 case BRIDGE_W9968CF:
2242 return w9968cf_i2c_r(sd, reg);
Hans de Goede1876bb92009-06-14 06:45:50 -03002243 }
2244 return -1; /* Should never happen */
2245}
2246
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002247/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
2248 * the same position as 1's in "mask" are cleared and set to "value". Bits
2249 * that are in the same position as 0's in "mask" are preserved, regardless
2250 * of their respective state in "value".
2251 */
2252static int i2c_w_mask(struct sd *sd,
2253 __u8 reg,
2254 __u8 value,
2255 __u8 mask)
2256{
2257 int rc;
2258 __u8 oldval;
2259
2260 value &= mask; /* Enforce mask on value */
2261 rc = i2c_r(sd, reg);
2262 if (rc < 0)
2263 return rc;
2264 oldval = rc & ~mask; /* Clear the masked bits */
2265 value |= oldval; /* Set the desired bits */
2266 return i2c_w(sd, reg, value);
2267}
2268
2269/* Temporarily stops OV511 from functioning. Must do this before changing
2270 * registers while the camera is streaming */
2271static inline int ov51x_stop(struct sd *sd)
2272{
Hans de Goedea511ba92009-10-16 07:13:07 -03002273 int ret;
2274
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002275 PDEBUG(D_STREAM, "stopping");
2276 sd->stopped = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03002277 switch (sd->bridge) {
2278 case BRIDGE_OV511:
2279 case BRIDGE_OV511PLUS:
2280 return reg_w(sd, R51x_SYS_RESET, 0x3d);
2281 case BRIDGE_OV518:
2282 case BRIDGE_OV518PLUS:
2283 return reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
2284 case BRIDGE_OV519:
2285 return reg_w(sd, OV519_SYS_RESET1, 0x0f);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002286 case BRIDGE_OVFX2:
2287 return reg_w_mask(sd, 0x0f, 0x00, 0x02);
Hans de Goedea511ba92009-10-16 07:13:07 -03002288 case BRIDGE_W9968CF:
2289 ret = reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
2290 ret += reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
2291 ret += reg_w(sd, 0x16, 0x0000); /* stop video capture */
2292 return ret;
Hans de Goede49809d62009-06-07 12:10:39 -03002293 }
2294
2295 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002296}
2297
2298/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
2299 * actually stopped (for performance). */
2300static inline int ov51x_restart(struct sd *sd)
2301{
Hans de Goede49809d62009-06-07 12:10:39 -03002302 int rc;
2303
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002304 PDEBUG(D_STREAM, "restarting");
2305 if (!sd->stopped)
2306 return 0;
2307 sd->stopped = 0;
2308
2309 /* Reinitialize the stream */
Hans de Goede49809d62009-06-07 12:10:39 -03002310 switch (sd->bridge) {
2311 case BRIDGE_OV511:
2312 case BRIDGE_OV511PLUS:
2313 return reg_w(sd, R51x_SYS_RESET, 0x00);
2314 case BRIDGE_OV518:
2315 case BRIDGE_OV518PLUS:
2316 rc = reg_w(sd, 0x2f, 0x80);
2317 if (rc < 0)
2318 return rc;
2319 return reg_w(sd, R51x_SYS_RESET, 0x00);
2320 case BRIDGE_OV519:
2321 return reg_w(sd, OV519_SYS_RESET1, 0x00);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002322 case BRIDGE_OVFX2:
2323 return reg_w_mask(sd, 0x0f, 0x02, 0x02);
Hans de Goedea511ba92009-10-16 07:13:07 -03002324 case BRIDGE_W9968CF:
2325 return reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
Hans de Goede49809d62009-06-07 12:10:39 -03002326 }
2327
2328 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002329}
2330
Hans de Goede229bb7d2009-10-11 07:41:46 -03002331static int ov51x_set_slave_ids(struct sd *sd, __u8 slave);
2332
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002333/* This does an initial reset of an OmniVision sensor and ensures that I2C
2334 * is synchronized. Returns <0 on failure.
2335 */
Hans de Goede229bb7d2009-10-11 07:41:46 -03002336static int init_ov_sensor(struct sd *sd, __u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002337{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002338 int i;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002339
Hans de Goede229bb7d2009-10-11 07:41:46 -03002340 if (ov51x_set_slave_ids(sd, slave) < 0)
2341 return -EIO;
2342
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002343 /* Reset the sensor */
2344 if (i2c_w(sd, 0x12, 0x80) < 0)
2345 return -EIO;
2346
2347 /* Wait for it to initialize */
2348 msleep(150);
2349
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002350 for (i = 0; i < i2c_detect_tries; i++) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002351 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
2352 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002353 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
2354 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002355 }
2356
2357 /* Reset the sensor */
2358 if (i2c_w(sd, 0x12, 0x80) < 0)
2359 return -EIO;
2360 /* Wait for it to initialize */
2361 msleep(150);
2362 /* Dummy read to sync I2C */
2363 if (i2c_r(sd, 0x00) < 0)
2364 return -EIO;
2365 }
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002366 return -EIO;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002367}
2368
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002369/* Set the read and write slave IDs. The "slave" argument is the write slave,
2370 * and the read slave will be set to (slave + 1).
2371 * This should not be called from outside the i2c I/O functions.
2372 * Sets I2C read and write slave IDs. Returns <0 for error
2373 */
2374static int ov51x_set_slave_ids(struct sd *sd,
2375 __u8 slave)
2376{
2377 int rc;
2378
Hans de Goedea511ba92009-10-16 07:13:07 -03002379 switch (sd->bridge) {
2380 case BRIDGE_OVFX2:
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002381 return reg_w(sd, OVFX2_I2C_ADDR, slave);
Hans de Goedea511ba92009-10-16 07:13:07 -03002382 case BRIDGE_W9968CF:
2383 sd->sensor_addr = slave;
2384 return 0;
2385 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002386
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002387 rc = reg_w(sd, R51x_I2C_W_SID, slave);
2388 if (rc < 0)
2389 return rc;
2390 return reg_w(sd, R51x_I2C_R_SID, slave + 1);
2391}
2392
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002393static int write_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002394 const struct ov_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002395 int n)
2396{
2397 int rc;
2398
2399 while (--n >= 0) {
2400 rc = reg_w(sd, regvals->reg, regvals->val);
2401 if (rc < 0)
2402 return rc;
2403 regvals++;
2404 }
2405 return 0;
2406}
2407
2408static int write_i2c_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002409 const struct ov_i2c_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002410 int n)
2411{
2412 int rc;
2413
2414 while (--n >= 0) {
2415 rc = i2c_w(sd, regvals->reg, regvals->val);
2416 if (rc < 0)
2417 return rc;
2418 regvals++;
2419 }
2420 return 0;
2421}
2422
2423/****************************************************************************
2424 *
2425 * OV511 and sensor configuration
2426 *
2427 ***************************************************************************/
2428
Hans de Goede635118d2009-10-11 09:49:03 -03002429/* This initializes the OV2x10 / OV3610 / OV3620 */
2430static int ov_hires_configure(struct sd *sd)
2431{
2432 int high, low;
2433
2434 if (sd->bridge != BRIDGE_OVFX2) {
2435 PDEBUG(D_ERR, "error hires sensors only supported with ovfx2");
2436 return -1;
2437 }
2438
2439 PDEBUG(D_PROBE, "starting ov hires configuration");
2440
2441 /* Detect sensor (sub)type */
2442 high = i2c_r(sd, 0x0a);
2443 low = i2c_r(sd, 0x0b);
2444 /* info("%x, %x", high, low); */
2445 if (high == 0x96 && low == 0x40) {
2446 PDEBUG(D_PROBE, "Sensor is an OV2610");
2447 sd->sensor = SEN_OV2610;
2448 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2449 PDEBUG(D_PROBE, "Sensor is an OV3610");
2450 sd->sensor = SEN_OV3610;
2451 } else {
2452 PDEBUG(D_ERR, "Error unknown sensor type: 0x%02x%02x",
2453 high, low);
2454 return -1;
2455 }
2456
2457 /* Set sensor-specific vars */
2458 return 0;
2459}
2460
2461
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002462/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
2463 * the same register settings as the OV8610, since they are very similar.
2464 */
2465static int ov8xx0_configure(struct sd *sd)
2466{
2467 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002468
2469 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
2470
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002471 /* Detect sensor (sub)type */
2472 rc = i2c_r(sd, OV7610_REG_COM_I);
2473 if (rc < 0) {
2474 PDEBUG(D_ERR, "Error detecting sensor type");
2475 return -1;
2476 }
2477 if ((rc & 3) == 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002478 sd->sensor = SEN_OV8610;
2479 } else {
2480 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
2481 return -1;
2482 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002483
2484 /* Set sensor-specific vars */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002485 return 0;
2486}
2487
2488/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
2489 * the same register settings as the OV7610, since they are very similar.
2490 */
2491static int ov7xx0_configure(struct sd *sd)
2492{
2493 int rc, high, low;
2494
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002495
2496 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
2497
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002498 /* Detect sensor (sub)type */
2499 rc = i2c_r(sd, OV7610_REG_COM_I);
2500
2501 /* add OV7670 here
2502 * it appears to be wrongly detected as a 7610 by default */
2503 if (rc < 0) {
2504 PDEBUG(D_ERR, "Error detecting sensor type");
2505 return -1;
2506 }
2507 if ((rc & 3) == 3) {
2508 /* quick hack to make OV7670s work */
2509 high = i2c_r(sd, 0x0a);
2510 low = i2c_r(sd, 0x0b);
2511 /* info("%x, %x", high, low); */
2512 if (high == 0x76 && low == 0x73) {
2513 PDEBUG(D_PROBE, "Sensor is an OV7670");
2514 sd->sensor = SEN_OV7670;
2515 } else {
2516 PDEBUG(D_PROBE, "Sensor is an OV7610");
2517 sd->sensor = SEN_OV7610;
2518 }
2519 } else if ((rc & 3) == 1) {
2520 /* I don't know what's different about the 76BE yet. */
Hans de Goedeb282d872009-06-14 19:10:40 -03002521 if (i2c_r(sd, 0x15) & 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002522 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
Hans de Goedeb282d872009-06-14 19:10:40 -03002523 sd->sensor = SEN_OV7620;
2524 } else {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002525 PDEBUG(D_PROBE, "Sensor is an OV76BE");
Hans de Goedeb282d872009-06-14 19:10:40 -03002526 sd->sensor = SEN_OV76BE;
2527 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002528 } else if ((rc & 3) == 0) {
2529 /* try to read product id registers */
2530 high = i2c_r(sd, 0x0a);
2531 if (high < 0) {
2532 PDEBUG(D_ERR, "Error detecting camera chip PID");
2533 return high;
2534 }
2535 low = i2c_r(sd, 0x0b);
2536 if (low < 0) {
2537 PDEBUG(D_ERR, "Error detecting camera chip VER");
2538 return low;
2539 }
2540 if (high == 0x76) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002541 switch (low) {
2542 case 0x30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002543 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002544 PDEBUG(D_ERR,
2545 "7630 is not supported by this driver");
2546 return -1;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002547 case 0x40:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002548 PDEBUG(D_PROBE, "Sensor is an OV7645");
2549 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002550 break;
2551 case 0x45:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002552 PDEBUG(D_PROBE, "Sensor is an OV7645B");
2553 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002554 break;
2555 case 0x48:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002556 PDEBUG(D_PROBE, "Sensor is an OV7648");
2557 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002558 break;
2559 default:
2560 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002561 return -1;
2562 }
2563 } else {
2564 PDEBUG(D_PROBE, "Sensor is an OV7620");
2565 sd->sensor = SEN_OV7620;
2566 }
2567 } else {
2568 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
2569 return -1;
2570 }
2571
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002572 /* Set sensor-specific vars */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002573 return 0;
2574}
2575
2576/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
2577static int ov6xx0_configure(struct sd *sd)
2578{
2579 int rc;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002580 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002581
2582 /* Detect sensor (sub)type */
2583 rc = i2c_r(sd, OV7610_REG_COM_I);
2584 if (rc < 0) {
2585 PDEBUG(D_ERR, "Error detecting sensor type");
2586 return -1;
2587 }
2588
2589 /* Ugh. The first two bits are the version bits, but
2590 * the entire register value must be used. I guess OVT
2591 * underestimated how many variants they would make. */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002592 switch (rc) {
2593 case 0x00:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002594 sd->sensor = SEN_OV6630;
2595 PDEBUG(D_ERR,
2596 "WARNING: Sensor is an OV66308. Your camera may have");
2597 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002598 break;
2599 case 0x01:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002600 sd->sensor = SEN_OV6620;
Hans de Goede7d971372009-06-14 05:28:17 -03002601 PDEBUG(D_PROBE, "Sensor is an OV6620");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002602 break;
2603 case 0x02:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002604 sd->sensor = SEN_OV6630;
2605 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002606 break;
2607 case 0x03:
Hans de Goede7d971372009-06-14 05:28:17 -03002608 sd->sensor = SEN_OV66308AF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002609 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002610 break;
2611 case 0x90:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002612 sd->sensor = SEN_OV6630;
2613 PDEBUG(D_ERR,
2614 "WARNING: Sensor is an OV66307. Your camera may have");
2615 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002616 break;
2617 default:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002618 PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc);
2619 return -1;
2620 }
2621
2622 /* Set sensor-specific vars */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002623 sd->sif = 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002624
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002625 return 0;
2626}
2627
2628/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
2629static void ov51x_led_control(struct sd *sd, int on)
2630{
Hans de Goede9e4d8252009-06-14 06:25:06 -03002631 if (sd->invert_led)
2632 on = !on;
2633
Hans de Goede49809d62009-06-07 12:10:39 -03002634 switch (sd->bridge) {
2635 /* OV511 has no LED control */
2636 case BRIDGE_OV511PLUS:
2637 reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0);
2638 break;
2639 case BRIDGE_OV518:
2640 case BRIDGE_OV518PLUS:
2641 reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02);
2642 break;
2643 case BRIDGE_OV519:
2644 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
2645 break;
2646 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002647}
2648
Hans de Goede1876bb92009-06-14 06:45:50 -03002649static int ov51x_upload_quan_tables(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03002650{
Hans de Goede1876bb92009-06-14 06:45:50 -03002651 const unsigned char yQuanTable511[] = {
2652 0, 1, 1, 2, 2, 3, 3, 4,
2653 1, 1, 1, 2, 2, 3, 4, 4,
2654 1, 1, 2, 2, 3, 4, 4, 4,
2655 2, 2, 2, 3, 4, 4, 4, 4,
2656 2, 2, 3, 4, 4, 5, 5, 5,
2657 3, 3, 4, 4, 5, 5, 5, 5,
2658 3, 4, 4, 4, 5, 5, 5, 5,
2659 4, 4, 4, 4, 5, 5, 5, 5
2660 };
2661
2662 const unsigned char uvQuanTable511[] = {
2663 0, 2, 2, 3, 4, 4, 4, 4,
2664 2, 2, 2, 4, 4, 4, 4, 4,
2665 2, 2, 3, 4, 4, 4, 4, 4,
2666 3, 4, 4, 4, 4, 4, 4, 4,
2667 4, 4, 4, 4, 4, 4, 4, 4,
2668 4, 4, 4, 4, 4, 4, 4, 4,
2669 4, 4, 4, 4, 4, 4, 4, 4,
2670 4, 4, 4, 4, 4, 4, 4, 4
2671 };
2672
2673 /* OV518 quantization tables are 8x4 (instead of 8x8) */
Hans de Goede49809d62009-06-07 12:10:39 -03002674 const unsigned char yQuanTable518[] = {
2675 5, 4, 5, 6, 6, 7, 7, 7,
2676 5, 5, 5, 5, 6, 7, 7, 7,
2677 6, 6, 6, 6, 7, 7, 7, 8,
2678 7, 7, 6, 7, 7, 7, 8, 8
2679 };
2680
2681 const unsigned char uvQuanTable518[] = {
2682 6, 6, 6, 7, 7, 7, 7, 7,
2683 6, 6, 6, 7, 7, 7, 7, 7,
2684 6, 6, 6, 7, 7, 7, 7, 8,
2685 7, 7, 7, 7, 7, 7, 8, 8
2686 };
2687
Hans de Goede1876bb92009-06-14 06:45:50 -03002688 const unsigned char *pYTable, *pUVTable;
Hans de Goede49809d62009-06-07 12:10:39 -03002689 unsigned char val0, val1;
Hans de Goede1876bb92009-06-14 06:45:50 -03002690 int i, size, rc, reg = R51x_COMP_LUT_BEGIN;
Hans de Goede49809d62009-06-07 12:10:39 -03002691
2692 PDEBUG(D_PROBE, "Uploading quantization tables");
2693
Hans de Goede1876bb92009-06-14 06:45:50 -03002694 if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
2695 pYTable = yQuanTable511;
2696 pUVTable = uvQuanTable511;
2697 size = 32;
2698 } else {
2699 pYTable = yQuanTable518;
2700 pUVTable = uvQuanTable518;
2701 size = 16;
2702 }
2703
2704 for (i = 0; i < size; i++) {
Hans de Goede49809d62009-06-07 12:10:39 -03002705 val0 = *pYTable++;
2706 val1 = *pYTable++;
2707 val0 &= 0x0f;
2708 val1 &= 0x0f;
2709 val0 |= val1 << 4;
2710 rc = reg_w(sd, reg, val0);
2711 if (rc < 0)
2712 return rc;
2713
2714 val0 = *pUVTable++;
2715 val1 = *pUVTable++;
2716 val0 &= 0x0f;
2717 val1 &= 0x0f;
2718 val0 |= val1 << 4;
Hans de Goede1876bb92009-06-14 06:45:50 -03002719 rc = reg_w(sd, reg + size, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03002720 if (rc < 0)
2721 return rc;
2722
2723 reg++;
2724 }
2725
2726 return 0;
2727}
2728
Hans de Goede1876bb92009-06-14 06:45:50 -03002729/* This initializes the OV511/OV511+ and the sensor */
2730static int ov511_configure(struct gspca_dev *gspca_dev)
2731{
2732 struct sd *sd = (struct sd *) gspca_dev;
2733 int rc;
2734
2735 /* For 511 and 511+ */
2736 const struct ov_regvals init_511[] = {
2737 { R51x_SYS_RESET, 0x7f },
2738 { R51x_SYS_INIT, 0x01 },
2739 { R51x_SYS_RESET, 0x7f },
2740 { R51x_SYS_INIT, 0x01 },
2741 { R51x_SYS_RESET, 0x3f },
2742 { R51x_SYS_INIT, 0x01 },
2743 { R51x_SYS_RESET, 0x3d },
2744 };
2745
2746 const struct ov_regvals norm_511[] = {
2747 { R511_DRAM_FLOW_CTL, 0x01 },
2748 { R51x_SYS_SNAP, 0x00 },
2749 { R51x_SYS_SNAP, 0x02 },
2750 { R51x_SYS_SNAP, 0x00 },
2751 { R511_FIFO_OPTS, 0x1f },
2752 { R511_COMP_EN, 0x00 },
2753 { R511_COMP_LUT_EN, 0x03 },
2754 };
2755
2756 const struct ov_regvals norm_511_p[] = {
2757 { R511_DRAM_FLOW_CTL, 0xff },
2758 { R51x_SYS_SNAP, 0x00 },
2759 { R51x_SYS_SNAP, 0x02 },
2760 { R51x_SYS_SNAP, 0x00 },
2761 { R511_FIFO_OPTS, 0xff },
2762 { R511_COMP_EN, 0x00 },
2763 { R511_COMP_LUT_EN, 0x03 },
2764 };
2765
2766 const struct ov_regvals compress_511[] = {
2767 { 0x70, 0x1f },
2768 { 0x71, 0x05 },
2769 { 0x72, 0x06 },
2770 { 0x73, 0x06 },
2771 { 0x74, 0x14 },
2772 { 0x75, 0x03 },
2773 { 0x76, 0x04 },
2774 { 0x77, 0x04 },
2775 };
2776
2777 PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
2778
2779 rc = write_regvals(sd, init_511, ARRAY_SIZE(init_511));
2780 if (rc < 0)
2781 return rc;
2782
2783 switch (sd->bridge) {
2784 case BRIDGE_OV511:
2785 rc = write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
2786 if (rc < 0)
2787 return rc;
2788 break;
2789 case BRIDGE_OV511PLUS:
2790 rc = write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
2791 if (rc < 0)
2792 return rc;
2793 break;
2794 }
2795
2796 /* Init compression */
2797 rc = write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
2798 if (rc < 0)
2799 return rc;
2800
2801 rc = ov51x_upload_quan_tables(sd);
2802 if (rc < 0) {
2803 PDEBUG(D_ERR, "Error uploading quantization tables");
2804 return rc;
2805 }
2806
2807 return 0;
2808}
2809
Hans de Goede49809d62009-06-07 12:10:39 -03002810/* This initializes the OV518/OV518+ and the sensor */
2811static int ov518_configure(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002812{
2813 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03002814 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002815
Hans de Goede49809d62009-06-07 12:10:39 -03002816 /* For 518 and 518+ */
Hans de Goedee080fcd2009-06-18 05:03:16 -03002817 const struct ov_regvals init_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002818 { R51x_SYS_RESET, 0x40 },
2819 { R51x_SYS_INIT, 0xe1 },
2820 { R51x_SYS_RESET, 0x3e },
2821 { R51x_SYS_INIT, 0xe1 },
2822 { R51x_SYS_RESET, 0x00 },
2823 { R51x_SYS_INIT, 0xe1 },
2824 { 0x46, 0x00 },
2825 { 0x5d, 0x03 },
2826 };
2827
Hans de Goedee080fcd2009-06-18 05:03:16 -03002828 const struct ov_regvals norm_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002829 { R51x_SYS_SNAP, 0x02 }, /* Reset */
2830 { R51x_SYS_SNAP, 0x01 }, /* Enable */
2831 { 0x31, 0x0f },
2832 { 0x5d, 0x03 },
2833 { 0x24, 0x9f },
2834 { 0x25, 0x90 },
2835 { 0x20, 0x00 },
2836 { 0x51, 0x04 },
2837 { 0x71, 0x19 },
2838 { 0x2f, 0x80 },
2839 };
2840
Hans de Goedee080fcd2009-06-18 05:03:16 -03002841 const struct ov_regvals norm_518_p[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002842 { R51x_SYS_SNAP, 0x02 }, /* Reset */
2843 { R51x_SYS_SNAP, 0x01 }, /* Enable */
2844 { 0x31, 0x0f },
2845 { 0x5d, 0x03 },
2846 { 0x24, 0x9f },
2847 { 0x25, 0x90 },
2848 { 0x20, 0x60 },
2849 { 0x51, 0x02 },
2850 { 0x71, 0x19 },
2851 { 0x40, 0xff },
2852 { 0x41, 0x42 },
2853 { 0x46, 0x00 },
2854 { 0x33, 0x04 },
2855 { 0x21, 0x19 },
2856 { 0x3f, 0x10 },
2857 { 0x2f, 0x80 },
2858 };
2859
2860 /* First 5 bits of custom ID reg are a revision ID on OV518 */
2861 PDEBUG(D_PROBE, "Device revision %d",
2862 0x1F & reg_r(sd, R51x_SYS_CUST_ID));
2863
2864 rc = write_regvals(sd, init_518, ARRAY_SIZE(init_518));
2865 if (rc < 0)
2866 return rc;
2867
2868 /* Set LED GPIO pin to output mode */
2869 rc = reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
2870 if (rc < 0)
2871 return rc;
2872
2873 switch (sd->bridge) {
2874 case BRIDGE_OV518:
2875 rc = write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
2876 if (rc < 0)
2877 return rc;
2878 break;
2879 case BRIDGE_OV518PLUS:
2880 rc = write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
2881 if (rc < 0)
2882 return rc;
2883 break;
2884 }
2885
Hans de Goede1876bb92009-06-14 06:45:50 -03002886 rc = ov51x_upload_quan_tables(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03002887 if (rc < 0) {
2888 PDEBUG(D_ERR, "Error uploading quantization tables");
2889 return rc;
2890 }
2891
2892 rc = reg_w(sd, 0x2f, 0x80);
2893 if (rc < 0)
2894 return rc;
2895
2896 return 0;
2897}
2898
2899static int ov519_configure(struct sd *sd)
2900{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002901 static const struct ov_regvals init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002902 { 0x5a, 0x6d }, /* EnableSystem */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002903 { 0x53, 0x9b },
2904 { 0x54, 0xff }, /* set bit2 to enable jpeg */
2905 { 0x5d, 0x03 },
2906 { 0x49, 0x01 },
2907 { 0x48, 0x00 },
2908 /* Set LED pin to output mode. Bit 4 must be cleared or sensor
2909 * detection will fail. This deserves further investigation. */
2910 { OV519_GPIO_IO_CTRL0, 0xee },
2911 { 0x51, 0x0f }, /* SetUsbInit */
2912 { 0x51, 0x00 },
2913 { 0x22, 0x00 },
2914 /* windows reads 0x55 at this point*/
2915 };
2916
Hans de Goede49809d62009-06-07 12:10:39 -03002917 return write_regvals(sd, init_519, ARRAY_SIZE(init_519));
2918}
2919
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002920static int ovfx2_configure(struct sd *sd)
2921{
2922 static const struct ov_regvals init_fx2[] = {
2923 { 0x00, 0x60 },
2924 { 0x02, 0x01 },
2925 { 0x0f, 0x1d },
2926 { 0xe9, 0x82 },
2927 { 0xea, 0xc7 },
2928 { 0xeb, 0x10 },
2929 { 0xec, 0xf6 },
2930 };
2931
2932 sd->stopped = 1;
2933
2934 return write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
2935}
2936
Hans de Goede49809d62009-06-07 12:10:39 -03002937/* this function is called at probe time */
2938static int sd_config(struct gspca_dev *gspca_dev,
2939 const struct usb_device_id *id)
2940{
2941 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002942 struct cam *cam = &gspca_dev->cam;
Hans de Goede49809d62009-06-07 12:10:39 -03002943 int ret = 0;
2944
Hans de Goede9e4d8252009-06-14 06:25:06 -03002945 sd->bridge = id->driver_info & BRIDGE_MASK;
2946 sd->invert_led = id->driver_info & BRIDGE_INVERT_LED;
Hans de Goede49809d62009-06-07 12:10:39 -03002947
2948 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03002949 case BRIDGE_OV511:
2950 case BRIDGE_OV511PLUS:
2951 ret = ov511_configure(gspca_dev);
2952 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002953 case BRIDGE_OV518:
2954 case BRIDGE_OV518PLUS:
2955 ret = ov518_configure(gspca_dev);
2956 break;
2957 case BRIDGE_OV519:
2958 ret = ov519_configure(sd);
2959 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002960 case BRIDGE_OVFX2:
2961 ret = ovfx2_configure(sd);
2962 cam->bulk_size = OVFX2_BULK_SIZE;
2963 cam->bulk_nurbs = MAX_NURBS;
2964 cam->bulk = 1;
2965 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002966 case BRIDGE_W9968CF:
2967 ret = w9968cf_configure(sd);
2968 cam->reverse_alts = 1;
2969 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002970 }
2971
2972 if (ret)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002973 goto error;
Hans de Goede49809d62009-06-07 12:10:39 -03002974
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002975 ov51x_led_control(sd, 0); /* turn LED off */
2976
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002977 /* The OV519 must be more aggressive about sensor detection since
2978 * I2C write will never fail if the sensor is not present. We have
2979 * to try to initialize the sensor to detect its presence */
Hans de Goede229bb7d2009-10-11 07:41:46 -03002980
2981 /* Test for 76xx */
2982 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002983 if (ov7xx0_configure(sd) < 0) {
2984 PDEBUG(D_ERR, "Failed to configure OV7xx0");
2985 goto error;
2986 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03002987 /* Test for 6xx0 */
2988 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
2989 if (ov6xx0_configure(sd) < 0) {
2990 PDEBUG(D_ERR, "Failed to configure OV6xx0");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002991 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002992 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03002993 /* Test for 8xx0 */
2994 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
2995 if (ov8xx0_configure(sd) < 0) {
2996 PDEBUG(D_ERR, "Failed to configure OV8xx0");
2997 goto error;
2998 }
Hans de Goede635118d2009-10-11 09:49:03 -03002999 /* Test for 3xxx / 2xxx */
3000 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
3001 if (ov_hires_configure(sd) < 0) {
3002 PDEBUG(D_ERR, "Failed to configure high res OV");
3003 goto error;
3004 }
Hans de Goede229bb7d2009-10-11 07:41:46 -03003005 } else {
3006 PDEBUG(D_ERR, "Can't determine sensor slave IDs");
3007 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003008 }
3009
Hans de Goede49809d62009-06-07 12:10:39 -03003010 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003011 case BRIDGE_OV511:
3012 case BRIDGE_OV511PLUS:
3013 if (!sd->sif) {
3014 cam->cam_mode = ov511_vga_mode;
3015 cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
3016 } else {
3017 cam->cam_mode = ov511_sif_mode;
3018 cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
3019 }
3020 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003021 case BRIDGE_OV518:
3022 case BRIDGE_OV518PLUS:
3023 if (!sd->sif) {
3024 cam->cam_mode = ov518_vga_mode;
3025 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
3026 } else {
3027 cam->cam_mode = ov518_sif_mode;
3028 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
3029 }
3030 break;
3031 case BRIDGE_OV519:
3032 if (!sd->sif) {
3033 cam->cam_mode = ov519_vga_mode;
3034 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3035 } else {
3036 cam->cam_mode = ov519_sif_mode;
3037 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3038 }
3039 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003040 case BRIDGE_OVFX2:
3041 if (sd->sensor == SEN_OV2610) {
3042 cam->cam_mode = ovfx2_ov2610_mode;
3043 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3044 } else if (sd->sensor == SEN_OV3610) {
3045 cam->cam_mode = ovfx2_ov3610_mode;
3046 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3047 } else if (!sd->sif) {
3048 cam->cam_mode = ov519_vga_mode;
3049 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3050 } else {
3051 cam->cam_mode = ov519_sif_mode;
3052 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3053 }
3054 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003055 case BRIDGE_W9968CF:
3056 cam->cam_mode = w9968cf_vga_mode;
3057 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
3058 /* if (sd->sif)
3059 cam->nmodes--; */
3060
3061 /* w9968cf needs initialisation once the sensor is known */
3062 if (w9968cf_init(sd) < 0)
3063 goto error;
3064 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003065 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003066 sd->brightness = BRIGHTNESS_DEF;
Hans de Goedef5cee952009-06-14 06:32:52 -03003067 if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
3068 sd->contrast = 200; /* The default is too low for the ov6630 */
3069 else
3070 sd->contrast = CONTRAST_DEF;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003071 sd->colors = COLOR_DEF;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003072 sd->hflip = HFLIP_DEF;
3073 sd->vflip = VFLIP_DEF;
Hans de Goede02ab18b2009-06-14 04:32:04 -03003074 sd->autobrightness = AUTOBRIGHT_DEF;
3075 if (sd->sensor == SEN_OV7670) {
3076 sd->freq = OV7670_FREQ_DEF;
3077 gspca_dev->ctrl_dis = 1 << FREQ_IDX;
3078 } else {
3079 sd->freq = FREQ_DEF;
3080 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
3081 (1 << OV7670_FREQ_IDX);
3082 }
3083 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670)
3084 gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
3085 /* OV8610 Frequency filter control should work but needs testing */
3086 if (sd->sensor == SEN_OV8610)
3087 gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
Hans de Goede635118d2009-10-11 09:49:03 -03003088 /* No controls for the OV2610/OV3610 */
3089 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
3090 gspca_dev->ctrl_dis |= 0xFF;
Hans de Goede02ab18b2009-06-14 04:32:04 -03003091
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003092 return 0;
3093error:
3094 PDEBUG(D_ERR, "OV519 Config failed");
3095 return -EBUSY;
3096}
3097
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03003098/* this function is called at probe and resume time */
3099static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003100{
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003101 struct sd *sd = (struct sd *) gspca_dev;
3102
3103 /* initialize the sensor */
3104 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003105 case SEN_OV2610:
3106 if (write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610)))
3107 return -EIO;
3108 /* Enable autogain, autoexpo, awb, bandfilter */
3109 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3110 return -EIO;
3111 break;
3112 case SEN_OV3610:
3113 if (write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)))
3114 return -EIO;
3115 /* Enable autogain, autoexpo, awb, bandfilter */
3116 if (i2c_w_mask(sd, 0x13, 0x27, 0x27) < 0)
3117 return -EIO;
3118 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003119 case SEN_OV6620:
3120 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
3121 return -EIO;
3122 break;
3123 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003124 case SEN_OV66308AF:
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003125 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
3126 return -EIO;
3127 break;
3128 default:
3129/* case SEN_OV7610: */
3130/* case SEN_OV76BE: */
3131 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
3132 return -EIO;
Hans de Goedeae49c402009-06-14 19:15:07 -03003133 if (i2c_w_mask(sd, 0x0e, 0x00, 0x40))
3134 return -EIO;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003135 break;
3136 case SEN_OV7620:
3137 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
3138 return -EIO;
3139 break;
3140 case SEN_OV7640:
3141 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
3142 return -EIO;
3143 break;
3144 case SEN_OV7670:
3145 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
3146 return -EIO;
3147 break;
3148 case SEN_OV8610:
3149 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
3150 return -EIO;
3151 break;
3152 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003153 return 0;
3154}
3155
Hans de Goede1876bb92009-06-14 06:45:50 -03003156/* Set up the OV511/OV511+ with the given image parameters.
3157 *
3158 * Do not put any sensor-specific code in here (including I2C I/O functions)
3159 */
3160static int ov511_mode_init_regs(struct sd *sd)
3161{
3162 int hsegs, vsegs, packet_size, fps, needed;
3163 int interlaced = 0;
3164 struct usb_host_interface *alt;
3165 struct usb_interface *intf;
3166
3167 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3168 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3169 if (!alt) {
3170 PDEBUG(D_ERR, "Couldn't get altsetting");
3171 return -EIO;
3172 }
3173
3174 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3175 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3176
3177 reg_w(sd, R511_CAM_UV_EN, 0x01);
3178 reg_w(sd, R511_SNAP_UV_EN, 0x01);
3179 reg_w(sd, R511_SNAP_OPTS, 0x03);
3180
3181 /* Here I'm assuming that snapshot size == image size.
3182 * I hope that's always true. --claudio
3183 */
3184 hsegs = (sd->gspca_dev.width >> 3) - 1;
3185 vsegs = (sd->gspca_dev.height >> 3) - 1;
3186
3187 reg_w(sd, R511_CAM_PXCNT, hsegs);
3188 reg_w(sd, R511_CAM_LNCNT, vsegs);
3189 reg_w(sd, R511_CAM_PXDIV, 0x00);
3190 reg_w(sd, R511_CAM_LNDIV, 0x00);
3191
3192 /* YUV420, low pass filter on */
3193 reg_w(sd, R511_CAM_OPTS, 0x03);
3194
3195 /* Snapshot additions */
3196 reg_w(sd, R511_SNAP_PXCNT, hsegs);
3197 reg_w(sd, R511_SNAP_LNCNT, vsegs);
3198 reg_w(sd, R511_SNAP_PXDIV, 0x00);
3199 reg_w(sd, R511_SNAP_LNDIV, 0x00);
3200
3201 /******** Set the framerate ********/
3202 if (frame_rate > 0)
3203 sd->frame_rate = frame_rate;
3204
3205 switch (sd->sensor) {
3206 case SEN_OV6620:
3207 /* No framerate control, doesn't like higher rates yet */
3208 sd->clockdiv = 3;
3209 break;
3210
3211 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
3212 for more sensors we need to do this for them too */
3213 case SEN_OV7620:
3214 case SEN_OV7640:
Hans de Goedeb282d872009-06-14 19:10:40 -03003215 case SEN_OV76BE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003216 if (sd->gspca_dev.width == 320)
3217 interlaced = 1;
3218 /* Fall through */
3219 case SEN_OV6630:
Hans de Goede1876bb92009-06-14 06:45:50 -03003220 case SEN_OV7610:
3221 case SEN_OV7670:
3222 switch (sd->frame_rate) {
3223 case 30:
3224 case 25:
3225 /* Not enough bandwidth to do 640x480 @ 30 fps */
3226 if (sd->gspca_dev.width != 640) {
3227 sd->clockdiv = 0;
3228 break;
3229 }
3230 /* Fall through for 640x480 case */
3231 default:
3232/* case 20: */
3233/* case 15: */
3234 sd->clockdiv = 1;
3235 break;
3236 case 10:
3237 sd->clockdiv = 2;
3238 break;
3239 case 5:
3240 sd->clockdiv = 5;
3241 break;
3242 }
3243 if (interlaced) {
3244 sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
3245 /* Higher then 10 does not work */
3246 if (sd->clockdiv > 10)
3247 sd->clockdiv = 10;
3248 }
3249 break;
3250
3251 case SEN_OV8610:
3252 /* No framerate control ?? */
3253 sd->clockdiv = 0;
3254 break;
3255 }
3256
3257 /* Check if we have enough bandwidth to disable compression */
3258 fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
3259 needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2;
3260 /* 1400 is a conservative estimate of the max nr of isoc packets/sec */
3261 if (needed > 1400 * packet_size) {
3262 /* Enable Y and UV quantization and compression */
3263 reg_w(sd, R511_COMP_EN, 0x07);
3264 reg_w(sd, R511_COMP_LUT_EN, 0x03);
3265 } else {
3266 reg_w(sd, R511_COMP_EN, 0x06);
3267 reg_w(sd, R511_COMP_LUT_EN, 0x00);
3268 }
3269
3270 reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
3271 reg_w(sd, R51x_SYS_RESET, 0);
3272
3273 return 0;
3274}
3275
Hans de Goede49809d62009-06-07 12:10:39 -03003276/* Sets up the OV518/OV518+ with the given image parameters
3277 *
3278 * OV518 needs a completely different approach, until we can figure out what
3279 * the individual registers do. Also, only 15 FPS is supported now.
3280 *
3281 * Do not put any sensor-specific code in here (including I2C I/O functions)
3282 */
3283static int ov518_mode_init_regs(struct sd *sd)
3284{
Hans de Goedeb282d872009-06-14 19:10:40 -03003285 int hsegs, vsegs, packet_size;
3286 struct usb_host_interface *alt;
3287 struct usb_interface *intf;
3288
3289 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3290 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3291 if (!alt) {
3292 PDEBUG(D_ERR, "Couldn't get altsetting");
3293 return -EIO;
3294 }
3295
3296 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3297 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
Hans de Goede49809d62009-06-07 12:10:39 -03003298
3299 /******** Set the mode ********/
3300
3301 reg_w(sd, 0x2b, 0);
3302 reg_w(sd, 0x2c, 0);
3303 reg_w(sd, 0x2d, 0);
3304 reg_w(sd, 0x2e, 0);
3305 reg_w(sd, 0x3b, 0);
3306 reg_w(sd, 0x3c, 0);
3307 reg_w(sd, 0x3d, 0);
3308 reg_w(sd, 0x3e, 0);
3309
3310 if (sd->bridge == BRIDGE_OV518) {
3311 /* Set 8-bit (YVYU) input format */
3312 reg_w_mask(sd, 0x20, 0x08, 0x08);
3313
3314 /* Set 12-bit (4:2:0) output format */
3315 reg_w_mask(sd, 0x28, 0x80, 0xf0);
3316 reg_w_mask(sd, 0x38, 0x80, 0xf0);
3317 } else {
3318 reg_w(sd, 0x28, 0x80);
3319 reg_w(sd, 0x38, 0x80);
3320 }
3321
3322 hsegs = sd->gspca_dev.width / 16;
3323 vsegs = sd->gspca_dev.height / 4;
3324
3325 reg_w(sd, 0x29, hsegs);
3326 reg_w(sd, 0x2a, vsegs);
3327
3328 reg_w(sd, 0x39, hsegs);
3329 reg_w(sd, 0x3a, vsegs);
3330
3331 /* Windows driver does this here; who knows why */
3332 reg_w(sd, 0x2f, 0x80);
3333
Hans de Goedeb282d872009-06-14 19:10:40 -03003334 /******** Set the framerate ********/
3335 sd->clockdiv = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03003336
3337 /* Mode independent, but framerate dependent, regs */
Hans de Goedeb282d872009-06-14 19:10:40 -03003338 /* 0x51: Clock divider; Only works on some cams which use 2 crystals */
3339 reg_w(sd, 0x51, 0x04);
Hans de Goede49809d62009-06-07 12:10:39 -03003340 reg_w(sd, 0x22, 0x18);
3341 reg_w(sd, 0x23, 0xff);
3342
Hans de Goedeb282d872009-06-14 19:10:40 -03003343 if (sd->bridge == BRIDGE_OV518PLUS) {
3344 switch (sd->sensor) {
3345 case SEN_OV7620:
3346 if (sd->gspca_dev.width == 320) {
3347 reg_w(sd, 0x20, 0x00);
3348 reg_w(sd, 0x21, 0x19);
3349 } else {
3350 reg_w(sd, 0x20, 0x60);
3351 reg_w(sd, 0x21, 0x1f);
3352 }
3353 break;
3354 default:
3355 reg_w(sd, 0x21, 0x19);
3356 }
3357 } else
Hans de Goede49809d62009-06-07 12:10:39 -03003358 reg_w(sd, 0x71, 0x17); /* Compression-related? */
3359
3360 /* FIXME: Sensor-specific */
3361 /* Bit 5 is what matters here. Of course, it is "reserved" */
3362 i2c_w(sd, 0x54, 0x23);
3363
3364 reg_w(sd, 0x2f, 0x80);
3365
3366 if (sd->bridge == BRIDGE_OV518PLUS) {
3367 reg_w(sd, 0x24, 0x94);
3368 reg_w(sd, 0x25, 0x90);
3369 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3370 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
3371 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
3372 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
3373 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
3374 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
3375 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
3376 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
3377 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
3378 } else {
3379 reg_w(sd, 0x24, 0x9f);
3380 reg_w(sd, 0x25, 0x90);
3381 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3382 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
3383 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
3384 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
3385 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
3386 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
3387 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
3388 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
3389 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
3390 }
3391
3392 reg_w(sd, 0x2f, 0x80);
3393
3394 return 0;
3395}
3396
3397
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003398/* Sets up the OV519 with the given image parameters
3399 *
3400 * OV519 needs a completely different approach, until we can figure out what
3401 * the individual registers do.
3402 *
3403 * Do not put any sensor-specific code in here (including I2C I/O functions)
3404 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003405static int ov519_mode_init_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003406{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003407 static const struct ov_regvals mode_init_519_ov7670[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003408 { 0x5d, 0x03 }, /* Turn off suspend mode */
3409 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
3410 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
3411 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3412 { 0xa3, 0x18 },
3413 { 0xa4, 0x04 },
3414 { 0xa5, 0x28 },
3415 { 0x37, 0x00 }, /* SetUsbInit */
3416 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3417 /* Enable both fields, YUV Input, disable defect comp (why?) */
3418 { 0x20, 0x0c },
3419 { 0x21, 0x38 },
3420 { 0x22, 0x1d },
3421 { 0x17, 0x50 }, /* undocumented */
3422 { 0x37, 0x00 }, /* undocumented */
3423 { 0x40, 0xff }, /* I2C timeout counter */
3424 { 0x46, 0x00 }, /* I2C clock prescaler */
3425 { 0x59, 0x04 }, /* new from windrv 090403 */
3426 { 0xff, 0x00 }, /* undocumented */
3427 /* windows reads 0x55 at this point, why? */
3428 };
3429
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003430 static const struct ov_regvals mode_init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003431 { 0x5d, 0x03 }, /* Turn off suspend mode */
3432 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
3433 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
3434 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3435 { 0xa3, 0x18 },
3436 { 0xa4, 0x04 },
3437 { 0xa5, 0x28 },
3438 { 0x37, 0x00 }, /* SetUsbInit */
3439 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3440 /* Enable both fields, YUV Input, disable defect comp (why?) */
3441 { 0x22, 0x1d },
3442 { 0x17, 0x50 }, /* undocumented */
3443 { 0x37, 0x00 }, /* undocumented */
3444 { 0x40, 0xff }, /* I2C timeout counter */
3445 { 0x46, 0x00 }, /* I2C clock prescaler */
3446 { 0x59, 0x04 }, /* new from windrv 090403 */
3447 { 0xff, 0x00 }, /* undocumented */
3448 /* windows reads 0x55 at this point, why? */
3449 };
3450
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003451 /******** Set the mode ********/
3452 if (sd->sensor != SEN_OV7670) {
3453 if (write_regvals(sd, mode_init_519,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003454 ARRAY_SIZE(mode_init_519)))
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003455 return -EIO;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003456 if (sd->sensor == SEN_OV7640) {
3457 /* Select 8-bit input mode */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003458 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003459 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003460 } else {
3461 if (write_regvals(sd, mode_init_519_ov7670,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003462 ARRAY_SIZE(mode_init_519_ov7670)))
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003463 return -EIO;
3464 }
3465
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003466 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
3467 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
Hans de Goede80142ef2009-06-14 06:26:49 -03003468 if (sd->sensor == SEN_OV7670 &&
3469 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3470 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
3471 else
3472 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003473 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
3474 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
3475 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
3476 reg_w(sd, OV519_R16_DIVIDER, 0x00);
3477 reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003478 reg_w(sd, 0x26, 0x00); /* Undocumented */
3479
3480 /******** Set the framerate ********/
3481 if (frame_rate > 0)
3482 sd->frame_rate = frame_rate;
3483
3484/* FIXME: These are only valid at the max resolution. */
3485 sd->clockdiv = 0;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003486 switch (sd->sensor) {
3487 case SEN_OV7640:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003488 switch (sd->frame_rate) {
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003489 default:
3490/* case 30: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003491 reg_w(sd, 0xa4, 0x0c);
3492 reg_w(sd, 0x23, 0xff);
3493 break;
3494 case 25:
3495 reg_w(sd, 0xa4, 0x0c);
3496 reg_w(sd, 0x23, 0x1f);
3497 break;
3498 case 20:
3499 reg_w(sd, 0xa4, 0x0c);
3500 reg_w(sd, 0x23, 0x1b);
3501 break;
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003502 case 15:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003503 reg_w(sd, 0xa4, 0x04);
3504 reg_w(sd, 0x23, 0xff);
3505 sd->clockdiv = 1;
3506 break;
3507 case 10:
3508 reg_w(sd, 0xa4, 0x04);
3509 reg_w(sd, 0x23, 0x1f);
3510 sd->clockdiv = 1;
3511 break;
3512 case 5:
3513 reg_w(sd, 0xa4, 0x04);
3514 reg_w(sd, 0x23, 0x1b);
3515 sd->clockdiv = 1;
3516 break;
3517 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003518 break;
3519 case SEN_OV8610:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003520 switch (sd->frame_rate) {
3521 default: /* 15 fps */
3522/* case 15: */
3523 reg_w(sd, 0xa4, 0x06);
3524 reg_w(sd, 0x23, 0xff);
3525 break;
3526 case 10:
3527 reg_w(sd, 0xa4, 0x06);
3528 reg_w(sd, 0x23, 0x1f);
3529 break;
3530 case 5:
3531 reg_w(sd, 0xa4, 0x06);
3532 reg_w(sd, 0x23, 0x1b);
3533 break;
3534 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003535 break;
3536 case SEN_OV7670: /* guesses, based on 7640 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003537 PDEBUG(D_STREAM, "Setting framerate to %d fps",
3538 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003539 reg_w(sd, 0xa4, 0x10);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003540 switch (sd->frame_rate) {
3541 case 30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003542 reg_w(sd, 0x23, 0xff);
3543 break;
3544 case 20:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003545 reg_w(sd, 0x23, 0x1b);
3546 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003547 default:
3548/* case 15: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003549 reg_w(sd, 0x23, 0xff);
3550 sd->clockdiv = 1;
3551 break;
3552 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003553 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003554 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003555 return 0;
3556}
3557
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003558static int mode_init_ov_sensor_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003559{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003560 struct gspca_dev *gspca_dev;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003561 int qvga, xstart, xend, ystart, yend;
3562 __u8 v;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003563
3564 gspca_dev = &sd->gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003565 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003566
3567 /******** Mode (VGA/QVGA) and sensor specific regs ********/
3568 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003569 case SEN_OV2610:
3570 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3571 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3572 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3573 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3574 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3575 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3576 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3577 return 0;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003578 case SEN_OV3610:
Hans de Goede635118d2009-10-11 09:49:03 -03003579 if (qvga) {
3580 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003581 ystart = (776 - gspca_dev->height) / 2;
Hans de Goede635118d2009-10-11 09:49:03 -03003582 } else {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003583 xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
Hans de Goede635118d2009-10-11 09:49:03 -03003584 ystart = (1544 - gspca_dev->height) / 2;
3585 }
3586 xend = xstart + gspca_dev->width;
3587 yend = ystart + gspca_dev->height;
3588 /* Writing to the COMH register resets the other windowing regs
3589 to their default values, so we must do this first. */
3590 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3591 i2c_w_mask(sd, 0x32,
3592 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3593 0x3f);
3594 i2c_w_mask(sd, 0x03,
3595 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3596 0x0f);
3597 i2c_w(sd, 0x17, xstart >> 4);
3598 i2c_w(sd, 0x18, xend >> 4);
3599 i2c_w(sd, 0x19, ystart >> 3);
3600 i2c_w(sd, 0x1a, yend >> 3);
3601 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003602 case SEN_OV8610:
3603 /* For OV8610 qvga means qsvga */
3604 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003605 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3606 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3607 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
3608 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003609 break;
3610 case SEN_OV7610:
3611 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003612 i2c_w(sd, 0x35, qvga?0x1e:0x9e);
3613 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3614 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003615 break;
3616 case SEN_OV7620:
Hans de Goedeb282d872009-06-14 19:10:40 -03003617 case SEN_OV76BE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003618 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3619 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3620 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3621 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3622 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goedeb282d872009-06-14 19:10:40 -03003623 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003624 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003625 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3626 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3627 if (sd->sensor == SEN_OV76BE)
3628 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003629 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003630 case SEN_OV7640:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003631 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3632 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3633/* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */
3634/* i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */
3635/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */
3636/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */
3637/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003638 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003639 break;
3640 case SEN_OV7670:
3641 /* set COM7_FMT_VGA or COM7_FMT_QVGA
3642 * do we need to set anything else?
3643 * HSTART etc are set in set_ov_sensor_window itself */
3644 i2c_w_mask(sd, OV7670_REG_COM7,
3645 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
3646 OV7670_COM7_FMT_MASK);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003647 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3648 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
3649 OV7670_COM8_AWB);
3650 if (qvga) { /* QVGA from ov7670.c by
3651 * Jonathan Corbet */
3652 xstart = 164;
3653 xend = 28;
3654 ystart = 14;
3655 yend = 494;
3656 } else { /* VGA */
3657 xstart = 158;
3658 xend = 14;
3659 ystart = 10;
3660 yend = 490;
3661 }
3662 /* OV7670 hardware window registers are split across
3663 * multiple locations */
3664 i2c_w(sd, OV7670_REG_HSTART, xstart >> 3);
3665 i2c_w(sd, OV7670_REG_HSTOP, xend >> 3);
3666 v = i2c_r(sd, OV7670_REG_HREF);
3667 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
3668 msleep(10); /* need to sleep between read and write to
3669 * same reg! */
3670 i2c_w(sd, OV7670_REG_HREF, v);
3671
3672 i2c_w(sd, OV7670_REG_VSTART, ystart >> 2);
3673 i2c_w(sd, OV7670_REG_VSTOP, yend >> 2);
3674 v = i2c_r(sd, OV7670_REG_VREF);
3675 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
3676 msleep(10); /* need to sleep between read and write to
3677 * same reg! */
3678 i2c_w(sd, OV7670_REG_VREF, v);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003679 break;
3680 case SEN_OV6620:
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003681 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3682 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3683 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3684 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003685 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003686 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003687 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003688 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003689 break;
3690 default:
3691 return -EINVAL;
3692 }
3693
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003694 /******** Clock programming ********/
Hans de Goedeae49c402009-06-14 19:15:07 -03003695 i2c_w(sd, 0x11, sd->clockdiv);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003696
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003697 return 0;
3698}
3699
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003700static void sethvflip(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003701{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003702 if (sd->sensor != SEN_OV7670)
3703 return;
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003704 if (sd->gspca_dev.streaming)
3705 ov51x_stop(sd);
3706 i2c_w_mask(sd, OV7670_REG_MVFP,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003707 OV7670_MVFP_MIRROR * sd->hflip
3708 | OV7670_MVFP_VFLIP * sd->vflip,
3709 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003710 if (sd->gspca_dev.streaming)
3711 ov51x_restart(sd);
3712}
3713
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003714static int set_ov_sensor_window(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003715{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003716 struct gspca_dev *gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003717 int qvga, crop;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003718 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003719 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003720
Hans de Goede635118d2009-10-11 09:49:03 -03003721 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003722 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610 ||
3723 sd->sensor == SEN_OV7670)
Hans de Goede635118d2009-10-11 09:49:03 -03003724 return mode_init_ov_sensor_regs(sd);
3725
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003726 gspca_dev = &sd->gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003727 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 1;
3728 crop = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 2;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003729
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003730 /* The different sensor ICs handle setting up of window differently.
3731 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
3732 switch (sd->sensor) {
3733 case SEN_OV8610:
3734 hwsbase = 0x1e;
3735 hwebase = 0x1e;
3736 vwsbase = 0x02;
3737 vwebase = 0x02;
3738 break;
3739 case SEN_OV7610:
3740 case SEN_OV76BE:
3741 hwsbase = 0x38;
3742 hwebase = 0x3a;
3743 vwsbase = vwebase = 0x05;
3744 break;
3745 case SEN_OV6620:
3746 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003747 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003748 hwsbase = 0x38;
3749 hwebase = 0x3a;
3750 vwsbase = 0x05;
3751 vwebase = 0x06;
Hans de Goede7d971372009-06-14 05:28:17 -03003752 if (sd->sensor == SEN_OV66308AF && qvga)
Hans de Goede49809d62009-06-07 12:10:39 -03003753 /* HDG: this fixes U and V getting swapped */
Hans de Goede7d971372009-06-14 05:28:17 -03003754 hwsbase++;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003755 if (crop) {
3756 hwsbase += 8;
3757 hwebase += 8;
3758 vwsbase += 11;
3759 vwebase += 11;
3760 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003761 break;
3762 case SEN_OV7620:
3763 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
3764 hwebase = 0x2f;
3765 vwsbase = vwebase = 0x05;
3766 break;
3767 case SEN_OV7640:
3768 hwsbase = 0x1a;
3769 hwebase = 0x1a;
3770 vwsbase = vwebase = 0x03;
3771 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003772 default:
3773 return -EINVAL;
3774 }
3775
3776 switch (sd->sensor) {
3777 case SEN_OV6620:
3778 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003779 case SEN_OV66308AF:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003780 if (qvga) { /* QCIF */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003781 hwscale = 0;
3782 vwscale = 0;
3783 } else { /* CIF */
3784 hwscale = 1;
3785 vwscale = 1; /* The datasheet says 0;
3786 * it's wrong */
3787 }
3788 break;
3789 case SEN_OV8610:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003790 if (qvga) { /* QSVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003791 hwscale = 1;
3792 vwscale = 1;
3793 } else { /* SVGA */
3794 hwscale = 2;
3795 vwscale = 2;
3796 }
3797 break;
3798 default: /* SEN_OV7xx0 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003799 if (qvga) { /* QVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003800 hwscale = 1;
3801 vwscale = 0;
3802 } else { /* VGA */
3803 hwscale = 2;
3804 vwscale = 1;
3805 }
3806 }
3807
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003808 ret = mode_init_ov_sensor_regs(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003809 if (ret < 0)
3810 return ret;
3811
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003812 i2c_w(sd, 0x17, hwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03003813 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003814 i2c_w(sd, 0x19, vwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03003815 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003816
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003817 return 0;
3818}
3819
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003820/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003821static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003822{
3823 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03003824 int ret = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003825
Hans de Goedea511ba92009-10-16 07:13:07 -03003826 /* Default for most bridges, allow bridge_mode_init_regs to override */
3827 sd->sensor_width = sd->gspca_dev.width;
3828 sd->sensor_height = sd->gspca_dev.height;
3829
Hans de Goede49809d62009-06-07 12:10:39 -03003830 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003831 case BRIDGE_OV511:
3832 case BRIDGE_OV511PLUS:
3833 ret = ov511_mode_init_regs(sd);
3834 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003835 case BRIDGE_OV518:
3836 case BRIDGE_OV518PLUS:
3837 ret = ov518_mode_init_regs(sd);
3838 break;
3839 case BRIDGE_OV519:
3840 ret = ov519_mode_init_regs(sd);
3841 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003842 /* case BRIDGE_OVFX2: nothing to do */
Hans de Goedea511ba92009-10-16 07:13:07 -03003843 case BRIDGE_W9968CF:
3844 ret = w9968cf_mode_init_regs(sd);
3845 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003846 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003847 if (ret < 0)
3848 goto out;
Hans de Goede49809d62009-06-07 12:10:39 -03003849
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003850 ret = set_ov_sensor_window(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003851 if (ret < 0)
3852 goto out;
3853
Hans de Goede49809d62009-06-07 12:10:39 -03003854 setcontrast(gspca_dev);
3855 setbrightness(gspca_dev);
3856 setcolors(gspca_dev);
Hans de Goede02ab18b2009-06-14 04:32:04 -03003857 sethvflip(sd);
3858 setautobrightness(sd);
3859 setfreq(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003860
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003861 ret = ov51x_restart(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003862 if (ret < 0)
3863 goto out;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003864 ov51x_led_control(sd, 1);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003865 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003866out:
3867 PDEBUG(D_ERR, "camera start error:%d", ret);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03003868 return ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003869}
3870
3871static void sd_stopN(struct gspca_dev *gspca_dev)
3872{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003873 struct sd *sd = (struct sd *) gspca_dev;
3874
3875 ov51x_stop(sd);
3876 ov51x_led_control(sd, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003877}
3878
Hans de Goede1876bb92009-06-14 06:45:50 -03003879static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
3880 struct gspca_frame *frame, /* target */
3881 __u8 *in, /* isoc packet */
3882 int len) /* iso packet length */
3883{
3884 struct sd *sd = (struct sd *) gspca_dev;
3885
3886 /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
3887 * byte non-zero. The EOF packet has image width/height in the
3888 * 10th and 11th bytes. The 9th byte is given as follows:
3889 *
3890 * bit 7: EOF
3891 * 6: compression enabled
3892 * 5: 422/420/400 modes
3893 * 4: 422/420/400 modes
3894 * 3: 1
3895 * 2: snapshot button on
3896 * 1: snapshot frame
3897 * 0: even/odd field
3898 */
3899 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
3900 (in[8] & 0x08)) {
3901 if (in[8] & 0x80) {
3902 /* Frame end */
3903 if ((in[9] + 1) * 8 != gspca_dev->width ||
3904 (in[10] + 1) * 8 != gspca_dev->height) {
3905 PDEBUG(D_ERR, "Invalid frame size, got: %dx%d,"
3906 " requested: %dx%d\n",
3907 (in[9] + 1) * 8, (in[10] + 1) * 8,
3908 gspca_dev->width, gspca_dev->height);
3909 gspca_dev->last_packet_type = DISCARD_PACKET;
3910 return;
3911 }
3912 /* Add 11 byte footer to frame, might be usefull */
3913 gspca_frame_add(gspca_dev, LAST_PACKET, frame, in, 11);
3914 return;
3915 } else {
3916 /* Frame start */
3917 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, in, 0);
3918 sd->packet_nr = 0;
3919 }
3920 }
3921
3922 /* Ignore the packet number */
3923 len--;
3924
3925 /* intermediate packet */
3926 gspca_frame_add(gspca_dev, INTER_PACKET, frame, in, len);
3927}
3928
Hans de Goede49809d62009-06-07 12:10:39 -03003929static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
3930 struct gspca_frame *frame, /* target */
3931 __u8 *data, /* isoc packet */
3932 int len) /* iso packet length */
3933{
Hans de Goede92918a52009-06-14 06:21:35 -03003934 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03003935
3936 /* A false positive here is likely, until OVT gives me
3937 * the definitive SOF/EOF format */
3938 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
Hans de Goede1381dfd2009-10-04 14:04:47 -03003939 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
Hans de Goede49809d62009-06-07 12:10:39 -03003940 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
Hans de Goede92918a52009-06-14 06:21:35 -03003941 sd->packet_nr = 0;
3942 }
3943
3944 if (gspca_dev->last_packet_type == DISCARD_PACKET)
3945 return;
3946
3947 /* Does this device use packet numbers ? */
3948 if (len & 7) {
3949 len--;
3950 if (sd->packet_nr == data[len])
3951 sd->packet_nr++;
3952 /* The last few packets of the frame (which are all 0's
3953 except that they may contain part of the footer), are
3954 numbered 0 */
3955 else if (sd->packet_nr == 0 || data[len]) {
3956 PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)",
3957 (int)data[len], (int)sd->packet_nr);
3958 gspca_dev->last_packet_type = DISCARD_PACKET;
3959 return;
3960 }
Hans de Goede49809d62009-06-07 12:10:39 -03003961 }
3962
3963 /* intermediate packet */
3964 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
3965}
3966
3967static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003968 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003969 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003970 int len) /* iso packet length */
3971{
3972 /* Header of ov519 is 16 bytes:
3973 * Byte Value Description
3974 * 0 0xff magic
3975 * 1 0xff magic
3976 * 2 0xff magic
3977 * 3 0xXX 0x50 = SOF, 0x51 = EOF
3978 * 9 0xXX 0x01 initial frame without data,
3979 * 0x00 standard frame with image
3980 * 14 Lo in EOF: length of image data / 8
3981 * 15 Hi
3982 */
3983
3984 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
3985 switch (data[3]) {
3986 case 0x50: /* start of frame */
3987#define HDRSZ 16
3988 data += HDRSZ;
3989 len -= HDRSZ;
3990#undef HDRSZ
3991 if (data[0] == 0xff || data[1] == 0xd8)
3992 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
3993 data, len);
3994 else
3995 gspca_dev->last_packet_type = DISCARD_PACKET;
3996 return;
3997 case 0x51: /* end of frame */
3998 if (data[9] != 0)
3999 gspca_dev->last_packet_type = DISCARD_PACKET;
4000 gspca_frame_add(gspca_dev, LAST_PACKET, frame,
4001 data, 0);
4002 return;
4003 }
4004 }
4005
4006 /* intermediate packet */
4007 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
4008 data, len);
4009}
4010
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004011static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
4012 struct gspca_frame *frame, /* target */
4013 __u8 *data, /* isoc packet */
4014 int len) /* iso packet length */
4015{
4016 /* A short read signals EOF */
4017 if (len < OVFX2_BULK_SIZE) {
4018 gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, len);
4019 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
4020 return;
4021 }
4022 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
4023}
4024
Hans de Goede49809d62009-06-07 12:10:39 -03004025static void sd_pkt_scan(struct gspca_dev *gspca_dev,
4026 struct gspca_frame *frame, /* target */
4027 __u8 *data, /* isoc packet */
4028 int len) /* iso packet length */
4029{
4030 struct sd *sd = (struct sd *) gspca_dev;
4031
4032 switch (sd->bridge) {
4033 case BRIDGE_OV511:
4034 case BRIDGE_OV511PLUS:
Hans de Goede1876bb92009-06-14 06:45:50 -03004035 ov511_pkt_scan(gspca_dev, frame, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004036 break;
4037 case BRIDGE_OV518:
4038 case BRIDGE_OV518PLUS:
4039 ov518_pkt_scan(gspca_dev, frame, data, len);
4040 break;
4041 case BRIDGE_OV519:
4042 ov519_pkt_scan(gspca_dev, frame, data, len);
4043 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004044 case BRIDGE_OVFX2:
4045 ovfx2_pkt_scan(gspca_dev, frame, data, len);
4046 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03004047 case BRIDGE_W9968CF:
4048 w9968cf_pkt_scan(gspca_dev, frame, data, len);
4049 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004050 }
4051}
4052
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004053/* -- management routines -- */
4054
4055static void setbrightness(struct gspca_dev *gspca_dev)
4056{
4057 struct sd *sd = (struct sd *) gspca_dev;
4058 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004059
4060 val = sd->brightness;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004061 switch (sd->sensor) {
4062 case SEN_OV8610:
4063 case SEN_OV7610:
4064 case SEN_OV76BE:
4065 case SEN_OV6620:
4066 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004067 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004068 case SEN_OV7640:
4069 i2c_w(sd, OV7610_REG_BRT, val);
4070 break;
4071 case SEN_OV7620:
4072 /* 7620 doesn't like manual changes when in auto mode */
Hans de Goede02ab18b2009-06-14 04:32:04 -03004073 if (!sd->autobrightness)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004074 i2c_w(sd, OV7610_REG_BRT, val);
4075 break;
4076 case SEN_OV7670:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004077/*win trace
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004078 * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
4079 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
4080 break;
4081 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004082}
4083
4084static void setcontrast(struct gspca_dev *gspca_dev)
4085{
4086 struct sd *sd = (struct sd *) gspca_dev;
4087 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004088
4089 val = sd->contrast;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004090 switch (sd->sensor) {
4091 case SEN_OV7610:
4092 case SEN_OV6620:
4093 i2c_w(sd, OV7610_REG_CNT, val);
4094 break;
4095 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004096 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004097 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
Hans de Goede49809d62009-06-07 12:10:39 -03004098 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004099 case SEN_OV8610: {
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004100 static const __u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004101 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
4102 };
4103
4104 /* Use Y gamma control instead. Bit 0 enables it. */
4105 i2c_w(sd, 0x64, ctab[val >> 5]);
4106 break;
4107 }
4108 case SEN_OV7620: {
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004109 static const __u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004110 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4111 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
4112 };
4113
4114 /* Use Y gamma control instead. Bit 0 enables it. */
4115 i2c_w(sd, 0x64, ctab[val >> 4]);
4116 break;
4117 }
4118 case SEN_OV7640:
4119 /* Use gain control instead. */
4120 i2c_w(sd, OV7610_REG_GAIN, val >> 2);
4121 break;
4122 case SEN_OV7670:
4123 /* check that this isn't just the same as ov7610 */
4124 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
4125 break;
4126 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004127}
4128
4129static void setcolors(struct gspca_dev *gspca_dev)
4130{
4131 struct sd *sd = (struct sd *) gspca_dev;
4132 int val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004133
4134 val = sd->colors;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004135 switch (sd->sensor) {
4136 case SEN_OV8610:
4137 case SEN_OV7610:
4138 case SEN_OV76BE:
4139 case SEN_OV6620:
4140 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004141 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004142 i2c_w(sd, OV7610_REG_SAT, val);
4143 break;
4144 case SEN_OV7620:
4145 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
4146/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
4147 if (rc < 0)
4148 goto out; */
4149 i2c_w(sd, OV7610_REG_SAT, val);
4150 break;
4151 case SEN_OV7640:
4152 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4153 break;
4154 case SEN_OV7670:
4155 /* supported later once I work out how to do it
4156 * transparently fail now! */
4157 /* set REG_COM13 values for UV sat auto mode */
4158 break;
4159 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004160}
4161
Hans de Goede02ab18b2009-06-14 04:32:04 -03004162static void setautobrightness(struct sd *sd)
4163{
Hans de Goede635118d2009-10-11 09:49:03 -03004164 if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7670 ||
4165 sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004166 return;
4167
4168 i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
4169}
4170
4171static void setfreq(struct sd *sd)
4172{
Hans de Goede635118d2009-10-11 09:49:03 -03004173 if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
4174 return;
4175
Hans de Goede02ab18b2009-06-14 04:32:04 -03004176 if (sd->sensor == SEN_OV7670) {
4177 switch (sd->freq) {
4178 case 0: /* Banding filter disabled */
4179 i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT);
4180 break;
4181 case 1: /* 50 hz */
4182 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
4183 OV7670_COM8_BFILT);
4184 i2c_w_mask(sd, OV7670_REG_COM11, 0x08, 0x18);
4185 break;
4186 case 2: /* 60 hz */
4187 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
4188 OV7670_COM8_BFILT);
4189 i2c_w_mask(sd, OV7670_REG_COM11, 0x00, 0x18);
4190 break;
4191 case 3: /* Auto hz */
4192 i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_BFILT,
4193 OV7670_COM8_BFILT);
4194 i2c_w_mask(sd, OV7670_REG_COM11, OV7670_COM11_HZAUTO,
4195 0x18);
4196 break;
4197 }
4198 } else {
4199 switch (sd->freq) {
4200 case 0: /* Banding filter disabled */
4201 i2c_w_mask(sd, 0x2d, 0x00, 0x04);
4202 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4203 break;
4204 case 1: /* 50 hz (filter on and framerate adj) */
4205 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4206 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4207 /* 20 fps -> 16.667 fps */
4208 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004209 sd->sensor == SEN_OV6630 ||
4210 sd->sensor == SEN_OV66308AF)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004211 i2c_w(sd, 0x2b, 0x5e);
4212 else
4213 i2c_w(sd, 0x2b, 0xac);
4214 break;
4215 case 2: /* 60 hz (filter on, ...) */
4216 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4217 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004218 sd->sensor == SEN_OV6630 ||
4219 sd->sensor == SEN_OV66308AF) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004220 /* 20 fps -> 15 fps */
4221 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4222 i2c_w(sd, 0x2b, 0xa8);
4223 } else {
4224 /* no framerate adj. */
4225 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4226 }
4227 break;
4228 }
4229 }
4230}
4231
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004232static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
4233{
4234 struct sd *sd = (struct sd *) gspca_dev;
4235
4236 sd->brightness = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004237 if (gspca_dev->streaming)
4238 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004239 return 0;
4240}
4241
4242static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
4243{
4244 struct sd *sd = (struct sd *) gspca_dev;
4245
4246 *val = sd->brightness;
4247 return 0;
4248}
4249
4250static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
4251{
4252 struct sd *sd = (struct sd *) gspca_dev;
4253
4254 sd->contrast = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004255 if (gspca_dev->streaming)
4256 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004257 return 0;
4258}
4259
4260static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
4261{
4262 struct sd *sd = (struct sd *) gspca_dev;
4263
4264 *val = sd->contrast;
4265 return 0;
4266}
4267
4268static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
4269{
4270 struct sd *sd = (struct sd *) gspca_dev;
4271
4272 sd->colors = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004273 if (gspca_dev->streaming)
4274 setcolors(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004275 return 0;
4276}
4277
4278static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
4279{
4280 struct sd *sd = (struct sd *) gspca_dev;
4281
4282 *val = sd->colors;
4283 return 0;
4284}
4285
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004286static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
4287{
4288 struct sd *sd = (struct sd *) gspca_dev;
4289
4290 sd->hflip = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004291 if (gspca_dev->streaming)
4292 sethvflip(sd);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004293 return 0;
4294}
4295
4296static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
4297{
4298 struct sd *sd = (struct sd *) gspca_dev;
4299
4300 *val = sd->hflip;
4301 return 0;
4302}
4303
4304static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
4305{
4306 struct sd *sd = (struct sd *) gspca_dev;
4307
4308 sd->vflip = val;
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004309 if (gspca_dev->streaming)
4310 sethvflip(sd);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004311 return 0;
4312}
4313
4314static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
4315{
4316 struct sd *sd = (struct sd *) gspca_dev;
4317
4318 *val = sd->vflip;
4319 return 0;
4320}
4321
Hans de Goede02ab18b2009-06-14 04:32:04 -03004322static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val)
4323{
4324 struct sd *sd = (struct sd *) gspca_dev;
4325
4326 sd->autobrightness = val;
4327 if (gspca_dev->streaming)
4328 setautobrightness(sd);
4329 return 0;
4330}
4331
4332static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val)
4333{
4334 struct sd *sd = (struct sd *) gspca_dev;
4335
4336 *val = sd->autobrightness;
4337 return 0;
4338}
4339
4340static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
4341{
4342 struct sd *sd = (struct sd *) gspca_dev;
4343
4344 sd->freq = val;
Hans de Goedea511ba92009-10-16 07:13:07 -03004345 if (gspca_dev->streaming) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004346 setfreq(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03004347 /* Ugly but necessary */
4348 if (sd->bridge == BRIDGE_W9968CF)
4349 w9968cf_set_crop_window(sd);
4350 }
Hans de Goede02ab18b2009-06-14 04:32:04 -03004351 return 0;
4352}
4353
4354static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
4355{
4356 struct sd *sd = (struct sd *) gspca_dev;
4357
4358 *val = sd->freq;
4359 return 0;
4360}
4361
4362static int sd_querymenu(struct gspca_dev *gspca_dev,
4363 struct v4l2_querymenu *menu)
4364{
4365 struct sd *sd = (struct sd *) gspca_dev;
4366
4367 switch (menu->id) {
4368 case V4L2_CID_POWER_LINE_FREQUENCY:
4369 switch (menu->index) {
4370 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
4371 strcpy((char *) menu->name, "NoFliker");
4372 return 0;
4373 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
4374 strcpy((char *) menu->name, "50 Hz");
4375 return 0;
4376 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
4377 strcpy((char *) menu->name, "60 Hz");
4378 return 0;
4379 case 3:
4380 if (sd->sensor != SEN_OV7670)
4381 return -EINVAL;
4382
4383 strcpy((char *) menu->name, "Automatic");
4384 return 0;
4385 }
4386 break;
4387 }
4388 return -EINVAL;
4389}
4390
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004391/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004392static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004393 .name = MODULE_NAME,
4394 .ctrls = sd_ctrls,
4395 .nctrls = ARRAY_SIZE(sd_ctrls),
4396 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03004397 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004398 .start = sd_start,
4399 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004400 .pkt_scan = sd_pkt_scan,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004401 .querymenu = sd_querymenu,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004402};
4403
4404/* -- module initialisation -- */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004405static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03004406 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
Hans de Goede49809d62009-06-07 12:10:39 -03004407 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
4408 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
4409 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
4410 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004411 {USB_DEVICE(0x041e, 0x4064),
4412 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Rafal Milecki518c8df2009-10-02 03:54:44 -03004413 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004414 {USB_DEVICE(0x041e, 0x4068),
4415 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede49809d62009-06-07 12:10:39 -03004416 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
4417 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
4418 {USB_DEVICE(0x054c, 0x0155), .driver_info = BRIDGE_OV519 },
Hans de Goede1876bb92009-06-14 06:45:50 -03004419 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
Hans de Goede49809d62009-06-07 12:10:39 -03004420 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4421 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
4422 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004423 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
Hans de Goede49809d62009-06-07 12:10:39 -03004424 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
4425 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
Hans de Goede1876bb92009-06-14 06:45:50 -03004426 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
Hans de Goede49809d62009-06-07 12:10:39 -03004427 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
Hans de Goede1876bb92009-06-14 06:45:50 -03004428 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004429 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4430 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
Hans de Goedea511ba92009-10-16 07:13:07 -03004431 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004432 {USB_DEVICE(0x8020, 0xEF04), .driver_info = BRIDGE_OVFX2 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004433 {}
4434};
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004435
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004436MODULE_DEVICE_TABLE(usb, device_table);
4437
4438/* -- device connect -- */
4439static int sd_probe(struct usb_interface *intf,
4440 const struct usb_device_id *id)
4441{
4442 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
4443 THIS_MODULE);
4444}
4445
4446static struct usb_driver sd_driver = {
4447 .name = MODULE_NAME,
4448 .id_table = device_table,
4449 .probe = sd_probe,
4450 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03004451#ifdef CONFIG_PM
4452 .suspend = gspca_suspend,
4453 .resume = gspca_resume,
4454#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004455};
4456
4457/* -- module insert / remove -- */
4458static int __init sd_mod_init(void)
4459{
Alexey Klimovf69e9522009-01-01 13:02:07 -03004460 int ret;
4461 ret = usb_register(&sd_driver);
4462 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03004463 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03004464 PDEBUG(D_PROBE, "registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004465 return 0;
4466}
4467static void __exit sd_mod_exit(void)
4468{
4469 usb_deregister(&sd_driver);
4470 PDEBUG(D_PROBE, "deregistered");
4471}
4472
4473module_init(sd_mod_init);
4474module_exit(sd_mod_exit);
4475
4476module_param(frame_rate, int, 0644);
4477MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");