blob: cb42a5182d1741798825c34382fdc9bfd4662bf0 [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/**
2 * OV519 driver
3 *
Jean-François Moine58c92d32011-03-13 16:36:49 -03004 * Copyright (C) 2008-2011 Jean-François Moine <moinejf@free.fr>
Hans de Goedeb46aaa02009-10-12 10:07:57 -03005 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03006 *
Romain Beauxis2961e872008-12-05 06:25:26 -03007 * This module is adapted from the ov51x-jpeg package, which itself
8 * was adapted from the ov511 driver.
9 *
10 * Original copyright for the ov511 driver is:
11 *
Hans de Goedeb46aaa02009-10-12 10:07:57 -030012 * Copyright (c) 1999-2006 Mark W. McClelland
Romain Beauxis2961e872008-12-05 06:25:26 -030013 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
Hans de Goedeb46aaa02009-10-12 10:07:57 -030014 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
15 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
16 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
17 * Changes by Claudio Matsuoka <claudio@conectiva.com>
Romain Beauxis2961e872008-12-05 06:25:26 -030018 *
19 * ov51x-jpeg original copyright is:
20 *
21 * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org>
22 * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 *
38 */
39#define MODULE_NAME "ov519"
40
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,
Jean-François Moine58c92d32011-03-13 16:36:49 -030064 EXPOSURE,
Jean-François Moine62833ac2010-10-02 04:27:02 -030065 COLORS,
66 HFLIP,
67 VFLIP,
68 AUTOBRIGHT,
Jean-François Moine58c92d32011-03-13 16:36:49 -030069 AUTOGAIN,
Jean-François Moine62833ac2010-10-02 04:27:02 -030070 FREQ,
71 NCTRL /* number of controls */
72};
73
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030074/* ov519 device descriptor */
75struct sd {
76 struct gspca_dev gspca_dev; /* !! must be the first item */
77
Jean-François Moine62833ac2010-10-02 04:27:02 -030078 struct gspca_ctrl ctrls[NCTRL];
79
Jean-François Moine9d1593a2010-11-11 08:04:06 -030080 u8 packet_nr;
Hans de Goede92918a52009-06-14 06:21:35 -030081
Hans de Goede49809d62009-06-07 12:10:39 -030082 char bridge;
83#define BRIDGE_OV511 0
84#define BRIDGE_OV511PLUS 1
85#define BRIDGE_OV518 2
86#define BRIDGE_OV518PLUS 3
Jean-François Moine42e142f2010-11-13 05:10:27 -030087#define BRIDGE_OV519 4 /* = ov530 */
Hans de Goede635118d2009-10-11 09:49:03 -030088#define BRIDGE_OVFX2 5
Hans de Goedea511ba92009-10-16 07:13:07 -030089#define BRIDGE_W9968CF 6
Hans de Goede9e4d8252009-06-14 06:25:06 -030090#define BRIDGE_MASK 7
91
92 char invert_led;
93#define BRIDGE_INVERT_LED 8
Hans de Goede49809d62009-06-07 12:10:39 -030094
Hans de Goede417a4d22010-02-19 07:37:08 -030095 char snapshot_pressed;
96 char snapshot_needs_reset;
97
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030098 /* Determined by sensor type */
Jean-François Moine9d1593a2010-11-11 08:04:06 -030099 u8 sif;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300100
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300101 u8 quality;
Hans de Goede79b35902009-10-19 06:08:01 -0300102#define QUALITY_MIN 50
103#define QUALITY_MAX 70
104#define QUALITY_DEF 50
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300105
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300106 u8 stopped; /* Streaming is temporarily paused */
107 u8 first_frame;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300108
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300109 u8 frame_rate; /* current Framerate */
110 u8 clockdiv; /* clockdiv override */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300111
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300112 s8 sensor; /* Type of image sensor chip (SEN_*) */
Hans de Goedea511ba92009-10-16 07:13:07 -0300113
114 u8 sensor_addr;
Jean-François Moined6fa6632010-11-11 08:05:50 -0300115 u16 sensor_width;
116 u16 sensor_height;
117 s16 sensor_reg_cache[256];
Hans de Goede79b35902009-10-19 06:08:01 -0300118
Jean-François Moine9a731a32010-06-04 05:26:42 -0300119 u8 jpeg_hdr[JPEG_HDR_SZ];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300120};
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300121enum sensors {
122 SEN_OV2610,
Jean-François Moine07c6c9c2011-02-10 13:32:22 -0300123 SEN_OV2610AE,
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300124 SEN_OV3610,
125 SEN_OV6620,
126 SEN_OV6630,
127 SEN_OV66308AF,
128 SEN_OV7610,
129 SEN_OV7620,
130 SEN_OV7620AE,
131 SEN_OV7640,
132 SEN_OV7648,
Jean-François Moine42e142f2010-11-13 05:10:27 -0300133 SEN_OV7660,
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300134 SEN_OV7670,
135 SEN_OV76BE,
136 SEN_OV8610,
Jean-François Moine798ae152011-05-23 05:38:10 -0300137 SEN_OV9600,
Jean-François Moine7bbe6b82010-11-11 08:27:24 -0300138};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300139
Hans de Goedea511ba92009-10-16 07:13:07 -0300140/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
141 the ov sensors which is already present here. When we have the time we
142 really should move the sensor drivers to v4l2 sub drivers. */
143#include "w996Xcf.c"
144
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300145/* V4L2 controls supported by the driver */
Hans de Goede49809d62009-06-07 12:10:39 -0300146static void setbrightness(struct gspca_dev *gspca_dev);
147static void setcontrast(struct gspca_dev *gspca_dev);
Jean-François Moine58c92d32011-03-13 16:36:49 -0300148static void setexposure(struct gspca_dev *gspca_dev);
Hans de Goede49809d62009-06-07 12:10:39 -0300149static void setcolors(struct gspca_dev *gspca_dev);
Jean-François Moine62833ac2010-10-02 04:27:02 -0300150static void sethvflip(struct gspca_dev *gspca_dev);
151static void setautobright(struct gspca_dev *gspca_dev);
Jean-François Moine58c92d32011-03-13 16:36:49 -0300152static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
Jean-François Moine62833ac2010-10-02 04:27:02 -0300153static void setfreq(struct gspca_dev *gspca_dev);
154static void setfreq_i(struct sd *sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300155
Hans de Goede02ab18b2009-06-14 04:32:04 -0300156static const struct ctrl sd_ctrls[] = {
Jean-François Moine62833ac2010-10-02 04:27:02 -0300157[BRIGHTNESS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300158 {
159 .id = V4L2_CID_BRIGHTNESS,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "Brightness",
162 .minimum = 0,
163 .maximum = 255,
164 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300165 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300166 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300167 .set_control = setbrightness,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300168 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300169[CONTRAST] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300170 {
171 .id = V4L2_CID_CONTRAST,
172 .type = V4L2_CTRL_TYPE_INTEGER,
173 .name = "Contrast",
174 .minimum = 0,
175 .maximum = 255,
176 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300177 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300178 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300179 .set_control = setcontrast,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300180 },
Jean-François Moine58c92d32011-03-13 16:36:49 -0300181[EXPOSURE] = {
182 {
183 .id = V4L2_CID_EXPOSURE,
184 .type = V4L2_CTRL_TYPE_INTEGER,
185 .name = "Exposure",
186 .minimum = 0,
187 .maximum = 255,
188 .step = 1,
189 .default_value = 127,
190 },
191 .set_control = setexposure,
192 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300193[COLORS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300194 {
195 .id = V4L2_CID_SATURATION,
196 .type = V4L2_CTRL_TYPE_INTEGER,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300197 .name = "Color",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300198 .minimum = 0,
199 .maximum = 255,
200 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300201 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300202 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300203 .set_control = setcolors,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300204 },
Jean-François Moine42e142f2010-11-13 05:10:27 -0300205/* The flip controls work for sensors ov7660 and ov7670 only */
Jean-François Moine62833ac2010-10-02 04:27:02 -0300206[HFLIP] = {
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300207 {
208 .id = V4L2_CID_HFLIP,
209 .type = V4L2_CTRL_TYPE_BOOLEAN,
210 .name = "Mirror",
211 .minimum = 0,
212 .maximum = 1,
213 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300214 .default_value = 0,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300215 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300216 .set_control = sethvflip,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300217 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300218[VFLIP] = {
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300219 {
220 .id = V4L2_CID_VFLIP,
221 .type = V4L2_CTRL_TYPE_BOOLEAN,
222 .name = "Vflip",
223 .minimum = 0,
224 .maximum = 1,
225 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300226 .default_value = 0,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300227 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300228 .set_control = sethvflip,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300229 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300230[AUTOBRIGHT] = {
Hans de Goede02ab18b2009-06-14 04:32:04 -0300231 {
232 .id = V4L2_CID_AUTOBRIGHTNESS,
233 .type = V4L2_CTRL_TYPE_BOOLEAN,
234 .name = "Auto Brightness",
235 .minimum = 0,
236 .maximum = 1,
237 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300238 .default_value = 1,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300239 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300240 .set_control = setautobright,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300241 },
Jean-François Moine58c92d32011-03-13 16:36:49 -0300242[AUTOGAIN] = {
243 {
244 .id = V4L2_CID_AUTOGAIN,
245 .type = V4L2_CTRL_TYPE_BOOLEAN,
246 .name = "Auto Gain",
247 .minimum = 0,
248 .maximum = 1,
249 .step = 1,
250 .default_value = 1,
251 .flags = V4L2_CTRL_FLAG_UPDATE
252 },
253 .set = sd_setautogain,
254 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300255[FREQ] = {
Hans de Goede02ab18b2009-06-14 04:32:04 -0300256 {
257 .id = V4L2_CID_POWER_LINE_FREQUENCY,
258 .type = V4L2_CTRL_TYPE_MENU,
259 .name = "Light frequency filter",
260 .minimum = 0,
Jean-François Moine87bae742010-11-12 05:31:34 -0300261 .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */
Hans de Goede02ab18b2009-06-14 04:32:04 -0300262 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300263 .default_value = 0,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300264 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300265 .set_control = setfreq,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300266 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300267};
268
Jean-François Moine83db7682010-11-12 07:14:08 -0300269/* table of the disabled controls */
270static const unsigned ctrl_dis[] = {
Jean-François Moine58c92d32011-03-13 16:36:49 -0300271[SEN_OV2610] = ((1 << NCTRL) - 1) /* no control */
272 ^ ((1 << EXPOSURE) /* but exposure */
273 | (1 << AUTOGAIN)), /* and autogain */
Jean-François Moine83db7682010-11-12 07:14:08 -0300274
Jean-François Moine58c92d32011-03-13 16:36:49 -0300275[SEN_OV2610AE] = ((1 << NCTRL) - 1) /* no control */
276 ^ ((1 << EXPOSURE) /* but exposure */
277 | (1 << AUTOGAIN)), /* and autogain */
Jean-François Moine07c6c9c2011-02-10 13:32:22 -0300278
Jean-François Moine83db7682010-11-12 07:14:08 -0300279[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
280
281[SEN_OV6620] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300282 (1 << VFLIP) |
283 (1 << EXPOSURE) |
284 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300285
286[SEN_OV6630] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300287 (1 << VFLIP) |
288 (1 << EXPOSURE) |
289 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300290
291[SEN_OV66308AF] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300292 (1 << VFLIP) |
293 (1 << EXPOSURE) |
294 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300295
296[SEN_OV7610] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300297 (1 << VFLIP) |
298 (1 << EXPOSURE) |
299 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300300
301[SEN_OV7620] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300302 (1 << VFLIP) |
303 (1 << EXPOSURE) |
304 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300305
306[SEN_OV7620AE] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300307 (1 << VFLIP) |
308 (1 << EXPOSURE) |
309 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300310
311[SEN_OV7640] = (1 << HFLIP) |
312 (1 << VFLIP) |
313 (1 << AUTOBRIGHT) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300314 (1 << CONTRAST) |
315 (1 << EXPOSURE) |
316 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300317
318[SEN_OV7648] = (1 << HFLIP) |
319 (1 << VFLIP) |
320 (1 << AUTOBRIGHT) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300321 (1 << CONTRAST) |
322 (1 << EXPOSURE) |
323 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300324
Jean-François Moine58c92d32011-03-13 16:36:49 -0300325[SEN_OV7660] = (1 << AUTOBRIGHT) |
326 (1 << EXPOSURE) |
327 (1 << AUTOGAIN),
Jean-François Moine42e142f2010-11-13 05:10:27 -0300328
Jean-François Moine83db7682010-11-12 07:14:08 -0300329[SEN_OV7670] = (1 << COLORS) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300330 (1 << AUTOBRIGHT) |
331 (1 << EXPOSURE) |
332 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300333
334[SEN_OV76BE] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300335 (1 << VFLIP) |
336 (1 << EXPOSURE) |
337 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300338
339[SEN_OV8610] = (1 << HFLIP) |
340 (1 << VFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300341 (1 << EXPOSURE) |
342 (1 << AUTOGAIN) |
Jean-François Moine83db7682010-11-12 07:14:08 -0300343 (1 << FREQ),
Jean-François Moine798ae152011-05-23 05:38:10 -0300344[SEN_OV9600] = ((1 << NCTRL) - 1) /* no control */
345 ^ ((1 << EXPOSURE) /* but exposure */
346 | (1 << AUTOGAIN)), /* and autogain */
347
Jean-François Moine83db7682010-11-12 07:14:08 -0300348};
349
Hans de Goede49809d62009-06-07 12:10:39 -0300350static const struct v4l2_pix_format ov519_vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300351 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
352 .bytesperline = 320,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300353 .sizeimage = 320 * 240 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300354 .colorspace = V4L2_COLORSPACE_JPEG,
355 .priv = 1},
356 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
357 .bytesperline = 640,
358 .sizeimage = 640 * 480 * 3 / 8 + 590,
359 .colorspace = V4L2_COLORSPACE_JPEG,
360 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300361};
Hans de Goede49809d62009-06-07 12:10:39 -0300362static const struct v4l2_pix_format ov519_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300363 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
364 .bytesperline = 160,
365 .sizeimage = 160 * 120 * 3 / 8 + 590,
366 .colorspace = V4L2_COLORSPACE_JPEG,
367 .priv = 3},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300368 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
369 .bytesperline = 176,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300370 .sizeimage = 176 * 144 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300371 .colorspace = V4L2_COLORSPACE_JPEG,
372 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300373 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
374 .bytesperline = 320,
375 .sizeimage = 320 * 240 * 3 / 8 + 590,
376 .colorspace = V4L2_COLORSPACE_JPEG,
377 .priv = 2},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300378 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
379 .bytesperline = 352,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300380 .sizeimage = 352 * 288 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300381 .colorspace = V4L2_COLORSPACE_JPEG,
382 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300383};
384
Hans de Goedeb282d872009-06-14 19:10:40 -0300385/* Note some of the sizeimage values for the ov511 / ov518 may seem
386 larger then necessary, however they need to be this big as the ov511 /
387 ov518 always fills the entire isoc frame, using 0 padding bytes when
388 it doesn't have any data. So with low framerates the amount of data
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300389 transferred can become quite large (libv4l will remove all the 0 padding
Hans de Goedeb282d872009-06-14 19:10:40 -0300390 in userspace). */
Hans de Goede49809d62009-06-07 12:10:39 -0300391static const struct v4l2_pix_format ov518_vga_mode[] = {
392 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
393 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300394 .sizeimage = 320 * 240 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300395 .colorspace = V4L2_COLORSPACE_JPEG,
396 .priv = 1},
397 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
398 .bytesperline = 640,
Hans de Goedeb282d872009-06-14 19:10:40 -0300399 .sizeimage = 640 * 480 * 2,
Hans de Goede49809d62009-06-07 12:10:39 -0300400 .colorspace = V4L2_COLORSPACE_JPEG,
401 .priv = 0},
402};
403static const struct v4l2_pix_format ov518_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300404 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
405 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300406 .sizeimage = 70000,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300407 .colorspace = V4L2_COLORSPACE_JPEG,
408 .priv = 3},
Hans de Goede49809d62009-06-07 12:10:39 -0300409 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
410 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300411 .sizeimage = 70000,
Hans de Goede49809d62009-06-07 12:10:39 -0300412 .colorspace = V4L2_COLORSPACE_JPEG,
413 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300414 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
415 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300416 .sizeimage = 320 * 240 * 3,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300417 .colorspace = V4L2_COLORSPACE_JPEG,
418 .priv = 2},
Hans de Goede49809d62009-06-07 12:10:39 -0300419 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
420 .bytesperline = 352,
Hans de Goedeb282d872009-06-14 19:10:40 -0300421 .sizeimage = 352 * 288 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300422 .colorspace = V4L2_COLORSPACE_JPEG,
423 .priv = 0},
424};
425
Hans de Goede1876bb92009-06-14 06:45:50 -0300426static const struct v4l2_pix_format ov511_vga_mode[] = {
427 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
428 .bytesperline = 320,
429 .sizeimage = 320 * 240 * 3,
430 .colorspace = V4L2_COLORSPACE_JPEG,
431 .priv = 1},
432 {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
433 .bytesperline = 640,
434 .sizeimage = 640 * 480 * 2,
435 .colorspace = V4L2_COLORSPACE_JPEG,
436 .priv = 0},
437};
438static const struct v4l2_pix_format ov511_sif_mode[] = {
439 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
440 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300441 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300442 .colorspace = V4L2_COLORSPACE_JPEG,
443 .priv = 3},
444 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
445 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300446 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300447 .colorspace = V4L2_COLORSPACE_JPEG,
448 .priv = 1},
449 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
450 .bytesperline = 320,
451 .sizeimage = 320 * 240 * 3,
452 .colorspace = V4L2_COLORSPACE_JPEG,
453 .priv = 2},
454 {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
455 .bytesperline = 352,
456 .sizeimage = 352 * 288 * 3,
457 .colorspace = V4L2_COLORSPACE_JPEG,
458 .priv = 0},
459};
Hans de Goede49809d62009-06-07 12:10:39 -0300460
Hans de Goede635118d2009-10-11 09:49:03 -0300461static const struct v4l2_pix_format ovfx2_vga_mode[] = {
462 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
463 .bytesperline = 320,
464 .sizeimage = 320 * 240,
465 .colorspace = V4L2_COLORSPACE_SRGB,
466 .priv = 1},
467 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
468 .bytesperline = 640,
469 .sizeimage = 640 * 480,
470 .colorspace = V4L2_COLORSPACE_SRGB,
471 .priv = 0},
472};
473static const struct v4l2_pix_format ovfx2_cif_mode[] = {
474 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
475 .bytesperline = 160,
476 .sizeimage = 160 * 120,
477 .colorspace = V4L2_COLORSPACE_SRGB,
478 .priv = 3},
479 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
480 .bytesperline = 176,
481 .sizeimage = 176 * 144,
482 .colorspace = V4L2_COLORSPACE_SRGB,
483 .priv = 1},
484 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
485 .bytesperline = 320,
486 .sizeimage = 320 * 240,
487 .colorspace = V4L2_COLORSPACE_SRGB,
488 .priv = 2},
489 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
490 .bytesperline = 352,
491 .sizeimage = 352 * 288,
492 .colorspace = V4L2_COLORSPACE_SRGB,
493 .priv = 0},
494};
495static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
Jean-François Moinec42cedb2011-02-10 13:37:48 -0300496 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
497 .bytesperline = 800,
498 .sizeimage = 800 * 600,
499 .colorspace = V4L2_COLORSPACE_SRGB,
500 .priv = 1},
Hans de Goede635118d2009-10-11 09:49:03 -0300501 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
502 .bytesperline = 1600,
503 .sizeimage = 1600 * 1200,
504 .colorspace = V4L2_COLORSPACE_SRGB},
505};
506static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300507 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
508 .bytesperline = 640,
509 .sizeimage = 640 * 480,
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300510 .colorspace = V4L2_COLORSPACE_SRGB,
511 .priv = 1},
512 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
513 .bytesperline = 800,
514 .sizeimage = 800 * 600,
515 .colorspace = V4L2_COLORSPACE_SRGB,
516 .priv = 1},
517 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
518 .bytesperline = 1024,
519 .sizeimage = 1024 * 768,
520 .colorspace = V4L2_COLORSPACE_SRGB,
521 .priv = 1},
522 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
523 .bytesperline = 1600,
524 .sizeimage = 1600 * 1200,
525 .colorspace = V4L2_COLORSPACE_SRGB,
526 .priv = 0},
527 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
528 .bytesperline = 2048,
529 .sizeimage = 2048 * 1536,
530 .colorspace = V4L2_COLORSPACE_SRGB,
531 .priv = 0},
Hans de Goede635118d2009-10-11 09:49:03 -0300532};
Jean-François Moine798ae152011-05-23 05:38:10 -0300533static const struct v4l2_pix_format ovfx2_ov9600_mode[] = {
534 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
535 .bytesperline = 640,
536 .sizeimage = 640 * 480,
537 .colorspace = V4L2_COLORSPACE_SRGB,
538 .priv = 1},
539 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
540 .bytesperline = 1280,
541 .sizeimage = 1280 * 1024,
542 .colorspace = V4L2_COLORSPACE_SRGB},
543};
Hans de Goede635118d2009-10-11 09:49:03 -0300544
Hans de Goede49809d62009-06-07 12:10:39 -0300545/* Registers common to OV511 / OV518 */
Hans de Goede1876bb92009-06-14 06:45:50 -0300546#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
Jean-François Moine780e3122010-10-19 04:29:10 -0300547#define R51x_SYS_RESET 0x50
Hans de Goede1876bb92009-06-14 06:45:50 -0300548 /* Reset type flags */
549 #define OV511_RESET_OMNICE 0x08
Jean-François Moine780e3122010-10-19 04:29:10 -0300550#define R51x_SYS_INIT 0x53
Hans de Goede49809d62009-06-07 12:10:39 -0300551#define R51x_SYS_SNAP 0x52
Jean-François Moine87bae742010-11-12 05:31:34 -0300552#define R51x_SYS_CUST_ID 0x5f
Hans de Goede49809d62009-06-07 12:10:39 -0300553#define R51x_COMP_LUT_BEGIN 0x80
554
555/* OV511 Camera interface register numbers */
Hans de Goede1876bb92009-06-14 06:45:50 -0300556#define R511_CAM_DELAY 0x10
557#define R511_CAM_EDGE 0x11
558#define R511_CAM_PXCNT 0x12
559#define R511_CAM_LNCNT 0x13
560#define R511_CAM_PXDIV 0x14
561#define R511_CAM_LNDIV 0x15
562#define R511_CAM_UV_EN 0x16
563#define R511_CAM_LINE_MODE 0x17
564#define R511_CAM_OPTS 0x18
565
566#define R511_SNAP_FRAME 0x19
Jean-François Moine87bae742010-11-12 05:31:34 -0300567#define R511_SNAP_PXCNT 0x1a
568#define R511_SNAP_LNCNT 0x1b
569#define R511_SNAP_PXDIV 0x1c
570#define R511_SNAP_LNDIV 0x1d
571#define R511_SNAP_UV_EN 0x1e
Jean-François Moine87bae742010-11-12 05:31:34 -0300572#define R511_SNAP_OPTS 0x1f
Hans de Goede1876bb92009-06-14 06:45:50 -0300573
574#define R511_DRAM_FLOW_CTL 0x20
575#define R511_FIFO_OPTS 0x31
576#define R511_I2C_CTL 0x40
Hans de Goede49809d62009-06-07 12:10:39 -0300577#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
Hans de Goede1876bb92009-06-14 06:45:50 -0300578#define R511_COMP_EN 0x78
579#define R511_COMP_LUT_EN 0x79
Hans de Goede49809d62009-06-07 12:10:39 -0300580
581/* OV518 Camera interface register numbers */
582#define R518_GPIO_OUT 0x56 /* OV518(+) only */
583#define R518_GPIO_CTL 0x57 /* OV518(+) only */
584
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300585/* OV519 Camera interface register numbers */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -0300586#define OV519_R10_H_SIZE 0x10
587#define OV519_R11_V_SIZE 0x11
588#define OV519_R12_X_OFFSETL 0x12
589#define OV519_R13_X_OFFSETH 0x13
590#define OV519_R14_Y_OFFSETL 0x14
591#define OV519_R15_Y_OFFSETH 0x15
592#define OV519_R16_DIVIDER 0x16
593#define OV519_R20_DFR 0x20
594#define OV519_R25_FORMAT 0x25
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300595
596/* OV519 System Controller register numbers */
Jean-François Moine21867802010-11-12 06:12:09 -0300597#define OV519_R51_RESET1 0x51
598#define OV519_R54_EN_CLK1 0x54
Jean-François Moineb4e96ea2010-11-12 16:13:17 -0300599#define OV519_R57_SNAPSHOT 0x57
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300600
601#define OV519_GPIO_DATA_OUT0 0x71
602#define OV519_GPIO_IO_CTRL0 0x72
603
Jean-François Moine87bae742010-11-12 05:31:34 -0300604/*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300605
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300606/*
607 * The FX2 chip does not give us a zero length read at end of frame.
608 * It does, however, give a short read at the end of a frame, if
Daniel Mack3ad2f3f2010-02-03 08:01:28 +0800609 * necessary, rather than run two frames together.
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300610 *
611 * By choosing the right bulk transfer size, we are guaranteed to always
612 * get a short read for the last read of each frame. Frame sizes are
613 * always a composite number (width * height, or a multiple) so if we
614 * choose a prime number, we are guaranteed that the last read of a
615 * frame will be short.
616 *
617 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
618 * otherwise EOVERFLOW "babbling" errors occur. I have not been able
619 * to figure out why. [PMiller]
620 *
621 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
622 *
623 * It isn't enough to know the number of bytes per frame, in case we
624 * have data dropouts or buffer overruns (even though the FX2 double
625 * buffers, there are some pretty strict real time constraints for
626 * isochronous transfer for larger frame sizes).
627 */
Jean-François Moine9cf208e2011-05-22 05:05:11 -0300628/*jfm: this value does not work for 800x600 - see isoc_init */
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300629#define OVFX2_BULK_SIZE (13 * 4096)
630
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300631/* I2C registers */
632#define R51x_I2C_W_SID 0x41
633#define R51x_I2C_SADDR_3 0x42
634#define R51x_I2C_SADDR_2 0x43
635#define R51x_I2C_R_SID 0x44
636#define R51x_I2C_DATA 0x45
637#define R518_I2C_CTL 0x47 /* OV518(+) only */
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300638#define OVFX2_I2C_ADDR 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300639
640/* I2C ADDRESSES */
641#define OV7xx0_SID 0x42
Hans de Goede229bb7d2009-10-11 07:41:46 -0300642#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300643#define OV8xx0_SID 0xa0
644#define OV6xx0_SID 0xc0
645
646/* OV7610 registers */
647#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
Hans de Goede49809d62009-06-07 12:10:39 -0300648#define OV7610_REG_BLUE 0x01 /* blue channel balance */
649#define OV7610_REG_RED 0x02 /* red channel balance */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300650#define OV7610_REG_SAT 0x03 /* saturation */
651#define OV8610_REG_HUE 0x04 /* 04 reserved */
652#define OV7610_REG_CNT 0x05 /* Y contrast */
653#define OV7610_REG_BRT 0x06 /* Y brightness */
654#define OV7610_REG_COM_C 0x14 /* misc common regs */
655#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
656#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
657#define OV7610_REG_COM_I 0x29 /* misc settings */
658
Jean-François Moine42e142f2010-11-13 05:10:27 -0300659/* OV7660 and OV7670 registers */
Jean-François Moine21867802010-11-12 06:12:09 -0300660#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
661#define OV7670_R01_BLUE 0x01 /* blue gain */
662#define OV7670_R02_RED 0x02 /* red gain */
663#define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
664#define OV7670_R04_COM1 0x04 /* Control 1 */
665/*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */
666#define OV7670_R0C_COM3 0x0c /* Control 3 */
667#define OV7670_R0D_COM4 0x0d /* Control 4 */
668#define OV7670_R0E_COM5 0x0e /* All "reserved" */
669#define OV7670_R0F_COM6 0x0f /* Control 6 */
670#define OV7670_R10_AECH 0x10 /* More bits of AEC value */
671#define OV7670_R11_CLKRC 0x11 /* Clock control */
672#define OV7670_R12_COM7 0x12 /* Control 7 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300673#define OV7670_COM7_FMT_VGA 0x00
674/*#define OV7670_COM7_YUV 0x00 * YUV */
675#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
676#define OV7670_COM7_FMT_MASK 0x38
677#define OV7670_COM7_RESET 0x80 /* Register reset */
Jean-François Moine21867802010-11-12 06:12:09 -0300678#define OV7670_R13_COM8 0x13 /* Control 8 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300679#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
680#define OV7670_COM8_AWB 0x02 /* White balance enable */
681#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
682#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
683#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
684#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
Jean-François Moine21867802010-11-12 06:12:09 -0300685#define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */
686#define OV7670_R15_COM10 0x15 /* Control 10 */
687#define OV7670_R17_HSTART 0x17 /* Horiz start high bits */
688#define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */
689#define OV7670_R19_VSTART 0x19 /* Vert start high bits */
690#define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */
691#define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */
Jean-François Moine87bae742010-11-12 05:31:34 -0300692#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
693#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
Jean-François Moine21867802010-11-12 06:12:09 -0300694#define OV7670_R24_AEW 0x24 /* AGC upper limit */
695#define OV7670_R25_AEB 0x25 /* AGC lower limit */
696#define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */
697#define OV7670_R32_HREF 0x32 /* HREF pieces */
698#define OV7670_R3A_TSLB 0x3a /* lots of stuff */
699#define OV7670_R3B_COM11 0x3b /* Control 11 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300700#define OV7670_COM11_EXP 0x02
701#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
Jean-François Moine21867802010-11-12 06:12:09 -0300702#define OV7670_R3C_COM12 0x3c /* Control 12 */
703#define OV7670_R3D_COM13 0x3d /* Control 13 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300704#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
705#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
Jean-François Moine21867802010-11-12 06:12:09 -0300706#define OV7670_R3E_COM14 0x3e /* Control 14 */
707#define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */
708#define OV7670_R40_COM15 0x40 /* Control 15 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300709/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */
Jean-François Moine21867802010-11-12 06:12:09 -0300710#define OV7670_R41_COM16 0x41 /* Control 16 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300711#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
Jean-François Moine42e142f2010-11-13 05:10:27 -0300712/* end of ov7660 common registers */
Jean-François Moine21867802010-11-12 06:12:09 -0300713#define OV7670_R55_BRIGHT 0x55 /* Brightness */
714#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
715#define OV7670_R69_GFIX 0x69 /* Fix gain control */
716/*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */
717#define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */
718#define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
719#define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */
720#define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
721#define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
722#define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
723#define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
724#define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */
725#define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300726
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300727struct ov_regvals {
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300728 u8 reg;
729 u8 val;
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300730};
731struct ov_i2c_regvals {
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300732 u8 reg;
733 u8 val;
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300734};
735
Hans de Goede635118d2009-10-11 09:49:03 -0300736/* Settings for OV2610 camera chip */
Jean-François Moine780e3122010-10-19 04:29:10 -0300737static const struct ov_i2c_regvals norm_2610[] = {
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300738 { 0x12, 0x80 }, /* reset */
Hans de Goede635118d2009-10-11 09:49:03 -0300739};
740
Jean-François Moine07c6c9c2011-02-10 13:32:22 -0300741static const struct ov_i2c_regvals norm_2610ae[] = {
742 {0x12, 0x80}, /* reset */
743 {0x13, 0xcd},
744 {0x09, 0x01},
745 {0x0d, 0x00},
746 {0x11, 0x80},
747 {0x12, 0x20}, /* 1600x1200 */
748 {0x33, 0x0c},
749 {0x35, 0x90},
750 {0x36, 0x37},
751/* ms-win traces */
752 {0x11, 0x83}, /* clock / 3 ? */
753 {0x2d, 0x00}, /* 60 Hz filter */
754 {0x24, 0xb0}, /* normal colors */
755 {0x25, 0x90},
756 {0x10, 0x43},
757};
758
Jean-François Moine780e3122010-10-19 04:29:10 -0300759static const struct ov_i2c_regvals norm_3620b[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300760 /*
761 * From the datasheet: "Note that after writing to register COMH
762 * (0x12) to change the sensor mode, registers related to the
763 * sensor’s cropping window will be reset back to their default
764 * values."
765 *
766 * "wait 4096 external clock ... to make sure the sensor is
767 * stable and ready to access registers" i.e. 160us at 24MHz
768 */
Hans de Goede635118d2009-10-11 09:49:03 -0300769 { 0x12, 0x80 }, /* COMH reset */
770 { 0x12, 0x00 }, /* QXGA, master */
771
772 /*
773 * 11 CLKRC "Clock Rate Control"
774 * [7] internal frequency doublers: on
775 * [6] video port mode: master
776 * [5:0] clock divider: 1
777 */
778 { 0x11, 0x80 },
779
780 /*
781 * 13 COMI "Common Control I"
782 * = 192 (0xC0) 11000000
783 * COMI[7] "AEC speed selection"
784 * = 1 (0x01) 1....... "Faster AEC correction"
785 * COMI[6] "AEC speed step selection"
786 * = 1 (0x01) .1...... "Big steps, fast"
787 * COMI[5] "Banding filter on off"
788 * = 0 (0x00) ..0..... "Off"
789 * COMI[4] "Banding filter option"
790 * = 0 (0x00) ...0.... "Main clock is 48 MHz and
791 * the PLL is ON"
792 * COMI[3] "Reserved"
793 * = 0 (0x00) ....0...
794 * COMI[2] "AGC auto manual control selection"
795 * = 0 (0x00) .....0.. "Manual"
796 * COMI[1] "AWB auto manual control selection"
797 * = 0 (0x00) ......0. "Manual"
798 * COMI[0] "Exposure control"
799 * = 0 (0x00) .......0 "Manual"
800 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300801 { 0x13, 0xc0 },
Hans de Goede635118d2009-10-11 09:49:03 -0300802
803 /*
804 * 09 COMC "Common Control C"
805 * = 8 (0x08) 00001000
806 * COMC[7:5] "Reserved"
807 * = 0 (0x00) 000.....
808 * COMC[4] "Sleep Mode Enable"
809 * = 0 (0x00) ...0.... "Normal mode"
810 * COMC[3:2] "Sensor sampling reset timing selection"
811 * = 2 (0x02) ....10.. "Longer reset time"
812 * COMC[1:0] "Output drive current select"
813 * = 0 (0x00) ......00 "Weakest"
814 */
815 { 0x09, 0x08 },
816
817 /*
818 * 0C COMD "Common Control D"
819 * = 8 (0x08) 00001000
820 * COMD[7] "Reserved"
821 * = 0 (0x00) 0.......
822 * COMD[6] "Swap MSB and LSB at the output port"
823 * = 0 (0x00) .0...... "False"
824 * COMD[5:3] "Reserved"
825 * = 1 (0x01) ..001...
826 * COMD[2] "Output Average On Off"
827 * = 0 (0x00) .....0.. "Output Normal"
828 * COMD[1] "Sensor precharge voltage selection"
829 * = 0 (0x00) ......0. "Selects internal
830 * reference precharge
831 * voltage"
832 * COMD[0] "Snapshot option"
833 * = 0 (0x00) .......0 "Enable live video output
834 * after snapshot sequence"
835 */
836 { 0x0c, 0x08 },
837
838 /*
839 * 0D COME "Common Control E"
840 * = 161 (0xA1) 10100001
841 * COME[7] "Output average option"
842 * = 1 (0x01) 1....... "Output average of 4 pixels"
843 * COME[6] "Anti-blooming control"
844 * = 0 (0x00) .0...... "Off"
845 * COME[5:3] "Reserved"
846 * = 4 (0x04) ..100...
847 * COME[2] "Clock output power down pin status"
848 * = 0 (0x00) .....0.. "Tri-state data output pin
849 * on power down"
850 * COME[1] "Data output pin status selection at power down"
851 * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
852 * HREF, and CHSYNC pins on
853 * power down"
854 * COME[0] "Auto zero circuit select"
855 * = 1 (0x01) .......1 "On"
856 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300857 { 0x0d, 0xa1 },
Hans de Goede635118d2009-10-11 09:49:03 -0300858
859 /*
860 * 0E COMF "Common Control F"
861 * = 112 (0x70) 01110000
862 * COMF[7] "System clock selection"
863 * = 0 (0x00) 0....... "Use 24 MHz system clock"
864 * COMF[6:4] "Reserved"
865 * = 7 (0x07) .111....
866 * COMF[3] "Manual auto negative offset canceling selection"
867 * = 0 (0x00) ....0... "Auto detect negative
868 * offset and cancel it"
869 * COMF[2:0] "Reserved"
870 * = 0 (0x00) .....000
871 */
872 { 0x0e, 0x70 },
873
874 /*
875 * 0F COMG "Common Control G"
876 * = 66 (0x42) 01000010
877 * COMG[7] "Optical black output selection"
878 * = 0 (0x00) 0....... "Disable"
879 * COMG[6] "Black level calibrate selection"
880 * = 1 (0x01) .1...... "Use optical black pixels
881 * to calibrate"
882 * COMG[5:4] "Reserved"
883 * = 0 (0x00) ..00....
884 * COMG[3] "Channel offset adjustment"
885 * = 0 (0x00) ....0... "Disable offset adjustment"
886 * COMG[2] "ADC black level calibration option"
887 * = 0 (0x00) .....0.. "Use B/G line and G/R
888 * line to calibrate each
889 * channel's black level"
890 * COMG[1] "Reserved"
891 * = 1 (0x01) ......1.
892 * COMG[0] "ADC black level calibration enable"
893 * = 0 (0x00) .......0 "Disable"
894 */
895 { 0x0f, 0x42 },
896
897 /*
898 * 14 COMJ "Common Control J"
899 * = 198 (0xC6) 11000110
900 * COMJ[7:6] "AGC gain ceiling"
901 * = 3 (0x03) 11...... "8x"
902 * COMJ[5:4] "Reserved"
903 * = 0 (0x00) ..00....
904 * COMJ[3] "Auto banding filter"
905 * = 0 (0x00) ....0... "Banding filter is always
906 * on off depending on
907 * COMI[5] setting"
908 * COMJ[2] "VSYNC drop option"
909 * = 1 (0x01) .....1.. "SYNC is dropped if frame
910 * data is dropped"
911 * COMJ[1] "Frame data drop"
912 * = 1 (0x01) ......1. "Drop frame data if
913 * exposure is not within
914 * tolerance. In AEC mode,
915 * data is normally dropped
916 * when data is out of
917 * range."
918 * COMJ[0] "Reserved"
919 * = 0 (0x00) .......0
920 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300921 { 0x14, 0xc6 },
Hans de Goede635118d2009-10-11 09:49:03 -0300922
923 /*
924 * 15 COMK "Common Control K"
925 * = 2 (0x02) 00000010
926 * COMK[7] "CHSYNC pin output swap"
927 * = 0 (0x00) 0....... "CHSYNC"
928 * COMK[6] "HREF pin output swap"
929 * = 0 (0x00) .0...... "HREF"
930 * COMK[5] "PCLK output selection"
931 * = 0 (0x00) ..0..... "PCLK always output"
932 * COMK[4] "PCLK edge selection"
933 * = 0 (0x00) ...0.... "Data valid on falling edge"
934 * COMK[3] "HREF output polarity"
935 * = 0 (0x00) ....0... "positive"
936 * COMK[2] "Reserved"
937 * = 0 (0x00) .....0..
938 * COMK[1] "VSYNC polarity"
939 * = 1 (0x01) ......1. "negative"
940 * COMK[0] "HSYNC polarity"
941 * = 0 (0x00) .......0 "positive"
942 */
943 { 0x15, 0x02 },
944
945 /*
946 * 33 CHLF "Current Control"
947 * = 9 (0x09) 00001001
948 * CHLF[7:6] "Sensor current control"
949 * = 0 (0x00) 00......
950 * CHLF[5] "Sensor current range control"
951 * = 0 (0x00) ..0..... "normal range"
952 * CHLF[4] "Sensor current"
953 * = 0 (0x00) ...0.... "normal current"
954 * CHLF[3] "Sensor buffer current control"
955 * = 1 (0x01) ....1... "half current"
956 * CHLF[2] "Column buffer current control"
957 * = 0 (0x00) .....0.. "normal current"
958 * CHLF[1] "Analog DSP current control"
959 * = 0 (0x00) ......0. "normal current"
960 * CHLF[1] "ADC current control"
961 * = 0 (0x00) ......0. "normal current"
962 */
963 { 0x33, 0x09 },
964
965 /*
966 * 34 VBLM "Blooming Control"
967 * = 80 (0x50) 01010000
968 * VBLM[7] "Hard soft reset switch"
969 * = 0 (0x00) 0....... "Hard reset"
970 * VBLM[6:4] "Blooming voltage selection"
971 * = 5 (0x05) .101....
972 * VBLM[3:0] "Sensor current control"
973 * = 0 (0x00) ....0000
974 */
975 { 0x34, 0x50 },
976
977 /*
978 * 36 VCHG "Sensor Precharge Voltage Control"
979 * = 0 (0x00) 00000000
980 * VCHG[7] "Reserved"
981 * = 0 (0x00) 0.......
982 * VCHG[6:4] "Sensor precharge voltage control"
983 * = 0 (0x00) .000....
984 * VCHG[3:0] "Sensor array common reference"
985 * = 0 (0x00) ....0000
986 */
987 { 0x36, 0x00 },
988
989 /*
990 * 37 ADC "ADC Reference Control"
991 * = 4 (0x04) 00000100
992 * ADC[7:4] "Reserved"
993 * = 0 (0x00) 0000....
994 * ADC[3] "ADC input signal range"
995 * = 0 (0x00) ....0... "Input signal 1.0x"
996 * ADC[2:0] "ADC range control"
997 * = 4 (0x04) .....100
998 */
999 { 0x37, 0x04 },
1000
1001 /*
1002 * 38 ACOM "Analog Common Ground"
1003 * = 82 (0x52) 01010010
1004 * ACOM[7] "Analog gain control"
1005 * = 0 (0x00) 0....... "Gain 1x"
1006 * ACOM[6] "Analog black level calibration"
1007 * = 1 (0x01) .1...... "On"
1008 * ACOM[5:0] "Reserved"
1009 * = 18 (0x12) ..010010
1010 */
1011 { 0x38, 0x52 },
1012
1013 /*
1014 * 3A FREFA "Internal Reference Adjustment"
1015 * = 0 (0x00) 00000000
1016 * FREFA[7:0] "Range"
1017 * = 0 (0x00) 00000000
1018 */
1019 { 0x3a, 0x00 },
1020
1021 /*
1022 * 3C FVOPT "Internal Reference Adjustment"
1023 * = 31 (0x1F) 00011111
1024 * FVOPT[7:0] "Range"
1025 * = 31 (0x1F) 00011111
1026 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001027 { 0x3c, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001028
1029 /*
1030 * 44 Undocumented = 0 (0x00) 00000000
1031 * 44[7:0] "It's a secret"
1032 * = 0 (0x00) 00000000
1033 */
1034 { 0x44, 0x00 },
1035
1036 /*
1037 * 40 Undocumented = 0 (0x00) 00000000
1038 * 40[7:0] "It's a secret"
1039 * = 0 (0x00) 00000000
1040 */
1041 { 0x40, 0x00 },
1042
1043 /*
1044 * 41 Undocumented = 0 (0x00) 00000000
1045 * 41[7:0] "It's a secret"
1046 * = 0 (0x00) 00000000
1047 */
1048 { 0x41, 0x00 },
1049
1050 /*
1051 * 42 Undocumented = 0 (0x00) 00000000
1052 * 42[7:0] "It's a secret"
1053 * = 0 (0x00) 00000000
1054 */
1055 { 0x42, 0x00 },
1056
1057 /*
1058 * 43 Undocumented = 0 (0x00) 00000000
1059 * 43[7:0] "It's a secret"
1060 * = 0 (0x00) 00000000
1061 */
1062 { 0x43, 0x00 },
1063
1064 /*
1065 * 45 Undocumented = 128 (0x80) 10000000
1066 * 45[7:0] "It's a secret"
1067 * = 128 (0x80) 10000000
1068 */
1069 { 0x45, 0x80 },
1070
1071 /*
1072 * 48 Undocumented = 192 (0xC0) 11000000
1073 * 48[7:0] "It's a secret"
1074 * = 192 (0xC0) 11000000
1075 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001076 { 0x48, 0xc0 },
Hans de Goede635118d2009-10-11 09:49:03 -03001077
1078 /*
1079 * 49 Undocumented = 25 (0x19) 00011001
1080 * 49[7:0] "It's a secret"
1081 * = 25 (0x19) 00011001
1082 */
1083 { 0x49, 0x19 },
1084
1085 /*
1086 * 4B Undocumented = 128 (0x80) 10000000
1087 * 4B[7:0] "It's a secret"
1088 * = 128 (0x80) 10000000
1089 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001090 { 0x4b, 0x80 },
Hans de Goede635118d2009-10-11 09:49:03 -03001091
1092 /*
1093 * 4D Undocumented = 196 (0xC4) 11000100
1094 * 4D[7:0] "It's a secret"
1095 * = 196 (0xC4) 11000100
1096 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001097 { 0x4d, 0xc4 },
Hans de Goede635118d2009-10-11 09:49:03 -03001098
1099 /*
1100 * 35 VREF "Reference Voltage Control"
Jean-François Moine87bae742010-11-12 05:31:34 -03001101 * = 76 (0x4c) 01001100
Hans de Goede635118d2009-10-11 09:49:03 -03001102 * VREF[7:5] "Column high reference control"
1103 * = 2 (0x02) 010..... "higher voltage"
1104 * VREF[4:2] "Column low reference control"
1105 * = 3 (0x03) ...011.. "Highest voltage"
1106 * VREF[1:0] "Reserved"
1107 * = 0 (0x00) ......00
1108 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001109 { 0x35, 0x4c },
Hans de Goede635118d2009-10-11 09:49:03 -03001110
1111 /*
1112 * 3D Undocumented = 0 (0x00) 00000000
1113 * 3D[7:0] "It's a secret"
1114 * = 0 (0x00) 00000000
1115 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001116 { 0x3d, 0x00 },
Hans de Goede635118d2009-10-11 09:49:03 -03001117
1118 /*
1119 * 3E Undocumented = 0 (0x00) 00000000
1120 * 3E[7:0] "It's a secret"
1121 * = 0 (0x00) 00000000
1122 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001123 { 0x3e, 0x00 },
Hans de Goede635118d2009-10-11 09:49:03 -03001124
1125 /*
1126 * 3B FREFB "Internal Reference Adjustment"
1127 * = 24 (0x18) 00011000
1128 * FREFB[7:0] "Range"
1129 * = 24 (0x18) 00011000
1130 */
1131 { 0x3b, 0x18 },
1132
1133 /*
1134 * 33 CHLF "Current Control"
1135 * = 25 (0x19) 00011001
1136 * CHLF[7:6] "Sensor current control"
1137 * = 0 (0x00) 00......
1138 * CHLF[5] "Sensor current range control"
1139 * = 0 (0x00) ..0..... "normal range"
1140 * CHLF[4] "Sensor current"
1141 * = 1 (0x01) ...1.... "double current"
1142 * CHLF[3] "Sensor buffer current control"
1143 * = 1 (0x01) ....1... "half current"
1144 * CHLF[2] "Column buffer current control"
1145 * = 0 (0x00) .....0.. "normal current"
1146 * CHLF[1] "Analog DSP current control"
1147 * = 0 (0x00) ......0. "normal current"
1148 * CHLF[1] "ADC current control"
1149 * = 0 (0x00) ......0. "normal current"
1150 */
1151 { 0x33, 0x19 },
1152
1153 /*
1154 * 34 VBLM "Blooming Control"
1155 * = 90 (0x5A) 01011010
1156 * VBLM[7] "Hard soft reset switch"
1157 * = 0 (0x00) 0....... "Hard reset"
1158 * VBLM[6:4] "Blooming voltage selection"
1159 * = 5 (0x05) .101....
1160 * VBLM[3:0] "Sensor current control"
1161 * = 10 (0x0A) ....1010
1162 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001163 { 0x34, 0x5a },
Hans de Goede635118d2009-10-11 09:49:03 -03001164
1165 /*
1166 * 3B FREFB "Internal Reference Adjustment"
1167 * = 0 (0x00) 00000000
1168 * FREFB[7:0] "Range"
1169 * = 0 (0x00) 00000000
1170 */
1171 { 0x3b, 0x00 },
1172
1173 /*
1174 * 33 CHLF "Current Control"
1175 * = 9 (0x09) 00001001
1176 * CHLF[7:6] "Sensor current control"
1177 * = 0 (0x00) 00......
1178 * CHLF[5] "Sensor current range control"
1179 * = 0 (0x00) ..0..... "normal range"
1180 * CHLF[4] "Sensor current"
1181 * = 0 (0x00) ...0.... "normal current"
1182 * CHLF[3] "Sensor buffer current control"
1183 * = 1 (0x01) ....1... "half current"
1184 * CHLF[2] "Column buffer current control"
1185 * = 0 (0x00) .....0.. "normal current"
1186 * CHLF[1] "Analog DSP current control"
1187 * = 0 (0x00) ......0. "normal current"
1188 * CHLF[1] "ADC current control"
1189 * = 0 (0x00) ......0. "normal current"
1190 */
1191 { 0x33, 0x09 },
1192
1193 /*
1194 * 34 VBLM "Blooming Control"
1195 * = 80 (0x50) 01010000
1196 * VBLM[7] "Hard soft reset switch"
1197 * = 0 (0x00) 0....... "Hard reset"
1198 * VBLM[6:4] "Blooming voltage selection"
1199 * = 5 (0x05) .101....
1200 * VBLM[3:0] "Sensor current control"
1201 * = 0 (0x00) ....0000
1202 */
1203 { 0x34, 0x50 },
1204
1205 /*
1206 * 12 COMH "Common Control H"
1207 * = 64 (0x40) 01000000
1208 * COMH[7] "SRST"
1209 * = 0 (0x00) 0....... "No-op"
1210 * COMH[6:4] "Resolution selection"
1211 * = 4 (0x04) .100.... "XGA"
1212 * COMH[3] "Master slave selection"
1213 * = 0 (0x00) ....0... "Master mode"
1214 * COMH[2] "Internal B/R channel option"
1215 * = 0 (0x00) .....0.. "B/R use same channel"
1216 * COMH[1] "Color bar test pattern"
1217 * = 0 (0x00) ......0. "Off"
1218 * COMH[0] "Reserved"
1219 * = 0 (0x00) .......0
1220 */
1221 { 0x12, 0x40 },
1222
1223 /*
1224 * 17 HREFST "Horizontal window start"
1225 * = 31 (0x1F) 00011111
1226 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1227 * = 31 (0x1F) 00011111
1228 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001229 { 0x17, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001230
1231 /*
1232 * 18 HREFEND "Horizontal window end"
1233 * = 95 (0x5F) 01011111
1234 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1235 * = 95 (0x5F) 01011111
1236 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001237 { 0x18, 0x5f },
Hans de Goede635118d2009-10-11 09:49:03 -03001238
1239 /*
1240 * 19 VSTRT "Vertical window start"
1241 * = 0 (0x00) 00000000
1242 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1243 * = 0 (0x00) 00000000
1244 */
1245 { 0x19, 0x00 },
1246
1247 /*
1248 * 1A VEND "Vertical window end"
1249 * = 96 (0x60) 01100000
1250 * VEND[7:0] "Vertical Window End, 8 MSBs"
1251 * = 96 (0x60) 01100000
1252 */
1253 { 0x1a, 0x60 },
1254
1255 /*
1256 * 32 COMM "Common Control M"
1257 * = 18 (0x12) 00010010
1258 * COMM[7:6] "Pixel clock divide option"
1259 * = 0 (0x00) 00...... "/1"
1260 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1261 * = 2 (0x02) ..010...
1262 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1263 * = 2 (0x02) .....010
1264 */
1265 { 0x32, 0x12 },
1266
1267 /*
1268 * 03 COMA "Common Control A"
1269 * = 74 (0x4A) 01001010
1270 * COMA[7:4] "AWB Update Threshold"
1271 * = 4 (0x04) 0100....
1272 * COMA[3:2] "Vertical window end line control 2 LSBs"
1273 * = 2 (0x02) ....10..
1274 * COMA[1:0] "Vertical window start line control 2 LSBs"
1275 * = 2 (0x02) ......10
1276 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001277 { 0x03, 0x4a },
Hans de Goede635118d2009-10-11 09:49:03 -03001278
1279 /*
1280 * 11 CLKRC "Clock Rate Control"
1281 * = 128 (0x80) 10000000
1282 * CLKRC[7] "Internal frequency doublers on off seclection"
1283 * = 1 (0x01) 1....... "On"
1284 * CLKRC[6] "Digital video master slave selection"
1285 * = 0 (0x00) .0...... "Master mode, sensor
1286 * provides PCLK"
1287 * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
1288 * = 0 (0x00) ..000000
1289 */
1290 { 0x11, 0x80 },
1291
1292 /*
1293 * 12 COMH "Common Control H"
1294 * = 0 (0x00) 00000000
1295 * COMH[7] "SRST"
1296 * = 0 (0x00) 0....... "No-op"
1297 * COMH[6:4] "Resolution selection"
1298 * = 0 (0x00) .000.... "QXGA"
1299 * COMH[3] "Master slave selection"
1300 * = 0 (0x00) ....0... "Master mode"
1301 * COMH[2] "Internal B/R channel option"
1302 * = 0 (0x00) .....0.. "B/R use same channel"
1303 * COMH[1] "Color bar test pattern"
1304 * = 0 (0x00) ......0. "Off"
1305 * COMH[0] "Reserved"
1306 * = 0 (0x00) .......0
1307 */
1308 { 0x12, 0x00 },
1309
1310 /*
1311 * 12 COMH "Common Control H"
1312 * = 64 (0x40) 01000000
1313 * COMH[7] "SRST"
1314 * = 0 (0x00) 0....... "No-op"
1315 * COMH[6:4] "Resolution selection"
1316 * = 4 (0x04) .100.... "XGA"
1317 * COMH[3] "Master slave selection"
1318 * = 0 (0x00) ....0... "Master mode"
1319 * COMH[2] "Internal B/R channel option"
1320 * = 0 (0x00) .....0.. "B/R use same channel"
1321 * COMH[1] "Color bar test pattern"
1322 * = 0 (0x00) ......0. "Off"
1323 * COMH[0] "Reserved"
1324 * = 0 (0x00) .......0
1325 */
1326 { 0x12, 0x40 },
1327
1328 /*
1329 * 17 HREFST "Horizontal window start"
1330 * = 31 (0x1F) 00011111
1331 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1332 * = 31 (0x1F) 00011111
1333 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001334 { 0x17, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001335
1336 /*
1337 * 18 HREFEND "Horizontal window end"
1338 * = 95 (0x5F) 01011111
1339 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1340 * = 95 (0x5F) 01011111
1341 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001342 { 0x18, 0x5f },
Hans de Goede635118d2009-10-11 09:49:03 -03001343
1344 /*
1345 * 19 VSTRT "Vertical window start"
1346 * = 0 (0x00) 00000000
1347 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1348 * = 0 (0x00) 00000000
1349 */
1350 { 0x19, 0x00 },
1351
1352 /*
1353 * 1A VEND "Vertical window end"
1354 * = 96 (0x60) 01100000
1355 * VEND[7:0] "Vertical Window End, 8 MSBs"
1356 * = 96 (0x60) 01100000
1357 */
1358 { 0x1a, 0x60 },
1359
1360 /*
1361 * 32 COMM "Common Control M"
1362 * = 18 (0x12) 00010010
1363 * COMM[7:6] "Pixel clock divide option"
1364 * = 0 (0x00) 00...... "/1"
1365 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1366 * = 2 (0x02) ..010...
1367 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1368 * = 2 (0x02) .....010
1369 */
1370 { 0x32, 0x12 },
1371
1372 /*
1373 * 03 COMA "Common Control A"
1374 * = 74 (0x4A) 01001010
1375 * COMA[7:4] "AWB Update Threshold"
1376 * = 4 (0x04) 0100....
1377 * COMA[3:2] "Vertical window end line control 2 LSBs"
1378 * = 2 (0x02) ....10..
1379 * COMA[1:0] "Vertical window start line control 2 LSBs"
1380 * = 2 (0x02) ......10
1381 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001382 { 0x03, 0x4a },
Hans de Goede635118d2009-10-11 09:49:03 -03001383
1384 /*
1385 * 02 RED "Red Gain Control"
1386 * = 175 (0xAF) 10101111
1387 * RED[7] "Action"
1388 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1389 * RED[6:0] "Value"
1390 * = 47 (0x2F) .0101111
1391 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001392 { 0x02, 0xaf },
Hans de Goede635118d2009-10-11 09:49:03 -03001393
1394 /*
1395 * 2D ADDVSL "VSYNC Pulse Width"
1396 * = 210 (0xD2) 11010010
1397 * ADDVSL[7:0] "VSYNC pulse width, LSB"
1398 * = 210 (0xD2) 11010010
1399 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001400 { 0x2d, 0xd2 },
Hans de Goede635118d2009-10-11 09:49:03 -03001401
1402 /*
1403 * 00 GAIN = 24 (0x18) 00011000
1404 * GAIN[7:6] "Reserved"
1405 * = 0 (0x00) 00......
1406 * GAIN[5] "Double"
1407 * = 0 (0x00) ..0..... "False"
1408 * GAIN[4] "Double"
1409 * = 1 (0x01) ...1.... "True"
1410 * GAIN[3:0] "Range"
1411 * = 8 (0x08) ....1000
1412 */
1413 { 0x00, 0x18 },
1414
1415 /*
1416 * 01 BLUE "Blue Gain Control"
1417 * = 240 (0xF0) 11110000
1418 * BLUE[7] "Action"
1419 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1420 * BLUE[6:0] "Value"
1421 * = 112 (0x70) .1110000
1422 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001423 { 0x01, 0xf0 },
Hans de Goede635118d2009-10-11 09:49:03 -03001424
1425 /*
1426 * 10 AEC "Automatic Exposure Control"
1427 * = 10 (0x0A) 00001010
1428 * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
1429 * = 10 (0x0A) 00001010
1430 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001431 { 0x10, 0x0a },
Hans de Goede635118d2009-10-11 09:49:03 -03001432
Jean-François Moine87bae742010-11-12 05:31:34 -03001433 { 0xe1, 0x67 },
1434 { 0xe3, 0x03 },
1435 { 0xe4, 0x26 },
1436 { 0xe5, 0x3e },
1437 { 0xf8, 0x01 },
1438 { 0xff, 0x01 },
Hans de Goede635118d2009-10-11 09:49:03 -03001439};
1440
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001441static const struct ov_i2c_regvals norm_6x20[] = {
1442 { 0x12, 0x80 }, /* reset */
1443 { 0x11, 0x01 },
1444 { 0x03, 0x60 },
1445 { 0x05, 0x7f }, /* For when autoadjust is off */
1446 { 0x07, 0xa8 },
Jean-François Moine87bae742010-11-12 05:31:34 -03001447 /* The ratio of 0x0c and 0x0d controls the white point */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001448 { 0x0c, 0x24 },
1449 { 0x0d, 0x24 },
1450 { 0x0f, 0x15 }, /* COMS */
1451 { 0x10, 0x75 }, /* AEC Exposure time */
1452 { 0x12, 0x24 }, /* Enable AGC */
1453 { 0x14, 0x04 },
1454 /* 0x16: 0x06 helps frame stability with moving objects */
1455 { 0x16, 0x06 },
1456/* { 0x20, 0x30 }, * Aperture correction enable */
1457 { 0x26, 0xb2 }, /* BLC enable */
1458 /* 0x28: 0x05 Selects RGB format if RGB on */
1459 { 0x28, 0x05 },
1460 { 0x2a, 0x04 }, /* Disable framerate adjust */
1461/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
Hans de Goedeae49c402009-06-14 19:15:07 -03001462 { 0x2d, 0x85 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001463 { 0x33, 0xa0 }, /* Color Processing Parameter */
1464 { 0x34, 0xd2 }, /* Max A/D range */
1465 { 0x38, 0x8b },
1466 { 0x39, 0x40 },
1467
1468 { 0x3c, 0x39 }, /* Enable AEC mode changing */
1469 { 0x3c, 0x3c }, /* Change AEC mode */
1470 { 0x3c, 0x24 }, /* Disable AEC mode changing */
1471
1472 { 0x3d, 0x80 },
1473 /* These next two registers (0x4a, 0x4b) are undocumented.
1474 * They control the color balance */
1475 { 0x4a, 0x80 },
1476 { 0x4b, 0x80 },
1477 { 0x4d, 0xd2 }, /* This reduces noise a bit */
1478 { 0x4e, 0xc1 },
1479 { 0x4f, 0x04 },
1480/* Do 50-53 have any effect? */
1481/* Toggle 0x12[2] off and on here? */
1482};
1483
1484static const struct ov_i2c_regvals norm_6x30[] = {
1485 { 0x12, 0x80 }, /* Reset */
1486 { 0x00, 0x1f }, /* Gain */
1487 { 0x01, 0x99 }, /* Blue gain */
1488 { 0x02, 0x7c }, /* Red gain */
1489 { 0x03, 0xc0 }, /* Saturation */
1490 { 0x05, 0x0a }, /* Contrast */
1491 { 0x06, 0x95 }, /* Brightness */
1492 { 0x07, 0x2d }, /* Sharpness */
1493 { 0x0c, 0x20 },
1494 { 0x0d, 0x20 },
Hans de Goede02ab18b2009-06-14 04:32:04 -03001495 { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001496 { 0x0f, 0x05 },
1497 { 0x10, 0x9a },
1498 { 0x11, 0x00 }, /* Pixel clock = fastest */
1499 { 0x12, 0x24 }, /* Enable AGC and AWB */
1500 { 0x13, 0x21 },
1501 { 0x14, 0x80 },
1502 { 0x15, 0x01 },
1503 { 0x16, 0x03 },
1504 { 0x17, 0x38 },
1505 { 0x18, 0xea },
1506 { 0x19, 0x04 },
1507 { 0x1a, 0x93 },
1508 { 0x1b, 0x00 },
1509 { 0x1e, 0xc4 },
1510 { 0x1f, 0x04 },
1511 { 0x20, 0x20 },
1512 { 0x21, 0x10 },
1513 { 0x22, 0x88 },
1514 { 0x23, 0xc0 }, /* Crystal circuit power level */
1515 { 0x25, 0x9a }, /* Increase AEC black ratio */
1516 { 0x26, 0xb2 }, /* BLC enable */
1517 { 0x27, 0xa2 },
1518 { 0x28, 0x00 },
1519 { 0x29, 0x00 },
1520 { 0x2a, 0x84 }, /* 60 Hz power */
1521 { 0x2b, 0xa8 }, /* 60 Hz power */
1522 { 0x2c, 0xa0 },
1523 { 0x2d, 0x95 }, /* Enable auto-brightness */
1524 { 0x2e, 0x88 },
1525 { 0x33, 0x26 },
1526 { 0x34, 0x03 },
1527 { 0x36, 0x8f },
1528 { 0x37, 0x80 },
1529 { 0x38, 0x83 },
1530 { 0x39, 0x80 },
1531 { 0x3a, 0x0f },
1532 { 0x3b, 0x3c },
1533 { 0x3c, 0x1a },
1534 { 0x3d, 0x80 },
1535 { 0x3e, 0x80 },
1536 { 0x3f, 0x0e },
1537 { 0x40, 0x00 }, /* White bal */
1538 { 0x41, 0x00 }, /* White bal */
1539 { 0x42, 0x80 },
1540 { 0x43, 0x3f }, /* White bal */
1541 { 0x44, 0x80 },
1542 { 0x45, 0x20 },
1543 { 0x46, 0x20 },
1544 { 0x47, 0x80 },
1545 { 0x48, 0x7f },
1546 { 0x49, 0x00 },
1547 { 0x4a, 0x00 },
1548 { 0x4b, 0x80 },
1549 { 0x4c, 0xd0 },
1550 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
1551 { 0x4e, 0x40 },
1552 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
1553 { 0x50, 0xff },
1554 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
1555 { 0x55, 0xff },
1556 { 0x56, 0x12 },
1557 { 0x57, 0x81 },
1558 { 0x58, 0x75 },
1559 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
1560 { 0x5a, 0x2c },
1561 { 0x5b, 0x0f }, /* AWB chrominance levels */
1562 { 0x5c, 0x10 },
1563 { 0x3d, 0x80 },
1564 { 0x27, 0xa6 },
1565 { 0x12, 0x20 }, /* Toggle AWB */
1566 { 0x12, 0x24 },
1567};
1568
1569/* Lawrence Glaister <lg@jfm.bc.ca> reports:
1570 *
1571 * Register 0x0f in the 7610 has the following effects:
1572 *
1573 * 0x85 (AEC method 1): Best overall, good contrast range
1574 * 0x45 (AEC method 2): Very overexposed
1575 * 0xa5 (spec sheet default): Ok, but the black level is
1576 * shifted resulting in loss of contrast
1577 * 0x05 (old driver setting): very overexposed, too much
1578 * contrast
1579 */
1580static const struct ov_i2c_regvals norm_7610[] = {
1581 { 0x10, 0xff },
1582 { 0x16, 0x06 },
1583 { 0x28, 0x24 },
1584 { 0x2b, 0xac },
1585 { 0x12, 0x00 },
1586 { 0x38, 0x81 },
1587 { 0x28, 0x24 }, /* 0c */
1588 { 0x0f, 0x85 }, /* lg's setting */
1589 { 0x15, 0x01 },
1590 { 0x20, 0x1c },
1591 { 0x23, 0x2a },
1592 { 0x24, 0x10 },
1593 { 0x25, 0x8a },
1594 { 0x26, 0xa2 },
1595 { 0x27, 0xc2 },
1596 { 0x2a, 0x04 },
1597 { 0x2c, 0xfe },
1598 { 0x2d, 0x93 },
1599 { 0x30, 0x71 },
1600 { 0x31, 0x60 },
1601 { 0x32, 0x26 },
1602 { 0x33, 0x20 },
1603 { 0x34, 0x48 },
1604 { 0x12, 0x24 },
1605 { 0x11, 0x01 },
1606 { 0x0c, 0x24 },
1607 { 0x0d, 0x24 },
1608};
1609
1610static const struct ov_i2c_regvals norm_7620[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03001611 { 0x12, 0x80 }, /* reset */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001612 { 0x00, 0x00 }, /* gain */
1613 { 0x01, 0x80 }, /* blue gain */
1614 { 0x02, 0x80 }, /* red gain */
Jean-François Moine21867802010-11-12 06:12:09 -03001615 { 0x03, 0xc0 }, /* OV7670_R03_VREF */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001616 { 0x06, 0x60 },
1617 { 0x07, 0x00 },
1618 { 0x0c, 0x24 },
1619 { 0x0c, 0x24 },
1620 { 0x0d, 0x24 },
1621 { 0x11, 0x01 },
1622 { 0x12, 0x24 },
1623 { 0x13, 0x01 },
1624 { 0x14, 0x84 },
1625 { 0x15, 0x01 },
1626 { 0x16, 0x03 },
1627 { 0x17, 0x2f },
1628 { 0x18, 0xcf },
1629 { 0x19, 0x06 },
1630 { 0x1a, 0xf5 },
1631 { 0x1b, 0x00 },
1632 { 0x20, 0x18 },
1633 { 0x21, 0x80 },
1634 { 0x22, 0x80 },
1635 { 0x23, 0x00 },
1636 { 0x26, 0xa2 },
1637 { 0x27, 0xea },
Hans de Goedeb282d872009-06-14 19:10:40 -03001638 { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001639 { 0x29, 0x00 },
1640 { 0x2a, 0x10 },
1641 { 0x2b, 0x00 },
1642 { 0x2c, 0x88 },
1643 { 0x2d, 0x91 },
1644 { 0x2e, 0x80 },
1645 { 0x2f, 0x44 },
1646 { 0x60, 0x27 },
1647 { 0x61, 0x02 },
1648 { 0x62, 0x5f },
1649 { 0x63, 0xd5 },
1650 { 0x64, 0x57 },
1651 { 0x65, 0x83 },
1652 { 0x66, 0x55 },
1653 { 0x67, 0x92 },
1654 { 0x68, 0xcf },
1655 { 0x69, 0x76 },
1656 { 0x6a, 0x22 },
1657 { 0x6b, 0x00 },
1658 { 0x6c, 0x02 },
1659 { 0x6d, 0x44 },
1660 { 0x6e, 0x80 },
1661 { 0x6f, 0x1d },
1662 { 0x70, 0x8b },
1663 { 0x71, 0x00 },
1664 { 0x72, 0x14 },
1665 { 0x73, 0x54 },
1666 { 0x74, 0x00 },
1667 { 0x75, 0x8e },
1668 { 0x76, 0x00 },
1669 { 0x77, 0xff },
1670 { 0x78, 0x80 },
1671 { 0x79, 0x80 },
1672 { 0x7a, 0x80 },
1673 { 0x7b, 0xe2 },
1674 { 0x7c, 0x00 },
1675};
1676
1677/* 7640 and 7648. The defaults should be OK for most registers. */
1678static const struct ov_i2c_regvals norm_7640[] = {
1679 { 0x12, 0x80 },
1680 { 0x12, 0x14 },
1681};
1682
Jean-François Moine42e142f2010-11-13 05:10:27 -03001683static const struct ov_regvals init_519_ov7660[] = {
1684 { 0x5d, 0x03 }, /* Turn off suspend mode */
1685 { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */
1686 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
1687 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
1688 { 0xa3, 0x18 },
1689 { 0xa4, 0x04 },
1690 { 0xa5, 0x28 },
1691 { 0x37, 0x00 }, /* SetUsbInit */
1692 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
1693 /* Enable both fields, YUV Input, disable defect comp (why?) */
1694 { 0x20, 0x0c }, /* 0x0d does U <-> V swap */
1695 { 0x21, 0x38 },
1696 { 0x22, 0x1d },
1697 { 0x17, 0x50 }, /* undocumented */
1698 { 0x37, 0x00 }, /* undocumented */
1699 { 0x40, 0xff }, /* I2C timeout counter */
1700 { 0x46, 0x00 }, /* I2C clock prescaler */
1701};
1702static const struct ov_i2c_regvals norm_7660[] = {
1703 {OV7670_R12_COM7, OV7670_COM7_RESET},
1704 {OV7670_R11_CLKRC, 0x81},
1705 {0x92, 0x00}, /* DM_LNL */
1706 {0x93, 0x00}, /* DM_LNH */
1707 {0x9d, 0x4c}, /* BD50ST */
1708 {0x9e, 0x3f}, /* BD60ST */
1709 {OV7670_R3B_COM11, 0x02},
1710 {OV7670_R13_COM8, 0xf5},
1711 {OV7670_R10_AECH, 0x00},
1712 {OV7670_R00_GAIN, 0x00},
1713 {OV7670_R01_BLUE, 0x7c},
1714 {OV7670_R02_RED, 0x9d},
1715 {OV7670_R12_COM7, 0x00},
1716 {OV7670_R04_COM1, 00},
1717 {OV7670_R18_HSTOP, 0x01},
1718 {OV7670_R17_HSTART, 0x13},
1719 {OV7670_R32_HREF, 0x92},
1720 {OV7670_R19_VSTART, 0x02},
1721 {OV7670_R1A_VSTOP, 0x7a},
1722 {OV7670_R03_VREF, 0x00},
1723 {OV7670_R0E_COM5, 0x04},
1724 {OV7670_R0F_COM6, 0x62},
1725 {OV7670_R15_COM10, 0x00},
1726 {0x16, 0x02}, /* RSVD */
1727 {0x1b, 0x00}, /* PSHFT */
1728 {OV7670_R1E_MVFP, 0x01},
1729 {0x29, 0x3c}, /* RSVD */
1730 {0x33, 0x00}, /* CHLF */
1731 {0x34, 0x07}, /* ARBLM */
1732 {0x35, 0x84}, /* RSVD */
1733 {0x36, 0x00}, /* RSVD */
1734 {0x37, 0x04}, /* ADC */
1735 {0x39, 0x43}, /* OFON */
1736 {OV7670_R3A_TSLB, 0x00},
1737 {OV7670_R3C_COM12, 0x6c},
1738 {OV7670_R3D_COM13, 0x98},
1739 {OV7670_R3F_EDGE, 0x23},
1740 {OV7670_R40_COM15, 0xc1},
1741 {OV7670_R41_COM16, 0x22},
1742 {0x6b, 0x0a}, /* DBLV */
1743 {0xa1, 0x08}, /* RSVD */
1744 {0x69, 0x80}, /* HV */
1745 {0x43, 0xf0}, /* RSVD.. */
1746 {0x44, 0x10},
1747 {0x45, 0x78},
1748 {0x46, 0xa8},
1749 {0x47, 0x60},
1750 {0x48, 0x80},
1751 {0x59, 0xba},
1752 {0x5a, 0x9a},
1753 {0x5b, 0x22},
1754 {0x5c, 0xb9},
1755 {0x5d, 0x9b},
1756 {0x5e, 0x10},
1757 {0x5f, 0xe0},
1758 {0x60, 0x85},
1759 {0x61, 0x60},
1760 {0x9f, 0x9d}, /* RSVD */
1761 {0xa0, 0xa0}, /* DSPC2 */
1762 {0x4f, 0x60}, /* matrix */
1763 {0x50, 0x64},
1764 {0x51, 0x04},
1765 {0x52, 0x18},
1766 {0x53, 0x3c},
1767 {0x54, 0x54},
1768 {0x55, 0x40},
1769 {0x56, 0x40},
1770 {0x57, 0x40},
1771 {0x58, 0x0d}, /* matrix sign */
1772 {0x8b, 0xcc}, /* RSVD */
1773 {0x8c, 0xcc},
1774 {0x8d, 0xcf},
1775 {0x6c, 0x40}, /* gamma curve */
1776 {0x6d, 0xe0},
1777 {0x6e, 0xa0},
1778 {0x6f, 0x80},
1779 {0x70, 0x70},
1780 {0x71, 0x80},
1781 {0x72, 0x60},
1782 {0x73, 0x60},
1783 {0x74, 0x50},
1784 {0x75, 0x40},
1785 {0x76, 0x38},
1786 {0x77, 0x3c},
1787 {0x78, 0x32},
1788 {0x79, 0x1a},
1789 {0x7a, 0x28},
1790 {0x7b, 0x24},
1791 {0x7c, 0x04}, /* gamma curve */
1792 {0x7d, 0x12},
1793 {0x7e, 0x26},
1794 {0x7f, 0x46},
1795 {0x80, 0x54},
1796 {0x81, 0x64},
1797 {0x82, 0x70},
1798 {0x83, 0x7c},
1799 {0x84, 0x86},
1800 {0x85, 0x8e},
1801 {0x86, 0x9c},
1802 {0x87, 0xab},
1803 {0x88, 0xc4},
1804 {0x89, 0xd1},
1805 {0x8a, 0xe5},
1806 {OV7670_R14_COM9, 0x1e},
1807 {OV7670_R24_AEW, 0x80},
1808 {OV7670_R25_AEB, 0x72},
1809 {OV7670_R26_VPT, 0xb3},
1810 {0x62, 0x80}, /* LCC1 */
1811 {0x63, 0x80}, /* LCC2 */
1812 {0x64, 0x06}, /* LCC3 */
1813 {0x65, 0x00}, /* LCC4 */
1814 {0x66, 0x01}, /* LCC5 */
1815 {0x94, 0x0e}, /* RSVD.. */
1816 {0x95, 0x14},
1817 {OV7670_R13_COM8, OV7670_COM8_FASTAEC
1818 | OV7670_COM8_AECSTEP
1819 | OV7670_COM8_BFILT
1820 | 0x10
1821 | OV7670_COM8_AGC
1822 | OV7670_COM8_AWB
1823 | OV7670_COM8_AEC},
1824 {0xa1, 0xc8}
1825};
Jean-François Moine798ae152011-05-23 05:38:10 -03001826static const struct ov_i2c_regvals norm_9600[] = {
1827 {0x12, 0x80},
1828 {0x0c, 0x28},
1829 {0x11, 0x80},
1830 {0x13, 0xb5},
1831 {0x14, 0x3e},
1832 {0x1b, 0x04},
1833 {0x24, 0xb0},
1834 {0x25, 0x90},
1835 {0x26, 0x94},
1836 {0x35, 0x90},
1837 {0x37, 0x07},
1838 {0x38, 0x08},
1839 {0x01, 0x8e},
1840 {0x02, 0x85}
1841};
Jean-François Moine42e142f2010-11-13 05:10:27 -03001842
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001843/* 7670. Defaults taken from OmniVision provided data,
1844* as provided by Jonathan Corbet of OLPC */
1845static const struct ov_i2c_regvals norm_7670[] = {
Jean-François Moine21867802010-11-12 06:12:09 -03001846 { OV7670_R12_COM7, OV7670_COM7_RESET },
1847 { OV7670_R3A_TSLB, 0x04 }, /* OV */
1848 { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
1849 { OV7670_R11_CLKRC, 0x01 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001850/*
1851 * Set the hardware window. These values from OV don't entirely
1852 * make sense - hstop is less than hstart. But they work...
1853 */
Jean-François Moine21867802010-11-12 06:12:09 -03001854 { OV7670_R17_HSTART, 0x13 },
1855 { OV7670_R18_HSTOP, 0x01 },
1856 { OV7670_R32_HREF, 0xb6 },
1857 { OV7670_R19_VSTART, 0x02 },
1858 { OV7670_R1A_VSTOP, 0x7a },
1859 { OV7670_R03_VREF, 0x0a },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001860
Jean-François Moine21867802010-11-12 06:12:09 -03001861 { OV7670_R0C_COM3, 0x00 },
1862 { OV7670_R3E_COM14, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001863/* Mystery scaling numbers */
1864 { 0x70, 0x3a },
1865 { 0x71, 0x35 },
1866 { 0x72, 0x11 },
1867 { 0x73, 0xf0 },
1868 { 0xa2, 0x02 },
Jean-François Moine21867802010-11-12 06:12:09 -03001869/* { OV7670_R15_COM10, 0x0 }, */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001870
1871/* Gamma curve values */
1872 { 0x7a, 0x20 },
1873 { 0x7b, 0x10 },
1874 { 0x7c, 0x1e },
1875 { 0x7d, 0x35 },
1876 { 0x7e, 0x5a },
1877 { 0x7f, 0x69 },
1878 { 0x80, 0x76 },
1879 { 0x81, 0x80 },
1880 { 0x82, 0x88 },
1881 { 0x83, 0x8f },
1882 { 0x84, 0x96 },
1883 { 0x85, 0xa3 },
1884 { 0x86, 0xaf },
1885 { 0x87, 0xc4 },
1886 { 0x88, 0xd7 },
1887 { 0x89, 0xe8 },
1888
1889/* AGC and AEC parameters. Note we start by disabling those features,
1890 then turn them only after tweaking the values. */
Jean-François Moine21867802010-11-12 06:12:09 -03001891 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001892 | OV7670_COM8_AECSTEP
1893 | OV7670_COM8_BFILT },
Jean-François Moine21867802010-11-12 06:12:09 -03001894 { OV7670_R00_GAIN, 0x00 },
1895 { OV7670_R10_AECH, 0x00 },
1896 { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */
1897 { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
1898 { OV7670_RA5_BD50MAX, 0x05 },
1899 { OV7670_RAB_BD60MAX, 0x07 },
1900 { OV7670_R24_AEW, 0x95 },
1901 { OV7670_R25_AEB, 0x33 },
1902 { OV7670_R26_VPT, 0xe3 },
1903 { OV7670_R9F_HAECC1, 0x78 },
1904 { OV7670_RA0_HAECC2, 0x68 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001905 { 0xa1, 0x03 }, /* magic */
Jean-François Moine21867802010-11-12 06:12:09 -03001906 { OV7670_RA6_HAECC3, 0xd8 },
1907 { OV7670_RA7_HAECC4, 0xd8 },
1908 { OV7670_RA8_HAECC5, 0xf0 },
1909 { OV7670_RA9_HAECC6, 0x90 },
1910 { OV7670_RAA_HAECC7, 0x94 },
1911 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001912 | OV7670_COM8_AECSTEP
1913 | OV7670_COM8_BFILT
1914 | OV7670_COM8_AGC
1915 | OV7670_COM8_AEC },
1916
1917/* Almost all of these are magic "reserved" values. */
Jean-François Moine21867802010-11-12 06:12:09 -03001918 { OV7670_R0E_COM5, 0x61 },
1919 { OV7670_R0F_COM6, 0x4b },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001920 { 0x16, 0x02 },
Jean-François Moine21867802010-11-12 06:12:09 -03001921 { OV7670_R1E_MVFP, 0x07 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001922 { 0x21, 0x02 },
1923 { 0x22, 0x91 },
1924 { 0x29, 0x07 },
1925 { 0x33, 0x0b },
1926 { 0x35, 0x0b },
1927 { 0x37, 0x1d },
1928 { 0x38, 0x71 },
1929 { 0x39, 0x2a },
Jean-François Moine21867802010-11-12 06:12:09 -03001930 { OV7670_R3C_COM12, 0x78 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001931 { 0x4d, 0x40 },
1932 { 0x4e, 0x20 },
Jean-François Moine21867802010-11-12 06:12:09 -03001933 { OV7670_R69_GFIX, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001934 { 0x6b, 0x4a },
1935 { 0x74, 0x10 },
1936 { 0x8d, 0x4f },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001937 { 0x8e, 0x00 },
1938 { 0x8f, 0x00 },
1939 { 0x90, 0x00 },
1940 { 0x91, 0x00 },
1941 { 0x96, 0x00 },
1942 { 0x9a, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001943 { 0xb0, 0x84 },
1944 { 0xb1, 0x0c },
1945 { 0xb2, 0x0e },
1946 { 0xb3, 0x82 },
1947 { 0xb8, 0x0a },
1948
1949/* More reserved magic, some of which tweaks white balance */
1950 { 0x43, 0x0a },
1951 { 0x44, 0xf0 },
1952 { 0x45, 0x34 },
1953 { 0x46, 0x58 },
1954 { 0x47, 0x28 },
1955 { 0x48, 0x3a },
1956 { 0x59, 0x88 },
1957 { 0x5a, 0x88 },
1958 { 0x5b, 0x44 },
1959 { 0x5c, 0x67 },
1960 { 0x5d, 0x49 },
1961 { 0x5e, 0x0e },
1962 { 0x6c, 0x0a },
1963 { 0x6d, 0x55 },
1964 { 0x6e, 0x11 },
Jean-François Moinefc63de882011-01-13 05:35:18 -03001965 { 0x6f, 0x9f }, /* "9e for advance AWB" */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001966 { 0x6a, 0x40 },
Jean-François Moine21867802010-11-12 06:12:09 -03001967 { OV7670_R01_BLUE, 0x40 },
1968 { OV7670_R02_RED, 0x60 },
1969 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001970 | OV7670_COM8_AECSTEP
1971 | OV7670_COM8_BFILT
1972 | OV7670_COM8_AGC
1973 | OV7670_COM8_AEC
1974 | OV7670_COM8_AWB },
1975
1976/* Matrix coefficients */
1977 { 0x4f, 0x80 },
1978 { 0x50, 0x80 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001979 { 0x51, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001980 { 0x52, 0x22 },
1981 { 0x53, 0x5e },
1982 { 0x54, 0x80 },
1983 { 0x58, 0x9e },
1984
Jean-François Moine21867802010-11-12 06:12:09 -03001985 { OV7670_R41_COM16, OV7670_COM16_AWBGAIN },
1986 { OV7670_R3F_EDGE, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001987 { 0x75, 0x05 },
1988 { 0x76, 0xe1 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001989 { 0x4c, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001990 { 0x77, 0x01 },
Jean-François Moine21867802010-11-12 06:12:09 -03001991 { OV7670_R3D_COM13, OV7670_COM13_GAMMA
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001992 | OV7670_COM13_UVSAT
1993 | 2}, /* was 3 */
1994 { 0x4b, 0x09 },
1995 { 0xc9, 0x60 },
Jean-François Moine21867802010-11-12 06:12:09 -03001996 { OV7670_R41_COM16, 0x38 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001997 { 0x56, 0x40 },
1998
1999 { 0x34, 0x11 },
Jean-François Moine21867802010-11-12 06:12:09 -03002000 { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002001 { 0xa4, 0x88 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002002 { 0x96, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002003 { 0x97, 0x30 },
2004 { 0x98, 0x20 },
2005 { 0x99, 0x30 },
2006 { 0x9a, 0x84 },
2007 { 0x9b, 0x29 },
2008 { 0x9c, 0x03 },
2009 { 0x9d, 0x4c },
2010 { 0x9e, 0x3f },
2011 { 0x78, 0x04 },
2012
2013/* Extra-weird stuff. Some sort of multiplexor register */
2014 { 0x79, 0x01 },
2015 { 0xc8, 0xf0 },
2016 { 0x79, 0x0f },
2017 { 0xc8, 0x00 },
2018 { 0x79, 0x10 },
2019 { 0xc8, 0x7e },
2020 { 0x79, 0x0a },
2021 { 0xc8, 0x80 },
2022 { 0x79, 0x0b },
2023 { 0xc8, 0x01 },
2024 { 0x79, 0x0c },
2025 { 0xc8, 0x0f },
2026 { 0x79, 0x0d },
2027 { 0xc8, 0x20 },
2028 { 0x79, 0x09 },
2029 { 0xc8, 0x80 },
2030 { 0x79, 0x02 },
2031 { 0xc8, 0xc0 },
2032 { 0x79, 0x03 },
2033 { 0xc8, 0x40 },
2034 { 0x79, 0x05 },
2035 { 0xc8, 0x30 },
2036 { 0x79, 0x26 },
2037};
2038
2039static const struct ov_i2c_regvals norm_8610[] = {
2040 { 0x12, 0x80 },
2041 { 0x00, 0x00 },
2042 { 0x01, 0x80 },
2043 { 0x02, 0x80 },
2044 { 0x03, 0xc0 },
2045 { 0x04, 0x30 },
2046 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
2047 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
2048 { 0x0a, 0x86 },
2049 { 0x0b, 0xb0 },
2050 { 0x0c, 0x20 },
2051 { 0x0d, 0x20 },
2052 { 0x11, 0x01 },
2053 { 0x12, 0x25 },
2054 { 0x13, 0x01 },
2055 { 0x14, 0x04 },
2056 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
2057 { 0x16, 0x03 },
2058 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
2059 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
2060 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
2061 { 0x1a, 0xf5 },
2062 { 0x1b, 0x00 },
2063 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
2064 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
2065 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
2066 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
2067 { 0x26, 0xa2 },
2068 { 0x27, 0xea },
2069 { 0x28, 0x00 },
2070 { 0x29, 0x00 },
2071 { 0x2a, 0x80 },
2072 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
2073 { 0x2c, 0xac },
2074 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
2075 { 0x2e, 0x80 },
2076 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
2077 { 0x4c, 0x00 },
2078 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
2079 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
2080 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
2081 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
2082 { 0x63, 0xff },
2083 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
2084 * maybe thats wrong */
2085 { 0x65, 0x00 },
2086 { 0x66, 0x55 },
2087 { 0x67, 0xb0 },
2088 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
2089 { 0x69, 0x02 },
2090 { 0x6a, 0x22 },
2091 { 0x6b, 0x00 },
2092 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
2093 * deleting bit7 colors the first images red */
2094 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
2095 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
2096 { 0x6f, 0x01 },
2097 { 0x70, 0x8b },
2098 { 0x71, 0x00 },
2099 { 0x72, 0x14 },
2100 { 0x73, 0x54 },
2101 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
2102 { 0x75, 0x0e },
2103 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
2104 { 0x77, 0xff },
2105 { 0x78, 0x80 },
2106 { 0x79, 0x80 },
2107 { 0x7a, 0x80 },
2108 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
2109 { 0x7c, 0x00 },
2110 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
2111 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
2112 { 0x7f, 0xfb },
2113 { 0x80, 0x28 },
2114 { 0x81, 0x00 },
2115 { 0x82, 0x23 },
2116 { 0x83, 0x0b },
2117 { 0x84, 0x00 },
2118 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
2119 { 0x86, 0xc9 },
2120 { 0x87, 0x00 },
2121 { 0x88, 0x00 },
2122 { 0x89, 0x01 },
2123 { 0x12, 0x20 },
2124 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
2125};
2126
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002127static unsigned char ov7670_abs_to_sm(unsigned char v)
2128{
2129 if (v > 127)
2130 return v & 0x7f;
2131 return (128 - v) | 0x80;
2132}
2133
2134/* Write a OV519 register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002135static void reg_w(struct sd *sd, u16 index, u16 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002136{
Hans de Goedea511ba92009-10-16 07:13:07 -03002137 int ret, req = 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002138
Jean-François Moinef8f20182010-11-12 07:54:02 -03002139 if (sd->gspca_dev.usb_err < 0)
2140 return;
2141
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002142 switch (sd->bridge) {
2143 case BRIDGE_OV511:
2144 case BRIDGE_OV511PLUS:
2145 req = 2;
2146 break;
2147 case BRIDGE_OVFX2:
Hans de Goedea511ba92009-10-16 07:13:07 -03002148 req = 0x0a;
2149 /* fall through */
2150 case BRIDGE_W9968CF:
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002151 PDEBUG(D_USBO, "SET %02x %04x %04x",
2152 req, value, index);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002153 ret = usb_control_msg(sd->gspca_dev.dev,
2154 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goedea511ba92009-10-16 07:13:07 -03002155 req,
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002156 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Hans de Goedea511ba92009-10-16 07:13:07 -03002157 value, index, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002158 goto leave;
2159 default:
2160 req = 1;
2161 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002162
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002163 PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
2164 req, index, value);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002165 sd->gspca_dev.usb_buf[0] = value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002166 ret = usb_control_msg(sd->gspca_dev.dev,
2167 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03002168 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002169 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2170 0, index,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002171 sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002172leave:
Hans de Goedea511ba92009-10-16 07:13:07 -03002173 if (ret < 0) {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002174 err("reg_w %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002175 sd->gspca_dev.usb_err = ret;
2176 return;
Hans de Goedea511ba92009-10-16 07:13:07 -03002177 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002178}
2179
Hans de Goedea511ba92009-10-16 07:13:07 -03002180/* Read from a OV519 register, note not valid for the w9968cf!! */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002181/* returns: negative is error, pos or zero is data */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002182static int reg_r(struct sd *sd, u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002183{
2184 int ret;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002185 int req;
2186
Jean-François Moinef8f20182010-11-12 07:54:02 -03002187 if (sd->gspca_dev.usb_err < 0)
2188 return -1;
2189
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002190 switch (sd->bridge) {
2191 case BRIDGE_OV511:
2192 case BRIDGE_OV511PLUS:
2193 req = 3;
2194 break;
2195 case BRIDGE_OVFX2:
2196 req = 0x0b;
2197 break;
2198 default:
2199 req = 1;
2200 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002201
2202 ret = usb_control_msg(sd->gspca_dev.dev,
2203 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03002204 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002205 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002206 0, index, sd->gspca_dev.usb_buf, 1, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002207
Hans de Goedea511ba92009-10-16 07:13:07 -03002208 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002209 ret = sd->gspca_dev.usb_buf[0];
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002210 PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
2211 req, index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002212 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002213 err("reg_r %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002214 sd->gspca_dev.usb_err = ret;
2215 }
Hans de Goedea511ba92009-10-16 07:13:07 -03002216
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002217 return ret;
2218}
2219
2220/* Read 8 values from a OV519 register */
2221static int reg_r8(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002222 u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002223{
2224 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002225
Jean-François Moinef8f20182010-11-12 07:54:02 -03002226 if (sd->gspca_dev.usb_err < 0)
2227 return -1;
2228
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002229 ret = usb_control_msg(sd->gspca_dev.dev,
2230 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2231 1, /* REQ_IO */
2232 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002233 0, index, sd->gspca_dev.usb_buf, 8, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002234
Jean-François Moinef8f20182010-11-12 07:54:02 -03002235 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002236 ret = sd->gspca_dev.usb_buf[0];
Jean-François Moinef8f20182010-11-12 07:54:02 -03002237 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002238 err("reg_r8 %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002239 sd->gspca_dev.usb_err = ret;
2240 }
Hans de Goedea511ba92009-10-16 07:13:07 -03002241
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002242 return ret;
2243}
2244
2245/*
2246 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
2247 * the same position as 1's in "mask" are cleared and set to "value". Bits
2248 * that are in the same position as 0's in "mask" are preserved, regardless
2249 * of their respective state in "value".
2250 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002251static void reg_w_mask(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002252 u16 index,
2253 u8 value,
2254 u8 mask)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002255{
2256 int ret;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002257 u8 oldval;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002258
2259 if (mask != 0xff) {
2260 value &= mask; /* Enforce mask on value */
2261 ret = reg_r(sd, index);
2262 if (ret < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002263 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002264
2265 oldval = ret & ~mask; /* Clear the masked bits */
2266 value |= oldval; /* Set the desired bits */
2267 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03002268 reg_w(sd, index, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002269}
2270
2271/*
Hans de Goede49809d62009-06-07 12:10:39 -03002272 * Writes multiple (n) byte value to a single register. Only valid with certain
2273 * registers (0x30 and 0xc4 - 0xce).
2274 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002275static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
Hans de Goede49809d62009-06-07 12:10:39 -03002276{
2277 int ret;
2278
Jean-François Moinef8f20182010-11-12 07:54:02 -03002279 if (sd->gspca_dev.usb_err < 0)
2280 return;
2281
Jean-Francois Moine83955552009-12-12 06:58:01 -03002282 *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
Hans de Goede49809d62009-06-07 12:10:39 -03002283
2284 ret = usb_control_msg(sd->gspca_dev.dev,
2285 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2286 1 /* REG_IO */,
2287 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2288 0, index,
2289 sd->gspca_dev.usb_buf, n, 500);
Hans de Goedea511ba92009-10-16 07:13:07 -03002290 if (ret < 0) {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002291 err("reg_w32 %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002292 sd->gspca_dev.usb_err = ret;
Hans de Goedea511ba92009-10-16 07:13:07 -03002293 }
Hans de Goede49809d62009-06-07 12:10:39 -03002294}
2295
Jean-François Moinef8f20182010-11-12 07:54:02 -03002296static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goede1876bb92009-06-14 06:45:50 -03002297{
2298 int rc, retries;
2299
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002300 PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002301
2302 /* Three byte write cycle */
2303 for (retries = 6; ; ) {
2304 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002305 reg_w(sd, R51x_I2C_SADDR_3, reg);
Hans de Goede1876bb92009-06-14 06:45:50 -03002306
2307 /* Write "value" to I2C data port of OV511 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002308 reg_w(sd, R51x_I2C_DATA, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002309
2310 /* Initiate 3-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002311 reg_w(sd, R511_I2C_CTL, 0x01);
Hans de Goede1876bb92009-06-14 06:45:50 -03002312
Jean-Francois Moine83955552009-12-12 06:58:01 -03002313 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002314 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002315 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002316
2317 if (rc < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002318 return;
Hans de Goede1876bb92009-06-14 06:45:50 -03002319
2320 if ((rc & 2) == 0) /* Ack? */
2321 break;
2322 if (--retries < 0) {
2323 PDEBUG(D_USBO, "i2c write retries exhausted");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002324 return;
Hans de Goede1876bb92009-06-14 06:45:50 -03002325 }
2326 }
Hans de Goede1876bb92009-06-14 06:45:50 -03002327}
2328
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002329static int ov511_i2c_r(struct sd *sd, u8 reg)
Hans de Goede1876bb92009-06-14 06:45:50 -03002330{
2331 int rc, value, retries;
2332
2333 /* Two byte write cycle */
2334 for (retries = 6; ; ) {
2335 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002336 reg_w(sd, R51x_I2C_SADDR_2, reg);
Hans de Goede1876bb92009-06-14 06:45:50 -03002337
2338 /* Initiate 2-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002339 reg_w(sd, R511_I2C_CTL, 0x03);
Hans de Goede1876bb92009-06-14 06:45:50 -03002340
Jean-Francois Moine83955552009-12-12 06:58:01 -03002341 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002342 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002343 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002344
2345 if (rc < 0)
2346 return rc;
2347
2348 if ((rc & 2) == 0) /* Ack? */
2349 break;
2350
2351 /* I2C abort */
2352 reg_w(sd, R511_I2C_CTL, 0x10);
2353
2354 if (--retries < 0) {
2355 PDEBUG(D_USBI, "i2c write retries exhausted");
2356 return -1;
2357 }
2358 }
2359
2360 /* Two byte read cycle */
2361 for (retries = 6; ; ) {
2362 /* Initiate 2-byte read cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002363 reg_w(sd, R511_I2C_CTL, 0x05);
Hans de Goede1876bb92009-06-14 06:45:50 -03002364
Jean-Francois Moine83955552009-12-12 06:58:01 -03002365 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002366 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002367 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002368
2369 if (rc < 0)
2370 return rc;
2371
2372 if ((rc & 2) == 0) /* Ack? */
2373 break;
2374
2375 /* I2C abort */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002376 reg_w(sd, R511_I2C_CTL, 0x10);
Hans de Goede1876bb92009-06-14 06:45:50 -03002377
2378 if (--retries < 0) {
2379 PDEBUG(D_USBI, "i2c read retries exhausted");
2380 return -1;
2381 }
2382 }
2383
2384 value = reg_r(sd, R51x_I2C_DATA);
2385
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002386 PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002387
2388 /* This is needed to make i2c_w() work */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002389 reg_w(sd, R511_I2C_CTL, 0x05);
Hans de Goede1876bb92009-06-14 06:45:50 -03002390
2391 return value;
2392}
Hans de Goede49809d62009-06-07 12:10:39 -03002393
2394/*
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002395 * The OV518 I2C I/O procedure is different, hence, this function.
2396 * This is normally only called from i2c_w(). Note that this function
2397 * always succeeds regardless of whether the sensor is present and working.
2398 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002399static void ov518_i2c_w(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002400 u8 reg,
2401 u8 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002402{
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002403 PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002404
2405 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002406 reg_w(sd, R51x_I2C_SADDR_3, reg);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002407
2408 /* Write "value" to I2C data port of OV511 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002409 reg_w(sd, R51x_I2C_DATA, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002410
2411 /* Initiate 3-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002412 reg_w(sd, R518_I2C_CTL, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002413
2414 /* wait for write complete */
2415 msleep(4);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002416 reg_r8(sd, R518_I2C_CTL);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002417}
2418
2419/*
2420 * returns: negative is error, pos or zero is data
2421 *
2422 * The OV518 I2C I/O procedure is different, hence, this function.
2423 * This is normally only called from i2c_r(). Note that this function
2424 * always succeeds regardless of whether the sensor is present and working.
2425 */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002426static int ov518_i2c_r(struct sd *sd, u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002427{
Jean-François Moinef8f20182010-11-12 07:54:02 -03002428 int value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002429
2430 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002431 reg_w(sd, R51x_I2C_SADDR_2, reg);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002432
2433 /* Initiate 2-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002434 reg_w(sd, R518_I2C_CTL, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002435
2436 /* Initiate 2-byte read cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002437 reg_w(sd, R518_I2C_CTL, 0x05);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002438 value = reg_r(sd, R51x_I2C_DATA);
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002439 PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002440 return value;
2441}
2442
Jean-François Moinef8f20182010-11-12 07:54:02 -03002443static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002444{
2445 int ret;
2446
Jean-François Moinef8f20182010-11-12 07:54:02 -03002447 if (sd->gspca_dev.usb_err < 0)
2448 return;
2449
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002450 ret = usb_control_msg(sd->gspca_dev.dev,
2451 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2452 0x02,
2453 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002454 (u16) value, (u16) reg, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002455
Hans de Goedea511ba92009-10-16 07:13:07 -03002456 if (ret < 0) {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002457 err("ovfx2_i2c_w %02x failed %d", reg, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002458 sd->gspca_dev.usb_err = ret;
Hans de Goedea511ba92009-10-16 07:13:07 -03002459 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002460
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002461 PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002462}
2463
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002464static int ovfx2_i2c_r(struct sd *sd, u8 reg)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002465{
2466 int ret;
2467
Jean-François Moinef8f20182010-11-12 07:54:02 -03002468 if (sd->gspca_dev.usb_err < 0)
2469 return -1;
2470
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002471 ret = usb_control_msg(sd->gspca_dev.dev,
2472 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2473 0x03,
2474 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002475 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002476
2477 if (ret >= 0) {
2478 ret = sd->gspca_dev.usb_buf[0];
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002479 PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002480 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002481 err("ovfx2_i2c_r %02x failed %d", reg, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002482 sd->gspca_dev.usb_err = ret;
2483 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002484
2485 return ret;
2486}
2487
Jean-François Moinef8f20182010-11-12 07:54:02 -03002488static void i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goede1876bb92009-06-14 06:45:50 -03002489{
Hans de Goedefb1f9022009-10-16 07:42:53 -03002490 if (sd->sensor_reg_cache[reg] == value)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002491 return;
Hans de Goedefb1f9022009-10-16 07:42:53 -03002492
Hans de Goede1876bb92009-06-14 06:45:50 -03002493 switch (sd->bridge) {
2494 case BRIDGE_OV511:
2495 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002496 ov511_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002497 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002498 case BRIDGE_OV518:
2499 case BRIDGE_OV518PLUS:
2500 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002501 ov518_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002502 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002503 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002504 ovfx2_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002505 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002506 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002507 w9968cf_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002508 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002509 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002510
Jean-François Moinef8f20182010-11-12 07:54:02 -03002511 if (sd->gspca_dev.usb_err >= 0) {
Hans de Goedefb1f9022009-10-16 07:42:53 -03002512 /* Up on sensor reset empty the register cache */
2513 if (reg == 0x12 && (value & 0x80))
2514 memset(sd->sensor_reg_cache, -1,
Jean-François Moine87bae742010-11-12 05:31:34 -03002515 sizeof(sd->sensor_reg_cache));
Hans de Goedefb1f9022009-10-16 07:42:53 -03002516 else
2517 sd->sensor_reg_cache[reg] = value;
2518 }
Hans de Goede1876bb92009-06-14 06:45:50 -03002519}
2520
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002521static int i2c_r(struct sd *sd, u8 reg)
Hans de Goede1876bb92009-06-14 06:45:50 -03002522{
Hans de Goede8394bcf2009-10-16 11:26:22 -03002523 int ret = -1;
Hans de Goedefb1f9022009-10-16 07:42:53 -03002524
2525 if (sd->sensor_reg_cache[reg] != -1)
2526 return sd->sensor_reg_cache[reg];
2527
Hans de Goede1876bb92009-06-14 06:45:50 -03002528 switch (sd->bridge) {
2529 case BRIDGE_OV511:
2530 case BRIDGE_OV511PLUS:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002531 ret = ov511_i2c_r(sd, reg);
2532 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002533 case BRIDGE_OV518:
2534 case BRIDGE_OV518PLUS:
2535 case BRIDGE_OV519:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002536 ret = ov518_i2c_r(sd, reg);
2537 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002538 case BRIDGE_OVFX2:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002539 ret = ovfx2_i2c_r(sd, reg);
2540 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002541 case BRIDGE_W9968CF:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002542 ret = w9968cf_i2c_r(sd, reg);
2543 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002544 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002545
2546 if (ret >= 0)
2547 sd->sensor_reg_cache[reg] = ret;
2548
2549 return ret;
Hans de Goede1876bb92009-06-14 06:45:50 -03002550}
2551
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002552/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
2553 * the same position as 1's in "mask" are cleared and set to "value". Bits
2554 * that are in the same position as 0's in "mask" are preserved, regardless
2555 * of their respective state in "value".
2556 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002557static void i2c_w_mask(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002558 u8 reg,
2559 u8 value,
2560 u8 mask)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002561{
2562 int rc;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002563 u8 oldval;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002564
2565 value &= mask; /* Enforce mask on value */
2566 rc = i2c_r(sd, reg);
2567 if (rc < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002568 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002569 oldval = rc & ~mask; /* Clear the masked bits */
2570 value |= oldval; /* Set the desired bits */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002571 i2c_w(sd, reg, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002572}
2573
2574/* Temporarily stops OV511 from functioning. Must do this before changing
2575 * registers while the camera is streaming */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002576static inline void ov51x_stop(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002577{
2578 PDEBUG(D_STREAM, "stopping");
2579 sd->stopped = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03002580 switch (sd->bridge) {
2581 case BRIDGE_OV511:
2582 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002583 reg_w(sd, R51x_SYS_RESET, 0x3d);
2584 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002585 case BRIDGE_OV518:
2586 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002587 reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
2588 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002589 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002590 reg_w(sd, OV519_R51_RESET1, 0x0f);
Jean-François Moine5927abc2010-11-12 15:32:29 -03002591 reg_w(sd, OV519_R51_RESET1, 0x00);
2592 reg_w(sd, 0x22, 0x00); /* FRAR */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002593 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002594 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002595 reg_w_mask(sd, 0x0f, 0x00, 0x02);
2596 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002597 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002598 reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
2599 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002600 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002601}
2602
2603/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
2604 * actually stopped (for performance). */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002605static inline void ov51x_restart(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002606{
2607 PDEBUG(D_STREAM, "restarting");
2608 if (!sd->stopped)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002609 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002610 sd->stopped = 0;
2611
2612 /* Reinitialize the stream */
Hans de Goede49809d62009-06-07 12:10:39 -03002613 switch (sd->bridge) {
2614 case BRIDGE_OV511:
2615 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002616 reg_w(sd, R51x_SYS_RESET, 0x00);
2617 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002618 case BRIDGE_OV518:
2619 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002620 reg_w(sd, 0x2f, 0x80);
2621 reg_w(sd, R51x_SYS_RESET, 0x00);
2622 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002623 case BRIDGE_OV519:
Jean-François Moine5927abc2010-11-12 15:32:29 -03002624 reg_w(sd, OV519_R51_RESET1, 0x0f);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002625 reg_w(sd, OV519_R51_RESET1, 0x00);
Jean-François Moine5927abc2010-11-12 15:32:29 -03002626 reg_w(sd, 0x22, 0x1d); /* FRAR */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002627 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002628 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002629 reg_w_mask(sd, 0x0f, 0x02, 0x02);
2630 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002631 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002632 reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
2633 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002634 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002635}
2636
Jean-François Moinef8f20182010-11-12 07:54:02 -03002637static void ov51x_set_slave_ids(struct sd *sd, u8 slave);
Hans de Goede229bb7d2009-10-11 07:41:46 -03002638
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002639/* This does an initial reset of an OmniVision sensor and ensures that I2C
2640 * is synchronized. Returns <0 on failure.
2641 */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002642static int init_ov_sensor(struct sd *sd, u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002643{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002644 int i;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002645
Jean-François Moinef8f20182010-11-12 07:54:02 -03002646 ov51x_set_slave_ids(sd, slave);
Hans de Goede229bb7d2009-10-11 07:41:46 -03002647
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002648 /* Reset the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002649 i2c_w(sd, 0x12, 0x80);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002650
2651 /* Wait for it to initialize */
2652 msleep(150);
2653
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002654 for (i = 0; i < i2c_detect_tries; i++) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002655 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
2656 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002657 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
2658 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002659 }
2660
2661 /* Reset the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002662 i2c_w(sd, 0x12, 0x80);
2663
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002664 /* Wait for it to initialize */
2665 msleep(150);
Jean-François Moine87bae742010-11-12 05:31:34 -03002666
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002667 /* Dummy read to sync I2C */
2668 if (i2c_r(sd, 0x00) < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002669 return -1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002670 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03002671 return -1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002672}
2673
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002674/* Set the read and write slave IDs. The "slave" argument is the write slave,
2675 * and the read slave will be set to (slave + 1).
2676 * This should not be called from outside the i2c I/O functions.
2677 * Sets I2C read and write slave IDs. Returns <0 for error
2678 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002679static void ov51x_set_slave_ids(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002680 u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002681{
Hans de Goedea511ba92009-10-16 07:13:07 -03002682 switch (sd->bridge) {
2683 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002684 reg_w(sd, OVFX2_I2C_ADDR, slave);
2685 return;
Hans de Goedea511ba92009-10-16 07:13:07 -03002686 case BRIDGE_W9968CF:
2687 sd->sensor_addr = slave;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002688 return;
Hans de Goedea511ba92009-10-16 07:13:07 -03002689 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002690
Jean-François Moinef8f20182010-11-12 07:54:02 -03002691 reg_w(sd, R51x_I2C_W_SID, slave);
2692 reg_w(sd, R51x_I2C_R_SID, slave + 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002693}
2694
Jean-François Moinef8f20182010-11-12 07:54:02 -03002695static void write_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002696 const struct ov_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002697 int n)
2698{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002699 while (--n >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03002700 reg_w(sd, regvals->reg, regvals->val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002701 regvals++;
2702 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002703}
2704
Jean-François Moinef8f20182010-11-12 07:54:02 -03002705static void write_i2c_regvals(struct sd *sd,
2706 const struct ov_i2c_regvals *regvals,
2707 int n)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002708{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002709 while (--n >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03002710 i2c_w(sd, regvals->reg, regvals->val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002711 regvals++;
2712 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002713}
2714
2715/****************************************************************************
2716 *
2717 * OV511 and sensor configuration
2718 *
2719 ***************************************************************************/
2720
Jean-François Moine798ae152011-05-23 05:38:10 -03002721/* This initializes the OV2x10 / OV3610 / OV3620 / OV9600 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002722static void ov_hires_configure(struct sd *sd)
Hans de Goede635118d2009-10-11 09:49:03 -03002723{
2724 int high, low;
2725
2726 if (sd->bridge != BRIDGE_OVFX2) {
Jean-François Moine0b656322010-09-13 05:19:58 -03002727 err("error hires sensors only supported with ovfx2");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002728 return;
Hans de Goede635118d2009-10-11 09:49:03 -03002729 }
2730
2731 PDEBUG(D_PROBE, "starting ov hires configuration");
2732
2733 /* Detect sensor (sub)type */
2734 high = i2c_r(sd, 0x0a);
2735 low = i2c_r(sd, 0x0b);
2736 /* info("%x, %x", high, low); */
Jean-François Moine798ae152011-05-23 05:38:10 -03002737 switch (high) {
2738 case 0x96:
2739 switch (low) {
2740 case 0x40:
2741 PDEBUG(D_PROBE, "Sensor is a OV2610");
2742 sd->sensor = SEN_OV2610;
2743 return;
2744 case 0x41:
2745 PDEBUG(D_PROBE, "Sensor is a OV2610AE");
2746 sd->sensor = SEN_OV2610AE;
2747 return;
2748 case 0xb1:
2749 PDEBUG(D_PROBE, "Sensor is a OV9600");
2750 sd->sensor = SEN_OV9600;
2751 return;
2752 }
2753 break;
2754 case 0x36:
2755 if ((low & 0x0f) == 0x00) {
2756 PDEBUG(D_PROBE, "Sensor is a OV3610");
2757 sd->sensor = SEN_OV3610;
2758 return;
2759 }
2760 break;
Hans de Goede635118d2009-10-11 09:49:03 -03002761 }
Jean-François Moine798ae152011-05-23 05:38:10 -03002762 err("Error unknown sensor type: %02x%02x", high, low);
Hans de Goede635118d2009-10-11 09:49:03 -03002763}
2764
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002765/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
2766 * the same register settings as the OV8610, since they are very similar.
2767 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002768static void ov8xx0_configure(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002769{
2770 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002771
2772 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
2773
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002774 /* Detect sensor (sub)type */
2775 rc = i2c_r(sd, OV7610_REG_COM_I);
2776 if (rc < 0) {
2777 PDEBUG(D_ERR, "Error detecting sensor type");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002778 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002779 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03002780 if ((rc & 3) == 1)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002781 sd->sensor = SEN_OV8610;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002782 else
Jean-François Moine0b656322010-09-13 05:19:58 -03002783 err("Unknown image sensor version: %d", rc & 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002784}
2785
2786/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
2787 * the same register settings as the OV7610, since they are very similar.
2788 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002789static void ov7xx0_configure(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002790{
2791 int rc, high, low;
2792
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002793 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
2794
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002795 /* Detect sensor (sub)type */
2796 rc = i2c_r(sd, OV7610_REG_COM_I);
2797
2798 /* add OV7670 here
2799 * it appears to be wrongly detected as a 7610 by default */
2800 if (rc < 0) {
2801 PDEBUG(D_ERR, "Error detecting sensor type");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002802 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002803 }
2804 if ((rc & 3) == 3) {
2805 /* quick hack to make OV7670s work */
2806 high = i2c_r(sd, 0x0a);
2807 low = i2c_r(sd, 0x0b);
2808 /* info("%x, %x", high, low); */
Jean-François Moine7a5a4142010-12-25 13:58:45 -03002809 if (high == 0x76 && (low & 0xf0) == 0x70) {
2810 PDEBUG(D_PROBE, "Sensor is an OV76%02x", low);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002811 sd->sensor = SEN_OV7670;
2812 } else {
2813 PDEBUG(D_PROBE, "Sensor is an OV7610");
2814 sd->sensor = SEN_OV7610;
2815 }
2816 } else if ((rc & 3) == 1) {
2817 /* I don't know what's different about the 76BE yet. */
Hans de Goedeb282d872009-06-14 19:10:40 -03002818 if (i2c_r(sd, 0x15) & 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002819 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
Hans de Goede859cc472010-01-07 15:42:35 -03002820 sd->sensor = SEN_OV7620AE;
Hans de Goedeb282d872009-06-14 19:10:40 -03002821 } else {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002822 PDEBUG(D_PROBE, "Sensor is an OV76BE");
Hans de Goedeb282d872009-06-14 19:10:40 -03002823 sd->sensor = SEN_OV76BE;
2824 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002825 } else if ((rc & 3) == 0) {
2826 /* try to read product id registers */
2827 high = i2c_r(sd, 0x0a);
2828 if (high < 0) {
2829 PDEBUG(D_ERR, "Error detecting camera chip PID");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002830 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002831 }
2832 low = i2c_r(sd, 0x0b);
2833 if (low < 0) {
2834 PDEBUG(D_ERR, "Error detecting camera chip VER");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002835 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002836 }
2837 if (high == 0x76) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002838 switch (low) {
2839 case 0x30:
Jean-François Moine0b656322010-09-13 05:19:58 -03002840 err("Sensor is an OV7630/OV7635");
2841 err("7630 is not supported by this driver");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002842 return;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002843 case 0x40:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002844 PDEBUG(D_PROBE, "Sensor is an OV7645");
2845 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002846 break;
2847 case 0x45:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002848 PDEBUG(D_PROBE, "Sensor is an OV7645B");
2849 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002850 break;
2851 case 0x48:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002852 PDEBUG(D_PROBE, "Sensor is an OV7648");
Hans de Goede035d3a32010-01-09 08:14:43 -03002853 sd->sensor = SEN_OV7648;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002854 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03002855 case 0x60:
2856 PDEBUG(D_PROBE, "Sensor is a OV7660");
2857 sd->sensor = SEN_OV7660;
2858 sd->invert_led = 0;
2859 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002860 default:
2861 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002862 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002863 }
2864 } else {
2865 PDEBUG(D_PROBE, "Sensor is an OV7620");
2866 sd->sensor = SEN_OV7620;
2867 }
2868 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03002869 err("Unknown image sensor version: %d", rc & 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002870 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002871}
2872
2873/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002874static void ov6xx0_configure(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002875{
2876 int rc;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002877 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002878
2879 /* Detect sensor (sub)type */
2880 rc = i2c_r(sd, OV7610_REG_COM_I);
2881 if (rc < 0) {
2882 PDEBUG(D_ERR, "Error detecting sensor type");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002883 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002884 }
2885
2886 /* Ugh. The first two bits are the version bits, but
2887 * the entire register value must be used. I guess OVT
2888 * underestimated how many variants they would make. */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002889 switch (rc) {
2890 case 0x00:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002891 sd->sensor = SEN_OV6630;
Jean-François Moine0b656322010-09-13 05:19:58 -03002892 warn("WARNING: Sensor is an OV66308. Your camera may have");
2893 warn("been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002894 break;
2895 case 0x01:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002896 sd->sensor = SEN_OV6620;
Hans de Goede7d971372009-06-14 05:28:17 -03002897 PDEBUG(D_PROBE, "Sensor is an OV6620");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002898 break;
2899 case 0x02:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002900 sd->sensor = SEN_OV6630;
2901 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002902 break;
2903 case 0x03:
Hans de Goede7d971372009-06-14 05:28:17 -03002904 sd->sensor = SEN_OV66308AF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002905 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002906 break;
2907 case 0x90:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002908 sd->sensor = SEN_OV6630;
Jean-François Moine0b656322010-09-13 05:19:58 -03002909 warn("WARNING: Sensor is an OV66307. Your camera may have");
2910 warn("been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002911 break;
2912 default:
Jean-François Moine0b656322010-09-13 05:19:58 -03002913 err("FATAL: Unknown sensor version: 0x%02x", rc);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002914 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002915 }
2916
2917 /* Set sensor-specific vars */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002918 sd->sif = 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002919}
2920
2921/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
2922static void ov51x_led_control(struct sd *sd, int on)
2923{
Hans de Goede9e4d8252009-06-14 06:25:06 -03002924 if (sd->invert_led)
2925 on = !on;
2926
Hans de Goede49809d62009-06-07 12:10:39 -03002927 switch (sd->bridge) {
2928 /* OV511 has no LED control */
2929 case BRIDGE_OV511PLUS:
Jean-François Moinea23acec2010-11-12 15:07:35 -03002930 reg_w(sd, R511_SYS_LED_CTL, on);
Hans de Goede49809d62009-06-07 12:10:39 -03002931 break;
2932 case BRIDGE_OV518:
2933 case BRIDGE_OV518PLUS:
Jean-François Moinea23acec2010-11-12 15:07:35 -03002934 reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02);
Hans de Goede49809d62009-06-07 12:10:39 -03002935 break;
2936 case BRIDGE_OV519:
Jean-François Moinea23acec2010-11-12 15:07:35 -03002937 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1);
Hans de Goede49809d62009-06-07 12:10:39 -03002938 break;
2939 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002940}
2941
Hans de Goede417a4d22010-02-19 07:37:08 -03002942static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
2943{
2944 struct sd *sd = (struct sd *) gspca_dev;
2945
2946 if (!sd->snapshot_needs_reset)
2947 return;
2948
2949 /* Note it is important that we clear sd->snapshot_needs_reset,
2950 before actually clearing the snapshot state in the bridge
2951 otherwise we might race with the pkt_scan interrupt handler */
2952 sd->snapshot_needs_reset = 0;
2953
2954 switch (sd->bridge) {
Hans de Goede88e8d202010-02-20 04:45:49 -03002955 case BRIDGE_OV511:
2956 case BRIDGE_OV511PLUS:
2957 reg_w(sd, R51x_SYS_SNAP, 0x02);
2958 reg_w(sd, R51x_SYS_SNAP, 0x00);
2959 break;
Hans de Goede92e232a2010-02-20 04:30:45 -03002960 case BRIDGE_OV518:
2961 case BRIDGE_OV518PLUS:
2962 reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
2963 reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
2964 break;
Hans de Goede417a4d22010-02-19 07:37:08 -03002965 case BRIDGE_OV519:
2966 reg_w(sd, R51x_SYS_RESET, 0x40);
2967 reg_w(sd, R51x_SYS_RESET, 0x00);
2968 break;
2969 }
2970}
2971
Jean-François Moinef8f20182010-11-12 07:54:02 -03002972static void ov51x_upload_quan_tables(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03002973{
Hans de Goede1876bb92009-06-14 06:45:50 -03002974 const unsigned char yQuanTable511[] = {
2975 0, 1, 1, 2, 2, 3, 3, 4,
2976 1, 1, 1, 2, 2, 3, 4, 4,
2977 1, 1, 2, 2, 3, 4, 4, 4,
2978 2, 2, 2, 3, 4, 4, 4, 4,
2979 2, 2, 3, 4, 4, 5, 5, 5,
2980 3, 3, 4, 4, 5, 5, 5, 5,
2981 3, 4, 4, 4, 5, 5, 5, 5,
2982 4, 4, 4, 4, 5, 5, 5, 5
2983 };
2984
2985 const unsigned char uvQuanTable511[] = {
2986 0, 2, 2, 3, 4, 4, 4, 4,
2987 2, 2, 2, 4, 4, 4, 4, 4,
2988 2, 2, 3, 4, 4, 4, 4, 4,
2989 3, 4, 4, 4, 4, 4, 4, 4,
2990 4, 4, 4, 4, 4, 4, 4, 4,
2991 4, 4, 4, 4, 4, 4, 4, 4,
2992 4, 4, 4, 4, 4, 4, 4, 4,
2993 4, 4, 4, 4, 4, 4, 4, 4
2994 };
2995
2996 /* OV518 quantization tables are 8x4 (instead of 8x8) */
Hans de Goede49809d62009-06-07 12:10:39 -03002997 const unsigned char yQuanTable518[] = {
2998 5, 4, 5, 6, 6, 7, 7, 7,
2999 5, 5, 5, 5, 6, 7, 7, 7,
3000 6, 6, 6, 6, 7, 7, 7, 8,
3001 7, 7, 6, 7, 7, 7, 8, 8
3002 };
Hans de Goede49809d62009-06-07 12:10:39 -03003003 const unsigned char uvQuanTable518[] = {
3004 6, 6, 6, 7, 7, 7, 7, 7,
3005 6, 6, 6, 7, 7, 7, 7, 7,
3006 6, 6, 6, 7, 7, 7, 7, 8,
3007 7, 7, 7, 7, 7, 7, 8, 8
3008 };
3009
Hans de Goede1876bb92009-06-14 06:45:50 -03003010 const unsigned char *pYTable, *pUVTable;
Hans de Goede49809d62009-06-07 12:10:39 -03003011 unsigned char val0, val1;
Jean-François Moinef8f20182010-11-12 07:54:02 -03003012 int i, size, reg = R51x_COMP_LUT_BEGIN;
Hans de Goede49809d62009-06-07 12:10:39 -03003013
3014 PDEBUG(D_PROBE, "Uploading quantization tables");
3015
Hans de Goede1876bb92009-06-14 06:45:50 -03003016 if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
3017 pYTable = yQuanTable511;
3018 pUVTable = uvQuanTable511;
Jean-François Moine87bae742010-11-12 05:31:34 -03003019 size = 32;
Hans de Goede1876bb92009-06-14 06:45:50 -03003020 } else {
3021 pYTable = yQuanTable518;
3022 pUVTable = uvQuanTable518;
Jean-François Moine87bae742010-11-12 05:31:34 -03003023 size = 16;
Hans de Goede1876bb92009-06-14 06:45:50 -03003024 }
3025
3026 for (i = 0; i < size; i++) {
Hans de Goede49809d62009-06-07 12:10:39 -03003027 val0 = *pYTable++;
3028 val1 = *pYTable++;
3029 val0 &= 0x0f;
3030 val1 &= 0x0f;
3031 val0 |= val1 << 4;
Jean-François Moinef8f20182010-11-12 07:54:02 -03003032 reg_w(sd, reg, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03003033
3034 val0 = *pUVTable++;
3035 val1 = *pUVTable++;
3036 val0 &= 0x0f;
3037 val1 &= 0x0f;
3038 val0 |= val1 << 4;
Jean-François Moinef8f20182010-11-12 07:54:02 -03003039 reg_w(sd, reg + size, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03003040
3041 reg++;
3042 }
Hans de Goede49809d62009-06-07 12:10:39 -03003043}
3044
Hans de Goede1876bb92009-06-14 06:45:50 -03003045/* This initializes the OV511/OV511+ and the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003046static void ov511_configure(struct gspca_dev *gspca_dev)
Hans de Goede1876bb92009-06-14 06:45:50 -03003047{
3048 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede1876bb92009-06-14 06:45:50 -03003049
3050 /* For 511 and 511+ */
3051 const struct ov_regvals init_511[] = {
3052 { R51x_SYS_RESET, 0x7f },
3053 { R51x_SYS_INIT, 0x01 },
3054 { R51x_SYS_RESET, 0x7f },
3055 { R51x_SYS_INIT, 0x01 },
3056 { R51x_SYS_RESET, 0x3f },
3057 { R51x_SYS_INIT, 0x01 },
3058 { R51x_SYS_RESET, 0x3d },
3059 };
3060
3061 const struct ov_regvals norm_511[] = {
Jean-François Moine780e3122010-10-19 04:29:10 -03003062 { R511_DRAM_FLOW_CTL, 0x01 },
Hans de Goede1876bb92009-06-14 06:45:50 -03003063 { R51x_SYS_SNAP, 0x00 },
3064 { R51x_SYS_SNAP, 0x02 },
3065 { R51x_SYS_SNAP, 0x00 },
3066 { R511_FIFO_OPTS, 0x1f },
3067 { R511_COMP_EN, 0x00 },
3068 { R511_COMP_LUT_EN, 0x03 },
3069 };
3070
3071 const struct ov_regvals norm_511_p[] = {
3072 { R511_DRAM_FLOW_CTL, 0xff },
3073 { R51x_SYS_SNAP, 0x00 },
3074 { R51x_SYS_SNAP, 0x02 },
3075 { R51x_SYS_SNAP, 0x00 },
3076 { R511_FIFO_OPTS, 0xff },
3077 { R511_COMP_EN, 0x00 },
3078 { R511_COMP_LUT_EN, 0x03 },
3079 };
3080
3081 const struct ov_regvals compress_511[] = {
3082 { 0x70, 0x1f },
3083 { 0x71, 0x05 },
3084 { 0x72, 0x06 },
3085 { 0x73, 0x06 },
3086 { 0x74, 0x14 },
3087 { 0x75, 0x03 },
3088 { 0x76, 0x04 },
3089 { 0x77, 0x04 },
3090 };
3091
3092 PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
3093
Jean-François Moinef8f20182010-11-12 07:54:02 -03003094 write_regvals(sd, init_511, ARRAY_SIZE(init_511));
Hans de Goede1876bb92009-06-14 06:45:50 -03003095
3096 switch (sd->bridge) {
3097 case BRIDGE_OV511:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003098 write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
Hans de Goede1876bb92009-06-14 06:45:50 -03003099 break;
3100 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003101 write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
Hans de Goede1876bb92009-06-14 06:45:50 -03003102 break;
3103 }
3104
3105 /* Init compression */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003106 write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
Hans de Goede1876bb92009-06-14 06:45:50 -03003107
Jean-François Moinef8f20182010-11-12 07:54:02 -03003108 ov51x_upload_quan_tables(sd);
Hans de Goede1876bb92009-06-14 06:45:50 -03003109}
3110
Hans de Goede49809d62009-06-07 12:10:39 -03003111/* This initializes the OV518/OV518+ and the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003112static void ov518_configure(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003113{
3114 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003115
Hans de Goede49809d62009-06-07 12:10:39 -03003116 /* For 518 and 518+ */
Hans de Goedee080fcd2009-06-18 05:03:16 -03003117 const struct ov_regvals init_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03003118 { R51x_SYS_RESET, 0x40 },
3119 { R51x_SYS_INIT, 0xe1 },
3120 { R51x_SYS_RESET, 0x3e },
3121 { R51x_SYS_INIT, 0xe1 },
3122 { R51x_SYS_RESET, 0x00 },
3123 { R51x_SYS_INIT, 0xe1 },
3124 { 0x46, 0x00 },
3125 { 0x5d, 0x03 },
3126 };
3127
Hans de Goedee080fcd2009-06-18 05:03:16 -03003128 const struct ov_regvals norm_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03003129 { R51x_SYS_SNAP, 0x02 }, /* Reset */
3130 { R51x_SYS_SNAP, 0x01 }, /* Enable */
Jean-François Moine780e3122010-10-19 04:29:10 -03003131 { 0x31, 0x0f },
Hans de Goede49809d62009-06-07 12:10:39 -03003132 { 0x5d, 0x03 },
3133 { 0x24, 0x9f },
3134 { 0x25, 0x90 },
3135 { 0x20, 0x00 },
3136 { 0x51, 0x04 },
3137 { 0x71, 0x19 },
3138 { 0x2f, 0x80 },
3139 };
3140
Hans de Goedee080fcd2009-06-18 05:03:16 -03003141 const struct ov_regvals norm_518_p[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03003142 { R51x_SYS_SNAP, 0x02 }, /* Reset */
3143 { R51x_SYS_SNAP, 0x01 }, /* Enable */
Jean-François Moine780e3122010-10-19 04:29:10 -03003144 { 0x31, 0x0f },
Hans de Goede49809d62009-06-07 12:10:39 -03003145 { 0x5d, 0x03 },
3146 { 0x24, 0x9f },
3147 { 0x25, 0x90 },
3148 { 0x20, 0x60 },
3149 { 0x51, 0x02 },
3150 { 0x71, 0x19 },
3151 { 0x40, 0xff },
3152 { 0x41, 0x42 },
3153 { 0x46, 0x00 },
3154 { 0x33, 0x04 },
3155 { 0x21, 0x19 },
3156 { 0x3f, 0x10 },
3157 { 0x2f, 0x80 },
3158 };
3159
3160 /* First 5 bits of custom ID reg are a revision ID on OV518 */
3161 PDEBUG(D_PROBE, "Device revision %d",
Jean-François Moine87bae742010-11-12 05:31:34 -03003162 0x1f & reg_r(sd, R51x_SYS_CUST_ID));
Hans de Goede49809d62009-06-07 12:10:39 -03003163
Jean-François Moinef8f20182010-11-12 07:54:02 -03003164 write_regvals(sd, init_518, ARRAY_SIZE(init_518));
Hans de Goede49809d62009-06-07 12:10:39 -03003165
3166 /* Set LED GPIO pin to output mode */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003167 reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
Hans de Goede49809d62009-06-07 12:10:39 -03003168
3169 switch (sd->bridge) {
3170 case BRIDGE_OV518:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003171 write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
Hans de Goede49809d62009-06-07 12:10:39 -03003172 break;
3173 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003174 write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
Hans de Goede49809d62009-06-07 12:10:39 -03003175 break;
3176 }
3177
Jean-François Moinef8f20182010-11-12 07:54:02 -03003178 ov51x_upload_quan_tables(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003179
Jean-François Moinef8f20182010-11-12 07:54:02 -03003180 reg_w(sd, 0x2f, 0x80);
Hans de Goede49809d62009-06-07 12:10:39 -03003181}
3182
Jean-François Moinef8f20182010-11-12 07:54:02 -03003183static void ov519_configure(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03003184{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003185 static const struct ov_regvals init_519[] = {
Jean-François Moine87bae742010-11-12 05:31:34 -03003186 { 0x5a, 0x6d }, /* EnableSystem */
Jean-François Moinefc63de882011-01-13 05:35:18 -03003187 { 0x53, 0x9b }, /* don't enable the microcontroller */
Jean-François Moine21867802010-11-12 06:12:09 -03003188 { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
Jean-François Moine87bae742010-11-12 05:31:34 -03003189 { 0x5d, 0x03 },
3190 { 0x49, 0x01 },
3191 { 0x48, 0x00 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003192 /* Set LED pin to output mode. Bit 4 must be cleared or sensor
3193 * detection will fail. This deserves further investigation. */
3194 { OV519_GPIO_IO_CTRL0, 0xee },
Jean-François Moine21867802010-11-12 06:12:09 -03003195 { OV519_R51_RESET1, 0x0f },
3196 { OV519_R51_RESET1, 0x00 },
Jean-François Moine87bae742010-11-12 05:31:34 -03003197 { 0x22, 0x00 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003198 /* windows reads 0x55 at this point*/
3199 };
3200
Jean-François Moinef8f20182010-11-12 07:54:02 -03003201 write_regvals(sd, init_519, ARRAY_SIZE(init_519));
Hans de Goede49809d62009-06-07 12:10:39 -03003202}
3203
Jean-François Moinef8f20182010-11-12 07:54:02 -03003204static void ovfx2_configure(struct sd *sd)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003205{
3206 static const struct ov_regvals init_fx2[] = {
3207 { 0x00, 0x60 },
3208 { 0x02, 0x01 },
3209 { 0x0f, 0x1d },
3210 { 0xe9, 0x82 },
3211 { 0xea, 0xc7 },
3212 { 0xeb, 0x10 },
3213 { 0xec, 0xf6 },
3214 };
3215
3216 sd->stopped = 1;
3217
Jean-François Moinef8f20182010-11-12 07:54:02 -03003218 write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003219}
3220
Jean-François Moine42e142f2010-11-13 05:10:27 -03003221/* set the mode */
3222/* This function works for ov7660 only */
3223static void ov519_set_mode(struct sd *sd)
3224{
3225 static const struct ov_regvals bridge_ov7660[2][10] = {
3226 {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
3227 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3228 {0x25, 0x01}, {0x26, 0x00}},
3229 {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
3230 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3231 {0x25, 0x03}, {0x26, 0x00}}
3232 };
3233 static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
3234 {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
3235 {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
3236 };
3237 static const struct ov_i2c_regvals sensor_ov7660_2[] = {
3238 {OV7670_R17_HSTART, 0x13},
3239 {OV7670_R18_HSTOP, 0x01},
3240 {OV7670_R32_HREF, 0x92},
3241 {OV7670_R19_VSTART, 0x02},
3242 {OV7670_R1A_VSTOP, 0x7a},
3243 {OV7670_R03_VREF, 0x00},
3244/* {0x33, 0x00}, */
3245/* {0x34, 0x07}, */
3246/* {0x36, 0x00}, */
3247/* {0x6b, 0x0a}, */
3248 };
3249
3250 write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
3251 ARRAY_SIZE(bridge_ov7660[0]));
3252 write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
3253 ARRAY_SIZE(sensor_ov7660[0]));
3254 write_i2c_regvals(sd, sensor_ov7660_2,
3255 ARRAY_SIZE(sensor_ov7660_2));
3256}
3257
3258/* set the frame rate */
3259/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */
3260static void ov519_set_fr(struct sd *sd)
3261{
3262 int fr;
3263 u8 clock;
3264 /* frame rate table with indices:
3265 * - mode = 0: 320x240, 1: 640x480
3266 * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5
3267 * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock)
3268 */
3269 static const u8 fr_tb[2][6][3] = {
3270 {{0x04, 0xff, 0x00},
3271 {0x04, 0x1f, 0x00},
3272 {0x04, 0x1b, 0x00},
3273 {0x04, 0x15, 0x00},
3274 {0x04, 0x09, 0x00},
3275 {0x04, 0x01, 0x00}},
3276 {{0x0c, 0xff, 0x00},
3277 {0x0c, 0x1f, 0x00},
3278 {0x0c, 0x1b, 0x00},
3279 {0x04, 0xff, 0x01},
3280 {0x04, 0x1f, 0x01},
3281 {0x04, 0x1b, 0x01}},
3282 };
3283
3284 if (frame_rate > 0)
3285 sd->frame_rate = frame_rate;
3286 if (sd->frame_rate >= 30)
3287 fr = 0;
3288 else if (sd->frame_rate >= 25)
3289 fr = 1;
3290 else if (sd->frame_rate >= 20)
3291 fr = 2;
3292 else if (sd->frame_rate >= 15)
3293 fr = 3;
3294 else if (sd->frame_rate >= 10)
3295 fr = 4;
3296 else
3297 fr = 5;
3298 reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
3299 reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
3300 clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
3301 if (sd->sensor == SEN_OV7660)
3302 clock |= 0x80; /* enable double clock */
3303 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
3304}
3305
Jean-François Moine58c92d32011-03-13 16:36:49 -03003306static void setautogain(struct gspca_dev *gspca_dev)
3307{
3308 struct sd *sd = (struct sd *) gspca_dev;
3309
3310 i2c_w_mask(sd, 0x13, sd->ctrls[AUTOGAIN].val ? 0x05 : 0x00, 0x05);
3311}
3312
Hans de Goede49809d62009-06-07 12:10:39 -03003313/* this function is called at probe time */
3314static int sd_config(struct gspca_dev *gspca_dev,
3315 const struct usb_device_id *id)
3316{
3317 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003318 struct cam *cam = &gspca_dev->cam;
Hans de Goede49809d62009-06-07 12:10:39 -03003319
Hans de Goede9e4d8252009-06-14 06:25:06 -03003320 sd->bridge = id->driver_info & BRIDGE_MASK;
Jean-François Moinea23acec2010-11-12 15:07:35 -03003321 sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0;
Hans de Goede49809d62009-06-07 12:10:39 -03003322
3323 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003324 case BRIDGE_OV511:
3325 case BRIDGE_OV511PLUS:
Jean-François Moine7491f782010-11-13 03:56:41 -03003326 cam->cam_mode = ov511_vga_mode;
3327 cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
3328 break;
3329 case BRIDGE_OV518:
3330 case BRIDGE_OV518PLUS:
3331 cam->cam_mode = ov518_vga_mode;
3332 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
3333 break;
3334 case BRIDGE_OV519:
3335 cam->cam_mode = ov519_vga_mode;
3336 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3337 sd->invert_led = !sd->invert_led;
3338 break;
3339 case BRIDGE_OVFX2:
3340 cam->cam_mode = ov519_vga_mode;
3341 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3342 cam->bulk_size = OVFX2_BULK_SIZE;
3343 cam->bulk_nurbs = MAX_NURBS;
3344 cam->bulk = 1;
3345 break;
3346 case BRIDGE_W9968CF:
3347 cam->cam_mode = w9968cf_vga_mode;
3348 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
3349 cam->reverse_alts = 1;
3350 break;
3351 }
3352
3353 gspca_dev->cam.ctrls = sd->ctrls;
3354 sd->quality = QUALITY_DEF;
Jean-François Moinec8ef0a52011-05-23 06:08:49 -03003355 sd->frame_rate = 15;
Jean-François Moine7491f782010-11-13 03:56:41 -03003356
3357 return 0;
3358}
3359
3360/* this function is called at probe and resume time */
3361static int sd_init(struct gspca_dev *gspca_dev)
3362{
3363 struct sd *sd = (struct sd *) gspca_dev;
3364 struct cam *cam = &gspca_dev->cam;
3365
3366 switch (sd->bridge) {
3367 case BRIDGE_OV511:
3368 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003369 ov511_configure(gspca_dev);
Hans de Goede1876bb92009-06-14 06:45:50 -03003370 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003371 case BRIDGE_OV518:
3372 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003373 ov518_configure(gspca_dev);
Hans de Goede49809d62009-06-07 12:10:39 -03003374 break;
3375 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003376 ov519_configure(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003377 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003378 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003379 ovfx2_configure(sd);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003380 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003381 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003382 w9968cf_configure(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03003383 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003384 }
3385
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003386 /* The OV519 must be more aggressive about sensor detection since
3387 * I2C write will never fail if the sensor is not present. We have
3388 * to try to initialize the sensor to detect its presence */
Jean-François Moine7bbe6b82010-11-11 08:27:24 -03003389 sd->sensor = -1;
Hans de Goede229bb7d2009-10-11 07:41:46 -03003390
3391 /* Test for 76xx */
3392 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003393 ov7xx0_configure(sd);
3394
Hans de Goede229bb7d2009-10-11 07:41:46 -03003395 /* Test for 6xx0 */
3396 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003397 ov6xx0_configure(sd);
3398
Hans de Goede229bb7d2009-10-11 07:41:46 -03003399 /* Test for 8xx0 */
3400 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003401 ov8xx0_configure(sd);
3402
Hans de Goede635118d2009-10-11 09:49:03 -03003403 /* Test for 3xxx / 2xxx */
3404 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003405 ov_hires_configure(sd);
Hans de Goede229bb7d2009-10-11 07:41:46 -03003406 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03003407 err("Can't determine sensor slave IDs");
Hans de Goede229bb7d2009-10-11 07:41:46 -03003408 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003409 }
3410
Jean-François Moine7bbe6b82010-11-11 08:27:24 -03003411 if (sd->sensor < 0)
3412 goto error;
3413
Jean-François Moine7491f782010-11-13 03:56:41 -03003414 ov51x_led_control(sd, 0); /* turn LED off */
3415
Hans de Goede49809d62009-06-07 12:10:39 -03003416 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003417 case BRIDGE_OV511:
3418 case BRIDGE_OV511PLUS:
Jean-François Moine7491f782010-11-13 03:56:41 -03003419 if (sd->sif) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003420 cam->cam_mode = ov511_sif_mode;
3421 cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
3422 }
3423 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003424 case BRIDGE_OV518:
3425 case BRIDGE_OV518PLUS:
Jean-François Moine7491f782010-11-13 03:56:41 -03003426 if (sd->sif) {
Hans de Goede49809d62009-06-07 12:10:39 -03003427 cam->cam_mode = ov518_sif_mode;
3428 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
3429 }
3430 break;
3431 case BRIDGE_OV519:
Jean-François Moine7491f782010-11-13 03:56:41 -03003432 if (sd->sif) {
Hans de Goede49809d62009-06-07 12:10:39 -03003433 cam->cam_mode = ov519_sif_mode;
3434 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3435 }
3436 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003437 case BRIDGE_OVFX2:
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003438 switch (sd->sensor) {
3439 case SEN_OV2610:
3440 case SEN_OV2610AE:
Hans de Goede635118d2009-10-11 09:49:03 -03003441 cam->cam_mode = ovfx2_ov2610_mode;
3442 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003443 break;
3444 case SEN_OV3610:
Hans de Goede635118d2009-10-11 09:49:03 -03003445 cam->cam_mode = ovfx2_ov3610_mode;
3446 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003447 break;
Jean-François Moine798ae152011-05-23 05:38:10 -03003448 case SEN_OV9600:
3449 cam->cam_mode = ovfx2_ov9600_mode;
3450 cam->nmodes = ARRAY_SIZE(ovfx2_ov9600_mode);
3451 break;
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003452 default:
3453 if (sd->sif) {
3454 cam->cam_mode = ov519_sif_mode;
3455 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3456 }
3457 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003458 }
3459 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003460 case BRIDGE_W9968CF:
Hans de Goede79b35902009-10-19 06:08:01 -03003461 if (sd->sif)
Jean-François Moine7491f782010-11-13 03:56:41 -03003462 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1;
Hans de Goedea511ba92009-10-16 07:13:07 -03003463
3464 /* w9968cf needs initialisation once the sensor is known */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003465 w9968cf_init(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03003466 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003467 }
Jean-François Moine83db7682010-11-12 07:14:08 -03003468
3469 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Hans de Goede02ab18b2009-06-14 04:32:04 -03003470
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003471 /* initialize the sensor */
3472 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003473 case SEN_OV2610:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003474 write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610));
3475
Hans de Goede635118d2009-10-11 09:49:03 -03003476 /* Enable autogain, autoexpo, awb, bandfilter */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003477 i2c_w_mask(sd, 0x13, 0x27, 0x27);
Hans de Goede635118d2009-10-11 09:49:03 -03003478 break;
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003479 case SEN_OV2610AE:
3480 write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae));
3481
3482 /* enable autoexpo */
3483 i2c_w_mask(sd, 0x13, 0x05, 0x05);
3484 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003485 case SEN_OV3610:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003486 write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
3487
Hans de Goede635118d2009-10-11 09:49:03 -03003488 /* Enable autogain, autoexpo, awb, bandfilter */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003489 i2c_w_mask(sd, 0x13, 0x27, 0x27);
Hans de Goede635118d2009-10-11 09:49:03 -03003490 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003491 case SEN_OV6620:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003492 write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003493 break;
3494 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003495 case SEN_OV66308AF:
Jean-François Moine62833ac2010-10-02 04:27:02 -03003496 sd->ctrls[CONTRAST].def = 200;
3497 /* The default is too low for the ov6630 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003498 write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003499 break;
3500 default:
3501/* case SEN_OV7610: */
3502/* case SEN_OV76BE: */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003503 write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610));
3504 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003505 break;
3506 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003507 case SEN_OV7620AE:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003508 write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003509 break;
3510 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003511 case SEN_OV7648:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003512 write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003513 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03003514 case SEN_OV7660:
3515 i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
3516 msleep(14);
3517 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
3518 write_regvals(sd, init_519_ov7660,
3519 ARRAY_SIZE(init_519_ov7660));
3520 write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
3521 sd->gspca_dev.curr_mode = 1; /* 640x480 */
Jean-François Moine42e142f2010-11-13 05:10:27 -03003522 ov519_set_mode(sd);
3523 ov519_set_fr(sd);
3524 sd->ctrls[COLORS].max = 4; /* 0..4 */
3525 sd->ctrls[COLORS].val =
3526 sd->ctrls[COLORS].def = 2;
3527 setcolors(gspca_dev);
3528 sd->ctrls[CONTRAST].max = 6; /* 0..6 */
3529 sd->ctrls[CONTRAST].val =
3530 sd->ctrls[CONTRAST].def = 3;
3531 setcontrast(gspca_dev);
3532 sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */
3533 sd->ctrls[BRIGHTNESS].val =
3534 sd->ctrls[BRIGHTNESS].def = 3;
3535 setbrightness(gspca_dev);
3536 sd_reset_snapshot(gspca_dev);
3537 ov51x_restart(sd);
3538 ov51x_stop(sd); /* not in win traces */
3539 ov51x_led_control(sd, 0);
3540 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003541 case SEN_OV7670:
Jean-François Moine62833ac2010-10-02 04:27:02 -03003542 sd->ctrls[FREQ].max = 3; /* auto */
3543 sd->ctrls[FREQ].def = 3;
Jean-François Moinef8f20182010-11-12 07:54:02 -03003544 write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003545 break;
3546 case SEN_OV8610:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003547 write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003548 break;
Jean-François Moine798ae152011-05-23 05:38:10 -03003549 case SEN_OV9600:
3550 write_i2c_regvals(sd, norm_9600, ARRAY_SIZE(norm_9600));
3551
3552 /* enable autoexpo */
3553/* i2c_w_mask(sd, 0x13, 0x05, 0x05); */
3554 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003555 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03003556 return gspca_dev->usb_err;
Jean-François Moine7491f782010-11-13 03:56:41 -03003557error:
3558 PDEBUG(D_ERR, "OV519 Config failed");
3559 return -EINVAL;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003560}
3561
Jean-François Moinec42cedb2011-02-10 13:37:48 -03003562/* function called at start time before URB creation */
3563static int sd_isoc_init(struct gspca_dev *gspca_dev)
3564{
3565 struct sd *sd = (struct sd *) gspca_dev;
3566
3567 switch (sd->bridge) {
3568 case BRIDGE_OVFX2:
Jean-François Moine9cf208e2011-05-22 05:05:11 -03003569 if (gspca_dev->width != 800)
Jean-François Moinec42cedb2011-02-10 13:37:48 -03003570 gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
3571 else
3572 gspca_dev->cam.bulk_size = 7 * 4096;
3573 break;
3574 }
3575 return 0;
3576}
3577
Hans de Goede1876bb92009-06-14 06:45:50 -03003578/* Set up the OV511/OV511+ with the given image parameters.
3579 *
3580 * Do not put any sensor-specific code in here (including I2C I/O functions)
3581 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003582static void ov511_mode_init_regs(struct sd *sd)
Hans de Goede1876bb92009-06-14 06:45:50 -03003583{
3584 int hsegs, vsegs, packet_size, fps, needed;
3585 int interlaced = 0;
3586 struct usb_host_interface *alt;
3587 struct usb_interface *intf;
3588
3589 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3590 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3591 if (!alt) {
Jean-François Moine0b656322010-09-13 05:19:58 -03003592 err("Couldn't get altsetting");
Jean-François Moinef8f20182010-11-12 07:54:02 -03003593 sd->gspca_dev.usb_err = -EIO;
3594 return;
Hans de Goede1876bb92009-06-14 06:45:50 -03003595 }
3596
3597 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3598 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3599
3600 reg_w(sd, R511_CAM_UV_EN, 0x01);
3601 reg_w(sd, R511_SNAP_UV_EN, 0x01);
3602 reg_w(sd, R511_SNAP_OPTS, 0x03);
3603
3604 /* Here I'm assuming that snapshot size == image size.
3605 * I hope that's always true. --claudio
3606 */
3607 hsegs = (sd->gspca_dev.width >> 3) - 1;
3608 vsegs = (sd->gspca_dev.height >> 3) - 1;
3609
3610 reg_w(sd, R511_CAM_PXCNT, hsegs);
3611 reg_w(sd, R511_CAM_LNCNT, vsegs);
3612 reg_w(sd, R511_CAM_PXDIV, 0x00);
3613 reg_w(sd, R511_CAM_LNDIV, 0x00);
3614
3615 /* YUV420, low pass filter on */
3616 reg_w(sd, R511_CAM_OPTS, 0x03);
3617
3618 /* Snapshot additions */
3619 reg_w(sd, R511_SNAP_PXCNT, hsegs);
3620 reg_w(sd, R511_SNAP_LNCNT, vsegs);
3621 reg_w(sd, R511_SNAP_PXDIV, 0x00);
3622 reg_w(sd, R511_SNAP_LNDIV, 0x00);
3623
3624 /******** Set the framerate ********/
3625 if (frame_rate > 0)
3626 sd->frame_rate = frame_rate;
3627
3628 switch (sd->sensor) {
3629 case SEN_OV6620:
3630 /* No framerate control, doesn't like higher rates yet */
3631 sd->clockdiv = 3;
3632 break;
3633
3634 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
3635 for more sensors we need to do this for them too */
3636 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003637 case SEN_OV7620AE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003638 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003639 case SEN_OV7648:
Hans de Goedeb282d872009-06-14 19:10:40 -03003640 case SEN_OV76BE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003641 if (sd->gspca_dev.width == 320)
3642 interlaced = 1;
3643 /* Fall through */
3644 case SEN_OV6630:
Hans de Goede1876bb92009-06-14 06:45:50 -03003645 case SEN_OV7610:
3646 case SEN_OV7670:
3647 switch (sd->frame_rate) {
3648 case 30:
3649 case 25:
3650 /* Not enough bandwidth to do 640x480 @ 30 fps */
3651 if (sd->gspca_dev.width != 640) {
3652 sd->clockdiv = 0;
3653 break;
3654 }
3655 /* Fall through for 640x480 case */
3656 default:
3657/* case 20: */
3658/* case 15: */
3659 sd->clockdiv = 1;
3660 break;
3661 case 10:
3662 sd->clockdiv = 2;
3663 break;
3664 case 5:
3665 sd->clockdiv = 5;
3666 break;
3667 }
3668 if (interlaced) {
3669 sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
3670 /* Higher then 10 does not work */
3671 if (sd->clockdiv > 10)
3672 sd->clockdiv = 10;
3673 }
3674 break;
3675
3676 case SEN_OV8610:
3677 /* No framerate control ?? */
3678 sd->clockdiv = 0;
3679 break;
3680 }
3681
3682 /* Check if we have enough bandwidth to disable compression */
3683 fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
3684 needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2;
3685 /* 1400 is a conservative estimate of the max nr of isoc packets/sec */
3686 if (needed > 1400 * packet_size) {
3687 /* Enable Y and UV quantization and compression */
3688 reg_w(sd, R511_COMP_EN, 0x07);
3689 reg_w(sd, R511_COMP_LUT_EN, 0x03);
3690 } else {
3691 reg_w(sd, R511_COMP_EN, 0x06);
3692 reg_w(sd, R511_COMP_LUT_EN, 0x00);
3693 }
3694
3695 reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
3696 reg_w(sd, R51x_SYS_RESET, 0);
Hans de Goede1876bb92009-06-14 06:45:50 -03003697}
3698
Hans de Goede49809d62009-06-07 12:10:39 -03003699/* Sets up the OV518/OV518+ with the given image parameters
3700 *
3701 * OV518 needs a completely different approach, until we can figure out what
3702 * the individual registers do. Also, only 15 FPS is supported now.
3703 *
3704 * Do not put any sensor-specific code in here (including I2C I/O functions)
3705 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003706static void ov518_mode_init_regs(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03003707{
Hans de Goedeb282d872009-06-14 19:10:40 -03003708 int hsegs, vsegs, packet_size;
3709 struct usb_host_interface *alt;
3710 struct usb_interface *intf;
3711
3712 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3713 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3714 if (!alt) {
Jean-François Moine0b656322010-09-13 05:19:58 -03003715 err("Couldn't get altsetting");
Jean-François Moinef8f20182010-11-12 07:54:02 -03003716 sd->gspca_dev.usb_err = -EIO;
3717 return;
Hans de Goedeb282d872009-06-14 19:10:40 -03003718 }
3719
3720 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3721 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
Hans de Goede49809d62009-06-07 12:10:39 -03003722
3723 /******** Set the mode ********/
Hans de Goede49809d62009-06-07 12:10:39 -03003724 reg_w(sd, 0x2b, 0);
3725 reg_w(sd, 0x2c, 0);
3726 reg_w(sd, 0x2d, 0);
3727 reg_w(sd, 0x2e, 0);
3728 reg_w(sd, 0x3b, 0);
3729 reg_w(sd, 0x3c, 0);
3730 reg_w(sd, 0x3d, 0);
3731 reg_w(sd, 0x3e, 0);
3732
3733 if (sd->bridge == BRIDGE_OV518) {
3734 /* Set 8-bit (YVYU) input format */
3735 reg_w_mask(sd, 0x20, 0x08, 0x08);
3736
3737 /* Set 12-bit (4:2:0) output format */
3738 reg_w_mask(sd, 0x28, 0x80, 0xf0);
3739 reg_w_mask(sd, 0x38, 0x80, 0xf0);
3740 } else {
3741 reg_w(sd, 0x28, 0x80);
3742 reg_w(sd, 0x38, 0x80);
3743 }
3744
3745 hsegs = sd->gspca_dev.width / 16;
3746 vsegs = sd->gspca_dev.height / 4;
3747
3748 reg_w(sd, 0x29, hsegs);
3749 reg_w(sd, 0x2a, vsegs);
3750
3751 reg_w(sd, 0x39, hsegs);
3752 reg_w(sd, 0x3a, vsegs);
3753
3754 /* Windows driver does this here; who knows why */
3755 reg_w(sd, 0x2f, 0x80);
3756
Jean-François Moine87bae742010-11-12 05:31:34 -03003757 /******** Set the framerate ********/
Hans de Goedeb282d872009-06-14 19:10:40 -03003758 sd->clockdiv = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03003759
3760 /* Mode independent, but framerate dependent, regs */
Hans de Goedeb282d872009-06-14 19:10:40 -03003761 /* 0x51: Clock divider; Only works on some cams which use 2 crystals */
3762 reg_w(sd, 0x51, 0x04);
Hans de Goede49809d62009-06-07 12:10:39 -03003763 reg_w(sd, 0x22, 0x18);
3764 reg_w(sd, 0x23, 0xff);
3765
Hans de Goedeb282d872009-06-14 19:10:40 -03003766 if (sd->bridge == BRIDGE_OV518PLUS) {
3767 switch (sd->sensor) {
Hans de Goede859cc472010-01-07 15:42:35 -03003768 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003769 if (sd->gspca_dev.width == 320) {
3770 reg_w(sd, 0x20, 0x00);
3771 reg_w(sd, 0x21, 0x19);
3772 } else {
3773 reg_w(sd, 0x20, 0x60);
3774 reg_w(sd, 0x21, 0x1f);
3775 }
3776 break;
Hans de Goede859cc472010-01-07 15:42:35 -03003777 case SEN_OV7620:
3778 reg_w(sd, 0x20, 0x00);
3779 reg_w(sd, 0x21, 0x19);
3780 break;
Hans de Goedeb282d872009-06-14 19:10:40 -03003781 default:
3782 reg_w(sd, 0x21, 0x19);
3783 }
3784 } else
Hans de Goede49809d62009-06-07 12:10:39 -03003785 reg_w(sd, 0x71, 0x17); /* Compression-related? */
3786
3787 /* FIXME: Sensor-specific */
3788 /* Bit 5 is what matters here. Of course, it is "reserved" */
3789 i2c_w(sd, 0x54, 0x23);
3790
3791 reg_w(sd, 0x2f, 0x80);
3792
3793 if (sd->bridge == BRIDGE_OV518PLUS) {
3794 reg_w(sd, 0x24, 0x94);
3795 reg_w(sd, 0x25, 0x90);
3796 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3797 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
3798 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
3799 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
3800 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
3801 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
3802 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
3803 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
3804 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
3805 } else {
3806 reg_w(sd, 0x24, 0x9f);
3807 reg_w(sd, 0x25, 0x90);
3808 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3809 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
3810 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
3811 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
3812 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
3813 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
3814 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
3815 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
3816 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
3817 }
3818
3819 reg_w(sd, 0x2f, 0x80);
Hans de Goede49809d62009-06-07 12:10:39 -03003820}
3821
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003822/* Sets up the OV519 with the given image parameters
3823 *
3824 * OV519 needs a completely different approach, until we can figure out what
3825 * the individual registers do.
3826 *
3827 * Do not put any sensor-specific code in here (including I2C I/O functions)
3828 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003829static void ov519_mode_init_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003830{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003831 static const struct ov_regvals mode_init_519_ov7670[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003832 { 0x5d, 0x03 }, /* Turn off suspend mode */
3833 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
Jean-François Moine21867802010-11-12 06:12:09 -03003834 { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003835 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3836 { 0xa3, 0x18 },
3837 { 0xa4, 0x04 },
3838 { 0xa5, 0x28 },
3839 { 0x37, 0x00 }, /* SetUsbInit */
3840 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3841 /* Enable both fields, YUV Input, disable defect comp (why?) */
3842 { 0x20, 0x0c },
3843 { 0x21, 0x38 },
3844 { 0x22, 0x1d },
3845 { 0x17, 0x50 }, /* undocumented */
3846 { 0x37, 0x00 }, /* undocumented */
3847 { 0x40, 0xff }, /* I2C timeout counter */
3848 { 0x46, 0x00 }, /* I2C clock prescaler */
3849 { 0x59, 0x04 }, /* new from windrv 090403 */
3850 { 0xff, 0x00 }, /* undocumented */
3851 /* windows reads 0x55 at this point, why? */
3852 };
3853
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003854 static const struct ov_regvals mode_init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003855 { 0x5d, 0x03 }, /* Turn off suspend mode */
3856 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
Jean-François Moine21867802010-11-12 06:12:09 -03003857 { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003858 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3859 { 0xa3, 0x18 },
3860 { 0xa4, 0x04 },
3861 { 0xa5, 0x28 },
3862 { 0x37, 0x00 }, /* SetUsbInit */
3863 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3864 /* Enable both fields, YUV Input, disable defect comp (why?) */
3865 { 0x22, 0x1d },
3866 { 0x17, 0x50 }, /* undocumented */
3867 { 0x37, 0x00 }, /* undocumented */
3868 { 0x40, 0xff }, /* I2C timeout counter */
3869 { 0x46, 0x00 }, /* I2C clock prescaler */
3870 { 0x59, 0x04 }, /* new from windrv 090403 */
3871 { 0xff, 0x00 }, /* undocumented */
3872 /* windows reads 0x55 at this point, why? */
3873 };
3874
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003875 /******** Set the mode ********/
Jean-François Moine42e142f2010-11-13 05:10:27 -03003876 switch (sd->sensor) {
3877 default:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003878 write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
Hans de Goede035d3a32010-01-09 08:14:43 -03003879 if (sd->sensor == SEN_OV7640 ||
3880 sd->sensor == SEN_OV7648) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003881 /* Select 8-bit input mode */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003882 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003883 }
Jean-François Moine42e142f2010-11-13 05:10:27 -03003884 break;
3885 case SEN_OV7660:
3886 return; /* done by ov519_set_mode/fr() */
3887 case SEN_OV7670:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003888 write_regvals(sd, mode_init_519_ov7670,
3889 ARRAY_SIZE(mode_init_519_ov7670));
Jean-François Moine42e142f2010-11-13 05:10:27 -03003890 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003891 }
3892
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003893 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
3894 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
Hans de Goede80142ef2009-06-14 06:26:49 -03003895 if (sd->sensor == SEN_OV7670 &&
3896 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3897 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
Hans de Goede035d3a32010-01-09 08:14:43 -03003898 else if (sd->sensor == SEN_OV7648 &&
3899 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3900 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
Hans de Goede80142ef2009-06-14 06:26:49 -03003901 else
3902 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003903 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
3904 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
3905 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
3906 reg_w(sd, OV519_R16_DIVIDER, 0x00);
3907 reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003908 reg_w(sd, 0x26, 0x00); /* Undocumented */
3909
3910 /******** Set the framerate ********/
3911 if (frame_rate > 0)
3912 sd->frame_rate = frame_rate;
3913
3914/* FIXME: These are only valid at the max resolution. */
3915 sd->clockdiv = 0;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003916 switch (sd->sensor) {
3917 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003918 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003919 switch (sd->frame_rate) {
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003920 default:
3921/* case 30: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003922 reg_w(sd, 0xa4, 0x0c);
3923 reg_w(sd, 0x23, 0xff);
3924 break;
3925 case 25:
3926 reg_w(sd, 0xa4, 0x0c);
3927 reg_w(sd, 0x23, 0x1f);
3928 break;
3929 case 20:
3930 reg_w(sd, 0xa4, 0x0c);
3931 reg_w(sd, 0x23, 0x1b);
3932 break;
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003933 case 15:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003934 reg_w(sd, 0xa4, 0x04);
3935 reg_w(sd, 0x23, 0xff);
3936 sd->clockdiv = 1;
3937 break;
3938 case 10:
3939 reg_w(sd, 0xa4, 0x04);
3940 reg_w(sd, 0x23, 0x1f);
3941 sd->clockdiv = 1;
3942 break;
3943 case 5:
3944 reg_w(sd, 0xa4, 0x04);
3945 reg_w(sd, 0x23, 0x1b);
3946 sd->clockdiv = 1;
3947 break;
3948 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003949 break;
3950 case SEN_OV8610:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003951 switch (sd->frame_rate) {
3952 default: /* 15 fps */
3953/* case 15: */
3954 reg_w(sd, 0xa4, 0x06);
3955 reg_w(sd, 0x23, 0xff);
3956 break;
3957 case 10:
3958 reg_w(sd, 0xa4, 0x06);
3959 reg_w(sd, 0x23, 0x1f);
3960 break;
3961 case 5:
3962 reg_w(sd, 0xa4, 0x06);
3963 reg_w(sd, 0x23, 0x1b);
3964 break;
3965 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003966 break;
3967 case SEN_OV7670: /* guesses, based on 7640 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003968 PDEBUG(D_STREAM, "Setting framerate to %d fps",
3969 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003970 reg_w(sd, 0xa4, 0x10);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003971 switch (sd->frame_rate) {
3972 case 30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003973 reg_w(sd, 0x23, 0xff);
3974 break;
3975 case 20:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003976 reg_w(sd, 0x23, 0x1b);
3977 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003978 default:
3979/* case 15: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003980 reg_w(sd, 0x23, 0xff);
3981 sd->clockdiv = 1;
3982 break;
3983 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003984 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003985 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003986}
3987
Jean-François Moinef8f20182010-11-12 07:54:02 -03003988static void mode_init_ov_sensor_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003989{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003990 struct gspca_dev *gspca_dev;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003991 int qvga, xstart, xend, ystart, yend;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03003992 u8 v;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003993
3994 gspca_dev = &sd->gspca_dev;
Jean-François Moine87bae742010-11-12 05:31:34 -03003995 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003996
3997 /******** Mode (VGA/QVGA) and sensor specific regs ********/
3998 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003999 case SEN_OV2610:
4000 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4001 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
4002 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
4003 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
4004 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
4005 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
4006 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Jean-François Moinef8f20182010-11-12 07:54:02 -03004007 return;
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03004008 case SEN_OV2610AE: {
4009 u8 v;
4010
4011 /* frame rates:
4012 * 10fps / 5 fps for 1600x1200
4013 * 40fps / 20fps for 800x600
4014 */
4015 v = 80;
4016 if (qvga) {
4017 if (sd->frame_rate < 25)
4018 v = 0x81;
4019 } else {
4020 if (sd->frame_rate < 10)
4021 v = 0x81;
4022 }
4023 i2c_w(sd, 0x11, v);
4024 i2c_w(sd, 0x12, qvga ? 0x60 : 0x20);
4025 return;
4026 }
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004027 case SEN_OV3610:
Hans de Goede635118d2009-10-11 09:49:03 -03004028 if (qvga) {
4029 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004030 ystart = (776 - gspca_dev->height) / 2;
Hans de Goede635118d2009-10-11 09:49:03 -03004031 } else {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004032 xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
Hans de Goede635118d2009-10-11 09:49:03 -03004033 ystart = (1544 - gspca_dev->height) / 2;
4034 }
4035 xend = xstart + gspca_dev->width;
4036 yend = ystart + gspca_dev->height;
4037 /* Writing to the COMH register resets the other windowing regs
4038 to their default values, so we must do this first. */
4039 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
4040 i2c_w_mask(sd, 0x32,
4041 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
4042 0x3f);
4043 i2c_w_mask(sd, 0x03,
4044 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
4045 0x0f);
4046 i2c_w(sd, 0x17, xstart >> 4);
4047 i2c_w(sd, 0x18, xend >> 4);
4048 i2c_w(sd, 0x19, ystart >> 3);
4049 i2c_w(sd, 0x1a, yend >> 3);
Jean-François Moinef8f20182010-11-12 07:54:02 -03004050 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004051 case SEN_OV8610:
4052 /* For OV8610 qvga means qsvga */
4053 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004054 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
4055 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
4056 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
4057 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004058 break;
4059 case SEN_OV7610:
4060 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Jean-François Moine780e3122010-10-19 04:29:10 -03004061 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004062 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
4063 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004064 break;
4065 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004066 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03004067 case SEN_OV76BE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004068 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4069 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
4070 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
4071 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
4072 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goedeb282d872009-06-14 19:10:40 -03004073 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004074 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004075 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
4076 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
4077 if (sd->sensor == SEN_OV76BE)
4078 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004079 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004080 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004081 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004082 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4083 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
Hans de Goede8d0082f2010-01-09 19:45:44 -03004084 /* Setting this undocumented bit in qvga mode removes a very
4085 annoying vertical shaking of the image */
Hans de Goede035d3a32010-01-09 08:14:43 -03004086 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goede8d0082f2010-01-09 19:45:44 -03004087 /* Unknown */
Hans de Goede035d3a32010-01-09 08:14:43 -03004088 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
Hans de Goede8d0082f2010-01-09 19:45:44 -03004089 /* Allow higher automatic gain (to allow higher framerates) */
Hans de Goede035d3a32010-01-09 08:14:43 -03004090 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004091 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004092 break;
4093 case SEN_OV7670:
4094 /* set COM7_FMT_VGA or COM7_FMT_QVGA
4095 * do we need to set anything else?
4096 * HSTART etc are set in set_ov_sensor_window itself */
Jean-François Moine21867802010-11-12 06:12:09 -03004097 i2c_w_mask(sd, OV7670_R12_COM7,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004098 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
4099 OV7670_COM7_FMT_MASK);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004100 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
Jean-François Moine21867802010-11-12 06:12:09 -03004101 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004102 OV7670_COM8_AWB);
4103 if (qvga) { /* QVGA from ov7670.c by
4104 * Jonathan Corbet */
4105 xstart = 164;
4106 xend = 28;
4107 ystart = 14;
4108 yend = 494;
4109 } else { /* VGA */
4110 xstart = 158;
4111 xend = 14;
4112 ystart = 10;
4113 yend = 490;
4114 }
4115 /* OV7670 hardware window registers are split across
4116 * multiple locations */
Jean-François Moine21867802010-11-12 06:12:09 -03004117 i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
4118 i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
4119 v = i2c_r(sd, OV7670_R32_HREF);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004120 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
4121 msleep(10); /* need to sleep between read and write to
4122 * same reg! */
Jean-François Moine21867802010-11-12 06:12:09 -03004123 i2c_w(sd, OV7670_R32_HREF, v);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004124
Jean-François Moine21867802010-11-12 06:12:09 -03004125 i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
4126 i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
4127 v = i2c_r(sd, OV7670_R03_VREF);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004128 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
4129 msleep(10); /* need to sleep between read and write to
4130 * same reg! */
Jean-François Moine21867802010-11-12 06:12:09 -03004131 i2c_w(sd, OV7670_R03_VREF, v);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004132 break;
4133 case SEN_OV6620:
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004134 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4135 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
4136 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
4137 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004138 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004139 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004140 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004141 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004142 break;
Jean-François Moine798ae152011-05-23 05:38:10 -03004143 case SEN_OV9600: {
4144 const struct ov_i2c_regvals *vals;
4145 static const struct ov_i2c_regvals sxga_15[] = {
4146 {0x11, 0x80}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75}
4147 };
4148 static const struct ov_i2c_regvals sxga_7_5[] = {
4149 {0x11, 0x81}, {0x14, 0x3e}, {0x24, 0x85}, {0x25, 0x75}
4150 };
4151 static const struct ov_i2c_regvals vga_30[] = {
4152 {0x11, 0x81}, {0x14, 0x7e}, {0x24, 0x70}, {0x25, 0x60}
4153 };
4154 static const struct ov_i2c_regvals vga_15[] = {
4155 {0x11, 0x83}, {0x14, 0x3e}, {0x24, 0x80}, {0x25, 0x70}
4156 };
4157
4158 /* frame rates:
4159 * 15fps / 7.5 fps for 1280x1024
4160 * 30fps / 15fps for 640x480
4161 */
4162 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0x40);
4163 if (qvga)
4164 vals = sd->frame_rate < 30 ? vga_15 : vga_30;
4165 else
4166 vals = sd->frame_rate < 15 ? sxga_7_5 : sxga_15;
4167 write_i2c_regvals(sd, vals, ARRAY_SIZE(sxga_15));
4168 return;
4169 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004170 default:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004171 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004172 }
4173
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004174 /******** Clock programming ********/
Hans de Goedeae49c402009-06-14 19:15:07 -03004175 i2c_w(sd, 0x11, sd->clockdiv);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004176}
4177
Jean-François Moine42e142f2010-11-13 05:10:27 -03004178/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */
Jean-François Moine62833ac2010-10-02 04:27:02 -03004179static void sethvflip(struct gspca_dev *gspca_dev)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004180{
Jean-François Moine62833ac2010-10-02 04:27:02 -03004181 struct sd *sd = (struct sd *) gspca_dev;
4182
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004183 if (sd->gspca_dev.streaming)
Jean-François Moine5927abc2010-11-12 15:32:29 -03004184 reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */
Jean-François Moine21867802010-11-12 06:12:09 -03004185 i2c_w_mask(sd, OV7670_R1E_MVFP,
Jean-François Moine62833ac2010-10-02 04:27:02 -03004186 OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val
4187 | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004188 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004189 if (sd->gspca_dev.streaming)
Jean-François Moine5927abc2010-11-12 15:32:29 -03004190 reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004191}
4192
Jean-François Moinef8f20182010-11-12 07:54:02 -03004193static void set_ov_sensor_window(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004194{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004195 struct gspca_dev *gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03004196 int qvga, crop;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004197 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004198
Hans de Goede635118d2009-10-11 09:49:03 -03004199 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
Jean-François Moine42e142f2010-11-13 05:10:27 -03004200 switch (sd->sensor) {
4201 case SEN_OV2610:
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03004202 case SEN_OV2610AE:
Jean-François Moine42e142f2010-11-13 05:10:27 -03004203 case SEN_OV3610:
4204 case SEN_OV7670:
Jean-François Moine798ae152011-05-23 05:38:10 -03004205 case SEN_OV9600:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004206 mode_init_ov_sensor_regs(sd);
4207 return;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004208 case SEN_OV7660:
4209 ov519_set_mode(sd);
4210 ov519_set_fr(sd);
4211 return;
Jean-François Moinef8f20182010-11-12 07:54:02 -03004212 }
Jean-François Moine42e142f2010-11-13 05:10:27 -03004213
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004214 gspca_dev = &sd->gspca_dev;
Jean-François Moine87bae742010-11-12 05:31:34 -03004215 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
4216 crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004217
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004218 /* The different sensor ICs handle setting up of window differently.
4219 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
4220 switch (sd->sensor) {
4221 case SEN_OV8610:
4222 hwsbase = 0x1e;
4223 hwebase = 0x1e;
4224 vwsbase = 0x02;
4225 vwebase = 0x02;
4226 break;
4227 case SEN_OV7610:
4228 case SEN_OV76BE:
4229 hwsbase = 0x38;
4230 hwebase = 0x3a;
4231 vwsbase = vwebase = 0x05;
4232 break;
4233 case SEN_OV6620:
4234 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004235 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004236 hwsbase = 0x38;
4237 hwebase = 0x3a;
4238 vwsbase = 0x05;
4239 vwebase = 0x06;
Hans de Goede7d971372009-06-14 05:28:17 -03004240 if (sd->sensor == SEN_OV66308AF && qvga)
Hans de Goede49809d62009-06-07 12:10:39 -03004241 /* HDG: this fixes U and V getting swapped */
Hans de Goede7d971372009-06-14 05:28:17 -03004242 hwsbase++;
Hans de Goede124cc9c2009-06-14 05:48:00 -03004243 if (crop) {
4244 hwsbase += 8;
4245 hwebase += 8;
4246 vwsbase += 11;
4247 vwebase += 11;
4248 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004249 break;
4250 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004251 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004252 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
4253 hwebase = 0x2f;
4254 vwsbase = vwebase = 0x05;
4255 break;
4256 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004257 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004258 hwsbase = 0x1a;
4259 hwebase = 0x1a;
4260 vwsbase = vwebase = 0x03;
4261 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004262 default:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004263 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004264 }
4265
4266 switch (sd->sensor) {
4267 case SEN_OV6620:
4268 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004269 case SEN_OV66308AF:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004270 if (qvga) { /* QCIF */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004271 hwscale = 0;
4272 vwscale = 0;
4273 } else { /* CIF */
4274 hwscale = 1;
4275 vwscale = 1; /* The datasheet says 0;
4276 * it's wrong */
4277 }
4278 break;
4279 case SEN_OV8610:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004280 if (qvga) { /* QSVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004281 hwscale = 1;
4282 vwscale = 1;
4283 } else { /* SVGA */
4284 hwscale = 2;
4285 vwscale = 2;
4286 }
4287 break;
4288 default: /* SEN_OV7xx0 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004289 if (qvga) { /* QVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004290 hwscale = 1;
4291 vwscale = 0;
4292 } else { /* VGA */
4293 hwscale = 2;
4294 vwscale = 1;
4295 }
4296 }
4297
Jean-François Moinef8f20182010-11-12 07:54:02 -03004298 mode_init_ov_sensor_regs(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004299
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004300 i2c_w(sd, 0x17, hwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03004301 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004302 i2c_w(sd, 0x19, vwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03004303 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004304}
4305
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004306/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03004307static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004308{
4309 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004310
Hans de Goedea511ba92009-10-16 07:13:07 -03004311 /* Default for most bridges, allow bridge_mode_init_regs to override */
4312 sd->sensor_width = sd->gspca_dev.width;
4313 sd->sensor_height = sd->gspca_dev.height;
4314
Hans de Goede49809d62009-06-07 12:10:39 -03004315 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03004316 case BRIDGE_OV511:
4317 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004318 ov511_mode_init_regs(sd);
Hans de Goede1876bb92009-06-14 06:45:50 -03004319 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004320 case BRIDGE_OV518:
4321 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004322 ov518_mode_init_regs(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03004323 break;
4324 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004325 ov519_mode_init_regs(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03004326 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004327 /* case BRIDGE_OVFX2: nothing to do */
Hans de Goedea511ba92009-10-16 07:13:07 -03004328 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004329 w9968cf_mode_init_regs(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03004330 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004331 }
Hans de Goede49809d62009-06-07 12:10:39 -03004332
Jean-François Moinef8f20182010-11-12 07:54:02 -03004333 set_ov_sensor_window(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004334
Jean-François Moinee2817022010-11-12 13:59:48 -03004335 if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST)))
4336 setcontrast(gspca_dev);
4337 if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
4338 setbrightness(gspca_dev);
Jean-François Moine58c92d32011-03-13 16:36:49 -03004339 if (!(sd->gspca_dev.ctrl_dis & (1 << EXPOSURE)))
4340 setexposure(gspca_dev);
Jean-François Moinee2817022010-11-12 13:59:48 -03004341 if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
4342 setcolors(gspca_dev);
4343 if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
4344 sethvflip(gspca_dev);
4345 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
4346 setautobright(gspca_dev);
Jean-François Moine58c92d32011-03-13 16:36:49 -03004347 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOGAIN)))
4348 setautogain(gspca_dev);
Jean-François Moinee2817022010-11-12 13:59:48 -03004349 if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
4350 setfreq_i(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03004351
Hans de Goede417a4d22010-02-19 07:37:08 -03004352 /* Force clear snapshot state in case the snapshot button was
4353 pressed while we weren't streaming */
4354 sd->snapshot_needs_reset = 1;
4355 sd_reset_snapshot(gspca_dev);
Hans de Goede417a4d22010-02-19 07:37:08 -03004356
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004357 sd->first_frame = 3;
4358
Jean-François Moinef8f20182010-11-12 07:54:02 -03004359 ov51x_restart(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004360 ov51x_led_control(sd, 1);
Jean-François Moinef8f20182010-11-12 07:54:02 -03004361 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004362}
4363
4364static void sd_stopN(struct gspca_dev *gspca_dev)
4365{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004366 struct sd *sd = (struct sd *) gspca_dev;
4367
4368 ov51x_stop(sd);
4369 ov51x_led_control(sd, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004370}
4371
Hans de Goede79b35902009-10-19 06:08:01 -03004372static void sd_stop0(struct gspca_dev *gspca_dev)
4373{
4374 struct sd *sd = (struct sd *) gspca_dev;
4375
Jean-François Moined65174c2010-11-11 06:20:42 -03004376 if (!sd->gspca_dev.present)
4377 return;
Hans de Goede79b35902009-10-19 06:08:01 -03004378 if (sd->bridge == BRIDGE_W9968CF)
4379 w9968cf_stop0(sd);
Hans de Goede614d0692010-10-27 07:42:28 -03004380
Jean-François Moine14653e62010-11-11 06:17:01 -03004381#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede614d0692010-10-27 07:42:28 -03004382 /* If the last button state is pressed, release it now! */
4383 if (sd->snapshot_pressed) {
4384 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
4385 input_sync(gspca_dev->input_dev);
4386 sd->snapshot_pressed = 0;
4387 }
4388#endif
Jean-François Moineb4e96ea2010-11-12 16:13:17 -03004389 if (sd->bridge == BRIDGE_OV519)
4390 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
Hans de Goede79b35902009-10-19 06:08:01 -03004391}
4392
Hans de Goede92e232a2010-02-20 04:30:45 -03004393static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
4394{
4395 struct sd *sd = (struct sd *) gspca_dev;
4396
4397 if (sd->snapshot_pressed != state) {
Jean-François Moine28566432010-10-01 07:33:26 -03004398#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede92e232a2010-02-20 04:30:45 -03004399 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
4400 input_sync(gspca_dev->input_dev);
4401#endif
4402 if (state)
4403 sd->snapshot_needs_reset = 1;
4404
4405 sd->snapshot_pressed = state;
4406 } else {
Hans de Goede88e8d202010-02-20 04:45:49 -03004407 /* On the ov511 / ov519 we need to reset the button state
4408 multiple times, as resetting does not work as long as the
4409 button stays pressed */
4410 switch (sd->bridge) {
4411 case BRIDGE_OV511:
4412 case BRIDGE_OV511PLUS:
4413 case BRIDGE_OV519:
4414 if (state)
4415 sd->snapshot_needs_reset = 1;
4416 break;
4417 }
Hans de Goede92e232a2010-02-20 04:30:45 -03004418 }
4419}
4420
Hans de Goede1876bb92009-06-14 06:45:50 -03004421static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004422 u8 *in, /* isoc packet */
4423 int len) /* iso packet length */
Hans de Goede1876bb92009-06-14 06:45:50 -03004424{
4425 struct sd *sd = (struct sd *) gspca_dev;
4426
4427 /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
4428 * byte non-zero. The EOF packet has image width/height in the
4429 * 10th and 11th bytes. The 9th byte is given as follows:
4430 *
4431 * bit 7: EOF
4432 * 6: compression enabled
4433 * 5: 422/420/400 modes
4434 * 4: 422/420/400 modes
4435 * 3: 1
4436 * 2: snapshot button on
4437 * 1: snapshot frame
4438 * 0: even/odd field
4439 */
4440 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
4441 (in[8] & 0x08)) {
Hans de Goede88e8d202010-02-20 04:45:49 -03004442 ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
Hans de Goede1876bb92009-06-14 06:45:50 -03004443 if (in[8] & 0x80) {
4444 /* Frame end */
4445 if ((in[9] + 1) * 8 != gspca_dev->width ||
4446 (in[10] + 1) * 8 != gspca_dev->height) {
4447 PDEBUG(D_ERR, "Invalid frame size, got: %dx%d,"
4448 " requested: %dx%d\n",
4449 (in[9] + 1) * 8, (in[10] + 1) * 8,
4450 gspca_dev->width, gspca_dev->height);
4451 gspca_dev->last_packet_type = DISCARD_PACKET;
4452 return;
4453 }
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004454 /* Add 11 byte footer to frame, might be useful */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004455 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
Hans de Goede1876bb92009-06-14 06:45:50 -03004456 return;
4457 } else {
4458 /* Frame start */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004459 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
Hans de Goede1876bb92009-06-14 06:45:50 -03004460 sd->packet_nr = 0;
4461 }
4462 }
4463
4464 /* Ignore the packet number */
4465 len--;
4466
4467 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004468 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
Hans de Goede1876bb92009-06-14 06:45:50 -03004469}
4470
Hans de Goede49809d62009-06-07 12:10:39 -03004471static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004472 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004473 int len) /* iso packet length */
4474{
Hans de Goede92918a52009-06-14 06:21:35 -03004475 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03004476
4477 /* A false positive here is likely, until OVT gives me
4478 * the definitive SOF/EOF format */
4479 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
Hans de Goede92e232a2010-02-20 04:30:45 -03004480 ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004481 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4482 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goede92918a52009-06-14 06:21:35 -03004483 sd->packet_nr = 0;
4484 }
4485
4486 if (gspca_dev->last_packet_type == DISCARD_PACKET)
4487 return;
4488
4489 /* Does this device use packet numbers ? */
4490 if (len & 7) {
4491 len--;
4492 if (sd->packet_nr == data[len])
4493 sd->packet_nr++;
4494 /* The last few packets of the frame (which are all 0's
4495 except that they may contain part of the footer), are
4496 numbered 0 */
4497 else if (sd->packet_nr == 0 || data[len]) {
4498 PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)",
4499 (int)data[len], (int)sd->packet_nr);
4500 gspca_dev->last_packet_type = DISCARD_PACKET;
4501 return;
4502 }
Hans de Goede49809d62009-06-07 12:10:39 -03004503 }
4504
4505 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004506 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004507}
4508
4509static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004510 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004511 int len) /* iso packet length */
4512{
4513 /* Header of ov519 is 16 bytes:
4514 * Byte Value Description
4515 * 0 0xff magic
4516 * 1 0xff magic
4517 * 2 0xff magic
4518 * 3 0xXX 0x50 = SOF, 0x51 = EOF
4519 * 9 0xXX 0x01 initial frame without data,
4520 * 0x00 standard frame with image
4521 * 14 Lo in EOF: length of image data / 8
4522 * 15 Hi
4523 */
4524
4525 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4526 switch (data[3]) {
4527 case 0x50: /* start of frame */
Hans de Goede417a4d22010-02-19 07:37:08 -03004528 /* Don't check the button state here, as the state
4529 usually (always ?) changes at EOF and checking it
4530 here leads to unnecessary snapshot state resets. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004531#define HDRSZ 16
4532 data += HDRSZ;
4533 len -= HDRSZ;
4534#undef HDRSZ
4535 if (data[0] == 0xff || data[1] == 0xd8)
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004536 gspca_frame_add(gspca_dev, FIRST_PACKET,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004537 data, len);
4538 else
4539 gspca_dev->last_packet_type = DISCARD_PACKET;
4540 return;
4541 case 0x51: /* end of frame */
Hans de Goede92e232a2010-02-20 04:30:45 -03004542 ov51x_handle_button(gspca_dev, data[11] & 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004543 if (data[9] != 0)
4544 gspca_dev->last_packet_type = DISCARD_PACKET;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004545 gspca_frame_add(gspca_dev, LAST_PACKET,
4546 NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004547 return;
4548 }
4549 }
4550
4551 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004552 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004553}
4554
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004555static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004556 u8 *data, /* isoc packet */
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004557 int len) /* iso packet length */
4558{
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004559 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004560
4561 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4562
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004563 /* A short read signals EOF */
Jean-François Moine9d2b9092011-05-22 04:56:32 -03004564 if (len < gspca_dev->cam.bulk_size) {
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004565 /* If the frame is short, and it is one of the first ones
4566 the sensor and bridge are still syncing, so drop it. */
4567 if (sd->first_frame) {
4568 sd->first_frame--;
Jean-François Moineb192ca92010-06-27 03:08:19 -03004569 if (gspca_dev->image_len <
4570 sd->gspca_dev.width * sd->gspca_dev.height)
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004571 gspca_dev->last_packet_type = DISCARD_PACKET;
4572 }
4573 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004574 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004575 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004576}
4577
Hans de Goede49809d62009-06-07 12:10:39 -03004578static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004579 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004580 int len) /* iso packet length */
4581{
4582 struct sd *sd = (struct sd *) gspca_dev;
4583
4584 switch (sd->bridge) {
4585 case BRIDGE_OV511:
4586 case BRIDGE_OV511PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004587 ov511_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004588 break;
4589 case BRIDGE_OV518:
4590 case BRIDGE_OV518PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004591 ov518_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004592 break;
4593 case BRIDGE_OV519:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004594 ov519_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004595 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004596 case BRIDGE_OVFX2:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004597 ovfx2_pkt_scan(gspca_dev, data, len);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004598 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03004599 case BRIDGE_W9968CF:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004600 w9968cf_pkt_scan(gspca_dev, data, len);
Hans de Goedea511ba92009-10-16 07:13:07 -03004601 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004602 }
4603}
4604
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004605/* -- management routines -- */
4606
4607static void setbrightness(struct gspca_dev *gspca_dev)
4608{
4609 struct sd *sd = (struct sd *) gspca_dev;
4610 int val;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004611 static const struct ov_i2c_regvals brit_7660[][7] = {
4612 {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
4613 {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
4614 {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
4615 {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
4616 {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
4617 {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
4618 {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
4619 {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
4620 {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
4621 {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
4622 {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
4623 {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
4624 {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
4625 {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
4626 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004627
Jean-François Moine62833ac2010-10-02 04:27:02 -03004628 val = sd->ctrls[BRIGHTNESS].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004629 switch (sd->sensor) {
4630 case SEN_OV8610:
4631 case SEN_OV7610:
4632 case SEN_OV76BE:
4633 case SEN_OV6620:
4634 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004635 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004636 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004637 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004638 i2c_w(sd, OV7610_REG_BRT, val);
4639 break;
4640 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004641 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004642 /* 7620 doesn't like manual changes when in auto mode */
Jean-François Moine62833ac2010-10-02 04:27:02 -03004643 if (!sd->ctrls[AUTOBRIGHT].val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004644 i2c_w(sd, OV7610_REG_BRT, val);
4645 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004646 case SEN_OV7660:
4647 write_i2c_regvals(sd, brit_7660[val],
4648 ARRAY_SIZE(brit_7660[0]));
4649 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004650 case SEN_OV7670:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004651/*win trace
Jean-François Moine21867802010-11-12 06:12:09 -03004652 * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
4653 i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004654 break;
4655 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004656}
4657
4658static void setcontrast(struct gspca_dev *gspca_dev)
4659{
4660 struct sd *sd = (struct sd *) gspca_dev;
4661 int val;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004662 static const struct ov_i2c_regvals contrast_7660[][31] = {
4663 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
4664 {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
4665 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
4666 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
4667 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
4668 {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
4669 {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
4670 {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
4671 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
4672 {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
4673 {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
4674 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
4675 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
4676 {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
4677 {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
4678 {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
4679 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
4680 {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
4681 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
4682 {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
4683 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
4684 {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
4685 {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
4686 {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
4687 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
4688 {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
4689 {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
4690 {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
4691 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
4692 {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
4693 {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
4694 {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
4695 {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
4696 {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
4697 {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
4698 {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
4699 {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
4700 {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
4701 {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
4702 {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
4703 {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
4704 {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
4705 {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
4706 {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
4707 {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
4708 {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
4709 {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
4710 {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
4711 {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
4712 {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
4713 {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
4714 {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
4715 {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
4716 {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
4717 {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
4718 {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
4719 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004720
Jean-François Moine62833ac2010-10-02 04:27:02 -03004721 val = sd->ctrls[CONTRAST].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004722 switch (sd->sensor) {
4723 case SEN_OV7610:
4724 case SEN_OV6620:
4725 i2c_w(sd, OV7610_REG_CNT, val);
4726 break;
4727 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004728 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004729 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
Hans de Goede49809d62009-06-07 12:10:39 -03004730 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004731 case SEN_OV8610: {
Jean-François Moine9d1593a2010-11-11 08:04:06 -03004732 static const u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004733 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
4734 };
4735
4736 /* Use Y gamma control instead. Bit 0 enables it. */
4737 i2c_w(sd, 0x64, ctab[val >> 5]);
4738 break;
4739 }
Hans de Goede859cc472010-01-07 15:42:35 -03004740 case SEN_OV7620:
4741 case SEN_OV7620AE: {
Jean-François Moine9d1593a2010-11-11 08:04:06 -03004742 static const u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004743 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4744 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
4745 };
4746
4747 /* Use Y gamma control instead. Bit 0 enables it. */
4748 i2c_w(sd, 0x64, ctab[val >> 4]);
4749 break;
4750 }
Jean-François Moine42e142f2010-11-13 05:10:27 -03004751 case SEN_OV7660:
4752 write_i2c_regvals(sd, contrast_7660[val],
4753 ARRAY_SIZE(contrast_7660[0]));
4754 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004755 case SEN_OV7670:
4756 /* check that this isn't just the same as ov7610 */
Jean-François Moine21867802010-11-12 06:12:09 -03004757 i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004758 break;
4759 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004760}
4761
Jean-François Moine58c92d32011-03-13 16:36:49 -03004762static void setexposure(struct gspca_dev *gspca_dev)
4763{
4764 struct sd *sd = (struct sd *) gspca_dev;
4765
4766 if (!sd->ctrls[AUTOGAIN].val)
4767 i2c_w(sd, 0x10, sd->ctrls[EXPOSURE].val);
4768}
4769
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004770static void setcolors(struct gspca_dev *gspca_dev)
4771{
4772 struct sd *sd = (struct sd *) gspca_dev;
4773 int val;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004774 static const struct ov_i2c_regvals colors_7660[][6] = {
4775 {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
4776 {0x53, 0x19}, {0x54, 0x23}},
4777 {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
4778 {0x53, 0x2c}, {0x54, 0x3e}},
4779 {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
4780 {0x53, 0x40}, {0x54, 0x59}},
4781 {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
4782 {0x53, 0x53}, {0x54, 0x73}},
4783 {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
4784 {0x53, 0x66}, {0x54, 0x8e}},
4785 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004786
Jean-François Moine62833ac2010-10-02 04:27:02 -03004787 val = sd->ctrls[COLORS].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004788 switch (sd->sensor) {
4789 case SEN_OV8610:
4790 case SEN_OV7610:
4791 case SEN_OV76BE:
4792 case SEN_OV6620:
4793 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004794 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004795 i2c_w(sd, OV7610_REG_SAT, val);
4796 break;
4797 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004798 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004799 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
4800/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
4801 if (rc < 0)
4802 goto out; */
4803 i2c_w(sd, OV7610_REG_SAT, val);
4804 break;
4805 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004806 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004807 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4808 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004809 case SEN_OV7660:
4810 write_i2c_regvals(sd, colors_7660[val],
4811 ARRAY_SIZE(colors_7660[0]));
4812 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004813 case SEN_OV7670:
4814 /* supported later once I work out how to do it
4815 * transparently fail now! */
4816 /* set REG_COM13 values for UV sat auto mode */
4817 break;
4818 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004819}
4820
Jean-François Moine62833ac2010-10-02 04:27:02 -03004821static void setautobright(struct gspca_dev *gspca_dev)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004822{
Jean-François Moine62833ac2010-10-02 04:27:02 -03004823 struct sd *sd = (struct sd *) gspca_dev;
4824
Jean-François Moine62833ac2010-10-02 04:27:02 -03004825 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004826}
4827
Jean-François Moine58c92d32011-03-13 16:36:49 -03004828static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
4829{
4830 struct sd *sd = (struct sd *) gspca_dev;
4831
4832 sd->ctrls[AUTOGAIN].val = val;
4833 if (val) {
4834 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
4835 } else {
4836 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
4837 sd->ctrls[EXPOSURE].val = i2c_r(sd, 0x10);
4838 }
4839 if (gspca_dev->streaming)
4840 setautogain(gspca_dev);
4841 return gspca_dev->usb_err;
4842}
4843
Jean-François Moine62833ac2010-10-02 04:27:02 -03004844static void setfreq_i(struct sd *sd)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004845{
Jean-François Moine42e142f2010-11-13 05:10:27 -03004846 if (sd->sensor == SEN_OV7660
4847 || sd->sensor == SEN_OV7670) {
Jean-François Moine62833ac2010-10-02 04:27:02 -03004848 switch (sd->ctrls[FREQ].val) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004849 case 0: /* Banding filter disabled */
Jean-François Moine21867802010-11-12 06:12:09 -03004850 i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004851 break;
4852 case 1: /* 50 hz */
Jean-François Moine21867802010-11-12 06:12:09 -03004853 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004854 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004855 i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004856 break;
4857 case 2: /* 60 hz */
Jean-François Moine21867802010-11-12 06:12:09 -03004858 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004859 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004860 i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004861 break;
Jean-François Moine21867802010-11-12 06:12:09 -03004862 case 3: /* Auto hz - ov7670 only */
4863 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004864 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004865 i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004866 0x18);
4867 break;
4868 }
4869 } else {
Jean-François Moine62833ac2010-10-02 04:27:02 -03004870 switch (sd->ctrls[FREQ].val) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004871 case 0: /* Banding filter disabled */
4872 i2c_w_mask(sd, 0x2d, 0x00, 0x04);
4873 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4874 break;
4875 case 1: /* 50 hz (filter on and framerate adj) */
4876 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4877 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4878 /* 20 fps -> 16.667 fps */
4879 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004880 sd->sensor == SEN_OV6630 ||
4881 sd->sensor == SEN_OV66308AF)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004882 i2c_w(sd, 0x2b, 0x5e);
4883 else
4884 i2c_w(sd, 0x2b, 0xac);
4885 break;
4886 case 2: /* 60 hz (filter on, ...) */
4887 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4888 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004889 sd->sensor == SEN_OV6630 ||
4890 sd->sensor == SEN_OV66308AF) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004891 /* 20 fps -> 15 fps */
4892 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4893 i2c_w(sd, 0x2b, 0xa8);
4894 } else {
4895 /* no framerate adj. */
4896 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4897 }
4898 break;
4899 }
4900 }
4901}
Jean-François Moine62833ac2010-10-02 04:27:02 -03004902static void setfreq(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004903{
4904 struct sd *sd = (struct sd *) gspca_dev;
4905
Jean-François Moine62833ac2010-10-02 04:27:02 -03004906 setfreq_i(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004907
Jean-François Moine62833ac2010-10-02 04:27:02 -03004908 /* Ugly but necessary */
4909 if (sd->bridge == BRIDGE_W9968CF)
4910 w9968cf_set_crop_window(sd);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004911}
4912
4913static int sd_querymenu(struct gspca_dev *gspca_dev,
4914 struct v4l2_querymenu *menu)
4915{
4916 struct sd *sd = (struct sd *) gspca_dev;
4917
4918 switch (menu->id) {
4919 case V4L2_CID_POWER_LINE_FREQUENCY:
4920 switch (menu->index) {
4921 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
4922 strcpy((char *) menu->name, "NoFliker");
4923 return 0;
4924 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
4925 strcpy((char *) menu->name, "50 Hz");
4926 return 0;
4927 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
4928 strcpy((char *) menu->name, "60 Hz");
4929 return 0;
4930 case 3:
4931 if (sd->sensor != SEN_OV7670)
4932 return -EINVAL;
4933
4934 strcpy((char *) menu->name, "Automatic");
4935 return 0;
4936 }
4937 break;
4938 }
4939 return -EINVAL;
4940}
4941
Hans de Goede79b35902009-10-19 06:08:01 -03004942static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4943 struct v4l2_jpegcompression *jcomp)
4944{
4945 struct sd *sd = (struct sd *) gspca_dev;
4946
4947 if (sd->bridge != BRIDGE_W9968CF)
4948 return -EINVAL;
4949
4950 memset(jcomp, 0, sizeof *jcomp);
4951 jcomp->quality = sd->quality;
4952 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4953 V4L2_JPEG_MARKER_DRI;
4954 return 0;
4955}
4956
4957static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4958 struct v4l2_jpegcompression *jcomp)
4959{
4960 struct sd *sd = (struct sd *) gspca_dev;
4961
4962 if (sd->bridge != BRIDGE_W9968CF)
4963 return -EINVAL;
4964
4965 if (gspca_dev->streaming)
4966 return -EBUSY;
4967
4968 if (jcomp->quality < QUALITY_MIN)
4969 sd->quality = QUALITY_MIN;
4970 else if (jcomp->quality > QUALITY_MAX)
4971 sd->quality = QUALITY_MAX;
4972 else
4973 sd->quality = jcomp->quality;
4974
4975 /* Return resulting jcomp params to app */
4976 sd_get_jcomp(gspca_dev, jcomp);
4977
4978 return 0;
4979}
4980
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004981/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004982static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004983 .name = MODULE_NAME,
4984 .ctrls = sd_ctrls,
4985 .nctrls = ARRAY_SIZE(sd_ctrls),
4986 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03004987 .init = sd_init,
Jean-François Moinec42cedb2011-02-10 13:37:48 -03004988 .isoc_init = sd_isoc_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004989 .start = sd_start,
4990 .stopN = sd_stopN,
Hans de Goede79b35902009-10-19 06:08:01 -03004991 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004992 .pkt_scan = sd_pkt_scan,
Hans de Goede417a4d22010-02-19 07:37:08 -03004993 .dq_callback = sd_reset_snapshot,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004994 .querymenu = sd_querymenu,
Hans de Goede79b35902009-10-19 06:08:01 -03004995 .get_jcomp = sd_get_jcomp,
4996 .set_jcomp = sd_set_jcomp,
Jean-François Moine28566432010-10-01 07:33:26 -03004997#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede417a4d22010-02-19 07:37:08 -03004998 .other_input = 1,
4999#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03005000};
5001
5002/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -03005003static const struct usb_device_id device_table[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03005004 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
Hans de Goede49809d62009-06-07 12:10:39 -03005005 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
5006 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
5007 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
5008 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03005009 {USB_DEVICE(0x041e, 0x4064),
Jean-François Moine87bae742010-11-12 05:31:34 -03005010 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Rafal Milecki518c8df2009-10-02 03:54:44 -03005011 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03005012 {USB_DEVICE(0x041e, 0x4068),
Jean-François Moine87bae742010-11-12 05:31:34 -03005013 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede49809d62009-06-07 12:10:39 -03005014 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
5015 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
Hans de Goede98184f72010-01-07 12:06:00 -03005016 {USB_DEVICE(0x054c, 0x0155),
Jean-François Moine87bae742010-11-12 05:31:34 -03005017 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede1876bb92009-06-14 06:45:50 -03005018 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
Hans de Goede49809d62009-06-07 12:10:39 -03005019 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
5020 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
5021 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03005022 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
Hans de Goede49809d62009-06-07 12:10:39 -03005023 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
5024 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
Hans de Goede1876bb92009-06-14 06:45:50 -03005025 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
Hans de Goede49809d62009-06-07 12:10:39 -03005026 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
Hans de Goede1876bb92009-06-14 06:45:50 -03005027 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03005028 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
5029 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
Hans de Goedea511ba92009-10-16 07:13:07 -03005030 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
Jean-François Moine87bae742010-11-12 05:31:34 -03005031 {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03005032 {}
5033};
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03005034
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03005035MODULE_DEVICE_TABLE(usb, device_table);
5036
5037/* -- device connect -- */
5038static int sd_probe(struct usb_interface *intf,
5039 const struct usb_device_id *id)
5040{
5041 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
5042 THIS_MODULE);
5043}
5044
5045static struct usb_driver sd_driver = {
5046 .name = MODULE_NAME,
5047 .id_table = device_table,
5048 .probe = sd_probe,
5049 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03005050#ifdef CONFIG_PM
5051 .suspend = gspca_suspend,
5052 .resume = gspca_resume,
5053#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03005054};
5055
5056/* -- module insert / remove -- */
5057static int __init sd_mod_init(void)
5058{
Jean-François Moine54826432010-09-13 04:53:03 -03005059 return usb_register(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03005060}
5061static void __exit sd_mod_exit(void)
5062{
5063 usb_deregister(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03005064}
5065
5066module_init(sd_mod_init);
5067module_exit(sd_mod_exit);
5068
5069module_param(frame_rate, int, 0644);
5070MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");