blob: e1c3b9328aceb9c0ae1de6df55ad608e102f47ee [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 Beauxis2961e8752008-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 Beauxis2961e8752008-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 Beauxis2961e8752008-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
Hans de Goede417a4d22010-02-19 07:37:08 -030041#include <linux/input.h>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030042#include "gspca.h"
43
Jean-François Moine9a731a32010-06-04 05:26:42 -030044/* The jpeg_hdr is used by w996Xcf only */
45/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
46#define CONEX_CAM
47#include "jpeg.h"
48
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030049MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
50MODULE_DESCRIPTION("OV519 USB Camera Driver");
51MODULE_LICENSE("GPL");
52
53/* global parameters */
54static int frame_rate;
55
56/* Number of times to retry a failed I2C transaction. Increase this if you
57 * are getting "Failed to read sensor ID..." */
58static int i2c_detect_tries = 10;
59
Jean-François Moine62833ac2010-10-02 04:27:02 -030060/* controls */
61enum e_ctrl {
62 BRIGHTNESS,
63 CONTRAST,
64 COLORS,
65 HFLIP,
66 VFLIP,
67 AUTOBRIGHT,
68 FREQ,
69 NCTRL /* number of controls */
70};
71
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030072/* ov519 device descriptor */
73struct sd {
74 struct gspca_dev gspca_dev; /* !! must be the first item */
75
Jean-François Moine62833ac2010-10-02 04:27:02 -030076 struct gspca_ctrl ctrls[NCTRL];
77
Jean-François Moine9d1593a2010-11-11 08:04:06 -030078 u8 packet_nr;
Hans de Goede92918a52009-06-14 06:21:35 -030079
Hans de Goede49809d62009-06-07 12:10:39 -030080 char bridge;
81#define BRIDGE_OV511 0
82#define BRIDGE_OV511PLUS 1
83#define BRIDGE_OV518 2
84#define BRIDGE_OV518PLUS 3
Jean-François Moine42e142f2010-11-13 05:10:27 -030085#define BRIDGE_OV519 4 /* = ov530 */
Hans de Goede635118d2009-10-11 09:49:03 -030086#define BRIDGE_OVFX2 5
Hans de Goedea511ba92009-10-16 07:13:07 -030087#define BRIDGE_W9968CF 6
Hans de Goede9e4d8252009-06-14 06:25:06 -030088#define BRIDGE_MASK 7
89
90 char invert_led;
91#define BRIDGE_INVERT_LED 8
Hans de Goede49809d62009-06-07 12:10:39 -030092
Hans de Goede417a4d22010-02-19 07:37:08 -030093 char snapshot_pressed;
94 char snapshot_needs_reset;
95
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030096 /* Determined by sensor type */
Jean-François Moine9d1593a2010-11-11 08:04:06 -030097 u8 sif;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030098
Jean-François Moine9d1593a2010-11-11 08:04:06 -030099 u8 quality;
Hans de Goede79b35902009-10-19 06:08:01 -0300100#define QUALITY_MIN 50
101#define QUALITY_MAX 70
102#define QUALITY_DEF 50
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300103
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300104 u8 stopped; /* Streaming is temporarily paused */
105 u8 first_frame;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300106
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300107 u8 frame_rate; /* current Framerate */
108 u8 clockdiv; /* clockdiv override */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300109
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300110 s8 sensor; /* Type of image sensor chip (SEN_*) */
Hans de Goedea511ba92009-10-16 07:13:07 -0300111
112 u8 sensor_addr;
Jean-François Moined6fa6632010-11-11 08:05:50 -0300113 u16 sensor_width;
114 u16 sensor_height;
115 s16 sensor_reg_cache[256];
Hans de Goede79b35902009-10-19 06:08:01 -0300116
Jean-François Moine9a731a32010-06-04 05:26:42 -0300117 u8 jpeg_hdr[JPEG_HDR_SZ];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300118};
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300119enum sensors {
120 SEN_OV2610,
121 SEN_OV3610,
122 SEN_OV6620,
123 SEN_OV6630,
124 SEN_OV66308AF,
125 SEN_OV7610,
126 SEN_OV7620,
127 SEN_OV7620AE,
128 SEN_OV7640,
129 SEN_OV7648,
Jean-François Moine42e142f2010-11-13 05:10:27 -0300130 SEN_OV7660,
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300131 SEN_OV7670,
132 SEN_OV76BE,
133 SEN_OV8610,
134};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300135
Hans de Goedea511ba92009-10-16 07:13:07 -0300136/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
137 the ov sensors which is already present here. When we have the time we
138 really should move the sensor drivers to v4l2 sub drivers. */
139#include "w996Xcf.c"
140
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300141/* V4L2 controls supported by the driver */
Hans de Goede49809d62009-06-07 12:10:39 -0300142static void setbrightness(struct gspca_dev *gspca_dev);
143static void setcontrast(struct gspca_dev *gspca_dev);
144static void setcolors(struct gspca_dev *gspca_dev);
Jean-François Moine62833ac2010-10-02 04:27:02 -0300145static void sethvflip(struct gspca_dev *gspca_dev);
146static void setautobright(struct gspca_dev *gspca_dev);
147static void setfreq(struct gspca_dev *gspca_dev);
148static void setfreq_i(struct sd *sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300149
Hans de Goede02ab18b2009-06-14 04:32:04 -0300150static const struct ctrl sd_ctrls[] = {
Jean-François Moine62833ac2010-10-02 04:27:02 -0300151[BRIGHTNESS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300152 {
153 .id = V4L2_CID_BRIGHTNESS,
154 .type = V4L2_CTRL_TYPE_INTEGER,
155 .name = "Brightness",
156 .minimum = 0,
157 .maximum = 255,
158 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300159 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300160 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300161 .set_control = setbrightness,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300162 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300163[CONTRAST] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300164 {
165 .id = V4L2_CID_CONTRAST,
166 .type = V4L2_CTRL_TYPE_INTEGER,
167 .name = "Contrast",
168 .minimum = 0,
169 .maximum = 255,
170 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300171 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300172 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300173 .set_control = setcontrast,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300174 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300175[COLORS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300176 {
177 .id = V4L2_CID_SATURATION,
178 .type = V4L2_CTRL_TYPE_INTEGER,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300179 .name = "Color",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300180 .minimum = 0,
181 .maximum = 255,
182 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300183 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300184 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300185 .set_control = setcolors,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300186 },
Jean-François Moine42e142f2010-11-13 05:10:27 -0300187/* The flip controls work for sensors ov7660 and ov7670 only */
Jean-François Moine62833ac2010-10-02 04:27:02 -0300188[HFLIP] = {
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300189 {
190 .id = V4L2_CID_HFLIP,
191 .type = V4L2_CTRL_TYPE_BOOLEAN,
192 .name = "Mirror",
193 .minimum = 0,
194 .maximum = 1,
195 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300196 .default_value = 0,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300197 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300198 .set_control = sethvflip,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300199 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300200[VFLIP] = {
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300201 {
202 .id = V4L2_CID_VFLIP,
203 .type = V4L2_CTRL_TYPE_BOOLEAN,
204 .name = "Vflip",
205 .minimum = 0,
206 .maximum = 1,
207 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300208 .default_value = 0,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300209 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300210 .set_control = sethvflip,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300211 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300212[AUTOBRIGHT] = {
Hans de Goede02ab18b2009-06-14 04:32:04 -0300213 {
214 .id = V4L2_CID_AUTOBRIGHTNESS,
215 .type = V4L2_CTRL_TYPE_BOOLEAN,
216 .name = "Auto Brightness",
217 .minimum = 0,
218 .maximum = 1,
219 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300220 .default_value = 1,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300221 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300222 .set_control = setautobright,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300223 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300224[FREQ] = {
Hans de Goede02ab18b2009-06-14 04:32:04 -0300225 {
226 .id = V4L2_CID_POWER_LINE_FREQUENCY,
227 .type = V4L2_CTRL_TYPE_MENU,
228 .name = "Light frequency filter",
229 .minimum = 0,
Jean-François Moine87bae742010-11-12 05:31:34 -0300230 .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */
Hans de Goede02ab18b2009-06-14 04:32:04 -0300231 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300232 .default_value = 0,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300233 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300234 .set_control = setfreq,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300235 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300236};
237
Jean-François Moine83db7682010-11-12 07:14:08 -0300238/* table of the disabled controls */
239static const unsigned ctrl_dis[] = {
240[SEN_OV2610] = (1 << NCTRL) - 1, /* no control */
241
242[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
243
244[SEN_OV6620] = (1 << HFLIP) |
245 (1 << VFLIP),
246
247[SEN_OV6630] = (1 << HFLIP) |
248 (1 << VFLIP),
249
250[SEN_OV66308AF] = (1 << HFLIP) |
251 (1 << VFLIP),
252
253[SEN_OV7610] = (1 << HFLIP) |
254 (1 << VFLIP),
255
256[SEN_OV7620] = (1 << HFLIP) |
257 (1 << VFLIP),
258
259[SEN_OV7620AE] = (1 << HFLIP) |
260 (1 << VFLIP),
261
262[SEN_OV7640] = (1 << HFLIP) |
263 (1 << VFLIP) |
264 (1 << AUTOBRIGHT) |
265 (1 << CONTRAST),
266
267[SEN_OV7648] = (1 << HFLIP) |
268 (1 << VFLIP) |
269 (1 << AUTOBRIGHT) |
270 (1 << CONTRAST),
271
Jean-François Moine42e142f2010-11-13 05:10:27 -0300272[SEN_OV7660] = (1 << AUTOBRIGHT),
273
Jean-François Moine83db7682010-11-12 07:14:08 -0300274[SEN_OV7670] = (1 << COLORS) |
275 (1 << AUTOBRIGHT),
276
277[SEN_OV76BE] = (1 << HFLIP) |
278 (1 << VFLIP),
279
280[SEN_OV8610] = (1 << HFLIP) |
281 (1 << VFLIP) |
282 (1 << FREQ),
283};
284
Hans de Goede49809d62009-06-07 12:10:39 -0300285static const struct v4l2_pix_format ov519_vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300286 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
287 .bytesperline = 320,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300288 .sizeimage = 320 * 240 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300289 .colorspace = V4L2_COLORSPACE_JPEG,
290 .priv = 1},
291 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
292 .bytesperline = 640,
293 .sizeimage = 640 * 480 * 3 / 8 + 590,
294 .colorspace = V4L2_COLORSPACE_JPEG,
295 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300296};
Hans de Goede49809d62009-06-07 12:10:39 -0300297static const struct v4l2_pix_format ov519_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300298 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
299 .bytesperline = 160,
300 .sizeimage = 160 * 120 * 3 / 8 + 590,
301 .colorspace = V4L2_COLORSPACE_JPEG,
302 .priv = 3},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300303 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
304 .bytesperline = 176,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300305 .sizeimage = 176 * 144 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300306 .colorspace = V4L2_COLORSPACE_JPEG,
307 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300308 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
309 .bytesperline = 320,
310 .sizeimage = 320 * 240 * 3 / 8 + 590,
311 .colorspace = V4L2_COLORSPACE_JPEG,
312 .priv = 2},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300313 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
314 .bytesperline = 352,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300315 .sizeimage = 352 * 288 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300316 .colorspace = V4L2_COLORSPACE_JPEG,
317 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300318};
319
Hans de Goedeb282d872009-06-14 19:10:40 -0300320/* Note some of the sizeimage values for the ov511 / ov518 may seem
321 larger then necessary, however they need to be this big as the ov511 /
322 ov518 always fills the entire isoc frame, using 0 padding bytes when
323 it doesn't have any data. So with low framerates the amount of data
324 transfered can become quite large (libv4l will remove all the 0 padding
325 in userspace). */
Hans de Goede49809d62009-06-07 12:10:39 -0300326static const struct v4l2_pix_format ov518_vga_mode[] = {
327 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
328 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300329 .sizeimage = 320 * 240 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300330 .colorspace = V4L2_COLORSPACE_JPEG,
331 .priv = 1},
332 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
333 .bytesperline = 640,
Hans de Goedeb282d872009-06-14 19:10:40 -0300334 .sizeimage = 640 * 480 * 2,
Hans de Goede49809d62009-06-07 12:10:39 -0300335 .colorspace = V4L2_COLORSPACE_JPEG,
336 .priv = 0},
337};
338static const struct v4l2_pix_format ov518_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300339 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
340 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300341 .sizeimage = 70000,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300342 .colorspace = V4L2_COLORSPACE_JPEG,
343 .priv = 3},
Hans de Goede49809d62009-06-07 12:10:39 -0300344 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
345 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300346 .sizeimage = 70000,
Hans de Goede49809d62009-06-07 12:10:39 -0300347 .colorspace = V4L2_COLORSPACE_JPEG,
348 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300349 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
350 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300351 .sizeimage = 320 * 240 * 3,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300352 .colorspace = V4L2_COLORSPACE_JPEG,
353 .priv = 2},
Hans de Goede49809d62009-06-07 12:10:39 -0300354 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
355 .bytesperline = 352,
Hans de Goedeb282d872009-06-14 19:10:40 -0300356 .sizeimage = 352 * 288 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300357 .colorspace = V4L2_COLORSPACE_JPEG,
358 .priv = 0},
359};
360
Hans de Goede1876bb92009-06-14 06:45:50 -0300361static const struct v4l2_pix_format ov511_vga_mode[] = {
362 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
363 .bytesperline = 320,
364 .sizeimage = 320 * 240 * 3,
365 .colorspace = V4L2_COLORSPACE_JPEG,
366 .priv = 1},
367 {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
368 .bytesperline = 640,
369 .sizeimage = 640 * 480 * 2,
370 .colorspace = V4L2_COLORSPACE_JPEG,
371 .priv = 0},
372};
373static const struct v4l2_pix_format ov511_sif_mode[] = {
374 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
375 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300376 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300377 .colorspace = V4L2_COLORSPACE_JPEG,
378 .priv = 3},
379 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
380 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300381 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300382 .colorspace = V4L2_COLORSPACE_JPEG,
383 .priv = 1},
384 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
385 .bytesperline = 320,
386 .sizeimage = 320 * 240 * 3,
387 .colorspace = V4L2_COLORSPACE_JPEG,
388 .priv = 2},
389 {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
390 .bytesperline = 352,
391 .sizeimage = 352 * 288 * 3,
392 .colorspace = V4L2_COLORSPACE_JPEG,
393 .priv = 0},
394};
Hans de Goede49809d62009-06-07 12:10:39 -0300395
Hans de Goede635118d2009-10-11 09:49:03 -0300396static const struct v4l2_pix_format ovfx2_vga_mode[] = {
397 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
398 .bytesperline = 320,
399 .sizeimage = 320 * 240,
400 .colorspace = V4L2_COLORSPACE_SRGB,
401 .priv = 1},
402 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
403 .bytesperline = 640,
404 .sizeimage = 640 * 480,
405 .colorspace = V4L2_COLORSPACE_SRGB,
406 .priv = 0},
407};
408static const struct v4l2_pix_format ovfx2_cif_mode[] = {
409 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
410 .bytesperline = 160,
411 .sizeimage = 160 * 120,
412 .colorspace = V4L2_COLORSPACE_SRGB,
413 .priv = 3},
414 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
415 .bytesperline = 176,
416 .sizeimage = 176 * 144,
417 .colorspace = V4L2_COLORSPACE_SRGB,
418 .priv = 1},
419 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
420 .bytesperline = 320,
421 .sizeimage = 320 * 240,
422 .colorspace = V4L2_COLORSPACE_SRGB,
423 .priv = 2},
424 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
425 .bytesperline = 352,
426 .sizeimage = 352 * 288,
427 .colorspace = V4L2_COLORSPACE_SRGB,
428 .priv = 0},
429};
430static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
431 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
432 .bytesperline = 1600,
433 .sizeimage = 1600 * 1200,
434 .colorspace = V4L2_COLORSPACE_SRGB},
435};
436static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300437 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
438 .bytesperline = 640,
439 .sizeimage = 640 * 480,
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300440 .colorspace = V4L2_COLORSPACE_SRGB,
441 .priv = 1},
442 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
443 .bytesperline = 800,
444 .sizeimage = 800 * 600,
445 .colorspace = V4L2_COLORSPACE_SRGB,
446 .priv = 1},
447 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
448 .bytesperline = 1024,
449 .sizeimage = 1024 * 768,
450 .colorspace = V4L2_COLORSPACE_SRGB,
451 .priv = 1},
452 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
453 .bytesperline = 1600,
454 .sizeimage = 1600 * 1200,
455 .colorspace = V4L2_COLORSPACE_SRGB,
456 .priv = 0},
457 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
458 .bytesperline = 2048,
459 .sizeimage = 2048 * 1536,
460 .colorspace = V4L2_COLORSPACE_SRGB,
461 .priv = 0},
Hans de Goede635118d2009-10-11 09:49:03 -0300462};
463
Hans de Goede49809d62009-06-07 12:10:39 -0300464/* Registers common to OV511 / OV518 */
Hans de Goede1876bb92009-06-14 06:45:50 -0300465#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
Jean-François Moine780e3122010-10-19 04:29:10 -0300466#define R51x_SYS_RESET 0x50
Hans de Goede1876bb92009-06-14 06:45:50 -0300467 /* Reset type flags */
468 #define OV511_RESET_OMNICE 0x08
Jean-François Moine780e3122010-10-19 04:29:10 -0300469#define R51x_SYS_INIT 0x53
Hans de Goede49809d62009-06-07 12:10:39 -0300470#define R51x_SYS_SNAP 0x52
Jean-François Moine87bae742010-11-12 05:31:34 -0300471#define R51x_SYS_CUST_ID 0x5f
Hans de Goede49809d62009-06-07 12:10:39 -0300472#define R51x_COMP_LUT_BEGIN 0x80
473
474/* OV511 Camera interface register numbers */
Hans de Goede1876bb92009-06-14 06:45:50 -0300475#define R511_CAM_DELAY 0x10
476#define R511_CAM_EDGE 0x11
477#define R511_CAM_PXCNT 0x12
478#define R511_CAM_LNCNT 0x13
479#define R511_CAM_PXDIV 0x14
480#define R511_CAM_LNDIV 0x15
481#define R511_CAM_UV_EN 0x16
482#define R511_CAM_LINE_MODE 0x17
483#define R511_CAM_OPTS 0x18
484
485#define R511_SNAP_FRAME 0x19
Jean-François Moine87bae742010-11-12 05:31:34 -0300486#define R511_SNAP_PXCNT 0x1a
487#define R511_SNAP_LNCNT 0x1b
488#define R511_SNAP_PXDIV 0x1c
489#define R511_SNAP_LNDIV 0x1d
490#define R511_SNAP_UV_EN 0x1e
491#define R511_SNAP_UV_EN 0x1e
492#define R511_SNAP_OPTS 0x1f
Hans de Goede1876bb92009-06-14 06:45:50 -0300493
494#define R511_DRAM_FLOW_CTL 0x20
495#define R511_FIFO_OPTS 0x31
496#define R511_I2C_CTL 0x40
Hans de Goede49809d62009-06-07 12:10:39 -0300497#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
Hans de Goede1876bb92009-06-14 06:45:50 -0300498#define R511_COMP_EN 0x78
499#define R511_COMP_LUT_EN 0x79
Hans de Goede49809d62009-06-07 12:10:39 -0300500
501/* OV518 Camera interface register numbers */
502#define R518_GPIO_OUT 0x56 /* OV518(+) only */
503#define R518_GPIO_CTL 0x57 /* OV518(+) only */
504
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300505/* OV519 Camera interface register numbers */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -0300506#define OV519_R10_H_SIZE 0x10
507#define OV519_R11_V_SIZE 0x11
508#define OV519_R12_X_OFFSETL 0x12
509#define OV519_R13_X_OFFSETH 0x13
510#define OV519_R14_Y_OFFSETL 0x14
511#define OV519_R15_Y_OFFSETH 0x15
512#define OV519_R16_DIVIDER 0x16
513#define OV519_R20_DFR 0x20
514#define OV519_R25_FORMAT 0x25
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300515
516/* OV519 System Controller register numbers */
Jean-François Moine21867802010-11-12 06:12:09 -0300517#define OV519_R51_RESET1 0x51
518#define OV519_R54_EN_CLK1 0x54
Jean-François Moineb4e96ea2010-11-12 16:13:17 -0300519#define OV519_R57_SNAPSHOT 0x57
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300520
521#define OV519_GPIO_DATA_OUT0 0x71
522#define OV519_GPIO_IO_CTRL0 0x72
523
Jean-François Moine87bae742010-11-12 05:31:34 -0300524/*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300525
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300526/*
527 * The FX2 chip does not give us a zero length read at end of frame.
528 * It does, however, give a short read at the end of a frame, if
Daniel Mack3ad2f3f2010-02-03 08:01:28 +0800529 * necessary, rather than run two frames together.
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300530 *
531 * By choosing the right bulk transfer size, we are guaranteed to always
532 * get a short read for the last read of each frame. Frame sizes are
533 * always a composite number (width * height, or a multiple) so if we
534 * choose a prime number, we are guaranteed that the last read of a
535 * frame will be short.
536 *
537 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
538 * otherwise EOVERFLOW "babbling" errors occur. I have not been able
539 * to figure out why. [PMiller]
540 *
541 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
542 *
543 * It isn't enough to know the number of bytes per frame, in case we
544 * have data dropouts or buffer overruns (even though the FX2 double
545 * buffers, there are some pretty strict real time constraints for
546 * isochronous transfer for larger frame sizes).
547 */
548#define OVFX2_BULK_SIZE (13 * 4096)
549
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300550/* I2C registers */
551#define R51x_I2C_W_SID 0x41
552#define R51x_I2C_SADDR_3 0x42
553#define R51x_I2C_SADDR_2 0x43
554#define R51x_I2C_R_SID 0x44
555#define R51x_I2C_DATA 0x45
556#define R518_I2C_CTL 0x47 /* OV518(+) only */
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300557#define OVFX2_I2C_ADDR 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300558
559/* I2C ADDRESSES */
560#define OV7xx0_SID 0x42
Hans de Goede229bb7d2009-10-11 07:41:46 -0300561#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300562#define OV8xx0_SID 0xa0
563#define OV6xx0_SID 0xc0
564
565/* OV7610 registers */
566#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
Hans de Goede49809d62009-06-07 12:10:39 -0300567#define OV7610_REG_BLUE 0x01 /* blue channel balance */
568#define OV7610_REG_RED 0x02 /* red channel balance */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300569#define OV7610_REG_SAT 0x03 /* saturation */
570#define OV8610_REG_HUE 0x04 /* 04 reserved */
571#define OV7610_REG_CNT 0x05 /* Y contrast */
572#define OV7610_REG_BRT 0x06 /* Y brightness */
573#define OV7610_REG_COM_C 0x14 /* misc common regs */
574#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
575#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
576#define OV7610_REG_COM_I 0x29 /* misc settings */
577
Jean-François Moine42e142f2010-11-13 05:10:27 -0300578/* OV7660 and OV7670 registers */
Jean-François Moine21867802010-11-12 06:12:09 -0300579#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
580#define OV7670_R01_BLUE 0x01 /* blue gain */
581#define OV7670_R02_RED 0x02 /* red gain */
582#define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
583#define OV7670_R04_COM1 0x04 /* Control 1 */
584/*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */
585#define OV7670_R0C_COM3 0x0c /* Control 3 */
586#define OV7670_R0D_COM4 0x0d /* Control 4 */
587#define OV7670_R0E_COM5 0x0e /* All "reserved" */
588#define OV7670_R0F_COM6 0x0f /* Control 6 */
589#define OV7670_R10_AECH 0x10 /* More bits of AEC value */
590#define OV7670_R11_CLKRC 0x11 /* Clock control */
591#define OV7670_R12_COM7 0x12 /* Control 7 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300592#define OV7670_COM7_FMT_VGA 0x00
593/*#define OV7670_COM7_YUV 0x00 * YUV */
594#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
595#define OV7670_COM7_FMT_MASK 0x38
596#define OV7670_COM7_RESET 0x80 /* Register reset */
Jean-François Moine21867802010-11-12 06:12:09 -0300597#define OV7670_R13_COM8 0x13 /* Control 8 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300598#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
599#define OV7670_COM8_AWB 0x02 /* White balance enable */
600#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
601#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
602#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
603#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
Jean-François Moine21867802010-11-12 06:12:09 -0300604#define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */
605#define OV7670_R15_COM10 0x15 /* Control 10 */
606#define OV7670_R17_HSTART 0x17 /* Horiz start high bits */
607#define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */
608#define OV7670_R19_VSTART 0x19 /* Vert start high bits */
609#define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */
610#define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */
Jean-François Moine87bae742010-11-12 05:31:34 -0300611#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
612#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
Jean-François Moine21867802010-11-12 06:12:09 -0300613#define OV7670_R24_AEW 0x24 /* AGC upper limit */
614#define OV7670_R25_AEB 0x25 /* AGC lower limit */
615#define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */
616#define OV7670_R32_HREF 0x32 /* HREF pieces */
617#define OV7670_R3A_TSLB 0x3a /* lots of stuff */
618#define OV7670_R3B_COM11 0x3b /* Control 11 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300619#define OV7670_COM11_EXP 0x02
620#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
Jean-François Moine21867802010-11-12 06:12:09 -0300621#define OV7670_R3C_COM12 0x3c /* Control 12 */
622#define OV7670_R3D_COM13 0x3d /* Control 13 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300623#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
624#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
Jean-François Moine21867802010-11-12 06:12:09 -0300625#define OV7670_R3E_COM14 0x3e /* Control 14 */
626#define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */
627#define OV7670_R40_COM15 0x40 /* Control 15 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300628/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */
Jean-François Moine21867802010-11-12 06:12:09 -0300629#define OV7670_R41_COM16 0x41 /* Control 16 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300630#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
Jean-François Moine42e142f2010-11-13 05:10:27 -0300631/* end of ov7660 common registers */
Jean-François Moine21867802010-11-12 06:12:09 -0300632#define OV7670_R55_BRIGHT 0x55 /* Brightness */
633#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
634#define OV7670_R69_GFIX 0x69 /* Fix gain control */
635/*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */
636#define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */
637#define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
638#define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */
639#define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
640#define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
641#define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
642#define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
643#define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */
644#define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300645
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300646struct ov_regvals {
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300647 u8 reg;
648 u8 val;
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300649};
650struct ov_i2c_regvals {
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300651 u8 reg;
652 u8 val;
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300653};
654
Hans de Goede635118d2009-10-11 09:49:03 -0300655/* Settings for OV2610 camera chip */
Jean-François Moine780e3122010-10-19 04:29:10 -0300656static const struct ov_i2c_regvals norm_2610[] = {
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300657 { 0x12, 0x80 }, /* reset */
Hans de Goede635118d2009-10-11 09:49:03 -0300658};
659
Jean-François Moine780e3122010-10-19 04:29:10 -0300660static const struct ov_i2c_regvals norm_3620b[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300661 /*
662 * From the datasheet: "Note that after writing to register COMH
663 * (0x12) to change the sensor mode, registers related to the
664 * sensor’s cropping window will be reset back to their default
665 * values."
666 *
667 * "wait 4096 external clock ... to make sure the sensor is
668 * stable and ready to access registers" i.e. 160us at 24MHz
669 */
Hans de Goede635118d2009-10-11 09:49:03 -0300670 { 0x12, 0x80 }, /* COMH reset */
671 { 0x12, 0x00 }, /* QXGA, master */
672
673 /*
674 * 11 CLKRC "Clock Rate Control"
675 * [7] internal frequency doublers: on
676 * [6] video port mode: master
677 * [5:0] clock divider: 1
678 */
679 { 0x11, 0x80 },
680
681 /*
682 * 13 COMI "Common Control I"
683 * = 192 (0xC0) 11000000
684 * COMI[7] "AEC speed selection"
685 * = 1 (0x01) 1....... "Faster AEC correction"
686 * COMI[6] "AEC speed step selection"
687 * = 1 (0x01) .1...... "Big steps, fast"
688 * COMI[5] "Banding filter on off"
689 * = 0 (0x00) ..0..... "Off"
690 * COMI[4] "Banding filter option"
691 * = 0 (0x00) ...0.... "Main clock is 48 MHz and
692 * the PLL is ON"
693 * COMI[3] "Reserved"
694 * = 0 (0x00) ....0...
695 * COMI[2] "AGC auto manual control selection"
696 * = 0 (0x00) .....0.. "Manual"
697 * COMI[1] "AWB auto manual control selection"
698 * = 0 (0x00) ......0. "Manual"
699 * COMI[0] "Exposure control"
700 * = 0 (0x00) .......0 "Manual"
701 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300702 { 0x13, 0xc0 },
Hans de Goede635118d2009-10-11 09:49:03 -0300703
704 /*
705 * 09 COMC "Common Control C"
706 * = 8 (0x08) 00001000
707 * COMC[7:5] "Reserved"
708 * = 0 (0x00) 000.....
709 * COMC[4] "Sleep Mode Enable"
710 * = 0 (0x00) ...0.... "Normal mode"
711 * COMC[3:2] "Sensor sampling reset timing selection"
712 * = 2 (0x02) ....10.. "Longer reset time"
713 * COMC[1:0] "Output drive current select"
714 * = 0 (0x00) ......00 "Weakest"
715 */
716 { 0x09, 0x08 },
717
718 /*
719 * 0C COMD "Common Control D"
720 * = 8 (0x08) 00001000
721 * COMD[7] "Reserved"
722 * = 0 (0x00) 0.......
723 * COMD[6] "Swap MSB and LSB at the output port"
724 * = 0 (0x00) .0...... "False"
725 * COMD[5:3] "Reserved"
726 * = 1 (0x01) ..001...
727 * COMD[2] "Output Average On Off"
728 * = 0 (0x00) .....0.. "Output Normal"
729 * COMD[1] "Sensor precharge voltage selection"
730 * = 0 (0x00) ......0. "Selects internal
731 * reference precharge
732 * voltage"
733 * COMD[0] "Snapshot option"
734 * = 0 (0x00) .......0 "Enable live video output
735 * after snapshot sequence"
736 */
737 { 0x0c, 0x08 },
738
739 /*
740 * 0D COME "Common Control E"
741 * = 161 (0xA1) 10100001
742 * COME[7] "Output average option"
743 * = 1 (0x01) 1....... "Output average of 4 pixels"
744 * COME[6] "Anti-blooming control"
745 * = 0 (0x00) .0...... "Off"
746 * COME[5:3] "Reserved"
747 * = 4 (0x04) ..100...
748 * COME[2] "Clock output power down pin status"
749 * = 0 (0x00) .....0.. "Tri-state data output pin
750 * on power down"
751 * COME[1] "Data output pin status selection at power down"
752 * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
753 * HREF, and CHSYNC pins on
754 * power down"
755 * COME[0] "Auto zero circuit select"
756 * = 1 (0x01) .......1 "On"
757 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300758 { 0x0d, 0xa1 },
Hans de Goede635118d2009-10-11 09:49:03 -0300759
760 /*
761 * 0E COMF "Common Control F"
762 * = 112 (0x70) 01110000
763 * COMF[7] "System clock selection"
764 * = 0 (0x00) 0....... "Use 24 MHz system clock"
765 * COMF[6:4] "Reserved"
766 * = 7 (0x07) .111....
767 * COMF[3] "Manual auto negative offset canceling selection"
768 * = 0 (0x00) ....0... "Auto detect negative
769 * offset and cancel it"
770 * COMF[2:0] "Reserved"
771 * = 0 (0x00) .....000
772 */
773 { 0x0e, 0x70 },
774
775 /*
776 * 0F COMG "Common Control G"
777 * = 66 (0x42) 01000010
778 * COMG[7] "Optical black output selection"
779 * = 0 (0x00) 0....... "Disable"
780 * COMG[6] "Black level calibrate selection"
781 * = 1 (0x01) .1...... "Use optical black pixels
782 * to calibrate"
783 * COMG[5:4] "Reserved"
784 * = 0 (0x00) ..00....
785 * COMG[3] "Channel offset adjustment"
786 * = 0 (0x00) ....0... "Disable offset adjustment"
787 * COMG[2] "ADC black level calibration option"
788 * = 0 (0x00) .....0.. "Use B/G line and G/R
789 * line to calibrate each
790 * channel's black level"
791 * COMG[1] "Reserved"
792 * = 1 (0x01) ......1.
793 * COMG[0] "ADC black level calibration enable"
794 * = 0 (0x00) .......0 "Disable"
795 */
796 { 0x0f, 0x42 },
797
798 /*
799 * 14 COMJ "Common Control J"
800 * = 198 (0xC6) 11000110
801 * COMJ[7:6] "AGC gain ceiling"
802 * = 3 (0x03) 11...... "8x"
803 * COMJ[5:4] "Reserved"
804 * = 0 (0x00) ..00....
805 * COMJ[3] "Auto banding filter"
806 * = 0 (0x00) ....0... "Banding filter is always
807 * on off depending on
808 * COMI[5] setting"
809 * COMJ[2] "VSYNC drop option"
810 * = 1 (0x01) .....1.. "SYNC is dropped if frame
811 * data is dropped"
812 * COMJ[1] "Frame data drop"
813 * = 1 (0x01) ......1. "Drop frame data if
814 * exposure is not within
815 * tolerance. In AEC mode,
816 * data is normally dropped
817 * when data is out of
818 * range."
819 * COMJ[0] "Reserved"
820 * = 0 (0x00) .......0
821 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300822 { 0x14, 0xc6 },
Hans de Goede635118d2009-10-11 09:49:03 -0300823
824 /*
825 * 15 COMK "Common Control K"
826 * = 2 (0x02) 00000010
827 * COMK[7] "CHSYNC pin output swap"
828 * = 0 (0x00) 0....... "CHSYNC"
829 * COMK[6] "HREF pin output swap"
830 * = 0 (0x00) .0...... "HREF"
831 * COMK[5] "PCLK output selection"
832 * = 0 (0x00) ..0..... "PCLK always output"
833 * COMK[4] "PCLK edge selection"
834 * = 0 (0x00) ...0.... "Data valid on falling edge"
835 * COMK[3] "HREF output polarity"
836 * = 0 (0x00) ....0... "positive"
837 * COMK[2] "Reserved"
838 * = 0 (0x00) .....0..
839 * COMK[1] "VSYNC polarity"
840 * = 1 (0x01) ......1. "negative"
841 * COMK[0] "HSYNC polarity"
842 * = 0 (0x00) .......0 "positive"
843 */
844 { 0x15, 0x02 },
845
846 /*
847 * 33 CHLF "Current Control"
848 * = 9 (0x09) 00001001
849 * CHLF[7:6] "Sensor current control"
850 * = 0 (0x00) 00......
851 * CHLF[5] "Sensor current range control"
852 * = 0 (0x00) ..0..... "normal range"
853 * CHLF[4] "Sensor current"
854 * = 0 (0x00) ...0.... "normal current"
855 * CHLF[3] "Sensor buffer current control"
856 * = 1 (0x01) ....1... "half current"
857 * CHLF[2] "Column buffer current control"
858 * = 0 (0x00) .....0.. "normal current"
859 * CHLF[1] "Analog DSP current control"
860 * = 0 (0x00) ......0. "normal current"
861 * CHLF[1] "ADC current control"
862 * = 0 (0x00) ......0. "normal current"
863 */
864 { 0x33, 0x09 },
865
866 /*
867 * 34 VBLM "Blooming Control"
868 * = 80 (0x50) 01010000
869 * VBLM[7] "Hard soft reset switch"
870 * = 0 (0x00) 0....... "Hard reset"
871 * VBLM[6:4] "Blooming voltage selection"
872 * = 5 (0x05) .101....
873 * VBLM[3:0] "Sensor current control"
874 * = 0 (0x00) ....0000
875 */
876 { 0x34, 0x50 },
877
878 /*
879 * 36 VCHG "Sensor Precharge Voltage Control"
880 * = 0 (0x00) 00000000
881 * VCHG[7] "Reserved"
882 * = 0 (0x00) 0.......
883 * VCHG[6:4] "Sensor precharge voltage control"
884 * = 0 (0x00) .000....
885 * VCHG[3:0] "Sensor array common reference"
886 * = 0 (0x00) ....0000
887 */
888 { 0x36, 0x00 },
889
890 /*
891 * 37 ADC "ADC Reference Control"
892 * = 4 (0x04) 00000100
893 * ADC[7:4] "Reserved"
894 * = 0 (0x00) 0000....
895 * ADC[3] "ADC input signal range"
896 * = 0 (0x00) ....0... "Input signal 1.0x"
897 * ADC[2:0] "ADC range control"
898 * = 4 (0x04) .....100
899 */
900 { 0x37, 0x04 },
901
902 /*
903 * 38 ACOM "Analog Common Ground"
904 * = 82 (0x52) 01010010
905 * ACOM[7] "Analog gain control"
906 * = 0 (0x00) 0....... "Gain 1x"
907 * ACOM[6] "Analog black level calibration"
908 * = 1 (0x01) .1...... "On"
909 * ACOM[5:0] "Reserved"
910 * = 18 (0x12) ..010010
911 */
912 { 0x38, 0x52 },
913
914 /*
915 * 3A FREFA "Internal Reference Adjustment"
916 * = 0 (0x00) 00000000
917 * FREFA[7:0] "Range"
918 * = 0 (0x00) 00000000
919 */
920 { 0x3a, 0x00 },
921
922 /*
923 * 3C FVOPT "Internal Reference Adjustment"
924 * = 31 (0x1F) 00011111
925 * FVOPT[7:0] "Range"
926 * = 31 (0x1F) 00011111
927 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300928 { 0x3c, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -0300929
930 /*
931 * 44 Undocumented = 0 (0x00) 00000000
932 * 44[7:0] "It's a secret"
933 * = 0 (0x00) 00000000
934 */
935 { 0x44, 0x00 },
936
937 /*
938 * 40 Undocumented = 0 (0x00) 00000000
939 * 40[7:0] "It's a secret"
940 * = 0 (0x00) 00000000
941 */
942 { 0x40, 0x00 },
943
944 /*
945 * 41 Undocumented = 0 (0x00) 00000000
946 * 41[7:0] "It's a secret"
947 * = 0 (0x00) 00000000
948 */
949 { 0x41, 0x00 },
950
951 /*
952 * 42 Undocumented = 0 (0x00) 00000000
953 * 42[7:0] "It's a secret"
954 * = 0 (0x00) 00000000
955 */
956 { 0x42, 0x00 },
957
958 /*
959 * 43 Undocumented = 0 (0x00) 00000000
960 * 43[7:0] "It's a secret"
961 * = 0 (0x00) 00000000
962 */
963 { 0x43, 0x00 },
964
965 /*
966 * 45 Undocumented = 128 (0x80) 10000000
967 * 45[7:0] "It's a secret"
968 * = 128 (0x80) 10000000
969 */
970 { 0x45, 0x80 },
971
972 /*
973 * 48 Undocumented = 192 (0xC0) 11000000
974 * 48[7:0] "It's a secret"
975 * = 192 (0xC0) 11000000
976 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300977 { 0x48, 0xc0 },
Hans de Goede635118d2009-10-11 09:49:03 -0300978
979 /*
980 * 49 Undocumented = 25 (0x19) 00011001
981 * 49[7:0] "It's a secret"
982 * = 25 (0x19) 00011001
983 */
984 { 0x49, 0x19 },
985
986 /*
987 * 4B Undocumented = 128 (0x80) 10000000
988 * 4B[7:0] "It's a secret"
989 * = 128 (0x80) 10000000
990 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300991 { 0x4b, 0x80 },
Hans de Goede635118d2009-10-11 09:49:03 -0300992
993 /*
994 * 4D Undocumented = 196 (0xC4) 11000100
995 * 4D[7:0] "It's a secret"
996 * = 196 (0xC4) 11000100
997 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300998 { 0x4d, 0xc4 },
Hans de Goede635118d2009-10-11 09:49:03 -0300999
1000 /*
1001 * 35 VREF "Reference Voltage Control"
Jean-François Moine87bae742010-11-12 05:31:34 -03001002 * = 76 (0x4c) 01001100
Hans de Goede635118d2009-10-11 09:49:03 -03001003 * VREF[7:5] "Column high reference control"
1004 * = 2 (0x02) 010..... "higher voltage"
1005 * VREF[4:2] "Column low reference control"
1006 * = 3 (0x03) ...011.. "Highest voltage"
1007 * VREF[1:0] "Reserved"
1008 * = 0 (0x00) ......00
1009 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001010 { 0x35, 0x4c },
Hans de Goede635118d2009-10-11 09:49:03 -03001011
1012 /*
1013 * 3D Undocumented = 0 (0x00) 00000000
1014 * 3D[7:0] "It's a secret"
1015 * = 0 (0x00) 00000000
1016 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001017 { 0x3d, 0x00 },
Hans de Goede635118d2009-10-11 09:49:03 -03001018
1019 /*
1020 * 3E Undocumented = 0 (0x00) 00000000
1021 * 3E[7:0] "It's a secret"
1022 * = 0 (0x00) 00000000
1023 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001024 { 0x3e, 0x00 },
Hans de Goede635118d2009-10-11 09:49:03 -03001025
1026 /*
1027 * 3B FREFB "Internal Reference Adjustment"
1028 * = 24 (0x18) 00011000
1029 * FREFB[7:0] "Range"
1030 * = 24 (0x18) 00011000
1031 */
1032 { 0x3b, 0x18 },
1033
1034 /*
1035 * 33 CHLF "Current Control"
1036 * = 25 (0x19) 00011001
1037 * CHLF[7:6] "Sensor current control"
1038 * = 0 (0x00) 00......
1039 * CHLF[5] "Sensor current range control"
1040 * = 0 (0x00) ..0..... "normal range"
1041 * CHLF[4] "Sensor current"
1042 * = 1 (0x01) ...1.... "double current"
1043 * CHLF[3] "Sensor buffer current control"
1044 * = 1 (0x01) ....1... "half current"
1045 * CHLF[2] "Column buffer current control"
1046 * = 0 (0x00) .....0.. "normal current"
1047 * CHLF[1] "Analog DSP current control"
1048 * = 0 (0x00) ......0. "normal current"
1049 * CHLF[1] "ADC current control"
1050 * = 0 (0x00) ......0. "normal current"
1051 */
1052 { 0x33, 0x19 },
1053
1054 /*
1055 * 34 VBLM "Blooming Control"
1056 * = 90 (0x5A) 01011010
1057 * VBLM[7] "Hard soft reset switch"
1058 * = 0 (0x00) 0....... "Hard reset"
1059 * VBLM[6:4] "Blooming voltage selection"
1060 * = 5 (0x05) .101....
1061 * VBLM[3:0] "Sensor current control"
1062 * = 10 (0x0A) ....1010
1063 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001064 { 0x34, 0x5a },
Hans de Goede635118d2009-10-11 09:49:03 -03001065
1066 /*
1067 * 3B FREFB "Internal Reference Adjustment"
1068 * = 0 (0x00) 00000000
1069 * FREFB[7:0] "Range"
1070 * = 0 (0x00) 00000000
1071 */
1072 { 0x3b, 0x00 },
1073
1074 /*
1075 * 33 CHLF "Current Control"
1076 * = 9 (0x09) 00001001
1077 * CHLF[7:6] "Sensor current control"
1078 * = 0 (0x00) 00......
1079 * CHLF[5] "Sensor current range control"
1080 * = 0 (0x00) ..0..... "normal range"
1081 * CHLF[4] "Sensor current"
1082 * = 0 (0x00) ...0.... "normal current"
1083 * CHLF[3] "Sensor buffer current control"
1084 * = 1 (0x01) ....1... "half current"
1085 * CHLF[2] "Column buffer current control"
1086 * = 0 (0x00) .....0.. "normal current"
1087 * CHLF[1] "Analog DSP current control"
1088 * = 0 (0x00) ......0. "normal current"
1089 * CHLF[1] "ADC current control"
1090 * = 0 (0x00) ......0. "normal current"
1091 */
1092 { 0x33, 0x09 },
1093
1094 /*
1095 * 34 VBLM "Blooming Control"
1096 * = 80 (0x50) 01010000
1097 * VBLM[7] "Hard soft reset switch"
1098 * = 0 (0x00) 0....... "Hard reset"
1099 * VBLM[6:4] "Blooming voltage selection"
1100 * = 5 (0x05) .101....
1101 * VBLM[3:0] "Sensor current control"
1102 * = 0 (0x00) ....0000
1103 */
1104 { 0x34, 0x50 },
1105
1106 /*
1107 * 12 COMH "Common Control H"
1108 * = 64 (0x40) 01000000
1109 * COMH[7] "SRST"
1110 * = 0 (0x00) 0....... "No-op"
1111 * COMH[6:4] "Resolution selection"
1112 * = 4 (0x04) .100.... "XGA"
1113 * COMH[3] "Master slave selection"
1114 * = 0 (0x00) ....0... "Master mode"
1115 * COMH[2] "Internal B/R channel option"
1116 * = 0 (0x00) .....0.. "B/R use same channel"
1117 * COMH[1] "Color bar test pattern"
1118 * = 0 (0x00) ......0. "Off"
1119 * COMH[0] "Reserved"
1120 * = 0 (0x00) .......0
1121 */
1122 { 0x12, 0x40 },
1123
1124 /*
1125 * 17 HREFST "Horizontal window start"
1126 * = 31 (0x1F) 00011111
1127 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1128 * = 31 (0x1F) 00011111
1129 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001130 { 0x17, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001131
1132 /*
1133 * 18 HREFEND "Horizontal window end"
1134 * = 95 (0x5F) 01011111
1135 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1136 * = 95 (0x5F) 01011111
1137 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001138 { 0x18, 0x5f },
Hans de Goede635118d2009-10-11 09:49:03 -03001139
1140 /*
1141 * 19 VSTRT "Vertical window start"
1142 * = 0 (0x00) 00000000
1143 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1144 * = 0 (0x00) 00000000
1145 */
1146 { 0x19, 0x00 },
1147
1148 /*
1149 * 1A VEND "Vertical window end"
1150 * = 96 (0x60) 01100000
1151 * VEND[7:0] "Vertical Window End, 8 MSBs"
1152 * = 96 (0x60) 01100000
1153 */
1154 { 0x1a, 0x60 },
1155
1156 /*
1157 * 32 COMM "Common Control M"
1158 * = 18 (0x12) 00010010
1159 * COMM[7:6] "Pixel clock divide option"
1160 * = 0 (0x00) 00...... "/1"
1161 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1162 * = 2 (0x02) ..010...
1163 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1164 * = 2 (0x02) .....010
1165 */
1166 { 0x32, 0x12 },
1167
1168 /*
1169 * 03 COMA "Common Control A"
1170 * = 74 (0x4A) 01001010
1171 * COMA[7:4] "AWB Update Threshold"
1172 * = 4 (0x04) 0100....
1173 * COMA[3:2] "Vertical window end line control 2 LSBs"
1174 * = 2 (0x02) ....10..
1175 * COMA[1:0] "Vertical window start line control 2 LSBs"
1176 * = 2 (0x02) ......10
1177 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001178 { 0x03, 0x4a },
Hans de Goede635118d2009-10-11 09:49:03 -03001179
1180 /*
1181 * 11 CLKRC "Clock Rate Control"
1182 * = 128 (0x80) 10000000
1183 * CLKRC[7] "Internal frequency doublers on off seclection"
1184 * = 1 (0x01) 1....... "On"
1185 * CLKRC[6] "Digital video master slave selection"
1186 * = 0 (0x00) .0...... "Master mode, sensor
1187 * provides PCLK"
1188 * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
1189 * = 0 (0x00) ..000000
1190 */
1191 { 0x11, 0x80 },
1192
1193 /*
1194 * 12 COMH "Common Control H"
1195 * = 0 (0x00) 00000000
1196 * COMH[7] "SRST"
1197 * = 0 (0x00) 0....... "No-op"
1198 * COMH[6:4] "Resolution selection"
1199 * = 0 (0x00) .000.... "QXGA"
1200 * COMH[3] "Master slave selection"
1201 * = 0 (0x00) ....0... "Master mode"
1202 * COMH[2] "Internal B/R channel option"
1203 * = 0 (0x00) .....0.. "B/R use same channel"
1204 * COMH[1] "Color bar test pattern"
1205 * = 0 (0x00) ......0. "Off"
1206 * COMH[0] "Reserved"
1207 * = 0 (0x00) .......0
1208 */
1209 { 0x12, 0x00 },
1210
1211 /*
1212 * 12 COMH "Common Control H"
1213 * = 64 (0x40) 01000000
1214 * COMH[7] "SRST"
1215 * = 0 (0x00) 0....... "No-op"
1216 * COMH[6:4] "Resolution selection"
1217 * = 4 (0x04) .100.... "XGA"
1218 * COMH[3] "Master slave selection"
1219 * = 0 (0x00) ....0... "Master mode"
1220 * COMH[2] "Internal B/R channel option"
1221 * = 0 (0x00) .....0.. "B/R use same channel"
1222 * COMH[1] "Color bar test pattern"
1223 * = 0 (0x00) ......0. "Off"
1224 * COMH[0] "Reserved"
1225 * = 0 (0x00) .......0
1226 */
1227 { 0x12, 0x40 },
1228
1229 /*
1230 * 17 HREFST "Horizontal window start"
1231 * = 31 (0x1F) 00011111
1232 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1233 * = 31 (0x1F) 00011111
1234 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001235 { 0x17, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001236
1237 /*
1238 * 18 HREFEND "Horizontal window end"
1239 * = 95 (0x5F) 01011111
1240 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1241 * = 95 (0x5F) 01011111
1242 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001243 { 0x18, 0x5f },
Hans de Goede635118d2009-10-11 09:49:03 -03001244
1245 /*
1246 * 19 VSTRT "Vertical window start"
1247 * = 0 (0x00) 00000000
1248 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1249 * = 0 (0x00) 00000000
1250 */
1251 { 0x19, 0x00 },
1252
1253 /*
1254 * 1A VEND "Vertical window end"
1255 * = 96 (0x60) 01100000
1256 * VEND[7:0] "Vertical Window End, 8 MSBs"
1257 * = 96 (0x60) 01100000
1258 */
1259 { 0x1a, 0x60 },
1260
1261 /*
1262 * 32 COMM "Common Control M"
1263 * = 18 (0x12) 00010010
1264 * COMM[7:6] "Pixel clock divide option"
1265 * = 0 (0x00) 00...... "/1"
1266 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1267 * = 2 (0x02) ..010...
1268 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1269 * = 2 (0x02) .....010
1270 */
1271 { 0x32, 0x12 },
1272
1273 /*
1274 * 03 COMA "Common Control A"
1275 * = 74 (0x4A) 01001010
1276 * COMA[7:4] "AWB Update Threshold"
1277 * = 4 (0x04) 0100....
1278 * COMA[3:2] "Vertical window end line control 2 LSBs"
1279 * = 2 (0x02) ....10..
1280 * COMA[1:0] "Vertical window start line control 2 LSBs"
1281 * = 2 (0x02) ......10
1282 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001283 { 0x03, 0x4a },
Hans de Goede635118d2009-10-11 09:49:03 -03001284
1285 /*
1286 * 02 RED "Red Gain Control"
1287 * = 175 (0xAF) 10101111
1288 * RED[7] "Action"
1289 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1290 * RED[6:0] "Value"
1291 * = 47 (0x2F) .0101111
1292 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001293 { 0x02, 0xaf },
Hans de Goede635118d2009-10-11 09:49:03 -03001294
1295 /*
1296 * 2D ADDVSL "VSYNC Pulse Width"
1297 * = 210 (0xD2) 11010010
1298 * ADDVSL[7:0] "VSYNC pulse width, LSB"
1299 * = 210 (0xD2) 11010010
1300 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001301 { 0x2d, 0xd2 },
Hans de Goede635118d2009-10-11 09:49:03 -03001302
1303 /*
1304 * 00 GAIN = 24 (0x18) 00011000
1305 * GAIN[7:6] "Reserved"
1306 * = 0 (0x00) 00......
1307 * GAIN[5] "Double"
1308 * = 0 (0x00) ..0..... "False"
1309 * GAIN[4] "Double"
1310 * = 1 (0x01) ...1.... "True"
1311 * GAIN[3:0] "Range"
1312 * = 8 (0x08) ....1000
1313 */
1314 { 0x00, 0x18 },
1315
1316 /*
1317 * 01 BLUE "Blue Gain Control"
1318 * = 240 (0xF0) 11110000
1319 * BLUE[7] "Action"
1320 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1321 * BLUE[6:0] "Value"
1322 * = 112 (0x70) .1110000
1323 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001324 { 0x01, 0xf0 },
Hans de Goede635118d2009-10-11 09:49:03 -03001325
1326 /*
1327 * 10 AEC "Automatic Exposure Control"
1328 * = 10 (0x0A) 00001010
1329 * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
1330 * = 10 (0x0A) 00001010
1331 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001332 { 0x10, 0x0a },
Hans de Goede635118d2009-10-11 09:49:03 -03001333
Jean-François Moine87bae742010-11-12 05:31:34 -03001334 { 0xe1, 0x67 },
1335 { 0xe3, 0x03 },
1336 { 0xe4, 0x26 },
1337 { 0xe5, 0x3e },
1338 { 0xf8, 0x01 },
1339 { 0xff, 0x01 },
Hans de Goede635118d2009-10-11 09:49:03 -03001340};
1341
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001342static const struct ov_i2c_regvals norm_6x20[] = {
1343 { 0x12, 0x80 }, /* reset */
1344 { 0x11, 0x01 },
1345 { 0x03, 0x60 },
1346 { 0x05, 0x7f }, /* For when autoadjust is off */
1347 { 0x07, 0xa8 },
Jean-François Moine87bae742010-11-12 05:31:34 -03001348 /* The ratio of 0x0c and 0x0d controls the white point */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001349 { 0x0c, 0x24 },
1350 { 0x0d, 0x24 },
1351 { 0x0f, 0x15 }, /* COMS */
1352 { 0x10, 0x75 }, /* AEC Exposure time */
1353 { 0x12, 0x24 }, /* Enable AGC */
1354 { 0x14, 0x04 },
1355 /* 0x16: 0x06 helps frame stability with moving objects */
1356 { 0x16, 0x06 },
1357/* { 0x20, 0x30 }, * Aperture correction enable */
1358 { 0x26, 0xb2 }, /* BLC enable */
1359 /* 0x28: 0x05 Selects RGB format if RGB on */
1360 { 0x28, 0x05 },
1361 { 0x2a, 0x04 }, /* Disable framerate adjust */
1362/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
Hans de Goedeae49c402009-06-14 19:15:07 -03001363 { 0x2d, 0x85 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001364 { 0x33, 0xa0 }, /* Color Processing Parameter */
1365 { 0x34, 0xd2 }, /* Max A/D range */
1366 { 0x38, 0x8b },
1367 { 0x39, 0x40 },
1368
1369 { 0x3c, 0x39 }, /* Enable AEC mode changing */
1370 { 0x3c, 0x3c }, /* Change AEC mode */
1371 { 0x3c, 0x24 }, /* Disable AEC mode changing */
1372
1373 { 0x3d, 0x80 },
1374 /* These next two registers (0x4a, 0x4b) are undocumented.
1375 * They control the color balance */
1376 { 0x4a, 0x80 },
1377 { 0x4b, 0x80 },
1378 { 0x4d, 0xd2 }, /* This reduces noise a bit */
1379 { 0x4e, 0xc1 },
1380 { 0x4f, 0x04 },
1381/* Do 50-53 have any effect? */
1382/* Toggle 0x12[2] off and on here? */
1383};
1384
1385static const struct ov_i2c_regvals norm_6x30[] = {
1386 { 0x12, 0x80 }, /* Reset */
1387 { 0x00, 0x1f }, /* Gain */
1388 { 0x01, 0x99 }, /* Blue gain */
1389 { 0x02, 0x7c }, /* Red gain */
1390 { 0x03, 0xc0 }, /* Saturation */
1391 { 0x05, 0x0a }, /* Contrast */
1392 { 0x06, 0x95 }, /* Brightness */
1393 { 0x07, 0x2d }, /* Sharpness */
1394 { 0x0c, 0x20 },
1395 { 0x0d, 0x20 },
Hans de Goede02ab18b2009-06-14 04:32:04 -03001396 { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001397 { 0x0f, 0x05 },
1398 { 0x10, 0x9a },
1399 { 0x11, 0x00 }, /* Pixel clock = fastest */
1400 { 0x12, 0x24 }, /* Enable AGC and AWB */
1401 { 0x13, 0x21 },
1402 { 0x14, 0x80 },
1403 { 0x15, 0x01 },
1404 { 0x16, 0x03 },
1405 { 0x17, 0x38 },
1406 { 0x18, 0xea },
1407 { 0x19, 0x04 },
1408 { 0x1a, 0x93 },
1409 { 0x1b, 0x00 },
1410 { 0x1e, 0xc4 },
1411 { 0x1f, 0x04 },
1412 { 0x20, 0x20 },
1413 { 0x21, 0x10 },
1414 { 0x22, 0x88 },
1415 { 0x23, 0xc0 }, /* Crystal circuit power level */
1416 { 0x25, 0x9a }, /* Increase AEC black ratio */
1417 { 0x26, 0xb2 }, /* BLC enable */
1418 { 0x27, 0xa2 },
1419 { 0x28, 0x00 },
1420 { 0x29, 0x00 },
1421 { 0x2a, 0x84 }, /* 60 Hz power */
1422 { 0x2b, 0xa8 }, /* 60 Hz power */
1423 { 0x2c, 0xa0 },
1424 { 0x2d, 0x95 }, /* Enable auto-brightness */
1425 { 0x2e, 0x88 },
1426 { 0x33, 0x26 },
1427 { 0x34, 0x03 },
1428 { 0x36, 0x8f },
1429 { 0x37, 0x80 },
1430 { 0x38, 0x83 },
1431 { 0x39, 0x80 },
1432 { 0x3a, 0x0f },
1433 { 0x3b, 0x3c },
1434 { 0x3c, 0x1a },
1435 { 0x3d, 0x80 },
1436 { 0x3e, 0x80 },
1437 { 0x3f, 0x0e },
1438 { 0x40, 0x00 }, /* White bal */
1439 { 0x41, 0x00 }, /* White bal */
1440 { 0x42, 0x80 },
1441 { 0x43, 0x3f }, /* White bal */
1442 { 0x44, 0x80 },
1443 { 0x45, 0x20 },
1444 { 0x46, 0x20 },
1445 { 0x47, 0x80 },
1446 { 0x48, 0x7f },
1447 { 0x49, 0x00 },
1448 { 0x4a, 0x00 },
1449 { 0x4b, 0x80 },
1450 { 0x4c, 0xd0 },
1451 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
1452 { 0x4e, 0x40 },
1453 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
1454 { 0x50, 0xff },
1455 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
1456 { 0x55, 0xff },
1457 { 0x56, 0x12 },
1458 { 0x57, 0x81 },
1459 { 0x58, 0x75 },
1460 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
1461 { 0x5a, 0x2c },
1462 { 0x5b, 0x0f }, /* AWB chrominance levels */
1463 { 0x5c, 0x10 },
1464 { 0x3d, 0x80 },
1465 { 0x27, 0xa6 },
1466 { 0x12, 0x20 }, /* Toggle AWB */
1467 { 0x12, 0x24 },
1468};
1469
1470/* Lawrence Glaister <lg@jfm.bc.ca> reports:
1471 *
1472 * Register 0x0f in the 7610 has the following effects:
1473 *
1474 * 0x85 (AEC method 1): Best overall, good contrast range
1475 * 0x45 (AEC method 2): Very overexposed
1476 * 0xa5 (spec sheet default): Ok, but the black level is
1477 * shifted resulting in loss of contrast
1478 * 0x05 (old driver setting): very overexposed, too much
1479 * contrast
1480 */
1481static const struct ov_i2c_regvals norm_7610[] = {
1482 { 0x10, 0xff },
1483 { 0x16, 0x06 },
1484 { 0x28, 0x24 },
1485 { 0x2b, 0xac },
1486 { 0x12, 0x00 },
1487 { 0x38, 0x81 },
1488 { 0x28, 0x24 }, /* 0c */
1489 { 0x0f, 0x85 }, /* lg's setting */
1490 { 0x15, 0x01 },
1491 { 0x20, 0x1c },
1492 { 0x23, 0x2a },
1493 { 0x24, 0x10 },
1494 { 0x25, 0x8a },
1495 { 0x26, 0xa2 },
1496 { 0x27, 0xc2 },
1497 { 0x2a, 0x04 },
1498 { 0x2c, 0xfe },
1499 { 0x2d, 0x93 },
1500 { 0x30, 0x71 },
1501 { 0x31, 0x60 },
1502 { 0x32, 0x26 },
1503 { 0x33, 0x20 },
1504 { 0x34, 0x48 },
1505 { 0x12, 0x24 },
1506 { 0x11, 0x01 },
1507 { 0x0c, 0x24 },
1508 { 0x0d, 0x24 },
1509};
1510
1511static const struct ov_i2c_regvals norm_7620[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03001512 { 0x12, 0x80 }, /* reset */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001513 { 0x00, 0x00 }, /* gain */
1514 { 0x01, 0x80 }, /* blue gain */
1515 { 0x02, 0x80 }, /* red gain */
Jean-François Moine21867802010-11-12 06:12:09 -03001516 { 0x03, 0xc0 }, /* OV7670_R03_VREF */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001517 { 0x06, 0x60 },
1518 { 0x07, 0x00 },
1519 { 0x0c, 0x24 },
1520 { 0x0c, 0x24 },
1521 { 0x0d, 0x24 },
1522 { 0x11, 0x01 },
1523 { 0x12, 0x24 },
1524 { 0x13, 0x01 },
1525 { 0x14, 0x84 },
1526 { 0x15, 0x01 },
1527 { 0x16, 0x03 },
1528 { 0x17, 0x2f },
1529 { 0x18, 0xcf },
1530 { 0x19, 0x06 },
1531 { 0x1a, 0xf5 },
1532 { 0x1b, 0x00 },
1533 { 0x20, 0x18 },
1534 { 0x21, 0x80 },
1535 { 0x22, 0x80 },
1536 { 0x23, 0x00 },
1537 { 0x26, 0xa2 },
1538 { 0x27, 0xea },
Hans de Goedeb282d872009-06-14 19:10:40 -03001539 { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001540 { 0x29, 0x00 },
1541 { 0x2a, 0x10 },
1542 { 0x2b, 0x00 },
1543 { 0x2c, 0x88 },
1544 { 0x2d, 0x91 },
1545 { 0x2e, 0x80 },
1546 { 0x2f, 0x44 },
1547 { 0x60, 0x27 },
1548 { 0x61, 0x02 },
1549 { 0x62, 0x5f },
1550 { 0x63, 0xd5 },
1551 { 0x64, 0x57 },
1552 { 0x65, 0x83 },
1553 { 0x66, 0x55 },
1554 { 0x67, 0x92 },
1555 { 0x68, 0xcf },
1556 { 0x69, 0x76 },
1557 { 0x6a, 0x22 },
1558 { 0x6b, 0x00 },
1559 { 0x6c, 0x02 },
1560 { 0x6d, 0x44 },
1561 { 0x6e, 0x80 },
1562 { 0x6f, 0x1d },
1563 { 0x70, 0x8b },
1564 { 0x71, 0x00 },
1565 { 0x72, 0x14 },
1566 { 0x73, 0x54 },
1567 { 0x74, 0x00 },
1568 { 0x75, 0x8e },
1569 { 0x76, 0x00 },
1570 { 0x77, 0xff },
1571 { 0x78, 0x80 },
1572 { 0x79, 0x80 },
1573 { 0x7a, 0x80 },
1574 { 0x7b, 0xe2 },
1575 { 0x7c, 0x00 },
1576};
1577
1578/* 7640 and 7648. The defaults should be OK for most registers. */
1579static const struct ov_i2c_regvals norm_7640[] = {
1580 { 0x12, 0x80 },
1581 { 0x12, 0x14 },
1582};
1583
Jean-François Moine42e142f2010-11-13 05:10:27 -03001584static const struct ov_regvals init_519_ov7660[] = {
1585 { 0x5d, 0x03 }, /* Turn off suspend mode */
1586 { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */
1587 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
1588 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
1589 { 0xa3, 0x18 },
1590 { 0xa4, 0x04 },
1591 { 0xa5, 0x28 },
1592 { 0x37, 0x00 }, /* SetUsbInit */
1593 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
1594 /* Enable both fields, YUV Input, disable defect comp (why?) */
1595 { 0x20, 0x0c }, /* 0x0d does U <-> V swap */
1596 { 0x21, 0x38 },
1597 { 0x22, 0x1d },
1598 { 0x17, 0x50 }, /* undocumented */
1599 { 0x37, 0x00 }, /* undocumented */
1600 { 0x40, 0xff }, /* I2C timeout counter */
1601 { 0x46, 0x00 }, /* I2C clock prescaler */
1602};
1603static const struct ov_i2c_regvals norm_7660[] = {
1604 {OV7670_R12_COM7, OV7670_COM7_RESET},
1605 {OV7670_R11_CLKRC, 0x81},
1606 {0x92, 0x00}, /* DM_LNL */
1607 {0x93, 0x00}, /* DM_LNH */
1608 {0x9d, 0x4c}, /* BD50ST */
1609 {0x9e, 0x3f}, /* BD60ST */
1610 {OV7670_R3B_COM11, 0x02},
1611 {OV7670_R13_COM8, 0xf5},
1612 {OV7670_R10_AECH, 0x00},
1613 {OV7670_R00_GAIN, 0x00},
1614 {OV7670_R01_BLUE, 0x7c},
1615 {OV7670_R02_RED, 0x9d},
1616 {OV7670_R12_COM7, 0x00},
1617 {OV7670_R04_COM1, 00},
1618 {OV7670_R18_HSTOP, 0x01},
1619 {OV7670_R17_HSTART, 0x13},
1620 {OV7670_R32_HREF, 0x92},
1621 {OV7670_R19_VSTART, 0x02},
1622 {OV7670_R1A_VSTOP, 0x7a},
1623 {OV7670_R03_VREF, 0x00},
1624 {OV7670_R0E_COM5, 0x04},
1625 {OV7670_R0F_COM6, 0x62},
1626 {OV7670_R15_COM10, 0x00},
1627 {0x16, 0x02}, /* RSVD */
1628 {0x1b, 0x00}, /* PSHFT */
1629 {OV7670_R1E_MVFP, 0x01},
1630 {0x29, 0x3c}, /* RSVD */
1631 {0x33, 0x00}, /* CHLF */
1632 {0x34, 0x07}, /* ARBLM */
1633 {0x35, 0x84}, /* RSVD */
1634 {0x36, 0x00}, /* RSVD */
1635 {0x37, 0x04}, /* ADC */
1636 {0x39, 0x43}, /* OFON */
1637 {OV7670_R3A_TSLB, 0x00},
1638 {OV7670_R3C_COM12, 0x6c},
1639 {OV7670_R3D_COM13, 0x98},
1640 {OV7670_R3F_EDGE, 0x23},
1641 {OV7670_R40_COM15, 0xc1},
1642 {OV7670_R41_COM16, 0x22},
1643 {0x6b, 0x0a}, /* DBLV */
1644 {0xa1, 0x08}, /* RSVD */
1645 {0x69, 0x80}, /* HV */
1646 {0x43, 0xf0}, /* RSVD.. */
1647 {0x44, 0x10},
1648 {0x45, 0x78},
1649 {0x46, 0xa8},
1650 {0x47, 0x60},
1651 {0x48, 0x80},
1652 {0x59, 0xba},
1653 {0x5a, 0x9a},
1654 {0x5b, 0x22},
1655 {0x5c, 0xb9},
1656 {0x5d, 0x9b},
1657 {0x5e, 0x10},
1658 {0x5f, 0xe0},
1659 {0x60, 0x85},
1660 {0x61, 0x60},
1661 {0x9f, 0x9d}, /* RSVD */
1662 {0xa0, 0xa0}, /* DSPC2 */
1663 {0x4f, 0x60}, /* matrix */
1664 {0x50, 0x64},
1665 {0x51, 0x04},
1666 {0x52, 0x18},
1667 {0x53, 0x3c},
1668 {0x54, 0x54},
1669 {0x55, 0x40},
1670 {0x56, 0x40},
1671 {0x57, 0x40},
1672 {0x58, 0x0d}, /* matrix sign */
1673 {0x8b, 0xcc}, /* RSVD */
1674 {0x8c, 0xcc},
1675 {0x8d, 0xcf},
1676 {0x6c, 0x40}, /* gamma curve */
1677 {0x6d, 0xe0},
1678 {0x6e, 0xa0},
1679 {0x6f, 0x80},
1680 {0x70, 0x70},
1681 {0x71, 0x80},
1682 {0x72, 0x60},
1683 {0x73, 0x60},
1684 {0x74, 0x50},
1685 {0x75, 0x40},
1686 {0x76, 0x38},
1687 {0x77, 0x3c},
1688 {0x78, 0x32},
1689 {0x79, 0x1a},
1690 {0x7a, 0x28},
1691 {0x7b, 0x24},
1692 {0x7c, 0x04}, /* gamma curve */
1693 {0x7d, 0x12},
1694 {0x7e, 0x26},
1695 {0x7f, 0x46},
1696 {0x80, 0x54},
1697 {0x81, 0x64},
1698 {0x82, 0x70},
1699 {0x83, 0x7c},
1700 {0x84, 0x86},
1701 {0x85, 0x8e},
1702 {0x86, 0x9c},
1703 {0x87, 0xab},
1704 {0x88, 0xc4},
1705 {0x89, 0xd1},
1706 {0x8a, 0xe5},
1707 {OV7670_R14_COM9, 0x1e},
1708 {OV7670_R24_AEW, 0x80},
1709 {OV7670_R25_AEB, 0x72},
1710 {OV7670_R26_VPT, 0xb3},
1711 {0x62, 0x80}, /* LCC1 */
1712 {0x63, 0x80}, /* LCC2 */
1713 {0x64, 0x06}, /* LCC3 */
1714 {0x65, 0x00}, /* LCC4 */
1715 {0x66, 0x01}, /* LCC5 */
1716 {0x94, 0x0e}, /* RSVD.. */
1717 {0x95, 0x14},
1718 {OV7670_R13_COM8, OV7670_COM8_FASTAEC
1719 | OV7670_COM8_AECSTEP
1720 | OV7670_COM8_BFILT
1721 | 0x10
1722 | OV7670_COM8_AGC
1723 | OV7670_COM8_AWB
1724 | OV7670_COM8_AEC},
1725 {0xa1, 0xc8}
1726};
1727
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001728/* 7670. Defaults taken from OmniVision provided data,
1729* as provided by Jonathan Corbet of OLPC */
1730static const struct ov_i2c_regvals norm_7670[] = {
Jean-François Moine21867802010-11-12 06:12:09 -03001731 { OV7670_R12_COM7, OV7670_COM7_RESET },
1732 { OV7670_R3A_TSLB, 0x04 }, /* OV */
1733 { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
1734 { OV7670_R11_CLKRC, 0x01 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001735/*
1736 * Set the hardware window. These values from OV don't entirely
1737 * make sense - hstop is less than hstart. But they work...
1738 */
Jean-François Moine21867802010-11-12 06:12:09 -03001739 { OV7670_R17_HSTART, 0x13 },
1740 { OV7670_R18_HSTOP, 0x01 },
1741 { OV7670_R32_HREF, 0xb6 },
1742 { OV7670_R19_VSTART, 0x02 },
1743 { OV7670_R1A_VSTOP, 0x7a },
1744 { OV7670_R03_VREF, 0x0a },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001745
Jean-François Moine21867802010-11-12 06:12:09 -03001746 { OV7670_R0C_COM3, 0x00 },
1747 { OV7670_R3E_COM14, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001748/* Mystery scaling numbers */
1749 { 0x70, 0x3a },
1750 { 0x71, 0x35 },
1751 { 0x72, 0x11 },
1752 { 0x73, 0xf0 },
1753 { 0xa2, 0x02 },
Jean-François Moine21867802010-11-12 06:12:09 -03001754/* { OV7670_R15_COM10, 0x0 }, */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001755
1756/* Gamma curve values */
1757 { 0x7a, 0x20 },
1758 { 0x7b, 0x10 },
1759 { 0x7c, 0x1e },
1760 { 0x7d, 0x35 },
1761 { 0x7e, 0x5a },
1762 { 0x7f, 0x69 },
1763 { 0x80, 0x76 },
1764 { 0x81, 0x80 },
1765 { 0x82, 0x88 },
1766 { 0x83, 0x8f },
1767 { 0x84, 0x96 },
1768 { 0x85, 0xa3 },
1769 { 0x86, 0xaf },
1770 { 0x87, 0xc4 },
1771 { 0x88, 0xd7 },
1772 { 0x89, 0xe8 },
1773
1774/* AGC and AEC parameters. Note we start by disabling those features,
1775 then turn them only after tweaking the values. */
Jean-François Moine21867802010-11-12 06:12:09 -03001776 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001777 | OV7670_COM8_AECSTEP
1778 | OV7670_COM8_BFILT },
Jean-François Moine21867802010-11-12 06:12:09 -03001779 { OV7670_R00_GAIN, 0x00 },
1780 { OV7670_R10_AECH, 0x00 },
1781 { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */
1782 { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
1783 { OV7670_RA5_BD50MAX, 0x05 },
1784 { OV7670_RAB_BD60MAX, 0x07 },
1785 { OV7670_R24_AEW, 0x95 },
1786 { OV7670_R25_AEB, 0x33 },
1787 { OV7670_R26_VPT, 0xe3 },
1788 { OV7670_R9F_HAECC1, 0x78 },
1789 { OV7670_RA0_HAECC2, 0x68 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001790 { 0xa1, 0x03 }, /* magic */
Jean-François Moine21867802010-11-12 06:12:09 -03001791 { OV7670_RA6_HAECC3, 0xd8 },
1792 { OV7670_RA7_HAECC4, 0xd8 },
1793 { OV7670_RA8_HAECC5, 0xf0 },
1794 { OV7670_RA9_HAECC6, 0x90 },
1795 { OV7670_RAA_HAECC7, 0x94 },
1796 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001797 | OV7670_COM8_AECSTEP
1798 | OV7670_COM8_BFILT
1799 | OV7670_COM8_AGC
1800 | OV7670_COM8_AEC },
1801
1802/* Almost all of these are magic "reserved" values. */
Jean-François Moine21867802010-11-12 06:12:09 -03001803 { OV7670_R0E_COM5, 0x61 },
1804 { OV7670_R0F_COM6, 0x4b },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001805 { 0x16, 0x02 },
Jean-François Moine21867802010-11-12 06:12:09 -03001806 { OV7670_R1E_MVFP, 0x07 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001807 { 0x21, 0x02 },
1808 { 0x22, 0x91 },
1809 { 0x29, 0x07 },
1810 { 0x33, 0x0b },
1811 { 0x35, 0x0b },
1812 { 0x37, 0x1d },
1813 { 0x38, 0x71 },
1814 { 0x39, 0x2a },
Jean-François Moine21867802010-11-12 06:12:09 -03001815 { OV7670_R3C_COM12, 0x78 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001816 { 0x4d, 0x40 },
1817 { 0x4e, 0x20 },
Jean-François Moine21867802010-11-12 06:12:09 -03001818 { OV7670_R69_GFIX, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001819 { 0x6b, 0x4a },
1820 { 0x74, 0x10 },
1821 { 0x8d, 0x4f },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001822 { 0x8e, 0x00 },
1823 { 0x8f, 0x00 },
1824 { 0x90, 0x00 },
1825 { 0x91, 0x00 },
1826 { 0x96, 0x00 },
1827 { 0x9a, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001828 { 0xb0, 0x84 },
1829 { 0xb1, 0x0c },
1830 { 0xb2, 0x0e },
1831 { 0xb3, 0x82 },
1832 { 0xb8, 0x0a },
1833
1834/* More reserved magic, some of which tweaks white balance */
1835 { 0x43, 0x0a },
1836 { 0x44, 0xf0 },
1837 { 0x45, 0x34 },
1838 { 0x46, 0x58 },
1839 { 0x47, 0x28 },
1840 { 0x48, 0x3a },
1841 { 0x59, 0x88 },
1842 { 0x5a, 0x88 },
1843 { 0x5b, 0x44 },
1844 { 0x5c, 0x67 },
1845 { 0x5d, 0x49 },
1846 { 0x5e, 0x0e },
1847 { 0x6c, 0x0a },
1848 { 0x6d, 0x55 },
1849 { 0x6e, 0x11 },
1850 { 0x6f, 0x9f },
1851 /* "9e for advance AWB" */
1852 { 0x6a, 0x40 },
Jean-François Moine21867802010-11-12 06:12:09 -03001853 { OV7670_R01_BLUE, 0x40 },
1854 { OV7670_R02_RED, 0x60 },
1855 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001856 | OV7670_COM8_AECSTEP
1857 | OV7670_COM8_BFILT
1858 | OV7670_COM8_AGC
1859 | OV7670_COM8_AEC
1860 | OV7670_COM8_AWB },
1861
1862/* Matrix coefficients */
1863 { 0x4f, 0x80 },
1864 { 0x50, 0x80 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001865 { 0x51, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001866 { 0x52, 0x22 },
1867 { 0x53, 0x5e },
1868 { 0x54, 0x80 },
1869 { 0x58, 0x9e },
1870
Jean-François Moine21867802010-11-12 06:12:09 -03001871 { OV7670_R41_COM16, OV7670_COM16_AWBGAIN },
1872 { OV7670_R3F_EDGE, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001873 { 0x75, 0x05 },
1874 { 0x76, 0xe1 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001875 { 0x4c, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001876 { 0x77, 0x01 },
Jean-François Moine21867802010-11-12 06:12:09 -03001877 { OV7670_R3D_COM13, OV7670_COM13_GAMMA
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001878 | OV7670_COM13_UVSAT
1879 | 2}, /* was 3 */
1880 { 0x4b, 0x09 },
1881 { 0xc9, 0x60 },
Jean-François Moine21867802010-11-12 06:12:09 -03001882 { OV7670_R41_COM16, 0x38 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001883 { 0x56, 0x40 },
1884
1885 { 0x34, 0x11 },
Jean-François Moine21867802010-11-12 06:12:09 -03001886 { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001887 { 0xa4, 0x88 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001888 { 0x96, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001889 { 0x97, 0x30 },
1890 { 0x98, 0x20 },
1891 { 0x99, 0x30 },
1892 { 0x9a, 0x84 },
1893 { 0x9b, 0x29 },
1894 { 0x9c, 0x03 },
1895 { 0x9d, 0x4c },
1896 { 0x9e, 0x3f },
1897 { 0x78, 0x04 },
1898
1899/* Extra-weird stuff. Some sort of multiplexor register */
1900 { 0x79, 0x01 },
1901 { 0xc8, 0xf0 },
1902 { 0x79, 0x0f },
1903 { 0xc8, 0x00 },
1904 { 0x79, 0x10 },
1905 { 0xc8, 0x7e },
1906 { 0x79, 0x0a },
1907 { 0xc8, 0x80 },
1908 { 0x79, 0x0b },
1909 { 0xc8, 0x01 },
1910 { 0x79, 0x0c },
1911 { 0xc8, 0x0f },
1912 { 0x79, 0x0d },
1913 { 0xc8, 0x20 },
1914 { 0x79, 0x09 },
1915 { 0xc8, 0x80 },
1916 { 0x79, 0x02 },
1917 { 0xc8, 0xc0 },
1918 { 0x79, 0x03 },
1919 { 0xc8, 0x40 },
1920 { 0x79, 0x05 },
1921 { 0xc8, 0x30 },
1922 { 0x79, 0x26 },
1923};
1924
1925static const struct ov_i2c_regvals norm_8610[] = {
1926 { 0x12, 0x80 },
1927 { 0x00, 0x00 },
1928 { 0x01, 0x80 },
1929 { 0x02, 0x80 },
1930 { 0x03, 0xc0 },
1931 { 0x04, 0x30 },
1932 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
1933 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
1934 { 0x0a, 0x86 },
1935 { 0x0b, 0xb0 },
1936 { 0x0c, 0x20 },
1937 { 0x0d, 0x20 },
1938 { 0x11, 0x01 },
1939 { 0x12, 0x25 },
1940 { 0x13, 0x01 },
1941 { 0x14, 0x04 },
1942 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
1943 { 0x16, 0x03 },
1944 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
1945 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
1946 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
1947 { 0x1a, 0xf5 },
1948 { 0x1b, 0x00 },
1949 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
1950 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
1951 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
1952 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
1953 { 0x26, 0xa2 },
1954 { 0x27, 0xea },
1955 { 0x28, 0x00 },
1956 { 0x29, 0x00 },
1957 { 0x2a, 0x80 },
1958 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
1959 { 0x2c, 0xac },
1960 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
1961 { 0x2e, 0x80 },
1962 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
1963 { 0x4c, 0x00 },
1964 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
1965 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
1966 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
1967 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
1968 { 0x63, 0xff },
1969 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
1970 * maybe thats wrong */
1971 { 0x65, 0x00 },
1972 { 0x66, 0x55 },
1973 { 0x67, 0xb0 },
1974 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
1975 { 0x69, 0x02 },
1976 { 0x6a, 0x22 },
1977 { 0x6b, 0x00 },
1978 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
1979 * deleting bit7 colors the first images red */
1980 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
1981 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
1982 { 0x6f, 0x01 },
1983 { 0x70, 0x8b },
1984 { 0x71, 0x00 },
1985 { 0x72, 0x14 },
1986 { 0x73, 0x54 },
1987 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
1988 { 0x75, 0x0e },
1989 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
1990 { 0x77, 0xff },
1991 { 0x78, 0x80 },
1992 { 0x79, 0x80 },
1993 { 0x7a, 0x80 },
1994 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
1995 { 0x7c, 0x00 },
1996 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
1997 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
1998 { 0x7f, 0xfb },
1999 { 0x80, 0x28 },
2000 { 0x81, 0x00 },
2001 { 0x82, 0x23 },
2002 { 0x83, 0x0b },
2003 { 0x84, 0x00 },
2004 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
2005 { 0x86, 0xc9 },
2006 { 0x87, 0x00 },
2007 { 0x88, 0x00 },
2008 { 0x89, 0x01 },
2009 { 0x12, 0x20 },
2010 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
2011};
2012
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002013static unsigned char ov7670_abs_to_sm(unsigned char v)
2014{
2015 if (v > 127)
2016 return v & 0x7f;
2017 return (128 - v) | 0x80;
2018}
2019
2020/* Write a OV519 register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002021static void reg_w(struct sd *sd, u16 index, u16 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002022{
Hans de Goedea511ba92009-10-16 07:13:07 -03002023 int ret, req = 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002024
Jean-François Moinef8f20182010-11-12 07:54:02 -03002025 if (sd->gspca_dev.usb_err < 0)
2026 return;
2027
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002028 switch (sd->bridge) {
2029 case BRIDGE_OV511:
2030 case BRIDGE_OV511PLUS:
2031 req = 2;
2032 break;
2033 case BRIDGE_OVFX2:
Hans de Goedea511ba92009-10-16 07:13:07 -03002034 req = 0x0a;
2035 /* fall through */
2036 case BRIDGE_W9968CF:
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002037 PDEBUG(D_USBO, "SET %02x %04x %04x",
2038 req, value, index);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002039 ret = usb_control_msg(sd->gspca_dev.dev,
2040 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goedea511ba92009-10-16 07:13:07 -03002041 req,
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002042 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Hans de Goedea511ba92009-10-16 07:13:07 -03002043 value, index, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002044 goto leave;
2045 default:
2046 req = 1;
2047 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002048
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002049 PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
2050 req, index, value);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002051 sd->gspca_dev.usb_buf[0] = value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002052 ret = usb_control_msg(sd->gspca_dev.dev,
2053 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03002054 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002055 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2056 0, index,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002057 sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002058leave:
Hans de Goedea511ba92009-10-16 07:13:07 -03002059 if (ret < 0) {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002060 err("reg_w %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002061 sd->gspca_dev.usb_err = ret;
2062 return;
Hans de Goedea511ba92009-10-16 07:13:07 -03002063 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002064}
2065
Hans de Goedea511ba92009-10-16 07:13:07 -03002066/* Read from a OV519 register, note not valid for the w9968cf!! */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002067/* returns: negative is error, pos or zero is data */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002068static int reg_r(struct sd *sd, u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002069{
2070 int ret;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002071 int req;
2072
Jean-François Moinef8f20182010-11-12 07:54:02 -03002073 if (sd->gspca_dev.usb_err < 0)
2074 return -1;
2075
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002076 switch (sd->bridge) {
2077 case BRIDGE_OV511:
2078 case BRIDGE_OV511PLUS:
2079 req = 3;
2080 break;
2081 case BRIDGE_OVFX2:
2082 req = 0x0b;
2083 break;
2084 default:
2085 req = 1;
2086 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002087
2088 ret = usb_control_msg(sd->gspca_dev.dev,
2089 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03002090 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002091 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002092 0, index, sd->gspca_dev.usb_buf, 1, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002093
Hans de Goedea511ba92009-10-16 07:13:07 -03002094 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002095 ret = sd->gspca_dev.usb_buf[0];
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002096 PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
2097 req, index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002098 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002099 err("reg_r %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002100 sd->gspca_dev.usb_err = ret;
2101 }
Hans de Goedea511ba92009-10-16 07:13:07 -03002102
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002103 return ret;
2104}
2105
2106/* Read 8 values from a OV519 register */
2107static int reg_r8(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002108 u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002109{
2110 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002111
Jean-François Moinef8f20182010-11-12 07:54:02 -03002112 if (sd->gspca_dev.usb_err < 0)
2113 return -1;
2114
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002115 ret = usb_control_msg(sd->gspca_dev.dev,
2116 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2117 1, /* REQ_IO */
2118 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002119 0, index, sd->gspca_dev.usb_buf, 8, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002120
Jean-François Moinef8f20182010-11-12 07:54:02 -03002121 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002122 ret = sd->gspca_dev.usb_buf[0];
Jean-François Moinef8f20182010-11-12 07:54:02 -03002123 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002124 err("reg_r8 %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002125 sd->gspca_dev.usb_err = ret;
2126 }
Hans de Goedea511ba92009-10-16 07:13:07 -03002127
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002128 return ret;
2129}
2130
2131/*
2132 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
2133 * the same position as 1's in "mask" are cleared and set to "value". Bits
2134 * that are in the same position as 0's in "mask" are preserved, regardless
2135 * of their respective state in "value".
2136 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002137static void reg_w_mask(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002138 u16 index,
2139 u8 value,
2140 u8 mask)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002141{
2142 int ret;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002143 u8 oldval;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002144
2145 if (mask != 0xff) {
2146 value &= mask; /* Enforce mask on value */
2147 ret = reg_r(sd, index);
2148 if (ret < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002149 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002150
2151 oldval = ret & ~mask; /* Clear the masked bits */
2152 value |= oldval; /* Set the desired bits */
2153 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03002154 reg_w(sd, index, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002155}
2156
2157/*
Hans de Goede49809d62009-06-07 12:10:39 -03002158 * Writes multiple (n) byte value to a single register. Only valid with certain
2159 * registers (0x30 and 0xc4 - 0xce).
2160 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002161static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
Hans de Goede49809d62009-06-07 12:10:39 -03002162{
2163 int ret;
2164
Jean-François Moinef8f20182010-11-12 07:54:02 -03002165 if (sd->gspca_dev.usb_err < 0)
2166 return;
2167
Jean-Francois Moine83955552009-12-12 06:58:01 -03002168 *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
Hans de Goede49809d62009-06-07 12:10:39 -03002169
2170 ret = usb_control_msg(sd->gspca_dev.dev,
2171 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2172 1 /* REG_IO */,
2173 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2174 0, index,
2175 sd->gspca_dev.usb_buf, n, 500);
Hans de Goedea511ba92009-10-16 07:13:07 -03002176 if (ret < 0) {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002177 err("reg_w32 %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002178 sd->gspca_dev.usb_err = ret;
Hans de Goedea511ba92009-10-16 07:13:07 -03002179 }
Hans de Goede49809d62009-06-07 12:10:39 -03002180}
2181
Jean-François Moinef8f20182010-11-12 07:54:02 -03002182static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goede1876bb92009-06-14 06:45:50 -03002183{
2184 int rc, retries;
2185
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002186 PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002187
2188 /* Three byte write cycle */
2189 for (retries = 6; ; ) {
2190 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002191 reg_w(sd, R51x_I2C_SADDR_3, reg);
Hans de Goede1876bb92009-06-14 06:45:50 -03002192
2193 /* Write "value" to I2C data port of OV511 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002194 reg_w(sd, R51x_I2C_DATA, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002195
2196 /* Initiate 3-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002197 reg_w(sd, R511_I2C_CTL, 0x01);
Hans de Goede1876bb92009-06-14 06:45:50 -03002198
Jean-Francois Moine83955552009-12-12 06:58:01 -03002199 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002200 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002201 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002202
2203 if (rc < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002204 return;
Hans de Goede1876bb92009-06-14 06:45:50 -03002205
2206 if ((rc & 2) == 0) /* Ack? */
2207 break;
2208 if (--retries < 0) {
2209 PDEBUG(D_USBO, "i2c write retries exhausted");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002210 return;
Hans de Goede1876bb92009-06-14 06:45:50 -03002211 }
2212 }
Hans de Goede1876bb92009-06-14 06:45:50 -03002213}
2214
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002215static int ov511_i2c_r(struct sd *sd, u8 reg)
Hans de Goede1876bb92009-06-14 06:45:50 -03002216{
2217 int rc, value, retries;
2218
2219 /* Two byte write cycle */
2220 for (retries = 6; ; ) {
2221 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002222 reg_w(sd, R51x_I2C_SADDR_2, reg);
Hans de Goede1876bb92009-06-14 06:45:50 -03002223
2224 /* Initiate 2-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002225 reg_w(sd, R511_I2C_CTL, 0x03);
Hans de Goede1876bb92009-06-14 06:45:50 -03002226
Jean-Francois Moine83955552009-12-12 06:58:01 -03002227 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002228 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002229 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002230
2231 if (rc < 0)
2232 return rc;
2233
2234 if ((rc & 2) == 0) /* Ack? */
2235 break;
2236
2237 /* I2C abort */
2238 reg_w(sd, R511_I2C_CTL, 0x10);
2239
2240 if (--retries < 0) {
2241 PDEBUG(D_USBI, "i2c write retries exhausted");
2242 return -1;
2243 }
2244 }
2245
2246 /* Two byte read cycle */
2247 for (retries = 6; ; ) {
2248 /* Initiate 2-byte read cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002249 reg_w(sd, R511_I2C_CTL, 0x05);
Hans de Goede1876bb92009-06-14 06:45:50 -03002250
Jean-Francois Moine83955552009-12-12 06:58:01 -03002251 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002252 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002253 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002254
2255 if (rc < 0)
2256 return rc;
2257
2258 if ((rc & 2) == 0) /* Ack? */
2259 break;
2260
2261 /* I2C abort */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002262 reg_w(sd, R511_I2C_CTL, 0x10);
Hans de Goede1876bb92009-06-14 06:45:50 -03002263
2264 if (--retries < 0) {
2265 PDEBUG(D_USBI, "i2c read retries exhausted");
2266 return -1;
2267 }
2268 }
2269
2270 value = reg_r(sd, R51x_I2C_DATA);
2271
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002272 PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002273
2274 /* This is needed to make i2c_w() work */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002275 reg_w(sd, R511_I2C_CTL, 0x05);
Hans de Goede1876bb92009-06-14 06:45:50 -03002276
2277 return value;
2278}
Hans de Goede49809d62009-06-07 12:10:39 -03002279
2280/*
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002281 * The OV518 I2C I/O procedure is different, hence, this function.
2282 * This is normally only called from i2c_w(). Note that this function
2283 * always succeeds regardless of whether the sensor is present and working.
2284 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002285static void ov518_i2c_w(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002286 u8 reg,
2287 u8 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002288{
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002289 PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002290
2291 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002292 reg_w(sd, R51x_I2C_SADDR_3, reg);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002293
2294 /* Write "value" to I2C data port of OV511 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002295 reg_w(sd, R51x_I2C_DATA, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002296
2297 /* Initiate 3-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002298 reg_w(sd, R518_I2C_CTL, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002299
2300 /* wait for write complete */
2301 msleep(4);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002302 reg_r8(sd, R518_I2C_CTL);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002303}
2304
2305/*
2306 * returns: negative is error, pos or zero is data
2307 *
2308 * The OV518 I2C I/O procedure is different, hence, this function.
2309 * This is normally only called from i2c_r(). Note that this function
2310 * always succeeds regardless of whether the sensor is present and working.
2311 */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002312static int ov518_i2c_r(struct sd *sd, u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002313{
Jean-François Moinef8f20182010-11-12 07:54:02 -03002314 int value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002315
2316 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002317 reg_w(sd, R51x_I2C_SADDR_2, reg);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002318
2319 /* Initiate 2-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002320 reg_w(sd, R518_I2C_CTL, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002321
2322 /* Initiate 2-byte read cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002323 reg_w(sd, R518_I2C_CTL, 0x05);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002324 value = reg_r(sd, R51x_I2C_DATA);
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002325 PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002326 return value;
2327}
2328
Jean-François Moinef8f20182010-11-12 07:54:02 -03002329static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002330{
2331 int ret;
2332
Jean-François Moinef8f20182010-11-12 07:54:02 -03002333 if (sd->gspca_dev.usb_err < 0)
2334 return;
2335
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002336 ret = usb_control_msg(sd->gspca_dev.dev,
2337 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2338 0x02,
2339 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002340 (u16) value, (u16) reg, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002341
Hans de Goedea511ba92009-10-16 07:13:07 -03002342 if (ret < 0) {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002343 err("ovfx2_i2c_w %02x failed %d", reg, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002344 sd->gspca_dev.usb_err = ret;
Hans de Goedea511ba92009-10-16 07:13:07 -03002345 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002346
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002347 PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002348}
2349
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002350static int ovfx2_i2c_r(struct sd *sd, u8 reg)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002351{
2352 int ret;
2353
Jean-François Moinef8f20182010-11-12 07:54:02 -03002354 if (sd->gspca_dev.usb_err < 0)
2355 return -1;
2356
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002357 ret = usb_control_msg(sd->gspca_dev.dev,
2358 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2359 0x03,
2360 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002361 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002362
2363 if (ret >= 0) {
2364 ret = sd->gspca_dev.usb_buf[0];
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002365 PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002366 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002367 err("ovfx2_i2c_r %02x failed %d", reg, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002368 sd->gspca_dev.usb_err = ret;
2369 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002370
2371 return ret;
2372}
2373
Jean-François Moinef8f20182010-11-12 07:54:02 -03002374static void i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goede1876bb92009-06-14 06:45:50 -03002375{
Hans de Goedefb1f9022009-10-16 07:42:53 -03002376 if (sd->sensor_reg_cache[reg] == value)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002377 return;
Hans de Goedefb1f9022009-10-16 07:42:53 -03002378
Hans de Goede1876bb92009-06-14 06:45:50 -03002379 switch (sd->bridge) {
2380 case BRIDGE_OV511:
2381 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002382 ov511_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002383 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002384 case BRIDGE_OV518:
2385 case BRIDGE_OV518PLUS:
2386 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002387 ov518_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002388 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002389 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002390 ovfx2_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002391 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002392 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002393 w9968cf_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002394 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002395 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002396
Jean-François Moinef8f20182010-11-12 07:54:02 -03002397 if (sd->gspca_dev.usb_err >= 0) {
Hans de Goedefb1f9022009-10-16 07:42:53 -03002398 /* Up on sensor reset empty the register cache */
2399 if (reg == 0x12 && (value & 0x80))
2400 memset(sd->sensor_reg_cache, -1,
Jean-François Moine87bae742010-11-12 05:31:34 -03002401 sizeof(sd->sensor_reg_cache));
Hans de Goedefb1f9022009-10-16 07:42:53 -03002402 else
2403 sd->sensor_reg_cache[reg] = value;
2404 }
Hans de Goede1876bb92009-06-14 06:45:50 -03002405}
2406
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002407static int i2c_r(struct sd *sd, u8 reg)
Hans de Goede1876bb92009-06-14 06:45:50 -03002408{
Hans de Goede8394bcf2009-10-16 11:26:22 -03002409 int ret = -1;
Hans de Goedefb1f9022009-10-16 07:42:53 -03002410
2411 if (sd->sensor_reg_cache[reg] != -1)
2412 return sd->sensor_reg_cache[reg];
2413
Hans de Goede1876bb92009-06-14 06:45:50 -03002414 switch (sd->bridge) {
2415 case BRIDGE_OV511:
2416 case BRIDGE_OV511PLUS:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002417 ret = ov511_i2c_r(sd, reg);
2418 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002419 case BRIDGE_OV518:
2420 case BRIDGE_OV518PLUS:
2421 case BRIDGE_OV519:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002422 ret = ov518_i2c_r(sd, reg);
2423 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002424 case BRIDGE_OVFX2:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002425 ret = ovfx2_i2c_r(sd, reg);
2426 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002427 case BRIDGE_W9968CF:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002428 ret = w9968cf_i2c_r(sd, reg);
2429 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002430 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002431
2432 if (ret >= 0)
2433 sd->sensor_reg_cache[reg] = ret;
2434
2435 return ret;
Hans de Goede1876bb92009-06-14 06:45:50 -03002436}
2437
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002438/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
2439 * the same position as 1's in "mask" are cleared and set to "value". Bits
2440 * that are in the same position as 0's in "mask" are preserved, regardless
2441 * of their respective state in "value".
2442 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002443static void i2c_w_mask(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002444 u8 reg,
2445 u8 value,
2446 u8 mask)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002447{
2448 int rc;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002449 u8 oldval;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002450
2451 value &= mask; /* Enforce mask on value */
2452 rc = i2c_r(sd, reg);
2453 if (rc < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002454 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002455 oldval = rc & ~mask; /* Clear the masked bits */
2456 value |= oldval; /* Set the desired bits */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002457 i2c_w(sd, reg, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002458}
2459
2460/* Temporarily stops OV511 from functioning. Must do this before changing
2461 * registers while the camera is streaming */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002462static inline void ov51x_stop(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002463{
2464 PDEBUG(D_STREAM, "stopping");
2465 sd->stopped = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03002466 switch (sd->bridge) {
2467 case BRIDGE_OV511:
2468 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002469 reg_w(sd, R51x_SYS_RESET, 0x3d);
2470 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002471 case BRIDGE_OV518:
2472 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002473 reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
2474 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002475 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002476 reg_w(sd, OV519_R51_RESET1, 0x0f);
Jean-François Moine5927abc2010-11-12 15:32:29 -03002477 reg_w(sd, OV519_R51_RESET1, 0x00);
2478 reg_w(sd, 0x22, 0x00); /* FRAR */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002479 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002480 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002481 reg_w_mask(sd, 0x0f, 0x00, 0x02);
2482 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002483 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002484 reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
2485 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002486 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002487}
2488
2489/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
2490 * actually stopped (for performance). */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002491static inline void ov51x_restart(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002492{
2493 PDEBUG(D_STREAM, "restarting");
2494 if (!sd->stopped)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002495 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002496 sd->stopped = 0;
2497
2498 /* Reinitialize the stream */
Hans de Goede49809d62009-06-07 12:10:39 -03002499 switch (sd->bridge) {
2500 case BRIDGE_OV511:
2501 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002502 reg_w(sd, R51x_SYS_RESET, 0x00);
2503 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002504 case BRIDGE_OV518:
2505 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002506 reg_w(sd, 0x2f, 0x80);
2507 reg_w(sd, R51x_SYS_RESET, 0x00);
2508 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002509 case BRIDGE_OV519:
Jean-François Moine5927abc2010-11-12 15:32:29 -03002510 reg_w(sd, OV519_R51_RESET1, 0x0f);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002511 reg_w(sd, OV519_R51_RESET1, 0x00);
Jean-François Moine5927abc2010-11-12 15:32:29 -03002512 reg_w(sd, 0x22, 0x1d); /* FRAR */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002513 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002514 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002515 reg_w_mask(sd, 0x0f, 0x02, 0x02);
2516 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002517 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002518 reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
2519 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002520 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002521}
2522
Jean-François Moinef8f20182010-11-12 07:54:02 -03002523static void ov51x_set_slave_ids(struct sd *sd, u8 slave);
Hans de Goede229bb7d2009-10-11 07:41:46 -03002524
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002525/* This does an initial reset of an OmniVision sensor and ensures that I2C
2526 * is synchronized. Returns <0 on failure.
2527 */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002528static int init_ov_sensor(struct sd *sd, u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002529{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002530 int i;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002531
Jean-François Moinef8f20182010-11-12 07:54:02 -03002532 ov51x_set_slave_ids(sd, slave);
Hans de Goede229bb7d2009-10-11 07:41:46 -03002533
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002534 /* Reset the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002535 i2c_w(sd, 0x12, 0x80);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002536
2537 /* Wait for it to initialize */
2538 msleep(150);
2539
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002540 for (i = 0; i < i2c_detect_tries; i++) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002541 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
2542 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002543 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
2544 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002545 }
2546
2547 /* Reset the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002548 i2c_w(sd, 0x12, 0x80);
2549
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002550 /* Wait for it to initialize */
2551 msleep(150);
Jean-François Moine87bae742010-11-12 05:31:34 -03002552
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002553 /* Dummy read to sync I2C */
2554 if (i2c_r(sd, 0x00) < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002555 return -1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002556 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03002557 return -1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002558}
2559
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002560/* Set the read and write slave IDs. The "slave" argument is the write slave,
2561 * and the read slave will be set to (slave + 1).
2562 * This should not be called from outside the i2c I/O functions.
2563 * Sets I2C read and write slave IDs. Returns <0 for error
2564 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002565static void ov51x_set_slave_ids(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002566 u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002567{
Hans de Goedea511ba92009-10-16 07:13:07 -03002568 switch (sd->bridge) {
2569 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002570 reg_w(sd, OVFX2_I2C_ADDR, slave);
2571 return;
Hans de Goedea511ba92009-10-16 07:13:07 -03002572 case BRIDGE_W9968CF:
2573 sd->sensor_addr = slave;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002574 return;
Hans de Goedea511ba92009-10-16 07:13:07 -03002575 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002576
Jean-François Moinef8f20182010-11-12 07:54:02 -03002577 reg_w(sd, R51x_I2C_W_SID, slave);
2578 reg_w(sd, R51x_I2C_R_SID, slave + 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002579}
2580
Jean-François Moinef8f20182010-11-12 07:54:02 -03002581static void write_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002582 const struct ov_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002583 int n)
2584{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002585 while (--n >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03002586 reg_w(sd, regvals->reg, regvals->val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002587 regvals++;
2588 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002589}
2590
Jean-François Moinef8f20182010-11-12 07:54:02 -03002591static void write_i2c_regvals(struct sd *sd,
2592 const struct ov_i2c_regvals *regvals,
2593 int n)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002594{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002595 while (--n >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03002596 i2c_w(sd, regvals->reg, regvals->val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002597 regvals++;
2598 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002599}
2600
2601/****************************************************************************
2602 *
2603 * OV511 and sensor configuration
2604 *
2605 ***************************************************************************/
2606
Hans de Goede635118d2009-10-11 09:49:03 -03002607/* This initializes the OV2x10 / OV3610 / OV3620 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002608static void ov_hires_configure(struct sd *sd)
Hans de Goede635118d2009-10-11 09:49:03 -03002609{
2610 int high, low;
2611
2612 if (sd->bridge != BRIDGE_OVFX2) {
Jean-François Moine0b656322010-09-13 05:19:58 -03002613 err("error hires sensors only supported with ovfx2");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002614 return;
Hans de Goede635118d2009-10-11 09:49:03 -03002615 }
2616
2617 PDEBUG(D_PROBE, "starting ov hires configuration");
2618
2619 /* Detect sensor (sub)type */
2620 high = i2c_r(sd, 0x0a);
2621 low = i2c_r(sd, 0x0b);
2622 /* info("%x, %x", high, low); */
2623 if (high == 0x96 && low == 0x40) {
2624 PDEBUG(D_PROBE, "Sensor is an OV2610");
2625 sd->sensor = SEN_OV2610;
2626 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2627 PDEBUG(D_PROBE, "Sensor is an OV3610");
2628 sd->sensor = SEN_OV3610;
2629 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002630 err("Error unknown sensor type: %02x%02x",
Jean-François Moine87bae742010-11-12 05:31:34 -03002631 high, low);
Hans de Goede635118d2009-10-11 09:49:03 -03002632 }
Hans de Goede635118d2009-10-11 09:49:03 -03002633}
2634
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002635/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
2636 * the same register settings as the OV8610, since they are very similar.
2637 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002638static void ov8xx0_configure(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002639{
2640 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002641
2642 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
2643
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002644 /* Detect sensor (sub)type */
2645 rc = i2c_r(sd, OV7610_REG_COM_I);
2646 if (rc < 0) {
2647 PDEBUG(D_ERR, "Error detecting sensor type");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002648 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002649 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03002650 if ((rc & 3) == 1)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002651 sd->sensor = SEN_OV8610;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002652 else
Jean-François Moine0b656322010-09-13 05:19:58 -03002653 err("Unknown image sensor version: %d", rc & 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002654}
2655
2656/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
2657 * the same register settings as the OV7610, since they are very similar.
2658 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002659static void ov7xx0_configure(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002660{
2661 int rc, high, low;
2662
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002663 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
2664
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002665 /* Detect sensor (sub)type */
2666 rc = i2c_r(sd, OV7610_REG_COM_I);
2667
2668 /* add OV7670 here
2669 * it appears to be wrongly detected as a 7610 by default */
2670 if (rc < 0) {
2671 PDEBUG(D_ERR, "Error detecting sensor type");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002672 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002673 }
2674 if ((rc & 3) == 3) {
2675 /* quick hack to make OV7670s work */
2676 high = i2c_r(sd, 0x0a);
2677 low = i2c_r(sd, 0x0b);
2678 /* info("%x, %x", high, low); */
Jean-François Moine7a5a4142010-12-25 13:58:45 -03002679 if (high == 0x76 && (low & 0xf0) == 0x70) {
2680 PDEBUG(D_PROBE, "Sensor is an OV76%02x", low);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002681 sd->sensor = SEN_OV7670;
2682 } else {
2683 PDEBUG(D_PROBE, "Sensor is an OV7610");
2684 sd->sensor = SEN_OV7610;
2685 }
2686 } else if ((rc & 3) == 1) {
2687 /* I don't know what's different about the 76BE yet. */
Hans de Goedeb282d872009-06-14 19:10:40 -03002688 if (i2c_r(sd, 0x15) & 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002689 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
Hans de Goede859cc472010-01-07 15:42:35 -03002690 sd->sensor = SEN_OV7620AE;
Hans de Goedeb282d872009-06-14 19:10:40 -03002691 } else {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002692 PDEBUG(D_PROBE, "Sensor is an OV76BE");
Hans de Goedeb282d872009-06-14 19:10:40 -03002693 sd->sensor = SEN_OV76BE;
2694 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002695 } else if ((rc & 3) == 0) {
2696 /* try to read product id registers */
2697 high = i2c_r(sd, 0x0a);
2698 if (high < 0) {
2699 PDEBUG(D_ERR, "Error detecting camera chip PID");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002700 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002701 }
2702 low = i2c_r(sd, 0x0b);
2703 if (low < 0) {
2704 PDEBUG(D_ERR, "Error detecting camera chip VER");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002705 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002706 }
2707 if (high == 0x76) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002708 switch (low) {
2709 case 0x30:
Jean-François Moine0b656322010-09-13 05:19:58 -03002710 err("Sensor is an OV7630/OV7635");
2711 err("7630 is not supported by this driver");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002712 return;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002713 case 0x40:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002714 PDEBUG(D_PROBE, "Sensor is an OV7645");
2715 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002716 break;
2717 case 0x45:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002718 PDEBUG(D_PROBE, "Sensor is an OV7645B");
2719 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002720 break;
2721 case 0x48:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002722 PDEBUG(D_PROBE, "Sensor is an OV7648");
Hans de Goede035d3a32010-01-09 08:14:43 -03002723 sd->sensor = SEN_OV7648;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002724 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03002725 case 0x60:
2726 PDEBUG(D_PROBE, "Sensor is a OV7660");
2727 sd->sensor = SEN_OV7660;
2728 sd->invert_led = 0;
2729 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002730 default:
2731 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002732 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002733 }
2734 } else {
2735 PDEBUG(D_PROBE, "Sensor is an OV7620");
2736 sd->sensor = SEN_OV7620;
2737 }
2738 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03002739 err("Unknown image sensor version: %d", rc & 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002740 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002741}
2742
2743/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002744static void ov6xx0_configure(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002745{
2746 int rc;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002747 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002748
2749 /* Detect sensor (sub)type */
2750 rc = i2c_r(sd, OV7610_REG_COM_I);
2751 if (rc < 0) {
2752 PDEBUG(D_ERR, "Error detecting sensor type");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002753 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002754 }
2755
2756 /* Ugh. The first two bits are the version bits, but
2757 * the entire register value must be used. I guess OVT
2758 * underestimated how many variants they would make. */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002759 switch (rc) {
2760 case 0x00:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002761 sd->sensor = SEN_OV6630;
Jean-François Moine0b656322010-09-13 05:19:58 -03002762 warn("WARNING: Sensor is an OV66308. Your camera may have");
2763 warn("been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002764 break;
2765 case 0x01:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002766 sd->sensor = SEN_OV6620;
Hans de Goede7d971372009-06-14 05:28:17 -03002767 PDEBUG(D_PROBE, "Sensor is an OV6620");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002768 break;
2769 case 0x02:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002770 sd->sensor = SEN_OV6630;
2771 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002772 break;
2773 case 0x03:
Hans de Goede7d971372009-06-14 05:28:17 -03002774 sd->sensor = SEN_OV66308AF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002775 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002776 break;
2777 case 0x90:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002778 sd->sensor = SEN_OV6630;
Jean-François Moine0b656322010-09-13 05:19:58 -03002779 warn("WARNING: Sensor is an OV66307. Your camera may have");
2780 warn("been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002781 break;
2782 default:
Jean-François Moine0b656322010-09-13 05:19:58 -03002783 err("FATAL: Unknown sensor version: 0x%02x", rc);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002784 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002785 }
2786
2787 /* Set sensor-specific vars */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002788 sd->sif = 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002789}
2790
2791/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
2792static void ov51x_led_control(struct sd *sd, int on)
2793{
Hans de Goede9e4d8252009-06-14 06:25:06 -03002794 if (sd->invert_led)
2795 on = !on;
2796
Hans de Goede49809d62009-06-07 12:10:39 -03002797 switch (sd->bridge) {
2798 /* OV511 has no LED control */
2799 case BRIDGE_OV511PLUS:
Jean-François Moinea23acec42010-11-12 15:07:35 -03002800 reg_w(sd, R511_SYS_LED_CTL, on);
Hans de Goede49809d62009-06-07 12:10:39 -03002801 break;
2802 case BRIDGE_OV518:
2803 case BRIDGE_OV518PLUS:
Jean-François Moinea23acec42010-11-12 15:07:35 -03002804 reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02);
Hans de Goede49809d62009-06-07 12:10:39 -03002805 break;
2806 case BRIDGE_OV519:
Jean-François Moinea23acec42010-11-12 15:07:35 -03002807 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1);
Hans de Goede49809d62009-06-07 12:10:39 -03002808 break;
2809 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002810}
2811
Hans de Goede417a4d22010-02-19 07:37:08 -03002812static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
2813{
2814 struct sd *sd = (struct sd *) gspca_dev;
2815
2816 if (!sd->snapshot_needs_reset)
2817 return;
2818
2819 /* Note it is important that we clear sd->snapshot_needs_reset,
2820 before actually clearing the snapshot state in the bridge
2821 otherwise we might race with the pkt_scan interrupt handler */
2822 sd->snapshot_needs_reset = 0;
2823
2824 switch (sd->bridge) {
Hans de Goede88e8d202010-02-20 04:45:49 -03002825 case BRIDGE_OV511:
2826 case BRIDGE_OV511PLUS:
2827 reg_w(sd, R51x_SYS_SNAP, 0x02);
2828 reg_w(sd, R51x_SYS_SNAP, 0x00);
2829 break;
Hans de Goede92e232a2010-02-20 04:30:45 -03002830 case BRIDGE_OV518:
2831 case BRIDGE_OV518PLUS:
2832 reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
2833 reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
2834 break;
Hans de Goede417a4d22010-02-19 07:37:08 -03002835 case BRIDGE_OV519:
2836 reg_w(sd, R51x_SYS_RESET, 0x40);
2837 reg_w(sd, R51x_SYS_RESET, 0x00);
2838 break;
2839 }
2840}
2841
Jean-François Moinef8f20182010-11-12 07:54:02 -03002842static void ov51x_upload_quan_tables(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03002843{
Hans de Goede1876bb92009-06-14 06:45:50 -03002844 const unsigned char yQuanTable511[] = {
2845 0, 1, 1, 2, 2, 3, 3, 4,
2846 1, 1, 1, 2, 2, 3, 4, 4,
2847 1, 1, 2, 2, 3, 4, 4, 4,
2848 2, 2, 2, 3, 4, 4, 4, 4,
2849 2, 2, 3, 4, 4, 5, 5, 5,
2850 3, 3, 4, 4, 5, 5, 5, 5,
2851 3, 4, 4, 4, 5, 5, 5, 5,
2852 4, 4, 4, 4, 5, 5, 5, 5
2853 };
2854
2855 const unsigned char uvQuanTable511[] = {
2856 0, 2, 2, 3, 4, 4, 4, 4,
2857 2, 2, 2, 4, 4, 4, 4, 4,
2858 2, 2, 3, 4, 4, 4, 4, 4,
2859 3, 4, 4, 4, 4, 4, 4, 4,
2860 4, 4, 4, 4, 4, 4, 4, 4,
2861 4, 4, 4, 4, 4, 4, 4, 4,
2862 4, 4, 4, 4, 4, 4, 4, 4,
2863 4, 4, 4, 4, 4, 4, 4, 4
2864 };
2865
2866 /* OV518 quantization tables are 8x4 (instead of 8x8) */
Hans de Goede49809d62009-06-07 12:10:39 -03002867 const unsigned char yQuanTable518[] = {
2868 5, 4, 5, 6, 6, 7, 7, 7,
2869 5, 5, 5, 5, 6, 7, 7, 7,
2870 6, 6, 6, 6, 7, 7, 7, 8,
2871 7, 7, 6, 7, 7, 7, 8, 8
2872 };
Hans de Goede49809d62009-06-07 12:10:39 -03002873 const unsigned char uvQuanTable518[] = {
2874 6, 6, 6, 7, 7, 7, 7, 7,
2875 6, 6, 6, 7, 7, 7, 7, 7,
2876 6, 6, 6, 7, 7, 7, 7, 8,
2877 7, 7, 7, 7, 7, 7, 8, 8
2878 };
2879
Hans de Goede1876bb92009-06-14 06:45:50 -03002880 const unsigned char *pYTable, *pUVTable;
Hans de Goede49809d62009-06-07 12:10:39 -03002881 unsigned char val0, val1;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002882 int i, size, reg = R51x_COMP_LUT_BEGIN;
Hans de Goede49809d62009-06-07 12:10:39 -03002883
2884 PDEBUG(D_PROBE, "Uploading quantization tables");
2885
Hans de Goede1876bb92009-06-14 06:45:50 -03002886 if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
2887 pYTable = yQuanTable511;
2888 pUVTable = uvQuanTable511;
Jean-François Moine87bae742010-11-12 05:31:34 -03002889 size = 32;
Hans de Goede1876bb92009-06-14 06:45:50 -03002890 } else {
2891 pYTable = yQuanTable518;
2892 pUVTable = uvQuanTable518;
Jean-François Moine87bae742010-11-12 05:31:34 -03002893 size = 16;
Hans de Goede1876bb92009-06-14 06:45:50 -03002894 }
2895
2896 for (i = 0; i < size; i++) {
Hans de Goede49809d62009-06-07 12:10:39 -03002897 val0 = *pYTable++;
2898 val1 = *pYTable++;
2899 val0 &= 0x0f;
2900 val1 &= 0x0f;
2901 val0 |= val1 << 4;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002902 reg_w(sd, reg, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03002903
2904 val0 = *pUVTable++;
2905 val1 = *pUVTable++;
2906 val0 &= 0x0f;
2907 val1 &= 0x0f;
2908 val0 |= val1 << 4;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002909 reg_w(sd, reg + size, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03002910
2911 reg++;
2912 }
Hans de Goede49809d62009-06-07 12:10:39 -03002913}
2914
Hans de Goede1876bb92009-06-14 06:45:50 -03002915/* This initializes the OV511/OV511+ and the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002916static void ov511_configure(struct gspca_dev *gspca_dev)
Hans de Goede1876bb92009-06-14 06:45:50 -03002917{
2918 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede1876bb92009-06-14 06:45:50 -03002919
2920 /* For 511 and 511+ */
2921 const struct ov_regvals init_511[] = {
2922 { R51x_SYS_RESET, 0x7f },
2923 { R51x_SYS_INIT, 0x01 },
2924 { R51x_SYS_RESET, 0x7f },
2925 { R51x_SYS_INIT, 0x01 },
2926 { R51x_SYS_RESET, 0x3f },
2927 { R51x_SYS_INIT, 0x01 },
2928 { R51x_SYS_RESET, 0x3d },
2929 };
2930
2931 const struct ov_regvals norm_511[] = {
Jean-François Moine780e3122010-10-19 04:29:10 -03002932 { R511_DRAM_FLOW_CTL, 0x01 },
Hans de Goede1876bb92009-06-14 06:45:50 -03002933 { R51x_SYS_SNAP, 0x00 },
2934 { R51x_SYS_SNAP, 0x02 },
2935 { R51x_SYS_SNAP, 0x00 },
2936 { R511_FIFO_OPTS, 0x1f },
2937 { R511_COMP_EN, 0x00 },
2938 { R511_COMP_LUT_EN, 0x03 },
2939 };
2940
2941 const struct ov_regvals norm_511_p[] = {
2942 { R511_DRAM_FLOW_CTL, 0xff },
2943 { R51x_SYS_SNAP, 0x00 },
2944 { R51x_SYS_SNAP, 0x02 },
2945 { R51x_SYS_SNAP, 0x00 },
2946 { R511_FIFO_OPTS, 0xff },
2947 { R511_COMP_EN, 0x00 },
2948 { R511_COMP_LUT_EN, 0x03 },
2949 };
2950
2951 const struct ov_regvals compress_511[] = {
2952 { 0x70, 0x1f },
2953 { 0x71, 0x05 },
2954 { 0x72, 0x06 },
2955 { 0x73, 0x06 },
2956 { 0x74, 0x14 },
2957 { 0x75, 0x03 },
2958 { 0x76, 0x04 },
2959 { 0x77, 0x04 },
2960 };
2961
2962 PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
2963
Jean-François Moinef8f20182010-11-12 07:54:02 -03002964 write_regvals(sd, init_511, ARRAY_SIZE(init_511));
Hans de Goede1876bb92009-06-14 06:45:50 -03002965
2966 switch (sd->bridge) {
2967 case BRIDGE_OV511:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002968 write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
Hans de Goede1876bb92009-06-14 06:45:50 -03002969 break;
2970 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002971 write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
Hans de Goede1876bb92009-06-14 06:45:50 -03002972 break;
2973 }
2974
2975 /* Init compression */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002976 write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
Hans de Goede1876bb92009-06-14 06:45:50 -03002977
Jean-François Moinef8f20182010-11-12 07:54:02 -03002978 ov51x_upload_quan_tables(sd);
Hans de Goede1876bb92009-06-14 06:45:50 -03002979}
2980
Hans de Goede49809d62009-06-07 12:10:39 -03002981/* This initializes the OV518/OV518+ and the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002982static void ov518_configure(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002983{
2984 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002985
Hans de Goede49809d62009-06-07 12:10:39 -03002986 /* For 518 and 518+ */
Hans de Goedee080fcd2009-06-18 05:03:16 -03002987 const struct ov_regvals init_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002988 { R51x_SYS_RESET, 0x40 },
2989 { R51x_SYS_INIT, 0xe1 },
2990 { R51x_SYS_RESET, 0x3e },
2991 { R51x_SYS_INIT, 0xe1 },
2992 { R51x_SYS_RESET, 0x00 },
2993 { R51x_SYS_INIT, 0xe1 },
2994 { 0x46, 0x00 },
2995 { 0x5d, 0x03 },
2996 };
2997
Hans de Goedee080fcd2009-06-18 05:03:16 -03002998 const struct ov_regvals norm_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03002999 { R51x_SYS_SNAP, 0x02 }, /* Reset */
3000 { R51x_SYS_SNAP, 0x01 }, /* Enable */
Jean-François Moine780e3122010-10-19 04:29:10 -03003001 { 0x31, 0x0f },
Hans de Goede49809d62009-06-07 12:10:39 -03003002 { 0x5d, 0x03 },
3003 { 0x24, 0x9f },
3004 { 0x25, 0x90 },
3005 { 0x20, 0x00 },
3006 { 0x51, 0x04 },
3007 { 0x71, 0x19 },
3008 { 0x2f, 0x80 },
3009 };
3010
Hans de Goedee080fcd2009-06-18 05:03:16 -03003011 const struct ov_regvals norm_518_p[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03003012 { R51x_SYS_SNAP, 0x02 }, /* Reset */
3013 { R51x_SYS_SNAP, 0x01 }, /* Enable */
Jean-François Moine780e3122010-10-19 04:29:10 -03003014 { 0x31, 0x0f },
Hans de Goede49809d62009-06-07 12:10:39 -03003015 { 0x5d, 0x03 },
3016 { 0x24, 0x9f },
3017 { 0x25, 0x90 },
3018 { 0x20, 0x60 },
3019 { 0x51, 0x02 },
3020 { 0x71, 0x19 },
3021 { 0x40, 0xff },
3022 { 0x41, 0x42 },
3023 { 0x46, 0x00 },
3024 { 0x33, 0x04 },
3025 { 0x21, 0x19 },
3026 { 0x3f, 0x10 },
3027 { 0x2f, 0x80 },
3028 };
3029
3030 /* First 5 bits of custom ID reg are a revision ID on OV518 */
3031 PDEBUG(D_PROBE, "Device revision %d",
Jean-François Moine87bae742010-11-12 05:31:34 -03003032 0x1f & reg_r(sd, R51x_SYS_CUST_ID));
Hans de Goede49809d62009-06-07 12:10:39 -03003033
Jean-François Moinef8f20182010-11-12 07:54:02 -03003034 write_regvals(sd, init_518, ARRAY_SIZE(init_518));
Hans de Goede49809d62009-06-07 12:10:39 -03003035
3036 /* Set LED GPIO pin to output mode */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003037 reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
Hans de Goede49809d62009-06-07 12:10:39 -03003038
3039 switch (sd->bridge) {
3040 case BRIDGE_OV518:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003041 write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
Hans de Goede49809d62009-06-07 12:10:39 -03003042 break;
3043 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003044 write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
Hans de Goede49809d62009-06-07 12:10:39 -03003045 break;
3046 }
3047
Jean-François Moinef8f20182010-11-12 07:54:02 -03003048 ov51x_upload_quan_tables(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003049
Jean-François Moinef8f20182010-11-12 07:54:02 -03003050 reg_w(sd, 0x2f, 0x80);
Hans de Goede49809d62009-06-07 12:10:39 -03003051}
3052
Jean-François Moinef8f20182010-11-12 07:54:02 -03003053static void ov519_configure(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03003054{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003055 static const struct ov_regvals init_519[] = {
Jean-François Moine87bae742010-11-12 05:31:34 -03003056 { 0x5a, 0x6d }, /* EnableSystem */
3057 { 0x53, 0x9b },
Jean-François Moine21867802010-11-12 06:12:09 -03003058 { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
Jean-François Moine87bae742010-11-12 05:31:34 -03003059 { 0x5d, 0x03 },
3060 { 0x49, 0x01 },
3061 { 0x48, 0x00 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003062 /* Set LED pin to output mode. Bit 4 must be cleared or sensor
3063 * detection will fail. This deserves further investigation. */
3064 { OV519_GPIO_IO_CTRL0, 0xee },
Jean-François Moine21867802010-11-12 06:12:09 -03003065 { OV519_R51_RESET1, 0x0f },
3066 { OV519_R51_RESET1, 0x00 },
Jean-François Moine87bae742010-11-12 05:31:34 -03003067 { 0x22, 0x00 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003068 /* windows reads 0x55 at this point*/
3069 };
3070
Jean-François Moinef8f20182010-11-12 07:54:02 -03003071 write_regvals(sd, init_519, ARRAY_SIZE(init_519));
Hans de Goede49809d62009-06-07 12:10:39 -03003072}
3073
Jean-François Moinef8f20182010-11-12 07:54:02 -03003074static void ovfx2_configure(struct sd *sd)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003075{
3076 static const struct ov_regvals init_fx2[] = {
3077 { 0x00, 0x60 },
3078 { 0x02, 0x01 },
3079 { 0x0f, 0x1d },
3080 { 0xe9, 0x82 },
3081 { 0xea, 0xc7 },
3082 { 0xeb, 0x10 },
3083 { 0xec, 0xf6 },
3084 };
3085
3086 sd->stopped = 1;
3087
Jean-François Moinef8f20182010-11-12 07:54:02 -03003088 write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003089}
3090
Jean-François Moine42e142f2010-11-13 05:10:27 -03003091/* set the mode */
3092/* This function works for ov7660 only */
3093static void ov519_set_mode(struct sd *sd)
3094{
3095 static const struct ov_regvals bridge_ov7660[2][10] = {
3096 {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
3097 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3098 {0x25, 0x01}, {0x26, 0x00}},
3099 {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
3100 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3101 {0x25, 0x03}, {0x26, 0x00}}
3102 };
3103 static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
3104 {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
3105 {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
3106 };
3107 static const struct ov_i2c_regvals sensor_ov7660_2[] = {
3108 {OV7670_R17_HSTART, 0x13},
3109 {OV7670_R18_HSTOP, 0x01},
3110 {OV7670_R32_HREF, 0x92},
3111 {OV7670_R19_VSTART, 0x02},
3112 {OV7670_R1A_VSTOP, 0x7a},
3113 {OV7670_R03_VREF, 0x00},
3114/* {0x33, 0x00}, */
3115/* {0x34, 0x07}, */
3116/* {0x36, 0x00}, */
3117/* {0x6b, 0x0a}, */
3118 };
3119
3120 write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
3121 ARRAY_SIZE(bridge_ov7660[0]));
3122 write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
3123 ARRAY_SIZE(sensor_ov7660[0]));
3124 write_i2c_regvals(sd, sensor_ov7660_2,
3125 ARRAY_SIZE(sensor_ov7660_2));
3126}
3127
3128/* set the frame rate */
3129/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */
3130static void ov519_set_fr(struct sd *sd)
3131{
3132 int fr;
3133 u8 clock;
3134 /* frame rate table with indices:
3135 * - mode = 0: 320x240, 1: 640x480
3136 * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5
3137 * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock)
3138 */
3139 static const u8 fr_tb[2][6][3] = {
3140 {{0x04, 0xff, 0x00},
3141 {0x04, 0x1f, 0x00},
3142 {0x04, 0x1b, 0x00},
3143 {0x04, 0x15, 0x00},
3144 {0x04, 0x09, 0x00},
3145 {0x04, 0x01, 0x00}},
3146 {{0x0c, 0xff, 0x00},
3147 {0x0c, 0x1f, 0x00},
3148 {0x0c, 0x1b, 0x00},
3149 {0x04, 0xff, 0x01},
3150 {0x04, 0x1f, 0x01},
3151 {0x04, 0x1b, 0x01}},
3152 };
3153
3154 if (frame_rate > 0)
3155 sd->frame_rate = frame_rate;
3156 if (sd->frame_rate >= 30)
3157 fr = 0;
3158 else if (sd->frame_rate >= 25)
3159 fr = 1;
3160 else if (sd->frame_rate >= 20)
3161 fr = 2;
3162 else if (sd->frame_rate >= 15)
3163 fr = 3;
3164 else if (sd->frame_rate >= 10)
3165 fr = 4;
3166 else
3167 fr = 5;
3168 reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
3169 reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
3170 clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
3171 if (sd->sensor == SEN_OV7660)
3172 clock |= 0x80; /* enable double clock */
3173 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
3174}
3175
Hans de Goede49809d62009-06-07 12:10:39 -03003176/* this function is called at probe time */
3177static int sd_config(struct gspca_dev *gspca_dev,
3178 const struct usb_device_id *id)
3179{
3180 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003181 struct cam *cam = &gspca_dev->cam;
Hans de Goede49809d62009-06-07 12:10:39 -03003182
Hans de Goede9e4d8252009-06-14 06:25:06 -03003183 sd->bridge = id->driver_info & BRIDGE_MASK;
Jean-François Moinea23acec42010-11-12 15:07:35 -03003184 sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0;
Hans de Goede49809d62009-06-07 12:10:39 -03003185
3186 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003187 case BRIDGE_OV511:
3188 case BRIDGE_OV511PLUS:
Jean-François Moine7491f782010-11-13 03:56:41 -03003189 cam->cam_mode = ov511_vga_mode;
3190 cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
3191 break;
3192 case BRIDGE_OV518:
3193 case BRIDGE_OV518PLUS:
3194 cam->cam_mode = ov518_vga_mode;
3195 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
3196 break;
3197 case BRIDGE_OV519:
3198 cam->cam_mode = ov519_vga_mode;
3199 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3200 sd->invert_led = !sd->invert_led;
3201 break;
3202 case BRIDGE_OVFX2:
3203 cam->cam_mode = ov519_vga_mode;
3204 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3205 cam->bulk_size = OVFX2_BULK_SIZE;
3206 cam->bulk_nurbs = MAX_NURBS;
3207 cam->bulk = 1;
3208 break;
3209 case BRIDGE_W9968CF:
3210 cam->cam_mode = w9968cf_vga_mode;
3211 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
3212 cam->reverse_alts = 1;
3213 break;
3214 }
3215
3216 gspca_dev->cam.ctrls = sd->ctrls;
3217 sd->quality = QUALITY_DEF;
3218
3219 return 0;
3220}
3221
3222/* this function is called at probe and resume time */
3223static int sd_init(struct gspca_dev *gspca_dev)
3224{
3225 struct sd *sd = (struct sd *) gspca_dev;
3226 struct cam *cam = &gspca_dev->cam;
3227
3228 switch (sd->bridge) {
3229 case BRIDGE_OV511:
3230 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003231 ov511_configure(gspca_dev);
Hans de Goede1876bb92009-06-14 06:45:50 -03003232 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003233 case BRIDGE_OV518:
3234 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003235 ov518_configure(gspca_dev);
Hans de Goede49809d62009-06-07 12:10:39 -03003236 break;
3237 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003238 ov519_configure(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003239 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003240 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003241 ovfx2_configure(sd);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003242 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003243 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003244 w9968cf_configure(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03003245 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003246 }
3247
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003248 /* The OV519 must be more aggressive about sensor detection since
3249 * I2C write will never fail if the sensor is not present. We have
3250 * to try to initialize the sensor to detect its presence */
Jean-François Moine7bbe6b82010-11-11 08:27:24 -03003251 sd->sensor = -1;
Hans de Goede229bb7d2009-10-11 07:41:46 -03003252
3253 /* Test for 76xx */
3254 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003255 ov7xx0_configure(sd);
3256
Hans de Goede229bb7d2009-10-11 07:41:46 -03003257 /* Test for 6xx0 */
3258 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003259 ov6xx0_configure(sd);
3260
Hans de Goede229bb7d2009-10-11 07:41:46 -03003261 /* Test for 8xx0 */
3262 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003263 ov8xx0_configure(sd);
3264
Hans de Goede635118d2009-10-11 09:49:03 -03003265 /* Test for 3xxx / 2xxx */
3266 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003267 ov_hires_configure(sd);
Hans de Goede229bb7d2009-10-11 07:41:46 -03003268 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03003269 err("Can't determine sensor slave IDs");
Hans de Goede229bb7d2009-10-11 07:41:46 -03003270 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003271 }
3272
Jean-François Moine7bbe6b82010-11-11 08:27:24 -03003273 if (sd->sensor < 0)
3274 goto error;
3275
Jean-François Moine7491f782010-11-13 03:56:41 -03003276 ov51x_led_control(sd, 0); /* turn LED off */
3277
Hans de Goede49809d62009-06-07 12:10:39 -03003278 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003279 case BRIDGE_OV511:
3280 case BRIDGE_OV511PLUS:
Jean-François Moine7491f782010-11-13 03:56:41 -03003281 if (sd->sif) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003282 cam->cam_mode = ov511_sif_mode;
3283 cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
3284 }
3285 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003286 case BRIDGE_OV518:
3287 case BRIDGE_OV518PLUS:
Jean-François Moine7491f782010-11-13 03:56:41 -03003288 if (sd->sif) {
Hans de Goede49809d62009-06-07 12:10:39 -03003289 cam->cam_mode = ov518_sif_mode;
3290 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
3291 }
3292 break;
3293 case BRIDGE_OV519:
Jean-François Moine7491f782010-11-13 03:56:41 -03003294 if (sd->sif) {
Hans de Goede49809d62009-06-07 12:10:39 -03003295 cam->cam_mode = ov519_sif_mode;
3296 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3297 }
3298 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003299 case BRIDGE_OVFX2:
3300 if (sd->sensor == SEN_OV2610) {
3301 cam->cam_mode = ovfx2_ov2610_mode;
3302 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3303 } else if (sd->sensor == SEN_OV3610) {
3304 cam->cam_mode = ovfx2_ov3610_mode;
3305 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
Jean-François Moine7491f782010-11-13 03:56:41 -03003306 } else if (sd->sif) {
Hans de Goede635118d2009-10-11 09:49:03 -03003307 cam->cam_mode = ov519_sif_mode;
3308 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3309 }
3310 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003311 case BRIDGE_W9968CF:
Hans de Goede79b35902009-10-19 06:08:01 -03003312 if (sd->sif)
Jean-François Moine7491f782010-11-13 03:56:41 -03003313 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1;
Hans de Goedea511ba92009-10-16 07:13:07 -03003314
3315 /* w9968cf needs initialisation once the sensor is known */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003316 w9968cf_init(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03003317 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003318 }
Jean-François Moine83db7682010-11-12 07:14:08 -03003319
3320 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Hans de Goede02ab18b2009-06-14 04:32:04 -03003321
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003322 /* initialize the sensor */
3323 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003324 case SEN_OV2610:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003325 write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610));
3326
Hans de Goede635118d2009-10-11 09:49:03 -03003327 /* Enable autogain, autoexpo, awb, bandfilter */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003328 i2c_w_mask(sd, 0x13, 0x27, 0x27);
Hans de Goede635118d2009-10-11 09:49:03 -03003329 break;
3330 case SEN_OV3610:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003331 write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
3332
Hans de Goede635118d2009-10-11 09:49:03 -03003333 /* Enable autogain, autoexpo, awb, bandfilter */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003334 i2c_w_mask(sd, 0x13, 0x27, 0x27);
Hans de Goede635118d2009-10-11 09:49:03 -03003335 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003336 case SEN_OV6620:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003337 write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003338 break;
3339 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003340 case SEN_OV66308AF:
Jean-François Moine62833ac2010-10-02 04:27:02 -03003341 sd->ctrls[CONTRAST].def = 200;
3342 /* The default is too low for the ov6630 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003343 write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003344 break;
3345 default:
3346/* case SEN_OV7610: */
3347/* case SEN_OV76BE: */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003348 write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610));
3349 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003350 break;
3351 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003352 case SEN_OV7620AE:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003353 write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003354 break;
3355 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003356 case SEN_OV7648:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003357 write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003358 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03003359 case SEN_OV7660:
3360 i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
3361 msleep(14);
3362 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
3363 write_regvals(sd, init_519_ov7660,
3364 ARRAY_SIZE(init_519_ov7660));
3365 write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
3366 sd->gspca_dev.curr_mode = 1; /* 640x480 */
3367 sd->frame_rate = 15;
3368 ov519_set_mode(sd);
3369 ov519_set_fr(sd);
3370 sd->ctrls[COLORS].max = 4; /* 0..4 */
3371 sd->ctrls[COLORS].val =
3372 sd->ctrls[COLORS].def = 2;
3373 setcolors(gspca_dev);
3374 sd->ctrls[CONTRAST].max = 6; /* 0..6 */
3375 sd->ctrls[CONTRAST].val =
3376 sd->ctrls[CONTRAST].def = 3;
3377 setcontrast(gspca_dev);
3378 sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */
3379 sd->ctrls[BRIGHTNESS].val =
3380 sd->ctrls[BRIGHTNESS].def = 3;
3381 setbrightness(gspca_dev);
3382 sd_reset_snapshot(gspca_dev);
3383 ov51x_restart(sd);
3384 ov51x_stop(sd); /* not in win traces */
3385 ov51x_led_control(sd, 0);
3386 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003387 case SEN_OV7670:
Jean-François Moine62833ac2010-10-02 04:27:02 -03003388 sd->ctrls[FREQ].max = 3; /* auto */
3389 sd->ctrls[FREQ].def = 3;
Jean-François Moinef8f20182010-11-12 07:54:02 -03003390 write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003391 break;
3392 case SEN_OV8610:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003393 write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003394 break;
3395 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03003396 return gspca_dev->usb_err;
Jean-François Moine7491f782010-11-13 03:56:41 -03003397error:
3398 PDEBUG(D_ERR, "OV519 Config failed");
3399 return -EINVAL;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003400}
3401
Hans de Goede1876bb92009-06-14 06:45:50 -03003402/* Set up the OV511/OV511+ with the given image parameters.
3403 *
3404 * Do not put any sensor-specific code in here (including I2C I/O functions)
3405 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003406static void ov511_mode_init_regs(struct sd *sd)
Hans de Goede1876bb92009-06-14 06:45:50 -03003407{
3408 int hsegs, vsegs, packet_size, fps, needed;
3409 int interlaced = 0;
3410 struct usb_host_interface *alt;
3411 struct usb_interface *intf;
3412
3413 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3414 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3415 if (!alt) {
Jean-François Moine0b656322010-09-13 05:19:58 -03003416 err("Couldn't get altsetting");
Jean-François Moinef8f20182010-11-12 07:54:02 -03003417 sd->gspca_dev.usb_err = -EIO;
3418 return;
Hans de Goede1876bb92009-06-14 06:45:50 -03003419 }
3420
3421 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3422 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3423
3424 reg_w(sd, R511_CAM_UV_EN, 0x01);
3425 reg_w(sd, R511_SNAP_UV_EN, 0x01);
3426 reg_w(sd, R511_SNAP_OPTS, 0x03);
3427
3428 /* Here I'm assuming that snapshot size == image size.
3429 * I hope that's always true. --claudio
3430 */
3431 hsegs = (sd->gspca_dev.width >> 3) - 1;
3432 vsegs = (sd->gspca_dev.height >> 3) - 1;
3433
3434 reg_w(sd, R511_CAM_PXCNT, hsegs);
3435 reg_w(sd, R511_CAM_LNCNT, vsegs);
3436 reg_w(sd, R511_CAM_PXDIV, 0x00);
3437 reg_w(sd, R511_CAM_LNDIV, 0x00);
3438
3439 /* YUV420, low pass filter on */
3440 reg_w(sd, R511_CAM_OPTS, 0x03);
3441
3442 /* Snapshot additions */
3443 reg_w(sd, R511_SNAP_PXCNT, hsegs);
3444 reg_w(sd, R511_SNAP_LNCNT, vsegs);
3445 reg_w(sd, R511_SNAP_PXDIV, 0x00);
3446 reg_w(sd, R511_SNAP_LNDIV, 0x00);
3447
3448 /******** Set the framerate ********/
3449 if (frame_rate > 0)
3450 sd->frame_rate = frame_rate;
3451
3452 switch (sd->sensor) {
3453 case SEN_OV6620:
3454 /* No framerate control, doesn't like higher rates yet */
3455 sd->clockdiv = 3;
3456 break;
3457
3458 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
3459 for more sensors we need to do this for them too */
3460 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003461 case SEN_OV7620AE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003462 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003463 case SEN_OV7648:
Hans de Goedeb282d872009-06-14 19:10:40 -03003464 case SEN_OV76BE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003465 if (sd->gspca_dev.width == 320)
3466 interlaced = 1;
3467 /* Fall through */
3468 case SEN_OV6630:
Hans de Goede1876bb92009-06-14 06:45:50 -03003469 case SEN_OV7610:
3470 case SEN_OV7670:
3471 switch (sd->frame_rate) {
3472 case 30:
3473 case 25:
3474 /* Not enough bandwidth to do 640x480 @ 30 fps */
3475 if (sd->gspca_dev.width != 640) {
3476 sd->clockdiv = 0;
3477 break;
3478 }
3479 /* Fall through for 640x480 case */
3480 default:
3481/* case 20: */
3482/* case 15: */
3483 sd->clockdiv = 1;
3484 break;
3485 case 10:
3486 sd->clockdiv = 2;
3487 break;
3488 case 5:
3489 sd->clockdiv = 5;
3490 break;
3491 }
3492 if (interlaced) {
3493 sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
3494 /* Higher then 10 does not work */
3495 if (sd->clockdiv > 10)
3496 sd->clockdiv = 10;
3497 }
3498 break;
3499
3500 case SEN_OV8610:
3501 /* No framerate control ?? */
3502 sd->clockdiv = 0;
3503 break;
3504 }
3505
3506 /* Check if we have enough bandwidth to disable compression */
3507 fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
3508 needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2;
3509 /* 1400 is a conservative estimate of the max nr of isoc packets/sec */
3510 if (needed > 1400 * packet_size) {
3511 /* Enable Y and UV quantization and compression */
3512 reg_w(sd, R511_COMP_EN, 0x07);
3513 reg_w(sd, R511_COMP_LUT_EN, 0x03);
3514 } else {
3515 reg_w(sd, R511_COMP_EN, 0x06);
3516 reg_w(sd, R511_COMP_LUT_EN, 0x00);
3517 }
3518
3519 reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
3520 reg_w(sd, R51x_SYS_RESET, 0);
Hans de Goede1876bb92009-06-14 06:45:50 -03003521}
3522
Hans de Goede49809d62009-06-07 12:10:39 -03003523/* Sets up the OV518/OV518+ with the given image parameters
3524 *
3525 * OV518 needs a completely different approach, until we can figure out what
3526 * the individual registers do. Also, only 15 FPS is supported now.
3527 *
3528 * Do not put any sensor-specific code in here (including I2C I/O functions)
3529 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003530static void ov518_mode_init_regs(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03003531{
Hans de Goedeb282d872009-06-14 19:10:40 -03003532 int hsegs, vsegs, packet_size;
3533 struct usb_host_interface *alt;
3534 struct usb_interface *intf;
3535
3536 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3537 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3538 if (!alt) {
Jean-François Moine0b656322010-09-13 05:19:58 -03003539 err("Couldn't get altsetting");
Jean-François Moinef8f20182010-11-12 07:54:02 -03003540 sd->gspca_dev.usb_err = -EIO;
3541 return;
Hans de Goedeb282d872009-06-14 19:10:40 -03003542 }
3543
3544 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3545 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
Hans de Goede49809d62009-06-07 12:10:39 -03003546
3547 /******** Set the mode ********/
Hans de Goede49809d62009-06-07 12:10:39 -03003548 reg_w(sd, 0x2b, 0);
3549 reg_w(sd, 0x2c, 0);
3550 reg_w(sd, 0x2d, 0);
3551 reg_w(sd, 0x2e, 0);
3552 reg_w(sd, 0x3b, 0);
3553 reg_w(sd, 0x3c, 0);
3554 reg_w(sd, 0x3d, 0);
3555 reg_w(sd, 0x3e, 0);
3556
3557 if (sd->bridge == BRIDGE_OV518) {
3558 /* Set 8-bit (YVYU) input format */
3559 reg_w_mask(sd, 0x20, 0x08, 0x08);
3560
3561 /* Set 12-bit (4:2:0) output format */
3562 reg_w_mask(sd, 0x28, 0x80, 0xf0);
3563 reg_w_mask(sd, 0x38, 0x80, 0xf0);
3564 } else {
3565 reg_w(sd, 0x28, 0x80);
3566 reg_w(sd, 0x38, 0x80);
3567 }
3568
3569 hsegs = sd->gspca_dev.width / 16;
3570 vsegs = sd->gspca_dev.height / 4;
3571
3572 reg_w(sd, 0x29, hsegs);
3573 reg_w(sd, 0x2a, vsegs);
3574
3575 reg_w(sd, 0x39, hsegs);
3576 reg_w(sd, 0x3a, vsegs);
3577
3578 /* Windows driver does this here; who knows why */
3579 reg_w(sd, 0x2f, 0x80);
3580
Jean-François Moine87bae742010-11-12 05:31:34 -03003581 /******** Set the framerate ********/
Hans de Goedeb282d872009-06-14 19:10:40 -03003582 sd->clockdiv = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03003583
3584 /* Mode independent, but framerate dependent, regs */
Hans de Goedeb282d872009-06-14 19:10:40 -03003585 /* 0x51: Clock divider; Only works on some cams which use 2 crystals */
3586 reg_w(sd, 0x51, 0x04);
Hans de Goede49809d62009-06-07 12:10:39 -03003587 reg_w(sd, 0x22, 0x18);
3588 reg_w(sd, 0x23, 0xff);
3589
Hans de Goedeb282d872009-06-14 19:10:40 -03003590 if (sd->bridge == BRIDGE_OV518PLUS) {
3591 switch (sd->sensor) {
Hans de Goede859cc472010-01-07 15:42:35 -03003592 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003593 if (sd->gspca_dev.width == 320) {
3594 reg_w(sd, 0x20, 0x00);
3595 reg_w(sd, 0x21, 0x19);
3596 } else {
3597 reg_w(sd, 0x20, 0x60);
3598 reg_w(sd, 0x21, 0x1f);
3599 }
3600 break;
Hans de Goede859cc472010-01-07 15:42:35 -03003601 case SEN_OV7620:
3602 reg_w(sd, 0x20, 0x00);
3603 reg_w(sd, 0x21, 0x19);
3604 break;
Hans de Goedeb282d872009-06-14 19:10:40 -03003605 default:
3606 reg_w(sd, 0x21, 0x19);
3607 }
3608 } else
Hans de Goede49809d62009-06-07 12:10:39 -03003609 reg_w(sd, 0x71, 0x17); /* Compression-related? */
3610
3611 /* FIXME: Sensor-specific */
3612 /* Bit 5 is what matters here. Of course, it is "reserved" */
3613 i2c_w(sd, 0x54, 0x23);
3614
3615 reg_w(sd, 0x2f, 0x80);
3616
3617 if (sd->bridge == BRIDGE_OV518PLUS) {
3618 reg_w(sd, 0x24, 0x94);
3619 reg_w(sd, 0x25, 0x90);
3620 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3621 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
3622 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
3623 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
3624 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
3625 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
3626 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
3627 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
3628 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
3629 } else {
3630 reg_w(sd, 0x24, 0x9f);
3631 reg_w(sd, 0x25, 0x90);
3632 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3633 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
3634 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
3635 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
3636 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
3637 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
3638 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
3639 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
3640 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
3641 }
3642
3643 reg_w(sd, 0x2f, 0x80);
Hans de Goede49809d62009-06-07 12:10:39 -03003644}
3645
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003646/* Sets up the OV519 with the given image parameters
3647 *
3648 * OV519 needs a completely different approach, until we can figure out what
3649 * the individual registers do.
3650 *
3651 * Do not put any sensor-specific code in here (including I2C I/O functions)
3652 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003653static void ov519_mode_init_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003654{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003655 static const struct ov_regvals mode_init_519_ov7670[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003656 { 0x5d, 0x03 }, /* Turn off suspend mode */
3657 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
Jean-François Moine21867802010-11-12 06:12:09 -03003658 { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003659 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3660 { 0xa3, 0x18 },
3661 { 0xa4, 0x04 },
3662 { 0xa5, 0x28 },
3663 { 0x37, 0x00 }, /* SetUsbInit */
3664 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3665 /* Enable both fields, YUV Input, disable defect comp (why?) */
3666 { 0x20, 0x0c },
3667 { 0x21, 0x38 },
3668 { 0x22, 0x1d },
3669 { 0x17, 0x50 }, /* undocumented */
3670 { 0x37, 0x00 }, /* undocumented */
3671 { 0x40, 0xff }, /* I2C timeout counter */
3672 { 0x46, 0x00 }, /* I2C clock prescaler */
3673 { 0x59, 0x04 }, /* new from windrv 090403 */
3674 { 0xff, 0x00 }, /* undocumented */
3675 /* windows reads 0x55 at this point, why? */
3676 };
3677
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003678 static const struct ov_regvals mode_init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003679 { 0x5d, 0x03 }, /* Turn off suspend mode */
3680 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
Jean-François Moine21867802010-11-12 06:12:09 -03003681 { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003682 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3683 { 0xa3, 0x18 },
3684 { 0xa4, 0x04 },
3685 { 0xa5, 0x28 },
3686 { 0x37, 0x00 }, /* SetUsbInit */
3687 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3688 /* Enable both fields, YUV Input, disable defect comp (why?) */
3689 { 0x22, 0x1d },
3690 { 0x17, 0x50 }, /* undocumented */
3691 { 0x37, 0x00 }, /* undocumented */
3692 { 0x40, 0xff }, /* I2C timeout counter */
3693 { 0x46, 0x00 }, /* I2C clock prescaler */
3694 { 0x59, 0x04 }, /* new from windrv 090403 */
3695 { 0xff, 0x00 }, /* undocumented */
3696 /* windows reads 0x55 at this point, why? */
3697 };
3698
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003699 /******** Set the mode ********/
Jean-François Moine42e142f2010-11-13 05:10:27 -03003700 switch (sd->sensor) {
3701 default:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003702 write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
Hans de Goede035d3a32010-01-09 08:14:43 -03003703 if (sd->sensor == SEN_OV7640 ||
3704 sd->sensor == SEN_OV7648) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003705 /* Select 8-bit input mode */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003706 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003707 }
Jean-François Moine42e142f2010-11-13 05:10:27 -03003708 break;
3709 case SEN_OV7660:
3710 return; /* done by ov519_set_mode/fr() */
3711 case SEN_OV7670:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003712 write_regvals(sd, mode_init_519_ov7670,
3713 ARRAY_SIZE(mode_init_519_ov7670));
Jean-François Moine42e142f2010-11-13 05:10:27 -03003714 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003715 }
3716
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003717 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
3718 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
Hans de Goede80142ef2009-06-14 06:26:49 -03003719 if (sd->sensor == SEN_OV7670 &&
3720 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3721 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
Hans de Goede035d3a32010-01-09 08:14:43 -03003722 else if (sd->sensor == SEN_OV7648 &&
3723 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3724 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
Hans de Goede80142ef2009-06-14 06:26:49 -03003725 else
3726 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003727 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
3728 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
3729 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
3730 reg_w(sd, OV519_R16_DIVIDER, 0x00);
3731 reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003732 reg_w(sd, 0x26, 0x00); /* Undocumented */
3733
3734 /******** Set the framerate ********/
3735 if (frame_rate > 0)
3736 sd->frame_rate = frame_rate;
3737
3738/* FIXME: These are only valid at the max resolution. */
3739 sd->clockdiv = 0;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003740 switch (sd->sensor) {
3741 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003742 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003743 switch (sd->frame_rate) {
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003744 default:
3745/* case 30: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003746 reg_w(sd, 0xa4, 0x0c);
3747 reg_w(sd, 0x23, 0xff);
3748 break;
3749 case 25:
3750 reg_w(sd, 0xa4, 0x0c);
3751 reg_w(sd, 0x23, 0x1f);
3752 break;
3753 case 20:
3754 reg_w(sd, 0xa4, 0x0c);
3755 reg_w(sd, 0x23, 0x1b);
3756 break;
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003757 case 15:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003758 reg_w(sd, 0xa4, 0x04);
3759 reg_w(sd, 0x23, 0xff);
3760 sd->clockdiv = 1;
3761 break;
3762 case 10:
3763 reg_w(sd, 0xa4, 0x04);
3764 reg_w(sd, 0x23, 0x1f);
3765 sd->clockdiv = 1;
3766 break;
3767 case 5:
3768 reg_w(sd, 0xa4, 0x04);
3769 reg_w(sd, 0x23, 0x1b);
3770 sd->clockdiv = 1;
3771 break;
3772 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003773 break;
3774 case SEN_OV8610:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003775 switch (sd->frame_rate) {
3776 default: /* 15 fps */
3777/* case 15: */
3778 reg_w(sd, 0xa4, 0x06);
3779 reg_w(sd, 0x23, 0xff);
3780 break;
3781 case 10:
3782 reg_w(sd, 0xa4, 0x06);
3783 reg_w(sd, 0x23, 0x1f);
3784 break;
3785 case 5:
3786 reg_w(sd, 0xa4, 0x06);
3787 reg_w(sd, 0x23, 0x1b);
3788 break;
3789 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003790 break;
3791 case SEN_OV7670: /* guesses, based on 7640 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003792 PDEBUG(D_STREAM, "Setting framerate to %d fps",
3793 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003794 reg_w(sd, 0xa4, 0x10);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003795 switch (sd->frame_rate) {
3796 case 30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003797 reg_w(sd, 0x23, 0xff);
3798 break;
3799 case 20:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003800 reg_w(sd, 0x23, 0x1b);
3801 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003802 default:
3803/* case 15: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003804 reg_w(sd, 0x23, 0xff);
3805 sd->clockdiv = 1;
3806 break;
3807 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003808 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003809 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003810}
3811
Jean-François Moinef8f20182010-11-12 07:54:02 -03003812static void mode_init_ov_sensor_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003813{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003814 struct gspca_dev *gspca_dev;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003815 int qvga, xstart, xend, ystart, yend;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03003816 u8 v;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003817
3818 gspca_dev = &sd->gspca_dev;
Jean-François Moine87bae742010-11-12 05:31:34 -03003819 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003820
3821 /******** Mode (VGA/QVGA) and sensor specific regs ********/
3822 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003823 case SEN_OV2610:
3824 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3825 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3826 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3827 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3828 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3829 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3830 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Jean-François Moinef8f20182010-11-12 07:54:02 -03003831 return;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003832 case SEN_OV3610:
Hans de Goede635118d2009-10-11 09:49:03 -03003833 if (qvga) {
3834 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003835 ystart = (776 - gspca_dev->height) / 2;
Hans de Goede635118d2009-10-11 09:49:03 -03003836 } else {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003837 xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
Hans de Goede635118d2009-10-11 09:49:03 -03003838 ystart = (1544 - gspca_dev->height) / 2;
3839 }
3840 xend = xstart + gspca_dev->width;
3841 yend = ystart + gspca_dev->height;
3842 /* Writing to the COMH register resets the other windowing regs
3843 to their default values, so we must do this first. */
3844 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3845 i2c_w_mask(sd, 0x32,
3846 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3847 0x3f);
3848 i2c_w_mask(sd, 0x03,
3849 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3850 0x0f);
3851 i2c_w(sd, 0x17, xstart >> 4);
3852 i2c_w(sd, 0x18, xend >> 4);
3853 i2c_w(sd, 0x19, ystart >> 3);
3854 i2c_w(sd, 0x1a, yend >> 3);
Jean-François Moinef8f20182010-11-12 07:54:02 -03003855 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003856 case SEN_OV8610:
3857 /* For OV8610 qvga means qsvga */
3858 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003859 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3860 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3861 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
3862 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003863 break;
3864 case SEN_OV7610:
3865 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Jean-François Moine780e3122010-10-19 04:29:10 -03003866 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003867 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3868 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003869 break;
3870 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003871 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003872 case SEN_OV76BE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003873 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3874 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3875 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3876 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3877 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goedeb282d872009-06-14 19:10:40 -03003878 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003879 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003880 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3881 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3882 if (sd->sensor == SEN_OV76BE)
3883 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003884 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003885 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003886 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003887 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3888 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
Hans de Goede8d0082f2010-01-09 19:45:44 -03003889 /* Setting this undocumented bit in qvga mode removes a very
3890 annoying vertical shaking of the image */
Hans de Goede035d3a32010-01-09 08:14:43 -03003891 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goede8d0082f2010-01-09 19:45:44 -03003892 /* Unknown */
Hans de Goede035d3a32010-01-09 08:14:43 -03003893 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
Hans de Goede8d0082f2010-01-09 19:45:44 -03003894 /* Allow higher automatic gain (to allow higher framerates) */
Hans de Goede035d3a32010-01-09 08:14:43 -03003895 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003896 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003897 break;
3898 case SEN_OV7670:
3899 /* set COM7_FMT_VGA or COM7_FMT_QVGA
3900 * do we need to set anything else?
3901 * HSTART etc are set in set_ov_sensor_window itself */
Jean-François Moine21867802010-11-12 06:12:09 -03003902 i2c_w_mask(sd, OV7670_R12_COM7,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003903 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
3904 OV7670_COM7_FMT_MASK);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003905 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
Jean-François Moine21867802010-11-12 06:12:09 -03003906 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003907 OV7670_COM8_AWB);
3908 if (qvga) { /* QVGA from ov7670.c by
3909 * Jonathan Corbet */
3910 xstart = 164;
3911 xend = 28;
3912 ystart = 14;
3913 yend = 494;
3914 } else { /* VGA */
3915 xstart = 158;
3916 xend = 14;
3917 ystart = 10;
3918 yend = 490;
3919 }
3920 /* OV7670 hardware window registers are split across
3921 * multiple locations */
Jean-François Moine21867802010-11-12 06:12:09 -03003922 i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
3923 i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
3924 v = i2c_r(sd, OV7670_R32_HREF);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003925 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
3926 msleep(10); /* need to sleep between read and write to
3927 * same reg! */
Jean-François Moine21867802010-11-12 06:12:09 -03003928 i2c_w(sd, OV7670_R32_HREF, v);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003929
Jean-François Moine21867802010-11-12 06:12:09 -03003930 i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
3931 i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
3932 v = i2c_r(sd, OV7670_R03_VREF);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003933 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
3934 msleep(10); /* need to sleep between read and write to
3935 * same reg! */
Jean-François Moine21867802010-11-12 06:12:09 -03003936 i2c_w(sd, OV7670_R03_VREF, v);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003937 break;
3938 case SEN_OV6620:
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003939 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3940 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
3941 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
3942 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003943 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003944 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003945 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003946 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003947 break;
3948 default:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003949 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003950 }
3951
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003952 /******** Clock programming ********/
Hans de Goedeae49c402009-06-14 19:15:07 -03003953 i2c_w(sd, 0x11, sd->clockdiv);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003954}
3955
Jean-François Moine42e142f2010-11-13 05:10:27 -03003956/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */
Jean-François Moine62833ac2010-10-02 04:27:02 -03003957static void sethvflip(struct gspca_dev *gspca_dev)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003958{
Jean-François Moine62833ac2010-10-02 04:27:02 -03003959 struct sd *sd = (struct sd *) gspca_dev;
3960
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003961 if (sd->gspca_dev.streaming)
Jean-François Moine5927abc2010-11-12 15:32:29 -03003962 reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */
Jean-François Moine21867802010-11-12 06:12:09 -03003963 i2c_w_mask(sd, OV7670_R1E_MVFP,
Jean-François Moine62833ac2010-10-02 04:27:02 -03003964 OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val
3965 | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003966 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003967 if (sd->gspca_dev.streaming)
Jean-François Moine5927abc2010-11-12 15:32:29 -03003968 reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003969}
3970
Jean-François Moinef8f20182010-11-12 07:54:02 -03003971static void set_ov_sensor_window(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03003972{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003973 struct gspca_dev *gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03003974 int qvga, crop;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003975 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003976
Hans de Goede635118d2009-10-11 09:49:03 -03003977 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
Jean-François Moine42e142f2010-11-13 05:10:27 -03003978 switch (sd->sensor) {
3979 case SEN_OV2610:
3980 case SEN_OV3610:
3981 case SEN_OV7670:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003982 mode_init_ov_sensor_regs(sd);
3983 return;
Jean-François Moine42e142f2010-11-13 05:10:27 -03003984 case SEN_OV7660:
3985 ov519_set_mode(sd);
3986 ov519_set_fr(sd);
3987 return;
Jean-François Moinef8f20182010-11-12 07:54:02 -03003988 }
Jean-François Moine42e142f2010-11-13 05:10:27 -03003989
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003990 gspca_dev = &sd->gspca_dev;
Jean-François Moine87bae742010-11-12 05:31:34 -03003991 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
3992 crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003993
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003994 /* The different sensor ICs handle setting up of window differently.
3995 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
3996 switch (sd->sensor) {
3997 case SEN_OV8610:
3998 hwsbase = 0x1e;
3999 hwebase = 0x1e;
4000 vwsbase = 0x02;
4001 vwebase = 0x02;
4002 break;
4003 case SEN_OV7610:
4004 case SEN_OV76BE:
4005 hwsbase = 0x38;
4006 hwebase = 0x3a;
4007 vwsbase = vwebase = 0x05;
4008 break;
4009 case SEN_OV6620:
4010 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004011 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004012 hwsbase = 0x38;
4013 hwebase = 0x3a;
4014 vwsbase = 0x05;
4015 vwebase = 0x06;
Hans de Goede7d971372009-06-14 05:28:17 -03004016 if (sd->sensor == SEN_OV66308AF && qvga)
Hans de Goede49809d62009-06-07 12:10:39 -03004017 /* HDG: this fixes U and V getting swapped */
Hans de Goede7d971372009-06-14 05:28:17 -03004018 hwsbase++;
Hans de Goede124cc9c2009-06-14 05:48:00 -03004019 if (crop) {
4020 hwsbase += 8;
4021 hwebase += 8;
4022 vwsbase += 11;
4023 vwebase += 11;
4024 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004025 break;
4026 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004027 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004028 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
4029 hwebase = 0x2f;
4030 vwsbase = vwebase = 0x05;
4031 break;
4032 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004033 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004034 hwsbase = 0x1a;
4035 hwebase = 0x1a;
4036 vwsbase = vwebase = 0x03;
4037 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004038 default:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004039 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004040 }
4041
4042 switch (sd->sensor) {
4043 case SEN_OV6620:
4044 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004045 case SEN_OV66308AF:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004046 if (qvga) { /* QCIF */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004047 hwscale = 0;
4048 vwscale = 0;
4049 } else { /* CIF */
4050 hwscale = 1;
4051 vwscale = 1; /* The datasheet says 0;
4052 * it's wrong */
4053 }
4054 break;
4055 case SEN_OV8610:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004056 if (qvga) { /* QSVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004057 hwscale = 1;
4058 vwscale = 1;
4059 } else { /* SVGA */
4060 hwscale = 2;
4061 vwscale = 2;
4062 }
4063 break;
4064 default: /* SEN_OV7xx0 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004065 if (qvga) { /* QVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004066 hwscale = 1;
4067 vwscale = 0;
4068 } else { /* VGA */
4069 hwscale = 2;
4070 vwscale = 1;
4071 }
4072 }
4073
Jean-François Moinef8f20182010-11-12 07:54:02 -03004074 mode_init_ov_sensor_regs(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004075
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004076 i2c_w(sd, 0x17, hwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03004077 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004078 i2c_w(sd, 0x19, vwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03004079 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004080}
4081
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004082/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03004083static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004084{
4085 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004086
Hans de Goedea511ba92009-10-16 07:13:07 -03004087 /* Default for most bridges, allow bridge_mode_init_regs to override */
4088 sd->sensor_width = sd->gspca_dev.width;
4089 sd->sensor_height = sd->gspca_dev.height;
4090
Hans de Goede49809d62009-06-07 12:10:39 -03004091 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03004092 case BRIDGE_OV511:
4093 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004094 ov511_mode_init_regs(sd);
Hans de Goede1876bb92009-06-14 06:45:50 -03004095 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004096 case BRIDGE_OV518:
4097 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004098 ov518_mode_init_regs(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03004099 break;
4100 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004101 ov519_mode_init_regs(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03004102 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004103 /* case BRIDGE_OVFX2: nothing to do */
Hans de Goedea511ba92009-10-16 07:13:07 -03004104 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004105 w9968cf_mode_init_regs(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03004106 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004107 }
Hans de Goede49809d62009-06-07 12:10:39 -03004108
Jean-François Moinef8f20182010-11-12 07:54:02 -03004109 set_ov_sensor_window(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004110
Jean-François Moinee2817022010-11-12 13:59:48 -03004111 if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST)))
4112 setcontrast(gspca_dev);
4113 if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
4114 setbrightness(gspca_dev);
4115 if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
4116 setcolors(gspca_dev);
4117 if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
4118 sethvflip(gspca_dev);
4119 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
4120 setautobright(gspca_dev);
4121 if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
4122 setfreq_i(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03004123
Hans de Goede417a4d22010-02-19 07:37:08 -03004124 /* Force clear snapshot state in case the snapshot button was
4125 pressed while we weren't streaming */
4126 sd->snapshot_needs_reset = 1;
4127 sd_reset_snapshot(gspca_dev);
Hans de Goede417a4d22010-02-19 07:37:08 -03004128
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004129 sd->first_frame = 3;
4130
Jean-François Moinef8f20182010-11-12 07:54:02 -03004131 ov51x_restart(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004132 ov51x_led_control(sd, 1);
Jean-François Moinef8f20182010-11-12 07:54:02 -03004133 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004134}
4135
4136static void sd_stopN(struct gspca_dev *gspca_dev)
4137{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004138 struct sd *sd = (struct sd *) gspca_dev;
4139
4140 ov51x_stop(sd);
4141 ov51x_led_control(sd, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004142}
4143
Hans de Goede79b35902009-10-19 06:08:01 -03004144static void sd_stop0(struct gspca_dev *gspca_dev)
4145{
4146 struct sd *sd = (struct sd *) gspca_dev;
4147
Jean-François Moined65174c2010-11-11 06:20:42 -03004148 if (!sd->gspca_dev.present)
4149 return;
Hans de Goede79b35902009-10-19 06:08:01 -03004150 if (sd->bridge == BRIDGE_W9968CF)
4151 w9968cf_stop0(sd);
Hans de Goede614d0692010-10-27 07:42:28 -03004152
Jean-François Moine14653e62010-11-11 06:17:01 -03004153#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede614d0692010-10-27 07:42:28 -03004154 /* If the last button state is pressed, release it now! */
4155 if (sd->snapshot_pressed) {
4156 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
4157 input_sync(gspca_dev->input_dev);
4158 sd->snapshot_pressed = 0;
4159 }
4160#endif
Jean-François Moineb4e96ea2010-11-12 16:13:17 -03004161 if (sd->bridge == BRIDGE_OV519)
4162 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
Hans de Goede79b35902009-10-19 06:08:01 -03004163}
4164
Hans de Goede92e232a2010-02-20 04:30:45 -03004165static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
4166{
4167 struct sd *sd = (struct sd *) gspca_dev;
4168
4169 if (sd->snapshot_pressed != state) {
Jean-François Moine28566432010-10-01 07:33:26 -03004170#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede92e232a2010-02-20 04:30:45 -03004171 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
4172 input_sync(gspca_dev->input_dev);
4173#endif
4174 if (state)
4175 sd->snapshot_needs_reset = 1;
4176
4177 sd->snapshot_pressed = state;
4178 } else {
Hans de Goede88e8d202010-02-20 04:45:49 -03004179 /* On the ov511 / ov519 we need to reset the button state
4180 multiple times, as resetting does not work as long as the
4181 button stays pressed */
4182 switch (sd->bridge) {
4183 case BRIDGE_OV511:
4184 case BRIDGE_OV511PLUS:
4185 case BRIDGE_OV519:
4186 if (state)
4187 sd->snapshot_needs_reset = 1;
4188 break;
4189 }
Hans de Goede92e232a2010-02-20 04:30:45 -03004190 }
4191}
4192
Hans de Goede1876bb92009-06-14 06:45:50 -03004193static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004194 u8 *in, /* isoc packet */
4195 int len) /* iso packet length */
Hans de Goede1876bb92009-06-14 06:45:50 -03004196{
4197 struct sd *sd = (struct sd *) gspca_dev;
4198
4199 /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
4200 * byte non-zero. The EOF packet has image width/height in the
4201 * 10th and 11th bytes. The 9th byte is given as follows:
4202 *
4203 * bit 7: EOF
4204 * 6: compression enabled
4205 * 5: 422/420/400 modes
4206 * 4: 422/420/400 modes
4207 * 3: 1
4208 * 2: snapshot button on
4209 * 1: snapshot frame
4210 * 0: even/odd field
4211 */
4212 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
4213 (in[8] & 0x08)) {
Hans de Goede88e8d202010-02-20 04:45:49 -03004214 ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
Hans de Goede1876bb92009-06-14 06:45:50 -03004215 if (in[8] & 0x80) {
4216 /* Frame end */
4217 if ((in[9] + 1) * 8 != gspca_dev->width ||
4218 (in[10] + 1) * 8 != gspca_dev->height) {
4219 PDEBUG(D_ERR, "Invalid frame size, got: %dx%d,"
4220 " requested: %dx%d\n",
4221 (in[9] + 1) * 8, (in[10] + 1) * 8,
4222 gspca_dev->width, gspca_dev->height);
4223 gspca_dev->last_packet_type = DISCARD_PACKET;
4224 return;
4225 }
4226 /* Add 11 byte footer to frame, might be usefull */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004227 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
Hans de Goede1876bb92009-06-14 06:45:50 -03004228 return;
4229 } else {
4230 /* Frame start */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004231 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
Hans de Goede1876bb92009-06-14 06:45:50 -03004232 sd->packet_nr = 0;
4233 }
4234 }
4235
4236 /* Ignore the packet number */
4237 len--;
4238
4239 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004240 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
Hans de Goede1876bb92009-06-14 06:45:50 -03004241}
4242
Hans de Goede49809d62009-06-07 12:10:39 -03004243static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004244 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004245 int len) /* iso packet length */
4246{
Hans de Goede92918a52009-06-14 06:21:35 -03004247 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03004248
4249 /* A false positive here is likely, until OVT gives me
4250 * the definitive SOF/EOF format */
4251 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
Hans de Goede92e232a2010-02-20 04:30:45 -03004252 ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004253 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4254 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goede92918a52009-06-14 06:21:35 -03004255 sd->packet_nr = 0;
4256 }
4257
4258 if (gspca_dev->last_packet_type == DISCARD_PACKET)
4259 return;
4260
4261 /* Does this device use packet numbers ? */
4262 if (len & 7) {
4263 len--;
4264 if (sd->packet_nr == data[len])
4265 sd->packet_nr++;
4266 /* The last few packets of the frame (which are all 0's
4267 except that they may contain part of the footer), are
4268 numbered 0 */
4269 else if (sd->packet_nr == 0 || data[len]) {
4270 PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)",
4271 (int)data[len], (int)sd->packet_nr);
4272 gspca_dev->last_packet_type = DISCARD_PACKET;
4273 return;
4274 }
Hans de Goede49809d62009-06-07 12:10:39 -03004275 }
4276
4277 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004278 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004279}
4280
4281static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004282 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004283 int len) /* iso packet length */
4284{
4285 /* Header of ov519 is 16 bytes:
4286 * Byte Value Description
4287 * 0 0xff magic
4288 * 1 0xff magic
4289 * 2 0xff magic
4290 * 3 0xXX 0x50 = SOF, 0x51 = EOF
4291 * 9 0xXX 0x01 initial frame without data,
4292 * 0x00 standard frame with image
4293 * 14 Lo in EOF: length of image data / 8
4294 * 15 Hi
4295 */
4296
4297 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4298 switch (data[3]) {
4299 case 0x50: /* start of frame */
Hans de Goede417a4d22010-02-19 07:37:08 -03004300 /* Don't check the button state here, as the state
4301 usually (always ?) changes at EOF and checking it
4302 here leads to unnecessary snapshot state resets. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004303#define HDRSZ 16
4304 data += HDRSZ;
4305 len -= HDRSZ;
4306#undef HDRSZ
4307 if (data[0] == 0xff || data[1] == 0xd8)
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004308 gspca_frame_add(gspca_dev, FIRST_PACKET,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004309 data, len);
4310 else
4311 gspca_dev->last_packet_type = DISCARD_PACKET;
4312 return;
4313 case 0x51: /* end of frame */
Hans de Goede92e232a2010-02-20 04:30:45 -03004314 ov51x_handle_button(gspca_dev, data[11] & 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004315 if (data[9] != 0)
4316 gspca_dev->last_packet_type = DISCARD_PACKET;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004317 gspca_frame_add(gspca_dev, LAST_PACKET,
4318 NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004319 return;
4320 }
4321 }
4322
4323 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004324 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004325}
4326
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004327static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004328 u8 *data, /* isoc packet */
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004329 int len) /* iso packet length */
4330{
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004331 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004332
4333 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4334
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004335 /* A short read signals EOF */
4336 if (len < OVFX2_BULK_SIZE) {
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004337 /* If the frame is short, and it is one of the first ones
4338 the sensor and bridge are still syncing, so drop it. */
4339 if (sd->first_frame) {
4340 sd->first_frame--;
Jean-François Moineb192ca92010-06-27 03:08:19 -03004341 if (gspca_dev->image_len <
4342 sd->gspca_dev.width * sd->gspca_dev.height)
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004343 gspca_dev->last_packet_type = DISCARD_PACKET;
4344 }
4345 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004346 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004347 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004348}
4349
Hans de Goede49809d62009-06-07 12:10:39 -03004350static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004351 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004352 int len) /* iso packet length */
4353{
4354 struct sd *sd = (struct sd *) gspca_dev;
4355
4356 switch (sd->bridge) {
4357 case BRIDGE_OV511:
4358 case BRIDGE_OV511PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004359 ov511_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004360 break;
4361 case BRIDGE_OV518:
4362 case BRIDGE_OV518PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004363 ov518_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004364 break;
4365 case BRIDGE_OV519:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004366 ov519_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004367 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004368 case BRIDGE_OVFX2:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004369 ovfx2_pkt_scan(gspca_dev, data, len);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004370 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03004371 case BRIDGE_W9968CF:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004372 w9968cf_pkt_scan(gspca_dev, data, len);
Hans de Goedea511ba92009-10-16 07:13:07 -03004373 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004374 }
4375}
4376
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004377/* -- management routines -- */
4378
4379static void setbrightness(struct gspca_dev *gspca_dev)
4380{
4381 struct sd *sd = (struct sd *) gspca_dev;
4382 int val;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004383 static const struct ov_i2c_regvals brit_7660[][7] = {
4384 {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
4385 {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
4386 {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
4387 {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
4388 {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
4389 {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
4390 {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
4391 {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
4392 {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
4393 {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
4394 {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
4395 {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
4396 {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
4397 {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
4398 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004399
Jean-François Moine62833ac2010-10-02 04:27:02 -03004400 val = sd->ctrls[BRIGHTNESS].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004401 switch (sd->sensor) {
4402 case SEN_OV8610:
4403 case SEN_OV7610:
4404 case SEN_OV76BE:
4405 case SEN_OV6620:
4406 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004407 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004408 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004409 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004410 i2c_w(sd, OV7610_REG_BRT, val);
4411 break;
4412 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004413 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004414 /* 7620 doesn't like manual changes when in auto mode */
Jean-François Moine62833ac2010-10-02 04:27:02 -03004415 if (!sd->ctrls[AUTOBRIGHT].val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004416 i2c_w(sd, OV7610_REG_BRT, val);
4417 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004418 case SEN_OV7660:
4419 write_i2c_regvals(sd, brit_7660[val],
4420 ARRAY_SIZE(brit_7660[0]));
4421 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004422 case SEN_OV7670:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004423/*win trace
Jean-François Moine21867802010-11-12 06:12:09 -03004424 * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
4425 i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004426 break;
4427 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004428}
4429
4430static void setcontrast(struct gspca_dev *gspca_dev)
4431{
4432 struct sd *sd = (struct sd *) gspca_dev;
4433 int val;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004434 static const struct ov_i2c_regvals contrast_7660[][31] = {
4435 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
4436 {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
4437 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
4438 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
4439 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
4440 {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
4441 {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
4442 {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
4443 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
4444 {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
4445 {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
4446 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
4447 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
4448 {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
4449 {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
4450 {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
4451 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
4452 {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
4453 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
4454 {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
4455 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
4456 {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
4457 {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
4458 {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
4459 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
4460 {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
4461 {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
4462 {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
4463 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
4464 {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
4465 {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
4466 {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
4467 {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
4468 {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
4469 {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
4470 {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
4471 {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
4472 {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
4473 {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
4474 {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
4475 {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
4476 {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
4477 {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
4478 {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
4479 {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
4480 {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
4481 {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
4482 {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
4483 {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
4484 {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
4485 {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
4486 {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
4487 {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
4488 {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
4489 {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
4490 {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
4491 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004492
Jean-François Moine62833ac2010-10-02 04:27:02 -03004493 val = sd->ctrls[CONTRAST].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004494 switch (sd->sensor) {
4495 case SEN_OV7610:
4496 case SEN_OV6620:
4497 i2c_w(sd, OV7610_REG_CNT, val);
4498 break;
4499 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004500 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004501 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
Hans de Goede49809d62009-06-07 12:10:39 -03004502 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004503 case SEN_OV8610: {
Jean-François Moine9d1593a2010-11-11 08:04:06 -03004504 static const u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004505 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
4506 };
4507
4508 /* Use Y gamma control instead. Bit 0 enables it. */
4509 i2c_w(sd, 0x64, ctab[val >> 5]);
4510 break;
4511 }
Hans de Goede859cc472010-01-07 15:42:35 -03004512 case SEN_OV7620:
4513 case SEN_OV7620AE: {
Jean-François Moine9d1593a2010-11-11 08:04:06 -03004514 static const u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004515 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4516 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
4517 };
4518
4519 /* Use Y gamma control instead. Bit 0 enables it. */
4520 i2c_w(sd, 0x64, ctab[val >> 4]);
4521 break;
4522 }
Jean-François Moine42e142f2010-11-13 05:10:27 -03004523 case SEN_OV7660:
4524 write_i2c_regvals(sd, contrast_7660[val],
4525 ARRAY_SIZE(contrast_7660[0]));
4526 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004527 case SEN_OV7670:
4528 /* check that this isn't just the same as ov7610 */
Jean-François Moine21867802010-11-12 06:12:09 -03004529 i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004530 break;
4531 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004532}
4533
4534static void setcolors(struct gspca_dev *gspca_dev)
4535{
4536 struct sd *sd = (struct sd *) gspca_dev;
4537 int val;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004538 static const struct ov_i2c_regvals colors_7660[][6] = {
4539 {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
4540 {0x53, 0x19}, {0x54, 0x23}},
4541 {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
4542 {0x53, 0x2c}, {0x54, 0x3e}},
4543 {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
4544 {0x53, 0x40}, {0x54, 0x59}},
4545 {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
4546 {0x53, 0x53}, {0x54, 0x73}},
4547 {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
4548 {0x53, 0x66}, {0x54, 0x8e}},
4549 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004550
Jean-François Moine62833ac2010-10-02 04:27:02 -03004551 val = sd->ctrls[COLORS].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004552 switch (sd->sensor) {
4553 case SEN_OV8610:
4554 case SEN_OV7610:
4555 case SEN_OV76BE:
4556 case SEN_OV6620:
4557 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004558 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004559 i2c_w(sd, OV7610_REG_SAT, val);
4560 break;
4561 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004562 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004563 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
4564/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
4565 if (rc < 0)
4566 goto out; */
4567 i2c_w(sd, OV7610_REG_SAT, val);
4568 break;
4569 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004570 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004571 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4572 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004573 case SEN_OV7660:
4574 write_i2c_regvals(sd, colors_7660[val],
4575 ARRAY_SIZE(colors_7660[0]));
4576 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004577 case SEN_OV7670:
4578 /* supported later once I work out how to do it
4579 * transparently fail now! */
4580 /* set REG_COM13 values for UV sat auto mode */
4581 break;
4582 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004583}
4584
Jean-François Moine62833ac2010-10-02 04:27:02 -03004585static void setautobright(struct gspca_dev *gspca_dev)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004586{
Jean-François Moine62833ac2010-10-02 04:27:02 -03004587 struct sd *sd = (struct sd *) gspca_dev;
4588
Jean-François Moine62833ac2010-10-02 04:27:02 -03004589 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004590}
4591
Jean-François Moine62833ac2010-10-02 04:27:02 -03004592static void setfreq_i(struct sd *sd)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004593{
Jean-François Moine42e142f2010-11-13 05:10:27 -03004594 if (sd->sensor == SEN_OV7660
4595 || sd->sensor == SEN_OV7670) {
Jean-François Moine62833ac2010-10-02 04:27:02 -03004596 switch (sd->ctrls[FREQ].val) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004597 case 0: /* Banding filter disabled */
Jean-François Moine21867802010-11-12 06:12:09 -03004598 i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004599 break;
4600 case 1: /* 50 hz */
Jean-François Moine21867802010-11-12 06:12:09 -03004601 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004602 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004603 i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004604 break;
4605 case 2: /* 60 hz */
Jean-François Moine21867802010-11-12 06:12:09 -03004606 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004607 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004608 i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004609 break;
Jean-François Moine21867802010-11-12 06:12:09 -03004610 case 3: /* Auto hz - ov7670 only */
4611 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004612 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004613 i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004614 0x18);
4615 break;
4616 }
4617 } else {
Jean-François Moine62833ac2010-10-02 04:27:02 -03004618 switch (sd->ctrls[FREQ].val) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004619 case 0: /* Banding filter disabled */
4620 i2c_w_mask(sd, 0x2d, 0x00, 0x04);
4621 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4622 break;
4623 case 1: /* 50 hz (filter on and framerate adj) */
4624 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4625 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4626 /* 20 fps -> 16.667 fps */
4627 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004628 sd->sensor == SEN_OV6630 ||
4629 sd->sensor == SEN_OV66308AF)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004630 i2c_w(sd, 0x2b, 0x5e);
4631 else
4632 i2c_w(sd, 0x2b, 0xac);
4633 break;
4634 case 2: /* 60 hz (filter on, ...) */
4635 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4636 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004637 sd->sensor == SEN_OV6630 ||
4638 sd->sensor == SEN_OV66308AF) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004639 /* 20 fps -> 15 fps */
4640 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4641 i2c_w(sd, 0x2b, 0xa8);
4642 } else {
4643 /* no framerate adj. */
4644 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4645 }
4646 break;
4647 }
4648 }
4649}
Jean-François Moine62833ac2010-10-02 04:27:02 -03004650static void setfreq(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004651{
4652 struct sd *sd = (struct sd *) gspca_dev;
4653
Jean-François Moine62833ac2010-10-02 04:27:02 -03004654 setfreq_i(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004655
Jean-François Moine62833ac2010-10-02 04:27:02 -03004656 /* Ugly but necessary */
4657 if (sd->bridge == BRIDGE_W9968CF)
4658 w9968cf_set_crop_window(sd);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004659}
4660
4661static int sd_querymenu(struct gspca_dev *gspca_dev,
4662 struct v4l2_querymenu *menu)
4663{
4664 struct sd *sd = (struct sd *) gspca_dev;
4665
4666 switch (menu->id) {
4667 case V4L2_CID_POWER_LINE_FREQUENCY:
4668 switch (menu->index) {
4669 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
4670 strcpy((char *) menu->name, "NoFliker");
4671 return 0;
4672 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
4673 strcpy((char *) menu->name, "50 Hz");
4674 return 0;
4675 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
4676 strcpy((char *) menu->name, "60 Hz");
4677 return 0;
4678 case 3:
4679 if (sd->sensor != SEN_OV7670)
4680 return -EINVAL;
4681
4682 strcpy((char *) menu->name, "Automatic");
4683 return 0;
4684 }
4685 break;
4686 }
4687 return -EINVAL;
4688}
4689
Hans de Goede79b35902009-10-19 06:08:01 -03004690static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4691 struct v4l2_jpegcompression *jcomp)
4692{
4693 struct sd *sd = (struct sd *) gspca_dev;
4694
4695 if (sd->bridge != BRIDGE_W9968CF)
4696 return -EINVAL;
4697
4698 memset(jcomp, 0, sizeof *jcomp);
4699 jcomp->quality = sd->quality;
4700 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4701 V4L2_JPEG_MARKER_DRI;
4702 return 0;
4703}
4704
4705static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4706 struct v4l2_jpegcompression *jcomp)
4707{
4708 struct sd *sd = (struct sd *) gspca_dev;
4709
4710 if (sd->bridge != BRIDGE_W9968CF)
4711 return -EINVAL;
4712
4713 if (gspca_dev->streaming)
4714 return -EBUSY;
4715
4716 if (jcomp->quality < QUALITY_MIN)
4717 sd->quality = QUALITY_MIN;
4718 else if (jcomp->quality > QUALITY_MAX)
4719 sd->quality = QUALITY_MAX;
4720 else
4721 sd->quality = jcomp->quality;
4722
4723 /* Return resulting jcomp params to app */
4724 sd_get_jcomp(gspca_dev, jcomp);
4725
4726 return 0;
4727}
4728
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004729/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004730static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004731 .name = MODULE_NAME,
4732 .ctrls = sd_ctrls,
4733 .nctrls = ARRAY_SIZE(sd_ctrls),
4734 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03004735 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004736 .start = sd_start,
4737 .stopN = sd_stopN,
Hans de Goede79b35902009-10-19 06:08:01 -03004738 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004739 .pkt_scan = sd_pkt_scan,
Hans de Goede417a4d22010-02-19 07:37:08 -03004740 .dq_callback = sd_reset_snapshot,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004741 .querymenu = sd_querymenu,
Hans de Goede79b35902009-10-19 06:08:01 -03004742 .get_jcomp = sd_get_jcomp,
4743 .set_jcomp = sd_set_jcomp,
Jean-François Moine28566432010-10-01 07:33:26 -03004744#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede417a4d22010-02-19 07:37:08 -03004745 .other_input = 1,
4746#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004747};
4748
4749/* -- module initialisation -- */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004750static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03004751 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
Hans de Goede49809d62009-06-07 12:10:39 -03004752 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
4753 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
4754 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
4755 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004756 {USB_DEVICE(0x041e, 0x4064),
Jean-François Moine87bae742010-11-12 05:31:34 -03004757 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Rafal Milecki518c8df2009-10-02 03:54:44 -03004758 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004759 {USB_DEVICE(0x041e, 0x4068),
Jean-François Moine87bae742010-11-12 05:31:34 -03004760 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede49809d62009-06-07 12:10:39 -03004761 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
4762 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
Hans de Goede98184f72010-01-07 12:06:00 -03004763 {USB_DEVICE(0x054c, 0x0155),
Jean-François Moine87bae742010-11-12 05:31:34 -03004764 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede1876bb92009-06-14 06:45:50 -03004765 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
Hans de Goede49809d62009-06-07 12:10:39 -03004766 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4767 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
4768 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004769 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
Hans de Goede49809d62009-06-07 12:10:39 -03004770 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
4771 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
Hans de Goede1876bb92009-06-14 06:45:50 -03004772 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
Hans de Goede49809d62009-06-07 12:10:39 -03004773 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
Hans de Goede1876bb92009-06-14 06:45:50 -03004774 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004775 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4776 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
Hans de Goedea511ba92009-10-16 07:13:07 -03004777 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
Jean-François Moine87bae742010-11-12 05:31:34 -03004778 {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004779 {}
4780};
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004781
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004782MODULE_DEVICE_TABLE(usb, device_table);
4783
4784/* -- device connect -- */
4785static int sd_probe(struct usb_interface *intf,
4786 const struct usb_device_id *id)
4787{
4788 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
4789 THIS_MODULE);
4790}
4791
4792static struct usb_driver sd_driver = {
4793 .name = MODULE_NAME,
4794 .id_table = device_table,
4795 .probe = sd_probe,
4796 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03004797#ifdef CONFIG_PM
4798 .suspend = gspca_suspend,
4799 .resume = gspca_resume,
4800#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004801};
4802
4803/* -- module insert / remove -- */
4804static int __init sd_mod_init(void)
4805{
Jean-François Moine54826432010-09-13 04:53:03 -03004806 return usb_register(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004807}
4808static void __exit sd_mod_exit(void)
4809{
4810 usb_deregister(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004811}
4812
4813module_init(sd_mod_init);
4814module_exit(sd_mod_exit);
4815
4816module_param(frame_rate, int, 0644);
4817MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");