blob: fd1b6082c96daec8b4312ac67106bac4ad7b13ac [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 Beauxis2961e8752008-12-05 06:25:26 -03007 * This module is adapted from the ov51x-jpeg package, which itself
8 * was adapted from the ov511 driver.
9 *
10 * Original copyright for the ov511 driver is:
11 *
Hans de Goedeb46aaa02009-10-12 10:07:57 -030012 * Copyright (c) 1999-2006 Mark W. McClelland
Romain Beauxis2961e8752008-12-05 06:25:26 -030013 * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach
Hans de Goedeb46aaa02009-10-12 10:07:57 -030014 * Many improvements by Bret Wallach <bwallac1@san.rr.com>
15 * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
16 * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
17 * Changes by Claudio Matsuoka <claudio@conectiva.com>
Romain Beauxis2961e8752008-12-05 06:25:26 -030018 *
19 * ov51x-jpeg original copyright is:
20 *
21 * Copyright (c) 2004-2007 Romain Beauxis <toots@rastageeks.org>
22 * Support for OV7670 sensors was contributed by Sam Skipsey <aoanla@yahoo.com>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030023 *
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * any later version.
28 *
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
33 *
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 *
38 */
39#define MODULE_NAME "ov519"
40
Hans de Goede417a4d22010-02-19 07:37:08 -030041#include <linux/input.h>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030042#include "gspca.h"
43
Jean-François Moine9a731a32010-06-04 05:26:42 -030044/* The jpeg_hdr is used by w996Xcf only */
45/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
46#define CONEX_CAM
47#include "jpeg.h"
48
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030049MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
50MODULE_DESCRIPTION("OV519 USB Camera Driver");
51MODULE_LICENSE("GPL");
52
53/* global parameters */
54static int frame_rate;
55
56/* Number of times to retry a failed I2C transaction. Increase this if you
57 * are getting "Failed to read sensor ID..." */
58static int i2c_detect_tries = 10;
59
Jean-François Moine62833ac2010-10-02 04:27:02 -030060/* controls */
61enum e_ctrl {
62 BRIGHTNESS,
63 CONTRAST,
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,
137};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300138
Hans de Goedea511ba92009-10-16 07:13:07 -0300139/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
140 the ov sensors which is already present here. When we have the time we
141 really should move the sensor drivers to v4l2 sub drivers. */
142#include "w996Xcf.c"
143
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300144/* V4L2 controls supported by the driver */
Hans de Goede49809d62009-06-07 12:10:39 -0300145static void setbrightness(struct gspca_dev *gspca_dev);
146static void setcontrast(struct gspca_dev *gspca_dev);
Jean-François Moine58c92d32011-03-13 16:36:49 -0300147static void setexposure(struct gspca_dev *gspca_dev);
Hans de Goede49809d62009-06-07 12:10:39 -0300148static void setcolors(struct gspca_dev *gspca_dev);
Jean-François Moine62833ac2010-10-02 04:27:02 -0300149static void sethvflip(struct gspca_dev *gspca_dev);
150static void setautobright(struct gspca_dev *gspca_dev);
Jean-François Moine58c92d32011-03-13 16:36:49 -0300151static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
Jean-François Moine62833ac2010-10-02 04:27:02 -0300152static void setfreq(struct gspca_dev *gspca_dev);
153static void setfreq_i(struct sd *sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300154
Hans de Goede02ab18b2009-06-14 04:32:04 -0300155static const struct ctrl sd_ctrls[] = {
Jean-François Moine62833ac2010-10-02 04:27:02 -0300156[BRIGHTNESS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300157 {
158 .id = V4L2_CID_BRIGHTNESS,
159 .type = V4L2_CTRL_TYPE_INTEGER,
160 .name = "Brightness",
161 .minimum = 0,
162 .maximum = 255,
163 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300164 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300165 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300166 .set_control = setbrightness,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300167 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300168[CONTRAST] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300169 {
170 .id = V4L2_CID_CONTRAST,
171 .type = V4L2_CTRL_TYPE_INTEGER,
172 .name = "Contrast",
173 .minimum = 0,
174 .maximum = 255,
175 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300176 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300177 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300178 .set_control = setcontrast,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300179 },
Jean-François Moine58c92d32011-03-13 16:36:49 -0300180[EXPOSURE] = {
181 {
182 .id = V4L2_CID_EXPOSURE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "Exposure",
185 .minimum = 0,
186 .maximum = 255,
187 .step = 1,
188 .default_value = 127,
189 },
190 .set_control = setexposure,
191 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300192[COLORS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300193 {
194 .id = V4L2_CID_SATURATION,
195 .type = V4L2_CTRL_TYPE_INTEGER,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300196 .name = "Color",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300197 .minimum = 0,
198 .maximum = 255,
199 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300200 .default_value = 127,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300201 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300202 .set_control = setcolors,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300203 },
Jean-François Moine42e142f2010-11-13 05:10:27 -0300204/* The flip controls work for sensors ov7660 and ov7670 only */
Jean-François Moine62833ac2010-10-02 04:27:02 -0300205[HFLIP] = {
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300206 {
207 .id = V4L2_CID_HFLIP,
208 .type = V4L2_CTRL_TYPE_BOOLEAN,
209 .name = "Mirror",
210 .minimum = 0,
211 .maximum = 1,
212 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300213 .default_value = 0,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300214 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300215 .set_control = sethvflip,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300216 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300217[VFLIP] = {
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300218 {
219 .id = V4L2_CID_VFLIP,
220 .type = V4L2_CTRL_TYPE_BOOLEAN,
221 .name = "Vflip",
222 .minimum = 0,
223 .maximum = 1,
224 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300225 .default_value = 0,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300226 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300227 .set_control = sethvflip,
Jean-Francois Moine0cd67592008-07-29 05:25:28 -0300228 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300229[AUTOBRIGHT] = {
Hans de Goede02ab18b2009-06-14 04:32:04 -0300230 {
231 .id = V4L2_CID_AUTOBRIGHTNESS,
232 .type = V4L2_CTRL_TYPE_BOOLEAN,
233 .name = "Auto Brightness",
234 .minimum = 0,
235 .maximum = 1,
236 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300237 .default_value = 1,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300238 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300239 .set_control = setautobright,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300240 },
Jean-François Moine58c92d32011-03-13 16:36:49 -0300241[AUTOGAIN] = {
242 {
243 .id = V4L2_CID_AUTOGAIN,
244 .type = V4L2_CTRL_TYPE_BOOLEAN,
245 .name = "Auto Gain",
246 .minimum = 0,
247 .maximum = 1,
248 .step = 1,
249 .default_value = 1,
250 .flags = V4L2_CTRL_FLAG_UPDATE
251 },
252 .set = sd_setautogain,
253 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300254[FREQ] = {
Hans de Goede02ab18b2009-06-14 04:32:04 -0300255 {
256 .id = V4L2_CID_POWER_LINE_FREQUENCY,
257 .type = V4L2_CTRL_TYPE_MENU,
258 .name = "Light frequency filter",
259 .minimum = 0,
Jean-François Moine87bae742010-11-12 05:31:34 -0300260 .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */
Hans de Goede02ab18b2009-06-14 04:32:04 -0300261 .step = 1,
Jean-François Moine62833ac2010-10-02 04:27:02 -0300262 .default_value = 0,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300263 },
Jean-François Moine62833ac2010-10-02 04:27:02 -0300264 .set_control = setfreq,
Hans de Goede02ab18b2009-06-14 04:32:04 -0300265 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300266};
267
Jean-François Moine83db7682010-11-12 07:14:08 -0300268/* table of the disabled controls */
269static const unsigned ctrl_dis[] = {
Jean-François Moine58c92d32011-03-13 16:36:49 -0300270[SEN_OV2610] = ((1 << NCTRL) - 1) /* no control */
271 ^ ((1 << EXPOSURE) /* but exposure */
272 | (1 << AUTOGAIN)), /* and autogain */
Jean-François Moine83db7682010-11-12 07:14:08 -0300273
Jean-François Moine58c92d32011-03-13 16:36:49 -0300274[SEN_OV2610AE] = ((1 << NCTRL) - 1) /* no control */
275 ^ ((1 << EXPOSURE) /* but exposure */
276 | (1 << AUTOGAIN)), /* and autogain */
Jean-François Moine07c6c9c2011-02-10 13:32:22 -0300277
Jean-François Moine83db7682010-11-12 07:14:08 -0300278[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
279
280[SEN_OV6620] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300281 (1 << VFLIP) |
282 (1 << EXPOSURE) |
283 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300284
285[SEN_OV6630] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300286 (1 << VFLIP) |
287 (1 << EXPOSURE) |
288 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300289
290[SEN_OV66308AF] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300291 (1 << VFLIP) |
292 (1 << EXPOSURE) |
293 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300294
295[SEN_OV7610] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300296 (1 << VFLIP) |
297 (1 << EXPOSURE) |
298 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300299
300[SEN_OV7620] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300301 (1 << VFLIP) |
302 (1 << EXPOSURE) |
303 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300304
305[SEN_OV7620AE] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300306 (1 << VFLIP) |
307 (1 << EXPOSURE) |
308 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300309
310[SEN_OV7640] = (1 << HFLIP) |
311 (1 << VFLIP) |
312 (1 << AUTOBRIGHT) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300313 (1 << CONTRAST) |
314 (1 << EXPOSURE) |
315 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300316
317[SEN_OV7648] = (1 << HFLIP) |
318 (1 << VFLIP) |
319 (1 << AUTOBRIGHT) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300320 (1 << CONTRAST) |
321 (1 << EXPOSURE) |
322 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300323
Jean-François Moine58c92d32011-03-13 16:36:49 -0300324[SEN_OV7660] = (1 << AUTOBRIGHT) |
325 (1 << EXPOSURE) |
326 (1 << AUTOGAIN),
Jean-François Moine42e142f2010-11-13 05:10:27 -0300327
Jean-François Moine83db7682010-11-12 07:14:08 -0300328[SEN_OV7670] = (1 << COLORS) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300329 (1 << AUTOBRIGHT) |
330 (1 << EXPOSURE) |
331 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300332
333[SEN_OV76BE] = (1 << HFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300334 (1 << VFLIP) |
335 (1 << EXPOSURE) |
336 (1 << AUTOGAIN),
Jean-François Moine83db7682010-11-12 07:14:08 -0300337
338[SEN_OV8610] = (1 << HFLIP) |
339 (1 << VFLIP) |
Jean-François Moine58c92d32011-03-13 16:36:49 -0300340 (1 << EXPOSURE) |
341 (1 << AUTOGAIN) |
Jean-François Moine83db7682010-11-12 07:14:08 -0300342 (1 << FREQ),
343};
344
Hans de Goede49809d62009-06-07 12:10:39 -0300345static const struct v4l2_pix_format ov519_vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300346 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
347 .bytesperline = 320,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300348 .sizeimage = 320 * 240 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300349 .colorspace = V4L2_COLORSPACE_JPEG,
350 .priv = 1},
351 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
352 .bytesperline = 640,
353 .sizeimage = 640 * 480 * 3 / 8 + 590,
354 .colorspace = V4L2_COLORSPACE_JPEG,
355 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300356};
Hans de Goede49809d62009-06-07 12:10:39 -0300357static const struct v4l2_pix_format ov519_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300358 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
359 .bytesperline = 160,
360 .sizeimage = 160 * 120 * 3 / 8 + 590,
361 .colorspace = V4L2_COLORSPACE_JPEG,
362 .priv = 3},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300363 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
364 .bytesperline = 176,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300365 .sizeimage = 176 * 144 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300366 .colorspace = V4L2_COLORSPACE_JPEG,
367 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300368 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
369 .bytesperline = 320,
370 .sizeimage = 320 * 240 * 3 / 8 + 590,
371 .colorspace = V4L2_COLORSPACE_JPEG,
372 .priv = 2},
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300373 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
374 .bytesperline = 352,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -0300375 .sizeimage = 352 * 288 * 3 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300376 .colorspace = V4L2_COLORSPACE_JPEG,
377 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300378};
379
Hans de Goedeb282d872009-06-14 19:10:40 -0300380/* Note some of the sizeimage values for the ov511 / ov518 may seem
381 larger then necessary, however they need to be this big as the ov511 /
382 ov518 always fills the entire isoc frame, using 0 padding bytes when
383 it doesn't have any data. So with low framerates the amount of data
384 transfered can become quite large (libv4l will remove all the 0 padding
385 in userspace). */
Hans de Goede49809d62009-06-07 12:10:39 -0300386static const struct v4l2_pix_format ov518_vga_mode[] = {
387 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
388 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300389 .sizeimage = 320 * 240 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300390 .colorspace = V4L2_COLORSPACE_JPEG,
391 .priv = 1},
392 {640, 480, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
393 .bytesperline = 640,
Hans de Goedeb282d872009-06-14 19:10:40 -0300394 .sizeimage = 640 * 480 * 2,
Hans de Goede49809d62009-06-07 12:10:39 -0300395 .colorspace = V4L2_COLORSPACE_JPEG,
396 .priv = 0},
397};
398static const struct v4l2_pix_format ov518_sif_mode[] = {
Hans de Goede124cc9c2009-06-14 05:48:00 -0300399 {160, 120, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
400 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300401 .sizeimage = 70000,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300402 .colorspace = V4L2_COLORSPACE_JPEG,
403 .priv = 3},
Hans de Goede49809d62009-06-07 12:10:39 -0300404 {176, 144, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
405 .bytesperline = 176,
Hans de Goedeb282d872009-06-14 19:10:40 -0300406 .sizeimage = 70000,
Hans de Goede49809d62009-06-07 12:10:39 -0300407 .colorspace = V4L2_COLORSPACE_JPEG,
408 .priv = 1},
Hans de Goede124cc9c2009-06-14 05:48:00 -0300409 {320, 240, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
410 .bytesperline = 320,
Hans de Goedeb282d872009-06-14 19:10:40 -0300411 .sizeimage = 320 * 240 * 3,
Hans de Goede124cc9c2009-06-14 05:48:00 -0300412 .colorspace = V4L2_COLORSPACE_JPEG,
413 .priv = 2},
Hans de Goede49809d62009-06-07 12:10:39 -0300414 {352, 288, V4L2_PIX_FMT_OV518, V4L2_FIELD_NONE,
415 .bytesperline = 352,
Hans de Goedeb282d872009-06-14 19:10:40 -0300416 .sizeimage = 352 * 288 * 3,
Hans de Goede49809d62009-06-07 12:10:39 -0300417 .colorspace = V4L2_COLORSPACE_JPEG,
418 .priv = 0},
419};
420
Hans de Goede1876bb92009-06-14 06:45:50 -0300421static const struct v4l2_pix_format ov511_vga_mode[] = {
422 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
423 .bytesperline = 320,
424 .sizeimage = 320 * 240 * 3,
425 .colorspace = V4L2_COLORSPACE_JPEG,
426 .priv = 1},
427 {640, 480, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
428 .bytesperline = 640,
429 .sizeimage = 640 * 480 * 2,
430 .colorspace = V4L2_COLORSPACE_JPEG,
431 .priv = 0},
432};
433static const struct v4l2_pix_format ov511_sif_mode[] = {
434 {160, 120, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
435 .bytesperline = 160,
Hans de Goedeb282d872009-06-14 19:10:40 -0300436 .sizeimage = 70000,
Hans de Goede1876bb92009-06-14 06:45:50 -0300437 .colorspace = V4L2_COLORSPACE_JPEG,
438 .priv = 3},
439 {176, 144, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
440 .bytesperline = 176,
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 = 1},
444 {320, 240, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
445 .bytesperline = 320,
446 .sizeimage = 320 * 240 * 3,
447 .colorspace = V4L2_COLORSPACE_JPEG,
448 .priv = 2},
449 {352, 288, V4L2_PIX_FMT_OV511, V4L2_FIELD_NONE,
450 .bytesperline = 352,
451 .sizeimage = 352 * 288 * 3,
452 .colorspace = V4L2_COLORSPACE_JPEG,
453 .priv = 0},
454};
Hans de Goede49809d62009-06-07 12:10:39 -0300455
Hans de Goede635118d2009-10-11 09:49:03 -0300456static const struct v4l2_pix_format ovfx2_vga_mode[] = {
457 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
458 .bytesperline = 320,
459 .sizeimage = 320 * 240,
460 .colorspace = V4L2_COLORSPACE_SRGB,
461 .priv = 1},
462 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
463 .bytesperline = 640,
464 .sizeimage = 640 * 480,
465 .colorspace = V4L2_COLORSPACE_SRGB,
466 .priv = 0},
467};
468static const struct v4l2_pix_format ovfx2_cif_mode[] = {
469 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
470 .bytesperline = 160,
471 .sizeimage = 160 * 120,
472 .colorspace = V4L2_COLORSPACE_SRGB,
473 .priv = 3},
474 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
475 .bytesperline = 176,
476 .sizeimage = 176 * 144,
477 .colorspace = V4L2_COLORSPACE_SRGB,
478 .priv = 1},
479 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
480 .bytesperline = 320,
481 .sizeimage = 320 * 240,
482 .colorspace = V4L2_COLORSPACE_SRGB,
483 .priv = 2},
484 {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
485 .bytesperline = 352,
486 .sizeimage = 352 * 288,
487 .colorspace = V4L2_COLORSPACE_SRGB,
488 .priv = 0},
489};
490static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
Jean-François Moinec42cedb2011-02-10 13:37:48 -0300491 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
492 .bytesperline = 800,
493 .sizeimage = 800 * 600,
494 .colorspace = V4L2_COLORSPACE_SRGB,
495 .priv = 1},
Hans de Goede635118d2009-10-11 09:49:03 -0300496 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
497 .bytesperline = 1600,
498 .sizeimage = 1600 * 1200,
499 .colorspace = V4L2_COLORSPACE_SRGB},
500};
501static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300502 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
503 .bytesperline = 640,
504 .sizeimage = 640 * 480,
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300505 .colorspace = V4L2_COLORSPACE_SRGB,
506 .priv = 1},
507 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
508 .bytesperline = 800,
509 .sizeimage = 800 * 600,
510 .colorspace = V4L2_COLORSPACE_SRGB,
511 .priv = 1},
512 {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
513 .bytesperline = 1024,
514 .sizeimage = 1024 * 768,
515 .colorspace = V4L2_COLORSPACE_SRGB,
516 .priv = 1},
517 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
518 .bytesperline = 1600,
519 .sizeimage = 1600 * 1200,
520 .colorspace = V4L2_COLORSPACE_SRGB,
521 .priv = 0},
522 {2048, 1536, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
523 .bytesperline = 2048,
524 .sizeimage = 2048 * 1536,
525 .colorspace = V4L2_COLORSPACE_SRGB,
526 .priv = 0},
Hans de Goede635118d2009-10-11 09:49:03 -0300527};
528
Hans de Goede49809d62009-06-07 12:10:39 -0300529/* Registers common to OV511 / OV518 */
Hans de Goede1876bb92009-06-14 06:45:50 -0300530#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
Jean-François Moine780e3122010-10-19 04:29:10 -0300531#define R51x_SYS_RESET 0x50
Hans de Goede1876bb92009-06-14 06:45:50 -0300532 /* Reset type flags */
533 #define OV511_RESET_OMNICE 0x08
Jean-François Moine780e3122010-10-19 04:29:10 -0300534#define R51x_SYS_INIT 0x53
Hans de Goede49809d62009-06-07 12:10:39 -0300535#define R51x_SYS_SNAP 0x52
Jean-François Moine87bae742010-11-12 05:31:34 -0300536#define R51x_SYS_CUST_ID 0x5f
Hans de Goede49809d62009-06-07 12:10:39 -0300537#define R51x_COMP_LUT_BEGIN 0x80
538
539/* OV511 Camera interface register numbers */
Hans de Goede1876bb92009-06-14 06:45:50 -0300540#define R511_CAM_DELAY 0x10
541#define R511_CAM_EDGE 0x11
542#define R511_CAM_PXCNT 0x12
543#define R511_CAM_LNCNT 0x13
544#define R511_CAM_PXDIV 0x14
545#define R511_CAM_LNDIV 0x15
546#define R511_CAM_UV_EN 0x16
547#define R511_CAM_LINE_MODE 0x17
548#define R511_CAM_OPTS 0x18
549
550#define R511_SNAP_FRAME 0x19
Jean-François Moine87bae742010-11-12 05:31:34 -0300551#define R511_SNAP_PXCNT 0x1a
552#define R511_SNAP_LNCNT 0x1b
553#define R511_SNAP_PXDIV 0x1c
554#define R511_SNAP_LNDIV 0x1d
555#define R511_SNAP_UV_EN 0x1e
Jean-François Moine87bae742010-11-12 05:31:34 -0300556#define R511_SNAP_OPTS 0x1f
Hans de Goede1876bb92009-06-14 06:45:50 -0300557
558#define R511_DRAM_FLOW_CTL 0x20
559#define R511_FIFO_OPTS 0x31
560#define R511_I2C_CTL 0x40
Hans de Goede49809d62009-06-07 12:10:39 -0300561#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
Hans de Goede1876bb92009-06-14 06:45:50 -0300562#define R511_COMP_EN 0x78
563#define R511_COMP_LUT_EN 0x79
Hans de Goede49809d62009-06-07 12:10:39 -0300564
565/* OV518 Camera interface register numbers */
566#define R518_GPIO_OUT 0x56 /* OV518(+) only */
567#define R518_GPIO_CTL 0x57 /* OV518(+) only */
568
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300569/* OV519 Camera interface register numbers */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -0300570#define OV519_R10_H_SIZE 0x10
571#define OV519_R11_V_SIZE 0x11
572#define OV519_R12_X_OFFSETL 0x12
573#define OV519_R13_X_OFFSETH 0x13
574#define OV519_R14_Y_OFFSETL 0x14
575#define OV519_R15_Y_OFFSETH 0x15
576#define OV519_R16_DIVIDER 0x16
577#define OV519_R20_DFR 0x20
578#define OV519_R25_FORMAT 0x25
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300579
580/* OV519 System Controller register numbers */
Jean-François Moine21867802010-11-12 06:12:09 -0300581#define OV519_R51_RESET1 0x51
582#define OV519_R54_EN_CLK1 0x54
Jean-François Moineb4e96ea2010-11-12 16:13:17 -0300583#define OV519_R57_SNAPSHOT 0x57
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300584
585#define OV519_GPIO_DATA_OUT0 0x71
586#define OV519_GPIO_IO_CTRL0 0x72
587
Jean-François Moine87bae742010-11-12 05:31:34 -0300588/*#define OV511_ENDPOINT_ADDRESS 1 * Isoc endpoint number */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300589
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300590/*
591 * The FX2 chip does not give us a zero length read at end of frame.
592 * It does, however, give a short read at the end of a frame, if
Daniel Mack3ad2f3f2010-02-03 08:01:28 +0800593 * necessary, rather than run two frames together.
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300594 *
595 * By choosing the right bulk transfer size, we are guaranteed to always
596 * get a short read for the last read of each frame. Frame sizes are
597 * always a composite number (width * height, or a multiple) so if we
598 * choose a prime number, we are guaranteed that the last read of a
599 * frame will be short.
600 *
601 * But it isn't that easy: the 2.6 kernel requires a multiple of 4KB,
602 * otherwise EOVERFLOW "babbling" errors occur. I have not been able
603 * to figure out why. [PMiller]
604 *
605 * The constant (13 * 4096) is the largest "prime enough" number less than 64KB.
606 *
607 * It isn't enough to know the number of bytes per frame, in case we
608 * have data dropouts or buffer overruns (even though the FX2 double
609 * buffers, there are some pretty strict real time constraints for
610 * isochronous transfer for larger frame sizes).
611 */
Jean-François Moinec42cedb2011-02-10 13:37:48 -0300612/*jfm: this value works well for 1600x1200, but not 800x600 - see isoc_init */
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300613#define OVFX2_BULK_SIZE (13 * 4096)
614
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300615/* I2C registers */
616#define R51x_I2C_W_SID 0x41
617#define R51x_I2C_SADDR_3 0x42
618#define R51x_I2C_SADDR_2 0x43
619#define R51x_I2C_R_SID 0x44
620#define R51x_I2C_DATA 0x45
621#define R518_I2C_CTL 0x47 /* OV518(+) only */
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300622#define OVFX2_I2C_ADDR 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300623
624/* I2C ADDRESSES */
625#define OV7xx0_SID 0x42
Hans de Goede229bb7d2009-10-11 07:41:46 -0300626#define OV_HIRES_SID 0x60 /* OV9xxx / OV2xxx / OV3xxx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300627#define OV8xx0_SID 0xa0
628#define OV6xx0_SID 0xc0
629
630/* OV7610 registers */
631#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
Hans de Goede49809d62009-06-07 12:10:39 -0300632#define OV7610_REG_BLUE 0x01 /* blue channel balance */
633#define OV7610_REG_RED 0x02 /* red channel balance */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300634#define OV7610_REG_SAT 0x03 /* saturation */
635#define OV8610_REG_HUE 0x04 /* 04 reserved */
636#define OV7610_REG_CNT 0x05 /* Y contrast */
637#define OV7610_REG_BRT 0x06 /* Y brightness */
638#define OV7610_REG_COM_C 0x14 /* misc common regs */
639#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
640#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
641#define OV7610_REG_COM_I 0x29 /* misc settings */
642
Jean-François Moine42e142f2010-11-13 05:10:27 -0300643/* OV7660 and OV7670 registers */
Jean-François Moine21867802010-11-12 06:12:09 -0300644#define OV7670_R00_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
645#define OV7670_R01_BLUE 0x01 /* blue gain */
646#define OV7670_R02_RED 0x02 /* red gain */
647#define OV7670_R03_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
648#define OV7670_R04_COM1 0x04 /* Control 1 */
649/*#define OV7670_R07_AECHH 0x07 * AEC MS 5 bits */
650#define OV7670_R0C_COM3 0x0c /* Control 3 */
651#define OV7670_R0D_COM4 0x0d /* Control 4 */
652#define OV7670_R0E_COM5 0x0e /* All "reserved" */
653#define OV7670_R0F_COM6 0x0f /* Control 6 */
654#define OV7670_R10_AECH 0x10 /* More bits of AEC value */
655#define OV7670_R11_CLKRC 0x11 /* Clock control */
656#define OV7670_R12_COM7 0x12 /* Control 7 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300657#define OV7670_COM7_FMT_VGA 0x00
658/*#define OV7670_COM7_YUV 0x00 * YUV */
659#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
660#define OV7670_COM7_FMT_MASK 0x38
661#define OV7670_COM7_RESET 0x80 /* Register reset */
Jean-François Moine21867802010-11-12 06:12:09 -0300662#define OV7670_R13_COM8 0x13 /* Control 8 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300663#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
664#define OV7670_COM8_AWB 0x02 /* White balance enable */
665#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
666#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
667#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
668#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
Jean-François Moine21867802010-11-12 06:12:09 -0300669#define OV7670_R14_COM9 0x14 /* Control 9 - gain ceiling */
670#define OV7670_R15_COM10 0x15 /* Control 10 */
671#define OV7670_R17_HSTART 0x17 /* Horiz start high bits */
672#define OV7670_R18_HSTOP 0x18 /* Horiz stop high bits */
673#define OV7670_R19_VSTART 0x19 /* Vert start high bits */
674#define OV7670_R1A_VSTOP 0x1a /* Vert stop high bits */
675#define OV7670_R1E_MVFP 0x1e /* Mirror / vflip */
Jean-François Moine87bae742010-11-12 05:31:34 -0300676#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
677#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
Jean-François Moine21867802010-11-12 06:12:09 -0300678#define OV7670_R24_AEW 0x24 /* AGC upper limit */
679#define OV7670_R25_AEB 0x25 /* AGC lower limit */
680#define OV7670_R26_VPT 0x26 /* AGC/AEC fast mode op region */
681#define OV7670_R32_HREF 0x32 /* HREF pieces */
682#define OV7670_R3A_TSLB 0x3a /* lots of stuff */
683#define OV7670_R3B_COM11 0x3b /* Control 11 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300684#define OV7670_COM11_EXP 0x02
685#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
Jean-François Moine21867802010-11-12 06:12:09 -0300686#define OV7670_R3C_COM12 0x3c /* Control 12 */
687#define OV7670_R3D_COM13 0x3d /* Control 13 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300688#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
689#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
Jean-François Moine21867802010-11-12 06:12:09 -0300690#define OV7670_R3E_COM14 0x3e /* Control 14 */
691#define OV7670_R3F_EDGE 0x3f /* Edge enhancement factor */
692#define OV7670_R40_COM15 0x40 /* Control 15 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300693/*#define OV7670_COM15_R00FF 0xc0 * 00 to FF */
Jean-François Moine21867802010-11-12 06:12:09 -0300694#define OV7670_R41_COM16 0x41 /* Control 16 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300695#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
Jean-François Moine42e142f2010-11-13 05:10:27 -0300696/* end of ov7660 common registers */
Jean-François Moine21867802010-11-12 06:12:09 -0300697#define OV7670_R55_BRIGHT 0x55 /* Brightness */
698#define OV7670_R56_CONTRAS 0x56 /* Contrast control */
699#define OV7670_R69_GFIX 0x69 /* Fix gain control */
700/*#define OV7670_R8C_RGB444 0x8c * RGB 444 control */
701#define OV7670_R9F_HAECC1 0x9f /* Hist AEC/AGC control 1 */
702#define OV7670_RA0_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
703#define OV7670_RA5_BD50MAX 0xa5 /* 50hz banding step limit */
704#define OV7670_RA6_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
705#define OV7670_RA7_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
706#define OV7670_RA8_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
707#define OV7670_RA9_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
708#define OV7670_RAA_HAECC7 0xaa /* Hist AEC/AGC control 7 */
709#define OV7670_RAB_BD60MAX 0xab /* 60hz banding step limit */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300710
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300711struct ov_regvals {
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300712 u8 reg;
713 u8 val;
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300714};
715struct ov_i2c_regvals {
Jean-François Moine9d1593a2010-11-11 08:04:06 -0300716 u8 reg;
717 u8 val;
Jean-Francois Moine4202f712008-09-03 17:12:15 -0300718};
719
Hans de Goede635118d2009-10-11 09:49:03 -0300720/* Settings for OV2610 camera chip */
Jean-François Moine780e3122010-10-19 04:29:10 -0300721static const struct ov_i2c_regvals norm_2610[] = {
Hans de Goedeb46aaa02009-10-12 10:07:57 -0300722 { 0x12, 0x80 }, /* reset */
Hans de Goede635118d2009-10-11 09:49:03 -0300723};
724
Jean-François Moine07c6c9c2011-02-10 13:32:22 -0300725static const struct ov_i2c_regvals norm_2610ae[] = {
726 {0x12, 0x80}, /* reset */
727 {0x13, 0xcd},
728 {0x09, 0x01},
729 {0x0d, 0x00},
730 {0x11, 0x80},
731 {0x12, 0x20}, /* 1600x1200 */
732 {0x33, 0x0c},
733 {0x35, 0x90},
734 {0x36, 0x37},
735/* ms-win traces */
736 {0x11, 0x83}, /* clock / 3 ? */
737 {0x2d, 0x00}, /* 60 Hz filter */
738 {0x24, 0xb0}, /* normal colors */
739 {0x25, 0x90},
740 {0x10, 0x43},
741};
742
Jean-François Moine780e3122010-10-19 04:29:10 -0300743static const struct ov_i2c_regvals norm_3620b[] = {
Hans de Goede635118d2009-10-11 09:49:03 -0300744 /*
745 * From the datasheet: "Note that after writing to register COMH
746 * (0x12) to change the sensor mode, registers related to the
747 * sensor’s cropping window will be reset back to their default
748 * values."
749 *
750 * "wait 4096 external clock ... to make sure the sensor is
751 * stable and ready to access registers" i.e. 160us at 24MHz
752 */
Hans de Goede635118d2009-10-11 09:49:03 -0300753 { 0x12, 0x80 }, /* COMH reset */
754 { 0x12, 0x00 }, /* QXGA, master */
755
756 /*
757 * 11 CLKRC "Clock Rate Control"
758 * [7] internal frequency doublers: on
759 * [6] video port mode: master
760 * [5:0] clock divider: 1
761 */
762 { 0x11, 0x80 },
763
764 /*
765 * 13 COMI "Common Control I"
766 * = 192 (0xC0) 11000000
767 * COMI[7] "AEC speed selection"
768 * = 1 (0x01) 1....... "Faster AEC correction"
769 * COMI[6] "AEC speed step selection"
770 * = 1 (0x01) .1...... "Big steps, fast"
771 * COMI[5] "Banding filter on off"
772 * = 0 (0x00) ..0..... "Off"
773 * COMI[4] "Banding filter option"
774 * = 0 (0x00) ...0.... "Main clock is 48 MHz and
775 * the PLL is ON"
776 * COMI[3] "Reserved"
777 * = 0 (0x00) ....0...
778 * COMI[2] "AGC auto manual control selection"
779 * = 0 (0x00) .....0.. "Manual"
780 * COMI[1] "AWB auto manual control selection"
781 * = 0 (0x00) ......0. "Manual"
782 * COMI[0] "Exposure control"
783 * = 0 (0x00) .......0 "Manual"
784 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300785 { 0x13, 0xc0 },
Hans de Goede635118d2009-10-11 09:49:03 -0300786
787 /*
788 * 09 COMC "Common Control C"
789 * = 8 (0x08) 00001000
790 * COMC[7:5] "Reserved"
791 * = 0 (0x00) 000.....
792 * COMC[4] "Sleep Mode Enable"
793 * = 0 (0x00) ...0.... "Normal mode"
794 * COMC[3:2] "Sensor sampling reset timing selection"
795 * = 2 (0x02) ....10.. "Longer reset time"
796 * COMC[1:0] "Output drive current select"
797 * = 0 (0x00) ......00 "Weakest"
798 */
799 { 0x09, 0x08 },
800
801 /*
802 * 0C COMD "Common Control D"
803 * = 8 (0x08) 00001000
804 * COMD[7] "Reserved"
805 * = 0 (0x00) 0.......
806 * COMD[6] "Swap MSB and LSB at the output port"
807 * = 0 (0x00) .0...... "False"
808 * COMD[5:3] "Reserved"
809 * = 1 (0x01) ..001...
810 * COMD[2] "Output Average On Off"
811 * = 0 (0x00) .....0.. "Output Normal"
812 * COMD[1] "Sensor precharge voltage selection"
813 * = 0 (0x00) ......0. "Selects internal
814 * reference precharge
815 * voltage"
816 * COMD[0] "Snapshot option"
817 * = 0 (0x00) .......0 "Enable live video output
818 * after snapshot sequence"
819 */
820 { 0x0c, 0x08 },
821
822 /*
823 * 0D COME "Common Control E"
824 * = 161 (0xA1) 10100001
825 * COME[7] "Output average option"
826 * = 1 (0x01) 1....... "Output average of 4 pixels"
827 * COME[6] "Anti-blooming control"
828 * = 0 (0x00) .0...... "Off"
829 * COME[5:3] "Reserved"
830 * = 4 (0x04) ..100...
831 * COME[2] "Clock output power down pin status"
832 * = 0 (0x00) .....0.. "Tri-state data output pin
833 * on power down"
834 * COME[1] "Data output pin status selection at power down"
835 * = 0 (0x00) ......0. "Tri-state VSYNC, PCLK,
836 * HREF, and CHSYNC pins on
837 * power down"
838 * COME[0] "Auto zero circuit select"
839 * = 1 (0x01) .......1 "On"
840 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300841 { 0x0d, 0xa1 },
Hans de Goede635118d2009-10-11 09:49:03 -0300842
843 /*
844 * 0E COMF "Common Control F"
845 * = 112 (0x70) 01110000
846 * COMF[7] "System clock selection"
847 * = 0 (0x00) 0....... "Use 24 MHz system clock"
848 * COMF[6:4] "Reserved"
849 * = 7 (0x07) .111....
850 * COMF[3] "Manual auto negative offset canceling selection"
851 * = 0 (0x00) ....0... "Auto detect negative
852 * offset and cancel it"
853 * COMF[2:0] "Reserved"
854 * = 0 (0x00) .....000
855 */
856 { 0x0e, 0x70 },
857
858 /*
859 * 0F COMG "Common Control G"
860 * = 66 (0x42) 01000010
861 * COMG[7] "Optical black output selection"
862 * = 0 (0x00) 0....... "Disable"
863 * COMG[6] "Black level calibrate selection"
864 * = 1 (0x01) .1...... "Use optical black pixels
865 * to calibrate"
866 * COMG[5:4] "Reserved"
867 * = 0 (0x00) ..00....
868 * COMG[3] "Channel offset adjustment"
869 * = 0 (0x00) ....0... "Disable offset adjustment"
870 * COMG[2] "ADC black level calibration option"
871 * = 0 (0x00) .....0.. "Use B/G line and G/R
872 * line to calibrate each
873 * channel's black level"
874 * COMG[1] "Reserved"
875 * = 1 (0x01) ......1.
876 * COMG[0] "ADC black level calibration enable"
877 * = 0 (0x00) .......0 "Disable"
878 */
879 { 0x0f, 0x42 },
880
881 /*
882 * 14 COMJ "Common Control J"
883 * = 198 (0xC6) 11000110
884 * COMJ[7:6] "AGC gain ceiling"
885 * = 3 (0x03) 11...... "8x"
886 * COMJ[5:4] "Reserved"
887 * = 0 (0x00) ..00....
888 * COMJ[3] "Auto banding filter"
889 * = 0 (0x00) ....0... "Banding filter is always
890 * on off depending on
891 * COMI[5] setting"
892 * COMJ[2] "VSYNC drop option"
893 * = 1 (0x01) .....1.. "SYNC is dropped if frame
894 * data is dropped"
895 * COMJ[1] "Frame data drop"
896 * = 1 (0x01) ......1. "Drop frame data if
897 * exposure is not within
898 * tolerance. In AEC mode,
899 * data is normally dropped
900 * when data is out of
901 * range."
902 * COMJ[0] "Reserved"
903 * = 0 (0x00) .......0
904 */
Jean-François Moine87bae742010-11-12 05:31:34 -0300905 { 0x14, 0xc6 },
Hans de Goede635118d2009-10-11 09:49:03 -0300906
907 /*
908 * 15 COMK "Common Control K"
909 * = 2 (0x02) 00000010
910 * COMK[7] "CHSYNC pin output swap"
911 * = 0 (0x00) 0....... "CHSYNC"
912 * COMK[6] "HREF pin output swap"
913 * = 0 (0x00) .0...... "HREF"
914 * COMK[5] "PCLK output selection"
915 * = 0 (0x00) ..0..... "PCLK always output"
916 * COMK[4] "PCLK edge selection"
917 * = 0 (0x00) ...0.... "Data valid on falling edge"
918 * COMK[3] "HREF output polarity"
919 * = 0 (0x00) ....0... "positive"
920 * COMK[2] "Reserved"
921 * = 0 (0x00) .....0..
922 * COMK[1] "VSYNC polarity"
923 * = 1 (0x01) ......1. "negative"
924 * COMK[0] "HSYNC polarity"
925 * = 0 (0x00) .......0 "positive"
926 */
927 { 0x15, 0x02 },
928
929 /*
930 * 33 CHLF "Current Control"
931 * = 9 (0x09) 00001001
932 * CHLF[7:6] "Sensor current control"
933 * = 0 (0x00) 00......
934 * CHLF[5] "Sensor current range control"
935 * = 0 (0x00) ..0..... "normal range"
936 * CHLF[4] "Sensor current"
937 * = 0 (0x00) ...0.... "normal current"
938 * CHLF[3] "Sensor buffer current control"
939 * = 1 (0x01) ....1... "half current"
940 * CHLF[2] "Column buffer current control"
941 * = 0 (0x00) .....0.. "normal current"
942 * CHLF[1] "Analog DSP current control"
943 * = 0 (0x00) ......0. "normal current"
944 * CHLF[1] "ADC current control"
945 * = 0 (0x00) ......0. "normal current"
946 */
947 { 0x33, 0x09 },
948
949 /*
950 * 34 VBLM "Blooming Control"
951 * = 80 (0x50) 01010000
952 * VBLM[7] "Hard soft reset switch"
953 * = 0 (0x00) 0....... "Hard reset"
954 * VBLM[6:4] "Blooming voltage selection"
955 * = 5 (0x05) .101....
956 * VBLM[3:0] "Sensor current control"
957 * = 0 (0x00) ....0000
958 */
959 { 0x34, 0x50 },
960
961 /*
962 * 36 VCHG "Sensor Precharge Voltage Control"
963 * = 0 (0x00) 00000000
964 * VCHG[7] "Reserved"
965 * = 0 (0x00) 0.......
966 * VCHG[6:4] "Sensor precharge voltage control"
967 * = 0 (0x00) .000....
968 * VCHG[3:0] "Sensor array common reference"
969 * = 0 (0x00) ....0000
970 */
971 { 0x36, 0x00 },
972
973 /*
974 * 37 ADC "ADC Reference Control"
975 * = 4 (0x04) 00000100
976 * ADC[7:4] "Reserved"
977 * = 0 (0x00) 0000....
978 * ADC[3] "ADC input signal range"
979 * = 0 (0x00) ....0... "Input signal 1.0x"
980 * ADC[2:0] "ADC range control"
981 * = 4 (0x04) .....100
982 */
983 { 0x37, 0x04 },
984
985 /*
986 * 38 ACOM "Analog Common Ground"
987 * = 82 (0x52) 01010010
988 * ACOM[7] "Analog gain control"
989 * = 0 (0x00) 0....... "Gain 1x"
990 * ACOM[6] "Analog black level calibration"
991 * = 1 (0x01) .1...... "On"
992 * ACOM[5:0] "Reserved"
993 * = 18 (0x12) ..010010
994 */
995 { 0x38, 0x52 },
996
997 /*
998 * 3A FREFA "Internal Reference Adjustment"
999 * = 0 (0x00) 00000000
1000 * FREFA[7:0] "Range"
1001 * = 0 (0x00) 00000000
1002 */
1003 { 0x3a, 0x00 },
1004
1005 /*
1006 * 3C FVOPT "Internal Reference Adjustment"
1007 * = 31 (0x1F) 00011111
1008 * FVOPT[7:0] "Range"
1009 * = 31 (0x1F) 00011111
1010 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001011 { 0x3c, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001012
1013 /*
1014 * 44 Undocumented = 0 (0x00) 00000000
1015 * 44[7:0] "It's a secret"
1016 * = 0 (0x00) 00000000
1017 */
1018 { 0x44, 0x00 },
1019
1020 /*
1021 * 40 Undocumented = 0 (0x00) 00000000
1022 * 40[7:0] "It's a secret"
1023 * = 0 (0x00) 00000000
1024 */
1025 { 0x40, 0x00 },
1026
1027 /*
1028 * 41 Undocumented = 0 (0x00) 00000000
1029 * 41[7:0] "It's a secret"
1030 * = 0 (0x00) 00000000
1031 */
1032 { 0x41, 0x00 },
1033
1034 /*
1035 * 42 Undocumented = 0 (0x00) 00000000
1036 * 42[7:0] "It's a secret"
1037 * = 0 (0x00) 00000000
1038 */
1039 { 0x42, 0x00 },
1040
1041 /*
1042 * 43 Undocumented = 0 (0x00) 00000000
1043 * 43[7:0] "It's a secret"
1044 * = 0 (0x00) 00000000
1045 */
1046 { 0x43, 0x00 },
1047
1048 /*
1049 * 45 Undocumented = 128 (0x80) 10000000
1050 * 45[7:0] "It's a secret"
1051 * = 128 (0x80) 10000000
1052 */
1053 { 0x45, 0x80 },
1054
1055 /*
1056 * 48 Undocumented = 192 (0xC0) 11000000
1057 * 48[7:0] "It's a secret"
1058 * = 192 (0xC0) 11000000
1059 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001060 { 0x48, 0xc0 },
Hans de Goede635118d2009-10-11 09:49:03 -03001061
1062 /*
1063 * 49 Undocumented = 25 (0x19) 00011001
1064 * 49[7:0] "It's a secret"
1065 * = 25 (0x19) 00011001
1066 */
1067 { 0x49, 0x19 },
1068
1069 /*
1070 * 4B Undocumented = 128 (0x80) 10000000
1071 * 4B[7:0] "It's a secret"
1072 * = 128 (0x80) 10000000
1073 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001074 { 0x4b, 0x80 },
Hans de Goede635118d2009-10-11 09:49:03 -03001075
1076 /*
1077 * 4D Undocumented = 196 (0xC4) 11000100
1078 * 4D[7:0] "It's a secret"
1079 * = 196 (0xC4) 11000100
1080 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001081 { 0x4d, 0xc4 },
Hans de Goede635118d2009-10-11 09:49:03 -03001082
1083 /*
1084 * 35 VREF "Reference Voltage Control"
Jean-François Moine87bae742010-11-12 05:31:34 -03001085 * = 76 (0x4c) 01001100
Hans de Goede635118d2009-10-11 09:49:03 -03001086 * VREF[7:5] "Column high reference control"
1087 * = 2 (0x02) 010..... "higher voltage"
1088 * VREF[4:2] "Column low reference control"
1089 * = 3 (0x03) ...011.. "Highest voltage"
1090 * VREF[1:0] "Reserved"
1091 * = 0 (0x00) ......00
1092 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001093 { 0x35, 0x4c },
Hans de Goede635118d2009-10-11 09:49:03 -03001094
1095 /*
1096 * 3D Undocumented = 0 (0x00) 00000000
1097 * 3D[7:0] "It's a secret"
1098 * = 0 (0x00) 00000000
1099 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001100 { 0x3d, 0x00 },
Hans de Goede635118d2009-10-11 09:49:03 -03001101
1102 /*
1103 * 3E Undocumented = 0 (0x00) 00000000
1104 * 3E[7:0] "It's a secret"
1105 * = 0 (0x00) 00000000
1106 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001107 { 0x3e, 0x00 },
Hans de Goede635118d2009-10-11 09:49:03 -03001108
1109 /*
1110 * 3B FREFB "Internal Reference Adjustment"
1111 * = 24 (0x18) 00011000
1112 * FREFB[7:0] "Range"
1113 * = 24 (0x18) 00011000
1114 */
1115 { 0x3b, 0x18 },
1116
1117 /*
1118 * 33 CHLF "Current Control"
1119 * = 25 (0x19) 00011001
1120 * CHLF[7:6] "Sensor current control"
1121 * = 0 (0x00) 00......
1122 * CHLF[5] "Sensor current range control"
1123 * = 0 (0x00) ..0..... "normal range"
1124 * CHLF[4] "Sensor current"
1125 * = 1 (0x01) ...1.... "double current"
1126 * CHLF[3] "Sensor buffer current control"
1127 * = 1 (0x01) ....1... "half current"
1128 * CHLF[2] "Column buffer current control"
1129 * = 0 (0x00) .....0.. "normal current"
1130 * CHLF[1] "Analog DSP current control"
1131 * = 0 (0x00) ......0. "normal current"
1132 * CHLF[1] "ADC current control"
1133 * = 0 (0x00) ......0. "normal current"
1134 */
1135 { 0x33, 0x19 },
1136
1137 /*
1138 * 34 VBLM "Blooming Control"
1139 * = 90 (0x5A) 01011010
1140 * VBLM[7] "Hard soft reset switch"
1141 * = 0 (0x00) 0....... "Hard reset"
1142 * VBLM[6:4] "Blooming voltage selection"
1143 * = 5 (0x05) .101....
1144 * VBLM[3:0] "Sensor current control"
1145 * = 10 (0x0A) ....1010
1146 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001147 { 0x34, 0x5a },
Hans de Goede635118d2009-10-11 09:49:03 -03001148
1149 /*
1150 * 3B FREFB "Internal Reference Adjustment"
1151 * = 0 (0x00) 00000000
1152 * FREFB[7:0] "Range"
1153 * = 0 (0x00) 00000000
1154 */
1155 { 0x3b, 0x00 },
1156
1157 /*
1158 * 33 CHLF "Current Control"
1159 * = 9 (0x09) 00001001
1160 * CHLF[7:6] "Sensor current control"
1161 * = 0 (0x00) 00......
1162 * CHLF[5] "Sensor current range control"
1163 * = 0 (0x00) ..0..... "normal range"
1164 * CHLF[4] "Sensor current"
1165 * = 0 (0x00) ...0.... "normal current"
1166 * CHLF[3] "Sensor buffer current control"
1167 * = 1 (0x01) ....1... "half current"
1168 * CHLF[2] "Column buffer current control"
1169 * = 0 (0x00) .....0.. "normal current"
1170 * CHLF[1] "Analog DSP current control"
1171 * = 0 (0x00) ......0. "normal current"
1172 * CHLF[1] "ADC current control"
1173 * = 0 (0x00) ......0. "normal current"
1174 */
1175 { 0x33, 0x09 },
1176
1177 /*
1178 * 34 VBLM "Blooming Control"
1179 * = 80 (0x50) 01010000
1180 * VBLM[7] "Hard soft reset switch"
1181 * = 0 (0x00) 0....... "Hard reset"
1182 * VBLM[6:4] "Blooming voltage selection"
1183 * = 5 (0x05) .101....
1184 * VBLM[3:0] "Sensor current control"
1185 * = 0 (0x00) ....0000
1186 */
1187 { 0x34, 0x50 },
1188
1189 /*
1190 * 12 COMH "Common Control H"
1191 * = 64 (0x40) 01000000
1192 * COMH[7] "SRST"
1193 * = 0 (0x00) 0....... "No-op"
1194 * COMH[6:4] "Resolution selection"
1195 * = 4 (0x04) .100.... "XGA"
1196 * COMH[3] "Master slave selection"
1197 * = 0 (0x00) ....0... "Master mode"
1198 * COMH[2] "Internal B/R channel option"
1199 * = 0 (0x00) .....0.. "B/R use same channel"
1200 * COMH[1] "Color bar test pattern"
1201 * = 0 (0x00) ......0. "Off"
1202 * COMH[0] "Reserved"
1203 * = 0 (0x00) .......0
1204 */
1205 { 0x12, 0x40 },
1206
1207 /*
1208 * 17 HREFST "Horizontal window start"
1209 * = 31 (0x1F) 00011111
1210 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1211 * = 31 (0x1F) 00011111
1212 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001213 { 0x17, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001214
1215 /*
1216 * 18 HREFEND "Horizontal window end"
1217 * = 95 (0x5F) 01011111
1218 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1219 * = 95 (0x5F) 01011111
1220 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001221 { 0x18, 0x5f },
Hans de Goede635118d2009-10-11 09:49:03 -03001222
1223 /*
1224 * 19 VSTRT "Vertical window start"
1225 * = 0 (0x00) 00000000
1226 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1227 * = 0 (0x00) 00000000
1228 */
1229 { 0x19, 0x00 },
1230
1231 /*
1232 * 1A VEND "Vertical window end"
1233 * = 96 (0x60) 01100000
1234 * VEND[7:0] "Vertical Window End, 8 MSBs"
1235 * = 96 (0x60) 01100000
1236 */
1237 { 0x1a, 0x60 },
1238
1239 /*
1240 * 32 COMM "Common Control M"
1241 * = 18 (0x12) 00010010
1242 * COMM[7:6] "Pixel clock divide option"
1243 * = 0 (0x00) 00...... "/1"
1244 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1245 * = 2 (0x02) ..010...
1246 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1247 * = 2 (0x02) .....010
1248 */
1249 { 0x32, 0x12 },
1250
1251 /*
1252 * 03 COMA "Common Control A"
1253 * = 74 (0x4A) 01001010
1254 * COMA[7:4] "AWB Update Threshold"
1255 * = 4 (0x04) 0100....
1256 * COMA[3:2] "Vertical window end line control 2 LSBs"
1257 * = 2 (0x02) ....10..
1258 * COMA[1:0] "Vertical window start line control 2 LSBs"
1259 * = 2 (0x02) ......10
1260 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001261 { 0x03, 0x4a },
Hans de Goede635118d2009-10-11 09:49:03 -03001262
1263 /*
1264 * 11 CLKRC "Clock Rate Control"
1265 * = 128 (0x80) 10000000
1266 * CLKRC[7] "Internal frequency doublers on off seclection"
1267 * = 1 (0x01) 1....... "On"
1268 * CLKRC[6] "Digital video master slave selection"
1269 * = 0 (0x00) .0...... "Master mode, sensor
1270 * provides PCLK"
1271 * CLKRC[5:0] "Clock divider { CLK = PCLK/(1+CLKRC[5:0]) }"
1272 * = 0 (0x00) ..000000
1273 */
1274 { 0x11, 0x80 },
1275
1276 /*
1277 * 12 COMH "Common Control H"
1278 * = 0 (0x00) 00000000
1279 * COMH[7] "SRST"
1280 * = 0 (0x00) 0....... "No-op"
1281 * COMH[6:4] "Resolution selection"
1282 * = 0 (0x00) .000.... "QXGA"
1283 * COMH[3] "Master slave selection"
1284 * = 0 (0x00) ....0... "Master mode"
1285 * COMH[2] "Internal B/R channel option"
1286 * = 0 (0x00) .....0.. "B/R use same channel"
1287 * COMH[1] "Color bar test pattern"
1288 * = 0 (0x00) ......0. "Off"
1289 * COMH[0] "Reserved"
1290 * = 0 (0x00) .......0
1291 */
1292 { 0x12, 0x00 },
1293
1294 /*
1295 * 12 COMH "Common Control H"
1296 * = 64 (0x40) 01000000
1297 * COMH[7] "SRST"
1298 * = 0 (0x00) 0....... "No-op"
1299 * COMH[6:4] "Resolution selection"
1300 * = 4 (0x04) .100.... "XGA"
1301 * COMH[3] "Master slave selection"
1302 * = 0 (0x00) ....0... "Master mode"
1303 * COMH[2] "Internal B/R channel option"
1304 * = 0 (0x00) .....0.. "B/R use same channel"
1305 * COMH[1] "Color bar test pattern"
1306 * = 0 (0x00) ......0. "Off"
1307 * COMH[0] "Reserved"
1308 * = 0 (0x00) .......0
1309 */
1310 { 0x12, 0x40 },
1311
1312 /*
1313 * 17 HREFST "Horizontal window start"
1314 * = 31 (0x1F) 00011111
1315 * HREFST[7:0] "Horizontal window start, 8 MSBs"
1316 * = 31 (0x1F) 00011111
1317 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001318 { 0x17, 0x1f },
Hans de Goede635118d2009-10-11 09:49:03 -03001319
1320 /*
1321 * 18 HREFEND "Horizontal window end"
1322 * = 95 (0x5F) 01011111
1323 * HREFEND[7:0] "Horizontal Window End, 8 MSBs"
1324 * = 95 (0x5F) 01011111
1325 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001326 { 0x18, 0x5f },
Hans de Goede635118d2009-10-11 09:49:03 -03001327
1328 /*
1329 * 19 VSTRT "Vertical window start"
1330 * = 0 (0x00) 00000000
1331 * VSTRT[7:0] "Vertical Window Start, 8 MSBs"
1332 * = 0 (0x00) 00000000
1333 */
1334 { 0x19, 0x00 },
1335
1336 /*
1337 * 1A VEND "Vertical window end"
1338 * = 96 (0x60) 01100000
1339 * VEND[7:0] "Vertical Window End, 8 MSBs"
1340 * = 96 (0x60) 01100000
1341 */
1342 { 0x1a, 0x60 },
1343
1344 /*
1345 * 32 COMM "Common Control M"
1346 * = 18 (0x12) 00010010
1347 * COMM[7:6] "Pixel clock divide option"
1348 * = 0 (0x00) 00...... "/1"
1349 * COMM[5:3] "Horizontal window end position, 3 LSBs"
1350 * = 2 (0x02) ..010...
1351 * COMM[2:0] "Horizontal window start position, 3 LSBs"
1352 * = 2 (0x02) .....010
1353 */
1354 { 0x32, 0x12 },
1355
1356 /*
1357 * 03 COMA "Common Control A"
1358 * = 74 (0x4A) 01001010
1359 * COMA[7:4] "AWB Update Threshold"
1360 * = 4 (0x04) 0100....
1361 * COMA[3:2] "Vertical window end line control 2 LSBs"
1362 * = 2 (0x02) ....10..
1363 * COMA[1:0] "Vertical window start line control 2 LSBs"
1364 * = 2 (0x02) ......10
1365 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001366 { 0x03, 0x4a },
Hans de Goede635118d2009-10-11 09:49:03 -03001367
1368 /*
1369 * 02 RED "Red Gain Control"
1370 * = 175 (0xAF) 10101111
1371 * RED[7] "Action"
1372 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1373 * RED[6:0] "Value"
1374 * = 47 (0x2F) .0101111
1375 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001376 { 0x02, 0xaf },
Hans de Goede635118d2009-10-11 09:49:03 -03001377
1378 /*
1379 * 2D ADDVSL "VSYNC Pulse Width"
1380 * = 210 (0xD2) 11010010
1381 * ADDVSL[7:0] "VSYNC pulse width, LSB"
1382 * = 210 (0xD2) 11010010
1383 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001384 { 0x2d, 0xd2 },
Hans de Goede635118d2009-10-11 09:49:03 -03001385
1386 /*
1387 * 00 GAIN = 24 (0x18) 00011000
1388 * GAIN[7:6] "Reserved"
1389 * = 0 (0x00) 00......
1390 * GAIN[5] "Double"
1391 * = 0 (0x00) ..0..... "False"
1392 * GAIN[4] "Double"
1393 * = 1 (0x01) ...1.... "True"
1394 * GAIN[3:0] "Range"
1395 * = 8 (0x08) ....1000
1396 */
1397 { 0x00, 0x18 },
1398
1399 /*
1400 * 01 BLUE "Blue Gain Control"
1401 * = 240 (0xF0) 11110000
1402 * BLUE[7] "Action"
1403 * = 1 (0x01) 1....... "gain = 1/(1+bitrev([6:0]))"
1404 * BLUE[6:0] "Value"
1405 * = 112 (0x70) .1110000
1406 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001407 { 0x01, 0xf0 },
Hans de Goede635118d2009-10-11 09:49:03 -03001408
1409 /*
1410 * 10 AEC "Automatic Exposure Control"
1411 * = 10 (0x0A) 00001010
1412 * AEC[7:0] "Automatic Exposure Control, 8 MSBs"
1413 * = 10 (0x0A) 00001010
1414 */
Jean-François Moine87bae742010-11-12 05:31:34 -03001415 { 0x10, 0x0a },
Hans de Goede635118d2009-10-11 09:49:03 -03001416
Jean-François Moine87bae742010-11-12 05:31:34 -03001417 { 0xe1, 0x67 },
1418 { 0xe3, 0x03 },
1419 { 0xe4, 0x26 },
1420 { 0xe5, 0x3e },
1421 { 0xf8, 0x01 },
1422 { 0xff, 0x01 },
Hans de Goede635118d2009-10-11 09:49:03 -03001423};
1424
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001425static const struct ov_i2c_regvals norm_6x20[] = {
1426 { 0x12, 0x80 }, /* reset */
1427 { 0x11, 0x01 },
1428 { 0x03, 0x60 },
1429 { 0x05, 0x7f }, /* For when autoadjust is off */
1430 { 0x07, 0xa8 },
Jean-François Moine87bae742010-11-12 05:31:34 -03001431 /* The ratio of 0x0c and 0x0d controls the white point */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001432 { 0x0c, 0x24 },
1433 { 0x0d, 0x24 },
1434 { 0x0f, 0x15 }, /* COMS */
1435 { 0x10, 0x75 }, /* AEC Exposure time */
1436 { 0x12, 0x24 }, /* Enable AGC */
1437 { 0x14, 0x04 },
1438 /* 0x16: 0x06 helps frame stability with moving objects */
1439 { 0x16, 0x06 },
1440/* { 0x20, 0x30 }, * Aperture correction enable */
1441 { 0x26, 0xb2 }, /* BLC enable */
1442 /* 0x28: 0x05 Selects RGB format if RGB on */
1443 { 0x28, 0x05 },
1444 { 0x2a, 0x04 }, /* Disable framerate adjust */
1445/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
Hans de Goedeae49c402009-06-14 19:15:07 -03001446 { 0x2d, 0x85 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001447 { 0x33, 0xa0 }, /* Color Processing Parameter */
1448 { 0x34, 0xd2 }, /* Max A/D range */
1449 { 0x38, 0x8b },
1450 { 0x39, 0x40 },
1451
1452 { 0x3c, 0x39 }, /* Enable AEC mode changing */
1453 { 0x3c, 0x3c }, /* Change AEC mode */
1454 { 0x3c, 0x24 }, /* Disable AEC mode changing */
1455
1456 { 0x3d, 0x80 },
1457 /* These next two registers (0x4a, 0x4b) are undocumented.
1458 * They control the color balance */
1459 { 0x4a, 0x80 },
1460 { 0x4b, 0x80 },
1461 { 0x4d, 0xd2 }, /* This reduces noise a bit */
1462 { 0x4e, 0xc1 },
1463 { 0x4f, 0x04 },
1464/* Do 50-53 have any effect? */
1465/* Toggle 0x12[2] off and on here? */
1466};
1467
1468static const struct ov_i2c_regvals norm_6x30[] = {
1469 { 0x12, 0x80 }, /* Reset */
1470 { 0x00, 0x1f }, /* Gain */
1471 { 0x01, 0x99 }, /* Blue gain */
1472 { 0x02, 0x7c }, /* Red gain */
1473 { 0x03, 0xc0 }, /* Saturation */
1474 { 0x05, 0x0a }, /* Contrast */
1475 { 0x06, 0x95 }, /* Brightness */
1476 { 0x07, 0x2d }, /* Sharpness */
1477 { 0x0c, 0x20 },
1478 { 0x0d, 0x20 },
Hans de Goede02ab18b2009-06-14 04:32:04 -03001479 { 0x0e, 0xa0 }, /* Was 0x20, bit7 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001480 { 0x0f, 0x05 },
1481 { 0x10, 0x9a },
1482 { 0x11, 0x00 }, /* Pixel clock = fastest */
1483 { 0x12, 0x24 }, /* Enable AGC and AWB */
1484 { 0x13, 0x21 },
1485 { 0x14, 0x80 },
1486 { 0x15, 0x01 },
1487 { 0x16, 0x03 },
1488 { 0x17, 0x38 },
1489 { 0x18, 0xea },
1490 { 0x19, 0x04 },
1491 { 0x1a, 0x93 },
1492 { 0x1b, 0x00 },
1493 { 0x1e, 0xc4 },
1494 { 0x1f, 0x04 },
1495 { 0x20, 0x20 },
1496 { 0x21, 0x10 },
1497 { 0x22, 0x88 },
1498 { 0x23, 0xc0 }, /* Crystal circuit power level */
1499 { 0x25, 0x9a }, /* Increase AEC black ratio */
1500 { 0x26, 0xb2 }, /* BLC enable */
1501 { 0x27, 0xa2 },
1502 { 0x28, 0x00 },
1503 { 0x29, 0x00 },
1504 { 0x2a, 0x84 }, /* 60 Hz power */
1505 { 0x2b, 0xa8 }, /* 60 Hz power */
1506 { 0x2c, 0xa0 },
1507 { 0x2d, 0x95 }, /* Enable auto-brightness */
1508 { 0x2e, 0x88 },
1509 { 0x33, 0x26 },
1510 { 0x34, 0x03 },
1511 { 0x36, 0x8f },
1512 { 0x37, 0x80 },
1513 { 0x38, 0x83 },
1514 { 0x39, 0x80 },
1515 { 0x3a, 0x0f },
1516 { 0x3b, 0x3c },
1517 { 0x3c, 0x1a },
1518 { 0x3d, 0x80 },
1519 { 0x3e, 0x80 },
1520 { 0x3f, 0x0e },
1521 { 0x40, 0x00 }, /* White bal */
1522 { 0x41, 0x00 }, /* White bal */
1523 { 0x42, 0x80 },
1524 { 0x43, 0x3f }, /* White bal */
1525 { 0x44, 0x80 },
1526 { 0x45, 0x20 },
1527 { 0x46, 0x20 },
1528 { 0x47, 0x80 },
1529 { 0x48, 0x7f },
1530 { 0x49, 0x00 },
1531 { 0x4a, 0x00 },
1532 { 0x4b, 0x80 },
1533 { 0x4c, 0xd0 },
1534 { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
1535 { 0x4e, 0x40 },
1536 { 0x4f, 0x07 }, /* UV avg., col. killer: max */
1537 { 0x50, 0xff },
1538 { 0x54, 0x23 }, /* Max AGC gain: 18dB */
1539 { 0x55, 0xff },
1540 { 0x56, 0x12 },
1541 { 0x57, 0x81 },
1542 { 0x58, 0x75 },
1543 { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
1544 { 0x5a, 0x2c },
1545 { 0x5b, 0x0f }, /* AWB chrominance levels */
1546 { 0x5c, 0x10 },
1547 { 0x3d, 0x80 },
1548 { 0x27, 0xa6 },
1549 { 0x12, 0x20 }, /* Toggle AWB */
1550 { 0x12, 0x24 },
1551};
1552
1553/* Lawrence Glaister <lg@jfm.bc.ca> reports:
1554 *
1555 * Register 0x0f in the 7610 has the following effects:
1556 *
1557 * 0x85 (AEC method 1): Best overall, good contrast range
1558 * 0x45 (AEC method 2): Very overexposed
1559 * 0xa5 (spec sheet default): Ok, but the black level is
1560 * shifted resulting in loss of contrast
1561 * 0x05 (old driver setting): very overexposed, too much
1562 * contrast
1563 */
1564static const struct ov_i2c_regvals norm_7610[] = {
1565 { 0x10, 0xff },
1566 { 0x16, 0x06 },
1567 { 0x28, 0x24 },
1568 { 0x2b, 0xac },
1569 { 0x12, 0x00 },
1570 { 0x38, 0x81 },
1571 { 0x28, 0x24 }, /* 0c */
1572 { 0x0f, 0x85 }, /* lg's setting */
1573 { 0x15, 0x01 },
1574 { 0x20, 0x1c },
1575 { 0x23, 0x2a },
1576 { 0x24, 0x10 },
1577 { 0x25, 0x8a },
1578 { 0x26, 0xa2 },
1579 { 0x27, 0xc2 },
1580 { 0x2a, 0x04 },
1581 { 0x2c, 0xfe },
1582 { 0x2d, 0x93 },
1583 { 0x30, 0x71 },
1584 { 0x31, 0x60 },
1585 { 0x32, 0x26 },
1586 { 0x33, 0x20 },
1587 { 0x34, 0x48 },
1588 { 0x12, 0x24 },
1589 { 0x11, 0x01 },
1590 { 0x0c, 0x24 },
1591 { 0x0d, 0x24 },
1592};
1593
1594static const struct ov_i2c_regvals norm_7620[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03001595 { 0x12, 0x80 }, /* reset */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001596 { 0x00, 0x00 }, /* gain */
1597 { 0x01, 0x80 }, /* blue gain */
1598 { 0x02, 0x80 }, /* red gain */
Jean-François Moine21867802010-11-12 06:12:09 -03001599 { 0x03, 0xc0 }, /* OV7670_R03_VREF */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001600 { 0x06, 0x60 },
1601 { 0x07, 0x00 },
1602 { 0x0c, 0x24 },
1603 { 0x0c, 0x24 },
1604 { 0x0d, 0x24 },
1605 { 0x11, 0x01 },
1606 { 0x12, 0x24 },
1607 { 0x13, 0x01 },
1608 { 0x14, 0x84 },
1609 { 0x15, 0x01 },
1610 { 0x16, 0x03 },
1611 { 0x17, 0x2f },
1612 { 0x18, 0xcf },
1613 { 0x19, 0x06 },
1614 { 0x1a, 0xf5 },
1615 { 0x1b, 0x00 },
1616 { 0x20, 0x18 },
1617 { 0x21, 0x80 },
1618 { 0x22, 0x80 },
1619 { 0x23, 0x00 },
1620 { 0x26, 0xa2 },
1621 { 0x27, 0xea },
Hans de Goedeb282d872009-06-14 19:10:40 -03001622 { 0x28, 0x22 }, /* Was 0x20, bit1 enables a 2x gain which we need */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001623 { 0x29, 0x00 },
1624 { 0x2a, 0x10 },
1625 { 0x2b, 0x00 },
1626 { 0x2c, 0x88 },
1627 { 0x2d, 0x91 },
1628 { 0x2e, 0x80 },
1629 { 0x2f, 0x44 },
1630 { 0x60, 0x27 },
1631 { 0x61, 0x02 },
1632 { 0x62, 0x5f },
1633 { 0x63, 0xd5 },
1634 { 0x64, 0x57 },
1635 { 0x65, 0x83 },
1636 { 0x66, 0x55 },
1637 { 0x67, 0x92 },
1638 { 0x68, 0xcf },
1639 { 0x69, 0x76 },
1640 { 0x6a, 0x22 },
1641 { 0x6b, 0x00 },
1642 { 0x6c, 0x02 },
1643 { 0x6d, 0x44 },
1644 { 0x6e, 0x80 },
1645 { 0x6f, 0x1d },
1646 { 0x70, 0x8b },
1647 { 0x71, 0x00 },
1648 { 0x72, 0x14 },
1649 { 0x73, 0x54 },
1650 { 0x74, 0x00 },
1651 { 0x75, 0x8e },
1652 { 0x76, 0x00 },
1653 { 0x77, 0xff },
1654 { 0x78, 0x80 },
1655 { 0x79, 0x80 },
1656 { 0x7a, 0x80 },
1657 { 0x7b, 0xe2 },
1658 { 0x7c, 0x00 },
1659};
1660
1661/* 7640 and 7648. The defaults should be OK for most registers. */
1662static const struct ov_i2c_regvals norm_7640[] = {
1663 { 0x12, 0x80 },
1664 { 0x12, 0x14 },
1665};
1666
Jean-François Moine42e142f2010-11-13 05:10:27 -03001667static const struct ov_regvals init_519_ov7660[] = {
1668 { 0x5d, 0x03 }, /* Turn off suspend mode */
1669 { 0x53, 0x9b }, /* 0x9f enables the (unused) microcontroller */
1670 { 0x54, 0x0f }, /* bit2 (jpeg enable) */
1671 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
1672 { 0xa3, 0x18 },
1673 { 0xa4, 0x04 },
1674 { 0xa5, 0x28 },
1675 { 0x37, 0x00 }, /* SetUsbInit */
1676 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
1677 /* Enable both fields, YUV Input, disable defect comp (why?) */
1678 { 0x20, 0x0c }, /* 0x0d does U <-> V swap */
1679 { 0x21, 0x38 },
1680 { 0x22, 0x1d },
1681 { 0x17, 0x50 }, /* undocumented */
1682 { 0x37, 0x00 }, /* undocumented */
1683 { 0x40, 0xff }, /* I2C timeout counter */
1684 { 0x46, 0x00 }, /* I2C clock prescaler */
1685};
1686static const struct ov_i2c_regvals norm_7660[] = {
1687 {OV7670_R12_COM7, OV7670_COM7_RESET},
1688 {OV7670_R11_CLKRC, 0x81},
1689 {0x92, 0x00}, /* DM_LNL */
1690 {0x93, 0x00}, /* DM_LNH */
1691 {0x9d, 0x4c}, /* BD50ST */
1692 {0x9e, 0x3f}, /* BD60ST */
1693 {OV7670_R3B_COM11, 0x02},
1694 {OV7670_R13_COM8, 0xf5},
1695 {OV7670_R10_AECH, 0x00},
1696 {OV7670_R00_GAIN, 0x00},
1697 {OV7670_R01_BLUE, 0x7c},
1698 {OV7670_R02_RED, 0x9d},
1699 {OV7670_R12_COM7, 0x00},
1700 {OV7670_R04_COM1, 00},
1701 {OV7670_R18_HSTOP, 0x01},
1702 {OV7670_R17_HSTART, 0x13},
1703 {OV7670_R32_HREF, 0x92},
1704 {OV7670_R19_VSTART, 0x02},
1705 {OV7670_R1A_VSTOP, 0x7a},
1706 {OV7670_R03_VREF, 0x00},
1707 {OV7670_R0E_COM5, 0x04},
1708 {OV7670_R0F_COM6, 0x62},
1709 {OV7670_R15_COM10, 0x00},
1710 {0x16, 0x02}, /* RSVD */
1711 {0x1b, 0x00}, /* PSHFT */
1712 {OV7670_R1E_MVFP, 0x01},
1713 {0x29, 0x3c}, /* RSVD */
1714 {0x33, 0x00}, /* CHLF */
1715 {0x34, 0x07}, /* ARBLM */
1716 {0x35, 0x84}, /* RSVD */
1717 {0x36, 0x00}, /* RSVD */
1718 {0x37, 0x04}, /* ADC */
1719 {0x39, 0x43}, /* OFON */
1720 {OV7670_R3A_TSLB, 0x00},
1721 {OV7670_R3C_COM12, 0x6c},
1722 {OV7670_R3D_COM13, 0x98},
1723 {OV7670_R3F_EDGE, 0x23},
1724 {OV7670_R40_COM15, 0xc1},
1725 {OV7670_R41_COM16, 0x22},
1726 {0x6b, 0x0a}, /* DBLV */
1727 {0xa1, 0x08}, /* RSVD */
1728 {0x69, 0x80}, /* HV */
1729 {0x43, 0xf0}, /* RSVD.. */
1730 {0x44, 0x10},
1731 {0x45, 0x78},
1732 {0x46, 0xa8},
1733 {0x47, 0x60},
1734 {0x48, 0x80},
1735 {0x59, 0xba},
1736 {0x5a, 0x9a},
1737 {0x5b, 0x22},
1738 {0x5c, 0xb9},
1739 {0x5d, 0x9b},
1740 {0x5e, 0x10},
1741 {0x5f, 0xe0},
1742 {0x60, 0x85},
1743 {0x61, 0x60},
1744 {0x9f, 0x9d}, /* RSVD */
1745 {0xa0, 0xa0}, /* DSPC2 */
1746 {0x4f, 0x60}, /* matrix */
1747 {0x50, 0x64},
1748 {0x51, 0x04},
1749 {0x52, 0x18},
1750 {0x53, 0x3c},
1751 {0x54, 0x54},
1752 {0x55, 0x40},
1753 {0x56, 0x40},
1754 {0x57, 0x40},
1755 {0x58, 0x0d}, /* matrix sign */
1756 {0x8b, 0xcc}, /* RSVD */
1757 {0x8c, 0xcc},
1758 {0x8d, 0xcf},
1759 {0x6c, 0x40}, /* gamma curve */
1760 {0x6d, 0xe0},
1761 {0x6e, 0xa0},
1762 {0x6f, 0x80},
1763 {0x70, 0x70},
1764 {0x71, 0x80},
1765 {0x72, 0x60},
1766 {0x73, 0x60},
1767 {0x74, 0x50},
1768 {0x75, 0x40},
1769 {0x76, 0x38},
1770 {0x77, 0x3c},
1771 {0x78, 0x32},
1772 {0x79, 0x1a},
1773 {0x7a, 0x28},
1774 {0x7b, 0x24},
1775 {0x7c, 0x04}, /* gamma curve */
1776 {0x7d, 0x12},
1777 {0x7e, 0x26},
1778 {0x7f, 0x46},
1779 {0x80, 0x54},
1780 {0x81, 0x64},
1781 {0x82, 0x70},
1782 {0x83, 0x7c},
1783 {0x84, 0x86},
1784 {0x85, 0x8e},
1785 {0x86, 0x9c},
1786 {0x87, 0xab},
1787 {0x88, 0xc4},
1788 {0x89, 0xd1},
1789 {0x8a, 0xe5},
1790 {OV7670_R14_COM9, 0x1e},
1791 {OV7670_R24_AEW, 0x80},
1792 {OV7670_R25_AEB, 0x72},
1793 {OV7670_R26_VPT, 0xb3},
1794 {0x62, 0x80}, /* LCC1 */
1795 {0x63, 0x80}, /* LCC2 */
1796 {0x64, 0x06}, /* LCC3 */
1797 {0x65, 0x00}, /* LCC4 */
1798 {0x66, 0x01}, /* LCC5 */
1799 {0x94, 0x0e}, /* RSVD.. */
1800 {0x95, 0x14},
1801 {OV7670_R13_COM8, OV7670_COM8_FASTAEC
1802 | OV7670_COM8_AECSTEP
1803 | OV7670_COM8_BFILT
1804 | 0x10
1805 | OV7670_COM8_AGC
1806 | OV7670_COM8_AWB
1807 | OV7670_COM8_AEC},
1808 {0xa1, 0xc8}
1809};
1810
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001811/* 7670. Defaults taken from OmniVision provided data,
1812* as provided by Jonathan Corbet of OLPC */
1813static const struct ov_i2c_regvals norm_7670[] = {
Jean-François Moine21867802010-11-12 06:12:09 -03001814 { OV7670_R12_COM7, OV7670_COM7_RESET },
1815 { OV7670_R3A_TSLB, 0x04 }, /* OV */
1816 { OV7670_R12_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
1817 { OV7670_R11_CLKRC, 0x01 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001818/*
1819 * Set the hardware window. These values from OV don't entirely
1820 * make sense - hstop is less than hstart. But they work...
1821 */
Jean-François Moine21867802010-11-12 06:12:09 -03001822 { OV7670_R17_HSTART, 0x13 },
1823 { OV7670_R18_HSTOP, 0x01 },
1824 { OV7670_R32_HREF, 0xb6 },
1825 { OV7670_R19_VSTART, 0x02 },
1826 { OV7670_R1A_VSTOP, 0x7a },
1827 { OV7670_R03_VREF, 0x0a },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001828
Jean-François Moine21867802010-11-12 06:12:09 -03001829 { OV7670_R0C_COM3, 0x00 },
1830 { OV7670_R3E_COM14, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001831/* Mystery scaling numbers */
1832 { 0x70, 0x3a },
1833 { 0x71, 0x35 },
1834 { 0x72, 0x11 },
1835 { 0x73, 0xf0 },
1836 { 0xa2, 0x02 },
Jean-François Moine21867802010-11-12 06:12:09 -03001837/* { OV7670_R15_COM10, 0x0 }, */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001838
1839/* Gamma curve values */
1840 { 0x7a, 0x20 },
1841 { 0x7b, 0x10 },
1842 { 0x7c, 0x1e },
1843 { 0x7d, 0x35 },
1844 { 0x7e, 0x5a },
1845 { 0x7f, 0x69 },
1846 { 0x80, 0x76 },
1847 { 0x81, 0x80 },
1848 { 0x82, 0x88 },
1849 { 0x83, 0x8f },
1850 { 0x84, 0x96 },
1851 { 0x85, 0xa3 },
1852 { 0x86, 0xaf },
1853 { 0x87, 0xc4 },
1854 { 0x88, 0xd7 },
1855 { 0x89, 0xe8 },
1856
1857/* AGC and AEC parameters. Note we start by disabling those features,
1858 then turn them only after tweaking the values. */
Jean-François Moine21867802010-11-12 06:12:09 -03001859 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001860 | OV7670_COM8_AECSTEP
1861 | OV7670_COM8_BFILT },
Jean-François Moine21867802010-11-12 06:12:09 -03001862 { OV7670_R00_GAIN, 0x00 },
1863 { OV7670_R10_AECH, 0x00 },
1864 { OV7670_R0D_COM4, 0x40 }, /* magic reserved bit */
1865 { OV7670_R14_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
1866 { OV7670_RA5_BD50MAX, 0x05 },
1867 { OV7670_RAB_BD60MAX, 0x07 },
1868 { OV7670_R24_AEW, 0x95 },
1869 { OV7670_R25_AEB, 0x33 },
1870 { OV7670_R26_VPT, 0xe3 },
1871 { OV7670_R9F_HAECC1, 0x78 },
1872 { OV7670_RA0_HAECC2, 0x68 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001873 { 0xa1, 0x03 }, /* magic */
Jean-François Moine21867802010-11-12 06:12:09 -03001874 { OV7670_RA6_HAECC3, 0xd8 },
1875 { OV7670_RA7_HAECC4, 0xd8 },
1876 { OV7670_RA8_HAECC5, 0xf0 },
1877 { OV7670_RA9_HAECC6, 0x90 },
1878 { OV7670_RAA_HAECC7, 0x94 },
1879 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001880 | OV7670_COM8_AECSTEP
1881 | OV7670_COM8_BFILT
1882 | OV7670_COM8_AGC
1883 | OV7670_COM8_AEC },
1884
1885/* Almost all of these are magic "reserved" values. */
Jean-François Moine21867802010-11-12 06:12:09 -03001886 { OV7670_R0E_COM5, 0x61 },
1887 { OV7670_R0F_COM6, 0x4b },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001888 { 0x16, 0x02 },
Jean-François Moine21867802010-11-12 06:12:09 -03001889 { OV7670_R1E_MVFP, 0x07 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001890 { 0x21, 0x02 },
1891 { 0x22, 0x91 },
1892 { 0x29, 0x07 },
1893 { 0x33, 0x0b },
1894 { 0x35, 0x0b },
1895 { 0x37, 0x1d },
1896 { 0x38, 0x71 },
1897 { 0x39, 0x2a },
Jean-François Moine21867802010-11-12 06:12:09 -03001898 { OV7670_R3C_COM12, 0x78 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001899 { 0x4d, 0x40 },
1900 { 0x4e, 0x20 },
Jean-François Moine21867802010-11-12 06:12:09 -03001901 { OV7670_R69_GFIX, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001902 { 0x6b, 0x4a },
1903 { 0x74, 0x10 },
1904 { 0x8d, 0x4f },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001905 { 0x8e, 0x00 },
1906 { 0x8f, 0x00 },
1907 { 0x90, 0x00 },
1908 { 0x91, 0x00 },
1909 { 0x96, 0x00 },
1910 { 0x9a, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001911 { 0xb0, 0x84 },
1912 { 0xb1, 0x0c },
1913 { 0xb2, 0x0e },
1914 { 0xb3, 0x82 },
1915 { 0xb8, 0x0a },
1916
1917/* More reserved magic, some of which tweaks white balance */
1918 { 0x43, 0x0a },
1919 { 0x44, 0xf0 },
1920 { 0x45, 0x34 },
1921 { 0x46, 0x58 },
1922 { 0x47, 0x28 },
1923 { 0x48, 0x3a },
1924 { 0x59, 0x88 },
1925 { 0x5a, 0x88 },
1926 { 0x5b, 0x44 },
1927 { 0x5c, 0x67 },
1928 { 0x5d, 0x49 },
1929 { 0x5e, 0x0e },
1930 { 0x6c, 0x0a },
1931 { 0x6d, 0x55 },
1932 { 0x6e, 0x11 },
Jean-François Moinefc63de882011-01-13 05:35:18 -03001933 { 0x6f, 0x9f }, /* "9e for advance AWB" */
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001934 { 0x6a, 0x40 },
Jean-François Moine21867802010-11-12 06:12:09 -03001935 { OV7670_R01_BLUE, 0x40 },
1936 { OV7670_R02_RED, 0x60 },
1937 { OV7670_R13_COM8, OV7670_COM8_FASTAEC
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001938 | OV7670_COM8_AECSTEP
1939 | OV7670_COM8_BFILT
1940 | OV7670_COM8_AGC
1941 | OV7670_COM8_AEC
1942 | OV7670_COM8_AWB },
1943
1944/* Matrix coefficients */
1945 { 0x4f, 0x80 },
1946 { 0x50, 0x80 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001947 { 0x51, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001948 { 0x52, 0x22 },
1949 { 0x53, 0x5e },
1950 { 0x54, 0x80 },
1951 { 0x58, 0x9e },
1952
Jean-François Moine21867802010-11-12 06:12:09 -03001953 { OV7670_R41_COM16, OV7670_COM16_AWBGAIN },
1954 { OV7670_R3F_EDGE, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001955 { 0x75, 0x05 },
1956 { 0x76, 0xe1 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001957 { 0x4c, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001958 { 0x77, 0x01 },
Jean-François Moine21867802010-11-12 06:12:09 -03001959 { OV7670_R3D_COM13, OV7670_COM13_GAMMA
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001960 | OV7670_COM13_UVSAT
1961 | 2}, /* was 3 */
1962 { 0x4b, 0x09 },
1963 { 0xc9, 0x60 },
Jean-François Moine21867802010-11-12 06:12:09 -03001964 { OV7670_R41_COM16, 0x38 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001965 { 0x56, 0x40 },
1966
1967 { 0x34, 0x11 },
Jean-François Moine21867802010-11-12 06:12:09 -03001968 { OV7670_R3B_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001969 { 0xa4, 0x88 },
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03001970 { 0x96, 0x00 },
Jean-Francois Moine4202f712008-09-03 17:12:15 -03001971 { 0x97, 0x30 },
1972 { 0x98, 0x20 },
1973 { 0x99, 0x30 },
1974 { 0x9a, 0x84 },
1975 { 0x9b, 0x29 },
1976 { 0x9c, 0x03 },
1977 { 0x9d, 0x4c },
1978 { 0x9e, 0x3f },
1979 { 0x78, 0x04 },
1980
1981/* Extra-weird stuff. Some sort of multiplexor register */
1982 { 0x79, 0x01 },
1983 { 0xc8, 0xf0 },
1984 { 0x79, 0x0f },
1985 { 0xc8, 0x00 },
1986 { 0x79, 0x10 },
1987 { 0xc8, 0x7e },
1988 { 0x79, 0x0a },
1989 { 0xc8, 0x80 },
1990 { 0x79, 0x0b },
1991 { 0xc8, 0x01 },
1992 { 0x79, 0x0c },
1993 { 0xc8, 0x0f },
1994 { 0x79, 0x0d },
1995 { 0xc8, 0x20 },
1996 { 0x79, 0x09 },
1997 { 0xc8, 0x80 },
1998 { 0x79, 0x02 },
1999 { 0xc8, 0xc0 },
2000 { 0x79, 0x03 },
2001 { 0xc8, 0x40 },
2002 { 0x79, 0x05 },
2003 { 0xc8, 0x30 },
2004 { 0x79, 0x26 },
2005};
2006
2007static const struct ov_i2c_regvals norm_8610[] = {
2008 { 0x12, 0x80 },
2009 { 0x00, 0x00 },
2010 { 0x01, 0x80 },
2011 { 0x02, 0x80 },
2012 { 0x03, 0xc0 },
2013 { 0x04, 0x30 },
2014 { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
2015 { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
2016 { 0x0a, 0x86 },
2017 { 0x0b, 0xb0 },
2018 { 0x0c, 0x20 },
2019 { 0x0d, 0x20 },
2020 { 0x11, 0x01 },
2021 { 0x12, 0x25 },
2022 { 0x13, 0x01 },
2023 { 0x14, 0x04 },
2024 { 0x15, 0x01 }, /* Lin and Win think different about UV order */
2025 { 0x16, 0x03 },
2026 { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
2027 { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
2028 { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
2029 { 0x1a, 0xf5 },
2030 { 0x1b, 0x00 },
2031 { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
2032 { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
2033 { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
2034 { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
2035 { 0x26, 0xa2 },
2036 { 0x27, 0xea },
2037 { 0x28, 0x00 },
2038 { 0x29, 0x00 },
2039 { 0x2a, 0x80 },
2040 { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
2041 { 0x2c, 0xac },
2042 { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
2043 { 0x2e, 0x80 },
2044 { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
2045 { 0x4c, 0x00 },
2046 { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
2047 { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
2048 { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
2049 { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
2050 { 0x63, 0xff },
2051 { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
2052 * maybe thats wrong */
2053 { 0x65, 0x00 },
2054 { 0x66, 0x55 },
2055 { 0x67, 0xb0 },
2056 { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
2057 { 0x69, 0x02 },
2058 { 0x6a, 0x22 },
2059 { 0x6b, 0x00 },
2060 { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
2061 * deleting bit7 colors the first images red */
2062 { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
2063 { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
2064 { 0x6f, 0x01 },
2065 { 0x70, 0x8b },
2066 { 0x71, 0x00 },
2067 { 0x72, 0x14 },
2068 { 0x73, 0x54 },
2069 { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
2070 { 0x75, 0x0e },
2071 { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
2072 { 0x77, 0xff },
2073 { 0x78, 0x80 },
2074 { 0x79, 0x80 },
2075 { 0x7a, 0x80 },
2076 { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
2077 { 0x7c, 0x00 },
2078 { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
2079 { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
2080 { 0x7f, 0xfb },
2081 { 0x80, 0x28 },
2082 { 0x81, 0x00 },
2083 { 0x82, 0x23 },
2084 { 0x83, 0x0b },
2085 { 0x84, 0x00 },
2086 { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
2087 { 0x86, 0xc9 },
2088 { 0x87, 0x00 },
2089 { 0x88, 0x00 },
2090 { 0x89, 0x01 },
2091 { 0x12, 0x20 },
2092 { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
2093};
2094
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002095static unsigned char ov7670_abs_to_sm(unsigned char v)
2096{
2097 if (v > 127)
2098 return v & 0x7f;
2099 return (128 - v) | 0x80;
2100}
2101
2102/* Write a OV519 register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002103static void reg_w(struct sd *sd, u16 index, u16 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002104{
Hans de Goedea511ba92009-10-16 07:13:07 -03002105 int ret, req = 0;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002106
Jean-François Moinef8f20182010-11-12 07:54:02 -03002107 if (sd->gspca_dev.usb_err < 0)
2108 return;
2109
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002110 switch (sd->bridge) {
2111 case BRIDGE_OV511:
2112 case BRIDGE_OV511PLUS:
2113 req = 2;
2114 break;
2115 case BRIDGE_OVFX2:
Hans de Goedea511ba92009-10-16 07:13:07 -03002116 req = 0x0a;
2117 /* fall through */
2118 case BRIDGE_W9968CF:
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002119 PDEBUG(D_USBO, "SET %02x %04x %04x",
2120 req, value, index);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002121 ret = usb_control_msg(sd->gspca_dev.dev,
2122 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goedea511ba92009-10-16 07:13:07 -03002123 req,
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002124 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Hans de Goedea511ba92009-10-16 07:13:07 -03002125 value, index, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002126 goto leave;
2127 default:
2128 req = 1;
2129 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002130
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002131 PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
2132 req, index, value);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002133 sd->gspca_dev.usb_buf[0] = value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002134 ret = usb_control_msg(sd->gspca_dev.dev,
2135 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03002136 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002137 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2138 0, index,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002139 sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002140leave:
Hans de Goedea511ba92009-10-16 07:13:07 -03002141 if (ret < 0) {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002142 err("reg_w %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002143 sd->gspca_dev.usb_err = ret;
2144 return;
Hans de Goedea511ba92009-10-16 07:13:07 -03002145 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002146}
2147
Hans de Goedea511ba92009-10-16 07:13:07 -03002148/* Read from a OV519 register, note not valid for the w9968cf!! */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002149/* returns: negative is error, pos or zero is data */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002150static int reg_r(struct sd *sd, u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002151{
2152 int ret;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002153 int req;
2154
Jean-François Moinef8f20182010-11-12 07:54:02 -03002155 if (sd->gspca_dev.usb_err < 0)
2156 return -1;
2157
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002158 switch (sd->bridge) {
2159 case BRIDGE_OV511:
2160 case BRIDGE_OV511PLUS:
2161 req = 3;
2162 break;
2163 case BRIDGE_OVFX2:
2164 req = 0x0b;
2165 break;
2166 default:
2167 req = 1;
2168 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002169
2170 ret = usb_control_msg(sd->gspca_dev.dev,
2171 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
Hans de Goede49809d62009-06-07 12:10:39 -03002172 req,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002173 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002174 0, index, sd->gspca_dev.usb_buf, 1, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002175
Hans de Goedea511ba92009-10-16 07:13:07 -03002176 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002177 ret = sd->gspca_dev.usb_buf[0];
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002178 PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
2179 req, index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002180 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002181 err("reg_r %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002182 sd->gspca_dev.usb_err = ret;
2183 }
Hans de Goedea511ba92009-10-16 07:13:07 -03002184
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002185 return ret;
2186}
2187
2188/* Read 8 values from a OV519 register */
2189static int reg_r8(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002190 u16 index)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002191{
2192 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002193
Jean-François Moinef8f20182010-11-12 07:54:02 -03002194 if (sd->gspca_dev.usb_err < 0)
2195 return -1;
2196
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002197 ret = usb_control_msg(sd->gspca_dev.dev,
2198 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2199 1, /* REQ_IO */
2200 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002201 0, index, sd->gspca_dev.usb_buf, 8, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002202
Jean-François Moinef8f20182010-11-12 07:54:02 -03002203 if (ret >= 0) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002204 ret = sd->gspca_dev.usb_buf[0];
Jean-François Moinef8f20182010-11-12 07:54:02 -03002205 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002206 err("reg_r8 %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002207 sd->gspca_dev.usb_err = ret;
2208 }
Hans de Goedea511ba92009-10-16 07:13:07 -03002209
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002210 return ret;
2211}
2212
2213/*
2214 * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
2215 * the same position as 1's in "mask" are cleared and set to "value". Bits
2216 * that are in the same position as 0's in "mask" are preserved, regardless
2217 * of their respective state in "value".
2218 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002219static void reg_w_mask(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002220 u16 index,
2221 u8 value,
2222 u8 mask)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002223{
2224 int ret;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002225 u8 oldval;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002226
2227 if (mask != 0xff) {
2228 value &= mask; /* Enforce mask on value */
2229 ret = reg_r(sd, index);
2230 if (ret < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002231 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002232
2233 oldval = ret & ~mask; /* Clear the masked bits */
2234 value |= oldval; /* Set the desired bits */
2235 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03002236 reg_w(sd, index, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002237}
2238
2239/*
Hans de Goede49809d62009-06-07 12:10:39 -03002240 * Writes multiple (n) byte value to a single register. Only valid with certain
2241 * registers (0x30 and 0xc4 - 0xce).
2242 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002243static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
Hans de Goede49809d62009-06-07 12:10:39 -03002244{
2245 int ret;
2246
Jean-François Moinef8f20182010-11-12 07:54:02 -03002247 if (sd->gspca_dev.usb_err < 0)
2248 return;
2249
Jean-Francois Moine83955552009-12-12 06:58:01 -03002250 *((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
Hans de Goede49809d62009-06-07 12:10:39 -03002251
2252 ret = usb_control_msg(sd->gspca_dev.dev,
2253 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2254 1 /* REG_IO */,
2255 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
2256 0, index,
2257 sd->gspca_dev.usb_buf, n, 500);
Hans de Goedea511ba92009-10-16 07:13:07 -03002258 if (ret < 0) {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002259 err("reg_w32 %02x failed %d", index, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002260 sd->gspca_dev.usb_err = ret;
Hans de Goedea511ba92009-10-16 07:13:07 -03002261 }
Hans de Goede49809d62009-06-07 12:10:39 -03002262}
2263
Jean-François Moinef8f20182010-11-12 07:54:02 -03002264static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goede1876bb92009-06-14 06:45:50 -03002265{
2266 int rc, retries;
2267
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002268 PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002269
2270 /* Three byte write cycle */
2271 for (retries = 6; ; ) {
2272 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002273 reg_w(sd, R51x_I2C_SADDR_3, reg);
Hans de Goede1876bb92009-06-14 06:45:50 -03002274
2275 /* Write "value" to I2C data port of OV511 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002276 reg_w(sd, R51x_I2C_DATA, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002277
2278 /* Initiate 3-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002279 reg_w(sd, R511_I2C_CTL, 0x01);
Hans de Goede1876bb92009-06-14 06:45:50 -03002280
Jean-Francois Moine83955552009-12-12 06:58:01 -03002281 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002282 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002283 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002284
2285 if (rc < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002286 return;
Hans de Goede1876bb92009-06-14 06:45:50 -03002287
2288 if ((rc & 2) == 0) /* Ack? */
2289 break;
2290 if (--retries < 0) {
2291 PDEBUG(D_USBO, "i2c write retries exhausted");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002292 return;
Hans de Goede1876bb92009-06-14 06:45:50 -03002293 }
2294 }
Hans de Goede1876bb92009-06-14 06:45:50 -03002295}
2296
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002297static int ov511_i2c_r(struct sd *sd, u8 reg)
Hans de Goede1876bb92009-06-14 06:45:50 -03002298{
2299 int rc, value, retries;
2300
2301 /* Two byte write cycle */
2302 for (retries = 6; ; ) {
2303 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002304 reg_w(sd, R51x_I2C_SADDR_2, reg);
Hans de Goede1876bb92009-06-14 06:45:50 -03002305
2306 /* Initiate 2-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002307 reg_w(sd, R511_I2C_CTL, 0x03);
Hans de Goede1876bb92009-06-14 06:45:50 -03002308
Jean-Francois Moine83955552009-12-12 06:58:01 -03002309 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002310 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002311 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002312
2313 if (rc < 0)
2314 return rc;
2315
2316 if ((rc & 2) == 0) /* Ack? */
2317 break;
2318
2319 /* I2C abort */
2320 reg_w(sd, R511_I2C_CTL, 0x10);
2321
2322 if (--retries < 0) {
2323 PDEBUG(D_USBI, "i2c write retries exhausted");
2324 return -1;
2325 }
2326 }
2327
2328 /* Two byte read cycle */
2329 for (retries = 6; ; ) {
2330 /* Initiate 2-byte read cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002331 reg_w(sd, R511_I2C_CTL, 0x05);
Hans de Goede1876bb92009-06-14 06:45:50 -03002332
Jean-Francois Moine83955552009-12-12 06:58:01 -03002333 do {
Hans de Goede1876bb92009-06-14 06:45:50 -03002334 rc = reg_r(sd, R511_I2C_CTL);
Jean-Francois Moine83955552009-12-12 06:58:01 -03002335 } while (rc > 0 && ((rc & 1) == 0)); /* Retry until idle */
Hans de Goede1876bb92009-06-14 06:45:50 -03002336
2337 if (rc < 0)
2338 return rc;
2339
2340 if ((rc & 2) == 0) /* Ack? */
2341 break;
2342
2343 /* I2C abort */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002344 reg_w(sd, R511_I2C_CTL, 0x10);
Hans de Goede1876bb92009-06-14 06:45:50 -03002345
2346 if (--retries < 0) {
2347 PDEBUG(D_USBI, "i2c read retries exhausted");
2348 return -1;
2349 }
2350 }
2351
2352 value = reg_r(sd, R51x_I2C_DATA);
2353
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002354 PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
Hans de Goede1876bb92009-06-14 06:45:50 -03002355
2356 /* This is needed to make i2c_w() work */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002357 reg_w(sd, R511_I2C_CTL, 0x05);
Hans de Goede1876bb92009-06-14 06:45:50 -03002358
2359 return value;
2360}
Hans de Goede49809d62009-06-07 12:10:39 -03002361
2362/*
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002363 * The OV518 I2C I/O procedure is different, hence, this function.
2364 * This is normally only called from i2c_w(). Note that this function
2365 * always succeeds regardless of whether the sensor is present and working.
2366 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002367static void ov518_i2c_w(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002368 u8 reg,
2369 u8 value)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002370{
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002371 PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002372
2373 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002374 reg_w(sd, R51x_I2C_SADDR_3, reg);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002375
2376 /* Write "value" to I2C data port of OV511 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002377 reg_w(sd, R51x_I2C_DATA, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002378
2379 /* Initiate 3-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002380 reg_w(sd, R518_I2C_CTL, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002381
2382 /* wait for write complete */
2383 msleep(4);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002384 reg_r8(sd, R518_I2C_CTL);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002385}
2386
2387/*
2388 * returns: negative is error, pos or zero is data
2389 *
2390 * The OV518 I2C I/O procedure is different, hence, this function.
2391 * This is normally only called from i2c_r(). Note that this function
2392 * always succeeds regardless of whether the sensor is present and working.
2393 */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002394static int ov518_i2c_r(struct sd *sd, u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002395{
Jean-François Moinef8f20182010-11-12 07:54:02 -03002396 int value;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002397
2398 /* Select camera register */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002399 reg_w(sd, R51x_I2C_SADDR_2, reg);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002400
2401 /* Initiate 2-byte write cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002402 reg_w(sd, R518_I2C_CTL, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002403
2404 /* Initiate 2-byte read cycle */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002405 reg_w(sd, R518_I2C_CTL, 0x05);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002406 value = reg_r(sd, R51x_I2C_DATA);
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002407 PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002408 return value;
2409}
2410
Jean-François Moinef8f20182010-11-12 07:54:02 -03002411static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002412{
2413 int ret;
2414
Jean-François Moinef8f20182010-11-12 07:54:02 -03002415 if (sd->gspca_dev.usb_err < 0)
2416 return;
2417
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002418 ret = usb_control_msg(sd->gspca_dev.dev,
2419 usb_sndctrlpipe(sd->gspca_dev.dev, 0),
2420 0x02,
2421 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002422 (u16) value, (u16) reg, NULL, 0, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002423
Hans de Goedea511ba92009-10-16 07:13:07 -03002424 if (ret < 0) {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002425 err("ovfx2_i2c_w %02x failed %d", reg, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002426 sd->gspca_dev.usb_err = ret;
Hans de Goedea511ba92009-10-16 07:13:07 -03002427 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002428
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002429 PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002430}
2431
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002432static int ovfx2_i2c_r(struct sd *sd, u8 reg)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002433{
2434 int ret;
2435
Jean-François Moinef8f20182010-11-12 07:54:02 -03002436 if (sd->gspca_dev.usb_err < 0)
2437 return -1;
2438
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002439 ret = usb_control_msg(sd->gspca_dev.dev,
2440 usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
2441 0x03,
2442 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002443 0, (u16) reg, sd->gspca_dev.usb_buf, 1, 500);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002444
2445 if (ret >= 0) {
2446 ret = sd->gspca_dev.usb_buf[0];
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002447 PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002448 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002449 err("ovfx2_i2c_r %02x failed %d", reg, ret);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002450 sd->gspca_dev.usb_err = ret;
2451 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002452
2453 return ret;
2454}
2455
Jean-François Moinef8f20182010-11-12 07:54:02 -03002456static void i2c_w(struct sd *sd, u8 reg, u8 value)
Hans de Goede1876bb92009-06-14 06:45:50 -03002457{
Hans de Goedefb1f9022009-10-16 07:42:53 -03002458 if (sd->sensor_reg_cache[reg] == value)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002459 return;
Hans de Goedefb1f9022009-10-16 07:42:53 -03002460
Hans de Goede1876bb92009-06-14 06:45:50 -03002461 switch (sd->bridge) {
2462 case BRIDGE_OV511:
2463 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002464 ov511_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002465 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002466 case BRIDGE_OV518:
2467 case BRIDGE_OV518PLUS:
2468 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002469 ov518_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002470 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002471 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002472 ovfx2_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002473 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002474 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002475 w9968cf_i2c_w(sd, reg, value);
Hans de Goedefb1f9022009-10-16 07:42:53 -03002476 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002477 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002478
Jean-François Moinef8f20182010-11-12 07:54:02 -03002479 if (sd->gspca_dev.usb_err >= 0) {
Hans de Goedefb1f9022009-10-16 07:42:53 -03002480 /* Up on sensor reset empty the register cache */
2481 if (reg == 0x12 && (value & 0x80))
2482 memset(sd->sensor_reg_cache, -1,
Jean-François Moine87bae742010-11-12 05:31:34 -03002483 sizeof(sd->sensor_reg_cache));
Hans de Goedefb1f9022009-10-16 07:42:53 -03002484 else
2485 sd->sensor_reg_cache[reg] = value;
2486 }
Hans de Goede1876bb92009-06-14 06:45:50 -03002487}
2488
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002489static int i2c_r(struct sd *sd, u8 reg)
Hans de Goede1876bb92009-06-14 06:45:50 -03002490{
Hans de Goede8394bcf2009-10-16 11:26:22 -03002491 int ret = -1;
Hans de Goedefb1f9022009-10-16 07:42:53 -03002492
2493 if (sd->sensor_reg_cache[reg] != -1)
2494 return sd->sensor_reg_cache[reg];
2495
Hans de Goede1876bb92009-06-14 06:45:50 -03002496 switch (sd->bridge) {
2497 case BRIDGE_OV511:
2498 case BRIDGE_OV511PLUS:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002499 ret = ov511_i2c_r(sd, reg);
2500 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002501 case BRIDGE_OV518:
2502 case BRIDGE_OV518PLUS:
2503 case BRIDGE_OV519:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002504 ret = ov518_i2c_r(sd, reg);
2505 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002506 case BRIDGE_OVFX2:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002507 ret = ovfx2_i2c_r(sd, reg);
2508 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002509 case BRIDGE_W9968CF:
Hans de Goedefb1f9022009-10-16 07:42:53 -03002510 ret = w9968cf_i2c_r(sd, reg);
2511 break;
Hans de Goede1876bb92009-06-14 06:45:50 -03002512 }
Hans de Goedefb1f9022009-10-16 07:42:53 -03002513
2514 if (ret >= 0)
2515 sd->sensor_reg_cache[reg] = ret;
2516
2517 return ret;
Hans de Goede1876bb92009-06-14 06:45:50 -03002518}
2519
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002520/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
2521 * the same position as 1's in "mask" are cleared and set to "value". Bits
2522 * that are in the same position as 0's in "mask" are preserved, regardless
2523 * of their respective state in "value".
2524 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002525static void i2c_w_mask(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002526 u8 reg,
2527 u8 value,
2528 u8 mask)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002529{
2530 int rc;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002531 u8 oldval;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002532
2533 value &= mask; /* Enforce mask on value */
2534 rc = i2c_r(sd, reg);
2535 if (rc < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002536 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002537 oldval = rc & ~mask; /* Clear the masked bits */
2538 value |= oldval; /* Set the desired bits */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002539 i2c_w(sd, reg, value);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002540}
2541
2542/* Temporarily stops OV511 from functioning. Must do this before changing
2543 * registers while the camera is streaming */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002544static inline void ov51x_stop(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002545{
2546 PDEBUG(D_STREAM, "stopping");
2547 sd->stopped = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03002548 switch (sd->bridge) {
2549 case BRIDGE_OV511:
2550 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002551 reg_w(sd, R51x_SYS_RESET, 0x3d);
2552 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002553 case BRIDGE_OV518:
2554 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002555 reg_w_mask(sd, R51x_SYS_RESET, 0x3a, 0x3a);
2556 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002557 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002558 reg_w(sd, OV519_R51_RESET1, 0x0f);
Jean-François Moine5927abc2010-11-12 15:32:29 -03002559 reg_w(sd, OV519_R51_RESET1, 0x00);
2560 reg_w(sd, 0x22, 0x00); /* FRAR */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002561 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002562 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002563 reg_w_mask(sd, 0x0f, 0x00, 0x02);
2564 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002565 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002566 reg_w(sd, 0x3c, 0x0a05); /* stop USB transfer */
2567 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002568 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002569}
2570
2571/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
2572 * actually stopped (for performance). */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002573static inline void ov51x_restart(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002574{
2575 PDEBUG(D_STREAM, "restarting");
2576 if (!sd->stopped)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002577 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002578 sd->stopped = 0;
2579
2580 /* Reinitialize the stream */
Hans de Goede49809d62009-06-07 12:10:39 -03002581 switch (sd->bridge) {
2582 case BRIDGE_OV511:
2583 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002584 reg_w(sd, R51x_SYS_RESET, 0x00);
2585 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002586 case BRIDGE_OV518:
2587 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002588 reg_w(sd, 0x2f, 0x80);
2589 reg_w(sd, R51x_SYS_RESET, 0x00);
2590 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002591 case BRIDGE_OV519:
Jean-François Moine5927abc2010-11-12 15:32:29 -03002592 reg_w(sd, OV519_R51_RESET1, 0x0f);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002593 reg_w(sd, OV519_R51_RESET1, 0x00);
Jean-François Moine5927abc2010-11-12 15:32:29 -03002594 reg_w(sd, 0x22, 0x1d); /* FRAR */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002595 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002596 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002597 reg_w_mask(sd, 0x0f, 0x02, 0x02);
2598 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03002599 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002600 reg_w(sd, 0x3c, 0x8a05); /* USB FIFO enable */
2601 break;
Hans de Goede49809d62009-06-07 12:10:39 -03002602 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002603}
2604
Jean-François Moinef8f20182010-11-12 07:54:02 -03002605static void ov51x_set_slave_ids(struct sd *sd, u8 slave);
Hans de Goede229bb7d2009-10-11 07:41:46 -03002606
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002607/* This does an initial reset of an OmniVision sensor and ensures that I2C
2608 * is synchronized. Returns <0 on failure.
2609 */
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002610static int init_ov_sensor(struct sd *sd, u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002611{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002612 int i;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002613
Jean-François Moinef8f20182010-11-12 07:54:02 -03002614 ov51x_set_slave_ids(sd, slave);
Hans de Goede229bb7d2009-10-11 07:41:46 -03002615
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002616 /* Reset the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002617 i2c_w(sd, 0x12, 0x80);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002618
2619 /* Wait for it to initialize */
2620 msleep(150);
2621
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002622 for (i = 0; i < i2c_detect_tries; i++) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002623 if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
2624 i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03002625 PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
2626 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002627 }
2628
2629 /* Reset the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002630 i2c_w(sd, 0x12, 0x80);
2631
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002632 /* Wait for it to initialize */
2633 msleep(150);
Jean-François Moine87bae742010-11-12 05:31:34 -03002634
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002635 /* Dummy read to sync I2C */
2636 if (i2c_r(sd, 0x00) < 0)
Jean-François Moinef8f20182010-11-12 07:54:02 -03002637 return -1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002638 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03002639 return -1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002640}
2641
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002642/* Set the read and write slave IDs. The "slave" argument is the write slave,
2643 * and the read slave will be set to (slave + 1).
2644 * This should not be called from outside the i2c I/O functions.
2645 * Sets I2C read and write slave IDs. Returns <0 for error
2646 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002647static void ov51x_set_slave_ids(struct sd *sd,
Jean-François Moine9d1593a2010-11-11 08:04:06 -03002648 u8 slave)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002649{
Hans de Goedea511ba92009-10-16 07:13:07 -03002650 switch (sd->bridge) {
2651 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03002652 reg_w(sd, OVFX2_I2C_ADDR, slave);
2653 return;
Hans de Goedea511ba92009-10-16 07:13:07 -03002654 case BRIDGE_W9968CF:
2655 sd->sensor_addr = slave;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002656 return;
Hans de Goedea511ba92009-10-16 07:13:07 -03002657 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03002658
Jean-François Moinef8f20182010-11-12 07:54:02 -03002659 reg_w(sd, R51x_I2C_W_SID, slave);
2660 reg_w(sd, R51x_I2C_R_SID, slave + 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002661}
2662
Jean-François Moinef8f20182010-11-12 07:54:02 -03002663static void write_regvals(struct sd *sd,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002664 const struct ov_regvals *regvals,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002665 int n)
2666{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002667 while (--n >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03002668 reg_w(sd, regvals->reg, regvals->val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002669 regvals++;
2670 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002671}
2672
Jean-François Moinef8f20182010-11-12 07:54:02 -03002673static void write_i2c_regvals(struct sd *sd,
2674 const struct ov_i2c_regvals *regvals,
2675 int n)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002676{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002677 while (--n >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03002678 i2c_w(sd, regvals->reg, regvals->val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002679 regvals++;
2680 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002681}
2682
2683/****************************************************************************
2684 *
2685 * OV511 and sensor configuration
2686 *
2687 ***************************************************************************/
2688
Hans de Goede635118d2009-10-11 09:49:03 -03002689/* This initializes the OV2x10 / OV3610 / OV3620 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002690static void ov_hires_configure(struct sd *sd)
Hans de Goede635118d2009-10-11 09:49:03 -03002691{
2692 int high, low;
2693
2694 if (sd->bridge != BRIDGE_OVFX2) {
Jean-François Moine0b656322010-09-13 05:19:58 -03002695 err("error hires sensors only supported with ovfx2");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002696 return;
Hans de Goede635118d2009-10-11 09:49:03 -03002697 }
2698
2699 PDEBUG(D_PROBE, "starting ov hires configuration");
2700
2701 /* Detect sensor (sub)type */
2702 high = i2c_r(sd, 0x0a);
2703 low = i2c_r(sd, 0x0b);
2704 /* info("%x, %x", high, low); */
2705 if (high == 0x96 && low == 0x40) {
2706 PDEBUG(D_PROBE, "Sensor is an OV2610");
2707 sd->sensor = SEN_OV2610;
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03002708 } else if (high == 0x96 && low == 0x41) {
2709 PDEBUG(D_PROBE, "Sensor is an OV2610AE");
2710 sd->sensor = SEN_OV2610AE;
Hans de Goede635118d2009-10-11 09:49:03 -03002711 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2712 PDEBUG(D_PROBE, "Sensor is an OV3610");
2713 sd->sensor = SEN_OV3610;
2714 } else {
Jean-François Moine858ea5e2010-11-12 13:53:10 -03002715 err("Error unknown sensor type: %02x%02x",
Jean-François Moine87bae742010-11-12 05:31:34 -03002716 high, low);
Hans de Goede635118d2009-10-11 09:49:03 -03002717 }
Hans de Goede635118d2009-10-11 09:49:03 -03002718}
2719
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002720/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
2721 * the same register settings as the OV8610, since they are very similar.
2722 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002723static void ov8xx0_configure(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002724{
2725 int rc;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002726
2727 PDEBUG(D_PROBE, "starting ov8xx0 configuration");
2728
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002729 /* Detect sensor (sub)type */
2730 rc = i2c_r(sd, OV7610_REG_COM_I);
2731 if (rc < 0) {
2732 PDEBUG(D_ERR, "Error detecting sensor type");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002733 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002734 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03002735 if ((rc & 3) == 1)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002736 sd->sensor = SEN_OV8610;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002737 else
Jean-François Moine0b656322010-09-13 05:19:58 -03002738 err("Unknown image sensor version: %d", rc & 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002739}
2740
2741/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
2742 * the same register settings as the OV7610, since they are very similar.
2743 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002744static void ov7xx0_configure(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002745{
2746 int rc, high, low;
2747
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002748 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
2749
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002750 /* Detect sensor (sub)type */
2751 rc = i2c_r(sd, OV7610_REG_COM_I);
2752
2753 /* add OV7670 here
2754 * it appears to be wrongly detected as a 7610 by default */
2755 if (rc < 0) {
2756 PDEBUG(D_ERR, "Error detecting sensor type");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002757 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002758 }
2759 if ((rc & 3) == 3) {
2760 /* quick hack to make OV7670s work */
2761 high = i2c_r(sd, 0x0a);
2762 low = i2c_r(sd, 0x0b);
2763 /* info("%x, %x", high, low); */
Jean-François Moine7a5a4142010-12-25 13:58:45 -03002764 if (high == 0x76 && (low & 0xf0) == 0x70) {
2765 PDEBUG(D_PROBE, "Sensor is an OV76%02x", low);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002766 sd->sensor = SEN_OV7670;
2767 } else {
2768 PDEBUG(D_PROBE, "Sensor is an OV7610");
2769 sd->sensor = SEN_OV7610;
2770 }
2771 } else if ((rc & 3) == 1) {
2772 /* I don't know what's different about the 76BE yet. */
Hans de Goedeb282d872009-06-14 19:10:40 -03002773 if (i2c_r(sd, 0x15) & 1) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002774 PDEBUG(D_PROBE, "Sensor is an OV7620AE");
Hans de Goede859cc472010-01-07 15:42:35 -03002775 sd->sensor = SEN_OV7620AE;
Hans de Goedeb282d872009-06-14 19:10:40 -03002776 } else {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002777 PDEBUG(D_PROBE, "Sensor is an OV76BE");
Hans de Goedeb282d872009-06-14 19:10:40 -03002778 sd->sensor = SEN_OV76BE;
2779 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002780 } else if ((rc & 3) == 0) {
2781 /* try to read product id registers */
2782 high = i2c_r(sd, 0x0a);
2783 if (high < 0) {
2784 PDEBUG(D_ERR, "Error detecting camera chip PID");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002785 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002786 }
2787 low = i2c_r(sd, 0x0b);
2788 if (low < 0) {
2789 PDEBUG(D_ERR, "Error detecting camera chip VER");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002790 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002791 }
2792 if (high == 0x76) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002793 switch (low) {
2794 case 0x30:
Jean-François Moine0b656322010-09-13 05:19:58 -03002795 err("Sensor is an OV7630/OV7635");
2796 err("7630 is not supported by this driver");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002797 return;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002798 case 0x40:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002799 PDEBUG(D_PROBE, "Sensor is an OV7645");
2800 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002801 break;
2802 case 0x45:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002803 PDEBUG(D_PROBE, "Sensor is an OV7645B");
2804 sd->sensor = SEN_OV7640; /* FIXME */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002805 break;
2806 case 0x48:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002807 PDEBUG(D_PROBE, "Sensor is an OV7648");
Hans de Goede035d3a32010-01-09 08:14:43 -03002808 sd->sensor = SEN_OV7648;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002809 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03002810 case 0x60:
2811 PDEBUG(D_PROBE, "Sensor is a OV7660");
2812 sd->sensor = SEN_OV7660;
2813 sd->invert_led = 0;
2814 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002815 default:
2816 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002817 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002818 }
2819 } else {
2820 PDEBUG(D_PROBE, "Sensor is an OV7620");
2821 sd->sensor = SEN_OV7620;
2822 }
2823 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03002824 err("Unknown image sensor version: %d", rc & 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002825 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002826}
2827
2828/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
Jean-François Moinef8f20182010-11-12 07:54:02 -03002829static void ov6xx0_configure(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002830{
2831 int rc;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03002832 PDEBUG(D_PROBE, "starting OV6xx0 configuration");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002833
2834 /* Detect sensor (sub)type */
2835 rc = i2c_r(sd, OV7610_REG_COM_I);
2836 if (rc < 0) {
2837 PDEBUG(D_ERR, "Error detecting sensor type");
Jean-François Moinef8f20182010-11-12 07:54:02 -03002838 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002839 }
2840
2841 /* Ugh. The first two bits are the version bits, but
2842 * the entire register value must be used. I guess OVT
2843 * underestimated how many variants they would make. */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002844 switch (rc) {
2845 case 0x00:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002846 sd->sensor = SEN_OV6630;
Jean-François Moine0b656322010-09-13 05:19:58 -03002847 warn("WARNING: Sensor is an OV66308. Your camera may have");
2848 warn("been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002849 break;
2850 case 0x01:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002851 sd->sensor = SEN_OV6620;
Hans de Goede7d971372009-06-14 05:28:17 -03002852 PDEBUG(D_PROBE, "Sensor is an OV6620");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002853 break;
2854 case 0x02:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002855 sd->sensor = SEN_OV6630;
2856 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002857 break;
2858 case 0x03:
Hans de Goede7d971372009-06-14 05:28:17 -03002859 sd->sensor = SEN_OV66308AF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002860 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002861 break;
2862 case 0x90:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002863 sd->sensor = SEN_OV6630;
Jean-François Moine0b656322010-09-13 05:19:58 -03002864 warn("WARNING: Sensor is an OV66307. Your camera may have");
2865 warn("been misdetected in previous driver versions.");
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002866 break;
2867 default:
Jean-François Moine0b656322010-09-13 05:19:58 -03002868 err("FATAL: Unknown sensor version: 0x%02x", rc);
Jean-François Moinef8f20182010-11-12 07:54:02 -03002869 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002870 }
2871
2872 /* Set sensor-specific vars */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03002873 sd->sif = 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002874}
2875
2876/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
2877static void ov51x_led_control(struct sd *sd, int on)
2878{
Hans de Goede9e4d8252009-06-14 06:25:06 -03002879 if (sd->invert_led)
2880 on = !on;
2881
Hans de Goede49809d62009-06-07 12:10:39 -03002882 switch (sd->bridge) {
2883 /* OV511 has no LED control */
2884 case BRIDGE_OV511PLUS:
Jean-François Moinea23acec42010-11-12 15:07:35 -03002885 reg_w(sd, R511_SYS_LED_CTL, on);
Hans de Goede49809d62009-06-07 12:10:39 -03002886 break;
2887 case BRIDGE_OV518:
2888 case BRIDGE_OV518PLUS:
Jean-François Moinea23acec42010-11-12 15:07:35 -03002889 reg_w_mask(sd, R518_GPIO_OUT, 0x02 * on, 0x02);
Hans de Goede49809d62009-06-07 12:10:39 -03002890 break;
2891 case BRIDGE_OV519:
Jean-François Moinea23acec42010-11-12 15:07:35 -03002892 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, on, 1);
Hans de Goede49809d62009-06-07 12:10:39 -03002893 break;
2894 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002895}
2896
Hans de Goede417a4d22010-02-19 07:37:08 -03002897static void sd_reset_snapshot(struct gspca_dev *gspca_dev)
2898{
2899 struct sd *sd = (struct sd *) gspca_dev;
2900
2901 if (!sd->snapshot_needs_reset)
2902 return;
2903
2904 /* Note it is important that we clear sd->snapshot_needs_reset,
2905 before actually clearing the snapshot state in the bridge
2906 otherwise we might race with the pkt_scan interrupt handler */
2907 sd->snapshot_needs_reset = 0;
2908
2909 switch (sd->bridge) {
Hans de Goede88e8d202010-02-20 04:45:49 -03002910 case BRIDGE_OV511:
2911 case BRIDGE_OV511PLUS:
2912 reg_w(sd, R51x_SYS_SNAP, 0x02);
2913 reg_w(sd, R51x_SYS_SNAP, 0x00);
2914 break;
Hans de Goede92e232a2010-02-20 04:30:45 -03002915 case BRIDGE_OV518:
2916 case BRIDGE_OV518PLUS:
2917 reg_w(sd, R51x_SYS_SNAP, 0x02); /* Reset */
2918 reg_w(sd, R51x_SYS_SNAP, 0x01); /* Enable */
2919 break;
Hans de Goede417a4d22010-02-19 07:37:08 -03002920 case BRIDGE_OV519:
2921 reg_w(sd, R51x_SYS_RESET, 0x40);
2922 reg_w(sd, R51x_SYS_RESET, 0x00);
2923 break;
2924 }
2925}
2926
Jean-François Moinef8f20182010-11-12 07:54:02 -03002927static void ov51x_upload_quan_tables(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03002928{
Hans de Goede1876bb92009-06-14 06:45:50 -03002929 const unsigned char yQuanTable511[] = {
2930 0, 1, 1, 2, 2, 3, 3, 4,
2931 1, 1, 1, 2, 2, 3, 4, 4,
2932 1, 1, 2, 2, 3, 4, 4, 4,
2933 2, 2, 2, 3, 4, 4, 4, 4,
2934 2, 2, 3, 4, 4, 5, 5, 5,
2935 3, 3, 4, 4, 5, 5, 5, 5,
2936 3, 4, 4, 4, 5, 5, 5, 5,
2937 4, 4, 4, 4, 5, 5, 5, 5
2938 };
2939
2940 const unsigned char uvQuanTable511[] = {
2941 0, 2, 2, 3, 4, 4, 4, 4,
2942 2, 2, 2, 4, 4, 4, 4, 4,
2943 2, 2, 3, 4, 4, 4, 4, 4,
2944 3, 4, 4, 4, 4, 4, 4, 4,
2945 4, 4, 4, 4, 4, 4, 4, 4,
2946 4, 4, 4, 4, 4, 4, 4, 4,
2947 4, 4, 4, 4, 4, 4, 4, 4,
2948 4, 4, 4, 4, 4, 4, 4, 4
2949 };
2950
2951 /* OV518 quantization tables are 8x4 (instead of 8x8) */
Hans de Goede49809d62009-06-07 12:10:39 -03002952 const unsigned char yQuanTable518[] = {
2953 5, 4, 5, 6, 6, 7, 7, 7,
2954 5, 5, 5, 5, 6, 7, 7, 7,
2955 6, 6, 6, 6, 7, 7, 7, 8,
2956 7, 7, 6, 7, 7, 7, 8, 8
2957 };
Hans de Goede49809d62009-06-07 12:10:39 -03002958 const unsigned char uvQuanTable518[] = {
2959 6, 6, 6, 7, 7, 7, 7, 7,
2960 6, 6, 6, 7, 7, 7, 7, 7,
2961 6, 6, 6, 7, 7, 7, 7, 8,
2962 7, 7, 7, 7, 7, 7, 8, 8
2963 };
2964
Hans de Goede1876bb92009-06-14 06:45:50 -03002965 const unsigned char *pYTable, *pUVTable;
Hans de Goede49809d62009-06-07 12:10:39 -03002966 unsigned char val0, val1;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002967 int i, size, reg = R51x_COMP_LUT_BEGIN;
Hans de Goede49809d62009-06-07 12:10:39 -03002968
2969 PDEBUG(D_PROBE, "Uploading quantization tables");
2970
Hans de Goede1876bb92009-06-14 06:45:50 -03002971 if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
2972 pYTable = yQuanTable511;
2973 pUVTable = uvQuanTable511;
Jean-François Moine87bae742010-11-12 05:31:34 -03002974 size = 32;
Hans de Goede1876bb92009-06-14 06:45:50 -03002975 } else {
2976 pYTable = yQuanTable518;
2977 pUVTable = uvQuanTable518;
Jean-François Moine87bae742010-11-12 05:31:34 -03002978 size = 16;
Hans de Goede1876bb92009-06-14 06:45:50 -03002979 }
2980
2981 for (i = 0; i < size; i++) {
Hans de Goede49809d62009-06-07 12:10:39 -03002982 val0 = *pYTable++;
2983 val1 = *pYTable++;
2984 val0 &= 0x0f;
2985 val1 &= 0x0f;
2986 val0 |= val1 << 4;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002987 reg_w(sd, reg, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03002988
2989 val0 = *pUVTable++;
2990 val1 = *pUVTable++;
2991 val0 &= 0x0f;
2992 val1 &= 0x0f;
2993 val0 |= val1 << 4;
Jean-François Moinef8f20182010-11-12 07:54:02 -03002994 reg_w(sd, reg + size, val0);
Hans de Goede49809d62009-06-07 12:10:39 -03002995
2996 reg++;
2997 }
Hans de Goede49809d62009-06-07 12:10:39 -03002998}
2999
Hans de Goede1876bb92009-06-14 06:45:50 -03003000/* This initializes the OV511/OV511+ and the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003001static void ov511_configure(struct gspca_dev *gspca_dev)
Hans de Goede1876bb92009-06-14 06:45:50 -03003002{
3003 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede1876bb92009-06-14 06:45:50 -03003004
3005 /* For 511 and 511+ */
3006 const struct ov_regvals init_511[] = {
3007 { R51x_SYS_RESET, 0x7f },
3008 { R51x_SYS_INIT, 0x01 },
3009 { R51x_SYS_RESET, 0x7f },
3010 { R51x_SYS_INIT, 0x01 },
3011 { R51x_SYS_RESET, 0x3f },
3012 { R51x_SYS_INIT, 0x01 },
3013 { R51x_SYS_RESET, 0x3d },
3014 };
3015
3016 const struct ov_regvals norm_511[] = {
Jean-François Moine780e3122010-10-19 04:29:10 -03003017 { R511_DRAM_FLOW_CTL, 0x01 },
Hans de Goede1876bb92009-06-14 06:45:50 -03003018 { R51x_SYS_SNAP, 0x00 },
3019 { R51x_SYS_SNAP, 0x02 },
3020 { R51x_SYS_SNAP, 0x00 },
3021 { R511_FIFO_OPTS, 0x1f },
3022 { R511_COMP_EN, 0x00 },
3023 { R511_COMP_LUT_EN, 0x03 },
3024 };
3025
3026 const struct ov_regvals norm_511_p[] = {
3027 { R511_DRAM_FLOW_CTL, 0xff },
3028 { R51x_SYS_SNAP, 0x00 },
3029 { R51x_SYS_SNAP, 0x02 },
3030 { R51x_SYS_SNAP, 0x00 },
3031 { R511_FIFO_OPTS, 0xff },
3032 { R511_COMP_EN, 0x00 },
3033 { R511_COMP_LUT_EN, 0x03 },
3034 };
3035
3036 const struct ov_regvals compress_511[] = {
3037 { 0x70, 0x1f },
3038 { 0x71, 0x05 },
3039 { 0x72, 0x06 },
3040 { 0x73, 0x06 },
3041 { 0x74, 0x14 },
3042 { 0x75, 0x03 },
3043 { 0x76, 0x04 },
3044 { 0x77, 0x04 },
3045 };
3046
3047 PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
3048
Jean-François Moinef8f20182010-11-12 07:54:02 -03003049 write_regvals(sd, init_511, ARRAY_SIZE(init_511));
Hans de Goede1876bb92009-06-14 06:45:50 -03003050
3051 switch (sd->bridge) {
3052 case BRIDGE_OV511:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003053 write_regvals(sd, norm_511, ARRAY_SIZE(norm_511));
Hans de Goede1876bb92009-06-14 06:45:50 -03003054 break;
3055 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003056 write_regvals(sd, norm_511_p, ARRAY_SIZE(norm_511_p));
Hans de Goede1876bb92009-06-14 06:45:50 -03003057 break;
3058 }
3059
3060 /* Init compression */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003061 write_regvals(sd, compress_511, ARRAY_SIZE(compress_511));
Hans de Goede1876bb92009-06-14 06:45:50 -03003062
Jean-François Moinef8f20182010-11-12 07:54:02 -03003063 ov51x_upload_quan_tables(sd);
Hans de Goede1876bb92009-06-14 06:45:50 -03003064}
3065
Hans de Goede49809d62009-06-07 12:10:39 -03003066/* This initializes the OV518/OV518+ and the sensor */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003067static void ov518_configure(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003068{
3069 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003070
Hans de Goede49809d62009-06-07 12:10:39 -03003071 /* For 518 and 518+ */
Hans de Goedee080fcd2009-06-18 05:03:16 -03003072 const struct ov_regvals init_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03003073 { R51x_SYS_RESET, 0x40 },
3074 { R51x_SYS_INIT, 0xe1 },
3075 { R51x_SYS_RESET, 0x3e },
3076 { R51x_SYS_INIT, 0xe1 },
3077 { R51x_SYS_RESET, 0x00 },
3078 { R51x_SYS_INIT, 0xe1 },
3079 { 0x46, 0x00 },
3080 { 0x5d, 0x03 },
3081 };
3082
Hans de Goedee080fcd2009-06-18 05:03:16 -03003083 const struct ov_regvals norm_518[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03003084 { R51x_SYS_SNAP, 0x02 }, /* Reset */
3085 { R51x_SYS_SNAP, 0x01 }, /* Enable */
Jean-François Moine780e3122010-10-19 04:29:10 -03003086 { 0x31, 0x0f },
Hans de Goede49809d62009-06-07 12:10:39 -03003087 { 0x5d, 0x03 },
3088 { 0x24, 0x9f },
3089 { 0x25, 0x90 },
3090 { 0x20, 0x00 },
3091 { 0x51, 0x04 },
3092 { 0x71, 0x19 },
3093 { 0x2f, 0x80 },
3094 };
3095
Hans de Goedee080fcd2009-06-18 05:03:16 -03003096 const struct ov_regvals norm_518_p[] = {
Hans de Goede49809d62009-06-07 12:10:39 -03003097 { R51x_SYS_SNAP, 0x02 }, /* Reset */
3098 { R51x_SYS_SNAP, 0x01 }, /* Enable */
Jean-François Moine780e3122010-10-19 04:29:10 -03003099 { 0x31, 0x0f },
Hans de Goede49809d62009-06-07 12:10:39 -03003100 { 0x5d, 0x03 },
3101 { 0x24, 0x9f },
3102 { 0x25, 0x90 },
3103 { 0x20, 0x60 },
3104 { 0x51, 0x02 },
3105 { 0x71, 0x19 },
3106 { 0x40, 0xff },
3107 { 0x41, 0x42 },
3108 { 0x46, 0x00 },
3109 { 0x33, 0x04 },
3110 { 0x21, 0x19 },
3111 { 0x3f, 0x10 },
3112 { 0x2f, 0x80 },
3113 };
3114
3115 /* First 5 bits of custom ID reg are a revision ID on OV518 */
3116 PDEBUG(D_PROBE, "Device revision %d",
Jean-François Moine87bae742010-11-12 05:31:34 -03003117 0x1f & reg_r(sd, R51x_SYS_CUST_ID));
Hans de Goede49809d62009-06-07 12:10:39 -03003118
Jean-François Moinef8f20182010-11-12 07:54:02 -03003119 write_regvals(sd, init_518, ARRAY_SIZE(init_518));
Hans de Goede49809d62009-06-07 12:10:39 -03003120
3121 /* Set LED GPIO pin to output mode */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003122 reg_w_mask(sd, R518_GPIO_CTL, 0x00, 0x02);
Hans de Goede49809d62009-06-07 12:10:39 -03003123
3124 switch (sd->bridge) {
3125 case BRIDGE_OV518:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003126 write_regvals(sd, norm_518, ARRAY_SIZE(norm_518));
Hans de Goede49809d62009-06-07 12:10:39 -03003127 break;
3128 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003129 write_regvals(sd, norm_518_p, ARRAY_SIZE(norm_518_p));
Hans de Goede49809d62009-06-07 12:10:39 -03003130 break;
3131 }
3132
Jean-François Moinef8f20182010-11-12 07:54:02 -03003133 ov51x_upload_quan_tables(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003134
Jean-François Moinef8f20182010-11-12 07:54:02 -03003135 reg_w(sd, 0x2f, 0x80);
Hans de Goede49809d62009-06-07 12:10:39 -03003136}
3137
Jean-François Moinef8f20182010-11-12 07:54:02 -03003138static void ov519_configure(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03003139{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003140 static const struct ov_regvals init_519[] = {
Jean-François Moine87bae742010-11-12 05:31:34 -03003141 { 0x5a, 0x6d }, /* EnableSystem */
Jean-François Moinefc63de882011-01-13 05:35:18 -03003142 { 0x53, 0x9b }, /* don't enable the microcontroller */
Jean-François Moine21867802010-11-12 06:12:09 -03003143 { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */
Jean-François Moine87bae742010-11-12 05:31:34 -03003144 { 0x5d, 0x03 },
3145 { 0x49, 0x01 },
3146 { 0x48, 0x00 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003147 /* Set LED pin to output mode. Bit 4 must be cleared or sensor
3148 * detection will fail. This deserves further investigation. */
3149 { OV519_GPIO_IO_CTRL0, 0xee },
Jean-François Moine21867802010-11-12 06:12:09 -03003150 { OV519_R51_RESET1, 0x0f },
3151 { OV519_R51_RESET1, 0x00 },
Jean-François Moine87bae742010-11-12 05:31:34 -03003152 { 0x22, 0x00 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003153 /* windows reads 0x55 at this point*/
3154 };
3155
Jean-François Moinef8f20182010-11-12 07:54:02 -03003156 write_regvals(sd, init_519, ARRAY_SIZE(init_519));
Hans de Goede49809d62009-06-07 12:10:39 -03003157}
3158
Jean-François Moinef8f20182010-11-12 07:54:02 -03003159static void ovfx2_configure(struct sd *sd)
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003160{
3161 static const struct ov_regvals init_fx2[] = {
3162 { 0x00, 0x60 },
3163 { 0x02, 0x01 },
3164 { 0x0f, 0x1d },
3165 { 0xe9, 0x82 },
3166 { 0xea, 0xc7 },
3167 { 0xeb, 0x10 },
3168 { 0xec, 0xf6 },
3169 };
3170
3171 sd->stopped = 1;
3172
Jean-François Moinef8f20182010-11-12 07:54:02 -03003173 write_regvals(sd, init_fx2, ARRAY_SIZE(init_fx2));
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003174}
3175
Jean-François Moine42e142f2010-11-13 05:10:27 -03003176/* set the mode */
3177/* This function works for ov7660 only */
3178static void ov519_set_mode(struct sd *sd)
3179{
3180 static const struct ov_regvals bridge_ov7660[2][10] = {
3181 {{0x10, 0x14}, {0x11, 0x1e}, {0x12, 0x00}, {0x13, 0x00},
3182 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3183 {0x25, 0x01}, {0x26, 0x00}},
3184 {{0x10, 0x28}, {0x11, 0x3c}, {0x12, 0x00}, {0x13, 0x00},
3185 {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x20, 0x0c},
3186 {0x25, 0x03}, {0x26, 0x00}}
3187 };
3188 static const struct ov_i2c_regvals sensor_ov7660[2][3] = {
3189 {{0x12, 0x00}, {0x24, 0x00}, {0x0c, 0x0c}},
3190 {{0x12, 0x00}, {0x04, 0x00}, {0x0c, 0x00}}
3191 };
3192 static const struct ov_i2c_regvals sensor_ov7660_2[] = {
3193 {OV7670_R17_HSTART, 0x13},
3194 {OV7670_R18_HSTOP, 0x01},
3195 {OV7670_R32_HREF, 0x92},
3196 {OV7670_R19_VSTART, 0x02},
3197 {OV7670_R1A_VSTOP, 0x7a},
3198 {OV7670_R03_VREF, 0x00},
3199/* {0x33, 0x00}, */
3200/* {0x34, 0x07}, */
3201/* {0x36, 0x00}, */
3202/* {0x6b, 0x0a}, */
3203 };
3204
3205 write_regvals(sd, bridge_ov7660[sd->gspca_dev.curr_mode],
3206 ARRAY_SIZE(bridge_ov7660[0]));
3207 write_i2c_regvals(sd, sensor_ov7660[sd->gspca_dev.curr_mode],
3208 ARRAY_SIZE(sensor_ov7660[0]));
3209 write_i2c_regvals(sd, sensor_ov7660_2,
3210 ARRAY_SIZE(sensor_ov7660_2));
3211}
3212
3213/* set the frame rate */
3214/* This function works for sensors ov7640, ov7648 ov7660 and ov7670 only */
3215static void ov519_set_fr(struct sd *sd)
3216{
3217 int fr;
3218 u8 clock;
3219 /* frame rate table with indices:
3220 * - mode = 0: 320x240, 1: 640x480
3221 * - fr rate = 0: 30, 1: 25, 2: 20, 3: 15, 4: 10, 5: 5
3222 * - reg = 0: bridge a4, 1: bridge 23, 2: sensor 11 (clock)
3223 */
3224 static const u8 fr_tb[2][6][3] = {
3225 {{0x04, 0xff, 0x00},
3226 {0x04, 0x1f, 0x00},
3227 {0x04, 0x1b, 0x00},
3228 {0x04, 0x15, 0x00},
3229 {0x04, 0x09, 0x00},
3230 {0x04, 0x01, 0x00}},
3231 {{0x0c, 0xff, 0x00},
3232 {0x0c, 0x1f, 0x00},
3233 {0x0c, 0x1b, 0x00},
3234 {0x04, 0xff, 0x01},
3235 {0x04, 0x1f, 0x01},
3236 {0x04, 0x1b, 0x01}},
3237 };
3238
3239 if (frame_rate > 0)
3240 sd->frame_rate = frame_rate;
3241 if (sd->frame_rate >= 30)
3242 fr = 0;
3243 else if (sd->frame_rate >= 25)
3244 fr = 1;
3245 else if (sd->frame_rate >= 20)
3246 fr = 2;
3247 else if (sd->frame_rate >= 15)
3248 fr = 3;
3249 else if (sd->frame_rate >= 10)
3250 fr = 4;
3251 else
3252 fr = 5;
3253 reg_w(sd, 0xa4, fr_tb[sd->gspca_dev.curr_mode][fr][0]);
3254 reg_w(sd, 0x23, fr_tb[sd->gspca_dev.curr_mode][fr][1]);
3255 clock = fr_tb[sd->gspca_dev.curr_mode][fr][2];
3256 if (sd->sensor == SEN_OV7660)
3257 clock |= 0x80; /* enable double clock */
3258 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
3259}
3260
Jean-François Moine58c92d32011-03-13 16:36:49 -03003261static void setautogain(struct gspca_dev *gspca_dev)
3262{
3263 struct sd *sd = (struct sd *) gspca_dev;
3264
3265 i2c_w_mask(sd, 0x13, sd->ctrls[AUTOGAIN].val ? 0x05 : 0x00, 0x05);
3266}
3267
Hans de Goede49809d62009-06-07 12:10:39 -03003268/* this function is called at probe time */
3269static int sd_config(struct gspca_dev *gspca_dev,
3270 const struct usb_device_id *id)
3271{
3272 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003273 struct cam *cam = &gspca_dev->cam;
Hans de Goede49809d62009-06-07 12:10:39 -03003274
Hans de Goede9e4d8252009-06-14 06:25:06 -03003275 sd->bridge = id->driver_info & BRIDGE_MASK;
Jean-François Moinea23acec42010-11-12 15:07:35 -03003276 sd->invert_led = (id->driver_info & BRIDGE_INVERT_LED) != 0;
Hans de Goede49809d62009-06-07 12:10:39 -03003277
3278 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003279 case BRIDGE_OV511:
3280 case BRIDGE_OV511PLUS:
Jean-François Moine7491f782010-11-13 03:56:41 -03003281 cam->cam_mode = ov511_vga_mode;
3282 cam->nmodes = ARRAY_SIZE(ov511_vga_mode);
3283 break;
3284 case BRIDGE_OV518:
3285 case BRIDGE_OV518PLUS:
3286 cam->cam_mode = ov518_vga_mode;
3287 cam->nmodes = ARRAY_SIZE(ov518_vga_mode);
3288 break;
3289 case BRIDGE_OV519:
3290 cam->cam_mode = ov519_vga_mode;
3291 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3292 sd->invert_led = !sd->invert_led;
3293 break;
3294 case BRIDGE_OVFX2:
3295 cam->cam_mode = ov519_vga_mode;
3296 cam->nmodes = ARRAY_SIZE(ov519_vga_mode);
3297 cam->bulk_size = OVFX2_BULK_SIZE;
3298 cam->bulk_nurbs = MAX_NURBS;
3299 cam->bulk = 1;
3300 break;
3301 case BRIDGE_W9968CF:
3302 cam->cam_mode = w9968cf_vga_mode;
3303 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
3304 cam->reverse_alts = 1;
3305 break;
3306 }
3307
3308 gspca_dev->cam.ctrls = sd->ctrls;
3309 sd->quality = QUALITY_DEF;
3310
3311 return 0;
3312}
3313
3314/* this function is called at probe and resume time */
3315static int sd_init(struct gspca_dev *gspca_dev)
3316{
3317 struct sd *sd = (struct sd *) gspca_dev;
3318 struct cam *cam = &gspca_dev->cam;
3319
3320 switch (sd->bridge) {
3321 case BRIDGE_OV511:
3322 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003323 ov511_configure(gspca_dev);
Hans de Goede1876bb92009-06-14 06:45:50 -03003324 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003325 case BRIDGE_OV518:
3326 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003327 ov518_configure(gspca_dev);
Hans de Goede49809d62009-06-07 12:10:39 -03003328 break;
3329 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003330 ov519_configure(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03003331 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003332 case BRIDGE_OVFX2:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003333 ovfx2_configure(sd);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003334 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003335 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003336 w9968cf_configure(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03003337 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003338 }
3339
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003340 /* The OV519 must be more aggressive about sensor detection since
3341 * I2C write will never fail if the sensor is not present. We have
3342 * to try to initialize the sensor to detect its presence */
Jean-François Moine7bbe6b82010-11-11 08:27:24 -03003343 sd->sensor = -1;
Hans de Goede229bb7d2009-10-11 07:41:46 -03003344
3345 /* Test for 76xx */
3346 if (init_ov_sensor(sd, OV7xx0_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003347 ov7xx0_configure(sd);
3348
Hans de Goede229bb7d2009-10-11 07:41:46 -03003349 /* Test for 6xx0 */
3350 } else if (init_ov_sensor(sd, OV6xx0_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003351 ov6xx0_configure(sd);
3352
Hans de Goede229bb7d2009-10-11 07:41:46 -03003353 /* Test for 8xx0 */
3354 } else if (init_ov_sensor(sd, OV8xx0_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003355 ov8xx0_configure(sd);
3356
Hans de Goede635118d2009-10-11 09:49:03 -03003357 /* Test for 3xxx / 2xxx */
3358 } else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
Jean-François Moinef8f20182010-11-12 07:54:02 -03003359 ov_hires_configure(sd);
Hans de Goede229bb7d2009-10-11 07:41:46 -03003360 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03003361 err("Can't determine sensor slave IDs");
Hans de Goede229bb7d2009-10-11 07:41:46 -03003362 goto error;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003363 }
3364
Jean-François Moine7bbe6b82010-11-11 08:27:24 -03003365 if (sd->sensor < 0)
3366 goto error;
3367
Jean-François Moine7491f782010-11-13 03:56:41 -03003368 ov51x_led_control(sd, 0); /* turn LED off */
3369
Hans de Goede49809d62009-06-07 12:10:39 -03003370 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003371 case BRIDGE_OV511:
3372 case BRIDGE_OV511PLUS:
Jean-François Moine7491f782010-11-13 03:56:41 -03003373 if (sd->sif) {
Hans de Goede1876bb92009-06-14 06:45:50 -03003374 cam->cam_mode = ov511_sif_mode;
3375 cam->nmodes = ARRAY_SIZE(ov511_sif_mode);
3376 }
3377 break;
Hans de Goede49809d62009-06-07 12:10:39 -03003378 case BRIDGE_OV518:
3379 case BRIDGE_OV518PLUS:
Jean-François Moine7491f782010-11-13 03:56:41 -03003380 if (sd->sif) {
Hans de Goede49809d62009-06-07 12:10:39 -03003381 cam->cam_mode = ov518_sif_mode;
3382 cam->nmodes = ARRAY_SIZE(ov518_sif_mode);
3383 }
3384 break;
3385 case BRIDGE_OV519:
Jean-François Moine7491f782010-11-13 03:56:41 -03003386 if (sd->sif) {
Hans de Goede49809d62009-06-07 12:10:39 -03003387 cam->cam_mode = ov519_sif_mode;
3388 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3389 }
3390 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003391 case BRIDGE_OVFX2:
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003392 switch (sd->sensor) {
3393 case SEN_OV2610:
3394 case SEN_OV2610AE:
Hans de Goede635118d2009-10-11 09:49:03 -03003395 cam->cam_mode = ovfx2_ov2610_mode;
3396 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003397 break;
3398 case SEN_OV3610:
Hans de Goede635118d2009-10-11 09:49:03 -03003399 cam->cam_mode = ovfx2_ov3610_mode;
3400 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003401 break;
3402 default:
3403 if (sd->sif) {
3404 cam->cam_mode = ov519_sif_mode;
3405 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3406 }
3407 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003408 }
3409 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03003410 case BRIDGE_W9968CF:
Hans de Goede79b35902009-10-19 06:08:01 -03003411 if (sd->sif)
Jean-François Moine7491f782010-11-13 03:56:41 -03003412 cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode) - 1;
Hans de Goedea511ba92009-10-16 07:13:07 -03003413
3414 /* w9968cf needs initialisation once the sensor is known */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003415 w9968cf_init(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03003416 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003417 }
Jean-François Moine83db7682010-11-12 07:14:08 -03003418
3419 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Hans de Goede02ab18b2009-06-14 04:32:04 -03003420
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003421 /* initialize the sensor */
3422 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003423 case SEN_OV2610:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003424 write_i2c_regvals(sd, norm_2610, ARRAY_SIZE(norm_2610));
3425
Hans de Goede635118d2009-10-11 09:49:03 -03003426 /* Enable autogain, autoexpo, awb, bandfilter */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003427 i2c_w_mask(sd, 0x13, 0x27, 0x27);
Hans de Goede635118d2009-10-11 09:49:03 -03003428 break;
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003429 case SEN_OV2610AE:
3430 write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae));
3431
3432 /* enable autoexpo */
3433 i2c_w_mask(sd, 0x13, 0x05, 0x05);
3434 break;
Hans de Goede635118d2009-10-11 09:49:03 -03003435 case SEN_OV3610:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003436 write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
3437
Hans de Goede635118d2009-10-11 09:49:03 -03003438 /* Enable autogain, autoexpo, awb, bandfilter */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003439 i2c_w_mask(sd, 0x13, 0x27, 0x27);
Hans de Goede635118d2009-10-11 09:49:03 -03003440 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003441 case SEN_OV6620:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003442 write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003443 break;
3444 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03003445 case SEN_OV66308AF:
Jean-François Moine62833ac2010-10-02 04:27:02 -03003446 sd->ctrls[CONTRAST].def = 200;
3447 /* The default is too low for the ov6630 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003448 write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003449 break;
3450 default:
3451/* case SEN_OV7610: */
3452/* case SEN_OV76BE: */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003453 write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610));
3454 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003455 break;
3456 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003457 case SEN_OV7620AE:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003458 write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003459 break;
3460 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003461 case SEN_OV7648:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003462 write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003463 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03003464 case SEN_OV7660:
3465 i2c_w(sd, OV7670_R12_COM7, OV7670_COM7_RESET);
3466 msleep(14);
3467 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
3468 write_regvals(sd, init_519_ov7660,
3469 ARRAY_SIZE(init_519_ov7660));
3470 write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
3471 sd->gspca_dev.curr_mode = 1; /* 640x480 */
3472 sd->frame_rate = 15;
3473 ov519_set_mode(sd);
3474 ov519_set_fr(sd);
3475 sd->ctrls[COLORS].max = 4; /* 0..4 */
3476 sd->ctrls[COLORS].val =
3477 sd->ctrls[COLORS].def = 2;
3478 setcolors(gspca_dev);
3479 sd->ctrls[CONTRAST].max = 6; /* 0..6 */
3480 sd->ctrls[CONTRAST].val =
3481 sd->ctrls[CONTRAST].def = 3;
3482 setcontrast(gspca_dev);
3483 sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */
3484 sd->ctrls[BRIGHTNESS].val =
3485 sd->ctrls[BRIGHTNESS].def = 3;
3486 setbrightness(gspca_dev);
3487 sd_reset_snapshot(gspca_dev);
3488 ov51x_restart(sd);
3489 ov51x_stop(sd); /* not in win traces */
3490 ov51x_led_control(sd, 0);
3491 break;
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003492 case SEN_OV7670:
Jean-François Moine62833ac2010-10-02 04:27:02 -03003493 sd->ctrls[FREQ].max = 3; /* auto */
3494 sd->ctrls[FREQ].def = 3;
Jean-François Moinef8f20182010-11-12 07:54:02 -03003495 write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003496 break;
3497 case SEN_OV8610:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003498 write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610));
Jean-Francois Moine4202f712008-09-03 17:12:15 -03003499 break;
3500 }
Jean-François Moinef8f20182010-11-12 07:54:02 -03003501 return gspca_dev->usb_err;
Jean-François Moine7491f782010-11-13 03:56:41 -03003502error:
3503 PDEBUG(D_ERR, "OV519 Config failed");
3504 return -EINVAL;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003505}
3506
Jean-François Moinec42cedb2011-02-10 13:37:48 -03003507/* function called at start time before URB creation */
3508static int sd_isoc_init(struct gspca_dev *gspca_dev)
3509{
3510 struct sd *sd = (struct sd *) gspca_dev;
3511
3512 switch (sd->bridge) {
3513 case BRIDGE_OVFX2:
3514 if (gspca_dev->width == 1600)
3515 gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
3516 else
3517 gspca_dev->cam.bulk_size = 7 * 4096;
3518 break;
3519 }
3520 return 0;
3521}
3522
Hans de Goede1876bb92009-06-14 06:45:50 -03003523/* Set up the OV511/OV511+ with the given image parameters.
3524 *
3525 * Do not put any sensor-specific code in here (including I2C I/O functions)
3526 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003527static void ov511_mode_init_regs(struct sd *sd)
Hans de Goede1876bb92009-06-14 06:45:50 -03003528{
3529 int hsegs, vsegs, packet_size, fps, needed;
3530 int interlaced = 0;
3531 struct usb_host_interface *alt;
3532 struct usb_interface *intf;
3533
3534 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3535 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3536 if (!alt) {
Jean-François Moine0b656322010-09-13 05:19:58 -03003537 err("Couldn't get altsetting");
Jean-François Moinef8f20182010-11-12 07:54:02 -03003538 sd->gspca_dev.usb_err = -EIO;
3539 return;
Hans de Goede1876bb92009-06-14 06:45:50 -03003540 }
3541
3542 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3543 reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
3544
3545 reg_w(sd, R511_CAM_UV_EN, 0x01);
3546 reg_w(sd, R511_SNAP_UV_EN, 0x01);
3547 reg_w(sd, R511_SNAP_OPTS, 0x03);
3548
3549 /* Here I'm assuming that snapshot size == image size.
3550 * I hope that's always true. --claudio
3551 */
3552 hsegs = (sd->gspca_dev.width >> 3) - 1;
3553 vsegs = (sd->gspca_dev.height >> 3) - 1;
3554
3555 reg_w(sd, R511_CAM_PXCNT, hsegs);
3556 reg_w(sd, R511_CAM_LNCNT, vsegs);
3557 reg_w(sd, R511_CAM_PXDIV, 0x00);
3558 reg_w(sd, R511_CAM_LNDIV, 0x00);
3559
3560 /* YUV420, low pass filter on */
3561 reg_w(sd, R511_CAM_OPTS, 0x03);
3562
3563 /* Snapshot additions */
3564 reg_w(sd, R511_SNAP_PXCNT, hsegs);
3565 reg_w(sd, R511_SNAP_LNCNT, vsegs);
3566 reg_w(sd, R511_SNAP_PXDIV, 0x00);
3567 reg_w(sd, R511_SNAP_LNDIV, 0x00);
3568
3569 /******** Set the framerate ********/
3570 if (frame_rate > 0)
3571 sd->frame_rate = frame_rate;
3572
3573 switch (sd->sensor) {
3574 case SEN_OV6620:
3575 /* No framerate control, doesn't like higher rates yet */
3576 sd->clockdiv = 3;
3577 break;
3578
3579 /* Note once the FIXME's in mode_init_ov_sensor_regs() are fixed
3580 for more sensors we need to do this for them too */
3581 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03003582 case SEN_OV7620AE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003583 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003584 case SEN_OV7648:
Hans de Goedeb282d872009-06-14 19:10:40 -03003585 case SEN_OV76BE:
Hans de Goede1876bb92009-06-14 06:45:50 -03003586 if (sd->gspca_dev.width == 320)
3587 interlaced = 1;
3588 /* Fall through */
3589 case SEN_OV6630:
Hans de Goede1876bb92009-06-14 06:45:50 -03003590 case SEN_OV7610:
3591 case SEN_OV7670:
3592 switch (sd->frame_rate) {
3593 case 30:
3594 case 25:
3595 /* Not enough bandwidth to do 640x480 @ 30 fps */
3596 if (sd->gspca_dev.width != 640) {
3597 sd->clockdiv = 0;
3598 break;
3599 }
3600 /* Fall through for 640x480 case */
3601 default:
3602/* case 20: */
3603/* case 15: */
3604 sd->clockdiv = 1;
3605 break;
3606 case 10:
3607 sd->clockdiv = 2;
3608 break;
3609 case 5:
3610 sd->clockdiv = 5;
3611 break;
3612 }
3613 if (interlaced) {
3614 sd->clockdiv = (sd->clockdiv + 1) * 2 - 1;
3615 /* Higher then 10 does not work */
3616 if (sd->clockdiv > 10)
3617 sd->clockdiv = 10;
3618 }
3619 break;
3620
3621 case SEN_OV8610:
3622 /* No framerate control ?? */
3623 sd->clockdiv = 0;
3624 break;
3625 }
3626
3627 /* Check if we have enough bandwidth to disable compression */
3628 fps = (interlaced ? 60 : 30) / (sd->clockdiv + 1) + 1;
3629 needed = fps * sd->gspca_dev.width * sd->gspca_dev.height * 3 / 2;
3630 /* 1400 is a conservative estimate of the max nr of isoc packets/sec */
3631 if (needed > 1400 * packet_size) {
3632 /* Enable Y and UV quantization and compression */
3633 reg_w(sd, R511_COMP_EN, 0x07);
3634 reg_w(sd, R511_COMP_LUT_EN, 0x03);
3635 } else {
3636 reg_w(sd, R511_COMP_EN, 0x06);
3637 reg_w(sd, R511_COMP_LUT_EN, 0x00);
3638 }
3639
3640 reg_w(sd, R51x_SYS_RESET, OV511_RESET_OMNICE);
3641 reg_w(sd, R51x_SYS_RESET, 0);
Hans de Goede1876bb92009-06-14 06:45:50 -03003642}
3643
Hans de Goede49809d62009-06-07 12:10:39 -03003644/* Sets up the OV518/OV518+ with the given image parameters
3645 *
3646 * OV518 needs a completely different approach, until we can figure out what
3647 * the individual registers do. Also, only 15 FPS is supported now.
3648 *
3649 * Do not put any sensor-specific code in here (including I2C I/O functions)
3650 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003651static void ov518_mode_init_regs(struct sd *sd)
Hans de Goede49809d62009-06-07 12:10:39 -03003652{
Hans de Goedeb282d872009-06-14 19:10:40 -03003653 int hsegs, vsegs, packet_size;
3654 struct usb_host_interface *alt;
3655 struct usb_interface *intf;
3656
3657 intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
3658 alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
3659 if (!alt) {
Jean-François Moine0b656322010-09-13 05:19:58 -03003660 err("Couldn't get altsetting");
Jean-François Moinef8f20182010-11-12 07:54:02 -03003661 sd->gspca_dev.usb_err = -EIO;
3662 return;
Hans de Goedeb282d872009-06-14 19:10:40 -03003663 }
3664
3665 packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
3666 ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
Hans de Goede49809d62009-06-07 12:10:39 -03003667
3668 /******** Set the mode ********/
Hans de Goede49809d62009-06-07 12:10:39 -03003669 reg_w(sd, 0x2b, 0);
3670 reg_w(sd, 0x2c, 0);
3671 reg_w(sd, 0x2d, 0);
3672 reg_w(sd, 0x2e, 0);
3673 reg_w(sd, 0x3b, 0);
3674 reg_w(sd, 0x3c, 0);
3675 reg_w(sd, 0x3d, 0);
3676 reg_w(sd, 0x3e, 0);
3677
3678 if (sd->bridge == BRIDGE_OV518) {
3679 /* Set 8-bit (YVYU) input format */
3680 reg_w_mask(sd, 0x20, 0x08, 0x08);
3681
3682 /* Set 12-bit (4:2:0) output format */
3683 reg_w_mask(sd, 0x28, 0x80, 0xf0);
3684 reg_w_mask(sd, 0x38, 0x80, 0xf0);
3685 } else {
3686 reg_w(sd, 0x28, 0x80);
3687 reg_w(sd, 0x38, 0x80);
3688 }
3689
3690 hsegs = sd->gspca_dev.width / 16;
3691 vsegs = sd->gspca_dev.height / 4;
3692
3693 reg_w(sd, 0x29, hsegs);
3694 reg_w(sd, 0x2a, vsegs);
3695
3696 reg_w(sd, 0x39, hsegs);
3697 reg_w(sd, 0x3a, vsegs);
3698
3699 /* Windows driver does this here; who knows why */
3700 reg_w(sd, 0x2f, 0x80);
3701
Jean-François Moine87bae742010-11-12 05:31:34 -03003702 /******** Set the framerate ********/
Hans de Goedeb282d872009-06-14 19:10:40 -03003703 sd->clockdiv = 1;
Hans de Goede49809d62009-06-07 12:10:39 -03003704
3705 /* Mode independent, but framerate dependent, regs */
Hans de Goedeb282d872009-06-14 19:10:40 -03003706 /* 0x51: Clock divider; Only works on some cams which use 2 crystals */
3707 reg_w(sd, 0x51, 0x04);
Hans de Goede49809d62009-06-07 12:10:39 -03003708 reg_w(sd, 0x22, 0x18);
3709 reg_w(sd, 0x23, 0xff);
3710
Hans de Goedeb282d872009-06-14 19:10:40 -03003711 if (sd->bridge == BRIDGE_OV518PLUS) {
3712 switch (sd->sensor) {
Hans de Goede859cc472010-01-07 15:42:35 -03003713 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03003714 if (sd->gspca_dev.width == 320) {
3715 reg_w(sd, 0x20, 0x00);
3716 reg_w(sd, 0x21, 0x19);
3717 } else {
3718 reg_w(sd, 0x20, 0x60);
3719 reg_w(sd, 0x21, 0x1f);
3720 }
3721 break;
Hans de Goede859cc472010-01-07 15:42:35 -03003722 case SEN_OV7620:
3723 reg_w(sd, 0x20, 0x00);
3724 reg_w(sd, 0x21, 0x19);
3725 break;
Hans de Goedeb282d872009-06-14 19:10:40 -03003726 default:
3727 reg_w(sd, 0x21, 0x19);
3728 }
3729 } else
Hans de Goede49809d62009-06-07 12:10:39 -03003730 reg_w(sd, 0x71, 0x17); /* Compression-related? */
3731
3732 /* FIXME: Sensor-specific */
3733 /* Bit 5 is what matters here. Of course, it is "reserved" */
3734 i2c_w(sd, 0x54, 0x23);
3735
3736 reg_w(sd, 0x2f, 0x80);
3737
3738 if (sd->bridge == BRIDGE_OV518PLUS) {
3739 reg_w(sd, 0x24, 0x94);
3740 reg_w(sd, 0x25, 0x90);
3741 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3742 ov518_reg_w32(sd, 0xc6, 540, 2); /* 21ch */
3743 ov518_reg_w32(sd, 0xc7, 540, 2); /* 21ch */
3744 ov518_reg_w32(sd, 0xc8, 108, 2); /* 6ch */
3745 ov518_reg_w32(sd, 0xca, 131098, 3); /* 2001ah */
3746 ov518_reg_w32(sd, 0xcb, 532, 2); /* 214h */
3747 ov518_reg_w32(sd, 0xcc, 2400, 2); /* 960h */
3748 ov518_reg_w32(sd, 0xcd, 32, 2); /* 20h */
3749 ov518_reg_w32(sd, 0xce, 608, 2); /* 260h */
3750 } else {
3751 reg_w(sd, 0x24, 0x9f);
3752 reg_w(sd, 0x25, 0x90);
3753 ov518_reg_w32(sd, 0xc4, 400, 2); /* 190h */
3754 ov518_reg_w32(sd, 0xc6, 381, 2); /* 17dh */
3755 ov518_reg_w32(sd, 0xc7, 381, 2); /* 17dh */
3756 ov518_reg_w32(sd, 0xc8, 128, 2); /* 80h */
3757 ov518_reg_w32(sd, 0xca, 183331, 3); /* 2cc23h */
3758 ov518_reg_w32(sd, 0xcb, 746, 2); /* 2eah */
3759 ov518_reg_w32(sd, 0xcc, 1750, 2); /* 6d6h */
3760 ov518_reg_w32(sd, 0xcd, 45, 2); /* 2dh */
3761 ov518_reg_w32(sd, 0xce, 851, 2); /* 353h */
3762 }
3763
3764 reg_w(sd, 0x2f, 0x80);
Hans de Goede49809d62009-06-07 12:10:39 -03003765}
3766
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003767/* Sets up the OV519 with the given image parameters
3768 *
3769 * OV519 needs a completely different approach, until we can figure out what
3770 * the individual registers do.
3771 *
3772 * Do not put any sensor-specific code in here (including I2C I/O functions)
3773 */
Jean-François Moinef8f20182010-11-12 07:54:02 -03003774static void ov519_mode_init_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003775{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003776 static const struct ov_regvals mode_init_519_ov7670[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003777 { 0x5d, 0x03 }, /* Turn off suspend mode */
3778 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
Jean-François Moine21867802010-11-12 06:12:09 -03003779 { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003780 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3781 { 0xa3, 0x18 },
3782 { 0xa4, 0x04 },
3783 { 0xa5, 0x28 },
3784 { 0x37, 0x00 }, /* SetUsbInit */
3785 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3786 /* Enable both fields, YUV Input, disable defect comp (why?) */
3787 { 0x20, 0x0c },
3788 { 0x21, 0x38 },
3789 { 0x22, 0x1d },
3790 { 0x17, 0x50 }, /* undocumented */
3791 { 0x37, 0x00 }, /* undocumented */
3792 { 0x40, 0xff }, /* I2C timeout counter */
3793 { 0x46, 0x00 }, /* I2C clock prescaler */
3794 { 0x59, 0x04 }, /* new from windrv 090403 */
3795 { 0xff, 0x00 }, /* undocumented */
3796 /* windows reads 0x55 at this point, why? */
3797 };
3798
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03003799 static const struct ov_regvals mode_init_519[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003800 { 0x5d, 0x03 }, /* Turn off suspend mode */
3801 { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
Jean-François Moine21867802010-11-12 06:12:09 -03003802 { OV519_R54_EN_CLK1, 0x0f }, /* bit2 (jpeg enable) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003803 { 0xa2, 0x20 }, /* a2-a5 are undocumented */
3804 { 0xa3, 0x18 },
3805 { 0xa4, 0x04 },
3806 { 0xa5, 0x28 },
3807 { 0x37, 0x00 }, /* SetUsbInit */
3808 { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
3809 /* Enable both fields, YUV Input, disable defect comp (why?) */
3810 { 0x22, 0x1d },
3811 { 0x17, 0x50 }, /* undocumented */
3812 { 0x37, 0x00 }, /* undocumented */
3813 { 0x40, 0xff }, /* I2C timeout counter */
3814 { 0x46, 0x00 }, /* I2C clock prescaler */
3815 { 0x59, 0x04 }, /* new from windrv 090403 */
3816 { 0xff, 0x00 }, /* undocumented */
3817 /* windows reads 0x55 at this point, why? */
3818 };
3819
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003820 /******** Set the mode ********/
Jean-François Moine42e142f2010-11-13 05:10:27 -03003821 switch (sd->sensor) {
3822 default:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003823 write_regvals(sd, mode_init_519, ARRAY_SIZE(mode_init_519));
Hans de Goede035d3a32010-01-09 08:14:43 -03003824 if (sd->sensor == SEN_OV7640 ||
3825 sd->sensor == SEN_OV7648) {
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003826 /* Select 8-bit input mode */
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003827 reg_w_mask(sd, OV519_R20_DFR, 0x10, 0x10);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003828 }
Jean-François Moine42e142f2010-11-13 05:10:27 -03003829 break;
3830 case SEN_OV7660:
3831 return; /* done by ov519_set_mode/fr() */
3832 case SEN_OV7670:
Jean-François Moinef8f20182010-11-12 07:54:02 -03003833 write_regvals(sd, mode_init_519_ov7670,
3834 ARRAY_SIZE(mode_init_519_ov7670));
Jean-François Moine42e142f2010-11-13 05:10:27 -03003835 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003836 }
3837
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003838 reg_w(sd, OV519_R10_H_SIZE, sd->gspca_dev.width >> 4);
3839 reg_w(sd, OV519_R11_V_SIZE, sd->gspca_dev.height >> 3);
Hans de Goede80142ef2009-06-14 06:26:49 -03003840 if (sd->sensor == SEN_OV7670 &&
3841 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3842 reg_w(sd, OV519_R12_X_OFFSETL, 0x04);
Hans de Goede035d3a32010-01-09 08:14:43 -03003843 else if (sd->sensor == SEN_OV7648 &&
3844 sd->gspca_dev.cam.cam_mode[sd->gspca_dev.curr_mode].priv)
3845 reg_w(sd, OV519_R12_X_OFFSETL, 0x01);
Hans de Goede80142ef2009-06-14 06:26:49 -03003846 else
3847 reg_w(sd, OV519_R12_X_OFFSETL, 0x00);
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03003848 reg_w(sd, OV519_R13_X_OFFSETH, 0x00);
3849 reg_w(sd, OV519_R14_Y_OFFSETL, 0x00);
3850 reg_w(sd, OV519_R15_Y_OFFSETH, 0x00);
3851 reg_w(sd, OV519_R16_DIVIDER, 0x00);
3852 reg_w(sd, OV519_R25_FORMAT, 0x03); /* YUV422 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003853 reg_w(sd, 0x26, 0x00); /* Undocumented */
3854
3855 /******** Set the framerate ********/
3856 if (frame_rate > 0)
3857 sd->frame_rate = frame_rate;
3858
3859/* FIXME: These are only valid at the max resolution. */
3860 sd->clockdiv = 0;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003861 switch (sd->sensor) {
3862 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03003863 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003864 switch (sd->frame_rate) {
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003865 default:
3866/* case 30: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003867 reg_w(sd, 0xa4, 0x0c);
3868 reg_w(sd, 0x23, 0xff);
3869 break;
3870 case 25:
3871 reg_w(sd, 0xa4, 0x0c);
3872 reg_w(sd, 0x23, 0x1f);
3873 break;
3874 case 20:
3875 reg_w(sd, 0xa4, 0x0c);
3876 reg_w(sd, 0x23, 0x1b);
3877 break;
Jean-Francois Moine53e74512008-11-08 06:10:19 -03003878 case 15:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003879 reg_w(sd, 0xa4, 0x04);
3880 reg_w(sd, 0x23, 0xff);
3881 sd->clockdiv = 1;
3882 break;
3883 case 10:
3884 reg_w(sd, 0xa4, 0x04);
3885 reg_w(sd, 0x23, 0x1f);
3886 sd->clockdiv = 1;
3887 break;
3888 case 5:
3889 reg_w(sd, 0xa4, 0x04);
3890 reg_w(sd, 0x23, 0x1b);
3891 sd->clockdiv = 1;
3892 break;
3893 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003894 break;
3895 case SEN_OV8610:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003896 switch (sd->frame_rate) {
3897 default: /* 15 fps */
3898/* case 15: */
3899 reg_w(sd, 0xa4, 0x06);
3900 reg_w(sd, 0x23, 0xff);
3901 break;
3902 case 10:
3903 reg_w(sd, 0xa4, 0x06);
3904 reg_w(sd, 0x23, 0x1f);
3905 break;
3906 case 5:
3907 reg_w(sd, 0xa4, 0x06);
3908 reg_w(sd, 0x23, 0x1b);
3909 break;
3910 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003911 break;
3912 case SEN_OV7670: /* guesses, based on 7640 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003913 PDEBUG(D_STREAM, "Setting framerate to %d fps",
3914 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003915 reg_w(sd, 0xa4, 0x10);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003916 switch (sd->frame_rate) {
3917 case 30:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003918 reg_w(sd, 0x23, 0xff);
3919 break;
3920 case 20:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003921 reg_w(sd, 0x23, 0x1b);
3922 break;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003923 default:
3924/* case 15: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003925 reg_w(sd, 0x23, 0xff);
3926 sd->clockdiv = 1;
3927 break;
3928 }
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003929 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003930 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003931}
3932
Jean-François Moinef8f20182010-11-12 07:54:02 -03003933static void mode_init_ov_sensor_regs(struct sd *sd)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003934{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003935 struct gspca_dev *gspca_dev;
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003936 int qvga, xstart, xend, ystart, yend;
Jean-François Moine9d1593a2010-11-11 08:04:06 -03003937 u8 v;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03003938
3939 gspca_dev = &sd->gspca_dev;
Jean-François Moine87bae742010-11-12 05:31:34 -03003940 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003941
3942 /******** Mode (VGA/QVGA) and sensor specific regs ********/
3943 switch (sd->sensor) {
Hans de Goede635118d2009-10-11 09:49:03 -03003944 case SEN_OV2610:
3945 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
3946 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
3947 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
3948 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
3949 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
3950 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3951 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Jean-François Moinef8f20182010-11-12 07:54:02 -03003952 return;
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03003953 case SEN_OV2610AE: {
3954 u8 v;
3955
3956 /* frame rates:
3957 * 10fps / 5 fps for 1600x1200
3958 * 40fps / 20fps for 800x600
3959 */
3960 v = 80;
3961 if (qvga) {
3962 if (sd->frame_rate < 25)
3963 v = 0x81;
3964 } else {
3965 if (sd->frame_rate < 10)
3966 v = 0x81;
3967 }
3968 i2c_w(sd, 0x11, v);
3969 i2c_w(sd, 0x12, qvga ? 0x60 : 0x20);
3970 return;
3971 }
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003972 case SEN_OV3610:
Hans de Goede635118d2009-10-11 09:49:03 -03003973 if (qvga) {
3974 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003975 ystart = (776 - gspca_dev->height) / 2;
Hans de Goede635118d2009-10-11 09:49:03 -03003976 } else {
Hans de Goedeb46aaa02009-10-12 10:07:57 -03003977 xstart = (2076 - gspca_dev->width) / 2 + (0x10 << 4);
Hans de Goede635118d2009-10-11 09:49:03 -03003978 ystart = (1544 - gspca_dev->height) / 2;
3979 }
3980 xend = xstart + gspca_dev->width;
3981 yend = ystart + gspca_dev->height;
3982 /* Writing to the COMH register resets the other windowing regs
3983 to their default values, so we must do this first. */
3984 i2c_w_mask(sd, 0x12, qvga ? 0x40 : 0x00, 0xf0);
3985 i2c_w_mask(sd, 0x32,
3986 (((xend >> 1) & 7) << 3) | ((xstart >> 1) & 7),
3987 0x3f);
3988 i2c_w_mask(sd, 0x03,
3989 (((yend >> 1) & 3) << 2) | ((ystart >> 1) & 3),
3990 0x0f);
3991 i2c_w(sd, 0x17, xstart >> 4);
3992 i2c_w(sd, 0x18, xend >> 4);
3993 i2c_w(sd, 0x19, ystart >> 3);
3994 i2c_w(sd, 0x1a, yend >> 3);
Jean-François Moinef8f20182010-11-12 07:54:02 -03003995 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003996 case SEN_OV8610:
3997 /* For OV8610 qvga means qsvga */
3998 i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03003999 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
4000 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
4001 i2c_w_mask(sd, 0x2d, 0x00, 0x40); /* from windrv 090403 */
4002 i2c_w_mask(sd, 0x28, 0x20, 0x20); /* progressive mode on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004003 break;
4004 case SEN_OV7610:
4005 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Jean-François Moine780e3122010-10-19 04:29:10 -03004006 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004007 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
4008 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004009 break;
4010 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004011 case SEN_OV7620AE:
Hans de Goedeb282d872009-06-14 19:10:40 -03004012 case SEN_OV76BE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004013 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4014 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
4015 i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
4016 i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
4017 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goedeb282d872009-06-14 19:10:40 -03004018 i2c_w_mask(sd, 0x67, qvga ? 0xb0 : 0x90, 0xf0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004019 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004020 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
4021 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
4022 if (sd->sensor == SEN_OV76BE)
4023 i2c_w(sd, 0x35, qvga ? 0x1e : 0x9e);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004024 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004025 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004026 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004027 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4028 i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
Hans de Goede8d0082f2010-01-09 19:45:44 -03004029 /* Setting this undocumented bit in qvga mode removes a very
4030 annoying vertical shaking of the image */
Hans de Goede035d3a32010-01-09 08:14:43 -03004031 i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
Hans de Goede8d0082f2010-01-09 19:45:44 -03004032 /* Unknown */
Hans de Goede035d3a32010-01-09 08:14:43 -03004033 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
Hans de Goede8d0082f2010-01-09 19:45:44 -03004034 /* Allow higher automatic gain (to allow higher framerates) */
Hans de Goede035d3a32010-01-09 08:14:43 -03004035 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004036 i2c_w_mask(sd, 0x12, 0x04, 0x04); /* AWB: 1 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004037 break;
4038 case SEN_OV7670:
4039 /* set COM7_FMT_VGA or COM7_FMT_QVGA
4040 * do we need to set anything else?
4041 * HSTART etc are set in set_ov_sensor_window itself */
Jean-François Moine21867802010-11-12 06:12:09 -03004042 i2c_w_mask(sd, OV7670_R12_COM7,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004043 qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
4044 OV7670_COM7_FMT_MASK);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004045 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
Jean-François Moine21867802010-11-12 06:12:09 -03004046 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_AWB,
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004047 OV7670_COM8_AWB);
4048 if (qvga) { /* QVGA from ov7670.c by
4049 * Jonathan Corbet */
4050 xstart = 164;
4051 xend = 28;
4052 ystart = 14;
4053 yend = 494;
4054 } else { /* VGA */
4055 xstart = 158;
4056 xend = 14;
4057 ystart = 10;
4058 yend = 490;
4059 }
4060 /* OV7670 hardware window registers are split across
4061 * multiple locations */
Jean-François Moine21867802010-11-12 06:12:09 -03004062 i2c_w(sd, OV7670_R17_HSTART, xstart >> 3);
4063 i2c_w(sd, OV7670_R18_HSTOP, xend >> 3);
4064 v = i2c_r(sd, OV7670_R32_HREF);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004065 v = (v & 0xc0) | ((xend & 0x7) << 3) | (xstart & 0x07);
4066 msleep(10); /* need to sleep between read and write to
4067 * same reg! */
Jean-François Moine21867802010-11-12 06:12:09 -03004068 i2c_w(sd, OV7670_R32_HREF, v);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004069
Jean-François Moine21867802010-11-12 06:12:09 -03004070 i2c_w(sd, OV7670_R19_VSTART, ystart >> 2);
4071 i2c_w(sd, OV7670_R1A_VSTOP, yend >> 2);
4072 v = i2c_r(sd, OV7670_R03_VREF);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004073 v = (v & 0xc0) | ((yend & 0x3) << 2) | (ystart & 0x03);
4074 msleep(10); /* need to sleep between read and write to
4075 * same reg! */
Jean-François Moine21867802010-11-12 06:12:09 -03004076 i2c_w(sd, OV7670_R03_VREF, v);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004077 break;
4078 case SEN_OV6620:
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004079 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
4080 i2c_w_mask(sd, 0x13, 0x00, 0x20); /* Select 16 bit data bus */
4081 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
4082 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004083 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004084 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004085 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004086 i2c_w_mask(sd, 0x12, 0x04, 0x06); /* AWB: 1 Test pattern: 0 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004087 break;
4088 default:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004089 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004090 }
4091
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004092 /******** Clock programming ********/
Hans de Goedeae49c402009-06-14 19:15:07 -03004093 i2c_w(sd, 0x11, sd->clockdiv);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004094}
4095
Jean-François Moine42e142f2010-11-13 05:10:27 -03004096/* this function works for bridge ov519 and sensors ov7660 and ov7670 only */
Jean-François Moine62833ac2010-10-02 04:27:02 -03004097static void sethvflip(struct gspca_dev *gspca_dev)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004098{
Jean-François Moine62833ac2010-10-02 04:27:02 -03004099 struct sd *sd = (struct sd *) gspca_dev;
4100
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004101 if (sd->gspca_dev.streaming)
Jean-François Moine5927abc2010-11-12 15:32:29 -03004102 reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */
Jean-François Moine21867802010-11-12 06:12:09 -03004103 i2c_w_mask(sd, OV7670_R1E_MVFP,
Jean-François Moine62833ac2010-10-02 04:27:02 -03004104 OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val
4105 | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val,
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004106 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004107 if (sd->gspca_dev.streaming)
Jean-François Moine5927abc2010-11-12 15:32:29 -03004108 reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004109}
4110
Jean-François Moinef8f20182010-11-12 07:54:02 -03004111static void set_ov_sensor_window(struct sd *sd)
Jean-Francois Moine0cd67592008-07-29 05:25:28 -03004112{
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004113 struct gspca_dev *gspca_dev;
Hans de Goede124cc9c2009-06-14 05:48:00 -03004114 int qvga, crop;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004115 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004116
Hans de Goede635118d2009-10-11 09:49:03 -03004117 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
Jean-François Moine42e142f2010-11-13 05:10:27 -03004118 switch (sd->sensor) {
4119 case SEN_OV2610:
Jean-François Moine07c6c9c2011-02-10 13:32:22 -03004120 case SEN_OV2610AE:
Jean-François Moine42e142f2010-11-13 05:10:27 -03004121 case SEN_OV3610:
4122 case SEN_OV7670:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004123 mode_init_ov_sensor_regs(sd);
4124 return;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004125 case SEN_OV7660:
4126 ov519_set_mode(sd);
4127 ov519_set_fr(sd);
4128 return;
Jean-François Moinef8f20182010-11-12 07:54:02 -03004129 }
Jean-François Moine42e142f2010-11-13 05:10:27 -03004130
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004131 gspca_dev = &sd->gspca_dev;
Jean-François Moine87bae742010-11-12 05:31:34 -03004132 qvga = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 1;
4133 crop = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & 2;
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004134
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004135 /* The different sensor ICs handle setting up of window differently.
4136 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
4137 switch (sd->sensor) {
4138 case SEN_OV8610:
4139 hwsbase = 0x1e;
4140 hwebase = 0x1e;
4141 vwsbase = 0x02;
4142 vwebase = 0x02;
4143 break;
4144 case SEN_OV7610:
4145 case SEN_OV76BE:
4146 hwsbase = 0x38;
4147 hwebase = 0x3a;
4148 vwsbase = vwebase = 0x05;
4149 break;
4150 case SEN_OV6620:
4151 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004152 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004153 hwsbase = 0x38;
4154 hwebase = 0x3a;
4155 vwsbase = 0x05;
4156 vwebase = 0x06;
Hans de Goede7d971372009-06-14 05:28:17 -03004157 if (sd->sensor == SEN_OV66308AF && qvga)
Hans de Goede49809d62009-06-07 12:10:39 -03004158 /* HDG: this fixes U and V getting swapped */
Hans de Goede7d971372009-06-14 05:28:17 -03004159 hwsbase++;
Hans de Goede124cc9c2009-06-14 05:48:00 -03004160 if (crop) {
4161 hwsbase += 8;
4162 hwebase += 8;
4163 vwsbase += 11;
4164 vwebase += 11;
4165 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004166 break;
4167 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004168 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004169 hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
4170 hwebase = 0x2f;
4171 vwsbase = vwebase = 0x05;
4172 break;
4173 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004174 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004175 hwsbase = 0x1a;
4176 hwebase = 0x1a;
4177 vwsbase = vwebase = 0x03;
4178 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004179 default:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004180 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004181 }
4182
4183 switch (sd->sensor) {
4184 case SEN_OV6620:
4185 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004186 case SEN_OV66308AF:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004187 if (qvga) { /* QCIF */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004188 hwscale = 0;
4189 vwscale = 0;
4190 } else { /* CIF */
4191 hwscale = 1;
4192 vwscale = 1; /* The datasheet says 0;
4193 * it's wrong */
4194 }
4195 break;
4196 case SEN_OV8610:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004197 if (qvga) { /* QSVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004198 hwscale = 1;
4199 vwscale = 1;
4200 } else { /* SVGA */
4201 hwscale = 2;
4202 vwscale = 2;
4203 }
4204 break;
4205 default: /* SEN_OV7xx0 */
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004206 if (qvga) { /* QVGA */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004207 hwscale = 1;
4208 vwscale = 0;
4209 } else { /* VGA */
4210 hwscale = 2;
4211 vwscale = 1;
4212 }
4213 }
4214
Jean-François Moinef8f20182010-11-12 07:54:02 -03004215 mode_init_ov_sensor_regs(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004216
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004217 i2c_w(sd, 0x17, hwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03004218 i2c_w(sd, 0x18, hwebase + (sd->sensor_width >> hwscale));
Hans de Goedeebbb5c32009-10-12 11:32:44 -03004219 i2c_w(sd, 0x19, vwsbase);
Hans de Goedea511ba92009-10-16 07:13:07 -03004220 i2c_w(sd, 0x1a, vwebase + (sd->sensor_height >> vwscale));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004221}
4222
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004223/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03004224static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004225{
4226 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004227
Hans de Goedea511ba92009-10-16 07:13:07 -03004228 /* Default for most bridges, allow bridge_mode_init_regs to override */
4229 sd->sensor_width = sd->gspca_dev.width;
4230 sd->sensor_height = sd->gspca_dev.height;
4231
Hans de Goede49809d62009-06-07 12:10:39 -03004232 switch (sd->bridge) {
Hans de Goede1876bb92009-06-14 06:45:50 -03004233 case BRIDGE_OV511:
4234 case BRIDGE_OV511PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004235 ov511_mode_init_regs(sd);
Hans de Goede1876bb92009-06-14 06:45:50 -03004236 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004237 case BRIDGE_OV518:
4238 case BRIDGE_OV518PLUS:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004239 ov518_mode_init_regs(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03004240 break;
4241 case BRIDGE_OV519:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004242 ov519_mode_init_regs(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03004243 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004244 /* case BRIDGE_OVFX2: nothing to do */
Hans de Goedea511ba92009-10-16 07:13:07 -03004245 case BRIDGE_W9968CF:
Jean-François Moinef8f20182010-11-12 07:54:02 -03004246 w9968cf_mode_init_regs(sd);
Hans de Goedea511ba92009-10-16 07:13:07 -03004247 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004248 }
Hans de Goede49809d62009-06-07 12:10:39 -03004249
Jean-François Moinef8f20182010-11-12 07:54:02 -03004250 set_ov_sensor_window(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004251
Jean-François Moinee2817022010-11-12 13:59:48 -03004252 if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST)))
4253 setcontrast(gspca_dev);
4254 if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
4255 setbrightness(gspca_dev);
Jean-François Moine58c92d32011-03-13 16:36:49 -03004256 if (!(sd->gspca_dev.ctrl_dis & (1 << EXPOSURE)))
4257 setexposure(gspca_dev);
Jean-François Moinee2817022010-11-12 13:59:48 -03004258 if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
4259 setcolors(gspca_dev);
4260 if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
4261 sethvflip(gspca_dev);
4262 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
4263 setautobright(gspca_dev);
Jean-François Moine58c92d32011-03-13 16:36:49 -03004264 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOGAIN)))
4265 setautogain(gspca_dev);
Jean-François Moinee2817022010-11-12 13:59:48 -03004266 if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
4267 setfreq_i(sd);
Hans de Goede49809d62009-06-07 12:10:39 -03004268
Hans de Goede417a4d22010-02-19 07:37:08 -03004269 /* Force clear snapshot state in case the snapshot button was
4270 pressed while we weren't streaming */
4271 sd->snapshot_needs_reset = 1;
4272 sd_reset_snapshot(gspca_dev);
Hans de Goede417a4d22010-02-19 07:37:08 -03004273
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004274 sd->first_frame = 3;
4275
Jean-François Moinef8f20182010-11-12 07:54:02 -03004276 ov51x_restart(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004277 ov51x_led_control(sd, 1);
Jean-François Moinef8f20182010-11-12 07:54:02 -03004278 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004279}
4280
4281static void sd_stopN(struct gspca_dev *gspca_dev)
4282{
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004283 struct sd *sd = (struct sd *) gspca_dev;
4284
4285 ov51x_stop(sd);
4286 ov51x_led_control(sd, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004287}
4288
Hans de Goede79b35902009-10-19 06:08:01 -03004289static void sd_stop0(struct gspca_dev *gspca_dev)
4290{
4291 struct sd *sd = (struct sd *) gspca_dev;
4292
Jean-François Moined65174c2010-11-11 06:20:42 -03004293 if (!sd->gspca_dev.present)
4294 return;
Hans de Goede79b35902009-10-19 06:08:01 -03004295 if (sd->bridge == BRIDGE_W9968CF)
4296 w9968cf_stop0(sd);
Hans de Goede614d0692010-10-27 07:42:28 -03004297
Jean-François Moine14653e62010-11-11 06:17:01 -03004298#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede614d0692010-10-27 07:42:28 -03004299 /* If the last button state is pressed, release it now! */
4300 if (sd->snapshot_pressed) {
4301 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
4302 input_sync(gspca_dev->input_dev);
4303 sd->snapshot_pressed = 0;
4304 }
4305#endif
Jean-François Moineb4e96ea2010-11-12 16:13:17 -03004306 if (sd->bridge == BRIDGE_OV519)
4307 reg_w(sd, OV519_R57_SNAPSHOT, 0x23);
Hans de Goede79b35902009-10-19 06:08:01 -03004308}
4309
Hans de Goede92e232a2010-02-20 04:30:45 -03004310static void ov51x_handle_button(struct gspca_dev *gspca_dev, u8 state)
4311{
4312 struct sd *sd = (struct sd *) gspca_dev;
4313
4314 if (sd->snapshot_pressed != state) {
Jean-François Moine28566432010-10-01 07:33:26 -03004315#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede92e232a2010-02-20 04:30:45 -03004316 input_report_key(gspca_dev->input_dev, KEY_CAMERA, state);
4317 input_sync(gspca_dev->input_dev);
4318#endif
4319 if (state)
4320 sd->snapshot_needs_reset = 1;
4321
4322 sd->snapshot_pressed = state;
4323 } else {
Hans de Goede88e8d202010-02-20 04:45:49 -03004324 /* On the ov511 / ov519 we need to reset the button state
4325 multiple times, as resetting does not work as long as the
4326 button stays pressed */
4327 switch (sd->bridge) {
4328 case BRIDGE_OV511:
4329 case BRIDGE_OV511PLUS:
4330 case BRIDGE_OV519:
4331 if (state)
4332 sd->snapshot_needs_reset = 1;
4333 break;
4334 }
Hans de Goede92e232a2010-02-20 04:30:45 -03004335 }
4336}
4337
Hans de Goede1876bb92009-06-14 06:45:50 -03004338static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004339 u8 *in, /* isoc packet */
4340 int len) /* iso packet length */
Hans de Goede1876bb92009-06-14 06:45:50 -03004341{
4342 struct sd *sd = (struct sd *) gspca_dev;
4343
4344 /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
4345 * byte non-zero. The EOF packet has image width/height in the
4346 * 10th and 11th bytes. The 9th byte is given as follows:
4347 *
4348 * bit 7: EOF
4349 * 6: compression enabled
4350 * 5: 422/420/400 modes
4351 * 4: 422/420/400 modes
4352 * 3: 1
4353 * 2: snapshot button on
4354 * 1: snapshot frame
4355 * 0: even/odd field
4356 */
4357 if (!(in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) &&
4358 (in[8] & 0x08)) {
Hans de Goede88e8d202010-02-20 04:45:49 -03004359 ov51x_handle_button(gspca_dev, (in[8] >> 2) & 1);
Hans de Goede1876bb92009-06-14 06:45:50 -03004360 if (in[8] & 0x80) {
4361 /* Frame end */
4362 if ((in[9] + 1) * 8 != gspca_dev->width ||
4363 (in[10] + 1) * 8 != gspca_dev->height) {
4364 PDEBUG(D_ERR, "Invalid frame size, got: %dx%d,"
4365 " requested: %dx%d\n",
4366 (in[9] + 1) * 8, (in[10] + 1) * 8,
4367 gspca_dev->width, gspca_dev->height);
4368 gspca_dev->last_packet_type = DISCARD_PACKET;
4369 return;
4370 }
4371 /* Add 11 byte footer to frame, might be usefull */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004372 gspca_frame_add(gspca_dev, LAST_PACKET, in, 11);
Hans de Goede1876bb92009-06-14 06:45:50 -03004373 return;
4374 } else {
4375 /* Frame start */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004376 gspca_frame_add(gspca_dev, FIRST_PACKET, in, 0);
Hans de Goede1876bb92009-06-14 06:45:50 -03004377 sd->packet_nr = 0;
4378 }
4379 }
4380
4381 /* Ignore the packet number */
4382 len--;
4383
4384 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004385 gspca_frame_add(gspca_dev, INTER_PACKET, in, len);
Hans de Goede1876bb92009-06-14 06:45:50 -03004386}
4387
Hans de Goede49809d62009-06-07 12:10:39 -03004388static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004389 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004390 int len) /* iso packet length */
4391{
Hans de Goede92918a52009-06-14 06:21:35 -03004392 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goede49809d62009-06-07 12:10:39 -03004393
4394 /* A false positive here is likely, until OVT gives me
4395 * the definitive SOF/EOF format */
4396 if ((!(data[0] | data[1] | data[2] | data[3] | data[5])) && data[6]) {
Hans de Goede92e232a2010-02-20 04:30:45 -03004397 ov51x_handle_button(gspca_dev, (data[6] >> 1) & 1);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004398 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
4399 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goede92918a52009-06-14 06:21:35 -03004400 sd->packet_nr = 0;
4401 }
4402
4403 if (gspca_dev->last_packet_type == DISCARD_PACKET)
4404 return;
4405
4406 /* Does this device use packet numbers ? */
4407 if (len & 7) {
4408 len--;
4409 if (sd->packet_nr == data[len])
4410 sd->packet_nr++;
4411 /* The last few packets of the frame (which are all 0's
4412 except that they may contain part of the footer), are
4413 numbered 0 */
4414 else if (sd->packet_nr == 0 || data[len]) {
4415 PDEBUG(D_ERR, "Invalid packet nr: %d (expect: %d)",
4416 (int)data[len], (int)sd->packet_nr);
4417 gspca_dev->last_packet_type = DISCARD_PACKET;
4418 return;
4419 }
Hans de Goede49809d62009-06-07 12:10:39 -03004420 }
4421
4422 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004423 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004424}
4425
4426static void ov519_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004427 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004428 int len) /* iso packet length */
4429{
4430 /* Header of ov519 is 16 bytes:
4431 * Byte Value Description
4432 * 0 0xff magic
4433 * 1 0xff magic
4434 * 2 0xff magic
4435 * 3 0xXX 0x50 = SOF, 0x51 = EOF
4436 * 9 0xXX 0x01 initial frame without data,
4437 * 0x00 standard frame with image
4438 * 14 Lo in EOF: length of image data / 8
4439 * 15 Hi
4440 */
4441
4442 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
4443 switch (data[3]) {
4444 case 0x50: /* start of frame */
Hans de Goede417a4d22010-02-19 07:37:08 -03004445 /* Don't check the button state here, as the state
4446 usually (always ?) changes at EOF and checking it
4447 here leads to unnecessary snapshot state resets. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004448#define HDRSZ 16
4449 data += HDRSZ;
4450 len -= HDRSZ;
4451#undef HDRSZ
4452 if (data[0] == 0xff || data[1] == 0xd8)
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004453 gspca_frame_add(gspca_dev, FIRST_PACKET,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004454 data, len);
4455 else
4456 gspca_dev->last_packet_type = DISCARD_PACKET;
4457 return;
4458 case 0x51: /* end of frame */
Hans de Goede92e232a2010-02-20 04:30:45 -03004459 ov51x_handle_button(gspca_dev, data[11] & 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004460 if (data[9] != 0)
4461 gspca_dev->last_packet_type = DISCARD_PACKET;
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004462 gspca_frame_add(gspca_dev, LAST_PACKET,
4463 NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004464 return;
4465 }
4466 }
4467
4468 /* intermediate packet */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004469 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004470}
4471
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004472static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004473 u8 *data, /* isoc packet */
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004474 int len) /* iso packet length */
4475{
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004476 struct sd *sd = (struct sd *) gspca_dev;
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004477
4478 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4479
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004480 /* A short read signals EOF */
4481 if (len < OVFX2_BULK_SIZE) {
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004482 /* If the frame is short, and it is one of the first ones
4483 the sensor and bridge are still syncing, so drop it. */
4484 if (sd->first_frame) {
4485 sd->first_frame--;
Jean-François Moineb192ca92010-06-27 03:08:19 -03004486 if (gspca_dev->image_len <
4487 sd->gspca_dev.width * sd->gspca_dev.height)
Hans de Goeded6b6d7a2010-05-08 08:55:42 -03004488 gspca_dev->last_packet_type = DISCARD_PACKET;
4489 }
4490 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004491 gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004492 }
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004493}
4494
Hans de Goede49809d62009-06-07 12:10:39 -03004495static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004496 u8 *data, /* isoc packet */
Hans de Goede49809d62009-06-07 12:10:39 -03004497 int len) /* iso packet length */
4498{
4499 struct sd *sd = (struct sd *) gspca_dev;
4500
4501 switch (sd->bridge) {
4502 case BRIDGE_OV511:
4503 case BRIDGE_OV511PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004504 ov511_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004505 break;
4506 case BRIDGE_OV518:
4507 case BRIDGE_OV518PLUS:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004508 ov518_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004509 break;
4510 case BRIDGE_OV519:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004511 ov519_pkt_scan(gspca_dev, data, len);
Hans de Goede49809d62009-06-07 12:10:39 -03004512 break;
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004513 case BRIDGE_OVFX2:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004514 ovfx2_pkt_scan(gspca_dev, data, len);
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004515 break;
Hans de Goedea511ba92009-10-16 07:13:07 -03004516 case BRIDGE_W9968CF:
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03004517 w9968cf_pkt_scan(gspca_dev, data, len);
Hans de Goedea511ba92009-10-16 07:13:07 -03004518 break;
Hans de Goede49809d62009-06-07 12:10:39 -03004519 }
4520}
4521
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004522/* -- management routines -- */
4523
4524static void setbrightness(struct gspca_dev *gspca_dev)
4525{
4526 struct sd *sd = (struct sd *) gspca_dev;
4527 int val;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004528 static const struct ov_i2c_regvals brit_7660[][7] = {
4529 {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90},
4530 {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}},
4531 {{0x0f, 0x6a}, {0x24, 0x50}, {0x25, 0x40}, {0x26, 0xa1},
4532 {0x27, 0xc0}, {0x28, 0xc0}, {0x2c, 0xc0}},
4533 {{0x0f, 0x6a}, {0x24, 0x68}, {0x25, 0x58}, {0x26, 0xc2},
4534 {0x27, 0xa0}, {0x28, 0xa0}, {0x2c, 0xa0}},
4535 {{0x0f, 0x6a}, {0x24, 0x70}, {0x25, 0x68}, {0x26, 0xd3},
4536 {0x27, 0x80}, {0x28, 0x80}, {0x2c, 0x80}},
4537 {{0x0f, 0x6a}, {0x24, 0x80}, {0x25, 0x70}, {0x26, 0xd3},
4538 {0x27, 0x20}, {0x28, 0x20}, {0x2c, 0x20}},
4539 {{0x0f, 0x6a}, {0x24, 0x88}, {0x25, 0x78}, {0x26, 0xd3},
4540 {0x27, 0x40}, {0x28, 0x40}, {0x2c, 0x40}},
4541 {{0x0f, 0x6a}, {0x24, 0x90}, {0x25, 0x80}, {0x26, 0xd4},
4542 {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}}
4543 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004544
Jean-François Moine62833ac2010-10-02 04:27:02 -03004545 val = sd->ctrls[BRIGHTNESS].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004546 switch (sd->sensor) {
4547 case SEN_OV8610:
4548 case SEN_OV7610:
4549 case SEN_OV76BE:
4550 case SEN_OV6620:
4551 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004552 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004553 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004554 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004555 i2c_w(sd, OV7610_REG_BRT, val);
4556 break;
4557 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004558 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004559 /* 7620 doesn't like manual changes when in auto mode */
Jean-François Moine62833ac2010-10-02 04:27:02 -03004560 if (!sd->ctrls[AUTOBRIGHT].val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004561 i2c_w(sd, OV7610_REG_BRT, val);
4562 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004563 case SEN_OV7660:
4564 write_i2c_regvals(sd, brit_7660[val],
4565 ARRAY_SIZE(brit_7660[0]));
4566 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004567 case SEN_OV7670:
Jean-Francois Moine594f5b82008-08-01 06:37:51 -03004568/*win trace
Jean-François Moine21867802010-11-12 06:12:09 -03004569 * i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_AEC); */
4570 i2c_w(sd, OV7670_R55_BRIGHT, ov7670_abs_to_sm(val));
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004571 break;
4572 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004573}
4574
4575static void setcontrast(struct gspca_dev *gspca_dev)
4576{
4577 struct sd *sd = (struct sd *) gspca_dev;
4578 int val;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004579 static const struct ov_i2c_regvals contrast_7660[][31] = {
4580 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0},
4581 {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30},
4582 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x24}, {0x77, 0x24},
4583 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x34},
4584 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x65},
4585 {0x80, 0x70}, {0x81, 0x77}, {0x82, 0x7d}, {0x83, 0x83},
4586 {0x84, 0x88}, {0x85, 0x8d}, {0x86, 0x96}, {0x87, 0x9f},
4587 {0x88, 0xb0}, {0x89, 0xc4}, {0x8a, 0xd9}},
4588 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0x94},
4589 {0x70, 0x58}, {0x71, 0x40}, {0x72, 0x30}, {0x73, 0x30},
4590 {0x74, 0x30}, {0x75, 0x30}, {0x76, 0x2c}, {0x77, 0x24},
4591 {0x78, 0x22}, {0x79, 0x28}, {0x7a, 0x2a}, {0x7b, 0x31},
4592 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3d}, {0x7f, 0x62},
4593 {0x80, 0x6d}, {0x81, 0x75}, {0x82, 0x7b}, {0x83, 0x81},
4594 {0x84, 0x87}, {0x85, 0x8d}, {0x86, 0x98}, {0x87, 0xa1},
4595 {0x88, 0xb2}, {0x89, 0xc6}, {0x8a, 0xdb}},
4596 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x84},
4597 {0x70, 0x58}, {0x71, 0x48}, {0x72, 0x40}, {0x73, 0x40},
4598 {0x74, 0x28}, {0x75, 0x28}, {0x76, 0x28}, {0x77, 0x24},
4599 {0x78, 0x26}, {0x79, 0x28}, {0x7a, 0x28}, {0x7b, 0x34},
4600 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x5d},
4601 {0x80, 0x68}, {0x81, 0x71}, {0x82, 0x79}, {0x83, 0x81},
4602 {0x84, 0x86}, {0x85, 0x8b}, {0x86, 0x95}, {0x87, 0x9e},
4603 {0x88, 0xb1}, {0x89, 0xc5}, {0x8a, 0xd9}},
4604 {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf0}, {0x6f, 0x70},
4605 {0x70, 0x58}, {0x71, 0x58}, {0x72, 0x48}, {0x73, 0x48},
4606 {0x74, 0x38}, {0x75, 0x40}, {0x76, 0x34}, {0x77, 0x34},
4607 {0x78, 0x2e}, {0x79, 0x28}, {0x7a, 0x24}, {0x7b, 0x22},
4608 {0x7c, 0x0f}, {0x7d, 0x1e}, {0x7e, 0x3c}, {0x7f, 0x58},
4609 {0x80, 0x63}, {0x81, 0x6e}, {0x82, 0x77}, {0x83, 0x80},
4610 {0x84, 0x87}, {0x85, 0x8f}, {0x86, 0x9c}, {0x87, 0xa9},
4611 {0x88, 0xc0}, {0x89, 0xd4}, {0x8a, 0xe6}},
4612 {{0x6c, 0xa0}, {0x6d, 0xf0}, {0x6e, 0x90}, {0x6f, 0x80},
4613 {0x70, 0x70}, {0x71, 0x80}, {0x72, 0x60}, {0x73, 0x60},
4614 {0x74, 0x58}, {0x75, 0x60}, {0x76, 0x4c}, {0x77, 0x38},
4615 {0x78, 0x38}, {0x79, 0x2a}, {0x7a, 0x20}, {0x7b, 0x0e},
4616 {0x7c, 0x0a}, {0x7d, 0x14}, {0x7e, 0x26}, {0x7f, 0x46},
4617 {0x80, 0x54}, {0x81, 0x64}, {0x82, 0x70}, {0x83, 0x7c},
4618 {0x84, 0x87}, {0x85, 0x93}, {0x86, 0xa6}, {0x87, 0xb4},
4619 {0x88, 0xd0}, {0x89, 0xe5}, {0x8a, 0xf5}},
4620 {{0x6c, 0x60}, {0x6d, 0x80}, {0x6e, 0x60}, {0x6f, 0x80},
4621 {0x70, 0x80}, {0x71, 0x80}, {0x72, 0x88}, {0x73, 0x30},
4622 {0x74, 0x70}, {0x75, 0x68}, {0x76, 0x64}, {0x77, 0x50},
4623 {0x78, 0x3c}, {0x79, 0x22}, {0x7a, 0x10}, {0x7b, 0x08},
4624 {0x7c, 0x06}, {0x7d, 0x0e}, {0x7e, 0x1a}, {0x7f, 0x3a},
4625 {0x80, 0x4a}, {0x81, 0x5a}, {0x82, 0x6b}, {0x83, 0x7b},
4626 {0x84, 0x89}, {0x85, 0x96}, {0x86, 0xaf}, {0x87, 0xc3},
4627 {0x88, 0xe1}, {0x89, 0xf2}, {0x8a, 0xfa}},
4628 {{0x6c, 0x20}, {0x6d, 0x40}, {0x6e, 0x20}, {0x6f, 0x60},
4629 {0x70, 0x88}, {0x71, 0xc8}, {0x72, 0xc0}, {0x73, 0xb8},
4630 {0x74, 0xa8}, {0x75, 0xb8}, {0x76, 0x80}, {0x77, 0x5c},
4631 {0x78, 0x26}, {0x79, 0x10}, {0x7a, 0x08}, {0x7b, 0x04},
4632 {0x7c, 0x02}, {0x7d, 0x06}, {0x7e, 0x0a}, {0x7f, 0x22},
4633 {0x80, 0x33}, {0x81, 0x4c}, {0x82, 0x64}, {0x83, 0x7b},
4634 {0x84, 0x90}, {0x85, 0xa7}, {0x86, 0xc7}, {0x87, 0xde},
4635 {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}},
4636 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004637
Jean-François Moine62833ac2010-10-02 04:27:02 -03004638 val = sd->ctrls[CONTRAST].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004639 switch (sd->sensor) {
4640 case SEN_OV7610:
4641 case SEN_OV6620:
4642 i2c_w(sd, OV7610_REG_CNT, val);
4643 break;
4644 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004645 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004646 i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
Hans de Goede49809d62009-06-07 12:10:39 -03004647 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004648 case SEN_OV8610: {
Jean-François Moine9d1593a2010-11-11 08:04:06 -03004649 static const u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004650 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
4651 };
4652
4653 /* Use Y gamma control instead. Bit 0 enables it. */
4654 i2c_w(sd, 0x64, ctab[val >> 5]);
4655 break;
4656 }
Hans de Goede859cc472010-01-07 15:42:35 -03004657 case SEN_OV7620:
4658 case SEN_OV7620AE: {
Jean-François Moine9d1593a2010-11-11 08:04:06 -03004659 static const u8 ctab[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004660 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
4661 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
4662 };
4663
4664 /* Use Y gamma control instead. Bit 0 enables it. */
4665 i2c_w(sd, 0x64, ctab[val >> 4]);
4666 break;
4667 }
Jean-François Moine42e142f2010-11-13 05:10:27 -03004668 case SEN_OV7660:
4669 write_i2c_regvals(sd, contrast_7660[val],
4670 ARRAY_SIZE(contrast_7660[0]));
4671 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004672 case SEN_OV7670:
4673 /* check that this isn't just the same as ov7610 */
Jean-François Moine21867802010-11-12 06:12:09 -03004674 i2c_w(sd, OV7670_R56_CONTRAS, val >> 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004675 break;
4676 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004677}
4678
Jean-François Moine58c92d32011-03-13 16:36:49 -03004679static void setexposure(struct gspca_dev *gspca_dev)
4680{
4681 struct sd *sd = (struct sd *) gspca_dev;
4682
4683 if (!sd->ctrls[AUTOGAIN].val)
4684 i2c_w(sd, 0x10, sd->ctrls[EXPOSURE].val);
4685}
4686
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004687static void setcolors(struct gspca_dev *gspca_dev)
4688{
4689 struct sd *sd = (struct sd *) gspca_dev;
4690 int val;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004691 static const struct ov_i2c_regvals colors_7660[][6] = {
4692 {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a},
4693 {0x53, 0x19}, {0x54, 0x23}},
4694 {{0x4f, 0x47}, {0x50, 0x4a}, {0x51, 0x03}, {0x52, 0x11},
4695 {0x53, 0x2c}, {0x54, 0x3e}},
4696 {{0x4f, 0x66}, {0x50, 0x6b}, {0x51, 0x05}, {0x52, 0x19},
4697 {0x53, 0x40}, {0x54, 0x59}},
4698 {{0x4f, 0x84}, {0x50, 0x8b}, {0x51, 0x06}, {0x52, 0x20},
4699 {0x53, 0x53}, {0x54, 0x73}},
4700 {{0x4f, 0xa3}, {0x50, 0xab}, {0x51, 0x08}, {0x52, 0x28},
4701 {0x53, 0x66}, {0x54, 0x8e}},
4702 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004703
Jean-François Moine62833ac2010-10-02 04:27:02 -03004704 val = sd->ctrls[COLORS].val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004705 switch (sd->sensor) {
4706 case SEN_OV8610:
4707 case SEN_OV7610:
4708 case SEN_OV76BE:
4709 case SEN_OV6620:
4710 case SEN_OV6630:
Hans de Goede7d971372009-06-14 05:28:17 -03004711 case SEN_OV66308AF:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004712 i2c_w(sd, OV7610_REG_SAT, val);
4713 break;
4714 case SEN_OV7620:
Hans de Goede859cc472010-01-07 15:42:35 -03004715 case SEN_OV7620AE:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004716 /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
4717/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
4718 if (rc < 0)
4719 goto out; */
4720 i2c_w(sd, OV7610_REG_SAT, val);
4721 break;
4722 case SEN_OV7640:
Hans de Goede035d3a32010-01-09 08:14:43 -03004723 case SEN_OV7648:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004724 i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
4725 break;
Jean-François Moine42e142f2010-11-13 05:10:27 -03004726 case SEN_OV7660:
4727 write_i2c_regvals(sd, colors_7660[val],
4728 ARRAY_SIZE(colors_7660[0]));
4729 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004730 case SEN_OV7670:
4731 /* supported later once I work out how to do it
4732 * transparently fail now! */
4733 /* set REG_COM13 values for UV sat auto mode */
4734 break;
4735 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004736}
4737
Jean-François Moine62833ac2010-10-02 04:27:02 -03004738static void setautobright(struct gspca_dev *gspca_dev)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004739{
Jean-François Moine62833ac2010-10-02 04:27:02 -03004740 struct sd *sd = (struct sd *) gspca_dev;
4741
Jean-François Moine62833ac2010-10-02 04:27:02 -03004742 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004743}
4744
Jean-François Moine58c92d32011-03-13 16:36:49 -03004745static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
4746{
4747 struct sd *sd = (struct sd *) gspca_dev;
4748
4749 sd->ctrls[AUTOGAIN].val = val;
4750 if (val) {
4751 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
4752 } else {
4753 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
4754 sd->ctrls[EXPOSURE].val = i2c_r(sd, 0x10);
4755 }
4756 if (gspca_dev->streaming)
4757 setautogain(gspca_dev);
4758 return gspca_dev->usb_err;
4759}
4760
Jean-François Moine62833ac2010-10-02 04:27:02 -03004761static void setfreq_i(struct sd *sd)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004762{
Jean-François Moine42e142f2010-11-13 05:10:27 -03004763 if (sd->sensor == SEN_OV7660
4764 || sd->sensor == SEN_OV7670) {
Jean-François Moine62833ac2010-10-02 04:27:02 -03004765 switch (sd->ctrls[FREQ].val) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004766 case 0: /* Banding filter disabled */
Jean-François Moine21867802010-11-12 06:12:09 -03004767 i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004768 break;
4769 case 1: /* 50 hz */
Jean-François Moine21867802010-11-12 06:12:09 -03004770 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004771 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004772 i2c_w_mask(sd, OV7670_R3B_COM11, 0x08, 0x18);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004773 break;
4774 case 2: /* 60 hz */
Jean-François Moine21867802010-11-12 06:12:09 -03004775 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004776 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004777 i2c_w_mask(sd, OV7670_R3B_COM11, 0x00, 0x18);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004778 break;
Jean-François Moine21867802010-11-12 06:12:09 -03004779 case 3: /* Auto hz - ov7670 only */
4780 i2c_w_mask(sd, OV7670_R13_COM8, OV7670_COM8_BFILT,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004781 OV7670_COM8_BFILT);
Jean-François Moine21867802010-11-12 06:12:09 -03004782 i2c_w_mask(sd, OV7670_R3B_COM11, OV7670_COM11_HZAUTO,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004783 0x18);
4784 break;
4785 }
4786 } else {
Jean-François Moine62833ac2010-10-02 04:27:02 -03004787 switch (sd->ctrls[FREQ].val) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004788 case 0: /* Banding filter disabled */
4789 i2c_w_mask(sd, 0x2d, 0x00, 0x04);
4790 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4791 break;
4792 case 1: /* 50 hz (filter on and framerate adj) */
4793 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4794 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4795 /* 20 fps -> 16.667 fps */
4796 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004797 sd->sensor == SEN_OV6630 ||
4798 sd->sensor == SEN_OV66308AF)
Hans de Goede02ab18b2009-06-14 04:32:04 -03004799 i2c_w(sd, 0x2b, 0x5e);
4800 else
4801 i2c_w(sd, 0x2b, 0xac);
4802 break;
4803 case 2: /* 60 hz (filter on, ...) */
4804 i2c_w_mask(sd, 0x2d, 0x04, 0x04);
4805 if (sd->sensor == SEN_OV6620 ||
Hans de Goede7d971372009-06-14 05:28:17 -03004806 sd->sensor == SEN_OV6630 ||
4807 sd->sensor == SEN_OV66308AF) {
Hans de Goede02ab18b2009-06-14 04:32:04 -03004808 /* 20 fps -> 15 fps */
4809 i2c_w_mask(sd, 0x2a, 0x80, 0x80);
4810 i2c_w(sd, 0x2b, 0xa8);
4811 } else {
4812 /* no framerate adj. */
4813 i2c_w_mask(sd, 0x2a, 0x00, 0x80);
4814 }
4815 break;
4816 }
4817 }
4818}
Jean-François Moine62833ac2010-10-02 04:27:02 -03004819static void setfreq(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004820{
4821 struct sd *sd = (struct sd *) gspca_dev;
4822
Jean-François Moine62833ac2010-10-02 04:27:02 -03004823 setfreq_i(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004824
Jean-François Moine62833ac2010-10-02 04:27:02 -03004825 /* Ugly but necessary */
4826 if (sd->bridge == BRIDGE_W9968CF)
4827 w9968cf_set_crop_window(sd);
Hans de Goede02ab18b2009-06-14 04:32:04 -03004828}
4829
4830static int sd_querymenu(struct gspca_dev *gspca_dev,
4831 struct v4l2_querymenu *menu)
4832{
4833 struct sd *sd = (struct sd *) gspca_dev;
4834
4835 switch (menu->id) {
4836 case V4L2_CID_POWER_LINE_FREQUENCY:
4837 switch (menu->index) {
4838 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
4839 strcpy((char *) menu->name, "NoFliker");
4840 return 0;
4841 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
4842 strcpy((char *) menu->name, "50 Hz");
4843 return 0;
4844 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
4845 strcpy((char *) menu->name, "60 Hz");
4846 return 0;
4847 case 3:
4848 if (sd->sensor != SEN_OV7670)
4849 return -EINVAL;
4850
4851 strcpy((char *) menu->name, "Automatic");
4852 return 0;
4853 }
4854 break;
4855 }
4856 return -EINVAL;
4857}
4858
Hans de Goede79b35902009-10-19 06:08:01 -03004859static int sd_get_jcomp(struct gspca_dev *gspca_dev,
4860 struct v4l2_jpegcompression *jcomp)
4861{
4862 struct sd *sd = (struct sd *) gspca_dev;
4863
4864 if (sd->bridge != BRIDGE_W9968CF)
4865 return -EINVAL;
4866
4867 memset(jcomp, 0, sizeof *jcomp);
4868 jcomp->quality = sd->quality;
4869 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT |
4870 V4L2_JPEG_MARKER_DRI;
4871 return 0;
4872}
4873
4874static int sd_set_jcomp(struct gspca_dev *gspca_dev,
4875 struct v4l2_jpegcompression *jcomp)
4876{
4877 struct sd *sd = (struct sd *) gspca_dev;
4878
4879 if (sd->bridge != BRIDGE_W9968CF)
4880 return -EINVAL;
4881
4882 if (gspca_dev->streaming)
4883 return -EBUSY;
4884
4885 if (jcomp->quality < QUALITY_MIN)
4886 sd->quality = QUALITY_MIN;
4887 else if (jcomp->quality > QUALITY_MAX)
4888 sd->quality = QUALITY_MAX;
4889 else
4890 sd->quality = jcomp->quality;
4891
4892 /* Return resulting jcomp params to app */
4893 sd_get_jcomp(gspca_dev, jcomp);
4894
4895 return 0;
4896}
4897
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004898/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03004899static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004900 .name = MODULE_NAME,
4901 .ctrls = sd_ctrls,
4902 .nctrls = ARRAY_SIZE(sd_ctrls),
4903 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03004904 .init = sd_init,
Jean-François Moinec42cedb2011-02-10 13:37:48 -03004905 .isoc_init = sd_isoc_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004906 .start = sd_start,
4907 .stopN = sd_stopN,
Hans de Goede79b35902009-10-19 06:08:01 -03004908 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004909 .pkt_scan = sd_pkt_scan,
Hans de Goede417a4d22010-02-19 07:37:08 -03004910 .dq_callback = sd_reset_snapshot,
Hans de Goede02ab18b2009-06-14 04:32:04 -03004911 .querymenu = sd_querymenu,
Hans de Goede79b35902009-10-19 06:08:01 -03004912 .get_jcomp = sd_get_jcomp,
4913 .set_jcomp = sd_set_jcomp,
Jean-François Moine28566432010-10-01 07:33:26 -03004914#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede417a4d22010-02-19 07:37:08 -03004915 .other_input = 1,
4916#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004917};
4918
4919/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -03004920static const struct usb_device_id device_table[] = {
Hans de Goedea511ba92009-10-16 07:13:07 -03004921 {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF },
Hans de Goede49809d62009-06-07 12:10:39 -03004922 {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 },
4923 {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 },
4924 {USB_DEVICE(0x041e, 0x4060), .driver_info = BRIDGE_OV519 },
4925 {USB_DEVICE(0x041e, 0x4061), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004926 {USB_DEVICE(0x041e, 0x4064),
Jean-François Moine87bae742010-11-12 05:31:34 -03004927 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Rafal Milecki518c8df2009-10-02 03:54:44 -03004928 {USB_DEVICE(0x041e, 0x4067), .driver_info = BRIDGE_OV519 },
Hans de Goede9e4d8252009-06-14 06:25:06 -03004929 {USB_DEVICE(0x041e, 0x4068),
Jean-François Moine87bae742010-11-12 05:31:34 -03004930 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede49809d62009-06-07 12:10:39 -03004931 {USB_DEVICE(0x045e, 0x028c), .driver_info = BRIDGE_OV519 },
4932 {USB_DEVICE(0x054c, 0x0154), .driver_info = BRIDGE_OV519 },
Hans de Goede98184f72010-01-07 12:06:00 -03004933 {USB_DEVICE(0x054c, 0x0155),
Jean-François Moine87bae742010-11-12 05:31:34 -03004934 .driver_info = BRIDGE_OV519 | BRIDGE_INVERT_LED },
Hans de Goede1876bb92009-06-14 06:45:50 -03004935 {USB_DEVICE(0x05a9, 0x0511), .driver_info = BRIDGE_OV511 },
Hans de Goede49809d62009-06-07 12:10:39 -03004936 {USB_DEVICE(0x05a9, 0x0518), .driver_info = BRIDGE_OV518 },
4937 {USB_DEVICE(0x05a9, 0x0519), .driver_info = BRIDGE_OV519 },
4938 {USB_DEVICE(0x05a9, 0x0530), .driver_info = BRIDGE_OV519 },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004939 {USB_DEVICE(0x05a9, 0x2800), .driver_info = BRIDGE_OVFX2 },
Hans de Goede49809d62009-06-07 12:10:39 -03004940 {USB_DEVICE(0x05a9, 0x4519), .driver_info = BRIDGE_OV519 },
4941 {USB_DEVICE(0x05a9, 0x8519), .driver_info = BRIDGE_OV519 },
Hans de Goede1876bb92009-06-14 06:45:50 -03004942 {USB_DEVICE(0x05a9, 0xa511), .driver_info = BRIDGE_OV511PLUS },
Hans de Goede49809d62009-06-07 12:10:39 -03004943 {USB_DEVICE(0x05a9, 0xa518), .driver_info = BRIDGE_OV518PLUS },
Hans de Goede1876bb92009-06-14 06:45:50 -03004944 {USB_DEVICE(0x0813, 0x0002), .driver_info = BRIDGE_OV511PLUS },
Hans de Goedeb46aaa02009-10-12 10:07:57 -03004945 {USB_DEVICE(0x0b62, 0x0059), .driver_info = BRIDGE_OVFX2 },
4946 {USB_DEVICE(0x0e96, 0xc001), .driver_info = BRIDGE_OVFX2 },
Hans de Goedea511ba92009-10-16 07:13:07 -03004947 {USB_DEVICE(0x1046, 0x9967), .driver_info = BRIDGE_W9968CF },
Jean-François Moine87bae742010-11-12 05:31:34 -03004948 {USB_DEVICE(0x8020, 0xef04), .driver_info = BRIDGE_OVFX2 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004949 {}
4950};
Jean-Francois Moineac40b1f2008-11-08 06:03:37 -03004951
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004952MODULE_DEVICE_TABLE(usb, device_table);
4953
4954/* -- device connect -- */
4955static int sd_probe(struct usb_interface *intf,
4956 const struct usb_device_id *id)
4957{
4958 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
4959 THIS_MODULE);
4960}
4961
4962static struct usb_driver sd_driver = {
4963 .name = MODULE_NAME,
4964 .id_table = device_table,
4965 .probe = sd_probe,
4966 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03004967#ifdef CONFIG_PM
4968 .suspend = gspca_suspend,
4969 .resume = gspca_resume,
4970#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004971};
4972
4973/* -- module insert / remove -- */
4974static int __init sd_mod_init(void)
4975{
Jean-François Moine54826432010-09-13 04:53:03 -03004976 return usb_register(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004977}
4978static void __exit sd_mod_exit(void)
4979{
4980 usb_deregister(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03004981}
4982
4983module_init(sd_mod_init);
4984module_exit(sd_mod_exit);
4985
4986module_param(frame_rate, int, 0644);
4987MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");